From 012bf388ab1425b02ccdf2fee677221bad18d0e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dofri=20J=C3=B3nsson?= <77961427+dofrijonsson@users.noreply.github.com> Date: Tue, 26 Jan 2021 02:20:59 +0100 Subject: [PATCH 01/24] Fix incorrect key name so registerManualConfirm setting works as expected. (#14455) --- modules/setting/service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/setting/service.go b/modules/setting/service.go index 4410a600dd86e..b6611830be191 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -67,7 +67,7 @@ func newService() { Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool() Service.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").MustBool() if !sec.Key("REGISTER_EMAIL_CONFIRM").MustBool() { - Service.RegisterManualConfirm = sec.Key("REGISTER_EMAIL_CONFIRM").MustBool(false) + Service.RegisterManualConfirm = sec.Key("REGISTER_MANUAL_CONFIRM").MustBool(false) } else { Service.RegisterManualConfirm = false } From 3adbbb4255c42cde04d59b6ebf5ead7e3edda3e7 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Tue, 26 Jan 2021 01:22:19 +0000 Subject: [PATCH 02/24] [skip ci] Updated translations via Crowdin --- options/locale/locale_cs-CZ.ini | 28 ++++++++++++++++ options/locale/locale_de-DE.ini | 59 +++++++++++++++++++++++---------- options/locale/locale_ja-JP.ini | 7 ++++ 3 files changed, 77 insertions(+), 17 deletions(-) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index dc8459fe65323..8f43706992d70 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -15,6 +15,7 @@ page=Strana template=Šablona language=Jazyk notifications=Oznámení +active_stopwatch=Aktivní sledování času create_new=Vytvořit… user_profile_and_more=Profily a nastavení… signed_in_as=Přihlášen jako @@ -358,6 +359,7 @@ password_not_match=Zadaná hesla nesouhlasí. lang_select_error=Vyberte jazyk ze seznamu. username_been_taken=Uživatelské jméno je již obsazeno. +username_change_not_local_user=Uživatelé, kteří jsou ověřováni jinak než lokálně, si nemohou změnit uživatelské jméno. repo_name_been_taken=Název repozitáře je již použit. repository_files_already_exist=Soubory pro tento repozitář již existují. Obraťte se na správce systému. repository_files_already_exist.adopt=Soubory pro tento repozitář již existují a mohou být pouze přijaty. @@ -447,6 +449,7 @@ update_language_not_found=Jazyk „%s“ není k dispozici. update_profile_success=Váš profil byl aktualizován. change_username=Vaše uživatelské jméno bylo změněno. change_username_prompt=Poznámka: změna uživatelského jména změní také URL účtu. +change_username_redirect_prompt=Staré uživatelské jméno bude přesměrovávat, dokud nebude znovu obsazeno. continue=Pokračovat cancel=Zrušit language=Jazyk @@ -517,6 +520,7 @@ ssh_helper=Potřebujete pomoct? Podívejte se do příručky Gi gpg_helper=Potřebujete pomoct? Podívejte se do příručky GitHubu o GPG. add_new_key=Přidat klíč SSH add_new_gpg_key=Přidat GPG klíč +key_content_ssh_placeholder=Začíná s „ssh-ed25519“, „ssh-rsa“, „ecdsa-sha2-nistp256“, „ecdsa-sha2-nistp384“, „ecdsa-sha2-nistp521“, „sk-ecdsa-sha2-nistp256@openssh.com“, nebo „sk-ssh-ed25519@openssh.com“ key_content_gpg_placeholder=Začíná s „-----BEGIN PGP PUBLIC KEY BLOCK-----“ add_new_principal=Přidat SSH Principal certifikát ssh_key_been_used=Tento SSH klíč byl na server již přidán. @@ -622,6 +626,7 @@ or_enter_secret=Nebo zadejte tajný kód: %s then_enter_passcode=A zadejte přístupový kód zobrazený ve vaší aplikaci: passcode_invalid=Přístupový kód není platný. Zkuste to znovu. twofa_enrolled=Ve vašem účtu bylo povoleno dvoufaktorové ověřování. Uložte si pomocný token (%s) na bezpečném místě, protože bude zobrazen pouze jednou! +twofa_failed_get_secret=Nepodařilo se získat tajemství. u2f_desc=Bezpečnostní klíče jsou hardwarová zařízení obsahující kryptografické klíče. Mohou být použity pro dvoufaktorové ověřování. Bezpečnostní klíče musí podporovat FIDO U2F standard. u2f_require_twofa=Váš účet musí mít povolené dvoufaktorové ověřování, aby bylo možné použít bezpečnostní klíč. @@ -643,6 +648,7 @@ repos_none=Nevlastníte žádné repozitáře delete_account=Smazat váš účet delete_prompt=Tato operace natrvalo odstraní váš uživatelský účet. NELZE ji vrátit zpět. +delete_with_all_comments=Váš účet je mladší než %s. Aby se zabránilo fantomovým komentářům, všechny komentáře k úkolům/požadavkům na natažení budou smazány. confirm_delete_account=Potvrdit smazání delete_account_title=Smazat uživatelský účet delete_account_desc=Jste si jisti, že chcete trvale smazat tento účet? @@ -735,6 +741,8 @@ archive.title=Tento repozitář je archivovaný. Můžete prohlížet soubory, k archive.issue.nocomment=Tento repozitář je archivovaný. Nemůžete komentovat úkoly. archive.pull.nocomment=Tento repozitář je archivovaný. Nemůžete komentovat požadavky na natažení. +form.reach_limit_of_creation_1=Již jste dosáhli svůj limit %d repozitář. +form.reach_limit_of_creation_n=Již jste dosáhli svůj limit %d repozitářů. form.name_reserved=Jméno repozitáře „%s“ je rezervované. form.name_pattern_not_allowed=Vzor „%s“ není povolený v názvu repozitáře. @@ -769,6 +777,7 @@ migrate.github.description=Migrace dat z Github.com nebo Github Enterprise. migrate.git.description=Migrace nebo zrcadlení git dat ze služeb Git migrate.gitlab.description=Migrace dat z GitLab.com nebo vlastního gitlab serveru. migrate.gitea.description=Migrace dat ze serveru Gitea.com nebo vlastního serveru Gitea. +migrate.gogs.description=Migrace dat z notabug.org nebo vlastního serveru Gogs. mirror_from=zrcadlo forked_from=rozštěpen z @@ -819,6 +828,8 @@ tag=Značka released_this=vydal(a) toto file_raw=Surový file_history=Historie +file_view_source=Zobrazit zdroj +file_view_rendered=Zobrazit vykreslené file_view_raw=Zobrazit v surovém stavu file_permalink=Trvalý odkaz file_too_large=Soubor je příliš velký pro zobrazení. @@ -915,6 +926,8 @@ ext_issues=Ext. úkoly ext_issues.desc=Odkaz na externí systém úkolů. projects=Projekty +projects.description=Popis (volitelné) +projects.description_placeholder=Popis projects.create=Vytvořit projekt projects.title=Název projects.new=Nový projekt @@ -938,6 +951,8 @@ projects.board.edit_title=Název nástěnky projects.board.new_title=Název nové nástěnky projects.board.new_submit=Odeslat projects.board.new=Nová nástěnka +projects.board.set_default=Nastavit jako výchozí +projects.board.set_default_desc=Nastavit tuto nástěnku jako výchozí pro nekategorizované úkoly a požadavky na natažení projects.board.delete=Smazat nástěnku projects.board.deletion_desc=Smazáním projektové nástěnky přesune všechny související problémy do kategorie „Nezařazené“. Pokračovat? projects.open=Otevřít @@ -1021,6 +1036,7 @@ issues.filter_type.all_issues=Všechny úkoly issues.filter_type.assigned_to_you=Přiřazené vám issues.filter_type.created_by_you=Vytvořené vámi issues.filter_type.mentioning_you=Zmiňující vás +issues.filter_type.review_requested=Požadováno posouzení issues.filter_sort=Seřadit issues.filter_sort.latest=Nejnovější issues.filter_sort.oldest=Nejstarší @@ -1056,6 +1072,7 @@ issues.commented_at=`okomentoval %s` issues.delete_comment_confirm=Jste si jist, že chcete smazat tento komentář? issues.context.copy_link=Kopírovat odkaz issues.context.quote_reply=Citovat odpověď +issues.context.reference_issue=Odkázat v novém úkolu issues.context.edit=Upravit issues.context.delete=Smazat issues.no_content=Není zde žádný obsah. @@ -1126,11 +1143,14 @@ issues.lock.title=Uzamknout konverzaci u tohoto úkolu. issues.unlock.title=Odemknout konverzaci u tohoto úkolu. issues.comment_on_locked=Nemůžete komentovat uzamčený úkol. issues.tracker=Sledování času +issues.start_tracking_short=Spustit časovač issues.start_tracking=Spustit sledování času issues.start_tracking_history=`započal(a) práci %s` issues.tracker_auto_close=Časovač se automaticky zastaví po zavření tohoto úkolu issues.tracking_already_started=`Již jste spustili sledování času na jiném úkolu!` +issues.stop_tracking=Zastavit časovač issues.stop_tracking_history=`ukončil(a) práci %s` +issues.cancel_tracking=Zahodit issues.cancel_tracking_history=`zrušil(a) sledování času %s` issues.add_time=Přidat čas ručně issues.add_time_short=Přidat čas @@ -1210,6 +1230,7 @@ issues.review.resolve_conversation=Vyřešit konverzaci issues.review.un_resolve_conversation=Nevyřešit konverzaci issues.review.resolved_by=označil tuto konverzaci jako vyřešenou issues.assignee.error=Ne všichni zpracovatelé byli přidáni z důvodu neočekávané chyby. +issues.reference_issue.body=Tělo zprávy pulls.desc=Povolit požadavky na natažení a posuzování kódu. pulls.new=Nový požadavek na natažení @@ -1920,6 +1941,7 @@ settings.visibility.private_shortname=Soukromý settings.update_settings=Upravit nastavení settings.update_setting_success=Nastavení organizace bylo upraveno. settings.change_orgname_prompt=Poznámka: změna názvu organizace změní i její URL. +settings.change_orgname_redirect_prompt=Staré jméno bude přesměrovávat, dokud nebude znovu obsazeno. settings.update_avatar_success=Avatar organizace byl aktualizován. settings.delete=Smazat organizaci settings.delete_account=Smazat tuto organizaci @@ -1991,6 +2013,7 @@ dashboard=Přehled users=Uživatelské účty organizations=Organizace repositories=Repozitáře +hooks=Webové háčky authentication=Zdroje ověření emails=Uživatelské e-maily config=Nastavení @@ -2140,8 +2163,13 @@ repos.forks=Rozštěpení repos.issues=Úkoly repos.size=Velikost +defaulthooks=Výchozí webové háčky +defaulthooks.desc=Webové háčky automaticky vytvářejí HTTP POST dotazy na server při určitých Gitea událostech. Webové háčky definované zde jsou výchozí a budou zkopírovány do všech nových repozitářů. Přečtěte si více v průvodci webovými háčky. +defaulthooks.add_webhook=Přidat výchozí webový háček +defaulthooks.update_webhook=Aktualizovat výchozí webový háček systemhooks=Systémové webové háčky +systemhooks.desc=Webové háčky automaticky vytvářejí HTTP POST dotazy na server při určitých Gitea událostech. Webové háčky definované zde budou vykonány na všech repozitářích systému, proto prosím zvažte jakékoli důsledky, které to může mít na výkon. Přečtěte si více v průvodci webovými háčky. systemhooks.add_webhook=Přidat systémový webový háček systemhooks.update_webhook=Aktualizovat systémový webový háček diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 377e9ca8516e6..31b55b499cd40 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -15,6 +15,7 @@ page=Seite template=Template language=Sprache notifications=Benachrichtigungen +active_stopwatch=Aktive Zeiterfassung create_new=Erstellen… user_profile_and_more=Profil und Einstellungen… signed_in_as=Angemeldet als @@ -358,6 +359,7 @@ password_not_match=Die Passwörter stimmen nicht überein. lang_select_error=Wähle eine Sprache aus der Liste aus. username_been_taken=Der Benutzername ist bereits vergeben. +username_change_not_local_user=Nicht-lokale Benutzer dürfen ihren Nutzernamen nicht ändern. repo_name_been_taken=Der Repository-Name wird schon verwendet. repository_files_already_exist=Dateien für dieses Repository sind bereits vorhanden. Kontaktiere den Systemadministrator. repository_files_already_exist.adopt=Dateien für dieses Repository existieren bereits und können nur übernommen werden. @@ -517,6 +519,7 @@ ssh_helper=Brauchst du Hilfe? Hier ist GitHubs Anleitung zum Brauchst du Hilfe? Hier ist GitHubs Anleitung über GPG. add_new_key=SSH-Schlüssel hinzufügen add_new_gpg_key=GPG-Schlüssel hinzufügen +key_content_ssh_placeholder=Startet mit 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', oder 'sk-ssh-ed25519@openssh.com' key_content_gpg_placeholder=Beginnt mit '-----BEGIN PGP PUBLIC KEY BLOCK-----' add_new_principal=Identität hinzufügen ssh_key_been_used=Dieser SSH-Key wird auf diesem Server bereits verwendet. @@ -622,6 +625,7 @@ or_enter_secret=Oder gib das Secret ein: %s then_enter_passcode=Und gebe dann die angezeigte PIN der Anwendung ein: passcode_invalid=Die PIN ist falsch. Probiere es erneut. twofa_enrolled=Die Zwei-Faktor-Authentifizierung wurde für dein Konto aktiviert. Bewahre dein Einmalpasswort (%s) an einem sicheren Ort auf, da es nicht wieder angezeigt werden wird. +twofa_failed_get_secret=Fehler beim Abrufen des Secrets. u2f_desc=Sicherheitsschlüssel sind Geräte, die kryptografische Schlüssel beeinhalten. Diese können für die Zwei-Faktor-Authentifizierung verwendet werden. Der Sicherheitsschlüssel muss den Standard „FIDO U2F“ unterstützen. u2f_require_twofa=Du musst die Zwei-Faktor-Authentifizierung für deinen Account aktivieren, um Sicherheitsschlüssel benutzen zu können. @@ -643,6 +647,7 @@ repos_none=Du besitzt keine Repositories delete_account=Konto löschen delete_prompt=Wenn du fortfährst, wird dein Account permanent gelöscht. Dies KANN NICHT rückgängig gemacht werden. +delete_with_all_comments=Dein Account existiert seit weniger als %s Tagen. Um Geisterkommentare zu vermeiden, werden alle deine Issue/PR-Kommentare gelöscht. confirm_delete_account=Löschen bestätigen delete_account_title=Benutzerkonto löschen delete_account_desc=Bist du sicher, dass du diesen Account dauerhaft löschen möchtest? @@ -654,6 +659,7 @@ email_notifications.submit=E-Mail-Einstellungen festlegen [repo] owner=Besitzer +owner_helper=Einige Organisationen könnten in der Dropdown-Liste nicht angezeigt werden, da die Anzahl an Repositories begrenzt ist. repo_name=Repository-Name repo_name_helper=Ein guter Repository-Name besteht normalerweise aus kurzen, unvergesslichen und einzigartigen Schlagwörtern. repo_size=Repository Größe @@ -734,6 +740,8 @@ archive.title=Dieses Repo ist archiviert. Du kannst Dateien sehen und es klonen, archive.issue.nocomment=Dieses Repo ist archiviert. Du kannst Issues nicht kommentieren. archive.pull.nocomment=Dieses Repo ist archiviert. Du kannst Pull-Requests nicht kommentieren. +form.reach_limit_of_creation_1=Du hast bereits dein Limit von %d Repository erreicht. +form.reach_limit_of_creation_n=Du hast bereits dein Limit von %d Repositories erreicht. form.name_reserved=Der Repository-Name „%s“ ist reserviert. form.name_pattern_not_allowed='%s' ist nicht erlaubt für Repository-Namen. @@ -818,6 +826,7 @@ tag=Tag released_this=hat released file_raw=Originalformat file_history=Verlauf +file_view_source=Quelltext anzeigen file_view_raw=Originalformat anzeigen file_permalink=Permalink file_too_large=Die Datei ist zu groß zum Anzeigen. @@ -914,6 +923,8 @@ ext_issues=Externe Issues ext_issues.desc=Link zu externem Issuetracker. projects=Projekte +projects.description=Beschreibung (optional) +projects.description_placeholder=Beschreibung projects.create=Projekt erstellen projects.title=Titel projects.new=Neues Projekt @@ -989,11 +1000,16 @@ issues.label_templates.info=Es existieren noch keine Label. Erstelle ein neues L issues.label_templates.helper=Wähle ein Label-Set issues.label_templates.use=Label-Set verwenden issues.label_templates.fail_to_load_file=Fehler beim Laden der Label-Vorlagendatei „%s“: %v +issues.add_label=hat das Label %s %s hinzugefügt +issues.add_labels=hat die Labels %s %s hinzugefügt +issues.remove_label=hat das Label %s %s entfernt +issues.remove_labels=hat die Labels %s %s entfernt +issues.add_remove_labels=hat %s hinzugefügt, und %s %s enternt issues.add_milestone_at=`hat diesen Issue %[2]s zum %[1]s Meilenstein hinzugefügt` issues.add_project_at=`hat dieses zum %s projekt %s hinzugefügt` issues.change_milestone_at=`hat den Meilenstein %[3]s von %[1]s zu %[2]s geändert` issues.change_project_at=`hat das Projekt %[3]s von %[1]s zu %[2]s geändert` -issues.remove_milestone_at=`hat diesen Issue %[2]s vom %[1]s Meilenstein entfernt` +issues.remove_milestone_at=`hat dieses Issue %[2]s vom %[1]s Meilenstein entfernt` issues.remove_project_at=`hat dieses vom %s Projekt %s entfernt` issues.deleted_milestone=`(gelöscht)` issues.deleted_project=`(gelöscht)` @@ -1053,6 +1069,7 @@ issues.commented_at=`hat %s kommentiert` issues.delete_comment_confirm=Bist du sicher dass du diesen Kommentar löschen möchtest? issues.context.copy_link=Link kopieren issues.context.quote_reply=Antwort zitieren +issues.context.reference_issue=In neuem Issue referenzieren issues.context.edit=Bearbeiten issues.context.delete=Löschen issues.no_content=Hier gibt es bis jetzt noch keinen Inhalt. @@ -1123,10 +1140,12 @@ issues.lock.title=Diskussion zu diesem Issue sperren. issues.unlock.title=Diskussion zu diesem Issue entsperren. issues.comment_on_locked=Du kannst einen gesperrten Issue nicht kommentieren. issues.tracker=Zeiterfassung +issues.start_tracking_short=Zeiterfassung starten issues.start_tracking=Zeiterfassung starten issues.start_tracking_history=hat die Zeiterfassung %s gestartet issues.tracker_auto_close=Der Timer wird automatisch gestoppt, wenn dieser Issue geschlossen wird issues.tracking_already_started=`Du hast die Zeiterfassung bereits in diesem Issue gestartet!` +issues.stop_tracking=Zeiterfassung stoppen issues.stop_tracking_history=hat die Zeiterfassung %s angehalten issues.cancel_tracking=Verwerfen issues.cancel_tracking_history=hat die Zeiterfassung %s abgebrochen @@ -1213,7 +1232,7 @@ issues.reference_issue.body=Beschreibung pulls.desc=Pull-Requests und Code-Reviews aktivieren. pulls.new=Neuer Pull-Request pulls.compare_changes=Neuer Pull-Request -pulls.compare_changes_desc=Wähle die Ziel- und Quellbranch aus. +pulls.compare_changes_desc=Wähle den Ziel- und Quellbranch aus. pulls.compare_base=Ziel pulls.compare_compare=pullen von pulls.filter_branch=Branch filtern @@ -1221,19 +1240,19 @@ pulls.no_results=Keine Ergebnisse verfügbar. pulls.nothing_to_compare=Diese Branches sind identisch. Es muss kein Pull-Request erstellt werden. pulls.has_pull_request=`Es existiert bereits ein Pull-Request zwischen diesen beiden Branches: %[2]s#%[3]d` pulls.create=Pull-Request erstellen -pulls.title_desc=möchte %[1]d Commits von %[2]s nach %[3]s zusammenführen +pulls.title_desc=möchte %[1]d Commits von %[2]s nach %[3]s mergen pulls.merged_title_desc=hat %[1]d Commits von %[2]s nach %[3]s %[4]s zusammengeführt pulls.change_target_branch_at=`hat den Zielbranch von %s nach %s %s geändert` pulls.tab_conversation=Diskussion pulls.tab_commits=Commits pulls.tab_files=Geänderte Dateien -pulls.reopen_to_merge=Bitte diesen Pull-Request wieder öffnen, um die Merge-Operation auszuführen. +pulls.reopen_to_merge=Bitte diesen Pull-Request wieder öffnen, um zu mergen. pulls.cant_reopen_deleted_branch=Dieser Pull-Request kann nicht wieder geöffnet werden, da die Branche bereits gelöscht wurde. pulls.merged=Zusammengeführt -pulls.merged_as=Der Pull Request wurde als %[2]s zusammengeführt. +pulls.merged_as=Der Pull Request wurde als %[2]s gemergt. pulls.is_closed=Der Pull-Request wurde geschlossen. -pulls.has_merged=Der Pull-Request wurde zusammengeführt. -pulls.title_wip_desc=`Beginne den Titel mit %s um zu verhindern, dass der Pull Request versehentlich zusammengeführt wird.` +pulls.has_merged=Der Pull-Request wurde gemergt. +pulls.title_wip_desc=`Beginne den Titel mit %s um zu verhindern, dass der Pull Request versehentlich gemergt wird.` pulls.cannot_merge_work_in_progress=Dieser Pull Request wurde als Work In Progress markiert. Entferne den %s-Präfix vom Titel, wenn dieser fertig ist. pulls.data_broken=Dieser Pull-Requests ist kaputt, da Fork-Informationen gelöscht wurden. pulls.files_conflicted=Dieser Pull-Request hat Änderungen, die im Widerspruch zum Ziel-Branch stehen. @@ -1247,9 +1266,9 @@ pulls.blocked_by_official_review_requests=Dieser Pull Request hat offizielle Rev pulls.blocked_by_outdated_branch=Dieser Pull Request ist blockiert, da er veraltet ist. pulls.blocked_by_changed_protected_files_1=Diese Pull Request ist blockiert, weil er eine geschützte Datei ändert: pulls.blocked_by_changed_protected_files_n=Dieser Pull Request ist blockiert, weil er geschützte Dateien ändert: -pulls.can_auto_merge_desc=Dieser Pull-Request kann automatisch zusammengeführt werden. -pulls.cannot_auto_merge_desc=Dieser Pull-Request kann nicht automatisch zusammengeführt werden, da es Konflikte gibt. -pulls.cannot_auto_merge_helper=Bitte manuell zusammenführen, um die Konflikte zu lösen. +pulls.can_auto_merge_desc=Dieser Pull-Request kann automatisch gemergt werden. +pulls.cannot_auto_merge_desc=Dieser Pull-Request kann nicht automatisch gemergt werden, da es Konflikte gibt. +pulls.cannot_auto_merge_helper=Bitte manuell mergen, um die Konflikte zu beheben. pulls.num_conflicting_files_1=%d Datei mit Konflikten pulls.num_conflicting_files_n=%d Dateien mit Konflikten pulls.approve_count_1=%d Zustimmung @@ -1261,14 +1280,14 @@ pulls.waiting_count_n=%d wartende Reviews pulls.no_merge_desc=Dieser Pull-Request kann nicht gemerged werden, da keine Mergeoptionen aktiviert sind. pulls.no_merge_helper=Aktiviere Mergeoptionen in den Repositoryeinstellungen oder merge den Pull-Request manuell. -pulls.no_merge_wip=Dieser Pull Request kann nicht zusammengeführt werden, da er als Work In Progress gekennzeichnet ist. -pulls.no_merge_not_ready=Dieser Pull-Request kann nicht zusammengeführt werden, überprüfe den Reviewstatus und die Statusprüfungen. +pulls.no_merge_wip=Dieser Pull Request kann nicht gemergt werden, da er als Work In Progress gekennzeichnet ist. +pulls.no_merge_not_ready=Dieser Pull-Request kann nicht gemergt werden, überprüfe den Reviewstatus und die Statusprüfungen. pulls.no_merge_access=Du bist nicht berechtigt, diesen Pull-Request zu Mergen. -pulls.merge_pull_request=Pull-Request zusammenführen +pulls.merge_pull_request=Pull-Request mergen pulls.rebase_merge_pull_request=Rebase und Mergen pulls.rebase_merge_commit_pull_request=Rebasen und Mergen (--no-ff) pulls.squash_merge_pull_request=Zusammenfassen und Mergen -pulls.require_signed_wont_sign=Die Branch erfordert einen signierten Commit, aber dieser Merge wird nicht signiert +pulls.require_signed_wont_sign=Der Branch erfordert einen signierten Commit, aber dieser Merge wird nicht signiert pulls.invalid_merge_option=Du kannst diese Mergeoption auf diesen Pull-Request nicht anwenden. pulls.merge_conflict=Zusammenführen fehlgeschlagen: Beim Zusammenführen gab es einen Konflikt. Hinweis: Probiere eine andere Strategie pulls.merge_conflict_summary=Fehlermeldung @@ -1519,6 +1538,8 @@ settings.trust_model.collaborator.long=Mitarbeiter: Vertraue Signaturen von Mita settings.trust_model.collaborator.desc=Gültige Signaturen von Mitarbeitern dieses Projekts werden als "vertrauenswürdig" markiert - ( egal ob sie mit dem Committer übereinstimmen oder nicht). Andernfalls werden gültige Signaturen als "nicht vertrauenswürdig" markiert, unabhängig ob die Signatur mit dem Committer übereinstimmt oder nicht. settings.trust_model.committer=Committer settings.trust_model.committer.long=Committer: Vertraue Signaturen, die zu Committern passen (Dies stimmt mit GitHub überein und zwingt signierte Commits von Gitea dazu, Gitea als Committer zu haben) +settings.trust_model.committer.desc=Gültige Signaturen von Mitwirkenden werden als "vertrauenswürdig" gekennzeichnet, wenn sie mit ihrem Committer übereinstimmen. Ansonsten werden sie als "nicht übereinstimmend" markiert. Das führt dazu, dass Gitea auf signierten Commits, bei denen der echte Committer als Co-authored-by: oder Co-committed-by in der Beschreibung eingetragen wurde, als Committer gilt. +Der Standard Gitea Schlüssel muss auf einen User in der Datenbank zeigen. settings.trust_model.collaboratorcommitter=Mitarbeiter+Committer settings.trust_model.collaboratorcommitter.long=Mitarbeiter+Committer: Signaturen der Mitarbeiter vertrauen die mit dem Committer übereinstimmen settings.trust_model.collaboratorcommitter.desc=Gültige Signaturen von Mitarbeitern dieses Projekts werden als "vertrauenswürdig" markiert, wenn sie mit dem Committer übereinstimmen. Andernfalls werden gültige Signaturen als "nicht vertrauenswürdig" markiert, wenn die Signatur mit dem Committer übereinstimmt als "nicht übereinstimmend". Dies zwingt Gitea als Committer bei signierten Commits mit dem tatsächlichen Committer als Co-Authored-By: und Co-Committed-By: Trailer im Commit. Der Standard-Gitea-Schlüssel muss mit einem Benutzer in der Datenbank übereinstimmen. @@ -1688,7 +1709,7 @@ settings.protect_merge_whitelist_committers_desc=Erlaube Nutzern oder Teams auf settings.protect_merge_whitelist_users=Nutzer, die mergen dürfen: settings.protect_merge_whitelist_teams=Teams, die mergen dürfen: settings.protect_check_status_contexts=Statusprüfungen aktivieren -settings.protect_check_status_contexts_desc=Statusprüfungen vor dem Zusammenführen erforderlich. Wähle aus, welche Statusprüfungen erfolgreich durchgeführt werden müssen, bevor Branches in einen anderen zusammengeführt werden können, der dieser Regel entspricht. Wenn aktiviert, müssen Commits zuerst auf einen anderen Branch gepusht werden, dann nach bestandener Statusprüfung zusammengeführt oder direkt auf den Branch gepusht werden, der dieser Regel entspricht. Wenn keine Kontext ausgewählt ist, muss der letzte Commit unabhängig vom Kontext erfolgreich sein. +settings.protect_check_status_contexts_desc=Vor dem Mergen müssen Statusprüfungen bestanden werden. Wähle aus, welche Statusprüfungen erfolgreich durchgeführt werden müssen, bevor Branches in einen anderen gemergt werden können, der dieser Regel entspricht. Wenn aktiviert, müssen Commits zuerst auf einen anderen Branch gepusht werden, dann nach bestandener Statusprüfung gemergt oder direkt auf einen Branch gepusht werden, der dieser Regel entspricht. Wenn kein Kontext ausgewählt ist, muss der letzte Commit unabhängig vom Kontext erfolgreich sein. settings.protect_check_status_contexts_list=Statusprüfungen, die in der letzten Woche für dieses Repository gefunden wurden settings.protect_required_approvals=Erforderliche Zustimmungen: settings.protect_required_approvals_desc=Erlaube nur Pull-Request mit genügend positiven Reviews zusammenzuführen. @@ -1713,7 +1734,7 @@ settings.block_rejected_reviews_desc=Mergen ist nicht möglich, wenn Änderungen settings.block_on_official_review_requests=Mergen bei offiziellen Review-Anfragen blockieren settings.block_on_official_review_requests_desc=Zusammenführung wird nicht möglich sein, wenn offizielle Review-Anfrangen vorliegen, selbst wenn genügend Genehmigungen vorliegen. settings.block_outdated_branch=Merge blockieren, wenn der Pull-Request veraltet ist -settings.block_outdated_branch_desc=Die Zusammenführung ist nicht möglich, wenn die Head-Branch hinter der Basis-Branch ist. +settings.block_outdated_branch_desc=Mergen ist nicht möglich, wenn der Head-Branch hinter dem Basis-Branch ist. settings.default_branch_desc=Wähle einen Standardbranch für Pull-Requests und Code-Commits: settings.choose_branch=Wähle einen Branch … settings.no_protected_branch=Es gibt keine geschützten Branches. @@ -2139,8 +2160,12 @@ repos.forks=Forks repos.issues=Issues repos.size=Größe +defaulthooks=Standard-Webhooks +defaulthooks.add_webhook=Standard-Webhook hinzufügen +defaulthooks.update_webhook=Standard-Webhook aktualisieren systemhooks=System-Webhooks +systemhooks.desc=Webhooks senden automatisch HTTP-POST Anfragen an einen Server, wenn bestimmte Gitea Events getriggered werden. Hier definierte Webhooks werden auf alle Repositories des Systems übertragen, beachte daher mögliche Performance-Einbrüche. Mehr Infos findest du in der Webhooks Anleitung (auf englisch). systemhooks.add_webhook=System-Webhook hinzufügen systemhooks.update_webhook=System-Webhook aktualisieren @@ -2469,7 +2494,7 @@ close_pull_request=`hat den Pull-Request %s#%[2]s gesc reopen_pull_request=`hat den Pull-Request %s#%[2]s wieder geöffnet` comment_issue=`hat das Issue %s#%[2]s kommentiert` comment_pull=`kommentierte im Pull Request %s#%[2]s` -merge_pull_request=`hat den Pull-Request %s#%[2]s zusammengeführt` +merge_pull_request=`hat den Pull-Request %s#%[2]s gemergt` transfer_repo=hat Repository %s transferiert an %s push_tag=hat Tag %[2]s auf %[3]s gepusht delete_tag=hat Tag %[2]s in %[3]s gelöscht diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index df71c8dae700b..8e48626327c34 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -624,6 +624,7 @@ or_enter_secret=またはシークレット文字列を入力: %s then_enter_passcode=次に、アプリケーションに表示されているパスコードを入力します。 passcode_invalid=パスコードが間違っています。 再度お試しください。 twofa_enrolled=あなたのアカウントに2要素認証が設定されました。 スクラッチトークン (%s) は一度しか表示しませんので安全な場所に保存してください! +twofa_failed_get_secret=シークレットが取得できません。 u2f_desc=セキュリティキーは暗号化キーを内蔵するハードウェア ・ デバイスで、2要素認証に使用できます。 セキュリティキーはFIDO U2F規格をサポートしている必要があります。 u2f_require_twofa=セキュリティキーを使用するには、アカウントに2要素認証を設定する必要があります。 @@ -645,6 +646,7 @@ repos_none=あなたはリポジトリを所有していません。 delete_account=アカウントを削除 delete_prompt=この操作により、あなたのユーザーアカウントは恒久的に抹消されます。 取り消すことはできません。 +delete_with_all_comments=あなたのアカウントは作成からまだ %s 経過していません。 幽霊コメント回避のため、課題やPRのすべてのコメントは一緒に削除されます。 confirm_delete_account=削除の続行 delete_account_title=ユーザーアカウントの削除 delete_account_desc=このユーザーアカウントを恒久的に削除してもよろしいですか? @@ -773,6 +775,7 @@ migrate.github.description=Github.com または Github Enterprise からデー migrate.git.description=Gitサービスからgitデータを移行またはミラーを作成します migrate.gitlab.description=GitLab.com またはセルフホストのgitlabサーバーからデータを移行します。 migrate.gitea.description=Gitea.comまたはセルフホストのGiteaサーバーからデータを移行します。 +migrate.gogs.description=notabug.org や、他のセルフホストのGogsサーバーからデータを移行します。 mirror_from=ミラー元 forked_from=フォーク元 @@ -1137,11 +1140,14 @@ issues.lock.title=この課題の会話をロックします。 issues.unlock.title=この課題の会話をアンロックします。 issues.comment_on_locked=ロックされている課題にコメントはできません。 issues.tracker=タイムトラッカー +issues.start_tracking_short=タイマー 開始 issues.start_tracking=タイムトラッキングを開始 issues.start_tracking_history=`が作業を開始 %s` issues.tracker_auto_close=タイマーは、この課題がクローズされると自動的に終了します issues.tracking_already_started=`別の課題で既にタイムトラッキングを開始しています!` +issues.stop_tracking=タイマー 終了 issues.stop_tracking_history=`が作業を終了 %s` +issues.cancel_tracking=中止 issues.cancel_tracking_history=`がタイムトラッキングを中止 %s` issues.add_time=手で時間を入力 issues.add_time_short=時間入力 @@ -1221,6 +1227,7 @@ issues.review.resolve_conversation=解決済みにする issues.review.un_resolve_conversation=未解決にする issues.review.resolved_by=がこの会話を解決済みにしました issues.assignee.error=予期しないエラーにより、一部の担当者を追加できませんでした。 +issues.reference_issue.body=内容 pulls.desc=プルリクエストとコードレビューの有効化。 pulls.new=新しいプルリクエスト From 6433ba0ec3dfde67f45267aa12bd713c4a44c740 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 26 Jan 2021 23:36:53 +0800 Subject: [PATCH 03/24] Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de> --- .golangci.yml | 2 +- cmd/dump.go | 2 +- cmd/web.go | 9 +- contrib/pr/checkout.go | 4 +- .../doc/advanced/config-cheat-sheet.en-us.md | 6 +- .../advanced/logging-documentation.en-us.md | 37 +- docs/content/page/index.en-us.md | 2 +- docs/content/page/index.fr-fr.md | 2 +- docs/content/page/index.zh-cn.md | 2 +- docs/content/page/index.zh-tw.md | 2 +- go.mod | 16 +- go.sum | 60 +- .../api_helper_for_declarative_test.go | 2 +- integrations/api_pull_test.go | 2 +- integrations/api_releases_test.go | 8 +- integrations/create_no_session_test.go | 10 +- integrations/integration_test.go | 11 +- integrations/lfs_getobject_test.go | 8 +- integrations/links_test.go | 3 +- modules/auth/sso/interface.go | 12 +- modules/auth/sso/oauth2.go | 2 + modules/cache/cache.go | 6 +- modules/cache/cache_redis.go | 2 +- modules/context/api.go | 141 ++- modules/context/auth.go | 129 ++- modules/context/captcha.go | 26 + modules/context/context.go | 559 ++++++++--- .../macaron/csrf => modules/context}/csrf.go | 144 ++- modules/context/form.go | 227 +++++ modules/context/org.go | 4 +- modules/context/permission.go | 12 +- modules/context/private.go | 45 + modules/context/repo.go | 570 +++++------ modules/context/response.go | 29 +- modules/context/secret.go | 100 ++ .../macaron/csrf => modules/context}/xsrf.go | 13 +- modules/context/xsrf_test.go | 90 ++ modules/{auth => forms}/admin.go | 25 +- modules/{auth => forms}/auth_form.go | 15 +- modules/{auth => forms}/org.go | 24 +- modules/{auth => forms}/repo_branch_form.go | 15 +- modules/{auth => forms}/repo_form.go | 173 ++-- modules/{auth => forms}/repo_form_test.go | 2 +- modules/{auth => forms}/user_form.go | 108 +- .../{auth => forms}/user_form_auth_openid.go | 24 +- modules/{auth => forms}/user_form_test.go | 2 +- modules/lfs/locks.go | 4 +- modules/lfs/server.go | 13 +- .../{auth/auth.go => middlewares/binding.go} | 16 +- modules/middlewares/cookie.go | 61 ++ modules/middlewares/data.go | 10 + modules/middlewares/flash.go | 65 ++ modules/middlewares/locale.go | 8 +- modules/middlewares/redis.go | 217 ---- modules/middlewares/virtual.go | 196 ---- modules/session/redis.go | 2 +- modules/session/store.go | 12 + modules/session/virtual.go | 13 +- modules/setting/log.go | 12 - modules/setting/session.go | 2 +- modules/templates/base.go | 14 + modules/templates/dynamic.go | 25 - modules/templates/static.go | 112 --- modules/test/context_tests.go | 109 +- modules/timeutil/since_test.go | 12 +- modules/translation/translation.go | 49 +- modules/validation/binding.go | 2 +- modules/validation/binding_test.go | 11 +- modules/validation/glob_pattern_test.go | 2 +- modules/validation/refname_test.go | 2 +- modules/validation/validurl_test.go | 2 +- modules/web/route.go | 322 ++++++ modules/web/route_test.go | 169 ++++ options/locale/locale_de-DE.ini | 3 +- routers/admin/admin.go | 11 +- routers/admin/auths.go | 9 +- routers/admin/users.go | 9 +- routers/admin/users_test.go | 12 +- routers/api/v1/admin/org.go | 5 +- routers/api/v1/admin/repo.go | 7 +- routers/api/v1/admin/user.go | 15 +- routers/api/v1/api.go | 245 +++-- routers/api/v1/misc/markdown.go | 8 +- routers/api/v1/misc/markdown_test.go | 34 +- routers/api/v1/org/hook.go | 14 +- routers/api/v1/org/label.go | 9 +- routers/api/v1/org/org.go | 9 +- routers/api/v1/org/team.go | 9 +- routers/api/v1/repo/branch.go | 11 +- routers/api/v1/repo/collaborators.go | 5 +- routers/api/v1/repo/commits.go | 6 +- routers/api/v1/repo/file.go | 11 +- routers/api/v1/repo/fork.go | 4 +- routers/api/v1/repo/git_hook.go | 4 +- routers/api/v1/repo/hook.go | 14 +- routers/api/v1/repo/issue.go | 12 +- routers/api/v1/repo/issue_comment.go | 15 +- routers/api/v1/repo/issue_label.go | 12 +- routers/api/v1/repo/issue_reaction.go | 25 +- routers/api/v1/repo/issue_tracked_time.go | 5 +- routers/api/v1/repo/key.go | 4 +- routers/api/v1/repo/label.go | 7 +- routers/api/v1/repo/migrate.go | 7 +- routers/api/v1/repo/milestone.go | 8 +- routers/api/v1/repo/pull.go | 14 +- routers/api/v1/repo/pull_review.go | 18 +- routers/api/v1/repo/release.go | 8 +- routers/api/v1/repo/release_attachment.go | 7 +- routers/api/v1/repo/repo.go | 21 +- routers/api/v1/repo/repo_test.go | 9 +- routers/api/v1/repo/status.go | 4 +- routers/api/v1/repo/topic.go | 4 +- routers/api/v1/repo/transfer.go | 5 +- routers/api/v1/swagger/options.go | 2 +- routers/api/v1/user/app.go | 14 +- routers/api/v1/user/email.go | 9 +- routers/api/v1/user/gpg_key.go | 6 +- routers/api/v1/user/key.go | 6 +- routers/init.go | 10 +- routers/install.go | 54 +- routers/org/org.go | 6 +- routers/org/org_labels.go | 12 +- routers/org/setting.go | 9 +- routers/org/teams.go | 9 +- routers/private/hook.go | 12 +- routers/private/internal.go | 82 +- routers/private/key.go | 7 +- routers/private/mail.go | 8 +- routers/private/manager.go | 20 +- routers/private/manager_unix.go | 7 +- routers/private/manager_windows.go | 7 +- routers/private/serv.go | 7 +- routers/repo/branch.go | 6 +- routers/repo/editor.go | 25 +- routers/repo/http.go | 178 ++-- routers/repo/issue.go | 17 +- routers/repo/issue_label.go | 12 +- routers/repo/issue_label_test.go | 12 +- routers/repo/issue_lock.go | 7 +- routers/repo/issue_timetrack.go | 6 +- routers/repo/migrate.go | 10 +- routers/repo/milestone.go | 9 +- routers/repo/projects.go | 17 +- routers/repo/pull.go | 17 +- routers/repo/pull_review.go | 9 +- routers/repo/release.go | 9 +- routers/repo/release_test.go | 6 +- routers/repo/repo.go | 6 +- routers/repo/setting.go | 14 +- routers/repo/setting_protected_branch.go | 6 +- routers/repo/settings_test.go | 9 +- routers/repo/webhook.go | 59 +- routers/repo/wiki.go | 9 +- routers/repo/wiki_test.go | 12 +- routers/routes/{chi.go => base.go} | 203 ++-- routers/routes/{recovery.go => install.go} | 101 +- routers/routes/{macaron.go => web.go} | 569 ++++++----- routers/swagger_json.go | 8 +- routers/user/auth.go | 44 +- routers/user/auth_openid.go | 21 +- routers/user/oauth.go | 16 +- routers/user/setting/account.go | 13 +- routers/user/setting/account_test.go | 6 +- routers/user/setting/applications.go | 6 +- routers/user/setting/keys.go | 6 +- routers/user/setting/oauth2.go | 9 +- routers/user/setting/profile.go | 11 +- routers/user/setting/security_openid.go | 10 +- routers/user/setting/security_twofa.go | 6 +- routers/user/setting/security_u2f.go | 14 +- templates/admin/config.tmpl | 17 - templates/repo/sub_menu.tmpl | 2 +- templates/swagger/v1_json.tmpl | 4 +- .../{macaron => go-chi}/binding/.drone.yml | 0 .../{macaron => go-chi}/binding/.gitignore | 0 .../{macaron => go-chi}/binding/LICENSE | 0 vendor/gitea.com/go-chi/binding/README.md | 5 + .../{macaron => go-chi}/binding/binding.go | 250 ++--- .../{macaron => go-chi}/binding/errors.go | 0 .../{macaron => go-chi}/binding/go.mod | 6 +- .../toolbox => go-chi/binding}/go.sum | 12 +- .../{macaron => go-chi}/cache/.drone.yml | 0 .../{macaron => go-chi}/cache/.gitignore | 0 .../{macaron => go-chi}/cache/LICENSE | 0 .../{macaron => go-chi}/cache/README.md | 0 .../{macaron => go-chi}/cache/cache.go | 42 +- .../{macaron => go-chi}/cache/file.go | 3 +- .../{macaron => go-chi}/cache/go.mod | 3 +- .../{macaron => go-chi}/cache/go.sum | 7 - .../cache/memcache/memcache.go | 2 +- .../cache/memcache/memcache.goconvey | 0 .../{macaron => go-chi}/cache/memory.go | 0 .../{macaron => go-chi}/cache/utils.go | 0 .../{macaron => go-chi}/captcha/.drone.yml | 0 .../{macaron => go-chi}/captcha/LICENSE | 0 .../{macaron => go-chi}/captcha/README.md | 0 .../{macaron => go-chi}/captcha/captcha.go | 89 +- .../toolbox => go-chi/captcha}/go.mod | 5 +- .../{macaron => go-chi}/captcha/go.sum | 17 +- .../{macaron => go-chi}/captcha/image.go | 0 .../{macaron => go-chi}/captcha/siprng.go | 0 vendor/gitea.com/lunny/log/.gitignore | 26 - vendor/gitea.com/lunny/log/LICENSE | 27 - vendor/gitea.com/lunny/log/README.md | 51 - vendor/gitea.com/lunny/log/README_CN.md | 54 - vendor/gitea.com/lunny/log/dbwriter.go | 36 - vendor/gitea.com/lunny/log/filewriter.go | 112 --- vendor/gitea.com/lunny/log/go.mod | 5 - vendor/gitea.com/lunny/log/go.sum | 2 - vendor/gitea.com/lunny/log/logext.go | 595 ----------- vendor/gitea.com/lunny/nodb/.gitignore | 7 - vendor/gitea.com/lunny/nodb/LICENSE | 21 - vendor/gitea.com/lunny/nodb/README.md | 83 -- vendor/gitea.com/lunny/nodb/README_CN.md | 80 -- vendor/gitea.com/lunny/nodb/batch.go | 106 -- vendor/gitea.com/lunny/nodb/binlog.go | 391 -------- vendor/gitea.com/lunny/nodb/binlog_util.go | 215 ---- vendor/gitea.com/lunny/nodb/config/config.go | 135 --- .../gitea.com/lunny/nodb/config/config.toml | 45 - vendor/gitea.com/lunny/nodb/const.go | 98 -- vendor/gitea.com/lunny/nodb/doc.go | 61 -- vendor/gitea.com/lunny/nodb/dump.go | 200 ---- vendor/gitea.com/lunny/nodb/go.mod | 11 - vendor/gitea.com/lunny/nodb/go.sum | 42 - vendor/gitea.com/lunny/nodb/info.go | 24 - vendor/gitea.com/lunny/nodb/multi.go | 73 -- vendor/gitea.com/lunny/nodb/nodb.go | 128 --- vendor/gitea.com/lunny/nodb/nodb_db.go | 171 ---- vendor/gitea.com/lunny/nodb/replication.go | 312 ------ vendor/gitea.com/lunny/nodb/scan.go | 144 --- vendor/gitea.com/lunny/nodb/store/db.go | 61 -- .../lunny/nodb/store/driver/batch.go | 39 - .../lunny/nodb/store/driver/driver.go | 67 -- .../lunny/nodb/store/driver/store.go | 46 - .../lunny/nodb/store/goleveldb/batch.go | 27 - .../lunny/nodb/store/goleveldb/const.go | 4 - .../lunny/nodb/store/goleveldb/db.go | 187 ---- .../lunny/nodb/store/goleveldb/iterator.go | 49 - .../lunny/nodb/store/goleveldb/snapshot.go | 26 - vendor/gitea.com/lunny/nodb/store/iterator.go | 327 ------ vendor/gitea.com/lunny/nodb/store/snapshot.go | 16 - vendor/gitea.com/lunny/nodb/store/store.go | 51 - vendor/gitea.com/lunny/nodb/store/tx.go | 42 - .../gitea.com/lunny/nodb/store/writebatch.go | 9 - vendor/gitea.com/lunny/nodb/t_bit.go | 922 ----------------- vendor/gitea.com/lunny/nodb/t_hash.go | 509 ---------- vendor/gitea.com/lunny/nodb/t_kv.go | 387 ------- vendor/gitea.com/lunny/nodb/t_list.go | 492 --------- vendor/gitea.com/lunny/nodb/t_set.go | 601 ----------- vendor/gitea.com/lunny/nodb/t_ttl.go | 195 ---- vendor/gitea.com/lunny/nodb/t_zset.go | 943 ------------------ vendor/gitea.com/lunny/nodb/tx.go | 113 --- vendor/gitea.com/lunny/nodb/util.go | 113 --- vendor/gitea.com/macaron/binding/README.md | 20 - vendor/gitea.com/macaron/binding/go.sum | 30 - vendor/gitea.com/macaron/captcha/go.mod | 10 - vendor/gitea.com/macaron/cors/.drone.yml | 9 - vendor/gitea.com/macaron/cors/.gitignore | 12 - vendor/gitea.com/macaron/cors/README.md | 5 - vendor/gitea.com/macaron/cors/cors.go | 169 ---- vendor/gitea.com/macaron/cors/go.mod | 5 - vendor/gitea.com/macaron/cors/go.sum | 31 - vendor/gitea.com/macaron/csrf/.drone.yml | 24 - vendor/gitea.com/macaron/csrf/LICENSE | 191 ---- vendor/gitea.com/macaron/csrf/README.md | 18 - vendor/gitea.com/macaron/csrf/go.mod | 12 - vendor/gitea.com/macaron/csrf/go.sum | 83 -- vendor/gitea.com/macaron/gzip/.drone.yml | 24 - vendor/gitea.com/macaron/gzip/README.md | 19 - vendor/gitea.com/macaron/gzip/go.mod | 11 - vendor/gitea.com/macaron/gzip/go.sum | 48 - vendor/gitea.com/macaron/gzip/gzip.go | 368 ------- vendor/gitea.com/macaron/i18n/.drone.yml | 24 - vendor/gitea.com/macaron/i18n/.gitignore | 1 - vendor/gitea.com/macaron/i18n/LICENSE | 191 ---- vendor/gitea.com/macaron/i18n/README.md | 16 - vendor/gitea.com/macaron/i18n/go.mod | 10 - vendor/gitea.com/macaron/i18n/go.sum | 52 - vendor/gitea.com/macaron/i18n/i18n.go | 242 ----- vendor/gitea.com/macaron/inject/.drone.yml | 20 - vendor/gitea.com/macaron/inject/LICENSE | 191 ---- vendor/gitea.com/macaron/inject/README.md | 11 - vendor/gitea.com/macaron/inject/go.mod | 5 - vendor/gitea.com/macaron/inject/go.sum | 13 - vendor/gitea.com/macaron/inject/inject.go | 262 ----- vendor/gitea.com/macaron/macaron/.drone.yml | 12 - vendor/gitea.com/macaron/macaron/.gitignore | 3 - vendor/gitea.com/macaron/macaron/LICENSE | 191 ---- vendor/gitea.com/macaron/macaron/README.md | 97 -- vendor/gitea.com/macaron/macaron/context.go | 563 ----------- vendor/gitea.com/macaron/macaron/go.mod | 12 - vendor/gitea.com/macaron/macaron/go.sum | 31 - vendor/gitea.com/macaron/macaron/logger.go | 73 -- vendor/gitea.com/macaron/macaron/macaron.go | 327 ------ .../gitea.com/macaron/macaron/macaronlogo.png | Bin 88924 -> 0 bytes vendor/gitea.com/macaron/macaron/recovery.go | 163 --- vendor/gitea.com/macaron/macaron/render.go | 724 -------------- .../macaron/macaron/response_writer.go | 124 --- .../macaron/macaron/return_handler.go | 76 -- vendor/gitea.com/macaron/macaron/router.go | 380 ------- vendor/gitea.com/macaron/macaron/static.go | 231 ----- vendor/gitea.com/macaron/macaron/tree.go | 390 -------- vendor/gitea.com/macaron/macaron/util_go17.go | 25 - vendor/gitea.com/macaron/macaron/util_go18.go | 24 - vendor/gitea.com/macaron/session/.drone.yml | 11 - vendor/gitea.com/macaron/session/.gitignore | 4 - vendor/gitea.com/macaron/session/LICENSE | 191 ---- vendor/gitea.com/macaron/session/README.md | 22 - .../macaron/session/couchbase/couchbase.go | 227 ----- vendor/gitea.com/macaron/session/file.go | 274 ----- vendor/gitea.com/macaron/session/flash.go | 61 -- vendor/gitea.com/macaron/session/go.mod | 30 - vendor/gitea.com/macaron/session/go.sum | 118 --- .../macaron/session/memcache/memcache.go | 203 ---- .../session/memcache/memcache.goconvey | 1 - vendor/gitea.com/macaron/session/memory.go | 223 ----- .../gitea.com/macaron/session/mysql/mysql.go | 201 ---- .../macaron/session/mysql/mysql.goconvey | 1 - vendor/gitea.com/macaron/session/nodb/nodb.go | 207 ---- .../macaron/session/nodb/nodb.goconvey | 1 - .../macaron/session/postgres/postgres.go | 202 ---- .../session/postgres/postgres.goconvey | 1 - vendor/gitea.com/macaron/session/session.go | 393 -------- vendor/gitea.com/macaron/session/utils.go | 63 -- vendor/gitea.com/macaron/toolbox/.drone.yml | 9 - vendor/gitea.com/macaron/toolbox/.gitignore | 2 - vendor/gitea.com/macaron/toolbox/LICENSE | 191 ---- vendor/gitea.com/macaron/toolbox/README.md | 112 --- .../gitea.com/macaron/toolbox/healthcheck.go | 83 -- vendor/gitea.com/macaron/toolbox/profile.go | 163 --- vendor/gitea.com/macaron/toolbox/statistic.go | 138 --- vendor/gitea.com/macaron/toolbox/toolbox.go | 158 --- .../github.com/NYTimes/gziphandler/.gitignore | 1 + .../NYTimes/gziphandler/.travis.yml | 10 + .../NYTimes/gziphandler/CODE_OF_CONDUCT.md | 75 ++ .../NYTimes/gziphandler/CONTRIBUTING.md | 30 + .../NYTimes/gziphandler}/LICENSE | 2 +- .../github.com/NYTimes/gziphandler/README.md | 56 ++ vendor/github.com/NYTimes/gziphandler/go.mod | 5 + vendor/github.com/NYTimes/gziphandler/go.sum | 7 + vendor/github.com/NYTimes/gziphandler/gzip.go | 532 ++++++++++ .../NYTimes/gziphandler/gzip_go18.go | 43 + vendor/github.com/go-chi/cors/LICENSE | 21 + vendor/github.com/go-chi/cors/README.md | 39 + vendor/github.com/go-chi/cors/cors.go | 400 ++++++++ vendor/github.com/go-chi/cors/utils.go | 70 ++ .../github.com/siddontang/go-snappy/AUTHORS | 12 - .../siddontang/go-snappy/CONTRIBUTORS | 34 - .../github.com/siddontang/go-snappy/LICENSE | 27 - .../siddontang/go-snappy/snappy/decode.go | 124 --- .../siddontang/go-snappy/snappy/encode.go | 174 ---- .../siddontang/go-snappy/snappy/snappy.go | 38 - vendor/modules.txt | 65 +- 353 files changed, 5412 insertions(+), 20734 deletions(-) create mode 100644 modules/context/captcha.go rename {vendor/gitea.com/macaron/csrf => modules/context}/csrf.go (69%) create mode 100644 modules/context/form.go create mode 100644 modules/context/private.go create mode 100644 modules/context/secret.go rename {vendor/gitea.com/macaron/csrf => modules/context}/xsrf.go (90%) create mode 100644 modules/context/xsrf_test.go rename modules/{auth => forms}/admin.go (70%) rename modules/{auth => forms}/auth_form.go (87%) rename modules/{auth => forms}/org.go (76%) rename modules/{auth => forms}/repo_branch_form.go (52%) rename modules/{auth => forms}/repo_form.go (78%) rename modules/{auth => forms}/repo_form_test.go (99%) rename modules/{auth => forms}/user_form.go (71%) rename modules/{auth => forms}/user_form_auth_openid.go (58%) rename modules/{auth => forms}/user_form_test.go (98%) rename modules/{auth/auth.go => middlewares/binding.go} (92%) create mode 100644 modules/middlewares/data.go create mode 100644 modules/middlewares/flash.go delete mode 100644 modules/middlewares/redis.go delete mode 100644 modules/middlewares/virtual.go create mode 100644 modules/session/store.go create mode 100644 modules/web/route.go create mode 100644 modules/web/route_test.go rename routers/routes/{chi.go => base.go} (53%) rename routers/routes/{recovery.go => install.go} (50%) rename routers/routes/{macaron.go => web.go} (70%) rename vendor/gitea.com/{macaron => go-chi}/binding/.drone.yml (100%) rename vendor/gitea.com/{macaron => go-chi}/binding/.gitignore (100%) rename vendor/gitea.com/{macaron => go-chi}/binding/LICENSE (100%) create mode 100644 vendor/gitea.com/go-chi/binding/README.md rename vendor/gitea.com/{macaron => go-chi}/binding/binding.go (80%) rename vendor/gitea.com/{macaron => go-chi}/binding/errors.go (100%) rename vendor/gitea.com/{macaron => go-chi}/binding/go.mod (57%) rename vendor/gitea.com/{macaron/toolbox => go-chi/binding}/go.sum (68%) rename vendor/gitea.com/{macaron => go-chi}/cache/.drone.yml (100%) rename vendor/gitea.com/{macaron => go-chi}/cache/.gitignore (100%) rename vendor/gitea.com/{macaron => go-chi}/cache/LICENSE (100%) rename vendor/gitea.com/{macaron => go-chi}/cache/README.md (100%) rename vendor/gitea.com/{macaron => go-chi}/cache/cache.go (74%) rename vendor/gitea.com/{macaron => go-chi}/cache/file.go (98%) rename vendor/gitea.com/{macaron => go-chi}/cache/go.mod (93%) rename vendor/gitea.com/{macaron => go-chi}/cache/go.sum (93%) rename vendor/gitea.com/{macaron => go-chi}/cache/memcache/memcache.go (98%) rename vendor/gitea.com/{macaron => go-chi}/cache/memcache/memcache.goconvey (100%) rename vendor/gitea.com/{macaron => go-chi}/cache/memory.go (100%) rename vendor/gitea.com/{macaron => go-chi}/cache/utils.go (100%) rename vendor/gitea.com/{macaron => go-chi}/captcha/.drone.yml (100%) rename vendor/gitea.com/{macaron => go-chi}/captcha/LICENSE (100%) rename vendor/gitea.com/{macaron => go-chi}/captcha/README.md (100%) rename vendor/gitea.com/{macaron => go-chi}/captcha/captcha.go (77%) rename vendor/gitea.com/{macaron/toolbox => go-chi/captcha}/go.mod (55%) rename vendor/gitea.com/{macaron => go-chi}/captcha/go.sum (85%) rename vendor/gitea.com/{macaron => go-chi}/captcha/image.go (100%) rename vendor/gitea.com/{macaron => go-chi}/captcha/siprng.go (100%) delete mode 100644 vendor/gitea.com/lunny/log/.gitignore delete mode 100644 vendor/gitea.com/lunny/log/LICENSE delete mode 100644 vendor/gitea.com/lunny/log/README.md delete mode 100644 vendor/gitea.com/lunny/log/README_CN.md delete mode 100644 vendor/gitea.com/lunny/log/dbwriter.go delete mode 100644 vendor/gitea.com/lunny/log/filewriter.go delete mode 100644 vendor/gitea.com/lunny/log/go.mod delete mode 100644 vendor/gitea.com/lunny/log/go.sum delete mode 100644 vendor/gitea.com/lunny/log/logext.go delete mode 100644 vendor/gitea.com/lunny/nodb/.gitignore delete mode 100644 vendor/gitea.com/lunny/nodb/LICENSE delete mode 100644 vendor/gitea.com/lunny/nodb/README.md delete mode 100644 vendor/gitea.com/lunny/nodb/README_CN.md delete mode 100644 vendor/gitea.com/lunny/nodb/batch.go delete mode 100644 vendor/gitea.com/lunny/nodb/binlog.go delete mode 100644 vendor/gitea.com/lunny/nodb/binlog_util.go delete mode 100644 vendor/gitea.com/lunny/nodb/config/config.go delete mode 100644 vendor/gitea.com/lunny/nodb/config/config.toml delete mode 100644 vendor/gitea.com/lunny/nodb/const.go delete mode 100644 vendor/gitea.com/lunny/nodb/doc.go delete mode 100644 vendor/gitea.com/lunny/nodb/dump.go delete mode 100644 vendor/gitea.com/lunny/nodb/go.mod delete mode 100644 vendor/gitea.com/lunny/nodb/go.sum delete mode 100644 vendor/gitea.com/lunny/nodb/info.go delete mode 100644 vendor/gitea.com/lunny/nodb/multi.go delete mode 100644 vendor/gitea.com/lunny/nodb/nodb.go delete mode 100644 vendor/gitea.com/lunny/nodb/nodb_db.go delete mode 100644 vendor/gitea.com/lunny/nodb/replication.go delete mode 100644 vendor/gitea.com/lunny/nodb/scan.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/db.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/driver/batch.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/driver/driver.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/driver/store.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/goleveldb/batch.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/goleveldb/const.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/goleveldb/db.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/goleveldb/iterator.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/goleveldb/snapshot.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/iterator.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/snapshot.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/store.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/tx.go delete mode 100644 vendor/gitea.com/lunny/nodb/store/writebatch.go delete mode 100644 vendor/gitea.com/lunny/nodb/t_bit.go delete mode 100644 vendor/gitea.com/lunny/nodb/t_hash.go delete mode 100644 vendor/gitea.com/lunny/nodb/t_kv.go delete mode 100644 vendor/gitea.com/lunny/nodb/t_list.go delete mode 100644 vendor/gitea.com/lunny/nodb/t_set.go delete mode 100644 vendor/gitea.com/lunny/nodb/t_ttl.go delete mode 100644 vendor/gitea.com/lunny/nodb/t_zset.go delete mode 100644 vendor/gitea.com/lunny/nodb/tx.go delete mode 100644 vendor/gitea.com/lunny/nodb/util.go delete mode 100644 vendor/gitea.com/macaron/binding/README.md delete mode 100644 vendor/gitea.com/macaron/binding/go.sum delete mode 100644 vendor/gitea.com/macaron/captcha/go.mod delete mode 100644 vendor/gitea.com/macaron/cors/.drone.yml delete mode 100644 vendor/gitea.com/macaron/cors/.gitignore delete mode 100644 vendor/gitea.com/macaron/cors/README.md delete mode 100644 vendor/gitea.com/macaron/cors/cors.go delete mode 100644 vendor/gitea.com/macaron/cors/go.mod delete mode 100644 vendor/gitea.com/macaron/cors/go.sum delete mode 100644 vendor/gitea.com/macaron/csrf/.drone.yml delete mode 100644 vendor/gitea.com/macaron/csrf/LICENSE delete mode 100644 vendor/gitea.com/macaron/csrf/README.md delete mode 100644 vendor/gitea.com/macaron/csrf/go.mod delete mode 100644 vendor/gitea.com/macaron/csrf/go.sum delete mode 100644 vendor/gitea.com/macaron/gzip/.drone.yml delete mode 100644 vendor/gitea.com/macaron/gzip/README.md delete mode 100644 vendor/gitea.com/macaron/gzip/go.mod delete mode 100644 vendor/gitea.com/macaron/gzip/go.sum delete mode 100644 vendor/gitea.com/macaron/gzip/gzip.go delete mode 100644 vendor/gitea.com/macaron/i18n/.drone.yml delete mode 100644 vendor/gitea.com/macaron/i18n/.gitignore delete mode 100644 vendor/gitea.com/macaron/i18n/LICENSE delete mode 100644 vendor/gitea.com/macaron/i18n/README.md delete mode 100644 vendor/gitea.com/macaron/i18n/go.mod delete mode 100644 vendor/gitea.com/macaron/i18n/go.sum delete mode 100644 vendor/gitea.com/macaron/i18n/i18n.go delete mode 100644 vendor/gitea.com/macaron/inject/.drone.yml delete mode 100644 vendor/gitea.com/macaron/inject/LICENSE delete mode 100644 vendor/gitea.com/macaron/inject/README.md delete mode 100644 vendor/gitea.com/macaron/inject/go.mod delete mode 100644 vendor/gitea.com/macaron/inject/go.sum delete mode 100644 vendor/gitea.com/macaron/inject/inject.go delete mode 100644 vendor/gitea.com/macaron/macaron/.drone.yml delete mode 100644 vendor/gitea.com/macaron/macaron/.gitignore delete mode 100644 vendor/gitea.com/macaron/macaron/LICENSE delete mode 100644 vendor/gitea.com/macaron/macaron/README.md delete mode 100644 vendor/gitea.com/macaron/macaron/context.go delete mode 100644 vendor/gitea.com/macaron/macaron/go.mod delete mode 100644 vendor/gitea.com/macaron/macaron/go.sum delete mode 100644 vendor/gitea.com/macaron/macaron/logger.go delete mode 100644 vendor/gitea.com/macaron/macaron/macaron.go delete mode 100644 vendor/gitea.com/macaron/macaron/macaronlogo.png delete mode 100644 vendor/gitea.com/macaron/macaron/recovery.go delete mode 100644 vendor/gitea.com/macaron/macaron/render.go delete mode 100644 vendor/gitea.com/macaron/macaron/response_writer.go delete mode 100644 vendor/gitea.com/macaron/macaron/return_handler.go delete mode 100644 vendor/gitea.com/macaron/macaron/router.go delete mode 100644 vendor/gitea.com/macaron/macaron/static.go delete mode 100644 vendor/gitea.com/macaron/macaron/tree.go delete mode 100644 vendor/gitea.com/macaron/macaron/util_go17.go delete mode 100644 vendor/gitea.com/macaron/macaron/util_go18.go delete mode 100644 vendor/gitea.com/macaron/session/.drone.yml delete mode 100644 vendor/gitea.com/macaron/session/.gitignore delete mode 100644 vendor/gitea.com/macaron/session/LICENSE delete mode 100644 vendor/gitea.com/macaron/session/README.md delete mode 100644 vendor/gitea.com/macaron/session/couchbase/couchbase.go delete mode 100644 vendor/gitea.com/macaron/session/file.go delete mode 100644 vendor/gitea.com/macaron/session/flash.go delete mode 100644 vendor/gitea.com/macaron/session/go.mod delete mode 100644 vendor/gitea.com/macaron/session/go.sum delete mode 100644 vendor/gitea.com/macaron/session/memcache/memcache.go delete mode 100644 vendor/gitea.com/macaron/session/memcache/memcache.goconvey delete mode 100644 vendor/gitea.com/macaron/session/memory.go delete mode 100644 vendor/gitea.com/macaron/session/mysql/mysql.go delete mode 100644 vendor/gitea.com/macaron/session/mysql/mysql.goconvey delete mode 100644 vendor/gitea.com/macaron/session/nodb/nodb.go delete mode 100644 vendor/gitea.com/macaron/session/nodb/nodb.goconvey delete mode 100644 vendor/gitea.com/macaron/session/postgres/postgres.go delete mode 100644 vendor/gitea.com/macaron/session/postgres/postgres.goconvey delete mode 100644 vendor/gitea.com/macaron/session/session.go delete mode 100644 vendor/gitea.com/macaron/session/utils.go delete mode 100644 vendor/gitea.com/macaron/toolbox/.drone.yml delete mode 100644 vendor/gitea.com/macaron/toolbox/.gitignore delete mode 100644 vendor/gitea.com/macaron/toolbox/LICENSE delete mode 100644 vendor/gitea.com/macaron/toolbox/README.md delete mode 100644 vendor/gitea.com/macaron/toolbox/healthcheck.go delete mode 100644 vendor/gitea.com/macaron/toolbox/profile.go delete mode 100644 vendor/gitea.com/macaron/toolbox/statistic.go delete mode 100644 vendor/gitea.com/macaron/toolbox/toolbox.go create mode 100644 vendor/github.com/NYTimes/gziphandler/.gitignore create mode 100644 vendor/github.com/NYTimes/gziphandler/.travis.yml create mode 100644 vendor/github.com/NYTimes/gziphandler/CODE_OF_CONDUCT.md create mode 100644 vendor/github.com/NYTimes/gziphandler/CONTRIBUTING.md rename vendor/{gitea.com/macaron/cors => github.com/NYTimes/gziphandler}/LICENSE (99%) create mode 100644 vendor/github.com/NYTimes/gziphandler/README.md create mode 100644 vendor/github.com/NYTimes/gziphandler/go.mod create mode 100644 vendor/github.com/NYTimes/gziphandler/go.sum create mode 100644 vendor/github.com/NYTimes/gziphandler/gzip.go create mode 100644 vendor/github.com/NYTimes/gziphandler/gzip_go18.go create mode 100644 vendor/github.com/go-chi/cors/LICENSE create mode 100644 vendor/github.com/go-chi/cors/README.md create mode 100644 vendor/github.com/go-chi/cors/cors.go create mode 100644 vendor/github.com/go-chi/cors/utils.go delete mode 100644 vendor/github.com/siddontang/go-snappy/AUTHORS delete mode 100644 vendor/github.com/siddontang/go-snappy/CONTRIBUTORS delete mode 100644 vendor/github.com/siddontang/go-snappy/LICENSE delete mode 100644 vendor/github.com/siddontang/go-snappy/snappy/decode.go delete mode 100644 vendor/github.com/siddontang/go-snappy/snappy/encode.go delete mode 100644 vendor/github.com/siddontang/go-snappy/snappy/snappy.go diff --git a/.golangci.yml b/.golangci.yml index 34752127e006a..2d098f6fcc7a5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -70,7 +70,7 @@ issues: - path: modules/log/ linters: - errcheck - - path: routers/routes/macaron.go + - path: routers/routes/web.go linters: - dupl - path: routers/api/v1/repo/issue_subscription.go diff --git a/cmd/dump.go b/cmd/dump.go index 1a2e62576792f..65e2c817f92b5 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -21,7 +21,7 @@ import ( "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/util" - "gitea.com/macaron/session" + "gitea.com/go-chi/session" archiver "github.com/mholt/archiver/v3" "github.com/urfave/cli" ) diff --git a/cmd/web.go b/cmd/web.go index 2e8c45a76e058..79915ad1948f1 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -102,8 +102,7 @@ func runWeb(ctx *cli.Context) error { return err } } - c := routes.NewChi() - routes.RegisterInstallRoute(c) + c := routes.InstallRoutes() err := listen(c, false) select { case <-graceful.GetManager().IsShutdown(): @@ -134,11 +133,9 @@ func runWeb(ctx *cli.Context) error { return err } } - // Set up Chi routes - c := routes.NewChi() - c.Mount("/", routes.NormalRoutes()) - routes.DelegateToMacaron(c) + // Set up Chi routes + c := routes.NormalRoutes() err := listen(c, true) <-graceful.GetManager().Done() log.Info("PID: %d Gitea Web Finished", os.Getpid()) diff --git a/contrib/pr/checkout.go b/contrib/pr/checkout.go index 9346577bd6970..63eca484a51d4 100644 --- a/contrib/pr/checkout.go +++ b/contrib/pr/checkout.go @@ -116,9 +116,7 @@ func runPR() { //routers.GlobalInit() external.RegisterParsers() markup.Init() - c := routes.NewChi() - c.Mount("/", routes.NormalRoutes()) - routes.DelegateToMacaron(c) + c := routes.NormalRoutes() log.Printf("[PR] Ready for testing !\n") log.Printf("[PR] Login with user1, user2, user3, ... with pass: password\n") diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 5d2670151cb55..e8866ab333d6c 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -549,7 +549,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type ## Session (`session`) -- `PROVIDER`: **memory**: Session engine provider \[memory, file, redis, mysql, couchbase, memcache, nodb, postgres\]. +- `PROVIDER`: **memory**: Session engine provider \[memory, file, redis, mysql, couchbase, memcache, postgres\]. - `PROVIDER_CONFIG`: **data/sessions**: For file, the root path; for others, the connection string. - `COOKIE_SECURE`: **false**: Enable this to force using HTTPS for all session access. - `COOKIE_NAME`: **i\_like\_gitea**: The name of the cookie used for the session ID. @@ -609,8 +609,6 @@ Default templates for project boards: - `MODE`: **console**: Logging mode. For multiple modes, use a comma to separate values. You can configure each mode in per mode log subsections `\[log.modename\]`. By default the file mode will log to `$ROOT_PATH/gitea.log`. - `LEVEL`: **Info**: General log level. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\] - `STACKTRACE_LEVEL`: **None**: Default log level at which to log create stack traces. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\] -- `REDIRECT_MACARON_LOG`: **false**: Redirects the Macaron log to its own logger or the default logger. -- `MACARON`: **file**: Logging mode for the macaron logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.macaron\]`. By default the file mode will log to `$ROOT_PATH/macaron.log`. (If you set this to `,` it will log to default gitea logger.) - `ROUTER_LOG_LEVEL`: **Info**: The log level that the router should log at. (If you are setting the access log, its recommended to place this at Debug.) - `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default gitea logger.) NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`. @@ -618,7 +616,7 @@ NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false` - `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default gitea logger.) - `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log. - The following variables are available: - - `Ctx`: the `macaron.Context` of the request. + - `Ctx`: the `context.Context` of the request. - `Identity`: the SignedUserName or `"-"` if not logged in. - `Start`: the start time of the request. - `ResponseWriter`: the responseWriter from the request. diff --git a/docs/content/doc/advanced/logging-documentation.en-us.md b/docs/content/doc/advanced/logging-documentation.en-us.md index bf9fc48881964..195820329d26f 100644 --- a/docs/content/doc/advanced/logging-documentation.en-us.md +++ b/docs/content/doc/advanced/logging-documentation.en-us.md @@ -67,40 +67,11 @@ The provider type of the sublogger can be set using the `MODE` value in its subsection, but will default to the name. This allows you to have multiple subloggers that will log to files. -### The "Macaron" logger - -By default Macaron will log to its own go `log` instance. This writes -to `os.Stdout`. You can redirect this log to a Gitea configurable logger -through setting the `REDIRECT_MACARON_LOG` setting in the `[log]` -section which you can configure the outputs of by setting the `MACARON` -value in the `[log]` section of the configuration. `MACARON` defaults -to `file` if unset. - -Please note, the macaron logger will log at `INFO` level, setting the -`LEVEL` of this logger to `WARN` or above will result in no macaron logs. - -Each output sublogger for this logger is configured in -`[log.sublogger.macaron]` sections. There are certain default values -which will not be inherited from the `[log]` or relevant -`[log.sublogger]` sections: - -- `FLAGS` is `stdflags` (Equal to - `date,time,medfile,shortfuncname,levelinitial`) -- `FILE_NAME` will default to `%(ROOT_PATH)/macaron.log` -- `EXPRESSION` will default to `""` -- `PREFIX` will default to `""` - -NB: You can redirect the macaron logger to send its events to the gitea -log using the value: `MACARON = ,` - ### The "Router" logger -There are two types of Router log. By default Macaron send its own -router log which will be directed to Macaron's go `log`, however if you -`REDIRECT_MACARON_LOG` you will enable Gitea's router log. You can -disable both types of Router log by setting `DISABLE_ROUTER_LOG`. +You can disable Router log by setting `DISABLE_ROUTER_LOG`. -If you enable the redirect, you can configure the outputs of this +You can configure the outputs of this router log by setting the `ROUTER` value in the `[log]` section of the configuration. `ROUTER` will default to `console` if unset. The Gitea Router logs the same data as the Macaron log but has slightly different @@ -162,11 +133,11 @@ This value represent a go template. It's default value is: The template is passed following options: -- `Ctx` is the `macaron.Context` +- `Ctx` is the `context.Context` - `Identity` is the `SignedUserName` or `"-"` if the user is not logged in - `Start` is the start time of the request -- `ResponseWriter` is the `macaron.ResponseWriter` +- `ResponseWriter` is the `http.ResponseWriter` Caution must be taken when changing this template as it runs outside of the standard panic recovery trap. The template should also be as simple diff --git a/docs/content/page/index.en-us.md b/docs/content/page/index.en-us.md index d190b20ae500e..6bf163ecbcced 100644 --- a/docs/content/page/index.en-us.md +++ b/docs/content/page/index.en-us.md @@ -267,7 +267,7 @@ Windows, on architectures like amd64, i386, ARM, PowerPC, and others. ## Components -* Web framework: [Macaron](http://go-macaron.com/) +* Web framework: [Chi](http://github.com/go-chi/chi) * ORM: [XORM](https://xorm.io) * UI components: * [Semantic UI](http://semantic-ui.com/) diff --git a/docs/content/page/index.fr-fr.md b/docs/content/page/index.fr-fr.md index 4bbf08c4d9952..17e22e8b593cd 100755 --- a/docs/content/page/index.fr-fr.md +++ b/docs/content/page/index.fr-fr.md @@ -254,7 +254,7 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide ## Composants -* Framework web : [Macaron](http://go-macaron.com/) +* Framework web : [Chi](http://github.com/go-chi/chi) * ORM: [XORM](https://xorm.io) * Interface graphique : * [Semantic UI](http://semantic-ui.com/) diff --git a/docs/content/page/index.zh-cn.md b/docs/content/page/index.zh-cn.md index 453715a84d8dc..cb6a1da793fc4 100644 --- a/docs/content/page/index.zh-cn.md +++ b/docs/content/page/index.zh-cn.md @@ -47,7 +47,7 @@ Gitea的首要目标是创建一个极易安装,运行非常快速,安装和 ## 组件 -* Web框架: [Macaron](http://go-macaron.com/) +* Web框架: [Chi](http://github.com/go-chi/chi) * ORM: [XORM](https://xorm.io) * UI组件: * [Semantic UI](http://semantic-ui.com/) diff --git a/docs/content/page/index.zh-tw.md b/docs/content/page/index.zh-tw.md index 4c7979f41caea..86c182a7d013d 100644 --- a/docs/content/page/index.zh-tw.md +++ b/docs/content/page/index.zh-tw.md @@ -47,7 +47,7 @@ Gitea 的首要目標是建立一個容易安裝,運行快速,安装和使 ## 元件 -* Web 框架: [Macaron](http://go-macaron.com/) +* Web 框架: [Chi](http://github.com/go-chi/chi) * ORM: [XORM](https://xorm.io) * UI 元件: * [Semantic UI](http://semantic-ui.com/) diff --git a/go.mod b/go.mod index 5d7fba0b7b181..ad10dadd293b5 100644 --- a/go.mod +++ b/go.mod @@ -5,19 +5,12 @@ go 1.14 require ( code.gitea.io/gitea-vet v0.2.1 code.gitea.io/sdk/gitea v0.13.1 + gitea.com/go-chi/binding v0.0.0-20210113025129-03f1d313373c + gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e + gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee gitea.com/lunny/levelqueue v0.3.0 - gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b - gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b - gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca - gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4 - gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439 - gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5 - gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60 - gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a - gitea.com/macaron/macaron v1.5.1-0.20201027213641-0db5d4584804 - gitea.com/macaron/session v0.0.0-20201103015045-a177a2701dee - gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7 + github.com/NYTimes/gziphandler v1.1.1 github.com/PuerkitoBio/goquery v1.5.1 github.com/RoaringBitmap/roaring v0.5.5 // indirect github.com/alecthomas/chroma v0.8.2 @@ -36,6 +29,7 @@ require ( github.com/gliderlabs/ssh v0.3.1 github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a // indirect github.com/go-chi/chi v1.5.1 + github.com/go-chi/cors v1.1.1 github.com/go-enry/go-enry/v2 v2.6.0 github.com/go-git/go-billy/v5 v5.0.0 github.com/go-git/go-git/v5 v5.2.0 diff --git a/go.sum b/go.sum index 458d0ab60e74a..79cba8d26b944 100644 --- a/go.sum +++ b/go.sum @@ -40,44 +40,16 @@ code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFj code.gitea.io/sdk/gitea v0.13.1 h1:Y7bpH2iO6Q0KhhMJfjP/LZ0AmiYITeRQlCD8b0oYqhk= code.gitea.io/sdk/gitea v0.13.1/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gitea.com/go-chi/binding v0.0.0-20210113025129-03f1d313373c h1:NTtrGYjR40WUdkCdn26Y5LGFT52rIkFPkjmtgCAyiTs= +gitea.com/go-chi/binding v0.0.0-20210113025129-03f1d313373c/go.mod h1:9bGA9dIsrz+wVQKH1DzvxuAvrudHaQ8Wx8hLme/GVGQ= +gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e h1:zgPGaf3kXP0cVm9J0l8ZA2+XDzILYATg0CXbihR6N+o= +gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e/go.mod h1:k2V/gPDEtXGjjMGuBJiapffAXTv76H4snSmlJRLUhH0= +gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e h1:YjaQU6XFicdhPN+MlGolcXO8seYY2+EY5g7vZPB17CQ= +gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e/go.mod h1:nfA7JaGv3hbGQ1ktdhAsZhdS84qKffI8NMlHr+Opsog= gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee h1:9U6HuKUBt/cGK6T/64dEuz0r7Yp97WAAEJvXHDlY3ws= gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee/go.mod h1:Ozg8IchVNb/Udg+ui39iHRYqVHSvf3C99ixdpLR8Vu0= gitea.com/lunny/levelqueue v0.3.0 h1:MHn1GuSZkxvVEDMyAPqlc7A3cOW+q8RcGhRgH/xtm6I= gitea.com/lunny/levelqueue v0.3.0/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= -gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e h1:r1en/D7xJmcY24VkHkjkcJFa+7ZWubVWPBrvsHkmHxk= -gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e/go.mod h1:uJEsN4LQpeGYRCjuPXPZBClU7N5pWzGuyF4uqLpE/e0= -gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727 h1:ZF2Bd6rqVlwhIDhYiS0uGYcT+GaVNGjuKVJkTNqWMIs= -gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727/go.mod h1:h0OwsgcpJLSYtHcM5+Xciw9OEeuxi6ty4HDiO8C7aIY= -gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b h1:vXt85uYV17KURaUlhU7v4GbCShkqRZDSfo0TkC0YCjQ= -gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b/go.mod h1:Cxadig6POWpPYYSfg23E7jo35Yf0yvsdC1lifoKWmPo= -gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76 h1:mMsMEg90c5KXQgRWsH8D6GHXfZIW1RAe5S9VYIb12lM= -gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76/go.mod h1:NFHb9Of+LUnU86bU20CiXXg6ZlgCJ4XytP14UsHOXFs= -gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b h1:2ZE0JE3bKVBcP1VTrWeE1jqWwCAMIzfOQm1U9EGbBKU= -gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b/go.mod h1:W5hKG8T1GBfypp5CRQlgoJU4figIL0jhx02y4XA/NOA= -gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca h1:f5P41nXmXd/YOh8f6098Q0F1Y0QfpyRPSSIkni2XH4Q= -gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca/go.mod h1:J5h3N+1nKTXtU1x4GxexaQKgAz8UiWecNwi/CfX7CtQ= -gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4 h1:e2rAFDejB0qN8OrY4xP4XSu8/yT6QmWxDZpB3J7r2GU= -gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4/go.mod h1:rtOK4J20kpMD9XcNsnO5YA843YSTe/MUMbDj/TJ/Q7A= -gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439 h1:88c34YM29a1GlWLrLBaG/GTT2htDdJz1u3n9+lmPolg= -gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439/go.mod h1:IsQPHx73HnnqFBYiVHjg87q4XBZyGXXu77xANukvZuk= -gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5 h1:6rbhThlqfOb+sSmhrsVFz3bZoAeoloe7TZqyeiPbbWI= -gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5/go.mod h1:z8vCjuhqDfvzPUJDowGqbsgoeYBvDbl95S5k6y43Pxo= -gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60 h1:tNWNe5HBIlsfapFMtT4twTbXQmInRQWmdWNi8Di1ct0= -gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60/go.mod h1:g5ope1b+iWhBdHzAn6EJ9u9Gp3FRESxpG+CDf7HYc/A= -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a h1:aOKEXkDTnh4euoH0so/THLXeHtQuqHmDPb1xEk6Ehok= -gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827/go.mod h1:/rvxMjIkOq4BM8uPUb+VHuU02ZfAO6R4+wD//tiCiRw= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs= -gitea.com/macaron/macaron v1.5.0 h1:TvWEcHw1/zaHlo0GTuKEukLh3A99+QsU2mjBrXLXjVQ= -gitea.com/macaron/macaron v1.5.0/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY= -gitea.com/macaron/macaron v1.5.1-0.20201027213641-0db5d4584804 h1:yUiJVZKzdXsBe2tumTAXHBZa1qPGoGXM3fBG4RJ5fQg= -gitea.com/macaron/macaron v1.5.1-0.20201027213641-0db5d4584804/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY= -gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705/go.mod h1:1ujH0jD6Ca4iK9NL0Q2a7fG2chvXx5hVa7hBfABwpkA= -gitea.com/macaron/session v0.0.0-20201103015045-a177a2701dee h1:8/N3a56RXRJ66nnep0z+T7oHCB0bY6lpvtjv9Y9FPhE= -gitea.com/macaron/session v0.0.0-20201103015045-a177a2701dee/go.mod h1:5tJCkDbrwpGv+MQUSIZSOW0wFrkh0exsonJgOvBs1Dw= -gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7 h1:N9QFoeNsUXLhl14mefLzGluqV7w2mGU3u+iZU+jCeWk= -gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7/go.mod h1:kgsbFPPS4P+acDYDOPDa3N4IWWOuDJt5/INKRUz7aks= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= github.com/6543-forks/go-gogs-client v0.0.0-20210116182316-f2f8bc0ea9cc h1:FLylYVXDwK+YtrmXYnv2Q1Y5lQ9TU1Xp5F2vndIOTb4= @@ -92,6 +64,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= @@ -106,7 +80,6 @@ github.com/RoaringBitmap/roaring v0.5.5 h1:naNqvO1mNnghk2UvcsqnzHDBn9DRbCIRy94Gm github.com/RoaringBitmap/roaring v0.5.5/go.mod h1:puNo5VdzwbaIQxSiDIwfXl4Hnc+fbovcX4IW/dSTtUk= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= @@ -233,19 +206,13 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k= github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89 h1:uNLXQ6QO1TocD8BaN/KkRki0Xw0brCM1PKl/ZA5pgfs= github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A= -github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= -github.com/couchbase/gomemcached v0.1.0 h1:whUde87n8CScx8ckMp2En5liqAlcuG3aKy/BQeBPu84= -github.com/couchbase/gomemcached v0.1.0/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= github.com/couchbase/gomemcached v0.1.1 h1:xCS8ZglJDhrlQg3jmK7Rn1V8f7bPjXABLC05CgLQauc= github.com/couchbase/gomemcached v0.1.1/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo= -github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 h1:NCqJ6fwen6YP0WlV/IyibaT0kPt3JEI1rA62V/UPKT4= github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs= github.com/couchbase/vellum v1.0.2 h1:BrbP0NKiyDdndMPec8Jjhy0U47CZ0Lgx3xUC2r9rZqw= github.com/couchbase/vellum v1.0.2/go.mod h1:FcwrEivFpNi24R3jLOs3n+fs5RnuQnQqCLBJ1uAg1W4= -github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7 h1:1XjEY/gnjQ+AfXef2U6dxCquhiRzkEpxZuWqs+QxTL8= -github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -331,6 +298,8 @@ github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-chi/chi v1.5.1 h1:kfTK3Cxd/dkMu/rKs5ZceWYp+t5CtiE7vmaTv3LjC6w= github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k= +github.com/go-chi/cors v1.1.1 h1:eHuqxsIw89iXcWnWUN8R72JMibABJTN/4IOYI5WERvw= +github.com/go-chi/cors v1.1.1/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I= github.com/go-enry/go-enry/v2 v2.6.0 h1:nbGWQBpO+D+cJuRxNgSDFnFY9QWz3QM/CeZxU7VAH20= github.com/go-enry/go-enry/v2 v2.6.0/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= @@ -548,7 +517,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw= github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= @@ -700,7 +668,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8h3jc= @@ -995,7 +962,6 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck= github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= @@ -1068,7 +1034,6 @@ github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oW github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6/go.mod h1:+5rDk6sDGpl3azws3O+f+GpFSyN9GVr0K8cvQLQM2ZQ= github.com/unknwon/i18n v0.0.0-20200823051745-09abd91c7f2c h1:679/gJXwrsHC3RATr0YYjZvDMJPYN7W9FGSGNoLmKxM= github.com/unknwon/i18n v0.0.0-20200823051745-09abd91c7f2c/go.mod h1:+5rDk6sDGpl3azws3O+f+GpFSyN9GVr0K8cvQLQM2ZQ= github.com/unknwon/paginater v0.0.0-20200328080006-042474bd0eae h1:ihaXiJkaca54IaCSnEXtE/uSZOmPxKZhDfVLrzZLFDs= @@ -1171,9 +1136,6 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201217014255-9d1352758620 h1:3wPMTskHO3+O6jqTEXyFcsnuxMQOqYSaHsDxcbUXpqA= golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1535,12 +1497,10 @@ gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg= gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.60.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/integrations/api_helper_for_declarative_test.go b/integrations/api_helper_for_declarative_test.go index b8e513958e841..551a9bb7517bc 100644 --- a/integrations/api_helper_for_declarative_test.go +++ b/integrations/api_helper_for_declarative_test.go @@ -14,7 +14,7 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/queue" api "code.gitea.io/gitea/modules/structs" diff --git a/integrations/api_pull_test.go b/integrations/api_pull_test.go index 61daf917ff277..369f4ce31f465 100644 --- a/integrations/api_pull_test.go +++ b/integrations/api_pull_test.go @@ -10,7 +10,7 @@ import ( "testing" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" issue_service "code.gitea.io/gitea/services/issue" diff --git a/integrations/api_releases_test.go b/integrations/api_releases_test.go index 8328b014d653e..870d7d0e64d6a 100644 --- a/integrations/api_releases_test.go +++ b/integrations/api_releases_test.go @@ -131,7 +131,7 @@ func TestAPIGetReleaseByTag(t *testing.T) { tag := "v1.1" - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s/", + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, tag) req := NewRequestf(t, "GET", urlStr) @@ -144,7 +144,7 @@ func TestAPIGetReleaseByTag(t *testing.T) { nonexistingtag := "nonexistingtag" - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s/", + urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, nonexistingtag) req = NewRequestf(t, "GET", urlStr) @@ -163,7 +163,7 @@ func TestAPIDeleteTagByName(t *testing.T) { session := loginUser(t, owner.LowerName) token := getTokenForLoggedInUser(t, session) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/delete-tag/?token=%s", + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/delete-tag?token=%s", owner.Name, repo.Name, token) req := NewRequestf(t, http.MethodDelete, urlStr) @@ -171,7 +171,7 @@ func TestAPIDeleteTagByName(t *testing.T) { // Make sure that actual releases can't be deleted outright createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test") - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag/?token=%s", + urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag?token=%s", owner.Name, repo.Name, token) req = NewRequestf(t, http.MethodDelete, urlStr) diff --git a/integrations/create_no_session_test.go b/integrations/create_no_session_test.go index ae0d9f8120084..89682e95cfcd3 100644 --- a/integrations/create_no_session_test.go +++ b/integrations/create_no_session_test.go @@ -17,7 +17,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/routes" - "gitea.com/macaron/session" + "gitea.com/go-chi/session" "github.com/stretchr/testify/assert" ) @@ -58,9 +58,7 @@ func TestSessionFileCreation(t *testing.T) { oldSessionConfig := setting.SessionConfig.ProviderConfig defer func() { setting.SessionConfig.ProviderConfig = oldSessionConfig - c = routes.NewChi() - c.Mount("/", routes.NormalRoutes()) - routes.DelegateToMacaron(c) + c = routes.NormalRoutes() }() var config session.Options @@ -84,9 +82,7 @@ func TestSessionFileCreation(t *testing.T) { setting.SessionConfig.ProviderConfig = string(newConfigBytes) - c = routes.NewChi() - c.Mount("/", routes.NormalRoutes()) - routes.DelegateToMacaron(c) + c = routes.NormalRoutes() t.Run("NoSessionOnViewIssue", func(t *testing.T) { defer PrintCurrentTest(t)() diff --git a/integrations/integration_test.go b/integrations/integration_test.go index f3b2644c7839f..ee005c087d33a 100644 --- a/integrations/integration_test.go +++ b/integrations/integration_test.go @@ -31,15 +31,15 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers" "code.gitea.io/gitea/routers/routes" "github.com/PuerkitoBio/goquery" - "github.com/go-chi/chi" "github.com/stretchr/testify/assert" ) -var c chi.Router +var c *web.Route type NilResponseRecorder struct { httptest.ResponseRecorder @@ -66,9 +66,7 @@ func TestMain(m *testing.M) { defer cancel() initIntegrationTest() - c = routes.NewChi() - c.Mount("/", routes.NormalRoutes()) - routes.DelegateToMacaron(c) + c = routes.NormalRoutes() // integration test settings... if setting.Cfg != nil { @@ -387,6 +385,9 @@ func NewRequestWithJSON(t testing.TB, method, urlStr string, v interface{}) *htt func NewRequestWithBody(t testing.TB, method, urlStr string, body io.Reader) *http.Request { t.Helper() + if !strings.HasPrefix(urlStr, "http") && !strings.HasPrefix(urlStr, "/") { + urlStr = "/" + urlStr + } request, err := http.NewRequest(method, urlStr, body) assert.NoError(t, err) request.RequestURI = urlStr diff --git a/integrations/lfs_getobject_test.go b/integrations/lfs_getobject_test.go index 180182dd42457..f364349ef140a 100644 --- a/integrations/lfs_getobject_test.go +++ b/integrations/lfs_getobject_test.go @@ -19,8 +19,8 @@ import ( "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" + "code.gitea.io/gitea/routers/routes" - "gitea.com/macaron/gzip" gzipp "github.com/klauspost/compress/gzip" "github.com/stretchr/testify/assert" ) @@ -121,7 +121,7 @@ func TestGetLFSLarge(t *testing.T) { t.Skip() return } - content := make([]byte, gzip.MinSize*10) + content := make([]byte, routes.GzipMinSize*10) for i := range content { content[i] = byte(i % 256) } @@ -137,7 +137,7 @@ func TestGetLFSGzip(t *testing.T) { t.Skip() return } - b := make([]byte, gzip.MinSize*10) + b := make([]byte, routes.GzipMinSize*10) for i := range b { b[i] = byte(i % 256) } @@ -158,7 +158,7 @@ func TestGetLFSZip(t *testing.T) { t.Skip() return } - b := make([]byte, gzip.MinSize*10) + b := make([]byte, routes.GzipMinSize*10) for i := range b { b[i] = byte(i % 256) } diff --git a/integrations/links_test.go b/integrations/links_test.go index 2c674c104acc0..e16b688c8de3b 100644 --- a/integrations/links_test.go +++ b/integrations/links_test.go @@ -32,7 +32,6 @@ func TestLinksNoLogin(t *testing.T) { "/user/login", "/user/forgot_password", "/api/swagger", - "/api/v1/swagger", "/user2/repo1", "/user2/repo1/projects", "/user2/repo1/projects/1", @@ -53,6 +52,7 @@ func TestRedirectsNoLogin(t *testing.T) { "/user2/repo1/src/master/file.txt": "/user2/repo1/src/branch/master/file.txt", "/user2/repo1/src/master/directory/file.txt": "/user2/repo1/src/branch/master/directory/file.txt", "/user/avatar/Ghost/-1": "/img/avatar_default.png", + "/api/v1/swagger": "/api/swagger", } for link, redirectLink := range redirects { req := NewRequest(t, "GET", link) @@ -86,7 +86,6 @@ func testLinksAsUser(userName string, t *testing.T) { "/", "/user/forgot_password", "/api/swagger", - "/api/v1/swagger", "/issues", "/issues?type=your_repositories&repos=[0]&sort=&state=open", "/issues?type=assigned&repos=[0]&sort=&state=open", diff --git a/modules/auth/sso/interface.go b/modules/auth/sso/interface.go index c957fad02f186..7efe79a69c27d 100644 --- a/modules/auth/sso/interface.go +++ b/modules/auth/sso/interface.go @@ -8,19 +8,15 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/middlewares" + "code.gitea.io/gitea/modules/session" ) // DataStore represents a data store -type DataStore interface { - GetData() map[string]interface{} -} +type DataStore middlewares.DataStore // SessionStore represents a session store -type SessionStore interface { - Get(interface{}) interface{} - Set(interface{}, interface{}) error - Delete(interface{}) error -} +type SessionStore session.Store // SingleSignOn represents a SSO authentication method (plugin) for HTTP requests. type SingleSignOn interface { diff --git a/modules/auth/sso/oauth2.go b/modules/auth/sso/oauth2.go index fc22e27282cc4..c3f6f08fb27d2 100644 --- a/modules/auth/sso/oauth2.go +++ b/modules/auth/sso/oauth2.go @@ -62,6 +62,8 @@ func (o *OAuth2) Free() error { // userIDFromToken returns the user id corresponding to the OAuth token. func (o *OAuth2) userIDFromToken(req *http.Request, store DataStore) int64 { + _ = req.ParseForm() + // Check access token. tokenSHA := req.Form.Get("token") if len(tokenSHA) == 0 { diff --git a/modules/cache/cache.go b/modules/cache/cache.go index 42227f928953b..3f8885ee306ed 100644 --- a/modules/cache/cache.go +++ b/modules/cache/cache.go @@ -10,9 +10,9 @@ import ( "code.gitea.io/gitea/modules/setting" - mc "gitea.com/macaron/cache" + mc "gitea.com/go-chi/cache" - _ "gitea.com/macaron/cache/memcache" // memcache plugin for cache + _ "gitea.com/go-chi/cache/memcache" // memcache plugin for cache ) var ( @@ -20,7 +20,7 @@ var ( ) func newCache(cacheConfig setting.Cache) (mc.Cache, error) { - return mc.NewCacher(cacheConfig.Adapter, mc.Options{ + return mc.NewCacher(mc.Options{ Adapter: cacheConfig.Adapter, AdapterConfig: cacheConfig.Conn, Interval: cacheConfig.Interval, diff --git a/modules/cache/cache_redis.go b/modules/cache/cache_redis.go index 96e865a3829df..3cb0292e21623 100644 --- a/modules/cache/cache_redis.go +++ b/modules/cache/cache_redis.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/modules/nosql" - "gitea.com/macaron/cache" + "gitea.com/go-chi/cache" "github.com/go-redis/redis/v7" "github.com/unknwon/com" ) diff --git a/modules/context/api.go b/modules/context/api.go index 7771ec1b14762..cf6dc265cd6fb 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -6,18 +6,21 @@ package context import ( + "context" "fmt" + "html" "net/http" "net/url" "strings" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/auth/sso" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/setting" - "gitea.com/macaron/csrf" - "gitea.com/macaron/macaron" + "gitea.com/go-chi/session" ) // APIContext is a specific macaron context for API service @@ -91,7 +94,7 @@ func (ctx *APIContext) Error(status int, title string, obj interface{}) { if status == http.StatusInternalServerError { log.ErrorWithSkip(1, "%s: %s", title, message) - if macaron.Env == macaron.PROD && !(ctx.User != nil && ctx.User.IsAdmin) { + if setting.IsProd() && !(ctx.User != nil && ctx.User.IsAdmin) { message = "" } } @@ -108,7 +111,7 @@ func (ctx *APIContext) InternalServerError(err error) { log.ErrorWithSkip(1, "InternalServerError: %v", err) var message string - if macaron.Env != macaron.PROD || (ctx.User != nil && ctx.User.IsAdmin) { + if !setting.IsProd() || (ctx.User != nil && ctx.User.IsAdmin) { message = err.Error() } @@ -118,6 +121,20 @@ func (ctx *APIContext) InternalServerError(err error) { }) } +var ( + apiContextKey interface{} = "default_api_context" +) + +// WithAPIContext set up api context in request +func WithAPIContext(req *http.Request, ctx *APIContext) *http.Request { + return req.WithContext(context.WithValue(req.Context(), apiContextKey, ctx)) +} + +// GetAPIContext returns a context for API routes +func GetAPIContext(req *http.Request) *APIContext { + return req.Context().Value(apiContextKey).(*APIContext) +} + func genAPILinks(curURL *url.URL, total, pageSize, curPage int) []string { page := NewPagination(total, pageSize, curPage, 0) paginater := page.Paginater @@ -172,7 +189,7 @@ func (ctx *APIContext) RequireCSRF() { headerToken := ctx.Req.Header.Get(ctx.csrf.GetHeaderName()) formValueToken := ctx.Req.FormValue(ctx.csrf.GetFormName()) if len(headerToken) > 0 || len(formValueToken) > 0 { - csrf.Validate(ctx.Context.Context, ctx.csrf) + Validate(ctx.Context, ctx.csrf) } else { ctx.Context.Error(401, "Missing CSRF token.") } @@ -201,42 +218,91 @@ func (ctx *APIContext) CheckForOTP() { } // APIContexter returns apicontext as macaron middleware -func APIContexter() macaron.Handler { - return func(c *Context) { - ctx := &APIContext{ - Context: c, - } - c.Map(ctx) +func APIContexter() func(http.Handler) http.Handler { + var csrfOpts = getCsrfOpts() + + return func(next http.Handler) http.Handler { + + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + var locale = middlewares.Locale(w, req) + var ctx = APIContext{ + Context: &Context{ + Resp: NewResponse(w), + Data: map[string]interface{}{}, + Locale: locale, + Session: session.GetSession(req), + Repo: &Repository{ + PullRequest: &PullRequest{}, + }, + Org: &Organization{}, + }, + Org: &APIOrganization{}, + } + + ctx.Req = WithAPIContext(WithContext(req, ctx.Context), &ctx) + ctx.csrf = Csrfer(csrfOpts, ctx.Context) + + // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid. + if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { + if err := ctx.Req.ParseMultipartForm(setting.Attachment.MaxSize << 20); err != nil && !strings.Contains(err.Error(), "EOF") { // 32MB max size + ctx.InternalServerError(err) + return + } + } + + // Get user from session if logged in. + ctx.User, ctx.IsBasicAuth = sso.SignedInUser(ctx.Req, ctx.Resp, &ctx, ctx.Session) + if ctx.User != nil { + ctx.IsSigned = true + ctx.Data["IsSigned"] = ctx.IsSigned + ctx.Data["SignedUser"] = ctx.User + ctx.Data["SignedUserID"] = ctx.User.ID + ctx.Data["SignedUserName"] = ctx.User.Name + ctx.Data["IsAdmin"] = ctx.User.IsAdmin + } else { + ctx.Data["SignedUserID"] = int64(0) + ctx.Data["SignedUserName"] = "" + } + + ctx.Resp.Header().Set(`X-Frame-Options`, `SAMEORIGIN`) + + ctx.Data["CsrfToken"] = html.EscapeString(ctx.csrf.GetToken()) + + next.ServeHTTP(ctx.Resp, ctx.Req) + }) } } // ReferencesGitRepo injects the GitRepo into the Context -func ReferencesGitRepo(allowEmpty bool) macaron.Handler { - return func(ctx *APIContext) { - // Empty repository does not have reference information. - if !allowEmpty && ctx.Repo.Repository.IsEmpty { - return - } - - // For API calls. - if ctx.Repo.GitRepo == nil { - repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) - gitRepo, err := git.OpenRepository(repoPath) - if err != nil { - ctx.Error(500, "RepoRef Invalid repo "+repoPath, err) +func ReferencesGitRepo(allowEmpty bool) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + ctx := GetAPIContext(req) + // Empty repository does not have reference information. + if !allowEmpty && ctx.Repo.Repository.IsEmpty { return } - ctx.Repo.GitRepo = gitRepo - // We opened it, we should close it - defer func() { - // If it's been set to nil then assume someone else has closed it. - if ctx.Repo.GitRepo != nil { - ctx.Repo.GitRepo.Close() + + // For API calls. + if ctx.Repo.GitRepo == nil { + repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) + gitRepo, err := git.OpenRepository(repoPath) + if err != nil { + ctx.Error(500, "RepoRef Invalid repo "+repoPath, err) + return } - }() - } + ctx.Repo.GitRepo = gitRepo + // We opened it, we should close it + defer func() { + // If it's been set to nil then assume someone else has closed it. + if ctx.Repo.GitRepo != nil { + ctx.Repo.GitRepo.Close() + } + }() + } - ctx.Next() + next.ServeHTTP(w, req) + }) } } @@ -266,8 +332,9 @@ func (ctx *APIContext) NotFound(objs ...interface{}) { } // RepoRefForAPI handles repository reference names when the ref name is not explicitly given -func RepoRefForAPI() macaron.Handler { - return func(ctx *APIContext) { +func RepoRefForAPI(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + ctx := GetAPIContext(req) // Empty repository does not have reference information. if ctx.Repo.Repository.IsEmpty { return @@ -319,6 +386,6 @@ func RepoRefForAPI() macaron.Handler { return } - ctx.Next() - } + next.ServeHTTP(w, req) + }) } diff --git a/modules/context/auth.go b/modules/context/auth.go index 02248384e1447..8be6ed1907e50 100644 --- a/modules/context/auth.go +++ b/modules/context/auth.go @@ -7,12 +7,8 @@ package context import ( "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - - "gitea.com/macaron/csrf" - "gitea.com/macaron/macaron" ) // ToggleOptions contains required or check options @@ -24,42 +20,23 @@ type ToggleOptions struct { } // Toggle returns toggle options as middleware -func Toggle(options *ToggleOptions) macaron.Handler { +func Toggle(options *ToggleOptions) func(ctx *Context) { return func(ctx *Context) { - isAPIPath := auth.IsAPIPath(ctx.Req.URL.Path) - // Check prohibit login users. if ctx.IsSigned { if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { ctx.Data["Title"] = ctx.Tr("auth.active_your_account") - if isAPIPath { - ctx.JSON(403, map[string]string{ - "message": "This account is not activated.", - }) - return - } ctx.HTML(200, "user/auth/activate") return - } else if !ctx.User.IsActive || ctx.User.ProhibitLogin { + } + if !ctx.User.IsActive || ctx.User.ProhibitLogin { log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr()) ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") - if isAPIPath { - ctx.JSON(403, map[string]string{ - "message": "This account is prohibited from signing in, please contact your site administrator.", - }) - return - } ctx.HTML(200, "user/auth/prohibit_login") return } if ctx.User.MustChangePassword { - if isAPIPath { - ctx.JSON(403, map[string]string{ - "message": "You must change your password. Change it at: " + setting.AppURL + "/user/change_password", - }) - return - } if ctx.Req.URL.Path != "/user/settings/change_password" { ctx.Data["Title"] = ctx.Tr("auth.must_change_password") ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password" @@ -82,8 +59,8 @@ func Toggle(options *ToggleOptions) macaron.Handler { return } - if !options.SignOutRequired && !options.DisableCSRF && ctx.Req.Method == "POST" && !auth.IsAPIPath(ctx.Req.URL.Path) { - csrf.Validate(ctx.Context, ctx.csrf) + if !options.SignOutRequired && !options.DisableCSRF && ctx.Req.Method == "POST" { + Validate(ctx, ctx.csrf) if ctx.Written() { return } @@ -91,13 +68,6 @@ func Toggle(options *ToggleOptions) macaron.Handler { if options.SignInRequired { if !ctx.IsSigned { - // Restrict API calls with error message. - if isAPIPath { - ctx.JSON(403, map[string]string{ - "message": "Only signed in user is allowed to call APIs.", - }) - return - } if ctx.Req.URL.Path != "/user/events" { ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) } @@ -108,19 +78,88 @@ func Toggle(options *ToggleOptions) macaron.Handler { ctx.HTML(200, "user/auth/activate") return } - if ctx.IsSigned && isAPIPath && ctx.IsBasicAuth { + } + + // Redirect to log in page if auto-signin info is provided and has not signed in. + if !options.SignOutRequired && !ctx.IsSigned && + len(ctx.GetCookie(setting.CookieUserName)) > 0 { + if ctx.Req.URL.Path != "/user/events" { + ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) + } + ctx.Redirect(setting.AppSubURL + "/user/login") + return + } + + if options.AdminRequired { + if !ctx.User.IsAdmin { + ctx.Error(403) + return + } + ctx.Data["PageIsAdmin"] = true + } + } +} + +// ToggleAPI returns toggle options as middleware +func ToggleAPI(options *ToggleOptions) func(ctx *APIContext) { + return func(ctx *APIContext) { + // Check prohibit login users. + if ctx.IsSigned { + if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { + ctx.Data["Title"] = ctx.Tr("auth.active_your_account") + ctx.JSON(403, map[string]string{ + "message": "This account is not activated.", + }) + return + } + if !ctx.User.IsActive || ctx.User.ProhibitLogin { + log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr()) + ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") + ctx.JSON(403, map[string]string{ + "message": "This account is prohibited from signing in, please contact your site administrator.", + }) + return + } + + if ctx.User.MustChangePassword { + ctx.JSON(403, map[string]string{ + "message": "You must change your password. Change it at: " + setting.AppURL + "/user/change_password", + }) + return + } + } + + // Redirect to dashboard if user tries to visit any non-login page. + if options.SignOutRequired && ctx.IsSigned && ctx.Req.URL.RequestURI() != "/" { + ctx.Redirect(setting.AppSubURL + "/") + return + } + + if options.SignInRequired { + if !ctx.IsSigned { + // Restrict API calls with error message. + ctx.JSON(403, map[string]string{ + "message": "Only signed in user is allowed to call APIs.", + }) + return + } else if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { + ctx.Data["Title"] = ctx.Tr("auth.active_your_account") + ctx.HTML(200, "user/auth/activate") + return + } + if ctx.IsSigned && ctx.IsBasicAuth { twofa, err := models.GetTwoFactorByUID(ctx.User.ID) if err != nil { if models.IsErrTwoFactorNotEnrolled(err) { return // No 2FA enrollment for this user } - ctx.Error(500) + ctx.InternalServerError(err) return } otpHeader := ctx.Req.Header.Get("X-Gitea-OTP") ok, err := twofa.ValidateTOTP(otpHeader) if err != nil { - ctx.Error(500) + ctx.InternalServerError(err) return } if !ok { @@ -132,19 +171,11 @@ func Toggle(options *ToggleOptions) macaron.Handler { } } - // Redirect to log in page if auto-signin info is provided and has not signed in. - if !options.SignOutRequired && !ctx.IsSigned && !isAPIPath && - len(ctx.GetCookie(setting.CookieUserName)) > 0 { - if ctx.Req.URL.Path != "/user/events" { - ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) - } - ctx.Redirect(setting.AppSubURL + "/user/login") - return - } - if options.AdminRequired { if !ctx.User.IsAdmin { - ctx.Error(403) + ctx.JSON(403, map[string]string{ + "message": "You have no permission to request for this.", + }) return } ctx.Data["PageIsAdmin"] = true diff --git a/modules/context/captcha.go b/modules/context/captcha.go new file mode 100644 index 0000000000000..956380ed731d8 --- /dev/null +++ b/modules/context/captcha.go @@ -0,0 +1,26 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package context + +import ( + "sync" + + "code.gitea.io/gitea/modules/setting" + + "gitea.com/go-chi/captcha" +) + +var imageCaptchaOnce sync.Once +var cpt *captcha.Captcha + +// GetImageCaptcha returns global image captcha +func GetImageCaptcha() *captcha.Captcha { + imageCaptchaOnce.Do(func() { + cpt = captcha.NewCaptcha(captcha.Options{ + SubURL: setting.AppSubURL, + }) + }) + return cpt +} diff --git a/modules/context/context.go b/modules/context/context.go index e4121649ae674..630129b8c12fc 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -6,37 +6,55 @@ package context import ( + "context" + "crypto/sha256" + "encoding/hex" + "encoding/json" "html" "html/template" "io" "net/http" "net/url" "path" + "strconv" "strings" "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/auth/sso" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/util" - "gitea.com/macaron/cache" - "gitea.com/macaron/csrf" - "gitea.com/macaron/i18n" - "gitea.com/macaron/macaron" - "gitea.com/macaron/session" + "gitea.com/go-chi/cache" + "gitea.com/go-chi/session" + "github.com/go-chi/chi" "github.com/unknwon/com" + "github.com/unknwon/i18n" + "github.com/unrolled/render" + "golang.org/x/crypto/pbkdf2" ) +// Render represents a template render +type Render interface { + TemplateLookup(tmpl string) *template.Template + HTML(w io.Writer, status int, name string, binding interface{}, htmlOpt ...render.HTMLOptions) error +} + // Context represents context of a request. type Context struct { - *macaron.Context + Resp ResponseWriter + Req *http.Request + Data map[string]interface{} + Render Render + translation.Locale Cache cache.Cache - csrf csrf.CSRF - Flash *session.Flash + csrf CSRF + Flash *middlewares.Flash Session session.Store Link string // current request URL @@ -163,13 +181,22 @@ func (ctx *Context) RedirectToFirst(location ...string) { // HTML calls Context.HTML and converts template name to string. func (ctx *Context) HTML(status int, name base.TplName) { log.Debug("Template: %s", name) - ctx.Context.HTML(status, string(name)) + if err := ctx.Render.HTML(ctx.Resp, status, string(name), ctx.Data); err != nil { + ctx.ServerError("Render failed", err) + } +} + +// HTMLString render content to a string but not http.ResponseWriter +func (ctx *Context) HTMLString(name string, data interface{}) (string, error) { + var buf strings.Builder + err := ctx.Render.HTML(&buf, 200, string(name), data) + return buf.String(), err } // RenderWithErr used for page has form validation but need to prompt error to users. func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, form interface{}) { if form != nil { - auth.AssignForm(form, ctx.Data) + middlewares.AssignForm(form, ctx.Data) } ctx.Flash.ErrorMsg = msg ctx.Data["Flash"] = ctx.Flash @@ -184,7 +211,7 @@ func (ctx *Context) NotFound(title string, err error) { func (ctx *Context) notFoundInternal(title string, err error) { if err != nil { log.ErrorWithSkip(2, "%s: %v", title, err) - if macaron.Env != macaron.PROD { + if !setting.IsProd() { ctx.Data["ErrorMsg"] = err } } @@ -203,7 +230,7 @@ func (ctx *Context) ServerError(title string, err error) { func (ctx *Context) serverErrorInternal(title string, err error) { if err != nil { log.ErrorWithSkip(2, "%s: %v", title, err) - if macaron.Env != macaron.PROD { + if !setting.IsProd() { ctx.Data["ErrorMsg"] = err } } @@ -224,6 +251,44 @@ func (ctx *Context) NotFoundOrServerError(title string, errck func(error) bool, ctx.serverErrorInternal(title, err) } +// Header returns a header +func (ctx *Context) Header() http.Header { + return ctx.Resp.Header() +} + +// FIXME: We should differ Query and Form, currently we just use form as query +// Currently to be compatible with macaron, we keep it. + +// Query returns request form as string with default +func (ctx *Context) Query(key string, defaults ...string) string { + return (*Forms)(ctx.Req).MustString(key, defaults...) +} + +// QueryTrim returns request form as string with default and trimmed spaces +func (ctx *Context) QueryTrim(key string, defaults ...string) string { + return (*Forms)(ctx.Req).MustTrimmed(key, defaults...) +} + +// QueryStrings returns request form as strings with default +func (ctx *Context) QueryStrings(key string, defaults ...[]string) []string { + return (*Forms)(ctx.Req).MustStrings(key, defaults...) +} + +// QueryInt returns request form as int with default +func (ctx *Context) QueryInt(key string, defaults ...int) int { + return (*Forms)(ctx.Req).MustInt(key, defaults...) +} + +// QueryInt64 returns request form as int64 with default +func (ctx *Context) QueryInt64(key string, defaults ...int64) int64 { + return (*Forms)(ctx.Req).MustInt64(key, defaults...) +} + +// QueryBool returns request form as bool with default +func (ctx *Context) QueryBool(key string, defaults ...bool) bool { + return (*Forms)(ctx.Req).MustBool(key, defaults...) +} + // HandleText handles HTTP status code func (ctx *Context) HandleText(status int, title string) { if (status/100 == 4) || (status/100 == 5) { @@ -249,66 +314,324 @@ func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interfa ctx.Resp.Header().Set("Cache-Control", "must-revalidate") ctx.Resp.Header().Set("Pragma", "public") ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") - http.ServeContent(ctx.Resp, ctx.Req.Request, name, modtime, r) + http.ServeContent(ctx.Resp, ctx.Req, name, modtime, r) +} + +// PlainText render content as plain text +func (ctx *Context) PlainText(status int, bs []byte) { + ctx.Resp.WriteHeader(status) + ctx.Resp.Header().Set("Content-Type", "text/plain;charset=utf8") + if _, err := ctx.Resp.Write(bs); err != nil { + ctx.ServerError("Render JSON failed", err) + } +} + +// ServeFile serves given file to response. +func (ctx *Context) ServeFile(file string, names ...string) { + var name string + if len(names) > 0 { + name = names[0] + } else { + name = path.Base(file) + } + ctx.Resp.Header().Set("Content-Description", "File Transfer") + ctx.Resp.Header().Set("Content-Type", "application/octet-stream") + ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+name) + ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary") + ctx.Resp.Header().Set("Expires", "0") + ctx.Resp.Header().Set("Cache-Control", "must-revalidate") + ctx.Resp.Header().Set("Pragma", "public") + http.ServeFile(ctx.Resp, ctx.Req, file) +} + +// Error returned an error to web browser +func (ctx *Context) Error(status int, contents ...string) { + var v = http.StatusText(status) + if len(contents) > 0 { + v = contents[0] + } + http.Error(ctx.Resp, v, status) +} + +// JSON render content as JSON +func (ctx *Context) JSON(status int, content interface{}) { + ctx.Resp.WriteHeader(status) + ctx.Resp.Header().Set("Content-Type", "application/json;charset=utf8") + if err := json.NewEncoder(ctx.Resp).Encode(content); err != nil { + ctx.ServerError("Render JSON failed", err) + } +} + +// Redirect redirect the request +func (ctx *Context) Redirect(location string, status ...int) { + code := http.StatusFound + if len(status) == 1 { + code = status[0] + } + + http.Redirect(ctx.Resp, ctx.Req, location, code) +} + +// SetCookie set cookies to web browser +func (ctx *Context) SetCookie(name string, value string, others ...interface{}) { + middlewares.SetCookie(ctx.Resp, name, value, others...) +} + +// GetCookie returns given cookie value from request header. +func (ctx *Context) GetCookie(name string) string { + return middlewares.GetCookie(ctx.Req, name) +} + +// GetSuperSecureCookie returns given cookie value from request header with secret string. +func (ctx *Context) GetSuperSecureCookie(secret, name string) (string, bool) { + val := ctx.GetCookie(name) + if val == "" { + return "", false + } + + text, err := hex.DecodeString(val) + if err != nil { + return "", false + } + + key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New) + text, err = com.AESGCMDecrypt(key, text) + return string(text), err == nil +} + +// SetSuperSecureCookie sets given cookie value to response header with secret string. +func (ctx *Context) SetSuperSecureCookie(secret, name, value string, others ...interface{}) { + key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New) + text, err := com.AESGCMEncrypt(key, []byte(value)) + if err != nil { + panic("error encrypting cookie: " + err.Error()) + } + + ctx.SetCookie(name, hex.EncodeToString(text), others...) +} + +// GetCookieInt returns cookie result in int type. +func (ctx *Context) GetCookieInt(name string) int { + r, _ := strconv.Atoi(ctx.GetCookie(name)) + return r +} + +// GetCookieInt64 returns cookie result in int64 type. +func (ctx *Context) GetCookieInt64(name string) int64 { + r, _ := strconv.ParseInt(ctx.GetCookie(name), 10, 64) + return r +} + +// GetCookieFloat64 returns cookie result in float64 type. +func (ctx *Context) GetCookieFloat64(name string) float64 { + v, _ := strconv.ParseFloat(ctx.GetCookie(name), 64) + return v +} + +// RemoteAddr returns the client machie ip address +func (ctx *Context) RemoteAddr() string { + return ctx.Req.RemoteAddr +} + +// Params returns the param on route +func (ctx *Context) Params(p string) string { + s, _ := url.PathUnescape(chi.URLParam(ctx.Req, strings.TrimPrefix(p, ":"))) + return s +} + +// ParamsInt64 returns the param on route as int64 +func (ctx *Context) ParamsInt64(p string) int64 { + v, _ := strconv.ParseInt(ctx.Params(p), 10, 64) + return v +} + +// SetParams set params into routes +func (ctx *Context) SetParams(k, v string) { + chiCtx := chi.RouteContext(ctx.Req.Context()) + chiCtx.URLParams.Add(strings.TrimPrefix(k, ":"), url.PathEscape(v)) +} + +// Write writes data to webbrowser +func (ctx *Context) Write(bs []byte) (int, error) { + return ctx.Resp.Write(bs) +} + +// Written returns true if there are something sent to web browser +func (ctx *Context) Written() bool { + return ctx.Resp.Status() > 0 +} + +// Status writes status code +func (ctx *Context) Status(status int) { + ctx.Resp.WriteHeader(status) +} + +// Handler represents a custom handler +type Handler func(*Context) + +// enumerate all content +var ( + contextKey interface{} = "default_context" +) + +// WithContext set up install context in request +func WithContext(req *http.Request, ctx *Context) *http.Request { + return req.WithContext(context.WithValue(req.Context(), contextKey, ctx)) +} + +// GetContext retrieves install context from request +func GetContext(req *http.Request) *Context { + return req.Context().Value(contextKey).(*Context) +} + +func getCsrfOpts() CsrfOptions { + return CsrfOptions{ + Secret: setting.SecretKey, + Cookie: setting.CSRFCookieName, + SetCookie: true, + Secure: setting.SessionConfig.Secure, + CookieHTTPOnly: setting.CSRFCookieHTTPOnly, + Header: "X-Csrf-Token", + CookieDomain: setting.SessionConfig.Domain, + CookiePath: setting.SessionConfig.CookiePath, + } } // Contexter initializes a classic context for a request. -func Contexter() macaron.Handler { - return func(c *macaron.Context, l i18n.Locale, cache cache.Cache, sess session.Store, f *session.Flash, x csrf.CSRF) { - ctx := &Context{ - Context: c, - Cache: cache, - csrf: x, - Flash: f, - Session: sess, - Link: setting.AppSubURL + strings.TrimSuffix(c.Req.URL.EscapedPath(), "/"), - Repo: &Repository{ - PullRequest: &PullRequest{}, - }, - Org: &Organization{}, +func Contexter() func(next http.Handler) http.Handler { + rnd := templates.HTMLRenderer() + + var c cache.Cache + var err error + if setting.CacheService.Enabled { + c, err = cache.NewCacher(cache.Options{ + Adapter: setting.CacheService.Adapter, + AdapterConfig: setting.CacheService.Conn, + Interval: setting.CacheService.Interval, + }) + if err != nil { + panic(err) } - ctx.Data["Language"] = ctx.Locale.Language() - c.Data["Link"] = ctx.Link - ctx.Data["CurrentURL"] = setting.AppSubURL + c.Req.URL.RequestURI() - ctx.Data["PageStartTime"] = time.Now() - // Quick responses appropriate go-get meta with status 200 - // regardless of if user have access to the repository, - // or the repository does not exist at all. - // This is particular a workaround for "go get" command which does not respect - // .netrc file. - if ctx.Query("go-get") == "1" { - ownerName := c.Params(":username") - repoName := c.Params(":reponame") - trimmedRepoName := strings.TrimSuffix(repoName, ".git") - - if ownerName == "" || trimmedRepoName == "" { - _, _ = c.Write([]byte(` + } + + var csrfOpts = getCsrfOpts() + //var flashEncryptionKey, _ = NewSecret() + + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + var locale = middlewares.Locale(resp, req) + var startTime = time.Now() + var link = setting.AppSubURL + strings.TrimSuffix(req.URL.EscapedPath(), "/") + var ctx = Context{ + Resp: NewResponse(resp), + Cache: c, + Locale: locale, + Link: link, + Render: rnd, + Session: session.GetSession(req), + Repo: &Repository{ + PullRequest: &PullRequest{}, + }, + Org: &Organization{}, + Data: map[string]interface{}{ + "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), + "PageStartTime": startTime, + "TmplLoadTimes": func() string { + return time.Since(startTime).String() + }, + "Link": link, + }, + } + + ctx.Req = WithContext(req, &ctx) + ctx.csrf = Csrfer(csrfOpts, &ctx) + + // Get flash. + flashCookie := ctx.GetCookie("macaron_flash") + vals, _ := url.ParseQuery(flashCookie) + if len(vals) > 0 { + f := &middlewares.Flash{ + DataStore: &ctx, + Values: vals, + ErrorMsg: vals.Get("error"), + SuccessMsg: vals.Get("success"), + InfoMsg: vals.Get("info"), + WarningMsg: vals.Get("warning"), + } + ctx.Data["Flash"] = f + } + + f := &middlewares.Flash{ + DataStore: &ctx, + Values: url.Values{}, + ErrorMsg: "", + WarningMsg: "", + InfoMsg: "", + SuccessMsg: "", + } + ctx.Resp.Before(func(resp ResponseWriter) { + if flash := f.Encode(); len(flash) > 0 { + if err == nil { + middlewares.SetCookie(resp, "macaron_flash", flash, 0, + setting.SessionConfig.CookiePath, + middlewares.Domain(setting.SessionConfig.Domain), + middlewares.HTTPOnly(true), + middlewares.Secure(setting.SessionConfig.Secure), + //middlewares.SameSite(opt.SameSite), FIXME: we need a samesite config + ) + return + } + } + + ctx.SetCookie("macaron_flash", "", -1, + setting.SessionConfig.CookiePath, + middlewares.Domain(setting.SessionConfig.Domain), + middlewares.HTTPOnly(true), + middlewares.Secure(setting.SessionConfig.Secure), + //middlewares.SameSite(), FIXME: we need a samesite config + ) + }) + + ctx.Flash = f + + // Quick responses appropriate go-get meta with status 200 + // regardless of if user have access to the repository, + // or the repository does not exist at all. + // This is particular a workaround for "go get" command which does not respect + // .netrc file. + if ctx.Query("go-get") == "1" { + ownerName := ctx.Params(":username") + repoName := ctx.Params(":reponame") + trimmedRepoName := strings.TrimSuffix(repoName, ".git") + + if ownerName == "" || trimmedRepoName == "" { + _, _ = ctx.Write([]byte(` invalid import path `)) - c.WriteHeader(400) - return - } - branchName := "master" - - repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName) - if err == nil && len(repo.DefaultBranch) > 0 { - branchName = repo.DefaultBranch - } - prefix := setting.AppURL + path.Join(url.PathEscape(ownerName), url.PathEscape(repoName), "src", "branch", util.PathEscapeSegments(branchName)) - - appURL, _ := url.Parse(setting.AppURL) - - insecure := "" - if appURL.Scheme == string(setting.HTTP) { - insecure = "--insecure " - } - c.Header().Set("Content-Type", "text/html") - c.WriteHeader(http.StatusOK) - _, _ = c.Write([]byte(com.Expand(` + ctx.Status(400) + return + } + branchName := "master" + + repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName) + if err == nil && len(repo.DefaultBranch) > 0 { + branchName = repo.DefaultBranch + } + prefix := setting.AppURL + path.Join(url.PathEscape(ownerName), url.PathEscape(repoName), "src", "branch", util.PathEscapeSegments(branchName)) + + appURL, _ := url.Parse(setting.AppURL) + + insecure := "" + if appURL.Scheme == string(setting.HTTP) { + insecure = "--insecure " + } + ctx.Header().Set("Content-Type", "text/html") + ctx.Status(http.StatusOK) + _, _ = ctx.Write([]byte(com.Expand(` @@ -319,60 +642,72 @@ func Contexter() macaron.Handler { `, map[string]string{ - "GoGetImport": ComposeGoGetImport(ownerName, trimmedRepoName), - "CloneLink": models.ComposeHTTPSCloneURL(ownerName, repoName), - "GoDocDirectory": prefix + "{/dir}", - "GoDocFile": prefix + "{/dir}/{file}#L{line}", - "Insecure": insecure, - }))) - return - } - - // Get user from session if logged in. - ctx.User, ctx.IsBasicAuth = sso.SignedInUser(ctx.Req.Request, c.Resp, ctx, ctx.Session) - - if ctx.User != nil { - ctx.IsSigned = true - ctx.Data["IsSigned"] = ctx.IsSigned - ctx.Data["SignedUser"] = ctx.User - ctx.Data["SignedUserID"] = ctx.User.ID - ctx.Data["SignedUserName"] = ctx.User.Name - ctx.Data["IsAdmin"] = ctx.User.IsAdmin - } else { - ctx.Data["SignedUserID"] = int64(0) - ctx.Data["SignedUserName"] = "" - } - - // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid. - if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { - if err := ctx.Req.ParseMultipartForm(setting.Attachment.MaxSize << 20); err != nil && !strings.Contains(err.Error(), "EOF") { // 32MB max size - ctx.ServerError("ParseMultipartForm", err) + "GoGetImport": ComposeGoGetImport(ownerName, trimmedRepoName), + "CloneLink": models.ComposeHTTPSCloneURL(ownerName, repoName), + "GoDocDirectory": prefix + "{/dir}", + "GoDocFile": prefix + "{/dir}/{file}#L{line}", + "Insecure": insecure, + }))) return } - } - - ctx.Resp.Header().Set(`X-Frame-Options`, `SAMEORIGIN`) - - ctx.Data["CsrfToken"] = html.EscapeString(x.GetToken()) - ctx.Data["CsrfTokenHtml"] = template.HTML(``) - log.Debug("Session ID: %s", sess.ID()) - log.Debug("CSRF Token: %v", ctx.Data["CsrfToken"]) - - ctx.Data["IsLandingPageHome"] = setting.LandingPageURL == setting.LandingPageHome - ctx.Data["IsLandingPageExplore"] = setting.LandingPageURL == setting.LandingPageExplore - ctx.Data["IsLandingPageOrganizations"] = setting.LandingPageURL == setting.LandingPageOrganizations - ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton - ctx.Data["ShowMilestonesDashboardPage"] = setting.Service.ShowMilestonesDashboardPage - ctx.Data["ShowFooterBranding"] = setting.ShowFooterBranding - ctx.Data["ShowFooterVersion"] = setting.ShowFooterVersion + // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid. + if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { + if err := ctx.Req.ParseMultipartForm(setting.Attachment.MaxSize << 20); err != nil && !strings.Contains(err.Error(), "EOF") { // 32MB max size + ctx.ServerError("ParseMultipartForm", err) + return + } + } - ctx.Data["EnableSwagger"] = setting.API.EnableSwagger - ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn - ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations + // Get user from session if logged in. + ctx.User, ctx.IsBasicAuth = sso.SignedInUser(ctx.Req, ctx.Resp, &ctx, ctx.Session) + + if ctx.User != nil { + ctx.IsSigned = true + ctx.Data["IsSigned"] = ctx.IsSigned + ctx.Data["SignedUser"] = ctx.User + ctx.Data["SignedUserID"] = ctx.User.ID + ctx.Data["SignedUserName"] = ctx.User.Name + ctx.Data["IsAdmin"] = ctx.User.IsAdmin + } else { + ctx.Data["SignedUserID"] = int64(0) + ctx.Data["SignedUserName"] = "" + } - ctx.Data["ManifestData"] = setting.ManifestData + ctx.Resp.Header().Set(`X-Frame-Options`, `SAMEORIGIN`) + + ctx.Data["CsrfToken"] = html.EscapeString(ctx.csrf.GetToken()) + ctx.Data["CsrfTokenHtml"] = template.HTML(``) + log.Debug("Session ID: %s", ctx.Session.ID()) + log.Debug("CSRF Token: %v", ctx.Data["CsrfToken"]) + + ctx.Data["IsLandingPageHome"] = setting.LandingPageURL == setting.LandingPageHome + ctx.Data["IsLandingPageExplore"] = setting.LandingPageURL == setting.LandingPageExplore + ctx.Data["IsLandingPageOrganizations"] = setting.LandingPageURL == setting.LandingPageOrganizations + + ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton + ctx.Data["ShowMilestonesDashboardPage"] = setting.Service.ShowMilestonesDashboardPage + ctx.Data["ShowFooterBranding"] = setting.ShowFooterBranding + ctx.Data["ShowFooterVersion"] = setting.ShowFooterVersion + + ctx.Data["EnableSwagger"] = setting.API.EnableSwagger + ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn + ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations + + ctx.Data["ManifestData"] = setting.ManifestData + + ctx.Data["i18n"] = locale + ctx.Data["Tr"] = i18n.Tr + ctx.Data["Lang"] = locale.Language() + ctx.Data["AllLangs"] = translation.AllLangs() + for _, lang := range translation.AllLangs() { + if lang.Lang == locale.Language() { + ctx.Data["LangName"] = lang.Name + break + } + } - c.Map(ctx) + next.ServeHTTP(ctx.Resp, ctx.Req) + }) } } diff --git a/vendor/gitea.com/macaron/csrf/csrf.go b/modules/context/csrf.go similarity index 69% rename from vendor/gitea.com/macaron/csrf/csrf.go rename to modules/context/csrf.go index 66f5b40a8e8ee..4a26664bf36b8 100644 --- a/vendor/gitea.com/macaron/csrf/csrf.go +++ b/modules/context/csrf.go @@ -1,5 +1,6 @@ // Copyright 2013 Martini Authors // Copyright 2014 The Macaron Authors +// Copyright 2021 The Gitea Authors // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain @@ -13,24 +14,17 @@ // License for the specific language governing permissions and limitations // under the License. -// Package csrf is a middleware that generates and validates CSRF tokens for Macaron. -package csrf +// a middleware that generates and validates CSRF tokens. + +package context import ( "net/http" "time" - "gitea.com/macaron/macaron" - "gitea.com/macaron/session" "github.com/unknwon/com" ) -const _VERSION = "0.1.1" - -func Version() string { - return _VERSION -} - // CSRF represents a CSRF service and is used to get the current token and validate a suspect token. type CSRF interface { // Return HTTP header to search for token. @@ -42,7 +36,7 @@ type CSRF interface { // Return cookie path GetCookiePath() string // Return the flag value used for the csrf token. - GetCookieHttpOnly() bool + GetCookieHTTPOnly() bool // Return the token. GetToken() string // Validate by token. @@ -63,7 +57,7 @@ type csrf struct { //Cookie path CookiePath string // Cookie HttpOnly flag value used for the csrf token. - CookieHttpOnly bool + CookieHTTPOnly bool // Token generated to pass via header, cookie, or hidden form value. Token string // This value must be unique per user. @@ -94,9 +88,9 @@ func (c *csrf) GetCookiePath() string { return c.CookiePath } -// GetCookieHttpOnly returns the flag value used for the csrf token. -func (c *csrf) GetCookieHttpOnly() bool { - return c.CookieHttpOnly +// GetCookieHTTPOnly returns the flag value used for the csrf token. +func (c *csrf) GetCookieHTTPOnly() bool { + return c.CookieHTTPOnly } // GetToken returns the current token. This is typically used @@ -115,8 +109,8 @@ func (c *csrf) Error(w http.ResponseWriter) { c.ErrorFunc(w) } -// Options maintains options to manage behavior of Generate. -type Options struct { +// CsrfOptions maintains options to manage behavior of Generate. +type CsrfOptions struct { // The global secret value used to generate Tokens. Secret string // HTTP header used to set and get token. @@ -129,11 +123,13 @@ type Options struct { CookieDomain string // Cookie path. CookiePath string - CookieHttpOnly bool + CookieHTTPOnly bool + // SameSite set the cookie SameSite type + SameSite http.SameSite // Key used for getting the unique ID per user. SessionKey string - // oldSeesionKey saves old value corresponding to SessionKey. - oldSeesionKey string + // oldSessionKey saves old value corresponding to SessionKey. + oldSessionKey string // If true, send token via X-CSRFToken header. SetHeader bool // If true, send token via _csrf cookie. @@ -144,10 +140,12 @@ type Options struct { Origin bool // The function called when Validate fails. ErrorFunc func(w http.ResponseWriter) + // Cookie life time. Default is 0 + CookieLifeTime int } -func prepareOptions(options []Options) Options { - var opt Options +func prepareOptions(options []CsrfOptions) CsrfOptions { + var opt CsrfOptions if len(options) > 0 { opt = options[0] } @@ -171,7 +169,7 @@ func prepareOptions(options []Options) Options { if len(opt.SessionKey) == 0 { opt.SessionKey = "uid" } - opt.oldSeesionKey = "_old_" + opt.SessionKey + opt.oldSessionKey = "_old_" + opt.SessionKey if opt.ErrorFunc == nil { opt.ErrorFunc = func(w http.ResponseWriter) { http.Error(w, "Invalid csrf token.", http.StatusBadRequest) @@ -181,73 +179,73 @@ func prepareOptions(options []Options) Options { return opt } -// Generate maps CSRF to each request. If this request is a Get request, it will generate a new token. +// Csrfer maps CSRF to each request. If this request is a Get request, it will generate a new token. // Additionally, depending on options set, generated tokens will be sent via Header and/or Cookie. -func Generate(options ...Options) macaron.Handler { - opt := prepareOptions(options) - return func(ctx *macaron.Context, sess session.Store) { - x := &csrf{ - Secret: opt.Secret, - Header: opt.Header, - Form: opt.Form, - Cookie: opt.Cookie, - CookieDomain: opt.CookieDomain, - CookiePath: opt.CookiePath, - CookieHttpOnly: opt.CookieHttpOnly, - ErrorFunc: opt.ErrorFunc, - } - ctx.MapTo(x, (*CSRF)(nil)) +func Csrfer(opt CsrfOptions, ctx *Context) CSRF { + opt = prepareOptions([]CsrfOptions{opt}) + x := &csrf{ + Secret: opt.Secret, + Header: opt.Header, + Form: opt.Form, + Cookie: opt.Cookie, + CookieDomain: opt.CookieDomain, + CookiePath: opt.CookiePath, + CookieHTTPOnly: opt.CookieHTTPOnly, + ErrorFunc: opt.ErrorFunc, + } - if opt.Origin && len(ctx.Req.Header.Get("Origin")) > 0 { - return - } + if opt.Origin && len(ctx.Req.Header.Get("Origin")) > 0 { + return x + } - x.ID = "0" - uid := sess.Get(opt.SessionKey) - if uid != nil { - x.ID = com.ToStr(uid) - } + x.ID = "0" + uid := ctx.Session.Get(opt.SessionKey) + if uid != nil { + x.ID = com.ToStr(uid) + } - needsNew := false - oldUid := sess.Get(opt.oldSeesionKey) - if oldUid == nil || oldUid.(string) != x.ID { - needsNew = true - sess.Set(opt.oldSeesionKey, x.ID) + needsNew := false + oldUID := ctx.Session.Get(opt.oldSessionKey) + if oldUID == nil || oldUID.(string) != x.ID { + needsNew = true + _ = ctx.Session.Set(opt.oldSessionKey, x.ID) + } else { + // If cookie present, map existing token, else generate a new one. + if val := ctx.GetCookie(opt.Cookie); len(val) > 0 { + // FIXME: test coverage. + x.Token = val } else { - // If cookie present, map existing token, else generate a new one. - if val := ctx.GetCookie(opt.Cookie); len(val) > 0 { - // FIXME: test coverage. - x.Token = val - } else { - needsNew = true - } + needsNew = true } + } - if needsNew { - // FIXME: actionId. - x.Token = GenerateToken(x.Secret, x.ID, "POST") - if opt.SetCookie { - ctx.SetCookie(opt.Cookie, x.Token, 0, opt.CookiePath, opt.CookieDomain, opt.Secure, opt.CookieHttpOnly, time.Now().AddDate(0, 0, 1)) + if needsNew { + // FIXME: actionId. + x.Token = GenerateToken(x.Secret, x.ID, "POST") + if opt.SetCookie { + var expires interface{} + if opt.CookieLifeTime == 0 { + expires = time.Now().AddDate(0, 0, 1) } - } - - if opt.SetHeader { - ctx.Resp.Header().Add(opt.Header, x.Token) + ctx.SetCookie(opt.Cookie, x.Token, opt.CookieLifeTime, opt.CookiePath, opt.CookieDomain, opt.Secure, opt.CookieHTTPOnly, expires, + func(c *http.Cookie) { + c.SameSite = opt.SameSite + }, + ) } } -} -// Csrfer maps CSRF to each request. If this request is a Get request, it will generate a new token. -// Additionally, depending on options set, generated tokens will be sent via Header and/or Cookie. -func Csrfer(options ...Options) macaron.Handler { - return Generate(options...) + if opt.SetHeader { + ctx.Resp.Header().Add(opt.Header, x.Token) + } + return x } // Validate should be used as a per route middleware. It attempts to get a token from a "X-CSRFToken" // HTTP header and then a "_csrf" form value. If one of these is found, the token will be validated // using ValidToken. If this validation fails, custom Error is sent in the reply. // If neither a header or form value is found, http.StatusBadRequest is sent. -func Validate(ctx *macaron.Context, x CSRF) { +func Validate(ctx *Context, x CSRF) { if token := ctx.Req.Header.Get(x.GetHeaderName()); len(token) > 0 { if !x.ValidToken(token) { ctx.SetCookie(x.GetCookieName(), "", -1, x.GetCookiePath()) diff --git a/modules/context/form.go b/modules/context/form.go new file mode 100644 index 0000000000000..c7b76c614c27a --- /dev/null +++ b/modules/context/form.go @@ -0,0 +1,227 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package context + +import ( + "errors" + "net/http" + "net/url" + "strconv" + "strings" + "text/template" + + "code.gitea.io/gitea/modules/log" +) + +// Forms a new enhancement of http.Request +type Forms http.Request + +// Values returns http.Request values +func (f *Forms) Values() url.Values { + return (*http.Request)(f).Form +} + +// String returns request form as string +func (f *Forms) String(key string) (string, error) { + return (*http.Request)(f).FormValue(key), nil +} + +// Trimmed returns request form as string with trimed spaces left and right +func (f *Forms) Trimmed(key string) (string, error) { + return strings.TrimSpace((*http.Request)(f).FormValue(key)), nil +} + +// Strings returns request form as strings +func (f *Forms) Strings(key string) ([]string, error) { + if (*http.Request)(f).Form == nil { + if err := (*http.Request)(f).ParseMultipartForm(32 << 20); err != nil { + return nil, err + } + } + if v, ok := (*http.Request)(f).Form[key]; ok { + return v, nil + } + return nil, errors.New("not exist") +} + +// Escape returns request form as escaped string +func (f *Forms) Escape(key string) (string, error) { + return template.HTMLEscapeString((*http.Request)(f).FormValue(key)), nil +} + +// Int returns request form as int +func (f *Forms) Int(key string) (int, error) { + return strconv.Atoi((*http.Request)(f).FormValue(key)) +} + +// Int32 returns request form as int32 +func (f *Forms) Int32(key string) (int32, error) { + v, err := strconv.ParseInt((*http.Request)(f).FormValue(key), 10, 32) + return int32(v), err +} + +// Int64 returns request form as int64 +func (f *Forms) Int64(key string) (int64, error) { + return strconv.ParseInt((*http.Request)(f).FormValue(key), 10, 64) +} + +// Uint returns request form as uint +func (f *Forms) Uint(key string) (uint, error) { + v, err := strconv.ParseUint((*http.Request)(f).FormValue(key), 10, 64) + return uint(v), err +} + +// Uint32 returns request form as uint32 +func (f *Forms) Uint32(key string) (uint32, error) { + v, err := strconv.ParseUint((*http.Request)(f).FormValue(key), 10, 32) + return uint32(v), err +} + +// Uint64 returns request form as uint64 +func (f *Forms) Uint64(key string) (uint64, error) { + return strconv.ParseUint((*http.Request)(f).FormValue(key), 10, 64) +} + +// Bool returns request form as bool +func (f *Forms) Bool(key string) (bool, error) { + return strconv.ParseBool((*http.Request)(f).FormValue(key)) +} + +// Float32 returns request form as float32 +func (f *Forms) Float32(key string) (float32, error) { + v, err := strconv.ParseFloat((*http.Request)(f).FormValue(key), 64) + return float32(v), err +} + +// Float64 returns request form as float64 +func (f *Forms) Float64(key string) (float64, error) { + return strconv.ParseFloat((*http.Request)(f).FormValue(key), 64) +} + +// MustString returns request form as string with default +func (f *Forms) MustString(key string, defaults ...string) string { + if v := (*http.Request)(f).FormValue(key); len(v) > 0 { + return v + } + if len(defaults) > 0 { + return defaults[0] + } + return "" +} + +// MustTrimmed returns request form as string with default +func (f *Forms) MustTrimmed(key string, defaults ...string) string { + return strings.TrimSpace(f.MustString(key, defaults...)) +} + +// MustStrings returns request form as strings with default +func (f *Forms) MustStrings(key string, defaults ...[]string) []string { + if (*http.Request)(f).Form == nil { + if err := (*http.Request)(f).ParseMultipartForm(32 << 20); err != nil { + log.Error("ParseMultipartForm: %v", err) + return []string{} + } + } + + if v, ok := (*http.Request)(f).Form[key]; ok { + return v + } + if len(defaults) > 0 { + return defaults[0] + } + return []string{} +} + +// MustEscape returns request form as escaped string with default +func (f *Forms) MustEscape(key string, defaults ...string) string { + if v := (*http.Request)(f).FormValue(key); len(v) > 0 { + return template.HTMLEscapeString(v) + } + if len(defaults) > 0 { + return defaults[0] + } + return "" +} + +// MustInt returns request form as int with default +func (f *Forms) MustInt(key string, defaults ...int) int { + v, err := strconv.Atoi((*http.Request)(f).FormValue(key)) + if len(defaults) > 0 && err != nil { + return defaults[0] + } + return v +} + +// MustInt32 returns request form as int32 with default +func (f *Forms) MustInt32(key string, defaults ...int32) int32 { + v, err := strconv.ParseInt((*http.Request)(f).FormValue(key), 10, 32) + if len(defaults) > 0 && err != nil { + return defaults[0] + } + return int32(v) +} + +// MustInt64 returns request form as int64 with default +func (f *Forms) MustInt64(key string, defaults ...int64) int64 { + v, err := strconv.ParseInt((*http.Request)(f).FormValue(key), 10, 64) + if len(defaults) > 0 && err != nil { + return defaults[0] + } + return v +} + +// MustUint returns request form as uint with default +func (f *Forms) MustUint(key string, defaults ...uint) uint { + v, err := strconv.ParseUint((*http.Request)(f).FormValue(key), 10, 64) + if len(defaults) > 0 && err != nil { + return defaults[0] + } + return uint(v) +} + +// MustUint32 returns request form as uint32 with default +func (f *Forms) MustUint32(key string, defaults ...uint32) uint32 { + v, err := strconv.ParseUint((*http.Request)(f).FormValue(key), 10, 32) + if len(defaults) > 0 && err != nil { + return defaults[0] + } + return uint32(v) +} + +// MustUint64 returns request form as uint64 with default +func (f *Forms) MustUint64(key string, defaults ...uint64) uint64 { + v, err := strconv.ParseUint((*http.Request)(f).FormValue(key), 10, 64) + if len(defaults) > 0 && err != nil { + return defaults[0] + } + return v +} + +// MustFloat32 returns request form as float32 with default +func (f *Forms) MustFloat32(key string, defaults ...float32) float32 { + v, err := strconv.ParseFloat((*http.Request)(f).FormValue(key), 32) + if len(defaults) > 0 && err != nil { + return defaults[0] + } + return float32(v) +} + +// MustFloat64 returns request form as float64 with default +func (f *Forms) MustFloat64(key string, defaults ...float64) float64 { + v, err := strconv.ParseFloat((*http.Request)(f).FormValue(key), 64) + if len(defaults) > 0 && err != nil { + return defaults[0] + } + return v +} + +// MustBool returns request form as bool with default +func (f *Forms) MustBool(key string, defaults ...bool) bool { + v, err := strconv.ParseBool((*http.Request)(f).FormValue(key)) + if len(defaults) > 0 && err != nil { + return defaults[0] + } + return v +} diff --git a/modules/context/org.go b/modules/context/org.go index f61a39c666b95..83d385a1e934b 100644 --- a/modules/context/org.go +++ b/modules/context/org.go @@ -10,8 +10,6 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/setting" - - "gitea.com/macaron/macaron" ) // Organization contains organization context @@ -173,7 +171,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { } // OrgAssignment returns a macaron middleware to handle organization assignment -func OrgAssignment(args ...bool) macaron.Handler { +func OrgAssignment(args ...bool) func(ctx *Context) { return func(ctx *Context) { HandleOrgAssignment(ctx, args...) } diff --git a/modules/context/permission.go b/modules/context/permission.go index 151be9f8320ba..6fb8237e22cbe 100644 --- a/modules/context/permission.go +++ b/modules/context/permission.go @@ -7,12 +7,10 @@ package context import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/log" - - "gitea.com/macaron/macaron" ) // RequireRepoAdmin returns a macaron middleware for requiring repository admin permission -func RequireRepoAdmin() macaron.Handler { +func RequireRepoAdmin() func(ctx *Context) { return func(ctx *Context) { if !ctx.IsSigned || !ctx.Repo.IsAdmin() { ctx.NotFound(ctx.Req.URL.RequestURI(), nil) @@ -22,7 +20,7 @@ func RequireRepoAdmin() macaron.Handler { } // RequireRepoWriter returns a macaron middleware for requiring repository write to the specify unitType -func RequireRepoWriter(unitType models.UnitType) macaron.Handler { +func RequireRepoWriter(unitType models.UnitType) func(ctx *Context) { return func(ctx *Context) { if !ctx.Repo.CanWrite(unitType) { ctx.NotFound(ctx.Req.URL.RequestURI(), nil) @@ -32,7 +30,7 @@ func RequireRepoWriter(unitType models.UnitType) macaron.Handler { } // RequireRepoWriterOr returns a macaron middleware for requiring repository write to one of the unit permission -func RequireRepoWriterOr(unitTypes ...models.UnitType) macaron.Handler { +func RequireRepoWriterOr(unitTypes ...models.UnitType) func(ctx *Context) { return func(ctx *Context) { for _, unitType := range unitTypes { if ctx.Repo.CanWrite(unitType) { @@ -44,7 +42,7 @@ func RequireRepoWriterOr(unitTypes ...models.UnitType) macaron.Handler { } // RequireRepoReader returns a macaron middleware for requiring repository read to the specify unitType -func RequireRepoReader(unitType models.UnitType) macaron.Handler { +func RequireRepoReader(unitType models.UnitType) func(ctx *Context) { return func(ctx *Context) { if !ctx.Repo.CanRead(unitType) { if log.IsTrace() { @@ -70,7 +68,7 @@ func RequireRepoReader(unitType models.UnitType) macaron.Handler { } // RequireRepoReaderOr returns a macaron middleware for requiring repository write to one of the unit permission -func RequireRepoReaderOr(unitTypes ...models.UnitType) macaron.Handler { +func RequireRepoReaderOr(unitTypes ...models.UnitType) func(ctx *Context) { return func(ctx *Context) { for _, unitType := range unitTypes { if ctx.Repo.CanRead(unitType) { diff --git a/modules/context/private.go b/modules/context/private.go new file mode 100644 index 0000000000000..a246100050845 --- /dev/null +++ b/modules/context/private.go @@ -0,0 +1,45 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package context + +import ( + "context" + "net/http" +) + +// PrivateContext represents a context for private routes +type PrivateContext struct { + *Context +} + +var ( + privateContextKey interface{} = "default_private_context" +) + +// WithPrivateContext set up private context in request +func WithPrivateContext(req *http.Request, ctx *PrivateContext) *http.Request { + return req.WithContext(context.WithValue(req.Context(), privateContextKey, ctx)) +} + +// GetPrivateContext returns a context for Private routes +func GetPrivateContext(req *http.Request) *PrivateContext { + return req.Context().Value(privateContextKey).(*PrivateContext) +} + +// PrivateContexter returns apicontext as macaron middleware +func PrivateContexter() func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + ctx := &PrivateContext{ + Context: &Context{ + Resp: NewResponse(w), + Data: map[string]interface{}{}, + }, + } + ctx.Req = WithPrivateContext(req, ctx) + next.ServeHTTP(ctx.Resp, ctx.Req) + }) + } +} diff --git a/modules/context/repo.go b/modules/context/repo.go index 63cb02dc067d7..79192267fbf48 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -8,6 +8,7 @@ package context import ( "fmt" "io/ioutil" + "net/http" "net/url" "path" "strings" @@ -21,7 +22,6 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" - "gitea.com/macaron/macaron" "github.com/editorconfig/editorconfig-core-go/v2" "github.com/unknwon/com" ) @@ -81,7 +81,7 @@ func (r *Repository) CanCreateBranch() bool { } // RepoMustNotBeArchived checks if a repo is archived -func RepoMustNotBeArchived() macaron.Handler { +func RepoMustNotBeArchived() func(ctx *Context) { return func(ctx *Context) { if ctx.Repo.Repository.IsArchived { ctx.NotFound("IsArchived", fmt.Errorf(ctx.Tr("repo.archive.title"))) @@ -374,7 +374,7 @@ func repoAssignment(ctx *Context, repo *models.Repository) { } // RepoIDAssignment returns a macaron handler which assigns the repo to the context. -func RepoIDAssignment() macaron.Handler { +func RepoIDAssignment() func(ctx *Context) { return func(ctx *Context) { repoID := ctx.ParamsInt64(":repoid") @@ -394,223 +394,220 @@ func RepoIDAssignment() macaron.Handler { } // RepoAssignment returns a macaron to handle repository assignment -func RepoAssignment() macaron.Handler { - return func(ctx *Context) { - var ( - owner *models.User - err error - ) - - userName := ctx.Params(":username") - repoName := ctx.Params(":reponame") +func RepoAssignment() func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + var ( + owner *models.User + err error + ctx = GetContext(req) + ) + + userName := ctx.Params(":username") + repoName := ctx.Params(":reponame") + repoName = strings.TrimSuffix(repoName, ".git") + + // Check if the user is the same as the repository owner + if ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName) { + owner = ctx.User + } else { + owner, err = models.GetUserByName(userName) + if err != nil { + if models.IsErrUserNotExist(err) { + if ctx.Query("go-get") == "1" { + EarlyResponseForGoGetMeta(ctx) + return + } + ctx.NotFound("GetUserByName", nil) + } else { + ctx.ServerError("GetUserByName", err) + } + return + } + } + ctx.Repo.Owner = owner + ctx.Data["Username"] = ctx.Repo.Owner.Name - // Check if the user is the same as the repository owner - if ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName) { - owner = ctx.User - } else { - owner, err = models.GetUserByName(userName) + // Get repository. + repo, err := models.GetRepositoryByName(owner.ID, repoName) if err != nil { - if models.IsErrUserNotExist(err) { - redirectUserID, err := models.LookupUserRedirect(userName) + if models.IsErrRepoNotExist(err) { + redirectRepoID, err := models.LookupRepoRedirect(owner.ID, repoName) if err == nil { - RedirectToUser(ctx, userName, redirectUserID) - } else if models.IsErrUserRedirectNotExist(err) { + RedirectToRepo(ctx, redirectRepoID) + } else if models.IsErrRepoRedirectNotExist(err) { if ctx.Query("go-get") == "1" { EarlyResponseForGoGetMeta(ctx) return } - ctx.NotFound("GetUserByName", nil) + ctx.NotFound("GetRepositoryByName", nil) } else { - ctx.ServerError("LookupUserRedirect", err) + ctx.ServerError("LookupRepoRedirect", err) } } else { - ctx.ServerError("GetUserByName", err) + ctx.ServerError("GetRepositoryByName", err) } return } - } - ctx.Repo.Owner = owner - ctx.Data["Username"] = ctx.Repo.Owner.Name + repo.Owner = owner - // Get repository. - repo, err := models.GetRepositoryByName(owner.ID, repoName) - if err != nil { - if models.IsErrRepoNotExist(err) { - redirectRepoID, err := models.LookupRepoRedirect(owner.ID, repoName) - if err == nil { - RedirectToRepo(ctx, redirectRepoID) - } else if models.IsErrRepoRedirectNotExist(err) { - if ctx.Query("go-get") == "1" { - EarlyResponseForGoGetMeta(ctx) - return - } - ctx.NotFound("GetRepositoryByName", nil) - } else { - ctx.ServerError("LookupRepoRedirect", err) - } - } else { - ctx.ServerError("GetRepositoryByName", err) + repoAssignment(ctx, repo) + if ctx.Written() { + return } - return - } - repo.Owner = owner - repoAssignment(ctx, repo) - if ctx.Written() { - return - } + ctx.Repo.RepoLink = repo.Link() + ctx.Data["RepoLink"] = ctx.Repo.RepoLink + ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name - ctx.Repo.RepoLink = repo.Link() - ctx.Data["RepoLink"] = ctx.Repo.RepoLink - ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name + unit, err := ctx.Repo.Repository.GetUnit(models.UnitTypeExternalTracker) + if err == nil { + ctx.Data["RepoExternalIssuesLink"] = unit.ExternalTrackerConfig().ExternalTrackerURL + } - unit, err := ctx.Repo.Repository.GetUnit(models.UnitTypeExternalTracker) - if err == nil { - ctx.Data["RepoExternalIssuesLink"] = unit.ExternalTrackerConfig().ExternalTrackerURL - } + ctx.Data["NumTags"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{ + IncludeTags: true, + }) + if err != nil { + ctx.ServerError("GetReleaseCountByRepoID", err) + return + } + ctx.Data["NumReleases"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{}) + if err != nil { + ctx.ServerError("GetReleaseCountByRepoID", err) + return + } - ctx.Data["NumTags"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{ - IncludeTags: true, - }) - if err != nil { - ctx.ServerError("GetReleaseCountByRepoID", err) - return - } - ctx.Data["NumReleases"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{}) - if err != nil { - ctx.ServerError("GetReleaseCountByRepoID", err) - return - } + ctx.Data["Title"] = owner.Name + "/" + repo.Name + ctx.Data["Repository"] = repo + ctx.Data["Owner"] = ctx.Repo.Repository.Owner + ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner() + ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin() + ctx.Data["RepoOwnerIsOrganization"] = repo.Owner.IsOrganization() + ctx.Data["CanWriteCode"] = ctx.Repo.CanWrite(models.UnitTypeCode) + ctx.Data["CanWriteIssues"] = ctx.Repo.CanWrite(models.UnitTypeIssues) + ctx.Data["CanWritePulls"] = ctx.Repo.CanWrite(models.UnitTypePullRequests) + + if ctx.Data["CanSignedUserFork"], err = ctx.Repo.Repository.CanUserFork(ctx.User); err != nil { + ctx.ServerError("CanUserFork", err) + return + } - ctx.Data["Title"] = owner.Name + "/" + repo.Name - ctx.Data["Repository"] = repo - ctx.Data["Owner"] = ctx.Repo.Repository.Owner - ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner() - ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin() - ctx.Data["RepoOwnerIsOrganization"] = repo.Owner.IsOrganization() - ctx.Data["CanWriteCode"] = ctx.Repo.CanWrite(models.UnitTypeCode) - ctx.Data["CanWriteIssues"] = ctx.Repo.CanWrite(models.UnitTypeIssues) - ctx.Data["CanWritePulls"] = ctx.Repo.CanWrite(models.UnitTypePullRequests) - - if ctx.Data["CanSignedUserFork"], err = ctx.Repo.Repository.CanUserFork(ctx.User); err != nil { - ctx.ServerError("CanUserFork", err) - return - } + ctx.Data["DisableSSH"] = setting.SSH.Disabled + ctx.Data["ExposeAnonSSH"] = setting.SSH.ExposeAnonymous + ctx.Data["DisableHTTP"] = setting.Repository.DisableHTTPGit + ctx.Data["RepoSearchEnabled"] = setting.Indexer.RepoIndexerEnabled + ctx.Data["CloneLink"] = repo.CloneLink() + ctx.Data["WikiCloneLink"] = repo.WikiCloneLink() - ctx.Data["DisableSSH"] = setting.SSH.Disabled - ctx.Data["ExposeAnonSSH"] = setting.SSH.ExposeAnonymous - ctx.Data["DisableHTTP"] = setting.Repository.DisableHTTPGit - ctx.Data["RepoSearchEnabled"] = setting.Indexer.RepoIndexerEnabled - ctx.Data["CloneLink"] = repo.CloneLink() - ctx.Data["WikiCloneLink"] = repo.WikiCloneLink() + if ctx.IsSigned { + ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) + ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) + } - if ctx.IsSigned { - ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) - ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) - } + if repo.IsFork { + RetrieveBaseRepo(ctx, repo) + if ctx.Written() { + return + } + } - if repo.IsFork { - RetrieveBaseRepo(ctx, repo) - if ctx.Written() { - return + if repo.IsGenerated() { + RetrieveTemplateRepo(ctx, repo) + if ctx.Written() { + return + } } - } - if repo.IsGenerated() { - RetrieveTemplateRepo(ctx, repo) - if ctx.Written() { + // Disable everything when the repo is being created + if ctx.Repo.Repository.IsBeingCreated() { + ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch return } - } - - // Disable everything when the repo is being created - if ctx.Repo.Repository.IsBeingCreated() { - ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch - return - } - gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName)) - if err != nil { - ctx.ServerError("RepoAssignment Invalid repo "+models.RepoPath(userName, repoName), err) - return - } - ctx.Repo.GitRepo = gitRepo - - // We opened it, we should close it - defer func() { - // If it's been set to nil then assume someone else has closed it. - if ctx.Repo.GitRepo != nil { - ctx.Repo.GitRepo.Close() + gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName)) + if err != nil { + ctx.ServerError("RepoAssignment Invalid repo "+models.RepoPath(userName, repoName), err) + return } - }() + ctx.Repo.GitRepo = gitRepo - // Stop at this point when the repo is empty. - if ctx.Repo.Repository.IsEmpty { - ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch - ctx.Next() - return - } + // We opened it, we should close it + defer func() { + // If it's been set to nil then assume someone else has closed it. + if ctx.Repo.GitRepo != nil { + ctx.Repo.GitRepo.Close() + } + }() - tags, err := ctx.Repo.GitRepo.GetTags() - if err != nil { - ctx.ServerError("GetTags", err) - return - } - ctx.Data["Tags"] = tags + // Stop at this point when the repo is empty. + if ctx.Repo.Repository.IsEmpty { + ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch + next.ServeHTTP(w, req) + return + } - brs, err := ctx.Repo.GitRepo.GetBranches() - if err != nil { - ctx.ServerError("GetBranches", err) - return - } - ctx.Data["Branches"] = brs - ctx.Data["BranchesCount"] = len(brs) - - ctx.Data["TagName"] = ctx.Repo.TagName - - // If not branch selected, try default one. - // If default branch doesn't exists, fall back to some other branch. - if len(ctx.Repo.BranchName) == 0 { - if len(ctx.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) { - ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch - } else if len(brs) > 0 { - ctx.Repo.BranchName = brs[0] + tags, err := ctx.Repo.GitRepo.GetTags() + if err != nil { + ctx.ServerError("GetTags", err) + return } - } - ctx.Data["BranchName"] = ctx.Repo.BranchName - ctx.Data["CommitID"] = ctx.Repo.CommitID - - // People who have push access or have forked repository can propose a new pull request. - canPush := ctx.Repo.CanWrite(models.UnitTypeCode) || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)) - canCompare := false - - // Pull request is allowed if this is a fork repository - // and base repository accepts pull requests. - if repo.BaseRepo != nil && repo.BaseRepo.AllowsPulls() { - canCompare = true - ctx.Data["BaseRepo"] = repo.BaseRepo - ctx.Repo.PullRequest.BaseRepo = repo.BaseRepo - ctx.Repo.PullRequest.Allowed = canPush - ctx.Repo.PullRequest.HeadInfo = ctx.Repo.Owner.Name + ":" + ctx.Repo.BranchName - } else if repo.AllowsPulls() { - // Or, this is repository accepts pull requests between branches. - canCompare = true - ctx.Data["BaseRepo"] = repo - ctx.Repo.PullRequest.BaseRepo = repo - ctx.Repo.PullRequest.Allowed = canPush - ctx.Repo.PullRequest.SameRepo = true - ctx.Repo.PullRequest.HeadInfo = ctx.Repo.BranchName - } - ctx.Data["CanCompareOrPull"] = canCompare - ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest + ctx.Data["Tags"] = tags - if ctx.Query("go-get") == "1" { - ctx.Data["GoGetImport"] = ComposeGoGetImport(owner.Name, repo.Name) - prefix := setting.AppURL + path.Join(owner.Name, repo.Name, "src", "branch", ctx.Repo.BranchName) - ctx.Data["GoDocDirectory"] = prefix + "{/dir}" - ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}" - } - ctx.Next() + brs, err := ctx.Repo.GitRepo.GetBranches() + if err != nil { + ctx.ServerError("GetBranches", err) + return + } + ctx.Data["Branches"] = brs + ctx.Data["BranchesCount"] = len(brs) + + ctx.Data["TagName"] = ctx.Repo.TagName + + // If not branch selected, try default one. + // If default branch doesn't exists, fall back to some other branch. + if len(ctx.Repo.BranchName) == 0 { + if len(ctx.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) { + ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch + } else if len(brs) > 0 { + ctx.Repo.BranchName = brs[0] + } + } + ctx.Data["BranchName"] = ctx.Repo.BranchName + ctx.Data["CommitID"] = ctx.Repo.CommitID + + // People who have push access or have forked repository can propose a new pull request. + canPush := ctx.Repo.CanWrite(models.UnitTypeCode) || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)) + canCompare := false + + // Pull request is allowed if this is a fork repository + // and base repository accepts pull requests. + if repo.BaseRepo != nil && repo.BaseRepo.AllowsPulls() { + canCompare = true + ctx.Data["BaseRepo"] = repo.BaseRepo + ctx.Repo.PullRequest.BaseRepo = repo.BaseRepo + ctx.Repo.PullRequest.Allowed = canPush + ctx.Repo.PullRequest.HeadInfo = ctx.Repo.Owner.Name + ":" + ctx.Repo.BranchName + } else if repo.AllowsPulls() { + // Or, this is repository accepts pull requests between branches. + canCompare = true + ctx.Data["BaseRepo"] = repo + ctx.Repo.PullRequest.BaseRepo = repo + ctx.Repo.PullRequest.Allowed = canPush + ctx.Repo.PullRequest.SameRepo = true + ctx.Repo.PullRequest.HeadInfo = ctx.Repo.BranchName + } + ctx.Data["CanCompareOrPull"] = canCompare + ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest + + if ctx.Query("go-get") == "1" { + ctx.Data["GoGetImport"] = ComposeGoGetImport(owner.Name, repo.Name) + prefix := setting.AppURL + path.Join(owner.Name, repo.Name, "src", "branch", ctx.Repo.BranchName) + ctx.Data["GoDocDirectory"] = prefix + "{/dir}" + ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}" + } + next.ServeHTTP(w, req) + }) } } @@ -636,7 +633,7 @@ const ( // RepoRef handles repository reference names when the ref name is not // explicitly given -func RepoRef() macaron.Handler { +func RepoRef() func(http.Handler) http.Handler { // since no ref name is explicitly specified, ok to just use branch return RepoRefByType(RepoRefBranch) } @@ -715,132 +712,135 @@ func getRefName(ctx *Context, pathType RepoRefType) string { // RepoRefByType handles repository reference name for a specific type // of repository reference -func RepoRefByType(refType RepoRefType) macaron.Handler { - return func(ctx *Context) { - // Empty repository does not have reference information. - if ctx.Repo.Repository.IsEmpty { - return - } - - var ( - refName string - err error - ) - - if ctx.Repo.GitRepo == nil { - repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) - ctx.Repo.GitRepo, err = git.OpenRepository(repoPath) - if err != nil { - ctx.ServerError("RepoRef Invalid repo "+repoPath, err) +func RepoRefByType(refType RepoRefType) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + ctx := GetContext(req) + // Empty repository does not have reference information. + if ctx.Repo.Repository.IsEmpty { return } - // We opened it, we should close it - defer func() { - // If it's been set to nil then assume someone else has closed it. - if ctx.Repo.GitRepo != nil { - ctx.Repo.GitRepo.Close() - } - }() - } - // Get default branch. - if len(ctx.Params("*")) == 0 { - refName = ctx.Repo.Repository.DefaultBranch - ctx.Repo.BranchName = refName - if !ctx.Repo.GitRepo.IsBranchExist(refName) { - brs, err := ctx.Repo.GitRepo.GetBranches() + var ( + refName string + err error + ) + + if ctx.Repo.GitRepo == nil { + repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) + ctx.Repo.GitRepo, err = git.OpenRepository(repoPath) if err != nil { - ctx.ServerError("GetBranches", err) - return - } else if len(brs) == 0 { - err = fmt.Errorf("No branches in non-empty repository %s", - ctx.Repo.GitRepo.Path) - ctx.ServerError("GetBranches", err) + ctx.ServerError("RepoRef Invalid repo "+repoPath, err) return } - refName = brs[0] - } - ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) - if err != nil { - ctx.ServerError("GetBranchCommit", err) - return + // We opened it, we should close it + defer func() { + // If it's been set to nil then assume someone else has closed it. + if ctx.Repo.GitRepo != nil { + ctx.Repo.GitRepo.Close() + } + }() } - ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - ctx.Repo.IsViewBranch = true - - } else { - refName = getRefName(ctx, refType) - ctx.Repo.BranchName = refName - if refType.RefTypeIncludesBranches() && ctx.Repo.GitRepo.IsBranchExist(refName) { - ctx.Repo.IsViewBranch = true + // Get default branch. + if len(ctx.Params("*")) == 0 { + refName = ctx.Repo.Repository.DefaultBranch + ctx.Repo.BranchName = refName + if !ctx.Repo.GitRepo.IsBranchExist(refName) { + brs, err := ctx.Repo.GitRepo.GetBranches() + if err != nil { + ctx.ServerError("GetBranches", err) + return + } else if len(brs) == 0 { + err = fmt.Errorf("No branches in non-empty repository %s", + ctx.Repo.GitRepo.Path) + ctx.ServerError("GetBranches", err) + return + } + refName = brs[0] + } ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) if err != nil { ctx.ServerError("GetBranchCommit", err) return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() + ctx.Repo.IsViewBranch = true - } else if refType.RefTypeIncludesTags() && ctx.Repo.GitRepo.IsTagExist(refName) { - ctx.Repo.IsViewTag = true - ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName) - if err != nil { - ctx.ServerError("GetTagCommit", err) + } else { + refName = getRefName(ctx, refType) + ctx.Repo.BranchName = refName + if refType.RefTypeIncludesBranches() && ctx.Repo.GitRepo.IsBranchExist(refName) { + ctx.Repo.IsViewBranch = true + + ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) + if err != nil { + ctx.ServerError("GetBranchCommit", err) + return + } + ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() + + } else if refType.RefTypeIncludesTags() && ctx.Repo.GitRepo.IsTagExist(refName) { + ctx.Repo.IsViewTag = true + ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName) + if err != nil { + ctx.ServerError("GetTagCommit", err) + return + } + ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() + } else if len(refName) >= 7 && len(refName) <= 40 { + ctx.Repo.IsViewCommit = true + ctx.Repo.CommitID = refName + + ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName) + if err != nil { + ctx.NotFound("GetCommit", err) + return + } + // If short commit ID add canonical link header + if len(refName) < 40 { + ctx.Header().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"", + util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), refName, ctx.Repo.Commit.ID.String(), 1)))) + } + } else { + ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refName)) return } - ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - } else if len(refName) >= 7 && len(refName) <= 40 { - ctx.Repo.IsViewCommit = true - ctx.Repo.CommitID = refName - ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName) - if err != nil { - ctx.NotFound("GetCommit", err) + if refType == RepoRefLegacy { + // redirect from old URL scheme to new URL scheme + ctx.Redirect(path.Join( + setting.AppSubURL, + strings.TrimSuffix(ctx.Req.URL.Path, ctx.Params("*")), + ctx.Repo.BranchNameSubURL(), + ctx.Repo.TreePath)) return } - // If short commit ID add canonical link header - if len(refName) < 40 { - ctx.Header().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"", - util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), refName, ctx.Repo.Commit.ID.String(), 1)))) - } - } else { - ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refName)) - return } - if refType == RepoRefLegacy { - // redirect from old URL scheme to new URL scheme - ctx.Redirect(path.Join( - setting.AppSubURL, - strings.TrimSuffix(ctx.Req.URL.Path, ctx.Params("*")), - ctx.Repo.BranchNameSubURL(), - ctx.Repo.TreePath)) + ctx.Data["BranchName"] = ctx.Repo.BranchName + ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL() + ctx.Data["CommitID"] = ctx.Repo.CommitID + ctx.Data["TreePath"] = ctx.Repo.TreePath + ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch + ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag + ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit + ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch() + + ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount() + if err != nil { + ctx.ServerError("GetCommitsCount", err) return } - } + ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount - ctx.Data["BranchName"] = ctx.Repo.BranchName - ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL() - ctx.Data["CommitID"] = ctx.Repo.CommitID - ctx.Data["TreePath"] = ctx.Repo.TreePath - ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch - ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag - ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit - ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch() - - ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount() - if err != nil { - ctx.ServerError("GetCommitsCount", err) - return - } - ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount - - ctx.Next() + next.ServeHTTP(w, req) + }) } } // GitHookService checks if repository Git hooks service has been enabled. -func GitHookService() macaron.Handler { +func GitHookService() func(ctx *Context) { return func(ctx *Context) { if !ctx.User.CanEditGitHook() { ctx.NotFound("GitHookService", nil) @@ -850,7 +850,7 @@ func GitHookService() macaron.Handler { } // UnitTypes returns a macaron middleware to set unit types to context variables. -func UnitTypes() macaron.Handler { +func UnitTypes() func(ctx *Context) { return func(ctx *Context) { ctx.Data["UnitTypeCode"] = models.UnitTypeCode ctx.Data["UnitTypeIssues"] = models.UnitTypeIssues diff --git a/modules/context/response.go b/modules/context/response.go index 549bd30ee020d..1881ec7b332c1 100644 --- a/modules/context/response.go +++ b/modules/context/response.go @@ -11,6 +11,7 @@ type ResponseWriter interface { http.ResponseWriter Flush() Status() int + Before(func(ResponseWriter)) } var ( @@ -20,11 +21,19 @@ var ( // Response represents a response type Response struct { http.ResponseWriter - status int + status int + befores []func(ResponseWriter) + beforeExecuted bool } // Write writes bytes to HTTP endpoint func (r *Response) Write(bs []byte) (int, error) { + if !r.beforeExecuted { + for _, before := range r.befores { + before(r) + } + r.beforeExecuted = true + } size, err := r.ResponseWriter.Write(bs) if err != nil { return 0, err @@ -37,6 +46,12 @@ func (r *Response) Write(bs []byte) (int, error) { // WriteHeader write status code func (r *Response) WriteHeader(statusCode int) { + if !r.beforeExecuted { + for _, before := range r.befores { + before(r) + } + r.beforeExecuted = true + } r.status = statusCode r.ResponseWriter.WriteHeader(statusCode) } @@ -53,10 +68,20 @@ func (r *Response) Status() int { return r.status } +// Before allows for a function to be called before the ResponseWriter has been written to. This is +// useful for setting headers or any other operations that must happen before a response has been written. +func (r *Response) Before(f func(ResponseWriter)) { + r.befores = append(r.befores, f) +} + // NewResponse creates a response func NewResponse(resp http.ResponseWriter) *Response { if v, ok := resp.(*Response); ok { return v } - return &Response{resp, 0} + return &Response{ + ResponseWriter: resp, + status: 0, + befores: make([]func(ResponseWriter), 0), + } } diff --git a/modules/context/secret.go b/modules/context/secret.go new file mode 100644 index 0000000000000..fcb488d211a0a --- /dev/null +++ b/modules/context/secret.go @@ -0,0 +1,100 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package context + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "errors" + "io" +) + +// NewSecret creates a new secret +func NewSecret() (string, error) { + return NewSecretWithLength(32) +} + +// NewSecretWithLength creates a new secret for a given length +func NewSecretWithLength(length int64) (string, error) { + return randomString(length) +} + +func randomBytes(len int64) ([]byte, error) { + b := make([]byte, len) + if _, err := rand.Read(b); err != nil { + return nil, err + } + return b, nil +} + +func randomString(len int64) (string, error) { + b, err := randomBytes(len) + return base64.URLEncoding.EncodeToString(b), err +} + +// AesEncrypt encrypts text and given key with AES. +func AesEncrypt(key, text []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + b := base64.StdEncoding.EncodeToString(text) + ciphertext := make([]byte, aes.BlockSize+len(b)) + iv := ciphertext[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, err + } + cfb := cipher.NewCFBEncrypter(block, iv) + cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b)) + return ciphertext, nil +} + +// AesDecrypt decrypts text and given key with AES. +func AesDecrypt(key, text []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + if len(text) < aes.BlockSize { + return nil, errors.New("ciphertext too short") + } + iv := text[:aes.BlockSize] + text = text[aes.BlockSize:] + cfb := cipher.NewCFBDecrypter(block, iv) + cfb.XORKeyStream(text, text) + data, err := base64.StdEncoding.DecodeString(string(text)) + if err != nil { + return nil, err + } + return data, nil +} + +// EncryptSecret encrypts a string with given key into a hex string +func EncryptSecret(key string, str string) (string, error) { + keyHash := sha256.Sum256([]byte(key)) + plaintext := []byte(str) + ciphertext, err := AesEncrypt(keyHash[:], plaintext) + if err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(ciphertext), nil +} + +// DecryptSecret decrypts a previously encrypted hex string +func DecryptSecret(key string, cipherhex string) (string, error) { + keyHash := sha256.Sum256([]byte(key)) + ciphertext, err := base64.StdEncoding.DecodeString(cipherhex) + if err != nil { + return "", err + } + plaintext, err := AesDecrypt(keyHash[:], ciphertext) + if err != nil { + return "", err + } + return string(plaintext), nil +} diff --git a/vendor/gitea.com/macaron/csrf/xsrf.go b/modules/context/xsrf.go similarity index 90% rename from vendor/gitea.com/macaron/csrf/xsrf.go rename to modules/context/xsrf.go index 7f31894f9500b..10e63a4180c61 100644 --- a/vendor/gitea.com/macaron/csrf/xsrf.go +++ b/modules/context/xsrf.go @@ -1,5 +1,6 @@ // Copyright 2012 Google Inc. All Rights Reserved. // Copyright 2014 The Macaron Authors +// Copyright 2020 The Gitea Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package csrf +package context import ( "bytes" @@ -27,13 +28,13 @@ import ( "time" ) -// The duration that XSRF tokens are valid. +// Timeout represents the duration that XSRF tokens are valid. // It is exported so clients may set cookie timeouts that match generated tokens. -const TIMEOUT = 24 * time.Hour +const Timeout = 24 * time.Hour // clean sanitizes a string for inclusion in a token by replacing all ":"s. func clean(s string) string { - return strings.Replace(s, ":", "_", -1) + return strings.ReplaceAll(s, ":", "_") } // GenerateToken returns a URL-safe secure XSRF token that expires in 24 hours. @@ -53,7 +54,7 @@ func generateTokenAtTime(key, userID, actionID string, now time.Time) string { return base64.RawURLEncoding.EncodeToString([]byte(tok)) } -// Valid returns true if token is a valid, unexpired token returned by Generate. +// ValidToken returns true if token is a valid, unexpired token returned by Generate. func ValidToken(token, key, userID, actionID string) bool { return validTokenAtTime(token, key, userID, actionID, time.Now()) } @@ -78,7 +79,7 @@ func validTokenAtTime(token, key, userID, actionID string, now time.Time) bool { issueTime := time.Unix(0, nanos) // Check that the token is not expired. - if now.Sub(issueTime) >= TIMEOUT { + if now.Sub(issueTime) >= Timeout { return false } diff --git a/modules/context/xsrf_test.go b/modules/context/xsrf_test.go new file mode 100644 index 0000000000000..c0c711bf07cdc --- /dev/null +++ b/modules/context/xsrf_test.go @@ -0,0 +1,90 @@ +// Copyright 2012 Google Inc. All Rights Reserved. +// Copyright 2014 The Macaron Authors +// Copyright 2020 The Gitea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package context + +import ( + "encoding/base64" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +const ( + key = "quay" + userID = "12345678" + actionID = "POST /form" +) + +var ( + now = time.Now() + oneMinuteFromNow = now.Add(1 * time.Minute) +) + +func Test_ValidToken(t *testing.T) { + t.Run("Validate token", func(t *testing.T) { + tok := generateTokenAtTime(key, userID, actionID, now) + assert.True(t, validTokenAtTime(tok, key, userID, actionID, oneMinuteFromNow)) + assert.True(t, validTokenAtTime(tok, key, userID, actionID, now.Add(Timeout-1*time.Nanosecond))) + assert.True(t, validTokenAtTime(tok, key, userID, actionID, now.Add(-1*time.Minute))) + }) +} + +// Test_SeparatorReplacement tests that separators are being correctly substituted +func Test_SeparatorReplacement(t *testing.T) { + t.Run("Test two separator replacements", func(t *testing.T) { + assert.NotEqual(t, generateTokenAtTime("foo:bar", "baz", "wah", now), + generateTokenAtTime("foo", "bar:baz", "wah", now)) + }) +} + +func Test_InvalidToken(t *testing.T) { + t.Run("Test invalid tokens", func(t *testing.T) { + invalidTokenTests := []struct { + name, key, userID, actionID string + t time.Time + }{ + {"Bad key", "foobar", userID, actionID, oneMinuteFromNow}, + {"Bad userID", key, "foobar", actionID, oneMinuteFromNow}, + {"Bad actionID", key, userID, "foobar", oneMinuteFromNow}, + {"Expired", key, userID, actionID, now.Add(Timeout)}, + {"More than 1 minute from the future", key, userID, actionID, now.Add(-1*time.Nanosecond - 1*time.Minute)}, + } + + tok := generateTokenAtTime(key, userID, actionID, now) + for _, itt := range invalidTokenTests { + assert.False(t, validTokenAtTime(tok, itt.key, itt.userID, itt.actionID, itt.t)) + } + }) +} + +// Test_ValidateBadData primarily tests that no unexpected panics are triggered during parsing +func Test_ValidateBadData(t *testing.T) { + t.Run("Validate bad data", func(t *testing.T) { + badDataTests := []struct { + name, tok string + }{ + {"Invalid Base64", "ASDab24(@)$*=="}, + {"No delimiter", base64.URLEncoding.EncodeToString([]byte("foobar12345678"))}, + {"Invalid time", base64.URLEncoding.EncodeToString([]byte("foobar:foobar"))}, + } + + for _, bdt := range badDataTests { + assert.False(t, validTokenAtTime(bdt.tok, key, userID, actionID, oneMinuteFromNow)) + } + }) +} diff --git a/modules/auth/admin.go b/modules/forms/admin.go similarity index 70% rename from modules/auth/admin.go rename to modules/forms/admin.go index f2d02635517ab..09ad420e159ac 100644 --- a/modules/auth/admin.go +++ b/modules/forms/admin.go @@ -2,11 +2,15 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package forms import ( - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "net/http" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/middlewares" + + "gitea.com/go-chi/binding" ) // AdminCreateUserForm form for admin to create user @@ -21,8 +25,9 @@ type AdminCreateUserForm struct { } // Validate validates form fields -func (f *AdminCreateUserForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AdminCreateUserForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // AdminEditUserForm form for admin to create user @@ -47,8 +52,9 @@ type AdminEditUserForm struct { } // Validate validates form fields -func (f *AdminEditUserForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AdminEditUserForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // AdminDashboardForm form for admin dashboard operations @@ -58,6 +64,7 @@ type AdminDashboardForm struct { } // Validate validates form fields -func (f *AdminDashboardForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AdminDashboardForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } diff --git a/modules/auth/auth_form.go b/modules/forms/auth_form.go similarity index 87% rename from modules/auth/auth_form.go rename to modules/forms/auth_form.go index e348b01e91304..10d0f82959537 100644 --- a/modules/auth/auth_form.go +++ b/modules/forms/auth_form.go @@ -2,11 +2,15 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package forms import ( - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "net/http" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/middlewares" + + "gitea.com/go-chi/binding" ) // AuthenticationForm form for authentication @@ -65,6 +69,7 @@ type AuthenticationForm struct { } // Validate validates fields -func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AuthenticationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } diff --git a/modules/auth/org.go b/modules/forms/org.go similarity index 76% rename from modules/auth/org.go rename to modules/forms/org.go index 20e2b09997e20..513f80768fa99 100644 --- a/modules/auth/org.go +++ b/modules/forms/org.go @@ -3,14 +3,17 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package forms import ( + "net/http" + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/structs" - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "gitea.com/go-chi/binding" ) // ________ .__ __ .__ @@ -28,8 +31,9 @@ type CreateOrgForm struct { } // Validate validates the fields -func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *CreateOrgForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // UpdateOrgSettingForm form for updating organization settings @@ -45,8 +49,9 @@ type UpdateOrgSettingForm struct { } // Validate validates the fields -func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *UpdateOrgSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // ___________ @@ -67,6 +72,7 @@ type CreateTeamForm struct { } // Validate validates the fields -func (f *CreateTeamForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *CreateTeamForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } diff --git a/modules/auth/repo_branch_form.go b/modules/forms/repo_branch_form.go similarity index 52% rename from modules/auth/repo_branch_form.go rename to modules/forms/repo_branch_form.go index a4baabe3545f3..afb7f8d4f007b 100644 --- a/modules/auth/repo_branch_form.go +++ b/modules/forms/repo_branch_form.go @@ -2,11 +2,15 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package forms import ( - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "net/http" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/middlewares" + + "gitea.com/go-chi/binding" ) // NewBranchForm form for creating a new branch @@ -15,6 +19,7 @@ type NewBranchForm struct { } // Validate validates the fields -func (f *NewBranchForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewBranchForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } diff --git a/modules/auth/repo_form.go b/modules/forms/repo_form.go similarity index 78% rename from modules/auth/repo_form.go rename to modules/forms/repo_form.go index 78b2197a2dda8..4a478c7d35fa4 100644 --- a/modules/auth/repo_form.go +++ b/modules/forms/repo_form.go @@ -3,21 +3,23 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package forms import ( + "net/http" "net/url" "strings" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/utils" - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "gitea.com/go-chi/binding" ) // _______________________________________ _________.______________________ _______________.___. @@ -52,8 +54,9 @@ type CreateRepoForm struct { } // Validate validates the fields -func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *CreateRepoForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // MigrateRepoForm form for migrating repository @@ -82,8 +85,9 @@ type MigrateRepoForm struct { } // Validate validates the fields -func (f *MigrateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *MigrateRepoForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // ParseRemoteAddr checks if given remote address is valid, @@ -166,8 +170,9 @@ type RepoSettingForm struct { } // Validate validates the fields -func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *RepoSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // __________ .__ @@ -202,8 +207,9 @@ type ProtectBranchForm struct { } // Validate validates the fields -func (f *ProtectBranchForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *ProtectBranchForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // __ __ ___. .__ .__ __ @@ -263,8 +269,9 @@ type NewWebhookForm struct { } // Validate validates the fields -func (f *NewWebhookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewWebhookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // NewGogshookForm form for creating gogs hook @@ -276,8 +283,9 @@ type NewGogshookForm struct { } // Validate validates the fields -func (f *NewGogshookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // NewSlackHookForm form for creating slack hook @@ -291,8 +299,9 @@ type NewSlackHookForm struct { } // Validate validates the fields -func (f *NewSlackHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewSlackHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // HasInvalidChannel validates the channel name is in the right format @@ -309,8 +318,9 @@ type NewDiscordHookForm struct { } // Validate validates the fields -func (f *NewDiscordHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewDiscordHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // NewDingtalkHookForm form for creating dingtalk hook @@ -320,8 +330,9 @@ type NewDingtalkHookForm struct { } // Validate validates the fields -func (f *NewDingtalkHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewDingtalkHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // NewTelegramHookForm form for creating telegram hook @@ -332,8 +343,9 @@ type NewTelegramHookForm struct { } // Validate validates the fields -func (f *NewTelegramHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewTelegramHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // NewMatrixHookForm form for creating Matrix hook @@ -346,8 +358,9 @@ type NewMatrixHookForm struct { } // Validate validates the fields -func (f *NewMatrixHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewMatrixHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // NewMSTeamsHookForm form for creating MS Teams hook @@ -357,8 +370,9 @@ type NewMSTeamsHookForm struct { } // Validate validates the fields -func (f *NewMSTeamsHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewMSTeamsHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // NewFeishuHookForm form for creating feishu hook @@ -368,8 +382,9 @@ type NewFeishuHookForm struct { } // Validate validates the fields -func (f *NewFeishuHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewFeishuHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // .___ @@ -393,8 +408,9 @@ type CreateIssueForm struct { } // Validate validates the fields -func (f *CreateIssueForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *CreateIssueForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // CreateCommentForm form for creating comment @@ -405,8 +421,9 @@ type CreateCommentForm struct { } // Validate validates the fields -func (f *CreateCommentForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *CreateCommentForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // ReactionForm form for adding and removing reaction @@ -415,8 +432,9 @@ type ReactionForm struct { } // Validate validates the fields -func (f *ReactionForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *ReactionForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // IssueLockForm form for locking an issue @@ -425,8 +443,9 @@ type IssueLockForm struct { } // Validate validates the fields -func (i *IssueLockForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, i, ctx.Locale) +func (i *IssueLockForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, i, ctx.Locale) } // HasValidReason checks to make sure that the reason submitted in @@ -489,8 +508,9 @@ type CreateMilestoneForm struct { } // Validate validates the fields -func (f *CreateMilestoneForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *CreateMilestoneForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // .____ ___. .__ @@ -509,8 +529,9 @@ type CreateLabelForm struct { } // Validate validates the fields -func (f *CreateLabelForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *CreateLabelForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // InitializeLabelsForm form for initializing labels @@ -519,8 +540,9 @@ type InitializeLabelsForm struct { } // Validate validates the fields -func (f *InitializeLabelsForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *InitializeLabelsForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // __________ .__ .__ __________ __ @@ -542,8 +564,9 @@ type MergePullRequestForm struct { } // Validate validates the fields -func (f *MergePullRequestForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *MergePullRequestForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // CodeCommentForm form for adding code comments for PRs @@ -559,8 +582,9 @@ type CodeCommentForm struct { } // Validate validates the fields -func (f *CodeCommentForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *CodeCommentForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // SubmitReviewForm for submitting a finished code review @@ -571,8 +595,9 @@ type SubmitReviewForm struct { } // Validate validates the fields -func (f *SubmitReviewForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *SubmitReviewForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // ReviewType will return the corresponding reviewtype for type @@ -616,8 +641,9 @@ type NewReleaseForm struct { } // Validate validates the fields -func (f *NewReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewReleaseForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // EditReleaseForm form for changing release @@ -630,8 +656,9 @@ type EditReleaseForm struct { } // Validate validates the fields -func (f *EditReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *EditReleaseForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // __ __.__ __ .__ @@ -650,8 +677,9 @@ type NewWikiForm struct { // Validate validates the fields // FIXME: use code generation to generate this method. -func (f *NewWikiForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewWikiForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // ___________ .___.__ __ @@ -673,8 +701,9 @@ type EditRepoFileForm struct { } // Validate validates the fields -func (f *EditRepoFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *EditRepoFileForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // EditPreviewDiffForm form for changing preview diff @@ -683,8 +712,9 @@ type EditPreviewDiffForm struct { } // Validate validates the fields -func (f *EditPreviewDiffForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *EditPreviewDiffForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // ____ ___ .__ .___ @@ -706,8 +736,9 @@ type UploadRepoFileForm struct { } // Validate validates the fields -func (f *UploadRepoFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *UploadRepoFileForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // RemoveUploadFileForm form for removing uploaded file @@ -716,8 +747,9 @@ type RemoveUploadFileForm struct { } // Validate validates the fields -func (f *RemoveUploadFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *RemoveUploadFileForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // ________ .__ __ @@ -737,8 +769,9 @@ type DeleteRepoFileForm struct { } // Validate validates the fields -func (f *DeleteRepoFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *DeleteRepoFileForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // ___________.__ ___________ __ @@ -755,8 +788,9 @@ type AddTimeManuallyForm struct { } // Validate validates the fields -func (f *AddTimeManuallyForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AddTimeManuallyForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // SaveTopicForm form for save topics for repository @@ -770,6 +804,7 @@ type DeadlineForm struct { } // Validate validates the fields -func (f *DeadlineForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *DeadlineForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } diff --git a/modules/auth/repo_form_test.go b/modules/forms/repo_form_test.go similarity index 99% rename from modules/auth/repo_form_test.go rename to modules/forms/repo_form_test.go index 6bad5d50bad28..4f65d59ca6d61 100644 --- a/modules/auth/repo_form_test.go +++ b/modules/forms/repo_form_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package forms import ( "testing" diff --git a/modules/auth/user_form.go b/modules/forms/user_form.go similarity index 71% rename from modules/auth/user_form.go rename to modules/forms/user_form.go index b94b8e0a4ebc6..e3090f9ae5729 100644 --- a/modules/auth/user_form.go +++ b/modules/forms/user_form.go @@ -3,16 +3,18 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package forms import ( "mime/multipart" + "net/http" "strings" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/setting" - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "gitea.com/go-chi/binding" ) // InstallForm form for installation page @@ -65,8 +67,9 @@ type InstallForm struct { } // Validate validates the fields -func (f *InstallForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *InstallForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // _____ ____ _________________ ___ @@ -87,8 +90,9 @@ type RegisterForm struct { } // Validate validates the fields -func (f *RegisterForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *RegisterForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // IsEmailDomainWhitelisted validates that the email address @@ -124,8 +128,9 @@ type MustChangePasswordForm struct { } // Validate validates the fields -func (f *MustChangePasswordForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *MustChangePasswordForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // SignInForm form for signing in with user/password @@ -137,8 +142,9 @@ type SignInForm struct { } // Validate validates the fields -func (f *SignInForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *SignInForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // AuthorizationForm form for authorizing oauth2 clients @@ -156,8 +162,9 @@ type AuthorizationForm struct { } // Validate validates the fields -func (f *AuthorizationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AuthorizationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // GrantApplicationForm form for authorizing oauth2 clients @@ -170,8 +177,9 @@ type GrantApplicationForm struct { } // Validate validates the fields -func (f *GrantApplicationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *GrantApplicationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // AccessTokenForm for issuing access tokens from authorization codes or refresh tokens @@ -188,8 +196,9 @@ type AccessTokenForm struct { } // Validate validates the fields -func (f *AccessTokenForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AccessTokenForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // __________________________________________.___ _______ ________ _________ @@ -212,8 +221,9 @@ type UpdateProfileForm struct { } // Validate validates the fields -func (f *UpdateProfileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *UpdateProfileForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // Avatar types @@ -231,8 +241,9 @@ type AvatarForm struct { } // Validate validates the fields -func (f *AvatarForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AvatarForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // AddEmailForm form for adding new email @@ -241,8 +252,9 @@ type AddEmailForm struct { } // Validate validates the fields -func (f *AddEmailForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AddEmailForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // UpdateThemeForm form for updating a users' theme @@ -251,8 +263,9 @@ type UpdateThemeForm struct { } // Validate validates the field -func (f *UpdateThemeForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *UpdateThemeForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // IsThemeExists checks if the theme is a theme available in the config. @@ -277,8 +290,9 @@ type ChangePasswordForm struct { } // Validate validates the fields -func (f *ChangePasswordForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *ChangePasswordForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // AddOpenIDForm is for changing openid uri @@ -287,8 +301,9 @@ type AddOpenIDForm struct { } // Validate validates the fields -func (f *AddOpenIDForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AddOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // AddKeyForm form for adding SSH/GPG key @@ -300,8 +315,9 @@ type AddKeyForm struct { } // Validate validates the fields -func (f *AddKeyForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *AddKeyForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // NewAccessTokenForm form for creating access token @@ -310,8 +326,9 @@ type NewAccessTokenForm struct { } // Validate validates the fields -func (f *NewAccessTokenForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *NewAccessTokenForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // EditOAuth2ApplicationForm form for editing oauth2 applications @@ -321,8 +338,9 @@ type EditOAuth2ApplicationForm struct { } // Validate validates the fields -func (f *EditOAuth2ApplicationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *EditOAuth2ApplicationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // TwoFactorAuthForm for logging in with 2FA token. @@ -331,8 +349,9 @@ type TwoFactorAuthForm struct { } // Validate validates the fields -func (f *TwoFactorAuthForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *TwoFactorAuthForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // TwoFactorScratchAuthForm for logging in with 2FA scratch token. @@ -341,8 +360,9 @@ type TwoFactorScratchAuthForm struct { } // Validate validates the fields -func (f *TwoFactorScratchAuthForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *TwoFactorScratchAuthForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // U2FRegistrationForm for reserving an U2F name @@ -351,8 +371,9 @@ type U2FRegistrationForm struct { } // Validate validates the fields -func (f *U2FRegistrationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *U2FRegistrationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // U2FDeleteForm for deleting U2F keys @@ -361,6 +382,7 @@ type U2FDeleteForm struct { } // Validate validates the fields -func (f *U2FDeleteForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *U2FDeleteForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } diff --git a/modules/auth/user_form_auth_openid.go b/modules/forms/user_form_auth_openid.go similarity index 58% rename from modules/auth/user_form_auth_openid.go rename to modules/forms/user_form_auth_openid.go index 841dbd840afca..06601d7e15053 100644 --- a/modules/auth/user_form_auth_openid.go +++ b/modules/forms/user_form_auth_openid.go @@ -2,11 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package forms import ( - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "net/http" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/middlewares" + "gitea.com/go-chi/binding" ) // SignInOpenIDForm form for signing in with OpenID @@ -16,8 +19,9 @@ type SignInOpenIDForm struct { } // Validate validates the fields -func (f *SignInOpenIDForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *SignInOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // SignUpOpenIDForm form for signin up with OpenID @@ -29,8 +33,9 @@ type SignUpOpenIDForm struct { } // Validate validates the fields -func (f *SignUpOpenIDForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *SignUpOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } // ConnectOpenIDForm form for connecting an existing account to an OpenID URI @@ -40,6 +45,7 @@ type ConnectOpenIDForm struct { } // Validate validates the fields -func (f *ConnectOpenIDForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { - return validate(errs, ctx.Data, f, ctx.Locale) +func (f *ConnectOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middlewares.Validate(errs, ctx.Data, f, ctx.Locale) } diff --git a/modules/auth/user_form_test.go b/modules/forms/user_form_test.go similarity index 98% rename from modules/auth/user_form_test.go rename to modules/forms/user_form_test.go index 084174622e151..6e0518789c14e 100644 --- a/modules/auth/user_form_test.go +++ b/modules/forms/user_form_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package forms import ( "testing" diff --git a/modules/lfs/locks.go b/modules/lfs/locks.go index a529afe1b92b0..cf62492c7e1e9 100644 --- a/modules/lfs/locks.go +++ b/modules/lfs/locks.go @@ -182,7 +182,7 @@ func PostLockHandler(ctx *context.Context) { } var req api.LFSLockRequest - bodyReader := ctx.Req.Body().ReadCloser() + bodyReader := ctx.Req.Body defer bodyReader.Close() dec := json.NewDecoder(bodyReader) if err := dec.Decode(&req); err != nil { @@ -317,7 +317,7 @@ func UnLockHandler(ctx *context.Context) { } var req api.LFSLockDeleteRequest - bodyReader := ctx.Req.Body().ReadCloser() + bodyReader := ctx.Req.Body defer bodyReader.Close() dec := json.NewDecoder(bodyReader) if err := dec.Decode(&req); err != nil { diff --git a/modules/lfs/server.go b/modules/lfs/server.go index 226bcbf55a7f3..be21a4de82917 100644 --- a/modules/lfs/server.go +++ b/modules/lfs/server.go @@ -22,7 +22,6 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" - "gitea.com/macaron/macaron" "github.com/dgrijalva/jwt-go" ) @@ -413,8 +412,8 @@ func PutHandler(ctx *context.Context) { } contentStore := &ContentStore{ObjectStorage: storage.LFS} - defer ctx.Req.Request.Body.Close() - if err := contentStore.Put(meta, ctx.Req.Request.Body); err != nil { + defer ctx.Req.Body.Close() + if err := contentStore.Put(meta, ctx.Req.Body); err != nil { // Put will log the error itself ctx.Resp.WriteHeader(500) if err == errSizeMismatch || err == errHashMismatch { @@ -513,7 +512,7 @@ func Represent(rv *RequestVars, meta *models.LFSMetaObject, download, upload boo // MetaMatcher provides a mux.MatcherFunc that only allows requests that contain // an Accept header with the metaMediaType -func MetaMatcher(r macaron.Request) bool { +func MetaMatcher(r *http.Request) bool { mediaParts := strings.Split(r.Header.Get("Accept"), ";") mt := mediaParts[0] return mt == metaMediaType @@ -530,7 +529,7 @@ func unpack(ctx *context.Context) *RequestVars { if r.Method == "POST" { // Maybe also check if +json var p RequestVars - bodyReader := r.Body().ReadCloser() + bodyReader := r.Body defer bodyReader.Close() dec := json.NewDecoder(bodyReader) err := dec.Decode(&p) @@ -553,7 +552,7 @@ func unpackbatch(ctx *context.Context) *BatchVars { r := ctx.Req var bv BatchVars - bodyReader := r.Body().ReadCloser() + bodyReader := r.Body defer bodyReader.Close() dec := json.NewDecoder(bodyReader) err := dec.Decode(&bv) @@ -586,7 +585,7 @@ func writeStatus(ctx *context.Context, status int) { logRequest(ctx.Req, status) } -func logRequest(r macaron.Request, status int) { +func logRequest(r *http.Request, status int) { log.Debug("LFS request - Method: %s, URL: %s, Status %d", r.Method, r.URL, status) } diff --git a/modules/auth/auth.go b/modules/middlewares/binding.go similarity index 92% rename from modules/auth/auth.go rename to modules/middlewares/binding.go index 1f4b9ec5beeb5..1dabdbb62e41e 100644 --- a/modules/auth/auth.go +++ b/modules/middlewares/binding.go @@ -3,24 +3,19 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package middlewares import ( "reflect" "strings" + "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/validation" - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "gitea.com/go-chi/binding" "github.com/unknwon/com" ) -// IsAPIPath if URL is an api path -func IsAPIPath(url string) bool { - return strings.HasPrefix(url, "/api/") -} - // Form form binding interface type Form interface { binding.Validator @@ -35,7 +30,7 @@ func AssignForm(form interface{}, data map[string]interface{}) { typ := reflect.TypeOf(form) val := reflect.ValueOf(form) - if typ.Kind() == reflect.Ptr { + for typ.Kind() == reflect.Ptr { typ = typ.Elem() val = val.Elem() } @@ -84,7 +79,8 @@ func GetInclude(field reflect.StructField) string { return getRuleBody(field, "Include(") } -func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaron.Locale) binding.Errors { +// Validate validate TODO: +func Validate(errs binding.Errors, data map[string]interface{}, f Form, l translation.Locale) binding.Errors { if errs.Len() == 0 { return errs } diff --git a/modules/middlewares/cookie.go b/modules/middlewares/cookie.go index 80d0e3b453ef6..d18541833f02a 100644 --- a/modules/middlewares/cookie.go +++ b/modules/middlewares/cookie.go @@ -1,3 +1,4 @@ +// Copyright 2020 The Macaron Authors // Copyright 2020 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. @@ -12,6 +13,56 @@ import ( "code.gitea.io/gitea/modules/setting" ) +// MaxAge sets the maximum age for a provided cookie +func MaxAge(maxAge int) func(*http.Cookie) { + return func(c *http.Cookie) { + c.MaxAge = maxAge + } +} + +// Path sets the path for a provided cookie +func Path(path string) func(*http.Cookie) { + return func(c *http.Cookie) { + c.Path = path + } +} + +// Domain sets the domain for a provided cookie +func Domain(domain string) func(*http.Cookie) { + return func(c *http.Cookie) { + c.Domain = domain + } +} + +// Secure sets the secure setting for a provided cookie +func Secure(secure bool) func(*http.Cookie) { + return func(c *http.Cookie) { + c.Secure = secure + } +} + +// HTTPOnly sets the HttpOnly setting for a provided cookie +func HTTPOnly(httpOnly bool) func(*http.Cookie) { + return func(c *http.Cookie) { + c.HttpOnly = httpOnly + } +} + +// Expires sets the expires and rawexpires for a provided cookie +func Expires(expires time.Time) func(*http.Cookie) { + return func(c *http.Cookie) { + c.Expires = expires + c.RawExpires = expires.Format(time.UnixDate) + } +} + +// SameSite sets the SameSite for a provided cookie +func SameSite(sameSite http.SameSite) func(*http.Cookie) { + return func(c *http.Cookie) { + c.SameSite = sameSite + } +} + // NewCookie creates a cookie func NewCookie(name, value string, maxAge int) *http.Cookie { return &http.Cookie{ @@ -102,3 +153,13 @@ func SetCookie(resp http.ResponseWriter, name string, value string, others ...in resp.Header().Add("Set-Cookie", cookie.String()) } + +// GetCookie returns given cookie value from request header. +func GetCookie(req *http.Request, name string) string { + cookie, err := req.Cookie(name) + if err != nil { + return "" + } + val, _ := url.QueryUnescape(cookie.Value) + return val +} diff --git a/modules/middlewares/data.go b/modules/middlewares/data.go new file mode 100644 index 0000000000000..269028936213e --- /dev/null +++ b/modules/middlewares/data.go @@ -0,0 +1,10 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package middlewares + +// DataStore represents a data store +type DataStore interface { + GetData() map[string]interface{} +} diff --git a/modules/middlewares/flash.go b/modules/middlewares/flash.go new file mode 100644 index 0000000000000..38217288e8109 --- /dev/null +++ b/modules/middlewares/flash.go @@ -0,0 +1,65 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package middlewares + +import "net/url" + +// flashes enumerates all the flash types +const ( + SuccessFlash = "SuccessMsg" + ErrorFlash = "ErrorMsg" + WarnFlash = "WarningMsg" + InfoFlash = "InfoMsg" +) + +var ( + // FlashNow FIXME: + FlashNow bool +) + +// Flash represents a one time data transfer between two requests. +type Flash struct { + DataStore + url.Values + ErrorMsg, WarningMsg, InfoMsg, SuccessMsg string +} + +func (f *Flash) set(name, msg string, current ...bool) { + isShow := false + if (len(current) == 0 && FlashNow) || + (len(current) > 0 && current[0]) { + isShow = true + } + + if isShow { + f.GetData()["Flash"] = f + } else { + f.Set(name, msg) + } +} + +// Error sets error message +func (f *Flash) Error(msg string, current ...bool) { + f.ErrorMsg = msg + f.set("error", msg, current...) +} + +// Warning sets warning message +func (f *Flash) Warning(msg string, current ...bool) { + f.WarningMsg = msg + f.set("warning", msg, current...) +} + +// Info sets info message +func (f *Flash) Info(msg string, current ...bool) { + f.InfoMsg = msg + f.set("info", msg, current...) +} + +// Success sets success message +func (f *Flash) Success(msg string, current ...bool) { + f.SuccessMsg = msg + f.set("success", msg, current...) +} diff --git a/modules/middlewares/locale.go b/modules/middlewares/locale.go index 98af890cfd20c..7cfba81bda6bf 100644 --- a/modules/middlewares/locale.go +++ b/modules/middlewares/locale.go @@ -23,12 +23,14 @@ func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale { // 2. Get language information from cookies. if len(lang) == 0 { ck, _ := req.Cookie("lang") - lang = ck.Value - hasCookie = true + if ck != nil { + lang = ck.Value + hasCookie = true + } } // Check again in case someone modify by purpose. - if !i18n.IsExist(lang) { + if lang != "" && !i18n.IsExist(lang) { lang = "" hasCookie = false } diff --git a/modules/middlewares/redis.go b/modules/middlewares/redis.go deleted file mode 100644 index ced1c1ee81491..0000000000000 --- a/modules/middlewares/redis.go +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// Copyright 2020 The Gitea Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package middlewares - -import ( - "fmt" - "sync" - "time" - - "code.gitea.io/gitea/modules/nosql" - - "gitea.com/go-chi/session" - "github.com/go-redis/redis/v7" -) - -// RedisStore represents a redis session store implementation. -// TODO: copied from modules/session/redis.go and should remove that one until macaron removed. -type RedisStore struct { - c redis.UniversalClient - prefix, sid string - duration time.Duration - lock sync.RWMutex - data map[interface{}]interface{} -} - -// NewRedisStore creates and returns a redis session store. -func NewRedisStore(c redis.UniversalClient, prefix, sid string, dur time.Duration, kv map[interface{}]interface{}) *RedisStore { - return &RedisStore{ - c: c, - prefix: prefix, - sid: sid, - duration: dur, - data: kv, - } -} - -// Set sets value to given key in session. -func (s *RedisStore) Set(key, val interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data[key] = val - return nil -} - -// Get gets value by given key in session. -func (s *RedisStore) Get(key interface{}) interface{} { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.data[key] -} - -// Delete delete a key from session. -func (s *RedisStore) Delete(key interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - delete(s.data, key) - return nil -} - -// ID returns current session ID. -func (s *RedisStore) ID() string { - return s.sid -} - -// Release releases resource and save data to provider. -func (s *RedisStore) Release() error { - // Skip encoding if the data is empty - if len(s.data) == 0 { - return nil - } - - data, err := session.EncodeGob(s.data) - if err != nil { - return err - } - - return s.c.Set(s.prefix+s.sid, string(data), s.duration).Err() -} - -// Flush deletes all session data. -func (s *RedisStore) Flush() error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data = make(map[interface{}]interface{}) - return nil -} - -// RedisProvider represents a redis session provider implementation. -type RedisProvider struct { - c redis.UniversalClient - duration time.Duration - prefix string -} - -// Init initializes redis session provider. -// configs: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180,prefix=session; -func (p *RedisProvider) Init(maxlifetime int64, configs string) (err error) { - p.duration, err = time.ParseDuration(fmt.Sprintf("%ds", maxlifetime)) - if err != nil { - return err - } - - uri := nosql.ToRedisURI(configs) - - for k, v := range uri.Query() { - switch k { - case "prefix": - p.prefix = v[0] - } - } - - p.c = nosql.GetManager().GetRedisClient(uri.String()) - return p.c.Ping().Err() -} - -// Read returns raw session store by session ID. -func (p *RedisProvider) Read(sid string) (session.RawStore, error) { - psid := p.prefix + sid - if !p.Exist(sid) { - if err := p.c.Set(psid, "", p.duration).Err(); err != nil { - return nil, err - } - } - - var kv map[interface{}]interface{} - kvs, err := p.c.Get(psid).Result() - if err != nil { - return nil, err - } - if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob([]byte(kvs)) - if err != nil { - return nil, err - } - } - - return NewRedisStore(p.c, p.prefix, sid, p.duration, kv), nil -} - -// Exist returns true if session with given ID exists. -func (p *RedisProvider) Exist(sid string) bool { - v, err := p.c.Exists(p.prefix + sid).Result() - return err == nil && v == 1 -} - -// Destroy deletes a session by session ID. -func (p *RedisProvider) Destroy(sid string) error { - return p.c.Del(p.prefix + sid).Err() -} - -// Regenerate regenerates a session store from old session ID to new one. -func (p *RedisProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) { - poldsid := p.prefix + oldsid - psid := p.prefix + sid - - if p.Exist(sid) { - return nil, fmt.Errorf("new sid '%s' already exists", sid) - } else if !p.Exist(oldsid) { - // Make a fake old session. - if err = p.c.Set(poldsid, "", p.duration).Err(); err != nil { - return nil, err - } - } - - if err = p.c.Rename(poldsid, psid).Err(); err != nil { - return nil, err - } - - var kv map[interface{}]interface{} - kvs, err := p.c.Get(psid).Result() - if err != nil { - return nil, err - } - - if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob([]byte(kvs)) - if err != nil { - return nil, err - } - } - - return NewRedisStore(p.c, p.prefix, sid, p.duration, kv), nil -} - -// Count counts and returns number of sessions. -func (p *RedisProvider) Count() int { - return int(p.c.DBSize().Val()) -} - -// GC calls GC to clean expired sessions. -func (*RedisProvider) GC() {} - -func init() { - session.Register("redis", &RedisProvider{}) -} diff --git a/modules/middlewares/virtual.go b/modules/middlewares/virtual.go deleted file mode 100644 index 70d780d65d4f7..0000000000000 --- a/modules/middlewares/virtual.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2019 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package middlewares - -import ( - "encoding/json" - "fmt" - "sync" - - "gitea.com/go-chi/session" - couchbase "gitea.com/go-chi/session/couchbase" - memcache "gitea.com/go-chi/session/memcache" - mysql "gitea.com/go-chi/session/mysql" - postgres "gitea.com/go-chi/session/postgres" -) - -// VirtualSessionProvider represents a shadowed session provider implementation. -// TODO: copied from modules/session/redis.go and should remove that one until macaron removed. -type VirtualSessionProvider struct { - lock sync.RWMutex - provider session.Provider -} - -// Init initializes the cookie session provider with given root path. -func (o *VirtualSessionProvider) Init(gclifetime int64, config string) error { - var opts session.Options - if err := json.Unmarshal([]byte(config), &opts); err != nil { - return err - } - // Note that these options are unprepared so we can't just use NewManager here. - // Nor can we access the provider map in session. - // So we will just have to do this by hand. - // This is only slightly more wrong than modules/setting/session.go:23 - switch opts.Provider { - case "memory": - o.provider = &session.MemProvider{} - case "file": - o.provider = &session.FileProvider{} - case "redis": - o.provider = &RedisProvider{} - case "mysql": - o.provider = &mysql.MysqlProvider{} - case "postgres": - o.provider = &postgres.PostgresProvider{} - case "couchbase": - o.provider = &couchbase.CouchbaseProvider{} - case "memcache": - o.provider = &memcache.MemcacheProvider{} - default: - return fmt.Errorf("VirtualSessionProvider: Unknown Provider: %s", opts.Provider) - } - return o.provider.Init(gclifetime, opts.ProviderConfig) -} - -// Read returns raw session store by session ID. -func (o *VirtualSessionProvider) Read(sid string) (session.RawStore, error) { - o.lock.RLock() - defer o.lock.RUnlock() - if o.provider.Exist(sid) { - return o.provider.Read(sid) - } - kv := make(map[interface{}]interface{}) - kv["_old_uid"] = "0" - return NewVirtualStore(o, sid, kv), nil -} - -// Exist returns true if session with given ID exists. -func (o *VirtualSessionProvider) Exist(sid string) bool { - return true -} - -// Destroy deletes a session by session ID. -func (o *VirtualSessionProvider) Destroy(sid string) error { - o.lock.Lock() - defer o.lock.Unlock() - return o.provider.Destroy(sid) -} - -// Regenerate regenerates a session store from old session ID to new one. -func (o *VirtualSessionProvider) Regenerate(oldsid, sid string) (session.RawStore, error) { - o.lock.Lock() - defer o.lock.Unlock() - return o.provider.Regenerate(oldsid, sid) -} - -// Count counts and returns number of sessions. -func (o *VirtualSessionProvider) Count() int { - o.lock.RLock() - defer o.lock.RUnlock() - return o.provider.Count() -} - -// GC calls GC to clean expired sessions. -func (o *VirtualSessionProvider) GC() { - o.provider.GC() -} - -func init() { - session.Register("VirtualSession", &VirtualSessionProvider{}) -} - -// VirtualStore represents a virtual session store implementation. -type VirtualStore struct { - p *VirtualSessionProvider - sid string - lock sync.RWMutex - data map[interface{}]interface{} - released bool -} - -// NewVirtualStore creates and returns a virtual session store. -func NewVirtualStore(p *VirtualSessionProvider, sid string, kv map[interface{}]interface{}) *VirtualStore { - return &VirtualStore{ - p: p, - sid: sid, - data: kv, - } -} - -// Set sets value to given key in session. -func (s *VirtualStore) Set(key, val interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data[key] = val - return nil -} - -// Get gets value by given key in session. -func (s *VirtualStore) Get(key interface{}) interface{} { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.data[key] -} - -// Delete delete a key from session. -func (s *VirtualStore) Delete(key interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - delete(s.data, key) - return nil -} - -// ID returns current session ID. -func (s *VirtualStore) ID() string { - return s.sid -} - -// Release releases resource and save data to provider. -func (s *VirtualStore) Release() error { - s.lock.Lock() - defer s.lock.Unlock() - // Now need to lock the provider - s.p.lock.Lock() - defer s.p.lock.Unlock() - if oldUID, ok := s.data["_old_uid"]; (ok && (oldUID != "0" || len(s.data) > 1)) || (!ok && len(s.data) > 0) { - // Now ensure that we don't exist! - realProvider := s.p.provider - - if !s.released && realProvider.Exist(s.sid) { - // This is an error! - return fmt.Errorf("new sid '%s' already exists", s.sid) - } - realStore, err := realProvider.Read(s.sid) - if err != nil { - return err - } - if err := realStore.Flush(); err != nil { - return err - } - for key, value := range s.data { - if err := realStore.Set(key, value); err != nil { - return err - } - } - err = realStore.Release() - if err == nil { - s.released = true - } - return err - } - return nil -} - -// Flush deletes all session data. -func (s *VirtualStore) Flush() error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data = make(map[interface{}]interface{}) - return nil -} diff --git a/modules/session/redis.go b/modules/session/redis.go index c88ebd57693d9..55e7a851687c5 100644 --- a/modules/session/redis.go +++ b/modules/session/redis.go @@ -23,7 +23,7 @@ import ( "code.gitea.io/gitea/modules/nosql" - "gitea.com/macaron/session" + "gitea.com/go-chi/session" "github.com/go-redis/redis/v7" ) diff --git a/modules/session/store.go b/modules/session/store.go new file mode 100644 index 0000000000000..529187d3be874 --- /dev/null +++ b/modules/session/store.go @@ -0,0 +1,12 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package session + +// Store represents a session store +type Store interface { + Get(interface{}) interface{} + Set(interface{}, interface{}) error + Delete(interface{}) error +} diff --git a/modules/session/virtual.go b/modules/session/virtual.go index 1139cfe89cc13..3da499d71a2ab 100644 --- a/modules/session/virtual.go +++ b/modules/session/virtual.go @@ -9,12 +9,11 @@ import ( "fmt" "sync" - "gitea.com/macaron/session" - couchbase "gitea.com/macaron/session/couchbase" - memcache "gitea.com/macaron/session/memcache" - mysql "gitea.com/macaron/session/mysql" - nodb "gitea.com/macaron/session/nodb" - postgres "gitea.com/macaron/session/postgres" + "gitea.com/go-chi/session" + couchbase "gitea.com/go-chi/session/couchbase" + memcache "gitea.com/go-chi/session/memcache" + mysql "gitea.com/go-chi/session/mysql" + postgres "gitea.com/go-chi/session/postgres" ) // VirtualSessionProvider represents a shadowed session provider implementation. @@ -48,8 +47,6 @@ func (o *VirtualSessionProvider) Init(gclifetime int64, config string) error { o.provider = &couchbase.CouchbaseProvider{} case "memcache": o.provider = &memcache.MemcacheProvider{} - case "nodb": - o.provider = &nodb.NodbProvider{} default: return fmt.Errorf("VirtualSessionProvider: Unknown Provider: %s", opts.Provider) } diff --git a/modules/setting/log.go b/modules/setting/log.go index 35bf021ac2d20..daa449a5ca76c 100644 --- a/modules/setting/log.go +++ b/modules/setting/log.go @@ -254,17 +254,6 @@ func generateNamedLogger(key string, options defaultLogOptions) *LogDescription return &description } -func newMacaronLogService() { - options := newDefaultLogOptions() - options.filename = filepath.Join(LogRootPath, "macaron.log") - options.bufferLength = Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000) - - Cfg.Section("log").Key("MACARON").MustString("file") - if RedirectMacaronLog { - generateNamedLogger("macaron", options) - } -} - func newAccessLogService() { EnableAccessLog = Cfg.Section("log").Key("ENABLE_ACCESS_LOG").MustBool(false) AccessLogTemplate = Cfg.Section("log").Key("ACCESS_LOG_TEMPLATE").MustString( @@ -360,7 +349,6 @@ func RestartLogsWithPIDSuffix() { // NewLogServices creates all the log services func NewLogServices(disableConsole bool) { newLogService() - newMacaronLogService() newRouterLogService() newAccessLogService() NewXORMLogService(disableConsole) diff --git a/modules/setting/session.go b/modules/setting/session.go index bd51c420a0efe..222c246e111a9 100644 --- a/modules/setting/session.go +++ b/modules/setting/session.go @@ -41,7 +41,7 @@ var ( func newSessionService() { sec := Cfg.Section("session") SessionConfig.Provider = sec.Key("PROVIDER").In("memory", - []string{"memory", "file", "redis", "mysql", "postgres", "couchbase", "memcache", "nodb"}) + []string{"memory", "file", "redis", "mysql", "postgres", "couchbase", "memcache"}) SessionConfig.ProviderConfig = strings.Trim(sec.Key("PROVIDER_CONFIG").MustString(path.Join(AppDataPath, "sessions")), "\" ") if SessionConfig.Provider == "file" && !filepath.IsAbs(SessionConfig.ProviderConfig) { SessionConfig.ProviderConfig = path.Join(AppWorkPath, SessionConfig.ProviderConfig) diff --git a/modules/templates/base.go b/modules/templates/base.go index a9b6b2737c368..ff31c12899408 100644 --- a/modules/templates/base.go +++ b/modules/templates/base.go @@ -12,6 +12,8 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + + "github.com/unrolled/render" ) // Vars represents variables to be render in golang templates @@ -80,3 +82,15 @@ func getDirAssetNames(dir string) []string { } return tmpls } + +// HTMLRenderer returns a render. +func HTMLRenderer() *render.Render { + return render.New(render.Options{ + Extensions: []string{".tmpl"}, + Directory: "templates", + Funcs: NewFuncMap(), + Asset: GetAsset, + AssetNames: GetAssetNames, + IsDevelopment: !setting.IsProd(), + }) +} diff --git a/modules/templates/dynamic.go b/modules/templates/dynamic.go index f7f05e9b7c170..160e4e05f2501 100644 --- a/modules/templates/dynamic.go +++ b/modules/templates/dynamic.go @@ -18,8 +18,6 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - - "gitea.com/macaron/macaron" ) var ( @@ -46,29 +44,6 @@ func GetAssetNames() []string { return append(tmpls, tmpls2...) } -// HTMLRenderer implements the macaron handler for serving HTML templates. -func HTMLRenderer() macaron.Handler { - return macaron.Renderer(macaron.RenderOptions{ - Funcs: NewFuncMap(), - Directory: path.Join(setting.StaticRootPath, "templates"), - AppendDirectories: []string{ - path.Join(setting.CustomPath, "templates"), - }, - }) -} - -// JSONRenderer implements the macaron handler for serving JSON templates. -func JSONRenderer() macaron.Handler { - return macaron.Renderer(macaron.RenderOptions{ - Funcs: NewFuncMap(), - Directory: path.Join(setting.StaticRootPath, "templates"), - AppendDirectories: []string{ - path.Join(setting.CustomPath, "templates"), - }, - HTMLContentType: "application/json", - }) -} - // Mailer provides the templates required for sending notification mails. func Mailer() (*texttmpl.Template, *template.Template) { for _, funcs := range NewTextFuncMap() { diff --git a/modules/templates/static.go b/modules/templates/static.go index 1dd3d217fccc5..7f95d77ad3242 100644 --- a/modules/templates/static.go +++ b/modules/templates/static.go @@ -7,10 +7,7 @@ package templates import ( - "bytes" - "fmt" "html/template" - "io" "io/ioutil" "os" "path" @@ -21,8 +18,6 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - - "gitea.com/macaron/macaron" ) var ( @@ -30,24 +25,6 @@ var ( bodyTemplates = template.New("") ) -type templateFileSystem struct { - files []macaron.TemplateFile -} - -func (templates templateFileSystem) ListFiles() []macaron.TemplateFile { - return templates.files -} - -func (templates templateFileSystem) Get(name string) (io.Reader, error) { - for i := range templates.files { - if templates.files[i].Name()+templates.files[i].Ext() == name { - return bytes.NewReader(templates.files[i].Data()), nil - } - } - - return nil, fmt.Errorf("file '%s' not found", name) -} - // GetAsset get a special asset, only for chi func GetAsset(name string) ([]byte, error) { bs, err := ioutil.ReadFile(filepath.Join(setting.CustomPath, name)) @@ -72,95 +49,6 @@ func GetAssetNames() []string { return append(tmpls, customTmpls...) } -func NewTemplateFileSystem() templateFileSystem { - fs := templateFileSystem{} - fs.files = make([]macaron.TemplateFile, 0, 10) - - for _, assetPath := range AssetNames() { - if strings.HasPrefix(assetPath, "mail/") { - continue - } - - if !strings.HasSuffix(assetPath, ".tmpl") { - continue - } - - content, err := Asset(assetPath) - - if err != nil { - log.Warn("Failed to read embedded %s template. %v", assetPath, err) - continue - } - - fs.files = append(fs.files, macaron.NewTplFile( - strings.TrimSuffix( - assetPath, - ".tmpl", - ), - content, - ".tmpl", - )) - } - - customDir := path.Join(setting.CustomPath, "templates") - isDir, err := util.IsDir(customDir) - if err != nil { - log.Warn("Unable to check if templates dir %s is a directory. Error: %v", customDir, err) - } - if isDir { - files, err := util.StatDir(customDir) - - if err != nil { - log.Warn("Failed to read %s templates dir. %v", customDir, err) - } else { - for _, filePath := range files { - if strings.HasPrefix(filePath, "mail/") { - continue - } - - if !strings.HasSuffix(filePath, ".tmpl") { - continue - } - - content, err := ioutil.ReadFile(path.Join(customDir, filePath)) - - if err != nil { - log.Warn("Failed to read custom %s template. %v", filePath, err) - continue - } - - fs.files = append(fs.files, macaron.NewTplFile( - strings.TrimSuffix( - filePath, - ".tmpl", - ), - content, - ".tmpl", - )) - } - } - } - - return fs -} - -// HTMLRenderer implements the macaron handler for serving HTML templates. -func HTMLRenderer() macaron.Handler { - return macaron.Renderer(macaron.RenderOptions{ - Funcs: NewFuncMap(), - TemplateFileSystem: NewTemplateFileSystem(), - }) -} - -// JSONRenderer implements the macaron handler for serving JSON templates. -func JSONRenderer() macaron.Handler { - return macaron.Renderer(macaron.RenderOptions{ - Funcs: NewFuncMap(), - TemplateFileSystem: NewTemplateFileSystem(), - HTMLContentType: "application/json", - }) -} - // Mailer provides the templates required for sending notification mails. func Mailer() (*texttmpl.Template, *template.Template) { for _, funcs := range NewTextFuncMap() { diff --git a/modules/test/context_tests.go b/modules/test/context_tests.go index 874d7db196eb9..e219a8e56ab0a 100644 --- a/modules/test/context_tests.go +++ b/modules/test/context_tests.go @@ -5,6 +5,9 @@ package test import ( + scontext "context" + "html/template" + "io" "net/http" "net/http/httptest" "net/url" @@ -13,32 +16,37 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/middlewares" - "gitea.com/macaron/macaron" - "gitea.com/macaron/session" + "github.com/go-chi/chi" "github.com/stretchr/testify/assert" + "github.com/unrolled/render" ) // MockContext mock context for unit tests func MockContext(t *testing.T, path string) *context.Context { - var macaronContext macaron.Context - macaronContext.ReplaceAllParams(macaron.Params{}) - macaronContext.Locale = &mockLocale{} + var resp = &mockResponseWriter{} + var ctx = context.Context{ + Render: &mockRender{}, + Data: make(map[string]interface{}), + Flash: &middlewares.Flash{ + Values: make(url.Values), + }, + Resp: context.NewResponse(resp), + Locale: &mockLocale{}, + } + requestURL, err := url.Parse(path) assert.NoError(t, err) - macaronContext.Req = macaron.Request{Request: &http.Request{ + var req = &http.Request{ URL: requestURL, Form: url.Values{}, - }} - macaronContext.Resp = &mockResponseWriter{} - macaronContext.Render = &mockRender{ResponseWriter: macaronContext.Resp} - macaronContext.Data = map[string]interface{}{} - return &context.Context{ - Context: &macaronContext, - Flash: &session.Flash{ - Values: make(url.Values), - }, } + + chiCtx := chi.NewRouteContext() + req = req.WithContext(scontext.WithValue(req.Context(), chi.RouteCtxKey, chiCtx)) + ctx.Req = context.WithContext(req, &ctx) + return &ctx } // LoadRepo load a repo into a test context. @@ -113,77 +121,20 @@ func (rw *mockResponseWriter) Size() int { return rw.size } -func (rw *mockResponseWriter) Before(b macaron.BeforeFunc) { - b(rw) -} - func (rw *mockResponseWriter) Push(target string, opts *http.PushOptions) error { return nil } type mockRender struct { - http.ResponseWriter -} - -func (tr *mockRender) SetResponseWriter(rw http.ResponseWriter) { - tr.ResponseWriter = rw -} - -func (tr *mockRender) JSON(status int, _ interface{}) { - tr.Status(status) -} - -func (tr *mockRender) JSONString(interface{}) (string, error) { - return "", nil -} - -func (tr *mockRender) RawData(status int, _ []byte) { - tr.Status(status) -} - -func (tr *mockRender) PlainText(status int, _ []byte) { - tr.Status(status) -} - -func (tr *mockRender) HTML(status int, _ string, _ interface{}, _ ...macaron.HTMLOptions) { - tr.Status(status) -} - -func (tr *mockRender) HTMLSet(status int, _ string, _ string, _ interface{}, _ ...macaron.HTMLOptions) { - tr.Status(status) -} - -func (tr *mockRender) HTMLSetString(string, string, interface{}, ...macaron.HTMLOptions) (string, error) { - return "", nil -} - -func (tr *mockRender) HTMLString(string, interface{}, ...macaron.HTMLOptions) (string, error) { - return "", nil -} - -func (tr *mockRender) HTMLSetBytes(string, string, interface{}, ...macaron.HTMLOptions) ([]byte, error) { - return nil, nil -} - -func (tr *mockRender) HTMLBytes(string, interface{}, ...macaron.HTMLOptions) ([]byte, error) { - return nil, nil -} - -func (tr *mockRender) XML(status int, _ interface{}) { - tr.Status(status) -} - -func (tr *mockRender) Error(status int, _ ...string) { - tr.Status(status) } -func (tr *mockRender) Status(status int) { - tr.ResponseWriter.WriteHeader(status) -} - -func (tr *mockRender) SetTemplatePath(string, string) { +func (tr *mockRender) TemplateLookup(tmpl string) *template.Template { + return nil } -func (tr *mockRender) HasTemplateSet(string) bool { - return true +func (tr *mockRender) HTML(w io.Writer, status int, _ string, _ interface{}, _ ...render.HTMLOptions) error { + if resp, ok := w.(http.ResponseWriter); ok { + resp.WriteHeader(status) + } + return nil } diff --git a/modules/timeutil/since_test.go b/modules/timeutil/since_test.go index 65d481a6aa71d..5710e91db5f0b 100644 --- a/modules/timeutil/since_test.go +++ b/modules/timeutil/since_test.go @@ -10,8 +10,8 @@ import ( "time" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/translation" - macaroni18n "gitea.com/macaron/i18n" "github.com/stretchr/testify/assert" "github.com/unknwon/i18n" ) @@ -27,13 +27,11 @@ const ( ) func TestMain(m *testing.M) { + setting.StaticRootPath = "../../" + setting.Names = []string{"english"} + setting.Langs = []string{"en-US"} // setup - macaroni18n.I18n(macaroni18n.Options{ - Directory: "../../options/locale/", - DefaultLang: "en-US", - Langs: []string{"en-US"}, - Names: []string{"english"}, - }) + translation.InitLocales() BaseDate = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC) // run the tests diff --git a/modules/translation/translation.go b/modules/translation/translation.go index e39bf8b21352f..94a93a40ae2a3 100644 --- a/modules/translation/translation.go +++ b/modules/translation/translation.go @@ -9,7 +9,6 @@ import ( "code.gitea.io/gitea/modules/options" "code.gitea.io/gitea/modules/setting" - macaron_i18n "gitea.com/macaron/i18n" "github.com/unknwon/i18n" "golang.org/x/text/language" ) @@ -20,49 +19,57 @@ type Locale interface { Tr(string, ...interface{}) string } +// LangType represents a lang type +type LangType struct { + Lang, Name string +} + var ( - matcher language.Matcher + matcher language.Matcher + allLangs []LangType ) +// AllLangs returns all supported langauages +func AllLangs() []LangType { + return allLangs +} + // InitLocales loads the locales func InitLocales() { localeNames, err := options.Dir("locale") - if err != nil { log.Fatal("Failed to list locale files: %v", err) } - localFiles := make(map[string][]byte) + localFiles := make(map[string][]byte) for _, name := range localeNames { localFiles[name], err = options.Locale(name) - if err != nil { log.Fatal("Failed to load %s locale file. %v", name, err) } } // These codes will be used once macaron removed - /*tags := make([]language.Tag, len(setting.Langs)) + tags := make([]language.Tag, len(setting.Langs)) for i, lang := range setting.Langs { tags[i] = language.Raw.Make(lang) } + matcher = language.NewMatcher(tags) - for i, name := range setting.Names { - i18n.SetMessage(setting.Langs[i], localFiles[name]) + for i := range setting.Names { + key := "locale_" + setting.Langs[i] + ".ini" + if err := i18n.SetMessageWithDesc(setting.Langs[i], setting.Names[i], localFiles[key]); err != nil { + log.Fatal("Failed to set messages to %s: %v", setting.Langs[i], err) + } + } + i18n.SetDefaultLang("en-US") + + allLangs = make([]LangType, 0, i18n.Count()-1) + langs := i18n.ListLangs() + names := i18n.ListLangDescs() + for i, v := range langs { + allLangs = append(allLangs, LangType{v, names[i]}) } - i18n.SetDefaultLang("en-US")*/ - - // To be compatible with macaron, we now have to use macaron i18n, once macaron - // removed, we can use i18n directly - macaron_i18n.I18n(macaron_i18n.Options{ - SubURL: setting.AppSubURL, - Files: localFiles, - Langs: setting.Langs, - Names: setting.Names, - DefaultLang: "en-US", - Redirect: false, - CookieDomain: setting.SessionConfig.Domain, - }) } // Match matches accept languages diff --git a/modules/validation/binding.go b/modules/validation/binding.go index 1c67878ea1023..5cfd994d2daeb 100644 --- a/modules/validation/binding.go +++ b/modules/validation/binding.go @@ -9,7 +9,7 @@ import ( "regexp" "strings" - "gitea.com/macaron/binding" + "gitea.com/go-chi/binding" "github.com/gobwas/glob" ) diff --git a/modules/validation/binding_test.go b/modules/validation/binding_test.go index 9fc9a6db08b7e..e0daba89e502a 100644 --- a/modules/validation/binding_test.go +++ b/modules/validation/binding_test.go @@ -9,8 +9,8 @@ import ( "net/http/httptest" "testing" - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "gitea.com/go-chi/binding" + "github.com/go-chi/chi" "github.com/stretchr/testify/assert" ) @@ -34,9 +34,10 @@ type ( func performValidationTest(t *testing.T, testCase validationTestCase) { httpRecorder := httptest.NewRecorder() - m := macaron.Classic() + m := chi.NewRouter() - m.Post(testRoute, binding.Validate(testCase.data), func(actual binding.Errors) { + m.Post(testRoute, func(resp http.ResponseWriter, req *http.Request) { + actual := binding.Validate(req, testCase.data) // see https://github.com/stretchr/testify/issues/435 if actual == nil { actual = binding.Errors{} @@ -49,7 +50,7 @@ func performValidationTest(t *testing.T, testCase validationTestCase) { if err != nil { panic(err) } - + req.Header.Add("Content-Type", "x-www-form-urlencoded") m.ServeHTTP(httpRecorder, req) switch httpRecorder.Code { diff --git a/modules/validation/glob_pattern_test.go b/modules/validation/glob_pattern_test.go index 26775167b4f05..cbaed7e66ac24 100644 --- a/modules/validation/glob_pattern_test.go +++ b/modules/validation/glob_pattern_test.go @@ -7,7 +7,7 @@ package validation import ( "testing" - "gitea.com/macaron/binding" + "gitea.com/go-chi/binding" "github.com/gobwas/glob" ) diff --git a/modules/validation/refname_test.go b/modules/validation/refname_test.go index 521a83fa04a01..974d9565632d0 100644 --- a/modules/validation/refname_test.go +++ b/modules/validation/refname_test.go @@ -7,7 +7,7 @@ package validation import ( "testing" - "gitea.com/macaron/binding" + "gitea.com/go-chi/binding" ) var gitRefNameValidationTestCases = []validationTestCase{ diff --git a/modules/validation/validurl_test.go b/modules/validation/validurl_test.go index aed7406c0a378..3cb620660203b 100644 --- a/modules/validation/validurl_test.go +++ b/modules/validation/validurl_test.go @@ -7,7 +7,7 @@ package validation import ( "testing" - "gitea.com/macaron/binding" + "gitea.com/go-chi/binding" ) var urlValidationTestCases = []validationTestCase{ diff --git a/modules/web/route.go b/modules/web/route.go new file mode 100644 index 0000000000000..701b3beed2113 --- /dev/null +++ b/modules/web/route.go @@ -0,0 +1,322 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package web + +import ( + "fmt" + "net/http" + "reflect" + "strings" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/middlewares" + + "gitea.com/go-chi/binding" + "github.com/go-chi/chi" +) + +// Wrap converts all kinds of routes to standard library one +func Wrap(handlers ...interface{}) http.HandlerFunc { + if len(handlers) == 0 { + panic("No handlers found") + } + + for _, handler := range handlers { + switch t := handler.(type) { + case http.HandlerFunc, func(http.ResponseWriter, *http.Request), + func(ctx *context.Context), + func(*context.APIContext), + func(*context.PrivateContext), + func(http.Handler) http.Handler: + default: + panic(fmt.Sprintf("Unsupported handler type: %#v", t)) + } + } + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + for i := 0; i < len(handlers); i++ { + handler := handlers[i] + switch t := handler.(type) { + case http.HandlerFunc: + t(resp, req) + if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 { + return + } + case func(http.ResponseWriter, *http.Request): + t(resp, req) + if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 { + return + } + case func(ctx *context.Context): + ctx := context.GetContext(req) + t(ctx) + if ctx.Written() { + return + } + case func(*context.APIContext): + ctx := context.GetAPIContext(req) + t(ctx) + if ctx.Written() { + return + } + case func(*context.PrivateContext): + ctx := context.GetPrivateContext(req) + t(ctx) + if ctx.Written() { + return + } + case func(http.Handler) http.Handler: + var next = http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}) + t(next).ServeHTTP(resp, req) + if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 { + return + } + default: + panic(fmt.Sprintf("Unsupported handler type: %#v", t)) + } + } + }) +} + +// Middle wrap a context function as a chi middleware +func Middle(f func(ctx *context.Context)) func(netx http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + ctx := context.GetContext(req) + f(ctx) + if ctx.Written() { + return + } + next.ServeHTTP(ctx.Resp, ctx.Req) + }) + } +} + +// MiddleAPI wrap a context function as a chi middleware +func MiddleAPI(f func(ctx *context.APIContext)) func(netx http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + ctx := context.GetAPIContext(req) + f(ctx) + if ctx.Written() { + return + } + next.ServeHTTP(ctx.Resp, ctx.Req) + }) + } +} + +// Bind binding an obj to a handler +func Bind(obj interface{}) http.HandlerFunc { + var tp = reflect.TypeOf(obj) + if tp.Kind() == reflect.Ptr { + tp = tp.Elem() + } + if tp.Kind() != reflect.Struct { + panic("Only structs are allowed to bind") + } + return Wrap(func(ctx *context.Context) { + var theObj = reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly + binding.Bind(ctx.Req, theObj) + SetForm(ctx, theObj) + middlewares.AssignForm(theObj, ctx.Data) + }) +} + +// SetForm set the form object +func SetForm(data middlewares.DataStore, obj interface{}) { + data.GetData()["__form"] = obj +} + +// GetForm returns the validate form information +func GetForm(data middlewares.DataStore) interface{} { + return data.GetData()["__form"] +} + +// Route defines a route based on chi's router +type Route struct { + R chi.Router + curGroupPrefix string + curMiddlewares []interface{} +} + +// NewRoute creates a new route +func NewRoute() *Route { + r := chi.NewRouter() + return &Route{ + R: r, + curGroupPrefix: "", + curMiddlewares: []interface{}{}, + } +} + +// Use supports two middlewares +func (r *Route) Use(middlewares ...interface{}) { + if r.curGroupPrefix != "" { + r.curMiddlewares = append(r.curMiddlewares, middlewares...) + } else { + for _, middle := range middlewares { + switch t := middle.(type) { + case func(http.Handler) http.Handler: + r.R.Use(t) + case func(*context.Context): + r.R.Use(Middle(t)) + case func(*context.APIContext): + r.R.Use(MiddleAPI(t)) + default: + panic(fmt.Sprintf("Unsupported middleware type: %#v", t)) + } + } + } +} + +// Group mounts a sub-Router along a `pattern` string. +func (r *Route) Group(pattern string, fn func(), middlewares ...interface{}) { + var previousGroupPrefix = r.curGroupPrefix + var previousMiddlewares = r.curMiddlewares + r.curGroupPrefix += pattern + r.curMiddlewares = append(r.curMiddlewares, middlewares...) + + fn() + + r.curGroupPrefix = previousGroupPrefix + r.curMiddlewares = previousMiddlewares +} + +func (r *Route) getPattern(pattern string) string { + newPattern := r.curGroupPrefix + pattern + if !strings.HasPrefix(newPattern, "/") { + newPattern = "/" + newPattern + } + if newPattern == "/" { + return newPattern + } + return strings.TrimSuffix(newPattern, "/") +} + +// Mount attaches another Route along ./pattern/* +func (r *Route) Mount(pattern string, subR *Route) { + var middlewares = make([]interface{}, len(r.curMiddlewares)) + copy(middlewares, r.curMiddlewares) + subR.Use(middlewares...) + r.R.Mount(r.getPattern(pattern), subR.R) +} + +// Any delegate requests for all methods +func (r *Route) Any(pattern string, h ...interface{}) { + var middlewares = r.getMiddlewares(h) + r.R.HandleFunc(r.getPattern(pattern), Wrap(middlewares...)) +} + +// Route delegate special methods +func (r *Route) Route(pattern string, methods string, h ...interface{}) { + p := r.getPattern(pattern) + ms := strings.Split(methods, ",") + var middlewares = r.getMiddlewares(h) + for _, method := range ms { + r.R.MethodFunc(strings.TrimSpace(method), p, Wrap(middlewares...)) + } +} + +// Delete delegate delete method +func (r *Route) Delete(pattern string, h ...interface{}) { + var middlewares = r.getMiddlewares(h) + r.R.Delete(r.getPattern(pattern), Wrap(middlewares...)) +} + +func (r *Route) getMiddlewares(h []interface{}) []interface{} { + var middlewares = make([]interface{}, len(r.curMiddlewares), len(r.curMiddlewares)+len(h)) + copy(middlewares, r.curMiddlewares) + middlewares = append(middlewares, h...) + return middlewares +} + +// Get delegate get method +func (r *Route) Get(pattern string, h ...interface{}) { + var middlewares = r.getMiddlewares(h) + r.R.Get(r.getPattern(pattern), Wrap(middlewares...)) +} + +// Head delegate head method +func (r *Route) Head(pattern string, h ...interface{}) { + var middlewares = r.getMiddlewares(h) + r.R.Head(r.getPattern(pattern), Wrap(middlewares...)) +} + +// Post delegate post method +func (r *Route) Post(pattern string, h ...interface{}) { + var middlewares = r.getMiddlewares(h) + r.R.Post(r.getPattern(pattern), Wrap(middlewares...)) +} + +// Put delegate put method +func (r *Route) Put(pattern string, h ...interface{}) { + var middlewares = r.getMiddlewares(h) + r.R.Put(r.getPattern(pattern), Wrap(middlewares...)) +} + +// Patch delegate patch method +func (r *Route) Patch(pattern string, h ...interface{}) { + var middlewares = r.getMiddlewares(h) + r.R.Patch(r.getPattern(pattern), Wrap(middlewares...)) +} + +// ServeHTTP implements http.Handler +func (r *Route) ServeHTTP(w http.ResponseWriter, req *http.Request) { + r.R.ServeHTTP(w, req) +} + +// NotFound defines a handler to respond whenever a route could +// not be found. +func (r *Route) NotFound(h http.HandlerFunc) { + r.R.NotFound(h) +} + +// MethodNotAllowed defines a handler to respond whenever a method is +// not allowed. +func (r *Route) MethodNotAllowed(h http.HandlerFunc) { + r.R.MethodNotAllowed(h) +} + +// Combo deletegate requests to Combo +func (r *Route) Combo(pattern string, h ...interface{}) *Combo { + return &Combo{r, pattern, h} +} + +// Combo represents a tiny group routes with same pattern +type Combo struct { + r *Route + pattern string + h []interface{} +} + +// Get deletegate Get method +func (c *Combo) Get(h ...interface{}) *Combo { + c.r.Get(c.pattern, append(c.h, h...)...) + return c +} + +// Post deletegate Post method +func (c *Combo) Post(h ...interface{}) *Combo { + c.r.Post(c.pattern, append(c.h, h...)...) + return c +} + +// Delete deletegate Delete method +func (c *Combo) Delete(h ...interface{}) *Combo { + c.r.Delete(c.pattern, append(c.h, h...)...) + return c +} + +// Put deletegate Put method +func (c *Combo) Put(h ...interface{}) *Combo { + c.r.Put(c.pattern, append(c.h, h...)...) + return c +} + +// Patch deletegate Patch method +func (c *Combo) Patch(h ...interface{}) *Combo { + c.r.Patch(c.pattern, append(c.h, h...)...) + return c +} diff --git a/modules/web/route_test.go b/modules/web/route_test.go new file mode 100644 index 0000000000000..03955f0f2d97f --- /dev/null +++ b/modules/web/route_test.go @@ -0,0 +1,169 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package web + +import ( + "bytes" + "net/http" + "net/http/httptest" + "testing" + + "github.com/go-chi/chi" + "github.com/stretchr/testify/assert" +) + +func TestRoute1(t *testing.T) { + buff := bytes.NewBufferString("") + recorder := httptest.NewRecorder() + recorder.Body = buff + + r := NewRoute() + r.Get("/{username}/{reponame}/{type:issues|pulls}", func(resp http.ResponseWriter, req *http.Request) { + username := chi.URLParam(req, "username") + assert.EqualValues(t, "gitea", username) + reponame := chi.URLParam(req, "reponame") + assert.EqualValues(t, "gitea", reponame) + tp := chi.URLParam(req, "type") + assert.EqualValues(t, "issues", tp) + }) + + req, err := http.NewRequest("GET", "http://localhost:8000/gitea/gitea/issues", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.EqualValues(t, http.StatusOK, recorder.Code) +} + +func TestRoute2(t *testing.T) { + buff := bytes.NewBufferString("") + recorder := httptest.NewRecorder() + recorder.Body = buff + + var route int + + r := NewRoute() + r.Group("/{username}/{reponame}", func() { + r.Group("", func() { + r.Get("/{type:issues|pulls}", func(resp http.ResponseWriter, req *http.Request) { + username := chi.URLParam(req, "username") + assert.EqualValues(t, "gitea", username) + reponame := chi.URLParam(req, "reponame") + assert.EqualValues(t, "gitea", reponame) + tp := chi.URLParam(req, "type") + assert.EqualValues(t, "issues", tp) + route = 0 + }) + + r.Get("/{type:issues|pulls}/{index}", func(resp http.ResponseWriter, req *http.Request) { + username := chi.URLParam(req, "username") + assert.EqualValues(t, "gitea", username) + reponame := chi.URLParam(req, "reponame") + assert.EqualValues(t, "gitea", reponame) + tp := chi.URLParam(req, "type") + assert.EqualValues(t, "issues", tp) + index := chi.URLParam(req, "index") + assert.EqualValues(t, "1", index) + route = 1 + }) + }, func(resp http.ResponseWriter, req *http.Request) { + resp.WriteHeader(200) + }) + + r.Group("/issues/{index}", func() { + r.Get("/view", func(resp http.ResponseWriter, req *http.Request) { + username := chi.URLParam(req, "username") + assert.EqualValues(t, "gitea", username) + reponame := chi.URLParam(req, "reponame") + assert.EqualValues(t, "gitea", reponame) + index := chi.URLParam(req, "index") + assert.EqualValues(t, "1", index) + route = 2 + }) + }) + }) + + req, err := http.NewRequest("GET", "http://localhost:8000/gitea/gitea/issues", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.EqualValues(t, http.StatusOK, recorder.Code) + assert.EqualValues(t, 0, route) + + req, err = http.NewRequest("GET", "http://localhost:8000/gitea/gitea/issues/1", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.EqualValues(t, http.StatusOK, recorder.Code) + assert.EqualValues(t, 1, route) + + req, err = http.NewRequest("GET", "http://localhost:8000/gitea/gitea/issues/1/view", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.EqualValues(t, http.StatusOK, recorder.Code) + assert.EqualValues(t, 2, route) +} + +func TestRoute3(t *testing.T) { + buff := bytes.NewBufferString("") + recorder := httptest.NewRecorder() + recorder.Body = buff + + var route int + + m := NewRoute() + r := NewRoute() + r.Mount("/api/v1", m) + + m.Group("/repos", func() { + m.Group("/{username}/{reponame}", func() { + m.Group("/branch_protections", func() { + m.Get("", func(resp http.ResponseWriter, req *http.Request) { + route = 0 + }) + m.Post("", func(resp http.ResponseWriter, req *http.Request) { + route = 1 + }) + m.Group("/{name}", func() { + m.Get("", func(resp http.ResponseWriter, req *http.Request) { + route = 2 + }) + m.Patch("", func(resp http.ResponseWriter, req *http.Request) { + route = 3 + }) + m.Delete("", func(resp http.ResponseWriter, req *http.Request) { + route = 4 + }) + }) + }) + }) + }) + + req, err := http.NewRequest("GET", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.EqualValues(t, http.StatusOK, recorder.Code) + assert.EqualValues(t, 0, route) + + req, err = http.NewRequest("POST", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.EqualValues(t, http.StatusOK, recorder.Code, http.StatusOK) + assert.EqualValues(t, 1, route) + + req, err = http.NewRequest("GET", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections/master", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.EqualValues(t, http.StatusOK, recorder.Code) + assert.EqualValues(t, 2, route) + + req, err = http.NewRequest("PATCH", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections/master", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.EqualValues(t, http.StatusOK, recorder.Code) + assert.EqualValues(t, 3, route) + + req, err = http.NewRequest("DELETE", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections/master", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.EqualValues(t, http.StatusOK, recorder.Code) + assert.EqualValues(t, 4, route) +} diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 31b55b499cd40..76433e6daafe0 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -1538,8 +1538,7 @@ settings.trust_model.collaborator.long=Mitarbeiter: Vertraue Signaturen von Mita settings.trust_model.collaborator.desc=Gültige Signaturen von Mitarbeitern dieses Projekts werden als "vertrauenswürdig" markiert - ( egal ob sie mit dem Committer übereinstimmen oder nicht). Andernfalls werden gültige Signaturen als "nicht vertrauenswürdig" markiert, unabhängig ob die Signatur mit dem Committer übereinstimmt oder nicht. settings.trust_model.committer=Committer settings.trust_model.committer.long=Committer: Vertraue Signaturen, die zu Committern passen (Dies stimmt mit GitHub überein und zwingt signierte Commits von Gitea dazu, Gitea als Committer zu haben) -settings.trust_model.committer.desc=Gültige Signaturen von Mitwirkenden werden als "vertrauenswürdig" gekennzeichnet, wenn sie mit ihrem Committer übereinstimmen. Ansonsten werden sie als "nicht übereinstimmend" markiert. Das führt dazu, dass Gitea auf signierten Commits, bei denen der echte Committer als Co-authored-by: oder Co-committed-by in der Beschreibung eingetragen wurde, als Committer gilt. -Der Standard Gitea Schlüssel muss auf einen User in der Datenbank zeigen. +settings.trust_model.committer.desc=Gültige Signaturen von Mitwirkenden werden als "vertrauenswürdig" gekennzeichnet, wenn sie mit ihrem Committer übereinstimmen. Ansonsten werden sie als "nicht übereinstimmend" markiert. Das führt dazu, dass Gitea auf signierten Commits, bei denen der echte Committer als Co-authored-by: oder Co-committed-by in der Beschreibung eingetragen wurde, als Committer gilt. Der Standard Gitea Schlüssel muss auf einen User in der Datenbank zeigen. settings.trust_model.collaboratorcommitter=Mitarbeiter+Committer settings.trust_model.collaboratorcommitter.long=Mitarbeiter+Committer: Signaturen der Mitarbeiter vertrauen die mit dem Committer übereinstimmen settings.trust_model.collaboratorcommitter.desc=Gültige Signaturen von Mitarbeitern dieses Projekts werden als "vertrauenswürdig" markiert, wenn sie mit dem Committer übereinstimmen. Andernfalls werden gültige Signaturen als "nicht vertrauenswürdig" markiert, wenn die Signatur mit dem Committer übereinstimmt als "nicht übereinstimmend". Dies zwingt Gitea als Committer bei signierten Commits mit dem tatsächlichen Committer als Co-Authored-By: und Co-Committed-By: Trailer im Commit. Der Standard-Gitea-Schlüssel muss mit einem Benutzer in der Datenbank übereinstimmen. diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 4180076b087f1..250bc5da5ec39 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -16,20 +16,20 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/cron" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/queue" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/mailer" - "gitea.com/macaron/macaron" - "gitea.com/macaron/session" + "gitea.com/go-chi/session" ) const ( @@ -132,7 +132,8 @@ func Dashboard(ctx *context.Context) { } // DashboardPost run an admin operation -func DashboardPost(ctx *context.Context, form auth.AdminDashboardForm) { +func DashboardPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AdminDashboardForm) ctx.Data["Title"] = ctx.Tr("admin.dashboard") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminDashboard"] = true @@ -239,7 +240,7 @@ func Config(ctx *context.Context) { ctx.Data["OfflineMode"] = setting.OfflineMode ctx.Data["DisableRouterLog"] = setting.DisableRouterLog ctx.Data["RunUser"] = setting.RunUser - ctx.Data["RunMode"] = strings.Title(macaron.Env) + ctx.Data["RunMode"] = strings.Title(setting.RunMode) if version, err := git.LocalVersion(); err == nil { ctx.Data["GitVersion"] = version.Original() } diff --git a/routers/admin/auths.go b/routers/admin/auths.go index 7a9d286373e51..12d0a2ccfa129 100644 --- a/routers/admin/auths.go +++ b/routers/admin/auths.go @@ -10,15 +10,16 @@ import ( "regexp" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/auth/ldap" "code.gitea.io/gitea/modules/auth/oauth2" "code.gitea.io/gitea/modules/auth/pam" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "xorm.io/xorm/convert" ) @@ -206,7 +207,8 @@ func parseSSPIConfig(ctx *context.Context, form auth.AuthenticationForm) (*model } // NewAuthSourcePost response for adding an auth source -func NewAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) { +func NewAuthSourcePost(ctx *context.Context) { + form := *web.GetForm(ctx).(*auth.AuthenticationForm) ctx.Data["Title"] = ctx.Tr("admin.auths.new") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminAuthentications"] = true @@ -312,7 +314,8 @@ func EditAuthSource(ctx *context.Context) { } // EditAuthSourcePost response for editing auth source -func EditAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) { +func EditAuthSourcePost(ctx *context.Context) { + form := *web.GetForm(ctx).(*auth.AuthenticationForm) ctx.Data["Title"] = ctx.Tr("admin.auths.edit") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminAuthentications"] = true diff --git a/routers/admin/users.go b/routers/admin/users.go index 74fce9a10cb53..2d40a883af3db 100644 --- a/routers/admin/users.go +++ b/routers/admin/users.go @@ -11,12 +11,13 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/password" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers" router_user_setting "code.gitea.io/gitea/routers/user/setting" "code.gitea.io/gitea/services/mailer" @@ -63,7 +64,8 @@ func NewUser(ctx *context.Context) { } // NewUserPost response for adding a new user -func NewUserPost(ctx *context.Context, form auth.AdminCreateUserForm) { +func NewUserPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AdminCreateUserForm) ctx.Data["Title"] = ctx.Tr("admin.users.new_account") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true @@ -214,7 +216,8 @@ func EditUser(ctx *context.Context) { } // EditUserPost response for editting user -func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) { +func EditUserPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AdminEditUserForm) ctx.Data["Title"] = ctx.Tr("admin.users.edit_account") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true diff --git a/routers/admin/users_test.go b/routers/admin/users_test.go index a282507f56b6c..bd00bb2bf1893 100644 --- a/routers/admin/users_test.go +++ b/routers/admin/users_test.go @@ -8,8 +8,9 @@ import ( "testing" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/web" "github.com/stretchr/testify/assert" ) @@ -39,7 +40,8 @@ func TestNewUserPost_MustChangePassword(t *testing.T) { MustChangePassword: true, } - NewUserPost(ctx, form) + web.SetForm(ctx, &form) + NewUserPost(ctx) assert.NotEmpty(t, ctx.Flash.SuccessMsg) @@ -76,7 +78,8 @@ func TestNewUserPost_MustChangePasswordFalse(t *testing.T) { MustChangePassword: false, } - NewUserPost(ctx, form) + web.SetForm(ctx, &form) + NewUserPost(ctx) assert.NotEmpty(t, ctx.Flash.SuccessMsg) @@ -113,7 +116,8 @@ func TestNewUserPost_InvalidEmail(t *testing.T) { MustChangePassword: false, } - NewUserPost(ctx, form) + web.SetForm(ctx, &form) + NewUserPost(ctx) assert.NotEmpty(t, ctx.Flash.ErrorMsg) } diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go index 0fd9e17f4194c..1356276f07f4f 100644 --- a/routers/api/v1/admin/org.go +++ b/routers/api/v1/admin/org.go @@ -13,12 +13,13 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" ) // CreateOrg api for create organization -func CreateOrg(ctx *context.APIContext, form api.CreateOrgOption) { +func CreateOrg(ctx *context.APIContext) { // swagger:operation POST /admin/users/{username}/orgs admin adminCreateOrg // --- // summary: Create an organization @@ -43,7 +44,7 @@ func CreateOrg(ctx *context.APIContext, form api.CreateOrgOption) { // "$ref": "#/responses/forbidden" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.CreateOrgOption) u := user.GetUserByParams(ctx) if ctx.Written() { return diff --git a/routers/api/v1/admin/repo.go b/routers/api/v1/admin/repo.go index 73c7d740f888b..467f8a22ffac3 100644 --- a/routers/api/v1/admin/repo.go +++ b/routers/api/v1/admin/repo.go @@ -7,12 +7,13 @@ package admin import ( "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/repo" "code.gitea.io/gitea/routers/api/v1/user" ) // CreateRepo api for creating a repository -func CreateRepo(ctx *context.APIContext, form api.CreateRepoOption) { +func CreateRepo(ctx *context.APIContext) { // swagger:operation POST /admin/users/{username}/repos admin adminCreateRepo // --- // summary: Create a repository on behalf of a user @@ -41,11 +42,11 @@ func CreateRepo(ctx *context.APIContext, form api.CreateRepoOption) { // "$ref": "#/responses/error" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.CreateRepoOption) owner := user.GetUserByParams(ctx) if ctx.Written() { return } - repo.CreateUserRepo(ctx, owner, form) + repo.CreateUserRepo(ctx, owner, *form) } diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 670baf020b95b..f148710c79715 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/password" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/services/mailer" @@ -42,7 +43,7 @@ func parseLoginSource(ctx *context.APIContext, u *models.User, sourceID int64, l } // CreateUser create a user -func CreateUser(ctx *context.APIContext, form api.CreateUserOption) { +func CreateUser(ctx *context.APIContext) { // swagger:operation POST /admin/users admin adminCreateUser // --- // summary: Create a user @@ -64,7 +65,7 @@ func CreateUser(ctx *context.APIContext, form api.CreateUserOption) { // "$ref": "#/responses/forbidden" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.CreateUserOption) u := &models.User{ Name: form.Username, FullName: form.FullName, @@ -119,7 +120,7 @@ func CreateUser(ctx *context.APIContext, form api.CreateUserOption) { } // EditUser api for modifying a user's information -func EditUser(ctx *context.APIContext, form api.EditUserOption) { +func EditUser(ctx *context.APIContext) { // swagger:operation PATCH /admin/users/{username} admin adminEditUser // --- // summary: Edit an existing user @@ -144,7 +145,7 @@ func EditUser(ctx *context.APIContext, form api.EditUserOption) { // "$ref": "#/responses/forbidden" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.EditUserOption) u := user.GetUserByParams(ctx) if ctx.Written() { return @@ -283,7 +284,7 @@ func DeleteUser(ctx *context.APIContext) { } // CreatePublicKey api for creating a public key to a user -func CreatePublicKey(ctx *context.APIContext, form api.CreateKeyOption) { +func CreatePublicKey(ctx *context.APIContext) { // swagger:operation POST /admin/users/{username}/keys admin adminCreatePublicKey // --- // summary: Add a public key on behalf of a user @@ -308,12 +309,12 @@ func CreatePublicKey(ctx *context.APIContext, form api.CreateKeyOption) { // "$ref": "#/responses/forbidden" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.CreateKeyOption) u := user.GetUserByParams(ctx) if ctx.Written() { return } - user.CreateUserPublicKey(ctx, form, u.ID) + user.CreateUserPublicKey(ctx, *form, u.ID) } // DeleteUserPublicKey api for deleting a user's public key diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 876f48ca5cca3..593551d770be0 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -66,14 +66,16 @@ package v1 import ( "net/http" + "reflect" "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/admin" "code.gitea.io/gitea/routers/api/v1/misc" "code.gitea.io/gitea/routers/api/v1/notify" @@ -83,11 +85,12 @@ import ( _ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation "code.gitea.io/gitea/routers/api/v1/user" - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "gitea.com/go-chi/binding" + "gitea.com/go-chi/session" + "github.com/go-chi/cors" ) -func sudo() macaron.Handler { +func sudo() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { sudo := ctx.Query("sudo") if len(sudo) == 0 { @@ -117,10 +120,10 @@ func sudo() macaron.Handler { } } -func repoAssignment() macaron.Handler { +func repoAssignment() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { - userName := ctx.Params(":username") - repoName := ctx.Params(":reponame") + userName := ctx.Params("username") + repoName := ctx.Params("reponame") var ( owner *models.User @@ -184,7 +187,7 @@ func repoAssignment() macaron.Handler { } // Contexter middleware already checks token for user sign in process. -func reqToken() macaron.Handler { +func reqToken() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if true == ctx.Data["IsApiToken"] { return @@ -201,7 +204,7 @@ func reqToken() macaron.Handler { } } -func reqBasicAuth() macaron.Handler { +func reqBasicAuth() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Context.IsBasicAuth { ctx.Error(http.StatusUnauthorized, "reqBasicAuth", "basic auth required") @@ -212,7 +215,7 @@ func reqBasicAuth() macaron.Handler { } // reqSiteAdmin user should be the site admin -func reqSiteAdmin() macaron.Handler { +func reqSiteAdmin() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserSiteAdmin() { ctx.Error(http.StatusForbidden, "reqSiteAdmin", "user should be the site admin") @@ -222,7 +225,7 @@ func reqSiteAdmin() macaron.Handler { } // reqOwner user should be the owner of the repo or site admin. -func reqOwner() macaron.Handler { +func reqOwner() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserRepoOwner() && !ctx.IsUserSiteAdmin() { ctx.Error(http.StatusForbidden, "reqOwner", "user should be the owner of the repo") @@ -232,7 +235,7 @@ func reqOwner() macaron.Handler { } // reqAdmin user should be an owner or a collaborator with admin write of a repository, or site admin -func reqAdmin() macaron.Handler { +func reqAdmin() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserRepoAdmin() && !ctx.IsUserSiteAdmin() { ctx.Error(http.StatusForbidden, "reqAdmin", "user should be an owner or a collaborator with admin write of a repository") @@ -242,7 +245,7 @@ func reqAdmin() macaron.Handler { } // reqRepoWriter user should have a permission to write to a repo, or be a site admin -func reqRepoWriter(unitTypes ...models.UnitType) macaron.Handler { +func reqRepoWriter(unitTypes ...models.UnitType) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserRepoWriter(unitTypes) && !ctx.IsUserRepoAdmin() && !ctx.IsUserSiteAdmin() { ctx.Error(http.StatusForbidden, "reqRepoWriter", "user should have a permission to write to a repo") @@ -252,7 +255,7 @@ func reqRepoWriter(unitTypes ...models.UnitType) macaron.Handler { } // reqRepoReader user should have specific read permission or be a repo admin or a site admin -func reqRepoReader(unitType models.UnitType) macaron.Handler { +func reqRepoReader(unitType models.UnitType) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserRepoReaderSpecific(unitType) && !ctx.IsUserRepoAdmin() && !ctx.IsUserSiteAdmin() { ctx.Error(http.StatusForbidden, "reqRepoReader", "user should have specific read permission or be a repo admin or a site admin") @@ -262,7 +265,7 @@ func reqRepoReader(unitType models.UnitType) macaron.Handler { } // reqAnyRepoReader user should have any permission to read repository or permissions of site admin -func reqAnyRepoReader() macaron.Handler { +func reqAnyRepoReader() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserRepoReaderAny() && !ctx.IsUserSiteAdmin() { ctx.Error(http.StatusForbidden, "reqAnyRepoReader", "user should have any permission to read repository or permissions of site admin") @@ -272,7 +275,7 @@ func reqAnyRepoReader() macaron.Handler { } // reqOrgOwnership user should be an organization owner, or a site admin -func reqOrgOwnership() macaron.Handler { +func reqOrgOwnership() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if ctx.Context.IsUserSiteAdmin() { return @@ -304,7 +307,7 @@ func reqOrgOwnership() macaron.Handler { } // reqTeamMembership user should be an team member, or a site admin -func reqTeamMembership() macaron.Handler { +func reqTeamMembership() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if ctx.Context.IsUserSiteAdmin() { return @@ -341,7 +344,7 @@ func reqTeamMembership() macaron.Handler { } // reqOrgMembership user should be an organization member, or a site admin -func reqOrgMembership() macaron.Handler { +func reqOrgMembership() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if ctx.Context.IsUserSiteAdmin() { return @@ -371,7 +374,7 @@ func reqOrgMembership() macaron.Handler { } } -func reqGitHook() macaron.Handler { +func reqGitHook() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.User.CanEditGitHook() { ctx.Error(http.StatusForbidden, "", "must be allowed to edit Git hooks") @@ -380,7 +383,7 @@ func reqGitHook() macaron.Handler { } } -func orgAssignment(args ...bool) macaron.Handler { +func orgAssignment(args ...bool) func(ctx *context.APIContext) { var ( assignOrg bool assignTeam bool @@ -500,13 +503,6 @@ func mustEnableIssuesOrPulls(ctx *context.APIContext) { } } -func mustEnableUserHeatmap(ctx *context.APIContext) { - if !setting.Service.EnableUserHeatmap { - ctx.NotFound() - return - } -} - func mustNotBeArchived(ctx *context.APIContext) { if ctx.Repo.Repository.IsArchived { ctx.NotFound() @@ -514,18 +510,59 @@ func mustNotBeArchived(ctx *context.APIContext) { } } -// RegisterRoutes registers all v1 APIs routes to web application. -func RegisterRoutes(m *macaron.Macaron) { - bind := binding.Bind +// bind binding an obj to a func(ctx *context.APIContext) +func bind(obj interface{}) http.HandlerFunc { + var tp = reflect.TypeOf(obj) + for tp.Kind() == reflect.Ptr { + tp = tp.Elem() + } + return web.Wrap(func(ctx *context.APIContext) { + var theObj = reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly + errs := binding.Bind(ctx.Req, theObj) + if len(errs) > 0 { + ctx.Error(422, "validationError", errs[0].Error()) + return + } + web.SetForm(ctx, theObj) + }) +} - if setting.API.EnableSwagger { - m.Get("/swagger", misc.Swagger) // Render V1 by default +// Routes registers all v1 APIs routes to web application. +func Routes() *web.Route { + var m = web.NewRoute() + + m.Use(session.Sessioner(session.Options{ + Provider: setting.SessionConfig.Provider, + ProviderConfig: setting.SessionConfig.ProviderConfig, + CookieName: setting.SessionConfig.CookieName, + CookiePath: setting.SessionConfig.CookiePath, + Gclifetime: setting.SessionConfig.Gclifetime, + Maxlifetime: setting.SessionConfig.Maxlifetime, + Secure: setting.SessionConfig.Secure, + Domain: setting.SessionConfig.Domain, + })) + m.Use(securityHeaders()) + if setting.CORSConfig.Enabled { + m.Use(cors.Handler(cors.Options{ + //Scheme: setting.CORSConfig.Scheme, // FIXME: the cors middleware needs scheme option + AllowedOrigins: setting.CORSConfig.AllowDomain, + //setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option + AllowedMethods: setting.CORSConfig.Methods, + AllowCredentials: setting.CORSConfig.AllowCredentials, + MaxAge: int(setting.CORSConfig.MaxAge.Seconds()), + })) } + m.Use(context.APIContexter()) + m.Use(context.ToggleAPI(&context.ToggleOptions{ + SignInRequired: setting.Service.RequireSignInView, + })) - m.Group("/v1", func() { + m.Group("", func() { // Miscellaneous if setting.API.EnableSwagger { - m.Get("/swagger", misc.Swagger) + m.Get("/swagger", func(ctx *context.APIContext) { + ctx.Redirect("/api/swagger") + }) } m.Get("/version", misc.Version) m.Get("/signing-key.gpg", misc.SigningKey) @@ -544,7 +581,7 @@ func RegisterRoutes(m *macaron.Macaron) { Get(notify.ListNotifications). Put(notify.ReadNotifications) m.Get("/new", notify.NewAvailable) - m.Combo("/threads/:id"). + m.Combo("/threads/{id}"). Get(notify.GetThread). Patch(notify.ReadThread) }, reqToken()) @@ -553,28 +590,31 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/users", func() { m.Get("/search", user.Search) - m.Group("/:username", func() { + m.Group("/{username}", func() { m.Get("", user.GetInfo) - m.Get("/heatmap", mustEnableUserHeatmap, user.GetUserHeatmapData) + + if setting.Service.EnableUserHeatmap { + m.Get("/heatmap", user.GetUserHeatmapData) + } m.Get("/repos", user.ListUserRepos) m.Group("/tokens", func() { m.Combo("").Get(user.ListAccessTokens). Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken) - m.Combo("/:id").Delete(user.DeleteAccessToken) + m.Combo("/{id}").Delete(user.DeleteAccessToken) }, reqBasicAuth()) }) }) m.Group("/users", func() { - m.Group("/:username", func() { + m.Group("/{username}", func() { m.Get("/keys", user.ListPublicKeys) m.Get("/gpg_keys", user.ListGPGKeys) m.Get("/followers", user.ListFollowers) m.Group("/following", func() { m.Get("", user.ListFollowing) - m.Get("/:target", user.CheckFollowing) + m.Get("/{target}", user.CheckFollowing) }) m.Get("/starred", user.GetStarredRepos) @@ -592,20 +632,20 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/followers", user.ListMyFollowers) m.Group("/following", func() { m.Get("", user.ListMyFollowing) - m.Combo("/:username").Get(user.CheckMyFollowing).Put(user.Follow).Delete(user.Unfollow) + m.Combo("/{username}").Get(user.CheckMyFollowing).Put(user.Follow).Delete(user.Unfollow) }) m.Group("/keys", func() { m.Combo("").Get(user.ListMyPublicKeys). Post(bind(api.CreateKeyOption{}), user.CreatePublicKey) - m.Combo("/:id").Get(user.GetPublicKey). + m.Combo("/{id}").Get(user.GetPublicKey). Delete(user.DeletePublicKey) }) m.Group("/applications", func() { m.Combo("/oauth2"). Get(user.ListOauth2Applications). Post(bind(api.CreateOAuth2ApplicationOptions{}), user.CreateOauth2Application) - m.Combo("/oauth2/:id"). + m.Combo("/oauth2/{id}"). Delete(user.DeleteOauth2Application). Patch(bind(api.CreateOAuth2ApplicationOptions{}), user.UpdateOauth2Application). Get(user.GetOauth2Application) @@ -614,7 +654,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/gpg_keys", func() { m.Combo("").Get(user.ListMyGPGKeys). Post(bind(api.CreateGPGKeyOption{}), user.CreateGPGKey) - m.Combo("/:id").Get(user.GetGPGKey). + m.Combo("/{id}").Get(user.GetGPGKey). Delete(user.DeleteGPGKey) }) @@ -623,7 +663,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/starred", func() { m.Get("", user.GetMyStarredRepos) - m.Group("/:username/:reponame", func() { + m.Group("/{username}/{reponame}", func() { m.Get("", user.IsStarring) m.Put("", user.Star) m.Delete("", user.Unstar) @@ -639,9 +679,9 @@ func RegisterRoutes(m *macaron.Macaron) { }, reqToken()) // Repositories - m.Post("/org/:org/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated) + m.Post("/org/{org}/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated) - m.Combo("/repositories/:id", reqToken()).Get(repo.GetByID) + m.Combo("/repositories/{id}", reqToken()).Get(repo.GetByID) m.Group("/repos", func() { m.Get("/search", repo.Search) @@ -650,10 +690,10 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/migrate", reqToken(), bind(api.MigrateRepoOptions{}), repo.Migrate) - m.Group("/:username/:reponame", func() { + m.Group("/{username}/{reponame}", func() { m.Combo("").Get(reqAnyRepoReader(), repo.Get). Delete(reqToken(), reqOwner(), repo.Delete). - Patch(reqToken(), reqAdmin(), context.RepoRefForAPI(), bind(api.EditRepoOption{}), repo.Edit) + Patch(reqToken(), reqAdmin(), context.RepoRefForAPI, bind(api.EditRepoOption{}), repo.Edit) m.Post("/transfer", reqOwner(), bind(api.TransferRepoOption{}), repo.Transfer) m.Combo("/notifications"). Get(reqToken(), notify.ListRepoNotifications). @@ -661,15 +701,15 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/hooks", func() { m.Combo("").Get(repo.ListHooks). Post(bind(api.CreateHookOption{}), repo.CreateHook) - m.Group("/:id", func() { + m.Group("/{id}", func() { m.Combo("").Get(repo.GetHook). Patch(bind(api.EditHookOption{}), repo.EditHook). Delete(repo.DeleteHook) - m.Post("/tests", context.RepoRefForAPI(), repo.TestHook) + m.Post("/tests", context.RepoRefForAPI, repo.TestHook) }) m.Group("/git", func() { m.Combo("").Get(repo.ListGitHooks) - m.Group("/:id", func() { + m.Group("/{id}", func() { m.Combo("").Get(repo.GetGitHook). Patch(bind(api.EditGitHookOption{}), repo.EditGitHook). Delete(repo.DeleteGitHook) @@ -678,11 +718,11 @@ func RegisterRoutes(m *macaron.Macaron) { }, reqToken(), reqAdmin()) m.Group("/collaborators", func() { m.Get("", reqAnyRepoReader(), repo.ListCollaborators) - m.Combo("/:collaborator").Get(reqAnyRepoReader(), repo.IsCollaborator). + m.Combo("/{collaborator}").Get(reqAnyRepoReader(), repo.IsCollaborator). Put(reqAdmin(), bind(api.AddCollaboratorOption{}), repo.AddCollaborator). Delete(reqAdmin(), repo.DeleteCollaborator) }, reqToken()) - m.Get("/raw/*", context.RepoRefForAPI(), reqRepoReader(models.UnitTypeCode), repo.GetRawFile) + m.Get("/raw/*", context.RepoRefForAPI, reqRepoReader(models.UnitTypeCode), repo.GetRawFile) m.Get("/archive/*", reqRepoReader(models.UnitTypeCode), repo.GetArchive) m.Combo("/forks").Get(repo.ListForks). Post(reqToken(), reqRepoReader(models.UnitTypeCode), bind(api.CreateForkOption{}), repo.CreateFork) @@ -695,7 +735,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/branch_protections", func() { m.Get("", repo.ListBranchProtections) m.Post("", bind(api.CreateBranchProtectionOption{}), repo.CreateBranchProtection) - m.Group("/:name", func() { + m.Group("/{name}", func() { m.Get("", repo.GetBranchProtection) m.Patch("", bind(api.EditBranchProtectionOption{}), repo.EditBranchProtection) m.Delete("", repo.DeleteBranchProtection) @@ -707,19 +747,19 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/keys", func() { m.Combo("").Get(repo.ListDeployKeys). Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey) - m.Combo("/:id").Get(repo.GetDeployKey). + m.Combo("/{id}").Get(repo.GetDeployKey). Delete(repo.DeleteDeploykey) }, reqToken(), reqAdmin()) m.Group("/times", func() { m.Combo("").Get(repo.ListTrackedTimesByRepository) - m.Combo("/:timetrackingusername").Get(repo.ListTrackedTimesByUser) + m.Combo("/{timetrackingusername}").Get(repo.ListTrackedTimesByUser) }, mustEnableIssues, reqToken()) m.Group("/issues", func() { m.Combo("").Get(repo.ListIssues). Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue) m.Group("/comments", func() { m.Get("", repo.ListRepoIssueComments) - m.Group("/:id", func() { + m.Group("/{id}", func() { m.Combo(""). Get(repo.GetIssueComment). Patch(mustNotBeArchived, reqToken(), bind(api.EditIssueCommentOption{}), repo.EditIssueComment). @@ -730,13 +770,13 @@ func RegisterRoutes(m *macaron.Macaron) { Delete(reqToken(), bind(api.EditReactionOption{}), repo.DeleteIssueCommentReaction) }) }) - m.Group("/:index", func() { + m.Group("/{index}", func() { m.Combo("").Get(repo.GetIssue). Patch(reqToken(), bind(api.EditIssueOption{}), repo.EditIssue) m.Group("/comments", func() { m.Combo("").Get(repo.ListIssueComments). Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment) - m.Combo("/:id", reqToken()).Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueCommentDeprecated). + m.Combo("/{id}", reqToken()).Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueCommentDeprecated). Delete(repo.DeleteIssueCommentDeprecated) }) m.Group("/labels", func() { @@ -744,14 +784,14 @@ func RegisterRoutes(m *macaron.Macaron) { Post(reqToken(), bind(api.IssueLabelsOption{}), repo.AddIssueLabels). Put(reqToken(), bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels). Delete(reqToken(), repo.ClearIssueLabels) - m.Delete("/:id", reqToken(), repo.DeleteIssueLabel) + m.Delete("/{id}", reqToken(), repo.DeleteIssueLabel) }) m.Group("/times", func() { m.Combo(""). Get(repo.ListTrackedTimes). Post(bind(api.AddTimeOption{}), repo.AddTime). Delete(repo.ResetIssueTime) - m.Delete("/:id", repo.DeleteTime) + m.Delete("/{id}", repo.DeleteTime) }, reqToken()) m.Combo("/deadline").Post(reqToken(), bind(api.EditDeadlineOption{}), repo.UpdateIssueDeadline) m.Group("/stopwatch", func() { @@ -762,8 +802,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/subscriptions", func() { m.Get("", repo.GetIssueSubscribers) m.Get("/check", reqToken(), repo.CheckIssueSubscription) - m.Put("/:user", reqToken(), repo.AddIssueSubscription) - m.Delete("/:user", reqToken(), repo.DelIssueSubscription) + m.Put("/{user}", reqToken(), repo.AddIssueSubscription) + m.Delete("/{user}", reqToken(), repo.DelIssueSubscription) }) m.Combo("/reactions"). Get(repo.GetIssueReactions). @@ -774,7 +814,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/labels", func() { m.Combo("").Get(repo.ListLabels). Post(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.CreateLabelOption{}), repo.CreateLabel) - m.Combo("/:id").Get(repo.GetLabel). + m.Combo("/{id}").Get(repo.GetLabel). Patch(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.EditLabelOption{}), repo.EditLabel). Delete(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), repo.DeleteLabel) }) @@ -783,7 +823,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/milestones", func() { m.Combo("").Get(repo.ListMilestones). Post(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.CreateMilestoneOption{}), repo.CreateMilestone) - m.Combo("/:id").Get(repo.GetMilestone). + m.Combo("/{id}").Get(repo.GetMilestone). Patch(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.EditMilestoneOption{}), repo.EditMilestone). Delete(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), repo.DeleteMilestone) }) @@ -797,30 +837,30 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/releases", func() { m.Combo("").Get(repo.ListReleases). Post(reqToken(), reqRepoWriter(models.UnitTypeReleases), context.ReferencesGitRepo(false), bind(api.CreateReleaseOption{}), repo.CreateRelease) - m.Group("/:id", func() { + m.Group("/{id}", func() { m.Combo("").Get(repo.GetRelease). Patch(reqToken(), reqRepoWriter(models.UnitTypeReleases), context.ReferencesGitRepo(false), bind(api.EditReleaseOption{}), repo.EditRelease). Delete(reqToken(), reqRepoWriter(models.UnitTypeReleases), repo.DeleteRelease) m.Group("/assets", func() { m.Combo("").Get(repo.ListReleaseAttachments). Post(reqToken(), reqRepoWriter(models.UnitTypeReleases), repo.CreateReleaseAttachment) - m.Combo("/:asset").Get(repo.GetReleaseAttachment). + m.Combo("/{asset}").Get(repo.GetReleaseAttachment). Patch(reqToken(), reqRepoWriter(models.UnitTypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment). Delete(reqToken(), reqRepoWriter(models.UnitTypeReleases), repo.DeleteReleaseAttachment) }) }) m.Group("/tags", func() { - m.Combo("/:tag"). + m.Combo("/{tag}"). Get(repo.GetReleaseTag). Delete(reqToken(), reqRepoWriter(models.UnitTypeReleases), repo.DeleteReleaseTag) }) }, reqRepoReader(models.UnitTypeReleases)) m.Post("/mirror-sync", reqToken(), reqRepoWriter(models.UnitTypeCode), repo.MirrorSync) - m.Get("/editorconfig/:filename", context.RepoRefForAPI(), reqRepoReader(models.UnitTypeCode), repo.GetEditorconfig) + m.Get("/editorconfig/{filename}", context.RepoRefForAPI, reqRepoReader(models.UnitTypeCode), repo.GetEditorconfig) m.Group("/pulls", func() { - m.Combo("").Get(bind(api.ListPullRequestsOptions{}), repo.ListPullRequests). + m.Combo("").Get(repo.ListPullRequests). Post(reqToken(), mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) - m.Group("/:index", func() { + m.Group("/{index}", func() { m.Combo("").Get(repo.GetPullRequest). Patch(reqToken(), reqRepoWriter(models.UnitTypePullRequests), bind(api.EditPullRequestOption{}), repo.EditPullRequest) m.Get(".diff", repo.DownloadPullDiff) @@ -832,7 +872,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Combo(""). Get(repo.ListPullReviews). Post(reqToken(), bind(api.CreatePullReviewOptions{}), repo.CreatePullReview) - m.Group("/:id", func() { + m.Group("/{id}", func() { m.Combo(""). Get(repo.GetPullReview). Delete(reqToken(), repo.DeletePullReview). @@ -847,25 +887,25 @@ func RegisterRoutes(m *macaron.Macaron) { }) }, mustAllowPulls, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(false)) m.Group("/statuses", func() { - m.Combo("/:sha").Get(repo.GetCommitStatuses). + m.Combo("/{sha}").Get(repo.GetCommitStatuses). Post(reqToken(), bind(api.CreateStatusOption{}), repo.NewCommitStatus) }, reqRepoReader(models.UnitTypeCode)) m.Group("/commits", func() { m.Get("", repo.GetAllCommits) - m.Group("/:ref", func() { + m.Group("/{ref}", func() { m.Get("/status", repo.GetCombinedCommitStatusByRef) m.Get("/statuses", repo.GetCommitStatusesByRef) }) }, reqRepoReader(models.UnitTypeCode)) m.Group("/git", func() { m.Group("/commits", func() { - m.Get("/:sha", repo.GetSingleCommit) + m.Get("/{sha}", repo.GetSingleCommit) }) m.Get("/refs", repo.GetGitAllRefs) m.Get("/refs/*", repo.GetGitRefs) - m.Get("/trees/:sha", context.RepoRefForAPI(), repo.GetTree) - m.Get("/blobs/:sha", context.RepoRefForAPI(), repo.GetBlob) - m.Get("/tags/:sha", context.RepoRefForAPI(), repo.GetTag) + m.Get("/trees/{sha}", context.RepoRefForAPI, repo.GetTree) + m.Get("/blobs/{sha}", context.RepoRefForAPI, repo.GetBlob) + m.Get("/tags/{sha}", context.RepoRefForAPI, repo.GetTag) }, reqRepoReader(models.UnitTypeCode)) m.Group("/contents", func() { m.Get("", repo.GetContentsList) @@ -880,7 +920,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/topics", func() { m.Combo("").Get(repo.ListTopics). Put(reqToken(), reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics) - m.Group("/:topic", func() { + m.Group("/{topic}", func() { m.Combo("").Put(reqToken(), repo.AddTopic). Delete(reqToken(), repo.DeleteTopic) }, reqAdmin()) @@ -892,10 +932,10 @@ func RegisterRoutes(m *macaron.Macaron) { // Organizations m.Get("/user/orgs", reqToken(), org.ListMyOrgs) - m.Get("/users/:username/orgs", org.ListUserOrgs) + m.Get("/users/{username}/orgs", org.ListUserOrgs) m.Post("/orgs", reqToken(), bind(api.CreateOrgOption{}), org.Create) m.Get("/orgs", org.GetAll) - m.Group("/orgs/:org", func() { + m.Group("/orgs/{org}", func() { m.Combo("").Get(org.Get). Patch(reqToken(), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). Delete(reqToken(), reqOrgOwnership(), org.Delete) @@ -903,12 +943,12 @@ func RegisterRoutes(m *macaron.Macaron) { Post(reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) m.Group("/members", func() { m.Get("", org.ListMembers) - m.Combo("/:username").Get(org.IsMember). + m.Combo("/{username}").Get(org.IsMember). Delete(reqToken(), reqOrgOwnership(), org.DeleteMember) }) m.Group("/public_members", func() { m.Get("", org.ListPublicMembers) - m.Combo("/:username").Get(org.IsPublicMember). + m.Combo("/{username}").Get(org.IsPublicMember). Put(reqToken(), reqOrgMembership(), org.PublicizeMember). Delete(reqToken(), reqOrgMembership(), org.ConcealMember) }) @@ -920,56 +960,52 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/labels", func() { m.Get("", org.ListLabels) m.Post("", reqToken(), reqOrgOwnership(), bind(api.CreateLabelOption{}), org.CreateLabel) - m.Combo("/:id").Get(org.GetLabel). + m.Combo("/{id}").Get(org.GetLabel). Patch(reqToken(), reqOrgOwnership(), bind(api.EditLabelOption{}), org.EditLabel). Delete(reqToken(), reqOrgOwnership(), org.DeleteLabel) }) m.Group("/hooks", func() { m.Combo("").Get(org.ListHooks). Post(bind(api.CreateHookOption{}), org.CreateHook) - m.Combo("/:id").Get(org.GetHook). + m.Combo("/{id}").Get(org.GetHook). Patch(bind(api.EditHookOption{}), org.EditHook). Delete(org.DeleteHook) }, reqToken(), reqOrgOwnership()) }, orgAssignment(true)) - m.Group("/teams/:teamid", func() { + m.Group("/teams/{teamid}", func() { m.Combo("").Get(org.GetTeam). Patch(reqOrgOwnership(), bind(api.EditTeamOption{}), org.EditTeam). Delete(reqOrgOwnership(), org.DeleteTeam) m.Group("/members", func() { m.Get("", org.GetTeamMembers) - m.Combo("/:username"). + m.Combo("/{username}"). Get(org.GetTeamMember). Put(reqOrgOwnership(), org.AddTeamMember). Delete(reqOrgOwnership(), org.RemoveTeamMember) }) m.Group("/repos", func() { m.Get("", org.GetTeamRepos) - m.Combo("/:org/:reponame"). + m.Combo("/{org}/{reponame}"). Put(org.AddTeamRepository). Delete(org.RemoveTeamRepository) }) }, orgAssignment(false, true), reqToken(), reqTeamMembership()) - m.Any("/*", func(ctx *context.APIContext) { - ctx.NotFound() - }) - m.Group("/admin", func() { m.Group("/cron", func() { m.Get("", admin.ListCronTasks) - m.Post("/:task", admin.PostCronTask) + m.Post("/{task}", admin.PostCronTask) }) m.Get("/orgs", admin.GetAllOrgs) m.Group("/users", func() { m.Get("", admin.GetAllUsers) m.Post("", bind(api.CreateUserOption{}), admin.CreateUser) - m.Group("/:username", func() { + m.Group("/{username}", func() { m.Combo("").Patch(bind(api.EditUserOption{}), admin.EditUser). Delete(admin.DeleteUser) m.Group("/keys", func() { m.Post("", bind(api.CreateKeyOption{}), admin.CreatePublicKey) - m.Delete("/:id", admin.DeleteUserPublicKey) + m.Delete("/{id}", admin.DeleteUserPublicKey) }) m.Get("/orgs", org.ListUserOrgs) m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg) @@ -978,23 +1014,26 @@ func RegisterRoutes(m *macaron.Macaron) { }) m.Group("/unadopted", func() { m.Get("", admin.ListUnadoptedRepositories) - m.Post("/:username/:reponame", admin.AdoptRepository) - m.Delete("/:username/:reponame", admin.DeleteUnadoptedRepository) + m.Post("/{username}/{reponame}", admin.AdoptRepository) + m.Delete("/{username}/{reponame}", admin.DeleteUnadoptedRepository) }) }, reqToken(), reqSiteAdmin()) m.Group("/topics", func() { m.Get("/search", repo.TopicSearch) }) - }, securityHeaders(), context.APIContexter(), sudo()) + }, sudo()) + + return m } -func securityHeaders() macaron.Handler { - return func(ctx *macaron.Context) { - ctx.Resp.Before(func(w macaron.ResponseWriter) { +func securityHeaders() func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { // CORB: https://www.chromium.org/Home/chromium-security/corb-for-developers // http://stackoverflow.com/a/3146618/244009 - w.Header().Set("x-content-type-options", "nosniff") + resp.Header().Set("x-content-type-options", "nosniff") + next.ServeHTTP(resp, req) }) } } diff --git a/routers/api/v1/misc/markdown.go b/routers/api/v1/misc/markdown.go index a10c288df482f..571818530981f 100644 --- a/routers/api/v1/misc/markdown.go +++ b/routers/api/v1/misc/markdown.go @@ -5,6 +5,7 @@ package misc import ( + "io/ioutil" "net/http" "strings" @@ -13,12 +14,13 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "mvdan.cc/xurls/v2" ) // Markdown render markdown document to HTML -func Markdown(ctx *context.APIContext, form api.MarkdownOption) { +func Markdown(ctx *context.APIContext) { // swagger:operation POST /markdown miscellaneous renderMarkdown // --- // summary: Render a markdown document as HTML @@ -37,6 +39,8 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) { // "422": // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.MarkdownOption) + if ctx.HasAPIError() { ctx.Error(http.StatusUnprocessableEntity, "", ctx.GetErrMsg()) return @@ -117,7 +121,7 @@ func MarkdownRaw(ctx *context.APIContext) { // "422": // "$ref": "#/responses/validationError" - body, err := ctx.Req.Body().Bytes() + body, err := ioutil.ReadAll(ctx.Req.Body) if err != nil { ctx.Error(http.StatusUnprocessableEntity, "", err) return diff --git a/routers/api/v1/misc/markdown_test.go b/routers/api/v1/misc/markdown_test.go index 6c81ec8eb4357..3ae3165fd3734 100644 --- a/routers/api/v1/misc/markdown_test.go +++ b/routers/api/v1/misc/markdown_test.go @@ -15,10 +15,10 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" - "gitea.com/macaron/inject" - "gitea.com/macaron/macaron" "github.com/stretchr/testify/assert" ) @@ -26,25 +26,21 @@ const AppURL = "http://localhost:3000/" const Repo = "gogits/gogs" const AppSubURL = AppURL + Repo + "/" -func createContext(req *http.Request) (*macaron.Context, *httptest.ResponseRecorder) { +func createContext(req *http.Request) (*context.Context, *httptest.ResponseRecorder) { + var rnd = templates.HTMLRenderer() resp := httptest.NewRecorder() - c := &macaron.Context{ - Injector: inject.New(), - Req: macaron.Request{Request: req}, - Resp: macaron.NewResponseWriter(req.Method, resp), - Render: &macaron.DummyRender{ResponseWriter: resp}, - Data: make(map[string]interface{}), + c := &context.Context{ + Req: req, + Resp: context.NewResponse(resp), + Render: rnd, + Data: make(map[string]interface{}), } - c.Map(c) - c.Map(req) return c, resp } -func wrap(ctx *macaron.Context) *context.APIContext { +func wrap(ctx *context.Context) *context.APIContext { return &context.APIContext{ - Context: &context.Context{ - Context: ctx, - }, + Context: ctx, } } @@ -115,7 +111,8 @@ Here are some links to the most important topics. You can find the full list of for i := 0; i < len(testCases); i += 2 { options.Text = testCases[i] - Markdown(ctx, options) + web.SetForm(ctx, &options) + Markdown(ctx) assert.Equal(t, testCases[i+1], resp.Body.String()) resp.Body.Reset() } @@ -156,7 +153,8 @@ func TestAPI_RenderSimple(t *testing.T) { for i := 0; i < len(simpleCases); i += 2 { options.Text = simpleCases[i] - Markdown(ctx, options) + web.SetForm(ctx, &options) + Markdown(ctx) assert.Equal(t, simpleCases[i+1], resp.Body.String()) resp.Body.Reset() } @@ -174,7 +172,7 @@ func TestAPI_RenderRaw(t *testing.T) { ctx := wrap(m) for i := 0; i < len(simpleCases); i += 2 { - ctx.Req.Request.Body = ioutil.NopCloser(strings.NewReader(simpleCases[i])) + ctx.Req.Body = ioutil.NopCloser(strings.NewReader(simpleCases[i])) MarkdownRaw(ctx) assert.Equal(t, simpleCases[i+1], resp.Body.String()) resp.Body.Reset() diff --git a/routers/api/v1/org/hook.go b/routers/api/v1/org/hook.go index cce959bb49153..ed827c48d43f6 100644 --- a/routers/api/v1/org/hook.go +++ b/routers/api/v1/org/hook.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -85,7 +86,7 @@ func GetHook(ctx *context.APIContext) { } // CreateHook create a hook for an organization -func CreateHook(ctx *context.APIContext, form api.CreateHookOption) { +func CreateHook(ctx *context.APIContext) { // swagger:operation POST /orgs/{org}/hooks/ organization orgCreateHook // --- // summary: Create a hook @@ -108,15 +109,16 @@ func CreateHook(ctx *context.APIContext, form api.CreateHookOption) { // "201": // "$ref": "#/responses/Hook" + form := web.GetForm(ctx).(*api.CreateHookOption) //TODO in body params - if !utils.CheckCreateHookOption(ctx, &form) { + if !utils.CheckCreateHookOption(ctx, form) { return } - utils.AddOrgHook(ctx, &form) + utils.AddOrgHook(ctx, form) } // EditHook modify a hook of a repository -func EditHook(ctx *context.APIContext, form api.EditHookOption) { +func EditHook(ctx *context.APIContext) { // swagger:operation PATCH /orgs/{org}/hooks/{id} organization orgEditHook // --- // summary: Update a hook @@ -144,9 +146,11 @@ func EditHook(ctx *context.APIContext, form api.EditHookOption) { // "200": // "$ref": "#/responses/Hook" + form := web.GetForm(ctx).(*api.EditHookOption) + //TODO in body params hookID := ctx.ParamsInt64(":id") - utils.EditOrgHook(ctx, &form, hookID) + utils.EditOrgHook(ctx, form, hookID) } // DeleteHook delete a hook of an organization diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index 9a8a4fa291542..76061f163aac3 100644 --- a/routers/api/v1/org/label.go +++ b/routers/api/v1/org/label.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -52,7 +53,7 @@ func ListLabels(ctx *context.APIContext) { } // CreateLabel create a label for a repository -func CreateLabel(ctx *context.APIContext, form api.CreateLabelOption) { +func CreateLabel(ctx *context.APIContext) { // swagger:operation POST /orgs/{org}/labels organization orgCreateLabel // --- // summary: Create a label for an organization @@ -75,7 +76,7 @@ func CreateLabel(ctx *context.APIContext, form api.CreateLabelOption) { // "$ref": "#/responses/Label" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.CreateLabelOption) form.Color = strings.Trim(form.Color, " ") if len(form.Color) == 6 { form.Color = "#" + form.Color @@ -144,7 +145,7 @@ func GetLabel(ctx *context.APIContext) { } // EditLabel modify a label for an Organization -func EditLabel(ctx *context.APIContext, form api.EditLabelOption) { +func EditLabel(ctx *context.APIContext) { // swagger:operation PATCH /orgs/{org}/labels/{id} organization orgEditLabel // --- // summary: Update a label @@ -173,7 +174,7 @@ func EditLabel(ctx *context.APIContext, form api.EditLabelOption) { // "$ref": "#/responses/Label" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.EditLabelOption) label, err := models.GetLabelInOrgByID(ctx.Org.Organization.ID, ctx.ParamsInt64(":id")) if err != nil { if models.IsErrOrgLabelNotExist(err) { diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index ca3e10173bffd..61e09e1126a04 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -149,7 +150,7 @@ func GetAll(ctx *context.APIContext) { } // Create api for create organization -func Create(ctx *context.APIContext, form api.CreateOrgOption) { +func Create(ctx *context.APIContext) { // swagger:operation POST /orgs organization orgCreate // --- // summary: Create an organization @@ -169,7 +170,7 @@ func Create(ctx *context.APIContext, form api.CreateOrgOption) { // "$ref": "#/responses/forbidden" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.CreateOrgOption) if !ctx.User.CanCreateOrganization() { ctx.Error(http.StatusForbidden, "Create organization not allowed", nil) return @@ -231,7 +232,7 @@ func Get(ctx *context.APIContext) { } // Edit change an organization's information -func Edit(ctx *context.APIContext, form api.EditOrgOption) { +func Edit(ctx *context.APIContext) { // swagger:operation PATCH /orgs/{org} organization orgEdit // --- // summary: Edit an organization @@ -253,7 +254,7 @@ func Edit(ctx *context.APIContext, form api.EditOrgOption) { // responses: // "200": // "$ref": "#/responses/Organization" - + form := web.GetForm(ctx).(*api.EditOrgOption) org := ctx.Org.Organization org.FullName = form.FullName org.Description = form.Description diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index 72387dcbf74a2..c749751ac4dbf 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -131,7 +132,7 @@ func GetTeam(ctx *context.APIContext) { } // CreateTeam api for create a team -func CreateTeam(ctx *context.APIContext, form api.CreateTeamOption) { +func CreateTeam(ctx *context.APIContext) { // swagger:operation POST /orgs/{org}/teams organization orgCreateTeam // --- // summary: Create a team @@ -154,7 +155,7 @@ func CreateTeam(ctx *context.APIContext, form api.CreateTeamOption) { // "$ref": "#/responses/Team" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.CreateTeamOption) team := &models.Team{ OrgID: ctx.Org.Organization.ID, Name: form.Name, @@ -190,7 +191,7 @@ func CreateTeam(ctx *context.APIContext, form api.CreateTeamOption) { } // EditTeam api for edit a team -func EditTeam(ctx *context.APIContext, form api.EditTeamOption) { +func EditTeam(ctx *context.APIContext) { // swagger:operation PATCH /teams/{id} organization orgEditTeam // --- // summary: Edit a team @@ -212,6 +213,8 @@ func EditTeam(ctx *context.APIContext, form api.EditTeamOption) { // "200": // "$ref": "#/responses/Team" + form := web.GetForm(ctx).(*api.EditTeamOption) + team := ctx.Org.Team if err := team.GetUnits(); err != nil { ctx.InternalServerError(err) diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 9a0a552bad2a3..790464c8bc55a 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" pull_service "code.gitea.io/gitea/services/pull" repo_service "code.gitea.io/gitea/services/repository" ) @@ -175,7 +176,7 @@ func DeleteBranch(ctx *context.APIContext) { } // CreateBranch creates a branch for a user's repository -func CreateBranch(ctx *context.APIContext, opt api.CreateBranchRepoOption) { +func CreateBranch(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/branches repository repoCreateBranch // --- // summary: Create a branch @@ -206,6 +207,7 @@ func CreateBranch(ctx *context.APIContext, opt api.CreateBranchRepoOption) { // "409": // description: The branch with the same name already exists. + opt := web.GetForm(ctx).(*api.CreateBranchRepoOption) if ctx.Repo.Repository.IsEmpty { ctx.Error(http.StatusNotFound, "", "Git Repository is empty.") return @@ -395,7 +397,7 @@ func ListBranchProtections(ctx *context.APIContext) { } // CreateBranchProtection creates a branch protection for a repo -func CreateBranchProtection(ctx *context.APIContext, form api.CreateBranchProtectionOption) { +func CreateBranchProtection(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/branch_protections repository repoCreateBranchProtection // --- // summary: Create a branch protections for a repository @@ -428,6 +430,7 @@ func CreateBranchProtection(ctx *context.APIContext, form api.CreateBranchProtec // "422": // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.CreateBranchProtectionOption) repo := ctx.Repo.Repository // Currently protection must match an actual branch @@ -561,7 +564,7 @@ func CreateBranchProtection(ctx *context.APIContext, form api.CreateBranchProtec } // EditBranchProtection edits a branch protection for a repo -func EditBranchProtection(ctx *context.APIContext, form api.EditBranchProtectionOption) { +func EditBranchProtection(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/branch_protections/{name} repository repoEditBranchProtection // --- // summary: Edit a branch protections for a repository. Only fields that are set will be changed @@ -596,7 +599,7 @@ func EditBranchProtection(ctx *context.APIContext, form api.EditBranchProtection // "$ref": "#/responses/notFound" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.EditBranchProtectionOption) repo := ctx.Repo.Repository bpName := ctx.Params(":name") protectBranch, err := models.GetProtectedBranchBy(repo.ID, bpName) diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index 497255a4742fb..a4fc1d8f114a2 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -111,7 +112,7 @@ func IsCollaborator(ctx *context.APIContext) { } // AddCollaborator add a collaborator to a repository -func AddCollaborator(ctx *context.APIContext, form api.AddCollaboratorOption) { +func AddCollaborator(ctx *context.APIContext) { // swagger:operation PUT /repos/{owner}/{repo}/collaborators/{collaborator} repository repoAddCollaborator // --- // summary: Add a collaborator to a repository @@ -143,6 +144,8 @@ func AddCollaborator(ctx *context.APIContext, form api.AddCollaboratorOption) { // "422": // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.AddCollaboratorOption) + collaborator, err := models.GetUserByName(ctx.Params(":collaborator")) if err != nil { if models.IsErrUserNotExist(err) { diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 8c877285a8448..a16cca0f4e147 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -69,7 +69,11 @@ func getCommit(ctx *context.APIContext, identifier string) { defer gitRepo.Close() commit, err := gitRepo.GetCommit(identifier) if err != nil { - ctx.NotFoundOrServerError("GetCommit", git.IsErrNotExist, err) + if git.IsErrNotExist(err) { + ctx.NotFound(identifier) + return + } + ctx.Error(http.StatusInternalServerError, "gitRepo.GetCommit", err) return } diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index bc85fec630208..044d0fe565556 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/repofiles" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/repo" ) @@ -167,7 +168,7 @@ func canReadFiles(r *context.Repository) bool { } // CreateFile handles API call for creating a file -func CreateFile(ctx *context.APIContext, apiOpts api.CreateFileOptions) { +func CreateFile(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/contents/{filepath} repository repoCreateFile // --- // summary: Create a file in a repository @@ -206,6 +207,7 @@ func CreateFile(ctx *context.APIContext, apiOpts api.CreateFileOptions) { // "422": // "$ref": "#/responses/error" + apiOpts := web.GetForm(ctx).(*api.CreateFileOptions) if ctx.Repo.Repository.IsEmpty { ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty")) } @@ -253,7 +255,7 @@ func CreateFile(ctx *context.APIContext, apiOpts api.CreateFileOptions) { } // UpdateFile handles API call for updating a file -func UpdateFile(ctx *context.APIContext, apiOpts api.UpdateFileOptions) { +func UpdateFile(ctx *context.APIContext) { // swagger:operation PUT /repos/{owner}/{repo}/contents/{filepath} repository repoUpdateFile // --- // summary: Update a file in a repository @@ -291,7 +293,7 @@ func UpdateFile(ctx *context.APIContext, apiOpts api.UpdateFileOptions) { // "$ref": "#/responses/notFound" // "422": // "$ref": "#/responses/error" - + apiOpts := web.GetForm(ctx).(*api.UpdateFileOptions) if ctx.Repo.Repository.IsEmpty { ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty")) } @@ -377,7 +379,7 @@ func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileO } // DeleteFile Delete a fle in a repository -func DeleteFile(ctx *context.APIContext, apiOpts api.DeleteFileOptions) { +func DeleteFile(ctx *context.APIContext) { // swagger:operation DELETE /repos/{owner}/{repo}/contents/{filepath} repository repoDeleteFile // --- // summary: Delete a file in a repository @@ -416,6 +418,7 @@ func DeleteFile(ctx *context.APIContext, apiOpts api.DeleteFileOptions) { // "404": // "$ref": "#/responses/error" + apiOpts := web.GetForm(ctx).(*api.DeleteFileOptions) if !canWriteFiles(ctx.Repo) { ctx.Error(http.StatusForbidden, "DeleteFile", models.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.User.ID, diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 24700f7a7f51e..55fcefaccc382 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" repo_service "code.gitea.io/gitea/services/repository" ) @@ -65,7 +66,7 @@ func ListForks(ctx *context.APIContext) { } // CreateFork create a fork of a repo -func CreateFork(ctx *context.APIContext, form api.CreateForkOption) { +func CreateFork(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/forks repository createFork // --- // summary: Fork a repository @@ -94,6 +95,7 @@ func CreateFork(ctx *context.APIContext, form api.CreateForkOption) { // "422": // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.CreateForkOption) repo := ctx.Repo.Repository var forker *models.User // user/org that will own the fork if form.Organization == nil { diff --git a/routers/api/v1/repo/git_hook.go b/routers/api/v1/repo/git_hook.go index 0c538ac6b3196..0b4e09cadd2a5 100644 --- a/routers/api/v1/repo/git_hook.go +++ b/routers/api/v1/repo/git_hook.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" ) // ListGitHooks list all Git hooks of a repository @@ -91,7 +92,7 @@ func GetGitHook(ctx *context.APIContext) { } // EditGitHook modify a Git hook of a repository -func EditGitHook(ctx *context.APIContext, form api.EditGitHookOption) { +func EditGitHook(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/hooks/git/{id} repository repoEditGitHook // --- // summary: Edit a Git hook in a repository @@ -123,6 +124,7 @@ func EditGitHook(ctx *context.APIContext, form api.EditGitHookOption) { // "404": // "$ref": "#/responses/notFound" + form := web.GetForm(ctx).(*api.EditGitHookOption) hookID := ctx.Params(":id") hook, err := ctx.Repo.GitRepo.GetHook(hookID) if err != nil { diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go index 575b1fc480ca3..520a7a02027b1 100644 --- a/routers/api/v1/repo/hook.go +++ b/routers/api/v1/repo/hook.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/services/webhook" ) @@ -158,7 +159,7 @@ func TestHook(ctx *context.APIContext) { } // CreateHook create a hook for a repository -func CreateHook(ctx *context.APIContext, form api.CreateHookOption) { +func CreateHook(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/hooks repository repoCreateHook // --- // summary: Create a hook @@ -184,14 +185,16 @@ func CreateHook(ctx *context.APIContext, form api.CreateHookOption) { // responses: // "201": // "$ref": "#/responses/Hook" - if !utils.CheckCreateHookOption(ctx, &form) { + form := web.GetForm(ctx).(*api.CreateHookOption) + + if !utils.CheckCreateHookOption(ctx, form) { return } - utils.AddRepoHook(ctx, &form) + utils.AddRepoHook(ctx, form) } // EditHook modify a hook of a repository -func EditHook(ctx *context.APIContext, form api.EditHookOption) { +func EditHook(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/hooks/{id} repository repoEditHook // --- // summary: Edit a hook in a repository @@ -221,8 +224,9 @@ func EditHook(ctx *context.APIContext, form api.EditHookOption) { // responses: // "200": // "$ref": "#/responses/Hook" + form := web.GetForm(ctx).(*api.EditHookOption) hookID := ctx.ParamsInt64(":id") - utils.EditRepoHook(ctx, &form, hookID) + utils.EditRepoHook(ctx, form, hookID) } // DeleteHook delete a hook of a repository diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index bab8f373ce271..17dad97945330 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -22,6 +22,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" issue_service "code.gitea.io/gitea/services/issue" ) @@ -448,7 +449,7 @@ func GetIssue(ctx *context.APIContext) { } // CreateIssue create an issue of a repository -func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { +func CreateIssue(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/issues issue issueCreateIssue // --- // summary: Create an issue. If using deadline only the date will be taken into account, and time of day ignored. @@ -480,7 +481,7 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { // "$ref": "#/responses/error" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.CreateIssueOption) var deadlineUnix timeutil.TimeStamp if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) { deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) @@ -564,7 +565,7 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { } // EditIssue modify an issue of a repository -func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { +func EditIssue(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/issues/{index} issue issueEditIssue // --- // summary: Edit an issue. If using deadline only the date will be taken into account, and time of day ignored. @@ -603,6 +604,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { // "412": // "$ref": "#/responses/error" + form := web.GetForm(ctx).(*api.EditIssueOption) issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { @@ -723,7 +725,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { } // UpdateIssueDeadline updates an issue deadline -func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) { +func UpdateIssueDeadline(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/issues/{index}/deadline issue issueEditIssueDeadline // --- // summary: Set an issue deadline. If set to null, the deadline is deleted. If using deadline only the date will be taken into account, and time of day ignored. @@ -759,7 +761,7 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) { // "$ref": "#/responses/forbidden" // "404": // "$ref": "#/responses/notFound" - + form := web.GetForm(ctx).(*api.EditDeadlineOption) issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index af69ae981ad3b..d62ca813149a3 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" comment_service "code.gitea.io/gitea/services/comments" ) @@ -174,7 +175,7 @@ func ListRepoIssueComments(ctx *context.APIContext) { } // CreateIssueComment create a comment for an issue -func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOption) { +func CreateIssueComment(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/issues/{index}/comments issue issueCreateComment // --- // summary: Add a comment to an issue @@ -208,7 +209,7 @@ func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOpti // "$ref": "#/responses/Comment" // "403": // "$ref": "#/responses/forbidden" - + form := web.GetForm(ctx).(*api.CreateIssueCommentOption) issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -298,7 +299,7 @@ func GetIssueComment(ctx *context.APIContext) { } // EditIssueComment modify a comment of an issue -func EditIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) { +func EditIssueComment(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/issues/comments/{id} issue issueEditComment // --- // summary: Edit a comment @@ -337,11 +338,12 @@ func EditIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) // "404": // "$ref": "#/responses/notFound" - editIssueComment(ctx, form) + form := web.GetForm(ctx).(*api.EditIssueCommentOption) + editIssueComment(ctx, *form) } // EditIssueCommentDeprecated modify a comment of an issue -func EditIssueCommentDeprecated(ctx *context.APIContext, form api.EditIssueCommentOption) { +func EditIssueCommentDeprecated(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/issues/{index}/comments/{id} issue issueEditCommentDeprecated // --- // summary: Edit a comment @@ -386,7 +388,8 @@ func EditIssueCommentDeprecated(ctx *context.APIContext, form api.EditIssueComme // "404": // "$ref": "#/responses/notFound" - editIssueComment(ctx, form) + form := web.GetForm(ctx).(*api.EditIssueCommentOption) + editIssueComment(ctx, *form) } func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) { diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index 8b2a1988fab40..d7f64b2d995eb 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" issue_service "code.gitea.io/gitea/services/issue" ) @@ -64,7 +65,7 @@ func ListIssueLabels(ctx *context.APIContext) { } // AddIssueLabels add labels for an issue -func AddIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) { +func AddIssueLabels(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/issues/{index}/labels issue issueAddLabel // --- // summary: Add a label to an issue @@ -99,7 +100,8 @@ func AddIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) { // "403": // "$ref": "#/responses/forbidden" - issue, labels, err := prepareForReplaceOrAdd(ctx, form) + form := web.GetForm(ctx).(*api.IssueLabelsOption) + issue, labels, err := prepareForReplaceOrAdd(ctx, *form) if err != nil { return } @@ -190,7 +192,7 @@ func DeleteIssueLabel(ctx *context.APIContext) { } // ReplaceIssueLabels replace labels for an issue -func ReplaceIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) { +func ReplaceIssueLabels(ctx *context.APIContext) { // swagger:operation PUT /repos/{owner}/{repo}/issues/{index}/labels issue issueReplaceLabels // --- // summary: Replace an issue's labels @@ -224,8 +226,8 @@ func ReplaceIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) { // "$ref": "#/responses/LabelList" // "403": // "$ref": "#/responses/forbidden" - - issue, labels, err := prepareForReplaceOrAdd(ctx, form) + form := web.GetForm(ctx).(*api.IssueLabelsOption) + issue, labels, err := prepareForReplaceOrAdd(ctx, *form) if err != nil { return } diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index dfe618480fa40..3994c6b941349 100644 --- a/routers/api/v1/repo/issue_reaction.go +++ b/routers/api/v1/repo/issue_reaction.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -90,7 +91,7 @@ func GetIssueCommentReactions(ctx *context.APIContext) { } // PostIssueCommentReaction add a reaction to a comment of an issue -func PostIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOption) { +func PostIssueCommentReaction(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/issues/comments/{id}/reactions issue issuePostCommentReaction // --- // summary: Add a reaction to a comment of an issue @@ -127,11 +128,13 @@ func PostIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOpti // "403": // "$ref": "#/responses/forbidden" - changeIssueCommentReaction(ctx, form, true) + form := web.GetForm(ctx).(*api.EditReactionOption) + + changeIssueCommentReaction(ctx, *form, true) } // DeleteIssueCommentReaction remove a reaction from a comment of an issue -func DeleteIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOption) { +func DeleteIssueCommentReaction(ctx *context.APIContext) { // swagger:operation DELETE /repos/{owner}/{repo}/issues/comments/{id}/reactions issue issueDeleteCommentReaction // --- // summary: Remove a reaction from a comment of an issue @@ -166,7 +169,9 @@ func DeleteIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp // "403": // "$ref": "#/responses/forbidden" - changeIssueCommentReaction(ctx, form, false) + form := web.GetForm(ctx).(*api.EditReactionOption) + + changeIssueCommentReaction(ctx, *form, false) } func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOption, isCreateType bool) { @@ -304,7 +309,7 @@ func GetIssueReactions(ctx *context.APIContext) { } // PostIssueReaction add a reaction to an issue -func PostIssueReaction(ctx *context.APIContext, form api.EditReactionOption) { +func PostIssueReaction(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/issues/{index}/reactions issue issuePostIssueReaction // --- // summary: Add a reaction to an issue @@ -340,12 +345,12 @@ func PostIssueReaction(ctx *context.APIContext, form api.EditReactionOption) { // "$ref": "#/responses/Reaction" // "403": // "$ref": "#/responses/forbidden" - - changeIssueReaction(ctx, form, true) + form := web.GetForm(ctx).(*api.EditReactionOption) + changeIssueReaction(ctx, *form, true) } // DeleteIssueReaction remove a reaction from an issue -func DeleteIssueReaction(ctx *context.APIContext, form api.EditReactionOption) { +func DeleteIssueReaction(ctx *context.APIContext) { // swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/reactions issue issueDeleteIssueReaction // --- // summary: Remove a reaction from an issue @@ -379,8 +384,8 @@ func DeleteIssueReaction(ctx *context.APIContext, form api.EditReactionOption) { // "$ref": "#/responses/empty" // "403": // "$ref": "#/responses/forbidden" - - changeIssueReaction(ctx, form, false) + form := web.GetForm(ctx).(*api.EditReactionOption) + changeIssueReaction(ctx, *form, false) } func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, isCreateType bool) { diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index 70ce420b77e93..642704800b5c8 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -132,7 +133,7 @@ func ListTrackedTimes(ctx *context.APIContext) { } // AddTime add time manual to the given issue -func AddTime(ctx *context.APIContext, form api.AddTimeOption) { +func AddTime(ctx *context.APIContext) { // swagger:operation Post /repos/{owner}/{repo}/issues/{index}/times issue issueAddTime // --- // summary: Add tracked time to a issue @@ -168,7 +169,7 @@ func AddTime(ctx *context.APIContext, form api.AddTimeOption) { // "$ref": "#/responses/error" // "403": // "$ref": "#/responses/forbidden" - + form := web.GetForm(ctx).(*api.AddTimeOption) issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go index 3e6174f621d44..b1b465ca113ff 100644 --- a/routers/api/v1/repo/key.go +++ b/routers/api/v1/repo/key.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -185,7 +186,7 @@ func HandleAddKeyError(ctx *context.APIContext, err error) { } // CreateDeployKey create deploy key for a repository -func CreateDeployKey(ctx *context.APIContext, form api.CreateKeyOption) { +func CreateDeployKey(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/keys repository repoCreateKey // --- // summary: Add a key to a repository @@ -214,6 +215,7 @@ func CreateDeployKey(ctx *context.APIContext, form api.CreateKeyOption) { // "422": // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.CreateKeyOption) content, err := models.CheckPublicKeyString(form.Key) if err != nil { HandleCheckKeyStringError(ctx, err) diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index fef6ebf07aa67..f71683f6ece19 100644 --- a/routers/api/v1/repo/label.go +++ b/routers/api/v1/repo/label.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -108,7 +109,7 @@ func GetLabel(ctx *context.APIContext) { } // CreateLabel create a label for a repository -func CreateLabel(ctx *context.APIContext, form api.CreateLabelOption) { +func CreateLabel(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/labels issue issueCreateLabel // --- // summary: Create a label @@ -137,6 +138,7 @@ func CreateLabel(ctx *context.APIContext, form api.CreateLabelOption) { // "422": // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.CreateLabelOption) form.Color = strings.Trim(form.Color, " ") if len(form.Color) == 6 { form.Color = "#" + form.Color @@ -160,7 +162,7 @@ func CreateLabel(ctx *context.APIContext, form api.CreateLabelOption) { } // EditLabel modify a label for a repository -func EditLabel(ctx *context.APIContext, form api.EditLabelOption) { +func EditLabel(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/labels/{id} issue issueEditLabel // --- // summary: Update a label @@ -195,6 +197,7 @@ func EditLabel(ctx *context.APIContext, form api.EditLabelOption) { // "422": // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.EditLabelOption) label, err := models.GetLabelInRepoByID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) if err != nil { if models.IsErrRepoLabelNotExist(err) { diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index 0b829c9dfba84..61cd12b991cb1 100644 --- a/routers/api/v1/repo/migrate.go +++ b/routers/api/v1/repo/migrate.go @@ -12,9 +12,9 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/migrations" @@ -24,10 +24,11 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" ) // Migrate migrate remote git repository to gitea -func Migrate(ctx *context.APIContext, form api.MigrateRepoOptions) { +func Migrate(ctx *context.APIContext) { // swagger:operation POST /repos/migrate repository repoMigrate // --- // summary: Migrate a remote git repository @@ -48,6 +49,8 @@ func Migrate(ctx *context.APIContext, form api.MigrateRepoOptions) { // "422": // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.MigrateRepoOptions) + //get repoOwner var ( repoOwner *models.User diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go index db86d0868f8bc..fc8b4efdbb243 100644 --- a/routers/api/v1/repo/milestone.go +++ b/routers/api/v1/repo/milestone.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -110,7 +111,7 @@ func GetMilestone(ctx *context.APIContext) { } // CreateMilestone create a milestone for a repository -func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) { +func CreateMilestone(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/milestones issue issueCreateMilestone // --- // summary: Create a milestone @@ -136,6 +137,7 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) { // responses: // "201": // "$ref": "#/responses/Milestone" + form := web.GetForm(ctx).(*api.CreateMilestoneOption) if form.Deadline == nil { defaultDeadline, _ := time.ParseInLocation("2006-01-02", "9999-12-31", time.Local) @@ -162,7 +164,7 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) { } // EditMilestone modify a milestone for a repository by ID and if not available by name -func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { +func EditMilestone(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/milestones/{id} issue issueEditMilestone // --- // summary: Update a milestone @@ -193,7 +195,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { // responses: // "200": // "$ref": "#/responses/Milestone" - + form := web.GetForm(ctx).(*api.EditMilestoneOption) milestone := getMilestoneByIDOrName(ctx) if ctx.Written() { return diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index b2b71180a481e..38dac36553353 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -11,21 +11,22 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" ) // ListPullRequests returns a list of all PRs -func ListPullRequests(ctx *context.APIContext, form api.ListPullRequestsOptions) { +func ListPullRequests(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/pulls repository repoListPullRequests // --- // summary: List a repo's pull requests @@ -253,7 +254,7 @@ func DownloadPullDiffOrPatch(ctx *context.APIContext, patch bool) { } // CreatePullRequest does what it says -func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption) { +func CreatePullRequest(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/pulls repository repoCreatePullRequest // --- // summary: Create a pull request @@ -284,6 +285,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption // "422": // "$ref": "#/responses/validationError" + form := *web.GetForm(ctx).(*api.CreatePullRequestOption) if form.Head == form.Base { ctx.Error(http.StatusUnprocessableEntity, "BaseHeadSame", "Invalid PullRequest: There are no changes between the head and the base") @@ -437,7 +439,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption } // EditPullRequest does what it says -func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { +func EditPullRequest(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/pulls/{index} repository repoEditPullRequest // --- // summary: Update a pull request. If using deadline only the date will be taken into account, and time of day ignored. @@ -478,6 +480,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { // "422": // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.EditPullRequestOption) pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrPullRequestNotExist(err) { @@ -685,7 +688,7 @@ func IsPullRequestMerged(ctx *context.APIContext) { } // MergePullRequest merges a PR given an index -func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) { +func MergePullRequest(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/merge repository repoMergePullRequest // --- // summary: Merge a pull request @@ -720,6 +723,7 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) { // "409": // "$ref": "#/responses/error" + form := web.GetForm(ctx).(*auth.MergePullRequestForm) pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrPullRequestNotExist(err) { diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index 9e7fd156642fc..d39db4c6605a8 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" @@ -258,7 +259,7 @@ func DeletePullReview(ctx *context.APIContext) { } // CreatePullReview create a review to an pull request -func CreatePullReview(ctx *context.APIContext, opts api.CreatePullReviewOptions) { +func CreatePullReview(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/reviews repository repoCreatePullReview // --- // summary: Create a review to an pull request @@ -294,6 +295,7 @@ func CreatePullReview(ctx *context.APIContext, opts api.CreatePullReviewOptions) // "422": // "$ref": "#/responses/validationError" + opts := web.GetForm(ctx).(*api.CreatePullReviewOptions) pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrPullRequestNotExist(err) { @@ -373,7 +375,7 @@ func CreatePullReview(ctx *context.APIContext, opts api.CreatePullReviewOptions) } // SubmitPullReview submit a pending review to an pull request -func SubmitPullReview(ctx *context.APIContext, opts api.SubmitPullReviewOptions) { +func SubmitPullReview(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/reviews/{id} repository repoSubmitPullReview // --- // summary: Submit a pending review to an pull request @@ -415,6 +417,7 @@ func SubmitPullReview(ctx *context.APIContext, opts api.SubmitPullReviewOptions) // "422": // "$ref": "#/responses/validationError" + opts := web.GetForm(ctx).(*api.SubmitPullReviewOptions) review, pr, isWrong := prepareSingleReview(ctx) if isWrong { return @@ -542,7 +545,7 @@ func prepareSingleReview(ctx *context.APIContext) (*models.Review, *models.PullR } // CreateReviewRequests create review requests to an pull request -func CreateReviewRequests(ctx *context.APIContext, opts api.PullReviewRequestOptions) { +func CreateReviewRequests(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/requested_reviewers repository repoCreatePullReviewRequests // --- // summary: create review requests for a pull request @@ -577,11 +580,13 @@ func CreateReviewRequests(ctx *context.APIContext, opts api.PullReviewRequestOpt // "$ref": "#/responses/validationError" // "404": // "$ref": "#/responses/notFound" - apiReviewRequest(ctx, opts, true) + + opts := web.GetForm(ctx).(*api.PullReviewRequestOptions) + apiReviewRequest(ctx, *opts, true) } // DeleteReviewRequests delete review requests to an pull request -func DeleteReviewRequests(ctx *context.APIContext, opts api.PullReviewRequestOptions) { +func DeleteReviewRequests(ctx *context.APIContext) { // swagger:operation DELETE /repos/{owner}/{repo}/pulls/{index}/requested_reviewers repository repoDeletePullReviewRequests // --- // summary: cancel review requests for a pull request @@ -616,7 +621,8 @@ func DeleteReviewRequests(ctx *context.APIContext, opts api.PullReviewRequestOpt // "$ref": "#/responses/validationError" // "404": // "$ref": "#/responses/notFound" - apiReviewRequest(ctx, opts, false) + opts := web.GetForm(ctx).(*api.PullReviewRequestOptions) + apiReviewRequest(ctx, *opts, false) } func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions, isAdd bool) { diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 358cc011433a3..08d92e6c0a86c 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" releaseservice "code.gitea.io/gitea/services/release" ) @@ -124,7 +125,7 @@ func ListReleases(ctx *context.APIContext) { } // CreateRelease create a release -func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) { +func CreateRelease(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/releases repository repoCreateRelease // --- // summary: Create a release @@ -154,7 +155,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) { // "$ref": "#/responses/notFound" // "409": // "$ref": "#/responses/error" - + form := web.GetForm(ctx).(*api.CreateReleaseOption) rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName) if err != nil { if !models.IsErrReleaseNotExist(err) { @@ -210,7 +211,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) { } // EditRelease edit a release -func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) { +func EditRelease(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/releases/{id} repository repoEditRelease // --- // summary: Update a release @@ -245,6 +246,7 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) { // "404": // "$ref": "#/responses/notFound" + form := web.GetForm(ctx).(*api.EditReleaseOption) id := ctx.ParamsInt64(":id") rel, err := models.GetReleaseByID(id) if err != nil && !models.IsErrReleaseNotExist(err) { diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index 51e1b160dad8e..0a6425cddc536 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/upload" + "code.gitea.io/gitea/modules/web" ) // GetReleaseAttachment gets a single attachment of the release @@ -168,7 +169,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) { } // Get uploaded file from request - file, header, err := ctx.GetFile("attachment") + file, header, err := ctx.Req.FormFile("attachment") if err != nil { ctx.Error(http.StatusInternalServerError, "GetFile", err) return @@ -208,7 +209,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) { } // EditReleaseAttachment updates the given attachment -func EditReleaseAttachment(ctx *context.APIContext, form api.EditAttachmentOptions) { +func EditReleaseAttachment(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id} repository repoEditReleaseAttachment // --- // summary: Edit a release attachment @@ -247,6 +248,8 @@ func EditReleaseAttachment(ctx *context.APIContext, form api.EditAttachmentOptio // "201": // "$ref": "#/responses/Attachment" + form := web.GetForm(ctx).(*api.EditAttachmentOptions) + // Check if release exists an load release releaseID := ctx.ParamsInt64(":id") attachID := ctx.ParamsInt64(":asset") diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 82d380a814715..375f2418b90d1 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -20,6 +20,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/validation" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" repo_service "code.gitea.io/gitea/services/repository" ) @@ -277,7 +278,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR } // Create one repository of mine -func Create(ctx *context.APIContext, opt api.CreateRepoOption) { +func Create(ctx *context.APIContext) { // swagger:operation POST /user/repos repository user createCurrentUserRepo // --- // summary: Create a repository @@ -297,17 +298,17 @@ func Create(ctx *context.APIContext, opt api.CreateRepoOption) { // description: The repository with the same name already exists. // "422": // "$ref": "#/responses/validationError" - + opt := web.GetForm(ctx).(*api.CreateRepoOption) if ctx.User.IsOrganization() { // Shouldn't reach this condition, but just in case. ctx.Error(http.StatusUnprocessableEntity, "", "not allowed creating repository for organization") return } - CreateUserRepo(ctx, ctx.User, opt) + CreateUserRepo(ctx, ctx.User, *opt) } // CreateOrgRepoDeprecated create one repository of the organization -func CreateOrgRepoDeprecated(ctx *context.APIContext, opt api.CreateRepoOption) { +func CreateOrgRepoDeprecated(ctx *context.APIContext) { // swagger:operation POST /org/{org}/repos organization createOrgRepoDeprecated // --- // summary: Create a repository in an organization @@ -334,11 +335,11 @@ func CreateOrgRepoDeprecated(ctx *context.APIContext, opt api.CreateRepoOption) // "403": // "$ref": "#/responses/forbidden" - CreateOrgRepo(ctx, opt) + CreateOrgRepo(ctx) } // CreateOrgRepo create one repository of the organization -func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) { +func CreateOrgRepo(ctx *context.APIContext) { // swagger:operation POST /orgs/{org}/repos organization createOrgRepo // --- // summary: Create a repository in an organization @@ -363,7 +364,7 @@ func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) { // "$ref": "#/responses/notFound" // "403": // "$ref": "#/responses/forbidden" - + opt := web.GetForm(ctx).(*api.CreateRepoOption) org, err := models.GetOrgByName(ctx.Params(":org")) if err != nil { if models.IsErrOrgNotExist(err) { @@ -389,7 +390,7 @@ func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) { return } } - CreateUserRepo(ctx, org, opt) + CreateUserRepo(ctx, org, *opt) } // Get one repository @@ -457,7 +458,7 @@ func GetByID(ctx *context.APIContext) { } // Edit edit repository properties -func Edit(ctx *context.APIContext, opts api.EditRepoOption) { +func Edit(ctx *context.APIContext) { // swagger:operation PATCH /repos/{owner}/{repo} repository repoEdit // --- // summary: Edit a repository's properties. Only fields that are set will be changed. @@ -488,6 +489,8 @@ func Edit(ctx *context.APIContext, opts api.EditRepoOption) { // "422": // "$ref": "#/responses/validationError" + opts := *web.GetForm(ctx).(*api.EditRepoOption) + if err := updateBasicProperties(ctx, opts); err != nil { return } diff --git a/routers/api/v1/repo/repo_test.go b/routers/api/v1/repo/repo_test.go index 053134ec6199b..a1bd3e85d75a5 100644 --- a/routers/api/v1/repo/repo_test.go +++ b/routers/api/v1/repo/repo_test.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/web" "github.com/stretchr/testify/assert" ) @@ -53,7 +54,9 @@ func TestRepoEdit(t *testing.T) { Archived: &archived, } - Edit(&context.APIContext{Context: ctx, Org: nil}, opts) + var apiCtx = &context.APIContext{Context: ctx, Org: nil} + web.SetForm(apiCtx, &opts) + Edit(apiCtx) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) models.AssertExistsAndLoadBean(t, &models.Repository{ @@ -73,7 +76,9 @@ func TestRepoEditNameChange(t *testing.T) { Name: &name, } - Edit(&context.APIContext{Context: ctx, Org: nil}, opts) + var apiCtx = &context.APIContext{Context: ctx, Org: nil} + web.SetForm(apiCtx, &opts) + Edit(apiCtx) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) models.AssertExistsAndLoadBean(t, &models.Repository{ diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index 9c0d902f76b28..7ab399b572752 100644 --- a/routers/api/v1/repo/status.go +++ b/routers/api/v1/repo/status.go @@ -13,11 +13,12 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/repofiles" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) // NewCommitStatus creates a new CommitStatus -func NewCommitStatus(ctx *context.APIContext, form api.CreateStatusOption) { +func NewCommitStatus(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/statuses/{sha} repository repoCreateStatus // --- // summary: Create a commit status @@ -49,6 +50,7 @@ func NewCommitStatus(ctx *context.APIContext, form api.CreateStatusOption) { // "400": // "$ref": "#/responses/error" + form := web.GetForm(ctx).(*api.CreateStatusOption) sha := ctx.Params("sha") if len(sha) == 0 { ctx.Error(http.StatusBadRequest, "sha not given", nil) diff --git a/routers/api/v1/repo/topic.go b/routers/api/v1/repo/topic.go index 41fa37a2c1a27..c612c2942c48d 100644 --- a/routers/api/v1/repo/topic.go +++ b/routers/api/v1/repo/topic.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -66,7 +67,7 @@ func ListTopics(ctx *context.APIContext) { } // UpdateTopics updates repo with a new set of topics -func UpdateTopics(ctx *context.APIContext, form api.RepoTopicOptions) { +func UpdateTopics(ctx *context.APIContext) { // swagger:operation PUT /repos/{owner}/{repo}/topics repository repoUpdateTopics // --- // summary: Replace list of topics for a repository @@ -93,6 +94,7 @@ func UpdateTopics(ctx *context.APIContext, form api.RepoTopicOptions) { // "422": // "$ref": "#/responses/invalidTopicsError" + form := web.GetForm(ctx).(*api.RepoTopicOptions) topicNames := form.Topics validTopics, invalidTopics := models.SanitizeAndValidateTopics(topicNames) diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index a0999a6ce296c..656ace032ed97 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -14,11 +14,12 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" repo_service "code.gitea.io/gitea/services/repository" ) // Transfer transfers the ownership of a repository -func Transfer(ctx *context.APIContext, opts api.TransferRepoOption) { +func Transfer(ctx *context.APIContext) { // swagger:operation POST /repos/{owner}/{repo}/transfer repository repoTransfer // --- // summary: Transfer a repo ownership @@ -51,6 +52,8 @@ func Transfer(ctx *context.APIContext, opts api.TransferRepoOption) { // "422": // "$ref": "#/responses/validationError" + opts := web.GetForm(ctx).(*api.TransferRepoOption) + newOwner, err := models.GetUserByName(opts.NewOwner) if err != nil { if models.IsErrUserNotExist(err) { diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go index a3bb9cc657810..8919a969ec7ce 100644 --- a/routers/api/v1/swagger/options.go +++ b/routers/api/v1/swagger/options.go @@ -5,7 +5,7 @@ package swagger import ( - "code.gitea.io/gitea/modules/auth" + auth "code.gitea.io/gitea/modules/forms" api "code.gitea.io/gitea/modules/structs" ) diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index 547730ea57e3a..33b27d60e0c1f 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -61,7 +62,7 @@ func ListAccessTokens(ctx *context.APIContext) { } // CreateAccessToken create access tokens -func CreateAccessToken(ctx *context.APIContext, form api.CreateAccessTokenOption) { +func CreateAccessToken(ctx *context.APIContext) { // swagger:operation POST /users/{username}/tokens user userCreateToken // --- // summary: Create an access token @@ -88,6 +89,8 @@ func CreateAccessToken(ctx *context.APIContext, form api.CreateAccessTokenOption // "201": // "$ref": "#/responses/AccessToken" + form := web.GetForm(ctx).(*api.CreateAccessTokenOption) + t := &models.AccessToken{ UID: ctx.User.ID, Name: form.Name, @@ -181,7 +184,7 @@ func DeleteAccessToken(ctx *context.APIContext) { } // CreateOauth2Application is the handler to create a new OAuth2 Application for the authenticated user -func CreateOauth2Application(ctx *context.APIContext, data api.CreateOAuth2ApplicationOptions) { +func CreateOauth2Application(ctx *context.APIContext) { // swagger:operation POST /user/applications/oauth2 user userCreateOAuth2Application // --- // summary: creates a new OAuth2 application @@ -196,6 +199,9 @@ func CreateOauth2Application(ctx *context.APIContext, data api.CreateOAuth2Appli // responses: // "201": // "$ref": "#/responses/OAuth2Application" + + data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) + app, err := models.CreateOAuth2Application(models.CreateOAuth2ApplicationOptions{ Name: data.Name, UserID: ctx.User.ID, @@ -309,7 +315,7 @@ func GetOauth2Application(ctx *context.APIContext) { } // UpdateOauth2Application update OAuth2 Application -func UpdateOauth2Application(ctx *context.APIContext, data api.CreateOAuth2ApplicationOptions) { +func UpdateOauth2Application(ctx *context.APIContext) { // swagger:operation PATCH /user/applications/oauth2/{id} user userUpdateOAuth2Application // --- // summary: update an OAuth2 Application, this includes regenerating the client secret @@ -332,6 +338,8 @@ func UpdateOauth2Application(ctx *context.APIContext, data api.CreateOAuth2Appli // "$ref": "#/responses/OAuth2Application" appID := ctx.ParamsInt64(":id") + data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) + app, err := models.UpdateOAuth2Application(models.UpdateOAuth2ApplicationOptions{ Name: data.Name, UserID: ctx.User.ID, diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go index d848f5e58d8d2..bc8b2fa87bec2 100644 --- a/routers/api/v1/user/email.go +++ b/routers/api/v1/user/email.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" ) // ListEmails list all of the authenticated user's email addresses @@ -40,7 +41,7 @@ func ListEmails(ctx *context.APIContext) { } // AddEmail add an email address -func AddEmail(ctx *context.APIContext, form api.CreateEmailOption) { +func AddEmail(ctx *context.APIContext) { // swagger:operation POST /user/emails user userAddEmail // --- // summary: Add email addresses @@ -61,7 +62,7 @@ func AddEmail(ctx *context.APIContext, form api.CreateEmailOption) { // "$ref": "#/responses/EmailList" // "422": // "$ref": "#/responses/validationError" - + form := web.GetForm(ctx).(*api.CreateEmailOption) if len(form.Emails) == 0 { ctx.Error(http.StatusUnprocessableEntity, "", "Email list empty") return @@ -96,7 +97,7 @@ func AddEmail(ctx *context.APIContext, form api.CreateEmailOption) { } // DeleteEmail delete email -func DeleteEmail(ctx *context.APIContext, form api.DeleteEmailOption) { +func DeleteEmail(ctx *context.APIContext) { // swagger:operation DELETE /user/emails user userDeleteEmail // --- // summary: Delete email addresses @@ -110,7 +111,7 @@ func DeleteEmail(ctx *context.APIContext, form api.DeleteEmailOption) { // responses: // "204": // "$ref": "#/responses/empty" - + form := web.GetForm(ctx).(*api.DeleteEmailOption) if len(form.Emails) == 0 { ctx.Status(http.StatusNoContent) return diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index 7290ef485a1cb..51bcaeacc6c4a 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -133,7 +134,7 @@ type swaggerUserCurrentPostGPGKey struct { } //CreateGPGKey create a GPG key belonging to the authenticated user -func CreateGPGKey(ctx *context.APIContext, form api.CreateGPGKeyOption) { +func CreateGPGKey(ctx *context.APIContext) { // swagger:operation POST /user/gpg_keys user userCurrentPostGPGKey // --- // summary: Create a GPG key @@ -149,7 +150,8 @@ func CreateGPGKey(ctx *context.APIContext, form api.CreateGPGKeyOption) { // "422": // "$ref": "#/responses/validationError" - CreateUserGPGKey(ctx, form, ctx.User.ID) + form := web.GetForm(ctx).(*api.CreateGPGKeyOption) + CreateUserGPGKey(ctx, *form, ctx.User.ID) } //DeleteGPGKey remove a GPG key belonging to the authenticated user diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index fa16df1836350..df8a11c61f1d1 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/repo" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -204,7 +205,7 @@ func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid } // CreatePublicKey create one public key for me -func CreatePublicKey(ctx *context.APIContext, form api.CreateKeyOption) { +func CreatePublicKey(ctx *context.APIContext) { // swagger:operation POST /user/keys user userCurrentPostKey // --- // summary: Create a public key @@ -223,7 +224,8 @@ func CreatePublicKey(ctx *context.APIContext, form api.CreateKeyOption) { // "422": // "$ref": "#/responses/validationError" - CreateUserPublicKey(ctx, form, ctx.User.ID) + form := web.GetForm(ctx).(*api.CreateKeyOption) + CreateUserPublicKey(ctx, *form, ctx.User.ID) } // DeletePublicKey delete one public key diff --git a/routers/init.go b/routers/init.go index 79e2f9130ab2a..9d13bc9ed59ab 100644 --- a/routers/init.go +++ b/routers/init.go @@ -37,22 +37,16 @@ import ( pull_service "code.gitea.io/gitea/services/pull" "code.gitea.io/gitea/services/repository" "code.gitea.io/gitea/services/webhook" - - "gitea.com/macaron/macaron" ) func checkRunMode() { switch setting.RunMode { - case "dev": - git.Debug = true - case "test": + case "dev", "test": git.Debug = true default: - macaron.Env = macaron.PROD - macaron.ColorLog = false git.Debug = false } - log.Info("Run Mode: %s", strings.Title(macaron.Env)) + log.Info("Run Mode: %s", strings.Title(setting.RunMode)) } // NewServices init new services diff --git a/routers/install.go b/routers/install.go index 50e929b6f368f..5dcd1d48a399d 100644 --- a/routers/install.go +++ b/routers/install.go @@ -11,18 +11,23 @@ import ( "os/exec" "path/filepath" "strings" + "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/generate" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/user" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" + "gitea.com/go-chi/session" "gopkg.in/ini.v1" ) @@ -33,17 +38,39 @@ const ( ) // InstallInit prepare for rendering installation page -func InstallInit(ctx *context.Context) { - if setting.InstallLock { - ctx.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login") - ctx.HTML(200, tplPostInstall) - return - } - - ctx.Data["Title"] = ctx.Tr("install.install") - ctx.Data["PageIsInstall"] = true +func InstallInit(next http.Handler) http.Handler { + var rnd = templates.HTMLRenderer() - ctx.Data["DbOptions"] = setting.SupportedDatabases + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + if setting.InstallLock { + resp.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login") + _ = rnd.HTML(resp, 200, string(tplPostInstall), nil) + return + } + var locale = middlewares.Locale(resp, req) + var startTime = time.Now() + var ctx = context.Context{ + Resp: context.NewResponse(resp), + Flash: &middlewares.Flash{}, + Locale: locale, + Render: rnd, + Session: session.GetSession(req), + Data: map[string]interface{}{ + "Title": locale.Tr("install.install"), + "PageIsInstall": true, + "DbOptions": setting.SupportedDatabases, + "i18n": locale, + "Language": locale.Language(), + "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), + "PageStartTime": startTime, + "TmplLoadTimes": func() string { + return time.Since(startTime).String() + }, + }, + } + ctx.Req = context.WithContext(req, &ctx) + next.ServeHTTP(resp, ctx.Req) + }) } // Install render installation page @@ -116,12 +143,13 @@ func Install(ctx *context.Context) { form.DefaultEnableTimetracking = setting.Service.DefaultEnableTimetracking form.NoReplyAddress = setting.Service.NoReplyAddress - auth.AssignForm(form, ctx.Data) + middlewares.AssignForm(form, ctx.Data) ctx.HTML(200, tplInstall) } // InstallPost response for submit install items -func InstallPost(ctx *context.Context, form auth.InstallForm) { +func InstallPost(ctx *context.Context) { + form := *web.GetForm(ctx).(*auth.InstallForm) var err error ctx.Data["CurDbOption"] = form.DbType diff --git a/routers/org/org.go b/routers/org/org.go index 85bc25217b080..98a327a97ede3 100644 --- a/routers/org/org.go +++ b/routers/org/org.go @@ -9,11 +9,12 @@ import ( "errors" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" ) const ( @@ -33,7 +34,8 @@ func Create(ctx *context.Context) { } // CreatePost response for create organization -func CreatePost(ctx *context.Context, form auth.CreateOrgForm) { +func CreatePost(ctx *context.Context) { + form := *web.GetForm(ctx).(*auth.CreateOrgForm) ctx.Data["Title"] = ctx.Tr("new_org") if !ctx.User.CanCreateOrganization() { diff --git a/routers/org/org_labels.go b/routers/org/org_labels.go index e5b9d9ddeef8a..554f86c9647e8 100644 --- a/routers/org/org_labels.go +++ b/routers/org/org_labels.go @@ -6,8 +6,9 @@ package org import ( "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" + "code.gitea.io/gitea/modules/web" ) // RetrieveLabels find all the labels of an organization @@ -26,7 +27,8 @@ func RetrieveLabels(ctx *context.Context) { } // NewLabel create new label for organization -func NewLabel(ctx *context.Context, form auth.CreateLabelForm) { +func NewLabel(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateLabelForm) ctx.Data["Title"] = ctx.Tr("repo.labels") ctx.Data["PageIsLabels"] = true @@ -50,7 +52,8 @@ func NewLabel(ctx *context.Context, form auth.CreateLabelForm) { } // UpdateLabel update a label's name and color -func UpdateLabel(ctx *context.Context, form auth.CreateLabelForm) { +func UpdateLabel(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateLabelForm) l, err := models.GetLabelInOrgByID(ctx.Org.Organization.ID, form.ID) if err != nil { switch { @@ -86,7 +89,8 @@ func DeleteLabel(ctx *context.Context) { } // InitializeLabels init labels for an organization -func InitializeLabels(ctx *context.Context, form auth.InitializeLabelsForm) { +func InitializeLabels(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.InitializeLabelsForm) if ctx.HasError() { ctx.Redirect(ctx.Repo.RepoLink + "/labels") return diff --git a/routers/org/setting.go b/routers/org/setting.go index 05075ca8202cc..ac120662581d3 100644 --- a/routers/org/setting.go +++ b/routers/org/setting.go @@ -9,11 +9,12 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" userSetting "code.gitea.io/gitea/routers/user/setting" ) @@ -38,7 +39,8 @@ func Settings(ctx *context.Context) { } // SettingsPost response for settings change submited -func SettingsPost(ctx *context.Context, form auth.UpdateOrgSettingForm) { +func SettingsPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.UpdateOrgSettingForm) ctx.Data["Title"] = ctx.Tr("org.settings") ctx.Data["PageIsSettingsOptions"] = true ctx.Data["CurrentVisibility"] = ctx.Org.Organization.Visibility @@ -115,7 +117,8 @@ func SettingsPost(ctx *context.Context, form auth.UpdateOrgSettingForm) { } // SettingsAvatar response for change avatar on settings page -func SettingsAvatar(ctx *context.Context, form auth.AvatarForm) { +func SettingsAvatar(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AvatarForm) form.Source = auth.AvatarLocal if err := userSetting.UpdateAvatarSetting(ctx, form, ctx.Org.Organization); err != nil { ctx.Flash.Error(err.Error()) diff --git a/routers/org/teams.go b/routers/org/teams.go index fa98add601625..cfa49d4e97f0a 100644 --- a/routers/org/teams.go +++ b/routers/org/teams.go @@ -11,10 +11,11 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" ) @@ -186,7 +187,8 @@ func NewTeam(ctx *context.Context) { } // NewTeamPost response for create new team -func NewTeamPost(ctx *context.Context, form auth.CreateTeamForm) { +func NewTeamPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateTeamForm) ctx.Data["Title"] = ctx.Org.Organization.FullName ctx.Data["PageIsOrgTeams"] = true ctx.Data["PageIsOrgTeamsNew"] = true @@ -274,7 +276,8 @@ func EditTeam(ctx *context.Context) { } // EditTeamPost response for modify team information -func EditTeamPost(ctx *context.Context, form auth.CreateTeamForm) { +func EditTeamPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateTeamForm) t := ctx.Org.Team ctx.Data["Title"] = ctx.Org.Organization.FullName ctx.Data["PageIsOrgTeams"] = true diff --git a/routers/private/hook.go b/routers/private/hook.go index 34e849f6f7717..853d3069ec913 100644 --- a/routers/private/hook.go +++ b/routers/private/hook.go @@ -15,16 +15,16 @@ import ( "strings" "code.gitea.io/gitea/models" + gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" pull_service "code.gitea.io/gitea/services/pull" repo_service "code.gitea.io/gitea/services/repository" - - "gitea.com/macaron/macaron" ) func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []string) error { @@ -117,7 +117,8 @@ func isErrUnverifiedCommit(err error) bool { } // HookPreReceive checks whether a individual commit is acceptable -func HookPreReceive(ctx *macaron.Context, opts private.HookOptions) { +func HookPreReceive(ctx *gitea_context.PrivateContext) { + opts := web.GetForm(ctx).(*private.HookOptions) ownerName := ctx.Params(":owner") repoName := ctx.Params(":repo") repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName) @@ -370,7 +371,8 @@ func HookPreReceive(ctx *macaron.Context, opts private.HookOptions) { } // HookPostReceive updates services and users -func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) { +func HookPostReceive(ctx *gitea_context.PrivateContext) { + opts := web.GetForm(ctx).(*private.HookOptions) ownerName := ctx.Params(":owner") repoName := ctx.Params(":repo") @@ -540,7 +542,7 @@ func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) { } // SetDefaultBranch updates the default branch -func SetDefaultBranch(ctx *macaron.Context) { +func SetDefaultBranch(ctx *gitea_context.PrivateContext) { ownerName := ctx.Params(":owner") repoName := ctx.Params(":repo") branch := ctx.Params(":branch") diff --git a/routers/private/internal.go b/routers/private/internal.go index 4fb267a49ab21..e541591a3840b 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -6,47 +6,69 @@ package private import ( + "net/http" + "reflect" "strings" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" - "gitea.com/macaron/binding" - "gitea.com/macaron/macaron" + "gitea.com/go-chi/binding" ) // CheckInternalToken check internal token is set -func CheckInternalToken(ctx *macaron.Context) { - tokens := ctx.Req.Header.Get("Authorization") - fields := strings.Fields(tokens) - if len(fields) != 2 || fields[0] != "Bearer" || fields[1] != setting.InternalToken { - log.Debug("Forbidden attempt to access internal url: Authorization header: %s", tokens) - ctx.Error(403) +func CheckInternalToken(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + tokens := req.Header.Get("Authorization") + fields := strings.Fields(tokens) + if len(fields) != 2 || fields[0] != "Bearer" || fields[1] != setting.InternalToken { + log.Debug("Forbidden attempt to access internal url: Authorization header: %s", tokens) + http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) + } else { + next.ServeHTTP(w, req) + } + }) +} + +// bind binding an obj to a handler +func bind(obj interface{}) http.HandlerFunc { + var tp = reflect.TypeOf(obj) + for tp.Kind() == reflect.Ptr { + tp = tp.Elem() } + return web.Wrap(func(ctx *context.PrivateContext) { + var theObj = reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly + binding.Bind(ctx.Req, theObj) + web.SetForm(ctx, theObj) + }) } -// RegisterRoutes registers all internal APIs routes to web application. +// Routes registers all internal APIs routes to web application. // These APIs will be invoked by internal commands for example `gitea serv` and etc. -func RegisterRoutes(m *macaron.Macaron) { - bind := binding.Bind - - m.Group("/", func() { - m.Post("/ssh/authorized_keys", AuthorizedPublicKeyByContent) - m.Post("/ssh/:id/update/:repoid", UpdatePublicKeyInRepo) - m.Post("/hook/pre-receive/:owner/:repo", bind(private.HookOptions{}), HookPreReceive) - m.Post("/hook/post-receive/:owner/:repo", bind(private.HookOptions{}), HookPostReceive) - m.Post("/hook/set-default-branch/:owner/:repo/:branch", SetDefaultBranch) - m.Get("/serv/none/:keyid", ServNoCommand) - m.Get("/serv/command/:keyid/:owner/:repo", ServCommand) - m.Post("/manager/shutdown", Shutdown) - m.Post("/manager/restart", Restart) - m.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues) - m.Post("/manager/pause-logging", PauseLogging) - m.Post("/manager/resume-logging", ResumeLogging) - m.Post("/manager/release-and-reopen-logging", ReleaseReopenLogging) - m.Post("/manager/add-logger", bind(private.LoggerOptions{}), AddLogger) - m.Post("/manager/remove-logger/:group/:name", RemoveLogger) - m.Post("/mail/send", SendEmail) - }, CheckInternalToken) +func Routes() *web.Route { + var r = web.NewRoute() + r.Use(context.PrivateContexter()) + r.Use(CheckInternalToken) + + r.Post("/ssh/authorized_keys", AuthorizedPublicKeyByContent) + r.Post("/ssh/{id}/update/{repoid}", UpdatePublicKeyInRepo) + r.Post("/hook/pre-receive/{owner}/{repo}", bind(private.HookOptions{}), HookPreReceive) + r.Post("/hook/post-receive/{owner}/{repo}", bind(private.HookOptions{}), HookPostReceive) + r.Post("/hook/set-default-branch/{owner}/{repo}/{branch}", SetDefaultBranch) + r.Get("/serv/none/{keyid}", ServNoCommand) + r.Get("/serv/command/{keyid}/{owner}/{repo}", ServCommand) + r.Post("/manager/shutdown", Shutdown) + r.Post("/manager/restart", Restart) + r.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues) + r.Post("/manager/pause-logging", PauseLogging) + r.Post("/manager/resume-logging", ResumeLogging) + r.Post("/manager/release-and-reopen-logging", ReleaseReopenLogging) + r.Post("/manager/add-logger", bind(private.LoggerOptions{}), AddLogger) + r.Post("/manager/remove-logger/{group}/{name}", RemoveLogger) + r.Post("/mail/send", SendEmail) + + return r } diff --git a/routers/private/key.go b/routers/private/key.go index c00330fe883a1..b90faa22a4fbf 100644 --- a/routers/private/key.go +++ b/routers/private/key.go @@ -9,13 +9,12 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/timeutil" - - "gitea.com/macaron/macaron" ) // UpdatePublicKeyInRepo update public key and deploy key updates -func UpdatePublicKeyInRepo(ctx *macaron.Context) { +func UpdatePublicKeyInRepo(ctx *context.PrivateContext) { keyID := ctx.ParamsInt64(":id") repoID := ctx.ParamsInt64(":repoid") if err := models.UpdatePublicKeyUpdated(keyID); err != nil { @@ -49,7 +48,7 @@ func UpdatePublicKeyInRepo(ctx *macaron.Context) { // AuthorizedPublicKeyByContent searches content as prefix (leak e-mail part) // and returns public key found. -func AuthorizedPublicKeyByContent(ctx *macaron.Context) { +func AuthorizedPublicKeyByContent(ctx *context.PrivateContext) { content := ctx.Query("content") publicKey, err := models.SearchPublicKeyByContent(content) diff --git a/routers/private/mail.go b/routers/private/mail.go index b3b21d042f7a7..330de14c46d29 100644 --- a/routers/private/mail.go +++ b/routers/private/mail.go @@ -11,17 +11,17 @@ import ( "strconv" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/services/mailer" - "gitea.com/macaron/macaron" ) // SendEmail pushes messages to mail queue // // It doesn't wait before each message will be processed -func SendEmail(ctx *macaron.Context) { +func SendEmail(ctx *context.PrivateContext) { if setting.MailService == nil { ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ "err": "Mail service is not enabled.", @@ -30,7 +30,7 @@ func SendEmail(ctx *macaron.Context) { } var mail private.Email - rd := ctx.Req.Body().ReadCloser() + rd := ctx.Req.Body defer rd.Close() if err := json.NewDecoder(rd).Decode(&mail); err != nil { log.Error("%v", err) @@ -77,7 +77,7 @@ func SendEmail(ctx *macaron.Context) { sendEmail(ctx, mail.Subject, mail.Message, emails) } -func sendEmail(ctx *macaron.Context, subject, message string, to []string) { +func sendEmail(ctx *context.PrivateContext, subject, message string, to []string) { for _, email := range to { msg := mailer.NewMessage([]string{email}, subject, message) mailer.SendAsync(msg) diff --git a/routers/private/manager.go b/routers/private/manager.go index 67bd92003fa39..e5b4583fd1b2e 100644 --- a/routers/private/manager.go +++ b/routers/private/manager.go @@ -9,17 +9,18 @@ import ( "fmt" "net/http" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/queue" "code.gitea.io/gitea/modules/setting" - - "gitea.com/macaron/macaron" + "code.gitea.io/gitea/modules/web" ) // FlushQueues flushes all the Queues -func FlushQueues(ctx *macaron.Context, opts private.FlushOptions) { +func FlushQueues(ctx *context.PrivateContext) { + opts := web.GetForm(ctx).(*private.FlushOptions) if opts.NonBlocking { // Save the hammer ctx here - as a new one is created each time you call this. baseCtx := graceful.GetManager().HammerContext() @@ -34,7 +35,7 @@ func FlushQueues(ctx *macaron.Context, opts private.FlushOptions) { }) return } - err := queue.GetManager().FlushAll(ctx.Req.Request.Context(), opts.Timeout) + err := queue.GetManager().FlushAll(ctx.Req.Context(), opts.Timeout) if err != nil { ctx.JSON(http.StatusRequestTimeout, map[string]interface{}{ "err": fmt.Sprintf("%v", err), @@ -44,19 +45,19 @@ func FlushQueues(ctx *macaron.Context, opts private.FlushOptions) { } // PauseLogging pauses logging -func PauseLogging(ctx *macaron.Context) { +func PauseLogging(ctx *context.PrivateContext) { log.Pause() ctx.PlainText(http.StatusOK, []byte("success")) } // ResumeLogging resumes logging -func ResumeLogging(ctx *macaron.Context) { +func ResumeLogging(ctx *context.PrivateContext) { log.Resume() ctx.PlainText(http.StatusOK, []byte("success")) } // ReleaseReopenLogging releases and reopens logging files -func ReleaseReopenLogging(ctx *macaron.Context) { +func ReleaseReopenLogging(ctx *context.PrivateContext) { if err := log.ReleaseReopen(); err != nil { ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ "err": fmt.Sprintf("Error during release and reopen: %v", err), @@ -67,7 +68,7 @@ func ReleaseReopenLogging(ctx *macaron.Context) { } // RemoveLogger removes a logger -func RemoveLogger(ctx *macaron.Context) { +func RemoveLogger(ctx *context.PrivateContext) { group := ctx.Params("group") name := ctx.Params("name") ok, err := log.GetLogger(group).DelLogger(name) @@ -84,7 +85,8 @@ func RemoveLogger(ctx *macaron.Context) { } // AddLogger adds a logger -func AddLogger(ctx *macaron.Context, opts private.LoggerOptions) { +func AddLogger(ctx *context.PrivateContext) { + opts := web.GetForm(ctx).(*private.LoggerOptions) if len(opts.Group) == 0 { opts.Group = log.DEFAULT } diff --git a/routers/private/manager_unix.go b/routers/private/manager_unix.go index ec5e97605981d..60ae9b68e82ca 100644 --- a/routers/private/manager_unix.go +++ b/routers/private/manager_unix.go @@ -9,20 +9,19 @@ package private import ( "net/http" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/graceful" - - "gitea.com/macaron/macaron" ) // Restart causes the server to perform a graceful restart -func Restart(ctx *macaron.Context) { +func Restart(ctx *context.PrivateContext) { graceful.GetManager().DoGracefulRestart() ctx.PlainText(http.StatusOK, []byte("success")) } // Shutdown causes the server to perform a graceful shutdown -func Shutdown(ctx *macaron.Context) { +func Shutdown(ctx *context.PrivateContext) { graceful.GetManager().DoGracefulShutdown() ctx.PlainText(http.StatusOK, []byte("success")) } diff --git a/routers/private/manager_windows.go b/routers/private/manager_windows.go index ac840a9d81ce8..244dbbe4df5b4 100644 --- a/routers/private/manager_windows.go +++ b/routers/private/manager_windows.go @@ -9,20 +9,19 @@ package private import ( "net/http" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/graceful" - - "gitea.com/macaron/macaron" ) // Restart is not implemented for Windows based servers as they can't fork -func Restart(ctx *macaron.Context) { +func Restart(ctx *context.PrivateContext) { ctx.JSON(http.StatusNotImplemented, map[string]interface{}{ "err": "windows servers cannot be gracefully restarted - shutdown and restart manually", }) } // Shutdown causes the server to perform a graceful shutdown -func Shutdown(ctx *macaron.Context) { +func Shutdown(ctx *context.PrivateContext) { graceful.GetManager().DoGracefulShutdown() ctx.PlainText(http.StatusOK, []byte("success")) } diff --git a/routers/private/serv.go b/routers/private/serv.go index 90e1d30b01384..1461194e7f72c 100644 --- a/routers/private/serv.go +++ b/routers/private/serv.go @@ -11,17 +11,16 @@ import ( "strings" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/setting" repo_service "code.gitea.io/gitea/services/repository" wiki_service "code.gitea.io/gitea/services/wiki" - - "gitea.com/macaron/macaron" ) // ServNoCommand returns information about the provided keyid -func ServNoCommand(ctx *macaron.Context) { +func ServNoCommand(ctx *context.PrivateContext) { keyID := ctx.ParamsInt64(":keyid") if keyID <= 0 { ctx.JSON(http.StatusBadRequest, map[string]interface{}{ @@ -73,7 +72,7 @@ func ServNoCommand(ctx *macaron.Context) { } // ServCommand returns information about the provided keyid -func ServCommand(ctx *macaron.Context) { +func ServCommand(ctx *context.PrivateContext) { keyID := ctx.ParamsInt64(":keyid") ownerName := ctx.Params(":owner") repoName := ctx.Params(":repo") diff --git a/routers/repo/branch.go b/routers/repo/branch.go index bf9f2e6a3652e..7d844abe5a023 100644 --- a/routers/repo/branch.go +++ b/routers/repo/branch.go @@ -10,14 +10,15 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/repofiles" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" repo_service "code.gitea.io/gitea/services/repository" ) @@ -367,7 +368,8 @@ func getDeletedBranches(ctx *context.Context) ([]*Branch, error) { } // CreateBranch creates new branch in repository -func CreateBranch(ctx *context.Context, form auth.NewBranchForm) { +func CreateBranch(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewBranchForm) if !ctx.Repo.CanCreateBranch() { ctx.NotFound("CreateBranch", nil) return diff --git a/routers/repo/editor.go b/routers/repo/editor.go index 0bc76504f9b9e..619912fef75b1 100644 --- a/routers/repo/editor.go +++ b/routers/repo/editor.go @@ -12,10 +12,10 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/repofiles" @@ -23,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" ) @@ -325,17 +326,20 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo } // EditFilePost response for editing file -func EditFilePost(ctx *context.Context, form auth.EditRepoFileForm) { - editFilePost(ctx, form, false) +func EditFilePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.EditRepoFileForm) + editFilePost(ctx, *form, false) } // NewFilePost response for creating file -func NewFilePost(ctx *context.Context, form auth.EditRepoFileForm) { - editFilePost(ctx, form, true) +func NewFilePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.EditRepoFileForm) + editFilePost(ctx, *form, true) } // DiffPreviewPost render preview diff page -func DiffPreviewPost(ctx *context.Context, form auth.EditPreviewDiffForm) { +func DiffPreviewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.EditPreviewDiffForm) treePath := cleanUploadFileName(ctx.Repo.TreePath) if len(treePath) == 0 { ctx.Error(500, "file name to diff is invalid") @@ -394,7 +398,8 @@ func DeleteFile(ctx *context.Context) { } // DeleteFilePost response for deleting file -func DeleteFilePost(ctx *context.Context, form auth.DeleteRepoFileForm) { +func DeleteFilePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.DeleteRepoFileForm) canCommit := renderCommitRights(ctx) branchName := ctx.Repo.BranchName if form.CommitChoice == frmCommitChoiceNewBranch { @@ -556,7 +561,8 @@ func UploadFile(ctx *context.Context) { } // UploadFilePost response for uploading file -func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) { +func UploadFilePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.UploadRepoFileForm) ctx.Data["PageIsUpload"] = true ctx.Data["RequireTribute"] = true ctx.Data["RequireSimpleMDE"] = true @@ -760,7 +766,8 @@ func UploadFileToServer(ctx *context.Context) { } // RemoveUploadFileFromServer remove file from server file dir -func RemoveUploadFileFromServer(ctx *context.Context, form auth.RemoveUploadFileForm) { +func RemoveUploadFileFromServer(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.RemoveUploadFileForm) if len(form.File) == 0 { ctx.Status(204) return diff --git a/routers/repo/http.go b/routers/repo/http.go index 3de45698e8dbb..0377979e8bb5c 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -35,8 +35,17 @@ import ( repo_service "code.gitea.io/gitea/services/repository" ) -// HTTP implmentation git smart HTTP protocol -func HTTP(ctx *context.Context) { +// httpBase implmentation git smart HTTP protocol +func httpBase(ctx *context.Context) (h *serviceHandler) { + if setting.Repository.DisableHTTPGit { + ctx.Resp.WriteHeader(http.StatusForbidden) + _, err := ctx.Resp.Write([]byte("Interacting with repositories by HTTP protocol is not allowed")) + if err != nil { + log.Error(err.Error()) + } + return + } + if len(setting.Repository.AccessControlAllowOrigin) > 0 { allowedOrigin := setting.Repository.AccessControlAllowOrigin // Set CORS headers for browser-based git clients @@ -344,7 +353,7 @@ func HTTP(ctx *context.Context) { environ = append(environ, models.EnvRepoID+fmt.Sprintf("=%d", repo.ID)) w := ctx.Resp - r := ctx.Req.Request + r := ctx.Req cfg := &serviceConfig{ UploadPack: true, ReceivePack: true, @@ -353,47 +362,9 @@ func HTTP(ctx *context.Context) { r.URL.Path = strings.ToLower(r.URL.Path) // blue: In case some repo name has upper case name - for _, route := range routes { - if m := route.reg.FindStringSubmatch(r.URL.Path); m != nil { - if setting.Repository.DisableHTTPGit { - w.WriteHeader(http.StatusForbidden) - _, err := w.Write([]byte("Interacting with repositories by HTTP protocol is not allowed")) - if err != nil { - log.Error(err.Error()) - } - return - } - if route.method != r.Method { - if r.Proto == "HTTP/1.1" { - w.WriteHeader(http.StatusMethodNotAllowed) - _, err := w.Write([]byte("Method Not Allowed")) - if err != nil { - log.Error(err.Error()) - } - } else { - w.WriteHeader(http.StatusBadRequest) - _, err := w.Write([]byte("Bad Request")) - if err != nil { - log.Error(err.Error()) - } - } - return - } - - file := strings.Replace(r.URL.Path, m[1]+"/", "", 1) - dir, err := getGitRepoPath(m[1]) - if err != nil { - log.Error(err.Error()) - ctx.NotFound("Smart Git HTTP", err) - return - } - - route.handler(serviceHandler{cfg, w, r, dir, file, cfg.Env}) - return - } - } + dir := models.RepoPath(username, reponame) - ctx.NotFound("Smart Git HTTP", nil) + return &serviceHandler{cfg, w, r, dir, cfg.Env} } var ( @@ -449,7 +420,6 @@ type serviceHandler struct { w http.ResponseWriter r *http.Request dir string - file string environ []string } @@ -467,8 +437,8 @@ func (h *serviceHandler) setHeaderCacheForever() { h.w.Header().Set("Cache-Control", "public, max-age=31536000") } -func (h *serviceHandler) sendFile(contentType string) { - reqFile := path.Join(h.dir, h.file) +func (h *serviceHandler) sendFile(contentType, file string) { + reqFile := path.Join(h.dir, file) fi, err := os.Stat(reqFile) if os.IsNotExist(err) { @@ -482,26 +452,6 @@ func (h *serviceHandler) sendFile(contentType string) { http.ServeFile(h.w, h.r, reqFile) } -type route struct { - reg *regexp.Regexp - method string - handler func(serviceHandler) -} - -var routes = []route{ - {regexp.MustCompile(`(.*?)/git-upload-pack$`), "POST", serviceUploadPack}, - {regexp.MustCompile(`(.*?)/git-receive-pack$`), "POST", serviceReceivePack}, - {regexp.MustCompile(`(.*?)/info/refs$`), "GET", getInfoRefs}, - {regexp.MustCompile(`(.*?)/HEAD$`), "GET", getTextFile}, - {regexp.MustCompile(`(.*?)/objects/info/alternates$`), "GET", getTextFile}, - {regexp.MustCompile(`(.*?)/objects/info/http-alternates$`), "GET", getTextFile}, - {regexp.MustCompile(`(.*?)/objects/info/packs$`), "GET", getInfoPacks}, - {regexp.MustCompile(`(.*?)/objects/info/[^/]*$`), "GET", getTextFile}, - {regexp.MustCompile(`(.*?)/objects/[0-9a-f]{2}/[0-9a-f]{38}$`), "GET", getLooseObject}, - {regexp.MustCompile(`(.*?)/objects/pack/pack-[0-9a-f]{40}\.pack$`), "GET", getPackFile}, - {regexp.MustCompile(`(.*?)/objects/pack/pack-[0-9a-f]{40}\.idx$`), "GET", getIdxFile}, -} - // one or more key=value pairs separated by colons var safeGitProtocolHeader = regexp.MustCompile(`^[0-9a-zA-Z]+=[0-9a-zA-Z]+(:[0-9a-zA-Z]+=[0-9a-zA-Z]+)*$`) @@ -598,12 +548,20 @@ func serviceRPC(h serviceHandler, service string) { } } -func serviceUploadPack(h serviceHandler) { - serviceRPC(h, "upload-pack") +// ServiceUploadPack implements Git Smart HTTP protocol +func ServiceUploadPack(ctx *context.Context) { + h := httpBase(ctx) + if h != nil { + serviceRPC(*h, "upload-pack") + } } -func serviceReceivePack(h serviceHandler) { - serviceRPC(h, "receive-pack") +// ServiceReceivePack implements Git Smart HTTP protocol +func ServiceReceivePack(ctx *context.Context) { + h := httpBase(ctx) + if h != nil { + serviceRPC(*h, "receive-pack") + } } func getServiceType(r *http.Request) string { @@ -630,9 +588,14 @@ func packetWrite(str string) []byte { return []byte(s + str) } -func getInfoRefs(h serviceHandler) { +// GetInfoRefs implements Git dumb HTTP +func GetInfoRefs(ctx *context.Context) { + h := httpBase(ctx) + if h == nil { + return + } h.setHeaderNoCache() - if hasAccess(getServiceType(h.r), h, false) { + if hasAccess(getServiceType(h.r), *h, false) { service := getServiceType(h.r) if protocol := h.r.Header.Get("Git-Protocol"); protocol != "" && safeGitProtocolHeader.MatchString(protocol) { @@ -652,44 +615,59 @@ func getInfoRefs(h serviceHandler) { _, _ = h.w.Write(refs) } else { updateServerInfo(h.dir) - h.sendFile("text/plain; charset=utf-8") + h.sendFile("text/plain; charset=utf-8", "info/refs") } } -func getTextFile(h serviceHandler) { - h.setHeaderNoCache() - h.sendFile("text/plain") -} - -func getInfoPacks(h serviceHandler) { - h.setHeaderCacheForever() - h.sendFile("text/plain; charset=utf-8") -} - -func getLooseObject(h serviceHandler) { - h.setHeaderCacheForever() - h.sendFile("application/x-git-loose-object") +// GetTextFile implements Git dumb HTTP +func GetTextFile(p string) func(*context.Context) { + return func(ctx *context.Context) { + h := httpBase(ctx) + if h != nil { + h.setHeaderNoCache() + file := ctx.Params("file") + if file != "" { + h.sendFile("text/plain", "objects/info/"+file) + } else { + h.sendFile("text/plain", p) + } + } + } } -func getPackFile(h serviceHandler) { - h.setHeaderCacheForever() - h.sendFile("application/x-git-packed-objects") +// GetInfoPacks implements Git dumb HTTP +func GetInfoPacks(ctx *context.Context) { + h := httpBase(ctx) + if h != nil { + h.setHeaderCacheForever() + h.sendFile("text/plain; charset=utf-8", "objects/info/packs") + } } -func getIdxFile(h serviceHandler) { - h.setHeaderCacheForever() - h.sendFile("application/x-git-packed-objects-toc") +// GetLooseObject implements Git dumb HTTP +func GetLooseObject(ctx *context.Context) { + h := httpBase(ctx) + if h != nil { + h.setHeaderCacheForever() + h.sendFile("application/x-git-loose-object", fmt.Sprintf("objects/%s/%s", + ctx.Params("head"), ctx.Params("hash"))) + } } -func getGitRepoPath(subdir string) (string, error) { - if !strings.HasSuffix(subdir, ".git") { - subdir += ".git" +// GetPackFile implements Git dumb HTTP +func GetPackFile(ctx *context.Context) { + h := httpBase(ctx) + if h != nil { + h.setHeaderCacheForever() + h.sendFile("application/x-git-packed-objects", "objects/pack/pack-"+ctx.Params("file")+".pack") } +} - fpath := path.Join(setting.RepoRootPath, subdir) - if _, err := os.Stat(fpath); os.IsNotExist(err) { - return "", err +// GetIdxFile implements Git dumb HTTP +func GetIdxFile(ctx *context.Context) { + h := httpBase(ctx) + if h != nil { + h.setHeaderCacheForever() + h.sendFile("application/x-git-packed-objects-toc", "objects/pack/pack-"+ctx.Params("file")+".idx") } - - return fpath, nil } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index fbeae75ab5218..fb7107451fed7 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -16,10 +16,10 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" issue_indexer "code.gitea.io/gitea/modules/indexer/issues" "code.gitea.io/gitea/modules/log" @@ -29,6 +29,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" comment_service "code.gitea.io/gitea/services/comments" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" @@ -924,7 +925,8 @@ func ValidateRepoMetas(ctx *context.Context, form auth.CreateIssueForm, isPull b } // NewIssuePost response for creating new issue -func NewIssuePost(ctx *context.Context, form auth.CreateIssueForm) { +func NewIssuePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateIssueForm) ctx.Data["Title"] = ctx.Tr("repo.issues.new") ctx.Data["PageIsIssueList"] = true ctx.Data["NewIssueChooseTemplate"] = len(ctx.IssueTemplatesFromDefaultBranch()) > 0 @@ -940,7 +942,7 @@ func NewIssuePost(ctx *context.Context, form auth.CreateIssueForm) { attachments []string ) - labelIDs, assigneeIDs, milestoneID, projectID := ValidateRepoMetas(ctx, form, false) + labelIDs, assigneeIDs, milestoneID, projectID := ValidateRepoMetas(ctx, *form, false) if ctx.Written() { return } @@ -1925,7 +1927,8 @@ func UpdateIssueStatus(ctx *context.Context) { } // NewComment create a comment for issue -func NewComment(ctx *context.Context, form auth.CreateCommentForm) { +func NewComment(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateCommentForm) issue := GetActionIssue(ctx) if ctx.Written() { return @@ -2134,7 +2137,8 @@ func DeleteComment(ctx *context.Context) { } // ChangeIssueReaction create a reaction for issue -func ChangeIssueReaction(ctx *context.Context, form auth.ReactionForm) { +func ChangeIssueReaction(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.ReactionForm) issue := GetActionIssue(ctx) if ctx.Written() { return @@ -2229,7 +2233,8 @@ func ChangeIssueReaction(ctx *context.Context, form auth.ReactionForm) { } // ChangeCommentReaction create a reaction for comment -func ChangeCommentReaction(ctx *context.Context, form auth.ReactionForm) { +func ChangeCommentReaction(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.ReactionForm) comment, err := models.GetCommentByID(ctx.ParamsInt64(":id")) if err != nil { ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) diff --git a/routers/repo/issue_label.go b/routers/repo/issue_label.go index f1e188fe3a7d5..35035103d588a 100644 --- a/routers/repo/issue_label.go +++ b/routers/repo/issue_label.go @@ -6,11 +6,12 @@ package repo import ( "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" issue_service "code.gitea.io/gitea/services/issue" ) @@ -29,7 +30,8 @@ func Labels(ctx *context.Context) { } // InitializeLabels init labels for a repository -func InitializeLabels(ctx *context.Context, form auth.InitializeLabelsForm) { +func InitializeLabels(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.InitializeLabelsForm) if ctx.HasError() { ctx.Redirect(ctx.Repo.RepoLink + "/labels") return @@ -94,7 +96,8 @@ func RetrieveLabels(ctx *context.Context) { } // NewLabel create new label for repository -func NewLabel(ctx *context.Context, form auth.CreateLabelForm) { +func NewLabel(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateLabelForm) ctx.Data["Title"] = ctx.Tr("repo.labels") ctx.Data["PageIsLabels"] = true @@ -118,7 +121,8 @@ func NewLabel(ctx *context.Context, form auth.CreateLabelForm) { } // UpdateLabel update a label's name and color -func UpdateLabel(ctx *context.Context, form auth.CreateLabelForm) { +func UpdateLabel(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateLabelForm) l, err := models.GetLabelInRepoByID(ctx.Repo.Repository.ID, form.ID) if err != nil { switch { diff --git a/routers/repo/issue_label_test.go b/routers/repo/issue_label_test.go index bf625112581e3..d67c70085d57d 100644 --- a/routers/repo/issue_label_test.go +++ b/routers/repo/issue_label_test.go @@ -10,8 +10,9 @@ import ( "testing" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/web" "github.com/stretchr/testify/assert" ) @@ -32,7 +33,8 @@ func TestInitializeLabels(t *testing.T) { ctx := test.MockContext(t, "user2/repo1/labels/initialize") test.LoadUser(t, ctx, 2) test.LoadRepo(t, ctx, 2) - InitializeLabels(ctx, auth.InitializeLabelsForm{TemplateName: "Default"}) + web.SetForm(ctx, &auth.InitializeLabelsForm{TemplateName: "Default"}) + InitializeLabels(ctx) assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) models.AssertExistsAndLoadBean(t, &models.Label{ RepoID: 2, @@ -74,10 +76,11 @@ func TestNewLabel(t *testing.T) { ctx := test.MockContext(t, "user2/repo1/labels/edit") test.LoadUser(t, ctx, 2) test.LoadRepo(t, ctx, 1) - NewLabel(ctx, auth.CreateLabelForm{ + web.SetForm(ctx, &auth.CreateLabelForm{ Title: "newlabel", Color: "#abcdef", }) + NewLabel(ctx) assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) models.AssertExistsAndLoadBean(t, &models.Label{ Name: "newlabel", @@ -91,11 +94,12 @@ func TestUpdateLabel(t *testing.T) { ctx := test.MockContext(t, "user2/repo1/labels/edit") test.LoadUser(t, ctx, 2) test.LoadRepo(t, ctx, 1) - UpdateLabel(ctx, auth.CreateLabelForm{ + web.SetForm(ctx, &auth.CreateLabelForm{ ID: 2, Title: "newnameforlabel", Color: "#abcdef", }) + UpdateLabel(ctx) assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) models.AssertExistsAndLoadBean(t, &models.Label{ ID: 2, diff --git a/routers/repo/issue_lock.go b/routers/repo/issue_lock.go index fa8758831938e..f8131e46aaff6 100644 --- a/routers/repo/issue_lock.go +++ b/routers/repo/issue_lock.go @@ -8,14 +8,15 @@ import ( "net/http" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" + "code.gitea.io/gitea/modules/web" ) // LockIssue locks an issue. This would limit commenting abilities to // users with write access to the repo. -func LockIssue(ctx *context.Context, form auth.IssueLockForm) { - +func LockIssue(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.IssueLockForm) issue := GetActionIssue(ctx) if ctx.Written() { return diff --git a/routers/repo/issue_timetrack.go b/routers/repo/issue_timetrack.go index 0f711bc7344c2..425f215110526 100644 --- a/routers/repo/issue_timetrack.go +++ b/routers/repo/issue_timetrack.go @@ -9,12 +9,14 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" + "code.gitea.io/gitea/modules/web" ) // AddTimeManually tracks time manually -func AddTimeManually(c *context.Context, form auth.AddTimeManuallyForm) { +func AddTimeManually(c *context.Context) { + form := web.GetForm(c).(*auth.AddTimeManuallyForm) issue := GetActionIssue(c) if c.Written() { return diff --git a/routers/repo/migrate.go b/routers/repo/migrate.go index a628fd2e2fd36..89452de0fabfb 100644 --- a/routers/repo/migrate.go +++ b/routers/repo/migrate.go @@ -10,14 +10,15 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/migrations" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/task" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" ) const ( @@ -117,7 +118,8 @@ func handleMigrateError(ctx *context.Context, owner *models.User, err error, nam } // MigratePost response for migrating from external git repository -func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) { +func MigratePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.MigrateRepoForm) if setting.Repository.DisableMigrations { ctx.Error(http.StatusForbidden, "MigratePost: the site administrator has disabled migrations") return @@ -192,7 +194,7 @@ func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) { err = models.CheckCreateRepository(ctx.User, ctxUser, opts.RepoName, false) if err != nil { - handleMigrateError(ctx, ctxUser, err, "MigratePost", tpl, &form) + handleMigrateError(ctx, ctxUser, err, "MigratePost", tpl, form) return } @@ -202,5 +204,5 @@ func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) { return } - handleMigrateError(ctx, ctxUser, err, "MigratePost", tpl, &form) + handleMigrateError(ctx, ctxUser, err, "MigratePost", tpl, form) } diff --git a/routers/repo/milestone.go b/routers/repo/milestone.go index 96f5b4e5f0060..a9beed75d7c64 100644 --- a/routers/repo/milestone.go +++ b/routers/repo/milestone.go @@ -8,14 +8,15 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "xorm.io/builder" ) @@ -106,7 +107,8 @@ func NewMilestone(ctx *context.Context) { } // NewMilestonePost response for creating milestone -func NewMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) { +func NewMilestonePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateMilestoneForm) ctx.Data["Title"] = ctx.Tr("repo.milestones.new") ctx.Data["PageIsIssueList"] = true ctx.Data["PageIsMilestones"] = true @@ -165,7 +167,8 @@ func EditMilestone(ctx *context.Context) { } // EditMilestonePost response for edting milestone -func EditMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) { +func EditMilestonePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateMilestoneForm) ctx.Data["Title"] = ctx.Tr("repo.milestones.edit") ctx.Data["PageIsMilestones"] = true ctx.Data["PageIsEditMilestone"] = true diff --git a/routers/repo/projects.go b/routers/repo/projects.go index 4cff199b34464..49bcfef0ce5b1 100644 --- a/routers/repo/projects.go +++ b/routers/repo/projects.go @@ -9,12 +9,13 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" ) const ( @@ -112,7 +113,8 @@ func NewProject(ctx *context.Context) { } // NewProjectPost creates a new project -func NewProjectPost(ctx *context.Context, form auth.CreateProjectForm) { +func NewProjectPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateProjectForm) ctx.Data["Title"] = ctx.Tr("repo.projects.new") if ctx.HasError() { @@ -217,7 +219,8 @@ func EditProject(ctx *context.Context) { } // EditProjectPost response for editing a project -func EditProjectPost(ctx *context.Context, form auth.CreateProjectForm) { +func EditProjectPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateProjectForm) ctx.Data["Title"] = ctx.Tr("repo.projects.edit") ctx.Data["PageIsProjects"] = true ctx.Data["PageIsEditProjects"] = true @@ -399,8 +402,8 @@ func DeleteProjectBoard(ctx *context.Context) { } // AddBoardToProjectPost allows a new board to be added to a project. -func AddBoardToProjectPost(ctx *context.Context, form auth.EditProjectBoardTitleForm) { - +func AddBoardToProjectPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.EditProjectBoardTitleForm) if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(models.AccessModeWrite, models.UnitTypeProjects) { ctx.JSON(403, map[string]string{ "message": "Only authorized users are allowed to perform this action.", @@ -479,8 +482,8 @@ func checkProjectBoardChangePermissions(ctx *context.Context) (*models.Project, } // EditProjectBoardTitle allows a project board's title to be updated -func EditProjectBoardTitle(ctx *context.Context, form auth.EditProjectBoardTitleForm) { - +func EditProjectBoardTitle(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.EditProjectBoardTitleForm) _, board := checkProjectBoardChangePermissions(ctx) if ctx.Written() { return diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 01c6efaa1de81..1862c15f4316c 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -16,17 +16,19 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/notification" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" "code.gitea.io/gitea/services/gitdiff" pull_service "code.gitea.io/gitea/services/pull" @@ -168,7 +170,8 @@ func Fork(ctx *context.Context) { } // ForkPost response for forking a repository -func ForkPost(ctx *context.Context, form auth.CreateRepoForm) { +func ForkPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateRepoForm) ctx.Data["Title"] = ctx.Tr("new_fork") ctxUser := checkContextUser(ctx, form.UID) @@ -765,7 +768,8 @@ func UpdatePullRequest(ctx *context.Context) { } // MergePullRequest response for merging pull request -func MergePullRequest(ctx *context.Context, form auth.MergePullRequestForm) { +func MergePullRequest(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.MergePullRequestForm) issue := checkPullInfo(ctx) if ctx.Written() { return @@ -954,7 +958,8 @@ func stopTimerIfAvailable(user *models.User, issue *models.Issue) error { } // CompareAndPullRequestPost response for creating pull request -func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm) { +func CompareAndPullRequestPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateIssueForm) ctx.Data["Title"] = ctx.Tr("repo.pulls.compare_changes") ctx.Data["PageIsComparePull"] = true ctx.Data["IsDiffCompare"] = true @@ -974,7 +979,7 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm) } defer headGitRepo.Close() - labelIDs, assigneeIDs, milestoneID, _ := ValidateRepoMetas(ctx, form, true) + labelIDs, assigneeIDs, milestoneID, _ := ValidateRepoMetas(ctx, *form, true) if ctx.Written() { return } @@ -984,7 +989,7 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm) } if ctx.HasError() { - auth.AssignForm(form, ctx.Data) + middlewares.AssignForm(form, ctx.Data) // This stage is already stop creating new pull request, so it does not matter if it has // something to compare or not. diff --git a/routers/repo/pull_review.go b/routers/repo/pull_review.go index 0bacc682324b3..df49b6cfe126e 100644 --- a/routers/repo/pull_review.go +++ b/routers/repo/pull_review.go @@ -8,10 +8,11 @@ import ( "fmt" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/web" pull_service "code.gitea.io/gitea/services/pull" ) @@ -44,7 +45,8 @@ func RenderNewCodeCommentForm(ctx *context.Context) { } // CreateCodeComment will create a code comment including an pending review if required -func CreateCodeComment(ctx *context.Context, form auth.CodeCommentForm) { +func CreateCodeComment(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CodeCommentForm) issue := GetActionIssue(ctx) if !issue.IsPull { return @@ -171,7 +173,8 @@ func renderConversation(ctx *context.Context, comment *models.Comment) { } // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist -func SubmitReview(ctx *context.Context, form auth.SubmitReviewForm) { +func SubmitReview(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.SubmitReviewForm) issue := GetActionIssue(ctx) if !issue.IsPull { return diff --git a/routers/repo/release.go b/routers/repo/release.go index 4d75c37c87640..54642f9b210a0 100644 --- a/routers/repo/release.go +++ b/routers/repo/release.go @@ -9,14 +9,15 @@ import ( "fmt" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/upload" + "code.gitea.io/gitea/modules/web" releaseservice "code.gitea.io/gitea/services/release" ) @@ -230,7 +231,8 @@ func NewRelease(ctx *context.Context) { } // NewReleasePost response for creating a release -func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) { +func NewReleasePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewReleaseForm) ctx.Data["Title"] = ctx.Tr("repo.release.new_release") ctx.Data["PageIsReleaseList"] = true @@ -336,7 +338,8 @@ func EditRelease(ctx *context.Context) { } // EditReleasePost response for edit release -func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) { +func EditReleasePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.EditReleaseForm) ctx.Data["Title"] = ctx.Tr("repo.release.edit_release") ctx.Data["PageIsReleaseList"] = true ctx.Data["PageIsEditRelease"] = true diff --git a/routers/repo/release_test.go b/routers/repo/release_test.go index 47d1a89b54a06..38c0d9fec01ba 100644 --- a/routers/repo/release_test.go +++ b/routers/repo/release_test.go @@ -8,8 +8,9 @@ import ( "testing" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/web" ) func TestNewReleasePost(t *testing.T) { @@ -48,7 +49,8 @@ func TestNewReleasePost(t *testing.T) { test.LoadUser(t, ctx, 2) test.LoadRepo(t, ctx, 1) test.LoadGitRepo(t, ctx) - NewReleasePost(ctx, testCase.Form) + web.SetForm(ctx, &testCase.Form) + NewReleasePost(ctx) models.AssertExistsAndLoadBean(t, &models.Release{ RepoID: 1, PublisherID: 2, diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 3832b8997170d..a8cfb9ad7c9b0 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -11,11 +11,12 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" archiver_service "code.gitea.io/gitea/services/archiver" repo_service "code.gitea.io/gitea/services/repository" ) @@ -181,7 +182,8 @@ func handleCreateError(ctx *context.Context, owner *models.User, err error, name } // CreatePost response for creating repository -func CreatePost(ctx *context.Context, form auth.CreateRepoForm) { +func CreatePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.CreateRepoForm) ctx.Data["Title"] = ctx.Tr("new_repo") ctx.Data["Gitignores"] = models.Gitignores diff --git a/routers/repo/setting.go b/routers/repo/setting.go index 368879234bcde..3e22e8804e5d5 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -15,9 +15,9 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/repository" @@ -25,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/validation" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" "code.gitea.io/gitea/services/mailer" mirror_service "code.gitea.io/gitea/services/mirror" @@ -59,7 +60,8 @@ func Settings(ctx *context.Context) { } // SettingsPost response for changes of a repository -func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { +func SettingsPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.RepoSettingForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsOptions"] = true @@ -839,7 +841,8 @@ func DeployKeys(ctx *context.Context) { } // DeployKeysPost response for adding a deploy key of a repository -func DeployKeysPost(ctx *context.Context, form auth.AddKeyForm) { +func DeployKeysPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AddKeyForm) ctx.Data["Title"] = ctx.Tr("repo.settings.deploy_keys") ctx.Data["PageIsSettingsKeys"] = true @@ -956,9 +959,10 @@ func UpdateAvatarSetting(ctx *context.Context, form auth.AvatarForm) error { } // SettingsAvatar save new POSTed repository avatar -func SettingsAvatar(ctx *context.Context, form auth.AvatarForm) { +func SettingsAvatar(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AvatarForm) form.Source = auth.AvatarLocal - if err := UpdateAvatarSetting(ctx, form); err != nil { + if err := UpdateAvatarSetting(ctx, *form); err != nil { ctx.Flash.Error(err.Error()) } else { ctx.Flash.Success(ctx.Tr("repo.settings.update_avatar_success")) diff --git a/routers/repo/setting_protected_branch.go b/routers/repo/setting_protected_branch.go index c2e7bc8fac77a..017054d4c273c 100644 --- a/routers/repo/setting_protected_branch.go +++ b/routers/repo/setting_protected_branch.go @@ -10,12 +10,13 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" pull_service "code.gitea.io/gitea/services/pull" ) @@ -168,7 +169,8 @@ func SettingsProtectedBranch(c *context.Context) { } // SettingsProtectedBranchPost updates the protected branch settings -func SettingsProtectedBranchPost(ctx *context.Context, f auth.ProtectBranchForm) { +func SettingsProtectedBranchPost(ctx *context.Context) { + f := web.GetForm(ctx).(*auth.ProtectBranchForm) branch := ctx.Params("*") if !ctx.Repo.GitRepo.IsBranchExist(branch) { ctx.NotFound("IsBranchExist", nil) diff --git a/routers/repo/settings_test.go b/routers/repo/settings_test.go index 679bb0d33ce10..85515121c7836 100644 --- a/routers/repo/settings_test.go +++ b/routers/repo/settings_test.go @@ -10,11 +10,12 @@ import ( "testing" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "github.com/stretchr/testify/assert" ) @@ -52,7 +53,8 @@ func TestAddReadOnlyDeployKey(t *testing.T) { Title: "read-only", Content: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n", } - DeployKeysPost(ctx, addKeyForm) + web.SetForm(ctx, &addKeyForm) + DeployKeysPost(ctx) assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) models.AssertExistsAndLoadBean(t, &models.DeployKey{ @@ -81,7 +83,8 @@ func TestAddReadWriteOnlyDeployKey(t *testing.T) { Content: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n", IsWritable: true, } - DeployKeysPost(ctx, addKeyForm) + web.SetForm(ctx, &addKeyForm) + DeployKeysPost(ctx) assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) models.AssertExistsAndLoadBean(t, &models.DeployKey{ diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 5d7074b339f38..01d142843f929 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -13,14 +13,15 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/webhook" ) @@ -181,7 +182,8 @@ func ParseHookEvent(form auth.WebhookForm) *models.HookEvent { } // GiteaHooksNewPost response for creating Gitea webhook -func GiteaHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { +func GiteaHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewWebhookForm) ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -230,8 +232,9 @@ func GiteaHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { } // GogsHooksNewPost response for creating webhook -func GogsHooksNewPost(ctx *context.Context, form auth.NewGogshookForm) { - newGogsWebhookPost(ctx, form, models.GOGS) +func GogsHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewGogshookForm) + newGogsWebhookPost(ctx, *form, models.GOGS) } // newGogsWebhookPost response for creating gogs hook @@ -283,7 +286,8 @@ func newGogsWebhookPost(ctx *context.Context, form auth.NewGogshookForm, kind mo } // DiscordHooksNewPost response for creating discord hook -func DiscordHooksNewPost(ctx *context.Context, form auth.NewDiscordHookForm) { +func DiscordHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewDiscordHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -334,7 +338,8 @@ func DiscordHooksNewPost(ctx *context.Context, form auth.NewDiscordHookForm) { } // DingtalkHooksNewPost response for creating dingtalk hook -func DingtalkHooksNewPost(ctx *context.Context, form auth.NewDingtalkHookForm) { +func DingtalkHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewDingtalkHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -376,7 +381,8 @@ func DingtalkHooksNewPost(ctx *context.Context, form auth.NewDingtalkHookForm) { } // TelegramHooksNewPost response for creating telegram hook -func TelegramHooksNewPost(ctx *context.Context, form auth.NewTelegramHookForm) { +func TelegramHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewTelegramHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -427,7 +433,8 @@ func TelegramHooksNewPost(ctx *context.Context, form auth.NewTelegramHookForm) { } // MatrixHooksNewPost response for creating a Matrix hook -func MatrixHooksNewPost(ctx *context.Context, form auth.NewMatrixHookForm) { +func MatrixHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewMatrixHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -481,7 +488,8 @@ func MatrixHooksNewPost(ctx *context.Context, form auth.NewMatrixHookForm) { } // MSTeamsHooksNewPost response for creating MS Teams hook -func MSTeamsHooksNewPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { +func MSTeamsHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewMSTeamsHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -523,7 +531,8 @@ func MSTeamsHooksNewPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { } // SlackHooksNewPost response for creating slack hook -func SlackHooksNewPost(ctx *context.Context, form auth.NewSlackHookForm) { +func SlackHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewSlackHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -582,7 +591,8 @@ func SlackHooksNewPost(ctx *context.Context, form auth.NewSlackHookForm) { } // FeishuHooksNewPost response for creating feishu hook -func FeishuHooksNewPost(ctx *context.Context, form auth.NewFeishuHookForm) { +func FeishuHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewFeishuHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -685,7 +695,8 @@ func WebHooksEdit(ctx *context.Context) { } // WebHooksEditPost response for editing web hook -func WebHooksEditPost(ctx *context.Context, form auth.NewWebhookForm) { +func WebHooksEditPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewWebhookForm) ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true @@ -725,7 +736,8 @@ func WebHooksEditPost(ctx *context.Context, form auth.NewWebhookForm) { } // GogsHooksEditPost response for editing gogs hook -func GogsHooksEditPost(ctx *context.Context, form auth.NewGogshookForm) { +func GogsHooksEditPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewGogshookForm) ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true @@ -764,7 +776,8 @@ func GogsHooksEditPost(ctx *context.Context, form auth.NewGogshookForm) { } // SlackHooksEditPost response for editing slack hook -func SlackHooksEditPost(ctx *context.Context, form auth.NewSlackHookForm) { +func SlackHooksEditPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewSlackHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true @@ -814,7 +827,8 @@ func SlackHooksEditPost(ctx *context.Context, form auth.NewSlackHookForm) { } // DiscordHooksEditPost response for editing discord hook -func DiscordHooksEditPost(ctx *context.Context, form auth.NewDiscordHookForm) { +func DiscordHooksEditPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewDiscordHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true @@ -856,7 +870,8 @@ func DiscordHooksEditPost(ctx *context.Context, form auth.NewDiscordHookForm) { } // DingtalkHooksEditPost response for editing discord hook -func DingtalkHooksEditPost(ctx *context.Context, form auth.NewDingtalkHookForm) { +func DingtalkHooksEditPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewDingtalkHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true @@ -888,7 +903,8 @@ func DingtalkHooksEditPost(ctx *context.Context, form auth.NewDingtalkHookForm) } // TelegramHooksEditPost response for editing discord hook -func TelegramHooksEditPost(ctx *context.Context, form auth.NewTelegramHookForm) { +func TelegramHooksEditPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewTelegramHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true @@ -928,7 +944,8 @@ func TelegramHooksEditPost(ctx *context.Context, form auth.NewTelegramHookForm) } // MatrixHooksEditPost response for editing a Matrix hook -func MatrixHooksEditPost(ctx *context.Context, form auth.NewMatrixHookForm) { +func MatrixHooksEditPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewMatrixHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true @@ -971,7 +988,8 @@ func MatrixHooksEditPost(ctx *context.Context, form auth.NewMatrixHookForm) { } // MSTeamsHooksEditPost response for editing MS Teams hook -func MSTeamsHooksEditPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { +func MSTeamsHooksEditPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewMSTeamsHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true @@ -1003,7 +1021,8 @@ func MSTeamsHooksEditPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { } // FeishuHooksEditPost response for editing feishu hook -func FeishuHooksEditPost(ctx *context.Context, form auth.NewFeishuHookForm) { +func FeishuHooksEditPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewFeishuHookForm) ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true diff --git a/routers/repo/wiki.go b/routers/repo/wiki.go index ac650d3fc4504..c4521a3071a30 100644 --- a/routers/repo/wiki.go +++ b/routers/repo/wiki.go @@ -13,15 +13,16 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" wiki_service "code.gitea.io/gitea/services/wiki" ) @@ -556,7 +557,8 @@ func NewWiki(ctx *context.Context) { } // NewWikiPost response for wiki create request -func NewWikiPost(ctx *context.Context, form auth.NewWikiForm) { +func NewWikiPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewWikiForm) ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page") ctx.Data["PageIsWiki"] = true ctx.Data["RequireSimpleMDE"] = true @@ -613,7 +615,8 @@ func EditWiki(ctx *context.Context) { } // EditWikiPost response for wiki modify request -func EditWikiPost(ctx *context.Context, form auth.NewWikiForm) { +func EditWikiPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewWikiForm) ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page") ctx.Data["PageIsWiki"] = true ctx.Data["RequireSimpleMDE"] = true diff --git a/routers/repo/wiki_test.go b/routers/repo/wiki_test.go index cc79c808f5424..badd07f080761 100644 --- a/routers/repo/wiki_test.go +++ b/routers/repo/wiki_test.go @@ -10,9 +10,10 @@ import ( "testing" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/web" wiki_service "code.gitea.io/gitea/services/wiki" "github.com/stretchr/testify/assert" @@ -114,11 +115,12 @@ func TestNewWikiPost(t *testing.T) { ctx := test.MockContext(t, "user2/repo1/wiki/_new") test.LoadUser(t, ctx, 2) test.LoadRepo(t, ctx, 1) - NewWikiPost(ctx, auth.NewWikiForm{ + web.SetForm(ctx, &auth.NewWikiForm{ Title: title, Content: content, Message: message, }) + NewWikiPost(ctx) assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) assertWikiExists(t, ctx.Repo.Repository, title) assert.Equal(t, wikiContent(t, ctx.Repo.Repository, title), content) @@ -131,11 +133,12 @@ func TestNewWikiPost_ReservedName(t *testing.T) { ctx := test.MockContext(t, "user2/repo1/wiki/_new") test.LoadUser(t, ctx, 2) test.LoadRepo(t, ctx, 1) - NewWikiPost(ctx, auth.NewWikiForm{ + web.SetForm(ctx, &auth.NewWikiForm{ Title: "_edit", Content: content, Message: message, }) + NewWikiPost(ctx) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) assert.EqualValues(t, ctx.Tr("repo.wiki.reserved_page"), ctx.Flash.ErrorMsg) assertWikiNotExists(t, ctx.Repo.Repository, "_edit") @@ -164,11 +167,12 @@ func TestEditWikiPost(t *testing.T) { ctx.SetParams(":page", "Home") test.LoadUser(t, ctx, 2) test.LoadRepo(t, ctx, 1) - EditWikiPost(ctx, auth.NewWikiForm{ + web.SetForm(ctx, &auth.NewWikiForm{ Title: title, Content: content, Message: message, }) + EditWikiPost(ctx) assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) assertWikiExists(t, ctx.Repo.Repository, title) assert.Equal(t, wikiContent(t, ctx.Repo.Repository, title), content) diff --git a/routers/routes/chi.go b/routers/routes/base.go similarity index 53% rename from routers/routes/chi.go rename to routers/routes/base.go index 2400140ae6706..a313032a88a6d 100644 --- a/routers/routes/chi.go +++ b/routers/routes/base.go @@ -16,19 +16,16 @@ import ( "text/template" "time" + "code.gitea.io/gitea/modules/auth/sso" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/metrics" - "code.gitea.io/gitea/modules/public" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" - "code.gitea.io/gitea/routers" + "code.gitea.io/gitea/modules/templates" "gitea.com/go-chi/session" - "github.com/go-chi/chi" - "github.com/go-chi/chi/middleware" - "github.com/prometheus/client_golang/prometheus" ) type routerLoggerOptions struct { @@ -39,20 +36,21 @@ type routerLoggerOptions struct { } // SignedUserName returns signed user's name via context -// FIXME currently no any data stored on chi.Context but macaron.Context, so this will -// return "" before we remove macaron totally func SignedUserName(req *http.Request) string { - if v, ok := req.Context().Value("SignedUserName").(string); ok { - return v + ctx := context.GetContext(req) + if ctx != nil { + v := ctx.Data["SignedUserName"] + if res, ok := v.(string); ok { + return res + } } return "" } -func setupAccessLogger(c chi.Router) { +func accessLogger() func(http.Handler) http.Handler { logger := log.GetLogger("access") - logTemplate, _ := template.New("log").Parse(setting.AccessLogTemplate) - c.Use(func(next http.Handler) http.Handler { + return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { start := time.Now() next.ServeHTTP(w, req) @@ -70,15 +68,15 @@ func setupAccessLogger(c chi.Router) { ResponseWriter: rw, }) if err != nil { - log.Error("Could not set up macaron access logger: %v", err.Error()) + log.Error("Could not set up chi access logger: %v", err.Error()) } err = logger.SendLog(log.INFO, "", "", 0, buf.String(), "") if err != nil { - log.Error("Could not set up macaron access logger: %v", err.Error()) + log.Error("Could not set up chi access logger: %v", err.Error()) } }) - }) + } } // LoggerHandler is a handler that will log the routing to the default gitea log @@ -179,131 +177,70 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor } } -var ( - sessionManager *session.Manager -) - -// NewChi creates a chi Router -func NewChi() chi.Router { - c := chi.NewRouter() - c.Use(func(next http.Handler) http.Handler { - return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - next.ServeHTTP(context.NewResponse(resp), req) - }) - }) - c.Use(middleware.RealIP) - if !setting.DisableRouterLog && setting.RouterLogLevel != log.NONE { - if log.GetLogger("router").GetLevel() <= setting.RouterLogLevel { - c.Use(LoggerHandler(setting.RouterLogLevel)) - } - } - - var opt = session.Options{ - Provider: setting.SessionConfig.Provider, - ProviderConfig: setting.SessionConfig.ProviderConfig, - CookieName: setting.SessionConfig.CookieName, - CookiePath: setting.SessionConfig.CookiePath, - Gclifetime: setting.SessionConfig.Gclifetime, - Maxlifetime: setting.SessionConfig.Maxlifetime, - Secure: setting.SessionConfig.Secure, - Domain: setting.SessionConfig.Domain, - } - opt = session.PrepareOptions([]session.Options{opt}) - - var err error - sessionManager, err = session.NewManager(opt.Provider, opt) - if err != nil { - panic(err) - } - - c.Use(Recovery()) - if setting.EnableAccessLog { - setupAccessLogger(c) - } - - c.Use(public.Custom( - &public.Options{ - SkipLogging: setting.DisableRouterLog, - }, - )) - c.Use(public.Static( - &public.Options{ - Directory: path.Join(setting.StaticRootPath, "public"), - SkipLogging: setting.DisableRouterLog, - }, - )) - - c.Use(storageHandler(setting.Avatar.Storage, "avatars", storage.Avatars)) - c.Use(storageHandler(setting.RepoAvatar.Storage, "repo-avatars", storage.RepoAvatars)) - - return c +type dataStore struct { + Data map[string]interface{} } -// RegisterInstallRoute registers the install routes -func RegisterInstallRoute(c chi.Router) { - m := NewMacaron() - RegisterMacaronInstallRoute(m) - - // We need at least one handler in chi so that it does not drop - // our middleware: https://github.com/go-gitea/gitea/issues/13725#issuecomment-735244395 - c.Get("/", func(w http.ResponseWriter, req *http.Request) { - m.ServeHTTP(w, req) - }) - - c.NotFound(func(w http.ResponseWriter, req *http.Request) { - m.ServeHTTP(w, req) - }) - - c.MethodNotAllowed(func(w http.ResponseWriter, req *http.Request) { - m.ServeHTTP(w, req) - }) +func (d *dataStore) GetData() map[string]interface{} { + return d.Data } -// NormalRoutes represents non install routes -func NormalRoutes() http.Handler { - r := chi.NewRouter() +// Recovery returns a middleware that recovers from any panics and writes a 500 and a log if so. +// This error will be created with the gitea 500 page. +func Recovery() func(next http.Handler) http.Handler { + var rnd = templates.HTMLRenderer() + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + defer func() { + if err := recover(); err != nil { + combinedErr := fmt.Sprintf("PANIC: %v\n%s", err, string(log.Stack(2))) + log.Error("%v", combinedErr) + + sessionStore := session.GetSession(req) + if sessionStore == nil { + if setting.IsProd() { + http.Error(w, http.StatusText(500), 500) + } else { + http.Error(w, combinedErr, 500) + } + return + } - // for health check - r.Head("/", func(w http.ResponseWriter, req *http.Request) { - w.WriteHeader(http.StatusOK) - }) + var lc = middlewares.Locale(w, req) + var store = dataStore{ + Data: templates.Vars{ + "Language": lc.Language(), + "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), + "i18n": lc, + }, + } - if setting.HasRobotsTxt { - r.Get("/robots.txt", func(w http.ResponseWriter, req *http.Request) { - filePath := path.Join(setting.CustomPath, "robots.txt") - fi, err := os.Stat(filePath) - if err == nil && httpcache.HandleTimeCache(req, w, fi) { - return - } - http.ServeFile(w, req, filePath) - }) - } + // Get user from session if logged in. + user, _ := sso.SignedInUser(req, w, &store, sessionStore) + if user != nil { + store.Data["IsSigned"] = true + store.Data["SignedUser"] = user + store.Data["SignedUserID"] = user.ID + store.Data["SignedUserName"] = user.Name + store.Data["IsAdmin"] = user.IsAdmin + } else { + store.Data["SignedUserID"] = int64(0) + store.Data["SignedUserName"] = "" + } - r.Get("/apple-touch-icon.png", func(w http.ResponseWriter, req *http.Request) { - http.Redirect(w, req, path.Join(setting.StaticURLPrefix, "img/apple-touch-icon.png"), 301) - }) + w.Header().Set(`X-Frame-Options`, `SAMEORIGIN`) - // prometheus metrics endpoint - if setting.Metrics.Enabled { - c := metrics.NewCollector() - prometheus.MustRegister(c) + if !setting.IsProd() { + store.Data["ErrorMsg"] = combinedErr + } + err = rnd.HTML(w, 500, "status/500", templates.BaseVars().Merge(store.Data)) + if err != nil { + log.Error("%v", err) + } + } + }() - r.Get("/metrics", routers.Metrics) + next.ServeHTTP(w, req) + }) } - - return r -} - -// DelegateToMacaron delegates other routes to macaron -func DelegateToMacaron(r chi.Router) { - m := NewMacaron() - RegisterMacaronRoutes(m) - - r.NotFound(func(w http.ResponseWriter, req *http.Request) { - m.ServeHTTP(w, req) - }) - - r.MethodNotAllowed(func(w http.ResponseWriter, req *http.Request) { - m.ServeHTTP(w, req) - }) } diff --git a/routers/routes/recovery.go b/routers/routes/install.go similarity index 50% rename from routers/routes/recovery.go rename to routers/routes/install.go index cfe1a4114cad6..0dc066d6000f9 100644 --- a/routers/routes/recovery.go +++ b/routers/routes/install.go @@ -7,38 +7,23 @@ package routes import ( "fmt" "net/http" + "path" - "code.gitea.io/gitea/modules/auth/sso" + "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/middlewares" + "code.gitea.io/gitea/modules/public" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/routers" - "github.com/unrolled/render" + "gitea.com/go-chi/session" ) -type dataStore struct { - Data map[string]interface{} -} - -func (d *dataStore) GetData() map[string]interface{} { - return d.Data -} - -// Recovery returns a middleware that recovers from any panics and writes a 500 and a log if so. -// Although similar to macaron.Recovery() the main difference is that this error will be created -// with the gitea 500 page. -func Recovery() func(next http.Handler) http.Handler { +func installRecovery() func(next http.Handler) http.Handler { + var rnd = templates.HTMLRenderer() return func(next http.Handler) http.Handler { - rnd := render.New(render.Options{ - Extensions: []string{".tmpl"}, - Directory: "templates", - Funcs: templates.NewFuncMap(), - Asset: templates.GetAsset, - AssetNames: templates.GetAssetNames, - IsDevelopment: !setting.IsProd(), - }) - return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { defer func() { // Why we need this? The first recover will try to render a beautiful @@ -62,35 +47,16 @@ func Recovery() func(next http.Handler) http.Handler { log.Error("%v", combinedErr) lc := middlewares.Locale(w, req) - - // TODO: this should be replaced by real session after macaron removed totally - sessionStore, err := sessionManager.Start(w, req) - if err != nil { - // Just invoke the above recover catch - panic("session(start): " + err.Error()) - } - var store = dataStore{ Data: templates.Vars{ - "Language": lc.Language(), - "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), - "i18n": lc, + "Language": lc.Language(), + "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), + "i18n": lc, + "SignedUserID": int64(0), + "SignedUserName": "", }, } - // Get user from session if logged in. - user, _ := sso.SignedInUser(req, w, &store, sessionStore) - if user != nil { - store.Data["IsSigned"] = true - store.Data["SignedUser"] = user - store.Data["SignedUserID"] = user.ID - store.Data["SignedUserName"] = user.Name - store.Data["IsAdmin"] = user.IsAdmin - } else { - store.Data["SignedUserID"] = int64(0) - store.Data["SignedUserName"] = "" - } - w.Header().Set(`X-Frame-Options`, `SAMEORIGIN`) if !setting.IsProd() { @@ -107,3 +73,44 @@ func Recovery() func(next http.Handler) http.Handler { }) } } + +// InstallRoutes registers the install routes +func InstallRoutes() *web.Route { + r := web.NewRoute() + for _, middle := range commonMiddlewares() { + r.Use(middle) + } + + r.Use(session.Sessioner(session.Options{ + Provider: setting.SessionConfig.Provider, + ProviderConfig: setting.SessionConfig.ProviderConfig, + CookieName: setting.SessionConfig.CookieName, + CookiePath: setting.SessionConfig.CookiePath, + Gclifetime: setting.SessionConfig.Gclifetime, + Maxlifetime: setting.SessionConfig.Maxlifetime, + Secure: setting.SessionConfig.Secure, + Domain: setting.SessionConfig.Domain, + })) + + r.Use(installRecovery()) + + r.Use(public.Custom( + &public.Options{ + SkipLogging: setting.DisableRouterLog, + }, + )) + r.Use(public.Static( + &public.Options{ + Directory: path.Join(setting.StaticRootPath, "public"), + SkipLogging: setting.DisableRouterLog, + }, + )) + + r.Use(routers.InstallInit) + r.Get("/", routers.Install) + r.Post("/", web.Bind(forms.InstallForm{}), routers.InstallPost) + r.NotFound(func(w http.ResponseWriter, req *http.Request) { + http.Redirect(w, req, setting.AppURL, 302) + }) + return r +} diff --git a/routers/routes/macaron.go b/routers/routes/web.go similarity index 70% rename from routers/routes/macaron.go rename to routers/routes/web.go index f64a0a597b584..24336185817f0 100644 --- a/routers/routes/macaron.go +++ b/routers/routes/web.go @@ -6,19 +6,29 @@ package routes import ( "encoding/gob" + "fmt" + "net/http" + "os" + "path" + "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" + "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/options" + "code.gitea.io/gitea/modules/metrics" + "code.gitea.io/gitea/modules/public" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/validation" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers" "code.gitea.io/gitea/routers/admin" apiv1 "code.gitea.io/gitea/routers/api/v1" + "code.gitea.io/gitea/routers/api/v1/misc" "code.gitea.io/gitea/routers/dev" "code.gitea.io/gitea/routers/events" "code.gitea.io/gitea/routers/org" @@ -31,77 +41,79 @@ import ( // to registers all internal adapters _ "code.gitea.io/gitea/modules/session" - "gitea.com/macaron/binding" - "gitea.com/macaron/cache" - "gitea.com/macaron/captcha" - "gitea.com/macaron/cors" - "gitea.com/macaron/csrf" - "gitea.com/macaron/gzip" - "gitea.com/macaron/i18n" - "gitea.com/macaron/macaron" - "gitea.com/macaron/session" - "gitea.com/macaron/toolbox" + "gitea.com/go-chi/captcha" + "gitea.com/go-chi/session" + "github.com/NYTimes/gziphandler" + "github.com/go-chi/chi/middleware" + "github.com/prometheus/client_golang/prometheus" "github.com/tstranex/u2f" ) -// NewMacaron initializes Macaron instance. -func NewMacaron() *macaron.Macaron { - gob.Register(&u2f.Challenge{}) - var m *macaron.Macaron - if setting.RedirectMacaronLog { - loggerAsWriter := log.NewLoggerAsWriter("INFO", log.GetLogger("macaron")) - m = macaron.NewWithLogger(loggerAsWriter) - } else { - m = macaron.New() - } +const ( + // GzipMinSize represents min size to compress for the body size of response + GzipMinSize = 1400 +) - if setting.EnableGzip { - m.Use(gzip.Middleware()) +func commonMiddlewares() []func(http.Handler) http.Handler { + var handlers = []func(http.Handler) http.Handler{ + func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + next.ServeHTTP(context.NewResponse(resp), req) + }) + }, + middleware.RealIP, } - if setting.Protocol == setting.FCGI || setting.Protocol == setting.FCGIUnix { - m.SetURLPrefix(setting.AppSubURL) + if !setting.DisableRouterLog && setting.RouterLogLevel != log.NONE { + if log.GetLogger("router").GetLevel() <= setting.RouterLogLevel { + handlers = append(handlers, LoggerHandler(setting.RouterLogLevel)) + } } + handlers = append(handlers, func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + // Why we need this? The Recovery() will try to render a beautiful + // error page for user, but the process can still panic again, and other + // middleware like session also may panic then we have to recover twice + // and send a simple error page that should not panic any more. + defer func() { + if err := recover(); err != nil { + combinedErr := fmt.Sprintf("PANIC: %v\n%s", err, string(log.Stack(2))) + log.Error("%v", combinedErr) + if setting.IsProd() { + http.Error(resp, http.StatusText(500), 500) + } else { + http.Error(resp, combinedErr, 500) + } + } + }() + next.ServeHTTP(resp, req) + }) + }) - m.Use(templates.HTMLRenderer()) - - mailer.InitMailRender(templates.Mailer()) - - localeNames, err := options.Dir("locale") - - if err != nil { - log.Fatal("Failed to list locale files: %v", err) + if setting.EnableAccessLog { + handlers = append(handlers, accessLogger()) } + return handlers +} - localFiles := make(map[string][]byte) +// NormalRoutes represents non install routes +func NormalRoutes() *web.Route { + r := web.NewRoute() + for _, middle := range commonMiddlewares() { + r.Use(middle) + } + r.Use(Recovery()) - for _, name := range localeNames { - localFiles[name], err = options.Locale(name) + r.Mount("/", WebRoutes()) + r.Mount("/api/v1", apiv1.Routes()) + r.Mount("/api/internal", private.Routes()) + return r +} - if err != nil { - log.Fatal("Failed to load %s locale file. %v", name, err) - } - } +// WebRoutes returns all web routes +func WebRoutes() *web.Route { + r := web.NewRoute() - m.Use(i18n.I18n(i18n.Options{ - SubURL: setting.AppSubURL, - Files: localFiles, - Langs: setting.Langs, - Names: setting.Names, - DefaultLang: "en-US", - Redirect: false, - CookieHttpOnly: true, - Secure: setting.SessionConfig.Secure, - CookieDomain: setting.SessionConfig.Domain, - })) - m.Use(cache.Cacher(cache.Options{ - Adapter: setting.CacheService.Adapter, - AdapterConfig: setting.CacheService.Conn, - Interval: setting.CacheService.Interval, - })) - m.Use(captcha.Captchaer(captcha.Options{ - SubURL: setting.AppSubURL, - })) - m.Use(session.Sessioner(session.Options{ + r.Use(session.Sessioner(session.Options{ Provider: setting.SessionConfig.Provider, ProviderConfig: setting.SessionConfig.ProviderConfig, CookieName: setting.SessionConfig.CookieName, @@ -111,47 +123,104 @@ func NewMacaron() *macaron.Macaron { Secure: setting.SessionConfig.Secure, Domain: setting.SessionConfig.Domain, })) - m.Use(csrf.Csrfer(csrf.Options{ - Secret: setting.SecretKey, - Cookie: setting.CSRFCookieName, - SetCookie: true, - Secure: setting.SessionConfig.Secure, - CookieHttpOnly: setting.CSRFCookieHTTPOnly, - Header: "X-Csrf-Token", - CookieDomain: setting.SessionConfig.Domain, - CookiePath: setting.AppSubURL, - })) - m.Use(toolbox.Toolboxer(m, toolbox.Options{ - HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{ - { - Desc: "Database connection", - Func: models.Ping, - }, + + r.Use(public.Custom( + &public.Options{ + SkipLogging: setting.DisableRouterLog, }, - DisableDebug: !setting.EnablePprof, - })) - m.Use(context.Contexter()) - m.SetAutoHead(true) - return m -} + )) + r.Use(public.Static( + &public.Options{ + Directory: path.Join(setting.StaticRootPath, "public"), + SkipLogging: setting.DisableRouterLog, + }, + )) + + r.Use(storageHandler(setting.Avatar.Storage, "avatars", storage.Avatars)) + r.Use(storageHandler(setting.RepoAvatar.Storage, "repo-avatars", storage.RepoAvatars)) -// RegisterMacaronInstallRoute registers the install routes -func RegisterMacaronInstallRoute(m *macaron.Macaron) { - m.Combo("/", routers.InstallInit).Get(routers.Install). - Post(binding.BindIgnErr(auth.InstallForm{}), routers.InstallPost) - m.NotFound(func(ctx *context.Context) { - ctx.Redirect(setting.AppURL, 302) + gob.Register(&u2f.Challenge{}) + + if setting.EnableGzip { + h, err := gziphandler.GzipHandlerWithOpts(gziphandler.MinSize(GzipMinSize)) + if err != nil { + log.Fatal("GzipHandlerWithOpts failed: %v", err) + } + r.Use(h) + } + + if (setting.Protocol == setting.FCGI || setting.Protocol == setting.FCGIUnix) && setting.AppSubURL != "" { + r.Use(func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + req.URL.Path = strings.TrimPrefix(req.URL.Path, setting.AppSubURL) + next.ServeHTTP(resp, req) + }) + }) + } + + mailer.InitMailRender(templates.Mailer()) + + r.Use(captcha.Captchaer(context.GetImageCaptcha())) + // Removed: toolbox.Toolboxer middleware will provide debug informations which seems unnecessary + r.Use(context.Contexter()) + // Removed: SetAutoHead allow a get request redirect to head if get method is not exist + + r.Use(user.GetNotificationCount) + r.Use(repo.GetActiveStopwatch) + r.Use(func(ctx *context.Context) { + ctx.Data["UnitWikiGlobalDisabled"] = models.UnitTypeWiki.UnitGlobalDisabled() + ctx.Data["UnitIssuesGlobalDisabled"] = models.UnitTypeIssues.UnitGlobalDisabled() + ctx.Data["UnitPullsGlobalDisabled"] = models.UnitTypePullRequests.UnitGlobalDisabled() + ctx.Data["UnitProjectsGlobalDisabled"] = models.UnitTypeProjects.UnitGlobalDisabled() + }) + + // for health check + r.Head("/", func(w http.ResponseWriter, req *http.Request) { + w.WriteHeader(http.StatusOK) + }) + + if setting.HasRobotsTxt { + r.Get("/robots.txt", func(w http.ResponseWriter, req *http.Request) { + filePath := path.Join(setting.CustomPath, "robots.txt") + fi, err := os.Stat(filePath) + if err == nil && httpcache.HandleTimeCache(req, w, fi) { + return + } + http.ServeFile(w, req, filePath) + }) + } + + r.Get("/apple-touch-icon.png", func(w http.ResponseWriter, req *http.Request) { + http.Redirect(w, req, path.Join(setting.StaticURLPrefix, "img/apple-touch-icon.png"), 301) }) + + // prometheus metrics endpoint + if setting.Metrics.Enabled { + c := metrics.NewCollector() + prometheus.MustRegister(c) + + r.Get("/metrics", routers.Metrics) + } + + if setting.API.EnableSwagger { + // Note: The route moved from apiroutes because it's in fact want to render a web page + r.Get("/api/swagger", misc.Swagger) // Render V1 by default + } + + RegisterRoutes(r) + + return r } -// RegisterMacaronRoutes routes routes to Macaron -func RegisterMacaronRoutes(m *macaron.Macaron) { +// RegisterRoutes routes routes to Macaron +func RegisterRoutes(m *web.Route) { reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true}) ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView}) ignSignInAndCsrf := context.Toggle(&context.ToggleOptions{DisableCSRF: true}) reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true}) - bindIgnErr := binding.BindIgnErr + //bindIgnErr := binding.BindIgnErr + bindIgnErr := web.Bind validation.AddBindingRules() openIDSignInEnabled := func(ctx *context.Context) { @@ -175,15 +244,6 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { } } - m.Use(user.GetNotificationCount) - m.Use(repo.GetActiveStopwatch) - m.Use(func(ctx *context.Context) { - ctx.Data["UnitWikiGlobalDisabled"] = models.UnitTypeWiki.UnitGlobalDisabled() - ctx.Data["UnitIssuesGlobalDisabled"] = models.UnitTypeIssues.UnitGlobalDisabled() - ctx.Data["UnitPullsGlobalDisabled"] = models.UnitTypePullRequests.UnitGlobalDisabled() - ctx.Data["UnitProjectsGlobalDisabled"] = models.UnitTypeProjects.UnitGlobalDisabled() - }) - // FIXME: not all routes need go through same middlewares. // Especially some AJAX requests, we can reduce middleware number to improve performance. // Routers. @@ -198,8 +258,6 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Get("/organizations", routers.ExploreOrganizations) m.Get("/code", routers.ExploreCode) }, ignSignIn) - m.Combo("/install", routers.InstallInit).Get(routers.Install). - Post(bindIgnErr(auth.InstallForm{}), routers.InstallPost) m.Get("/issues", reqSignIn, user.Issues) m.Get("/pulls", reqSignIn, user.Pulls) m.Get("/milestones", reqSignIn, reqMilestonesDashboardPageEnabled, user.Milestones) @@ -226,8 +284,8 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Get("/sign_up", user.SignUp) m.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost) m.Group("/oauth2", func() { - m.Get("/:provider", user.SignInOAuth) - m.Get("/:provider/callback", user.SignInOAuthCallback) + m.Get("/{provider}", user.SignInOAuth) + m.Get("/{provider}/callback", user.SignInOAuthCallback) }) m.Get("/link_account", user.LinkAccount) m.Post("/link_account_signin", bindIgnErr(auth.SignInForm{}), user.LinkAccountPostSignIn) @@ -261,7 +319,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("", bindIgnErr(auth.UpdateProfileForm{}), userSetting.ProfilePost) m.Get("/change_password", user.MustChangePassword) m.Post("/change_password", bindIgnErr(auth.MustChangePasswordForm{}), user.MustChangePasswordPost) - m.Post("/avatar", binding.MultipartForm(auth.AvatarForm{}), userSetting.AvatarPost) + m.Post("/avatar", bindIgnErr(auth.AvatarForm{}), userSetting.AvatarPost) m.Post("/avatar/delete", userSetting.DeleteAvatar) m.Group("/account", func() { m.Combo("").Get(userSetting.Account).Post(bindIgnErr(auth.ChangePasswordForm{}), userSetting.AccountPost) @@ -291,9 +349,9 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("/account_link", userSetting.DeleteAccountLink) }) m.Group("/applications/oauth2", func() { - m.Get("/:id", userSetting.OAuth2ApplicationShow) - m.Post("/:id", bindIgnErr(auth.EditOAuth2ApplicationForm{}), userSetting.OAuthApplicationsEdit) - m.Post("/:id/regenerate_secret", userSetting.OAuthApplicationsRegenerateSecret) + m.Get("/{id}", userSetting.OAuth2ApplicationShow) + m.Post("/{id}", bindIgnErr(auth.EditOAuth2ApplicationForm{}), userSetting.OAuthApplicationsEdit) + m.Post("/{id}/regenerate_secret", userSetting.OAuthApplicationsRegenerateSecret) m.Post("", bindIgnErr(auth.EditOAuth2ApplicationForm{}), userSetting.OAuthApplicationsPost) m.Post("/delete", userSetting.DeleteOAuth2Application) m.Post("/revoke", userSetting.RevokeOAuth2Grant) @@ -316,18 +374,18 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { // r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds) m.Any("/activate", user.Activate, reqSignIn) m.Any("/activate_email", user.ActivateEmail) - m.Get("/avatar/:username/:size", user.Avatar) + m.Get("/avatar/{username}/{size}", user.Avatar) m.Get("/email2user", user.Email2User) m.Get("/recover_account", user.ResetPasswd) m.Post("/recover_account", user.ResetPasswdPost) m.Get("/forgot_password", user.ForgotPasswd) m.Post("/forgot_password", user.ForgotPasswdPost) m.Post("/logout", user.SignOut) - m.Get("/task/:task", user.TaskStatus) + m.Get("/task/{task}", user.TaskStatus) }) // ***** END: User ***** - m.Get("/avatar/:hash", user.AvatarByEmailHash) + m.Get("/avatar/{hash}", user.AvatarByEmailHash) adminReq := context.Toggle(&context.ToggleOptions{SignInRequired: true, AdminRequired: true}) @@ -339,12 +397,12 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("/config/test_mail", admin.SendTestMail) m.Group("/monitor", func() { m.Get("", admin.Monitor) - m.Post("/cancel/:pid", admin.MonitorCancel) - m.Group("/queue/:qid", func() { + m.Post("/cancel/{pid}", admin.MonitorCancel) + m.Group("/queue/{qid}", func() { m.Get("", admin.Queue) m.Post("/set", admin.SetQueueSettings) m.Post("/add", admin.AddWorkers) - m.Post("/cancel/:pid", admin.WorkerCancel) + m.Post("/cancel/{pid}", admin.WorkerCancel) m.Post("/flush", admin.Flush) }) }) @@ -352,8 +410,8 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("/users", func() { m.Get("", admin.Users) m.Combo("/new").Get(admin.NewUser).Post(bindIgnErr(auth.AdminCreateUserForm{}), admin.NewUserPost) - m.Combo("/:userid").Get(admin.EditUser).Post(bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost) - m.Post("/:userid/delete", admin.DeleteUser) + m.Combo("/{userid}").Get(admin.EditUser).Post(bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost) + m.Post("/{userid}/delete", admin.DeleteUser) }) m.Group("/emails", func() { @@ -374,20 +432,20 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("/hooks", func() { m.Get("", admin.DefaultOrSystemWebhooks) m.Post("/delete", admin.DeleteDefaultOrSystemWebhook) - m.Get("/:id", repo.WebHooksEdit) - m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) - m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost) - m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) - m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost) - m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) - m.Post("/telegram/:id", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost) - m.Post("/matrix/:id", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksEditPost) - m.Post("/msteams/:id", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) - m.Post("/feishu/:id", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost) + m.Get("/{id}", repo.WebHooksEdit) + m.Post("/gitea/{id}", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) + m.Post("/gogs/{id}", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost) + m.Post("/slack/{id}", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) + m.Post("/discord/{id}", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost) + m.Post("/dingtalk/{id}", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) + m.Post("/telegram/{id}", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost) + m.Post("/matrix/{id}", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksEditPost) + m.Post("/msteams/{id}", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) + m.Post("/feishu/{id}", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost) }) - m.Group("/^:configType(default-hooks|system-hooks)$", func() { - m.Get("/:type/new", repo.WebhooksNew) + m.Group("/{configType:default-hooks|system-hooks}", func() { + m.Get("/{type}/new", repo.WebhooksNew) m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.GiteaHooksNewPost) m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) @@ -402,9 +460,9 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("/auths", func() { m.Get("", admin.Authentications) m.Combo("/new").Get(admin.NewAuthSource).Post(bindIgnErr(auth.AuthenticationForm{}), admin.NewAuthSourcePost) - m.Combo("/:authid").Get(admin.EditAuthSource). + m.Combo("/{authid}").Get(admin.EditAuthSource). Post(bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost) - m.Post("/:authid/delete", admin.DeleteAuthSource) + m.Post("/{authid}/delete", admin.DeleteAuthSource) }) m.Group("/notices", func() { @@ -416,15 +474,15 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { // ***** END: Admin ***** m.Group("", func() { - m.Get("/:username", user.Profile) - m.Get("/attachments/:uuid", repo.GetAttachment) + m.Get("/{username}", user.Profile) + m.Get("/attachments/{uuid}", repo.GetAttachment) }, ignSignIn) - m.Group("/:username", func() { - m.Post("/action/:action", user.Action) + m.Group("/{username}", func() { + m.Post("/action/{action}", user.Action) }, reqSignIn) - if macaron.Env == macaron.DEV { + if !setting.IsProd() { m.Get("/template/*", dev.TemplatePreview) } @@ -449,44 +507,44 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.CreatePost) }) - m.Group("/:org", func() { + m.Group("/{org}", func() { m.Get("/dashboard", user.Dashboard) - m.Get("/dashboard/:team", user.Dashboard) + m.Get("/dashboard/{team}", user.Dashboard) m.Get("/issues", user.Issues) - m.Get("/issues/:team", user.Issues) + m.Get("/issues/{team}", user.Issues) m.Get("/pulls", user.Pulls) - m.Get("/pulls/:team", user.Pulls) + m.Get("/pulls/{team}", user.Pulls) m.Get("/milestones", reqMilestonesDashboardPageEnabled, user.Milestones) - m.Get("/milestones/:team", reqMilestonesDashboardPageEnabled, user.Milestones) + m.Get("/milestones/{team}", reqMilestonesDashboardPageEnabled, user.Milestones) m.Get("/members", org.Members) - m.Post("/members/action/:action", org.MembersAction) + m.Post("/members/action/{action}", org.MembersAction) m.Get("/teams", org.Teams) }, context.OrgAssignment(true, false, true)) - m.Group("/:org", func() { - m.Get("/teams/:team", org.TeamMembers) - m.Get("/teams/:team/repositories", org.TeamRepositories) - m.Post("/teams/:team/action/:action", org.TeamsAction) - m.Post("/teams/:team/action/repo/:action", org.TeamsRepoAction) + m.Group("/{org}", func() { + m.Get("/teams/{team}", org.TeamMembers) + m.Get("/teams/{team}/repositories", org.TeamRepositories) + m.Post("/teams/{team}/action/{action}", org.TeamsAction) + m.Post("/teams/{team}/action/repo/{action}", org.TeamsRepoAction) }, context.OrgAssignment(true, false, true)) - m.Group("/:org", func() { + m.Group("/{org}", func() { m.Get("/teams/new", org.NewTeam) m.Post("/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost) - m.Get("/teams/:team/edit", org.EditTeam) - m.Post("/teams/:team/edit", bindIgnErr(auth.CreateTeamForm{}), org.EditTeamPost) - m.Post("/teams/:team/delete", org.DeleteTeam) + m.Get("/teams/{team}/edit", org.EditTeam) + m.Post("/teams/{team}/edit", bindIgnErr(auth.CreateTeamForm{}), org.EditTeamPost) + m.Post("/teams/{team}/delete", org.DeleteTeam) m.Group("/settings", func() { m.Combo("").Get(org.Settings). Post(bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost) - m.Post("/avatar", binding.MultipartForm(auth.AvatarForm{}), org.SettingsAvatar) + m.Post("/avatar", bindIgnErr(auth.AvatarForm{}), org.SettingsAvatar) m.Post("/avatar/delete", org.SettingsDeleteAvatar) m.Group("/hooks", func() { m.Get("", org.Webhooks) m.Post("/delete", org.DeleteWebhook) - m.Get("/:type/new", repo.WebhooksNew) + m.Get("/{type}/new", repo.WebhooksNew) m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.GiteaHooksNewPost) m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) @@ -496,16 +554,16 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("/matrix/new", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksNewPost) m.Post("/msteams/new", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) m.Post("/feishu/new", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksNewPost) - m.Get("/:id", repo.WebHooksEdit) - m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) - m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost) - m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) - m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost) - m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) - m.Post("/telegram/:id", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost) - m.Post("/matrix/:id", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksEditPost) - m.Post("/msteams/:id", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) - m.Post("/feishu/:id", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost) + m.Get("/{id}", repo.WebHooksEdit) + m.Post("/gitea/{id}", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) + m.Post("/gogs/{id}", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost) + m.Post("/slack/{id}", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) + m.Post("/discord/{id}", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost) + m.Post("/dingtalk/{id}", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) + m.Post("/telegram/{id}", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost) + m.Post("/matrix/{id}", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksEditPost) + m.Post("/msteams/{id}", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) + m.Post("/feishu/{id}", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost) }) m.Group("/labels", func() { @@ -529,19 +587,19 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Get("/migrate", repo.Migrate) m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost) m.Group("/fork", func() { - m.Combo("/:repoid").Get(repo.Fork). + m.Combo("/{repoid}").Get(repo.Fork). Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost) }, context.RepoIDAssignment(), context.UnitTypes(), reqRepoCodeReader) }, reqSignIn) // ***** Release Attachment Download without Signin - m.Get("/:username/:reponame/releases/download/:vTag/:fileName", ignSignIn, context.RepoAssignment(), repo.MustBeNotEmpty, repo.RedirectDownload) + m.Get("/{username}/{reponame}/releases/download/{vTag}/{fileName}", ignSignIn, context.RepoAssignment(), repo.MustBeNotEmpty, repo.RedirectDownload) - m.Group("/:username/:reponame", func() { + m.Group("/{username}/{reponame}", func() { m.Group("/settings", func() { m.Combo("").Get(repo.Settings). Post(bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost) - m.Post("/avatar", binding.MultipartForm(auth.AvatarForm{}), repo.SettingsAvatar) + m.Post("/avatar", bindIgnErr(auth.AvatarForm{}), repo.SettingsAvatar) m.Post("/avatar/delete", repo.SettingsDeleteAvatar) m.Group("/collaboration", func() { @@ -562,7 +620,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("/hooks", func() { m.Get("", repo.Webhooks) m.Post("/delete", repo.DeleteWebhook) - m.Get("/:type/new", repo.WebhooksNew) + m.Get("/{type}/new", repo.WebhooksNew) m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.GiteaHooksNewPost) m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) @@ -572,21 +630,21 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("/matrix/new", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksNewPost) m.Post("/msteams/new", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) m.Post("/feishu/new", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksNewPost) - m.Get("/:id", repo.WebHooksEdit) - m.Post("/:id/test", repo.TestWebhook) - m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) - m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost) - m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) - m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost) - m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) - m.Post("/telegram/:id", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost) - m.Post("/matrix/:id", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksEditPost) - m.Post("/msteams/:id", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) - m.Post("/feishu/:id", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost) + m.Get("/{id}", repo.WebHooksEdit) + m.Post("/{id}/test", repo.TestWebhook) + m.Post("/gitea/{id}", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) + m.Post("/gogs/{id}", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost) + m.Post("/slack/{id}", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) + m.Post("/discord/{id}", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost) + m.Post("/dingtalk/{id}", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) + m.Post("/telegram/{id}", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost) + m.Post("/matrix/{id}", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksEditPost) + m.Post("/msteams/{id}", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) + m.Post("/feishu/{id}", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost) m.Group("/git", func() { m.Get("", repo.GitHooks) - m.Combo("/:name").Get(repo.GitHooksEdit). + m.Combo("/{name}").Get(repo.GitHooksEdit). Post(repo.GitHooksEditPost) }, context.GitHookService()) }) @@ -598,16 +656,16 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { }) m.Group("/lfs", func() { - m.Get("", repo.LFSFiles) - m.Get("/show/:oid", repo.LFSFileGet) - m.Post("/delete/:oid", repo.LFSDelete) + m.Get("/", repo.LFSFiles) + m.Get("/show/{oid}", repo.LFSFileGet) + m.Post("/delete/{oid}", repo.LFSDelete) m.Get("/pointers", repo.LFSPointerFiles) m.Post("/pointers/associate", repo.LFSAutoAssociate) m.Get("/find", repo.LFSFileFind) m.Group("/locks", func() { m.Get("/", repo.LFSLocks) m.Post("/", repo.LFSLockFile) - m.Post("/:lid/unlock", repo.LFSUnlock) + m.Post("/{lid}/unlock", repo.LFSUnlock) }) }) @@ -617,12 +675,12 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { }) }, reqSignIn, context.RepoAssignment(), context.UnitTypes(), reqRepoAdmin, context.RepoRef()) - m.Post("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action) + m.Post("/{username}/{reponame}/action/{action}", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action) // Grouping for those endpoints not requiring authentication - m.Group("/:username/:reponame", func() { + m.Group("/{username}/{reponame}", func() { m.Group("/milestone", func() { - m.Get("/:id", repo.MilestoneIssuesAndPulls) + m.Get("/{id}", repo.MilestoneIssuesAndPulls) }, reqRepoIssuesOrPullsReader, context.RepoRef()) m.Combo("/compare/*", repo.MustBeNotEmpty, reqRepoCodeReader, repo.SetEditorconfigIfExists). Get(ignSignIn, repo.SetDiffViewStyle, repo.CompareDiff). @@ -630,7 +688,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { }, context.RepoAssignment(), context.UnitTypes()) // Grouping for those endpoints that do require authentication - m.Group("/:username/:reponame", func() { + m.Group("/{username}/{reponame}", func() { m.Group("/issues", func() { m.Group("/new", func() { m.Combo("").Get(context.RepoRef(), repo.NewIssue). @@ -641,7 +699,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { // FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest. // So they can apply their own enable/disable logic on routers. m.Group("/issues", func() { - m.Group("/:index", func() { + m.Group("/{index}", func() { m.Post("/title", repo.UpdateIssueTitle) m.Post("/content", repo.UpdateIssueContent) m.Post("/watch", repo.IssueWatch) @@ -658,13 +716,13 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("/cancel", repo.CancelStopwatch) }) }) - m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeIssueReaction) + m.Post("/reactions/{action}", bindIgnErr(auth.ReactionForm{}), repo.ChangeIssueReaction) m.Post("/lock", reqRepoIssueWriter, bindIgnErr(auth.IssueLockForm{}), repo.LockIssue) m.Post("/unlock", reqRepoIssueWriter, repo.UnlockIssue) }, context.RepoMustNotBeArchived()) - m.Group("/:index", func() { + m.Group("/{index}", func() { m.Get("/attachments", repo.GetIssueAttachments) - m.Get("/attachments/:uuid", repo.GetAttachment) + m.Get("/attachments/{uuid}", repo.GetAttachment) }) m.Post("/labels", reqRepoIssuesOrPullsWriter, repo.UpdateIssueLabel) @@ -677,12 +735,12 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Post("/attachments", repo.UploadIssueAttachment) m.Post("/attachments/remove", repo.DeleteAttachment) }, context.RepoMustNotBeArchived()) - m.Group("/comments/:id", func() { + m.Group("/comments/{id}", func() { m.Post("", repo.UpdateCommentContent) m.Post("/delete", repo.DeleteComment) - m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeCommentReaction) + m.Post("/reactions/{action}", bindIgnErr(auth.ReactionForm{}), repo.ChangeCommentReaction) }, context.RepoMustNotBeArchived()) - m.Group("/comments/:id", func() { + m.Group("/comments/{id}", func() { m.Get("/attachments", repo.GetCommentAttachments) }) m.Group("/labels", func() { @@ -694,13 +752,13 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("/milestones", func() { m.Combo("/new").Get(repo.NewMilestone). Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost) - m.Get("/:id/edit", repo.EditMilestone) - m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost) - m.Post("/:id/:action", repo.ChangeMilestoneStatus) + m.Get("/{id}/edit", repo.EditMilestone) + m.Post("/{id}/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost) + m.Post("/{id}/{action}", repo.ChangeMilestoneStatus) m.Post("/delete", repo.DeleteMilestone) }, context.RepoMustNotBeArchived(), reqRepoIssuesOrPullsWriter, context.RepoRef()) m.Group("/pull", func() { - m.Post("/:index/target_branch", repo.UpdatePullRequestTarget) + m.Post("/{index}/target_branch", repo.UpdatePullRequestTarget) }, context.RepoMustNotBeArchived()) m.Group("", func() { @@ -723,7 +781,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { }, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustBeNotEmpty) m.Group("/branches", func() { - m.Group("/_new/", func() { + m.Group("/_new", func() { m.Post("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.CreateBranch) m.Post("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.CreateBranch) m.Post("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.CreateBranch) @@ -735,14 +793,14 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { }, reqSignIn, context.RepoAssignment(), context.UnitTypes()) // Releases - m.Group("/:username/:reponame", func() { + m.Group("/{username}/{reponame}", func() { m.Get("/tags", repo.TagsList, repo.MustBeNotEmpty, reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag)) m.Group("/releases", func() { m.Get("/", repo.Releases) m.Get("/tag/*", repo.SingleRelease) m.Get("/latest", repo.LatestRelease) - m.Get("/attachments/:uuid", repo.GetAttachment) + m.Get("/attachments/{uuid}", repo.GetAttachment) }, repo.MustBeNotEmpty, reqRepoReleaseReader, context.RepoRefByType(context.RepoRefTag)) m.Group("/releases", func() { m.Get("/new", repo.NewRelease) @@ -772,56 +830,57 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { }) }, ignSignIn, context.RepoAssignment(), context.UnitTypes(), reqRepoReleaseReader) - m.Group("/:username/:reponame", func() { + m.Group("/{username}/{reponame}", func() { m.Post("/topics", repo.TopicsPost) }, context.RepoAssignment(), context.RepoMustNotBeArchived(), reqRepoAdmin) - m.Group("/:username/:reponame", func() { + m.Group("/{username}/{reponame}", func() { m.Group("", func() { - m.Get("/^:type(issues|pulls)$", repo.Issues) - m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue) - m.Get("/labels/", reqRepoIssuesOrPullsReader, repo.RetrieveLabels, repo.Labels) + m.Get("/{type:issues|pulls}", repo.Issues) + m.Get("/{type:issues|pulls}/{index}", repo.ViewIssue) + m.Get("/labels", reqRepoIssuesOrPullsReader, repo.RetrieveLabels, repo.Labels) m.Get("/milestones", reqRepoIssuesOrPullsReader, repo.Milestones) }, context.RepoRef()) m.Group("/projects", func() { m.Get("", repo.Projects) - m.Get("/:id", repo.ViewProject) + m.Get("/{id}", repo.ViewProject) m.Group("", func() { m.Get("/new", repo.NewProject) m.Post("/new", bindIgnErr(auth.CreateProjectForm{}), repo.NewProjectPost) - m.Group("/:id", func() { + m.Group("/{id}", func() { m.Post("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.AddBoardToProjectPost) m.Post("/delete", repo.DeleteProject) m.Get("/edit", repo.EditProject) m.Post("/edit", bindIgnErr(auth.CreateProjectForm{}), repo.EditProjectPost) - m.Post("/^:action(open|close)$", repo.ChangeProjectStatus) + m.Post("/{action:open|close}", repo.ChangeProjectStatus) - m.Group("/:boardID", func() { + m.Group("/{boardID}", func() { m.Put("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.EditProjectBoardTitle) m.Delete("", repo.DeleteProjectBoard) m.Post("/default", repo.SetDefaultProjectBoard) - m.Post("/:index", repo.MoveIssueAcrossBoards) + m.Post("/{index}", repo.MoveIssueAcrossBoards) }) }) }, reqRepoProjectsWriter, context.RepoMustNotBeArchived()) }, reqRepoProjectsReader, repo.MustEnableProjects) m.Group("/wiki", func() { - m.Get("/?:page", repo.Wiki) + m.Get("/", repo.Wiki) + m.Get("/{page}", repo.Wiki) m.Get("/_pages", repo.WikiPages) - m.Get("/:page/_revision", repo.WikiRevision) - m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff) - m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)", repo.RawDiff) + m.Get("/{page}/_revision", repo.WikiRevision) + m.Get("/commit/{sha:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff) + m.Get("/commit/{sha:[a-f0-9]{7,40}}.{:patch|diff}", repo.RawDiff) m.Group("", func() { m.Combo("/_new").Get(repo.NewWiki). Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost) - m.Combo("/:page/_edit").Get(repo.EditWiki). + m.Combo("/{page}/_edit").Get(repo.EditWiki). Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost) - m.Post("/:page/delete", repo.DeleteWikiPagePost) + m.Post("/{page}/delete", repo.DeleteWikiPagePost) }, context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter) }, repo.MustEnableWiki, context.RepoRef(), func(ctx *context.Context) { ctx.Data["PageIsWiki"] = true @@ -833,12 +892,12 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("/activity", func() { m.Get("", repo.Activity) - m.Get("/:period", repo.Activity) + m.Get("/{period}", repo.Activity) }, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(models.UnitTypePullRequests, models.UnitTypeIssues, models.UnitTypeReleases)) m.Group("/activity_author_data", func() { m.Get("", repo.ActivityAuthors) - m.Get("/:period", repo.ActivityAuthors) + m.Get("/{period}", repo.ActivityAuthors) }, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(models.UnitTypeCode)) m.Group("/archive", func() { @@ -851,10 +910,10 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) m.Group("/blob_excerpt", func() { - m.Get("/:sha", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob) + m.Get("/{sha}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob) }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) - m.Group("/pulls/:index", func() { + m.Group("/pulls/{index}", func() { m.Get(".diff", repo.DownloadPullDiff) m.Get(".patch", repo.DownloadPullPatch) m.Get("/commits", context.RepoRef(), repo.ViewPullCommits) @@ -875,7 +934,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.SingleDownloadOrLFS) m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.SingleDownloadOrLFS) m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.SingleDownloadOrLFS) - m.Get("/blob/:sha", context.RepoRefByType(context.RepoRefBlob), repo.DownloadByIDOrLFS) + m.Get("/blob/{sha}", context.RepoRefByType(context.RepoRefBlob), repo.DownloadByIDOrLFS) // "/*" route is deprecated, and kept for backward compatibility m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.SingleDownloadOrLFS) }, repo.MustBeNotEmpty, reqRepoCodeReader) @@ -884,7 +943,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.SingleDownload) m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.SingleDownload) m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.SingleDownload) - m.Get("/blob/:sha", context.RepoRefByType(context.RepoRefBlob), repo.DownloadByID) + m.Get("/blob/{sha}", context.RepoRefByType(context.RepoRefBlob), repo.DownloadByID) // "/*" route is deprecated, and kept for backward compatibility m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.SingleDownload) }, repo.MustBeNotEmpty, reqRepoCodeReader) @@ -905,7 +964,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("", func() { m.Get("/graph", repo.Graph) - m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff) + m.Get("/commit/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff) }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) m.Group("/src", func() { @@ -919,39 +978,52 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("", func() { m.Get("/forks", repo.Forks) }, context.RepoRef(), reqRepoCodeReader) - m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)", + m.Get("/commit/{sha:([a-f0-9]{7,40})}.{ext:patch|diff}", repo.MustBeNotEmpty, reqRepoCodeReader, repo.RawDiff) }, ignSignIn, context.RepoAssignment(), context.UnitTypes()) - m.Group("/:username/:reponame", func() { + m.Group("/{username}/{reponame}", func() { m.Get("/stars", repo.Stars) m.Get("/watchers", repo.Watchers) m.Get("/search", reqRepoCodeReader, repo.Search) }, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes()) - m.Group("/:username", func() { - m.Group("/:reponame", func() { + m.Group("/{username}", func() { + m.Group("/{reponame}", func() { m.Get("", repo.SetEditorconfigIfExists, repo.Home) - m.Get("\\.git$", repo.SetEditorconfigIfExists, repo.Home) }, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes()) - m.Group("/:reponame", func() { - m.Group("\\.git/info/lfs", func() { + m.Group("/{reponame}", func() { + m.Group("/info/lfs", func() { m.Post("/objects/batch", lfs.BatchHandler) - m.Get("/objects/:oid/:filename", lfs.ObjectOidHandler) - m.Any("/objects/:oid", lfs.ObjectOidHandler) + m.Get("/objects/{oid}/{filename}", lfs.ObjectOidHandler) + m.Any("/objects/{oid}", lfs.ObjectOidHandler) m.Post("/objects", lfs.PostHandler) m.Post("/verify", lfs.VerifyHandler) m.Group("/locks", func() { m.Get("/", lfs.GetListLockHandler) m.Post("/", lfs.PostLockHandler) m.Post("/verify", lfs.VerifyLockHandler) - m.Post("/:lid/unlock", lfs.UnLockHandler) + m.Post("/{lid}/unlock", lfs.UnLockHandler) }) m.Any("/*", func(ctx *context.Context) { ctx.NotFound("", nil) }) }, ignSignInAndCsrf) - m.Any("/*", ignSignInAndCsrf, repo.HTTP) + + m.Group("", func() { + m.Post("/git-upload-pack", repo.ServiceUploadPack) + m.Post("/git-receive-pack", repo.ServiceReceivePack) + m.Get("/info/refs", repo.GetInfoRefs) + m.Get("/HEAD", repo.GetTextFile("HEAD")) + m.Get("/objects/info/alternates", repo.GetTextFile("objects/info/alternates")) + m.Get("/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates")) + m.Get("/objects/info/packs", repo.GetInfoPacks) + m.Get("/objects/info/{file:[^/]*}", repo.GetTextFile("")) + m.Get("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject) + m.Get("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile) + m.Get("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile) + }, ignSignInAndCsrf) + m.Head("/tasks/trigger", repo.TriggerTask) }) }) @@ -964,30 +1036,9 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { }, reqSignIn) if setting.API.EnableSwagger { - m.Get("/swagger.v1.json", templates.JSONRenderer(), routers.SwaggerV1Json) - } - - var handlers []macaron.Handler - if setting.CORSConfig.Enabled { - handlers = append(handlers, cors.CORS(cors.Options{ - Scheme: setting.CORSConfig.Scheme, - AllowDomain: setting.CORSConfig.AllowDomain, - AllowSubdomain: setting.CORSConfig.AllowSubdomain, - Methods: setting.CORSConfig.Methods, - MaxAgeSeconds: int(setting.CORSConfig.MaxAge.Seconds()), - AllowCredentials: setting.CORSConfig.AllowCredentials, - })) + m.Get("/swagger.v1.json", routers.SwaggerV1Json) } - handlers = append(handlers, ignSignIn) - m.Group("/api", func() { - apiv1.RegisterRoutes(m) - }, handlers...) - - m.Group("/api/internal", func() { - // package name internal is ideal but Golang is not allowed, so we use private as package name. - private.RegisterRoutes(m) - }) // Not found handler. - m.NotFound(routers.NotFound) + m.NotFound(web.Wrap(routers.NotFound)) } diff --git a/routers/swagger_json.go b/routers/swagger_json.go index 58c4ec50d9d7d..3ff1674f048ef 100644 --- a/routers/swagger_json.go +++ b/routers/swagger_json.go @@ -7,6 +7,7 @@ package routers import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" ) // tplSwaggerV1Json swagger v1 json template @@ -14,5 +15,10 @@ const tplSwaggerV1Json base.TplName = "swagger/v1_json" // SwaggerV1Json render swagger v1 json func SwaggerV1Json(ctx *context.Context) { - ctx.HTML(200, tplSwaggerV1Json) + t := ctx.Render.TemplateLookup(string(tplSwaggerV1Json)) + ctx.Resp.Header().Set("Content-Type", "application/json") + if err := t.Execute(ctx.Resp, ctx.Data); err != nil { + log.Error("%v", err) + ctx.Error(500) + } } diff --git a/routers/user/auth.go b/routers/user/auth.go index bce801847d2f6..909d0a2ee5918 100644 --- a/routers/user/auth.go +++ b/routers/user/auth.go @@ -12,22 +12,22 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/auth/oauth2" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/eventsource" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/hcaptcha" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/password" "code.gitea.io/gitea/modules/recaptcha" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" "code.gitea.io/gitea/services/externalaccount" "code.gitea.io/gitea/services/mailer" - "gitea.com/macaron/captcha" "github.com/markbates/goth" "github.com/tstranex/u2f" ) @@ -149,7 +149,7 @@ func SignIn(ctx *context.Context) { } // SignInPost response for sign in request -func SignInPost(ctx *context.Context, form auth.SignInForm) { +func SignInPost(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("sign_in") orderedOAuth2Names, oauth2Providers, err := models.GetActiveOAuth2Providers() @@ -170,6 +170,7 @@ func SignInPost(ctx *context.Context, form auth.SignInForm) { return } + form := web.GetForm(ctx).(*auth.SignInForm) u, err := models.UserSignIn(form.UserName, form.Password) if err != nil { if models.IsErrUserNotExist(err) { @@ -250,7 +251,8 @@ func TwoFactor(ctx *context.Context) { } // TwoFactorPost validates a user's two-factor authentication token. -func TwoFactorPost(ctx *context.Context, form auth.TwoFactorAuthForm) { +func TwoFactorPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.TwoFactorAuthForm) ctx.Data["Title"] = ctx.Tr("twofa") // Ensure user is in a 2FA session. @@ -328,7 +330,8 @@ func TwoFactorScratch(ctx *context.Context) { } // TwoFactorScratchPost validates and invalidates a user's two-factor scratch token. -func TwoFactorScratchPost(ctx *context.Context, form auth.TwoFactorScratchAuthForm) { +func TwoFactorScratchPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.TwoFactorScratchAuthForm) ctx.Data["Title"] = ctx.Tr("twofa_scratch") // Ensure user is in a 2FA session. @@ -427,7 +430,8 @@ func U2FChallenge(ctx *context.Context) { } // U2FSign authenticates the user by signResp -func U2FSign(ctx *context.Context, signResp u2f.SignResponse) { +func U2FSign(ctx *context.Context) { + signResp := web.GetForm(ctx).(*u2f.SignResponse) challSess := ctx.Session.Get("u2fChallenge") idSess := ctx.Session.Get("twofaUid") if challSess == nil || idSess == nil { @@ -447,7 +451,7 @@ func U2FSign(ctx *context.Context, signResp u2f.SignResponse) { log.Fatal("parsing u2f registration: %v", err) continue } - newCounter, authErr := r.Authenticate(signResp, *challenge, reg.Counter) + newCounter, authErr := r.Authenticate(*signResp, *challenge, reg.Counter) if authErr == nil { reg.Counter = newCounter user, err := models.GetUserByID(id) @@ -563,20 +567,20 @@ func SignInOAuth(ctx *context.Context) { } // try to do a direct callback flow, so we don't authenticate the user again but use the valid accesstoken to get the user - user, gothUser, err := oAuth2UserLoginCallback(loginSource, ctx.Req.Request, ctx.Resp) + user, gothUser, err := oAuth2UserLoginCallback(loginSource, ctx.Req, ctx.Resp) if err == nil && user != nil { // we got the user without going through the whole OAuth2 authentication flow again handleOAuth2SignIn(user, gothUser, ctx, err) return } - if err = oauth2.Auth(loginSource.Name, ctx.Req.Request, ctx.Resp); err != nil { + if err = oauth2.Auth(loginSource.Name, ctx.Req, ctx.Resp); err != nil { if strings.Contains(err.Error(), "no provider for ") { if err = models.ResetOAuth2(); err != nil { ctx.ServerError("SignIn", err) return } - if err = oauth2.Auth(loginSource.Name, ctx.Req.Request, ctx.Resp); err != nil { + if err = oauth2.Auth(loginSource.Name, ctx.Req, ctx.Resp); err != nil { ctx.ServerError("SignIn", err) } return @@ -602,7 +606,7 @@ func SignInOAuthCallback(ctx *context.Context) { return } - u, gothUser, err := oAuth2UserLoginCallback(loginSource, ctx.Req.Request, ctx.Resp) + u, gothUser, err := oAuth2UserLoginCallback(loginSource, ctx.Req, ctx.Resp) handleOAuth2SignIn(u, gothUser, ctx, err) } @@ -788,7 +792,8 @@ func LinkAccount(ctx *context.Context) { } // LinkAccountPostSignIn handle the coupling of external account with another account using signIn -func LinkAccountPostSignIn(ctx *context.Context, signInForm auth.SignInForm) { +func LinkAccountPostSignIn(ctx *context.Context) { + signInForm := web.GetForm(ctx).(*auth.SignInForm) ctx.Data["DisablePassword"] = !setting.Service.RequireExternalRegistrationPassword || setting.Service.AllowOnlyExternalRegistration ctx.Data["Title"] = ctx.Tr("link_account") ctx.Data["LinkAccountMode"] = true @@ -870,7 +875,8 @@ func LinkAccountPostSignIn(ctx *context.Context, signInForm auth.SignInForm) { } // LinkAccountPostRegister handle the creation of a new account for an external account using signUp -func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterForm) { +func LinkAccountPostRegister(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.RegisterForm) // TODO Make insecure passwords optional for local accounts also, // once email-based Second-Factor Auth is available ctx.Data["DisablePassword"] = !setting.Service.RequireExternalRegistrationPassword || setting.Service.AllowOnlyExternalRegistration @@ -909,7 +915,7 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au var err error switch setting.Service.CaptchaType { case setting.ImageCaptcha: - valid = cpt.VerifyReq(ctx.Req) + valid = context.GetImageCaptcha().VerifyReq(ctx.Req) case setting.ReCaptcha: valid, err = recaptcha.Verify(ctx.Req.Context(), form.GRecaptchaResponse) case setting.HCaptcha: @@ -1029,7 +1035,7 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au // HandleSignOut resets the session and sets the cookies func HandleSignOut(ctx *context.Context) { _ = ctx.Session.Flush() - _ = ctx.Session.Destroy(ctx.Context) + _ = ctx.Session.Destroy(ctx.Resp, ctx.Req) ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) @@ -1069,7 +1075,8 @@ func SignUp(ctx *context.Context) { } // SignUpPost response for sign up information submission -func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterForm) { +func SignUpPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.RegisterForm) ctx.Data["Title"] = ctx.Tr("sign_up") ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up" @@ -1097,7 +1104,7 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo var err error switch setting.Service.CaptchaType { case setting.ImageCaptcha: - valid = cpt.VerifyReq(ctx.Req) + valid = context.GetImageCaptcha().VerifyReq(ctx.Req) case setting.ReCaptcha: valid, err = recaptcha.Verify(ctx.Req.Context(), form.GRecaptchaResponse) case setting.HCaptcha: @@ -1562,7 +1569,8 @@ func MustChangePassword(ctx *context.Context) { // MustChangePasswordPost response for updating a user's password after his/her // account was created by an admin -func MustChangePasswordPost(ctx *context.Context, cpt *captcha.Captcha, form auth.MustChangePasswordForm) { +func MustChangePasswordPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.MustChangePasswordForm) ctx.Data["Title"] = ctx.Tr("auth.must_change_password") ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/settings/change_password" if ctx.HasError() { diff --git a/routers/user/auth_openid.go b/routers/user/auth_openid.go index 39e75f202dd78..1efcc7eda82c1 100644 --- a/routers/user/auth_openid.go +++ b/routers/user/auth_openid.go @@ -9,19 +9,18 @@ import ( "net/url" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/auth/openid" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/generate" "code.gitea.io/gitea/modules/hcaptcha" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/recaptcha" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/mailer" - - "gitea.com/macaron/captcha" ) const ( @@ -90,7 +89,8 @@ func allowedOpenIDURI(uri string) (err error) { } // SignInOpenIDPost response for openid sign in request -func SignInOpenIDPost(ctx *context.Context, form auth.SignInOpenIDForm) { +func SignInOpenIDPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.SignInOpenIDForm) ctx.Data["Title"] = ctx.Tr("sign_in") ctx.Data["PageIsSignIn"] = true ctx.Data["PageIsLoginOpenID"] = true @@ -143,9 +143,9 @@ func SignInOpenIDPost(ctx *context.Context, form auth.SignInOpenIDForm) { // signInOpenIDVerify handles response from OpenID provider func signInOpenIDVerify(ctx *context.Context) { - log.Trace("Incoming call to: " + ctx.Req.Request.URL.String()) + log.Trace("Incoming call to: " + ctx.Req.URL.String()) - fullURL := setting.AppURL + ctx.Req.Request.URL.String()[1:] + fullURL := setting.AppURL + ctx.Req.URL.String()[1:] log.Trace("Full URL: " + fullURL) var id, err = openid.Verify(fullURL) @@ -276,8 +276,8 @@ func ConnectOpenID(ctx *context.Context) { } // ConnectOpenIDPost handles submission of a form to connect an OpenID URI to an existing account -func ConnectOpenIDPost(ctx *context.Context, form auth.ConnectOpenIDForm) { - +func ConnectOpenIDPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.ConnectOpenIDForm) oid, _ := ctx.Session.Get("openid_verified_uri").(string) if oid == "" { ctx.Redirect(setting.AppSubURL + "/user/login/openid") @@ -346,7 +346,8 @@ func RegisterOpenID(ctx *context.Context) { } // RegisterOpenIDPost handles submission of a form to create a new user authenticated via an OpenID URI -func RegisterOpenIDPost(ctx *context.Context, cpt *captcha.Captcha, form auth.SignUpOpenIDForm) { +func RegisterOpenIDPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.SignUpOpenIDForm) oid, _ := ctx.Session.Get("openid_verified_uri").(string) if oid == "" { ctx.Redirect(setting.AppSubURL + "/user/login/openid") @@ -369,7 +370,7 @@ func RegisterOpenIDPost(ctx *context.Context, cpt *captcha.Captcha, form auth.Si var err error switch setting.Service.CaptchaType { case setting.ImageCaptcha: - valid = cpt.VerifyReq(ctx.Req) + valid = context.GetImageCaptcha().VerifyReq(ctx.Req) case setting.ReCaptcha: if err := ctx.Req.ParseForm(); err != nil { ctx.ServerError("", err) diff --git a/routers/user/oauth.go b/routers/user/oauth.go index dda1268f8a1db..d943ec4200b6d 100644 --- a/routers/user/oauth.go +++ b/routers/user/oauth.go @@ -12,14 +12,15 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/web" - "gitea.com/macaron/binding" + "gitea.com/go-chi/binding" "github.com/dgrijalva/jwt-go" ) @@ -192,9 +193,10 @@ func newAccessTokenResponse(grant *models.OAuth2Grant, clientSecret string) (*Ac } // AuthorizeOAuth manages authorize requests -func AuthorizeOAuth(ctx *context.Context, form auth.AuthorizationForm) { +func AuthorizeOAuth(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AuthorizationForm) errs := binding.Errors{} - errs = form.Validate(ctx.Context, errs) + errs = form.Validate(ctx.Req, errs) if len(errs) > 0 { errstring := "" for _, e := range errs { @@ -341,7 +343,8 @@ func AuthorizeOAuth(ctx *context.Context, form auth.AuthorizationForm) { } // GrantApplicationOAuth manages the post request submitted when a user grants access to an application -func GrantApplicationOAuth(ctx *context.Context, form auth.GrantApplicationForm) { +func GrantApplicationOAuth(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.GrantApplicationForm) if ctx.Session.Get("client_id") != form.ClientID || ctx.Session.Get("state") != form.State || ctx.Session.Get("redirect_uri") != form.RedirectURI { ctx.Error(400) @@ -386,7 +389,8 @@ func GrantApplicationOAuth(ctx *context.Context, form auth.GrantApplicationForm) } // AccessTokenOAuth manages all access token requests by the client -func AccessTokenOAuth(ctx *context.Context, form auth.AccessTokenForm) { +func AccessTokenOAuth(ctx *context.Context) { + form := *web.GetForm(ctx).(*auth.AccessTokenForm) if form.ClientID == "" { authHeader := ctx.Req.Header.Get("Authorization") authContent := strings.SplitN(authHeader, " ", 2) diff --git a/routers/user/setting/account.go b/routers/user/setting/account.go index 42c2c59b7e752..4900bba14ac0c 100644 --- a/routers/user/setting/account.go +++ b/routers/user/setting/account.go @@ -10,13 +10,14 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/password" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/mailer" ) @@ -36,7 +37,8 @@ func Account(ctx *context.Context) { } // AccountPost response for change user's password -func AccountPost(ctx *context.Context, form auth.ChangePasswordForm) { +func AccountPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.ChangePasswordForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true @@ -80,7 +82,8 @@ func AccountPost(ctx *context.Context, form auth.ChangePasswordForm) { } // EmailPost response for change user's email -func EmailPost(ctx *context.Context, form auth.AddEmailForm) { +func EmailPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AddEmailForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true @@ -252,8 +255,8 @@ func DeleteAccount(ctx *context.Context) { } // UpdateUIThemePost is used to update users' specific theme -func UpdateUIThemePost(ctx *context.Context, form auth.UpdateThemeForm) { - +func UpdateUIThemePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.UpdateThemeForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true diff --git a/routers/user/setting/account_test.go b/routers/user/setting/account_test.go index 841ecb8ac25c5..0e7e147b8bc72 100644 --- a/routers/user/setting/account_test.go +++ b/routers/user/setting/account_test.go @@ -9,9 +9,10 @@ import ( "testing" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/web" "github.com/stretchr/testify/assert" ) @@ -85,11 +86,12 @@ func TestChangePassword(t *testing.T) { test.LoadUser(t, ctx, 2) test.LoadRepo(t, ctx, 1) - AccountPost(ctx, auth.ChangePasswordForm{ + web.SetForm(ctx, &auth.ChangePasswordForm{ OldPassword: req.OldPassword, Password: req.NewPassword, Retype: req.Retype, }) + AccountPost(ctx) assert.Contains(t, ctx.Flash.ErrorMsg, req.Message) assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) diff --git a/routers/user/setting/applications.go b/routers/user/setting/applications.go index 04f9d9f7f9b92..8da36dc6cf4bb 100644 --- a/routers/user/setting/applications.go +++ b/routers/user/setting/applications.go @@ -7,10 +7,11 @@ package setting import ( "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" ) const ( @@ -28,7 +29,8 @@ func Applications(ctx *context.Context) { } // ApplicationsPost response for add user's access token -func ApplicationsPost(ctx *context.Context, form auth.NewAccessTokenForm) { +func ApplicationsPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.NewAccessTokenForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsApplications"] = true diff --git a/routers/user/setting/keys.go b/routers/user/setting/keys.go index 76c7ef9da4470..a52ffd667bdcb 100644 --- a/routers/user/setting/keys.go +++ b/routers/user/setting/keys.go @@ -7,10 +7,11 @@ package setting import ( "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" ) const ( @@ -31,7 +32,8 @@ func Keys(ctx *context.Context) { } // KeysPost response for change user's SSH/GPG keys -func KeysPost(ctx *context.Context, form auth.AddKeyForm) { +func KeysPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AddKeyForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsKeys"] = true ctx.Data["DisableSSH"] = setting.SSH.Disabled diff --git a/routers/user/setting/oauth2.go b/routers/user/setting/oauth2.go index f42c1123e174b..7f0f8db1c8d9e 100644 --- a/routers/user/setting/oauth2.go +++ b/routers/user/setting/oauth2.go @@ -8,11 +8,12 @@ import ( "fmt" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" ) const ( @@ -20,7 +21,8 @@ const ( ) // OAuthApplicationsPost response for adding a oauth2 application -func OAuthApplicationsPost(ctx *context.Context, form auth.EditOAuth2ApplicationForm) { +func OAuthApplicationsPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.EditOAuth2ApplicationForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsApplications"] = true @@ -51,7 +53,8 @@ func OAuthApplicationsPost(ctx *context.Context, form auth.EditOAuth2Application } // OAuthApplicationsEdit response for editing oauth2 application -func OAuthApplicationsEdit(ctx *context.Context, form auth.EditOAuth2ApplicationForm) { +func OAuthApplicationsEdit(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.EditOAuth2ApplicationForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsApplications"] = true diff --git a/routers/user/setting/profile.go b/routers/user/setting/profile.go index c935b56230d85..7e90a7ccec3cf 100644 --- a/routers/user/setting/profile.go +++ b/routers/user/setting/profile.go @@ -14,12 +14,13 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" "github.com/unknwon/i18n" ) @@ -71,7 +72,8 @@ func HandleUsernameChange(ctx *context.Context, user *models.User, newName strin } // ProfilePost response for change user's profile -func ProfilePost(ctx *context.Context, form auth.UpdateProfileForm) { +func ProfilePost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.UpdateProfileForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsProfile"] = true @@ -123,7 +125,7 @@ func ProfilePost(ctx *context.Context, form auth.UpdateProfileForm) { // UpdateAvatarSetting update user's avatar // FIXME: limit size. -func UpdateAvatarSetting(ctx *context.Context, form auth.AvatarForm, ctxUser *models.User) error { +func UpdateAvatarSetting(ctx *context.Context, form *auth.AvatarForm, ctxUser *models.User) error { ctxUser.UseCustomAvatar = form.Source == auth.AvatarLocal if len(form.Gravatar) > 0 { if form.Avatar != nil { @@ -171,7 +173,8 @@ func UpdateAvatarSetting(ctx *context.Context, form auth.AvatarForm, ctxUser *mo } // AvatarPost response for change user's avatar request -func AvatarPost(ctx *context.Context, form auth.AvatarForm) { +func AvatarPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AvatarForm) if err := UpdateAvatarSetting(ctx, form, ctx.User); err != nil { ctx.Flash.Error(err.Error()) } else { diff --git a/routers/user/setting/security_openid.go b/routers/user/setting/security_openid.go index 6813765f6f336..401705608a8e6 100644 --- a/routers/user/setting/security_openid.go +++ b/routers/user/setting/security_openid.go @@ -6,15 +6,17 @@ package setting import ( "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/auth/openid" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" ) // OpenIDPost response for change user's openid -func OpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) { +func OpenIDPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.AddOpenIDForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsSecurity"] = true @@ -70,9 +72,9 @@ func OpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) { } func settingsOpenIDVerify(ctx *context.Context) { - log.Trace("Incoming call to: " + ctx.Req.Request.URL.String()) + log.Trace("Incoming call to: " + ctx.Req.URL.String()) - fullURL := setting.AppURL + ctx.Req.Request.URL.String()[1:] + fullURL := setting.AppURL + ctx.Req.URL.String()[1:] log.Trace("Full URL: " + fullURL) id, err := openid.Verify(fullURL) diff --git a/routers/user/setting/security_twofa.go b/routers/user/setting/security_twofa.go index 3f4c8f6c3f22a..0dee827cab1d3 100644 --- a/routers/user/setting/security_twofa.go +++ b/routers/user/setting/security_twofa.go @@ -13,10 +13,11 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" @@ -165,7 +166,8 @@ func EnrollTwoFactor(ctx *context.Context) { } // EnrollTwoFactorPost handles enrolling the user into 2FA. -func EnrollTwoFactorPost(ctx *context.Context, form auth.TwoFactorAuthForm) { +func EnrollTwoFactorPost(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.TwoFactorAuthForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsSecurity"] = true diff --git a/routers/user/setting/security_u2f.go b/routers/user/setting/security_u2f.go index 7e32b4aaeca52..8140c3c04a744 100644 --- a/routers/user/setting/security_u2f.go +++ b/routers/user/setting/security_u2f.go @@ -8,16 +8,18 @@ import ( "errors" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" + auth "code.gitea.io/gitea/modules/forms" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" "github.com/tstranex/u2f" ) // U2FRegister initializes the u2f registration procedure -func U2FRegister(ctx *context.Context, form auth.U2FRegistrationForm) { +func U2FRegister(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.U2FRegistrationForm) if form.Name == "" { ctx.Error(409) return @@ -55,7 +57,8 @@ func U2FRegister(ctx *context.Context, form auth.U2FRegistrationForm) { } // U2FRegisterPost receives the response of the security key -func U2FRegisterPost(ctx *context.Context, response u2f.RegisterResponse) { +func U2FRegisterPost(ctx *context.Context) { + response := web.GetForm(ctx).(*u2f.RegisterResponse) challSess := ctx.Session.Get("u2fChallenge") u2fName := ctx.Session.Get("u2fName") if challSess == nil || u2fName == nil { @@ -69,7 +72,7 @@ func U2FRegisterPost(ctx *context.Context, response u2f.RegisterResponse) { // certificate by default. SkipAttestationVerify: true, } - reg, err := u2f.Register(response, *challenge, config) + reg, err := u2f.Register(*response, *challenge, config) if err != nil { ctx.ServerError("u2f.Register", err) return @@ -82,7 +85,8 @@ func U2FRegisterPost(ctx *context.Context, response u2f.RegisterResponse) { } // U2FDelete deletes an security key by id -func U2FDelete(ctx *context.Context, form auth.U2FDeleteForm) { +func U2FDelete(ctx *context.Context) { + form := web.GetForm(ctx).(*auth.U2FDeleteForm) reg, err := models.GetU2FRegistrationByID(form.ID) if err != nil { if models.IsErrU2FRegistrationNotExist(err) { diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index 3fbb80caf1862..aa6a9b793b23b 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -340,23 +340,6 @@
{{.Config | JsonPrettyPrint}}
{{end}}
-
{{$.i18n.Tr "admin.config.macaron_log_mode"}}
- {{if .RedirectMacaronLog}} - {{if .Loggers.macaron.SubLogDescriptions}} -
{{$.i18n.Tr "admin.config.own_named_logger"}}
- {{range .Loggers.macaron.SubLogDescriptions}} -
{{$.i18n.Tr "admin.config.log_mode"}}
-
{{.Name}} ({{.Provider}})
-
{{$.i18n.Tr "admin.config.log_config"}}
-
{{.Config | JsonPrettyPrint}}
- {{end}} - {{else}} -
{{$.i18n.Tr "admin.config.routes_to_default_logger"}}
- {{end}} - {{else}} -
{{$.i18n.Tr "admin.config.go_log"}}
- {{end}} -
{{$.i18n.Tr "admin.config.router_log_mode"}}
{{if .DisableRouterLog}}
{{$.i18n.Tr "admin.config.disabled_logger"}}
diff --git a/templates/repo/sub_menu.tmpl b/templates/repo/sub_menu.tmpl index 5bb71ba49ddd5..f00237047e875 100644 --- a/templates/repo/sub_menu.tmpl +++ b/templates/repo/sub_menu.tmpl @@ -6,7 +6,7 @@ {{svg "octicon-history"}} {{.CommitsCount}} {{.i18n.Tr (TrN .i18n.Lang .CommitsCount "repo.commit" "repo.commits") }} {{if $.Permission.CanRead $.UnitTypeCode}}
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 0f26943da16a9..86f09e2bbb877 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -14212,7 +14212,7 @@ } }, "x-go-name": "MergePullRequestForm", - "x-go-package": "code.gitea.io/gitea/modules/auth" + "x-go-package": "code.gitea.io/gitea/modules/forms" }, "MigrateRepoForm": { "description": "MigrateRepoForm form for migrating repository\nthis is used to interact with web ui", @@ -14292,7 +14292,7 @@ "x-go-name": "Wiki" } }, - "x-go-package": "code.gitea.io/gitea/modules/auth" + "x-go-package": "code.gitea.io/gitea/modules/forms" }, "MigrateRepoOptions": { "description": "MigrateRepoOptions options for migrating repository's\nthis is used to interact with api v1", diff --git a/vendor/gitea.com/macaron/binding/.drone.yml b/vendor/gitea.com/go-chi/binding/.drone.yml similarity index 100% rename from vendor/gitea.com/macaron/binding/.drone.yml rename to vendor/gitea.com/go-chi/binding/.drone.yml diff --git a/vendor/gitea.com/macaron/binding/.gitignore b/vendor/gitea.com/go-chi/binding/.gitignore similarity index 100% rename from vendor/gitea.com/macaron/binding/.gitignore rename to vendor/gitea.com/go-chi/binding/.gitignore diff --git a/vendor/gitea.com/macaron/binding/LICENSE b/vendor/gitea.com/go-chi/binding/LICENSE similarity index 100% rename from vendor/gitea.com/macaron/binding/LICENSE rename to vendor/gitea.com/go-chi/binding/LICENSE diff --git a/vendor/gitea.com/go-chi/binding/README.md b/vendor/gitea.com/go-chi/binding/README.md new file mode 100644 index 0000000000000..80ea7637359d7 --- /dev/null +++ b/vendor/gitea.com/go-chi/binding/README.md @@ -0,0 +1,5 @@ +Middleware binding provides request data binding and validation for net/http, It's a fork of [Macaron](https://github.com/go-macaron/macaron). + +## License + +This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/binding/binding.go b/vendor/gitea.com/go-chi/binding/binding.go similarity index 80% rename from vendor/gitea.com/macaron/binding/binding.go rename to vendor/gitea.com/go-chi/binding/binding.go index 633d836b6449b..acd2a7e17118e 100644 --- a/vendor/gitea.com/macaron/binding/binding.go +++ b/vendor/gitea.com/go-chi/binding/binding.go @@ -1,5 +1,6 @@ // Copyright 2014 Martini Authors // Copyright 2014 The Macaron Authors +// Copyright 2020 The Gitea Authors // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain @@ -13,7 +14,7 @@ // License for the specific language governing permissions and limitations // under the License. -// Package binding is a middleware that provides request data binding and validation for Macaron. +// Package binding is a middleware that provides request data binding and validation for Chi. package binding import ( @@ -29,26 +30,27 @@ import ( "strings" "unicode/utf8" - "gitea.com/macaron/macaron" "github.com/unknwon/com" ) -const _VERSION = "0.6.0" - -func Version() string { - return _VERSION -} - -func bind(ctx *macaron.Context, obj interface{}, ifacePtr ...interface{}) { - contentType := ctx.Req.Header.Get("Content-Type") - if ctx.Req.Method == "POST" || ctx.Req.Method == "PUT" || len(contentType) > 0 { +// Bind wraps up the functionality of the Form and Json middleware +// according to the Content-Type and verb of the request. +// A Content-Type is required for POST and PUT requests. +// Bind invokes the ErrorHandler middleware to bail out if errors +// occurred. If you want to perform your own error handling, use +// Form or Json middleware directly. An interface pointer can +// be added as a second argument in order to map the struct to +// a specific interface. +func Bind(req *http.Request, obj interface{}) Errors { + contentType := req.Header.Get("Content-Type") + if req.Method == "POST" || req.Method == "PUT" || len(contentType) > 0 { switch { case strings.Contains(contentType, "form-urlencoded"): - ctx.Invoke(Form(obj, ifacePtr...)) + return Form(req, obj) case strings.Contains(contentType, "multipart/form-data"): - ctx.Invoke(MultipartForm(obj, ifacePtr...)) + return MultipartForm(req, obj) case strings.Contains(contentType, "json"): - ctx.Invoke(Json(obj, ifacePtr...)) + return JSON(req, obj) default: var errors Errors if contentType == "" { @@ -56,11 +58,10 @@ func bind(ctx *macaron.Context, obj interface{}, ifacePtr ...interface{}) { } else { errors.Add([]string{}, ERR_CONTENT_TYPE, "Unsupported Content-Type") } - ctx.Map(errors) - ctx.Map(obj) // Map a fake struct so handler won't panic. + return errors } } else { - ctx.Invoke(Form(obj, ifacePtr...)) + return Form(req, obj) } } @@ -94,34 +95,6 @@ func errorHandler(errs Errors, rw http.ResponseWriter) { } } -// Bind wraps up the functionality of the Form and Json middleware -// according to the Content-Type and verb of the request. -// A Content-Type is required for POST and PUT requests. -// Bind invokes the ErrorHandler middleware to bail out if errors -// occurred. If you want to perform your own error handling, use -// Form or Json middleware directly. An interface pointer can -// be added as a second argument in order to map the struct to -// a specific interface. -func Bind(obj interface{}, ifacePtr ...interface{}) macaron.Handler { - return func(ctx *macaron.Context) { - bind(ctx, obj, ifacePtr...) - if handler, ok := obj.(ErrorHandler); ok { - ctx.Invoke(handler.Error) - } else { - ctx.Invoke(errorHandler) - } - } -} - -// BindIgnErr will do the exactly same thing as Bind but without any -// error handling, which user has freedom to deal with them. -// This allows user take advantages of validation. -func BindIgnErr(obj interface{}, ifacePtr ...interface{}) macaron.Handler { - return func(ctx *macaron.Context) { - bind(ctx, obj, ifacePtr...) - } -} - // Form is middleware to deserialize form-urlencoded data from the request. // It gets data from the form-urlencoded body, if present, or from the // query string. It uses the http.Request.ParseForm() method @@ -131,27 +104,25 @@ func BindIgnErr(obj interface{}, ifacePtr ...interface{}) macaron.Handler { // keys, for example: key=val1&key=val2&key=val3 // An interface pointer can be added as a second argument in order // to map the struct to a specific interface. -func Form(formStruct interface{}, ifacePtr ...interface{}) macaron.Handler { - return func(ctx *macaron.Context) { - var errors Errors - - ensureNotPointer(formStruct) - formStruct := reflect.New(reflect.TypeOf(formStruct)) - parseErr := ctx.Req.ParseForm() - - // Format validation of the request body or the URL would add considerable overhead, - // and ParseForm does not complain when URL encoding is off. - // Because an empty request body or url can also mean absence of all needed values, - // it is not in all cases a bad request, so let's return 422. - if parseErr != nil { - errors.Add([]string{}, ERR_DESERIALIZATION, parseErr.Error()) - } - errors = mapForm(formStruct, ctx.Req.Form, nil, errors) - validateAndMap(formStruct, ctx, errors, ifacePtr...) +func Form(req *http.Request, formStruct interface{}) Errors { + var errors Errors + + ensurePointer(formStruct) + formStructV := reflect.ValueOf(formStruct) + parseErr := req.ParseForm() + + // Format validation of the request body or the URL would add considerable overhead, + // and ParseForm does not complain when URL encoding is off. + // Because an empty request body or url can also mean absence of all needed values, + // it is not in all cases a bad request, so let's return 422. + if parseErr != nil { + errors.Add([]string{}, ERR_DESERIALIZATION, parseErr.Error()) } + errors = mapForm(formStructV, req.Form, nil, errors) + return append(errors, Validate(req, formStruct)...) } -// Maximum amount of memory to use when parsing a multipart form. +// MaxMemory represents maximum amount of memory to use when parsing a multipart form. // Set this to whatever value you prefer; default is 10 MB. var MaxMemory = int64(1024 * 1024 * 10) @@ -159,57 +130,53 @@ var MaxMemory = int64(1024 * 1024 * 10) // and handle file uploads. Like the other deserialization middleware handlers, // you can pass in an interface to make the interface available for injection // into other handlers later. -func MultipartForm(formStruct interface{}, ifacePtr ...interface{}) macaron.Handler { - return func(ctx *macaron.Context) { - var errors Errors - ensureNotPointer(formStruct) - formStruct := reflect.New(reflect.TypeOf(formStruct)) - // This if check is necessary due to https://github.com/martini-contrib/csrf/issues/6 - if ctx.Req.MultipartForm == nil { - // Workaround for multipart forms returning nil instead of an error - // when content is not multipart; see https://code.google.com/p/go/issues/detail?id=6334 - if multipartReader, err := ctx.Req.MultipartReader(); err != nil { - errors.Add([]string{}, ERR_DESERIALIZATION, err.Error()) - } else { - form, parseErr := multipartReader.ReadForm(MaxMemory) - if parseErr != nil { - errors.Add([]string{}, ERR_DESERIALIZATION, parseErr.Error()) - } - - if ctx.Req.Form == nil { - ctx.Req.ParseForm() - } - for k, v := range form.Value { - ctx.Req.Form[k] = append(ctx.Req.Form[k], v...) - } +func MultipartForm(req *http.Request, formStruct interface{}) Errors { + var errors Errors + ensurePointer(formStruct) + formStructV := reflect.ValueOf(formStruct) + // This if check is necessary due to https://github.com/martini-contrib/csrf/issues/6 + if req.MultipartForm == nil { + // Workaround for multipart forms returning nil instead of an error + // when content is not multipart; see https://code.google.com/p/go/issues/detail?id=6334 + if multipartReader, err := req.MultipartReader(); err != nil { + errors.Add([]string{}, ERR_DESERIALIZATION, err.Error()) + } else { + form, parseErr := multipartReader.ReadForm(MaxMemory) + if parseErr != nil { + errors.Add([]string{}, ERR_DESERIALIZATION, parseErr.Error()) + } - ctx.Req.MultipartForm = form + if req.Form == nil { + req.ParseForm() } + for k, v := range form.Value { + req.Form[k] = append(req.Form[k], v...) + } + + req.MultipartForm = form } - errors = mapForm(formStruct, ctx.Req.MultipartForm.Value, ctx.Req.MultipartForm.File, errors) - validateAndMap(formStruct, ctx, errors, ifacePtr...) } + errors = mapForm(formStructV, req.MultipartForm.Value, req.MultipartForm.File, errors) + return append(errors, Validate(req, formStruct)...) } -// Json is middleware to deserialize a JSON payload from the request +// JSON is middleware to deserialize a JSON payload from the request // into the struct that is passed in. The resulting struct is then // validated, but no error handling is actually performed here. // An interface pointer can be added as a second argument in order // to map the struct to a specific interface. -func Json(jsonStruct interface{}, ifacePtr ...interface{}) macaron.Handler { - return func(ctx *macaron.Context) { - var errors Errors - ensureNotPointer(jsonStruct) - jsonStruct := reflect.New(reflect.TypeOf(jsonStruct)) - if ctx.Req.Request.Body != nil { - defer ctx.Req.Request.Body.Close() - err := json.NewDecoder(ctx.Req.Request.Body).Decode(jsonStruct.Interface()) - if err != nil && err != io.EOF { - errors.Add([]string{}, ERR_DESERIALIZATION, err.Error()) - } +func JSON(req *http.Request, jsonStruct interface{}) Errors { + var errors Errors + ensurePointer(jsonStruct) + + if req.Body != nil { + defer req.Body.Close() + err := json.NewDecoder(req.Body).Decode(jsonStruct) + if err != nil && err != io.EOF { + errors.Add([]string{}, ERR_DESERIALIZATION, err.Error()) } - validateAndMap(jsonStruct, ctx, errors, ifacePtr...) } + return append(errors, Validate(req, jsonStruct)...) } // RawValidate is same as Validate but does not require a HTTP context, @@ -238,31 +205,29 @@ func RawValidate(obj interface{}) Errors { // passed in implements Validator, then the user-defined Validate method // is executed, and its errors are mapped to the context. This middleware // performs no error handling: it merely detects errors and maps them. -func Validate(obj interface{}) macaron.Handler { - return func(ctx *macaron.Context) { - var errs Errors - v := reflect.ValueOf(obj) - k := v.Kind() - if k == reflect.Interface || k == reflect.Ptr { - v = v.Elem() - k = v.Kind() - } - if k == reflect.Slice || k == reflect.Array { - for i := 0; i < v.Len(); i++ { - e := v.Index(i).Interface() - errs = validateStruct(errs, e) - if validator, ok := e.(Validator); ok { - errs = validator.Validate(ctx, errs) - } - } - } else { - errs = validateStruct(errs, obj) - if validator, ok := obj.(Validator); ok { - errs = validator.Validate(ctx, errs) +func Validate(req *http.Request, obj interface{}) Errors { + var errs Errors + v := reflect.ValueOf(obj) + k := v.Kind() + if k == reflect.Interface || k == reflect.Ptr { + v = v.Elem() + k = v.Kind() + } + if k == reflect.Slice || k == reflect.Array { + for i := 0; i < v.Len(); i++ { + e := v.Index(i).Interface() + errs = validateStruct(errs, e) + if validator, ok := e.(Validator); ok { + errs = validator.Validate(req, errs) } } - ctx.Map(errs) + } else { + errs = validateStruct(errs, obj) + if validator, ok := obj.(Validator); ok { + errs = validator.Validate(req, errs) + } } + return errs } var ( @@ -394,6 +359,13 @@ func validateStruct(errors Errors, obj interface{}) Errors { return errors } +// Don't pass in pointers to bind to. Can lead to bugs. +func ensureNotPointer(obj interface{}) { + if reflect.TypeOf(obj).Kind() == reflect.Ptr { + panic("Pointers are not accepted as binding models") + } +} + func validateField(errors Errors, zero interface{}, field reflect.StructField, fieldVal reflect.Value, fieldValue interface{}) Errors { if fieldVal.Kind() == reflect.Slice { for i := 0; i < fieldVal.Len(); i++ { @@ -715,36 +687,18 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V return errors } -// Don't pass in pointers to bind to. Can lead to bugs. -func ensureNotPointer(obj interface{}) { - if reflect.TypeOf(obj).Kind() == reflect.Ptr { - panic("Pointers are not accepted as binding models") +// Pointers must be bind to. +func ensurePointer(obj interface{}) { + if reflect.TypeOf(obj).Kind() != reflect.Ptr { + panic("Pointers are only accepted as binding models") } } -// Performs validation and combines errors from validation -// with errors from deserialization, then maps both the -// resulting struct and the errors to the context. -func validateAndMap(obj reflect.Value, ctx *macaron.Context, errors Errors, ifacePtr ...interface{}) { - ctx.Invoke(Validate(obj.Interface())) - errors = append(errors, getErrors(ctx)...) - ctx.Map(errors) - ctx.Map(obj.Elem().Interface()) - if len(ifacePtr) > 0 { - ctx.MapTo(obj.Elem().Interface(), ifacePtr[0]) - } -} - -// getErrors simply gets the errors from the context (it's kind of a chore) -func getErrors(ctx *macaron.Context) Errors { - return ctx.GetVal(reflect.TypeOf(Errors{})).Interface().(Errors) -} - type ( // ErrorHandler is the interface that has custom error handling process. ErrorHandler interface { // Error handles validation errors with custom process. - Error(*macaron.Context, Errors) + Error(*http.Request, Errors) } // Validator is the interface that handles some rudimentary @@ -756,6 +710,6 @@ type ( // in your application. For example, you might verify that a credit // card number matches a valid pattern, but you probably wouldn't // perform an actual credit card authorization here. - Validate(*macaron.Context, Errors) Errors + Validate(*http.Request, Errors) Errors } ) diff --git a/vendor/gitea.com/macaron/binding/errors.go b/vendor/gitea.com/go-chi/binding/errors.go similarity index 100% rename from vendor/gitea.com/macaron/binding/errors.go rename to vendor/gitea.com/go-chi/binding/errors.go diff --git a/vendor/gitea.com/macaron/binding/go.mod b/vendor/gitea.com/go-chi/binding/go.mod similarity index 57% rename from vendor/gitea.com/macaron/binding/go.mod rename to vendor/gitea.com/go-chi/binding/go.mod index 8609495d49c2b..68e7cc5c7e948 100644 --- a/vendor/gitea.com/macaron/binding/go.mod +++ b/vendor/gitea.com/go-chi/binding/go.mod @@ -1,9 +1,9 @@ -module gitea.com/macaron/binding +module gitea.com/go-chi/binding -go 1.11 +go 1.13 require ( - gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb + github.com/go-chi/chi v1.5.1 github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e ) diff --git a/vendor/gitea.com/macaron/toolbox/go.sum b/vendor/gitea.com/go-chi/binding/go.sum similarity index 68% rename from vendor/gitea.com/macaron/toolbox/go.sum rename to vendor/gitea.com/go-chi/binding/go.sum index 56302b6a5f723..158860f7c2124 100644 --- a/vendor/gitea.com/macaron/toolbox/go.sum +++ b/vendor/gitea.com/go-chi/binding/go.sum @@ -1,7 +1,5 @@ -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ= -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs= +github.com/go-chi/chi v1.5.1 h1:kfTK3Cxd/dkMu/rKs5ZceWYp+t5CtiE7vmaTv3LjC6w= +github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -18,13 +16,7 @@ github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6x github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/vendor/gitea.com/macaron/cache/.drone.yml b/vendor/gitea.com/go-chi/cache/.drone.yml similarity index 100% rename from vendor/gitea.com/macaron/cache/.drone.yml rename to vendor/gitea.com/go-chi/cache/.drone.yml diff --git a/vendor/gitea.com/macaron/cache/.gitignore b/vendor/gitea.com/go-chi/cache/.gitignore similarity index 100% rename from vendor/gitea.com/macaron/cache/.gitignore rename to vendor/gitea.com/go-chi/cache/.gitignore diff --git a/vendor/gitea.com/macaron/cache/LICENSE b/vendor/gitea.com/go-chi/cache/LICENSE similarity index 100% rename from vendor/gitea.com/macaron/cache/LICENSE rename to vendor/gitea.com/go-chi/cache/LICENSE diff --git a/vendor/gitea.com/macaron/cache/README.md b/vendor/gitea.com/go-chi/cache/README.md similarity index 100% rename from vendor/gitea.com/macaron/cache/README.md rename to vendor/gitea.com/go-chi/cache/README.md diff --git a/vendor/gitea.com/macaron/cache/cache.go b/vendor/gitea.com/go-chi/cache/cache.go similarity index 74% rename from vendor/gitea.com/macaron/cache/cache.go rename to vendor/gitea.com/go-chi/cache/cache.go index 0893bca6c04be..79d92cc6d8903 100644 --- a/vendor/gitea.com/macaron/cache/cache.go +++ b/vendor/gitea.com/go-chi/cache/cache.go @@ -18,16 +18,8 @@ package cache import ( "fmt" - - "gitea.com/macaron/macaron" ) -const _VERSION = "0.3.0" - -func Version() string { - return _VERSION -} - // Cache is the interface that operates the cache data. type Cache interface { // Put puts value into cache with key and expire time. @@ -62,24 +54,18 @@ type Options struct { Section string } -func prepareOptions(options []Options) Options { - var opt Options - if len(options) > 0 { - opt = options[0] - } +func prepareOptions(opt Options) Options { if len(opt.Section) == 0 { opt.Section = "cache" } - sec := macaron.Config().Section(opt.Section) - if len(opt.Adapter) == 0 { - opt.Adapter = sec.Key("ADAPTER").MustString("memory") + opt.Adapter = "memory" } if opt.Interval == 0 { - opt.Interval = sec.Key("INTERVAL").MustInt(60) + opt.Interval = 60 } if len(opt.AdapterConfig) == 0 { - opt.AdapterConfig = sec.Key("ADAPTER_CONFIG").MustString("data/caches") + opt.AdapterConfig = "data/caches" } return opt @@ -87,27 +73,15 @@ func prepareOptions(options []Options) Options { // NewCacher creates and returns a new cacher by given adapter name and configuration. // It panics when given adapter isn't registered and starts GC automatically. -func NewCacher(name string, opt Options) (Cache, error) { - adapter, ok := adapters[name] +func NewCacher(opt Options) (Cache, error) { + opt = prepareOptions(opt) + adapter, ok := adapters[opt.Adapter] if !ok { - return nil, fmt.Errorf("cache: unknown adapter '%s'(forgot to import?)", name) + return nil, fmt.Errorf("cache: unknown adapter '%s'(forgot to import?)", opt.Adapter) } return adapter, adapter.StartAndGC(opt) } -// Cacher is a middleware that maps a cache.Cache service into the Macaron handler chain. -// An single variadic cache.Options struct can be optionally provided to configure. -func Cacher(options ...Options) macaron.Handler { - opt := prepareOptions(options) - cache, err := NewCacher(opt.Adapter, opt) - if err != nil { - panic(err) - } - return func(ctx *macaron.Context) { - ctx.Map(cache) - } -} - var adapters = make(map[string]Cache) // Register registers a adapter. diff --git a/vendor/gitea.com/macaron/cache/file.go b/vendor/gitea.com/go-chi/cache/file.go similarity index 98% rename from vendor/gitea.com/macaron/cache/file.go rename to vendor/gitea.com/go-chi/cache/file.go index 3a51892b41d46..d07ab0b11eff3 100644 --- a/vendor/gitea.com/macaron/cache/file.go +++ b/vendor/gitea.com/go-chi/cache/file.go @@ -26,7 +26,6 @@ import ( "sync" "time" - "gitea.com/macaron/macaron" "github.com/unknwon/com" ) @@ -191,7 +190,7 @@ func (c *FileCacher) StartAndGC(opt Options) error { c.interval = opt.Interval if !filepath.IsAbs(c.rootPath) { - c.rootPath = filepath.Join(macaron.Root, c.rootPath) + panic("rootPath must be an absolute path") } c.lock.Unlock() diff --git a/vendor/gitea.com/macaron/cache/go.mod b/vendor/gitea.com/go-chi/cache/go.mod similarity index 93% rename from vendor/gitea.com/macaron/cache/go.mod rename to vendor/gitea.com/go-chi/cache/go.mod index d214f0c34db49..3609e210bd3c2 100644 --- a/vendor/gitea.com/macaron/cache/go.mod +++ b/vendor/gitea.com/go-chi/cache/go.mod @@ -1,9 +1,8 @@ -module gitea.com/macaron/cache +module gitea.com/go-chi/cache go 1.11 require ( - gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb github.com/BurntSushi/toml v0.3.1 // indirect github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 // indirect diff --git a/vendor/gitea.com/macaron/cache/go.sum b/vendor/gitea.com/go-chi/cache/go.sum similarity index 93% rename from vendor/gitea.com/macaron/cache/go.sum rename to vendor/gitea.com/go-chi/cache/go.sum index ceec0162af202..8ed30d7a7a057 100644 --- a/vendor/gitea.com/macaron/cache/go.sum +++ b/vendor/gitea.com/go-chi/cache/go.sum @@ -1,7 +1,3 @@ -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ= -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA= @@ -70,8 +66,6 @@ github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6x github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -98,7 +92,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.44.2 h1:N6kNUPqiIyxP+s/aINPzRvNpcTVV30qLC0t6ZjZFlUU= gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/vendor/gitea.com/macaron/cache/memcache/memcache.go b/vendor/gitea.com/go-chi/cache/memcache/memcache.go similarity index 98% rename from vendor/gitea.com/macaron/cache/memcache/memcache.go rename to vendor/gitea.com/go-chi/cache/memcache/memcache.go index 79f44bfccce06..400a774569773 100644 --- a/vendor/gitea.com/macaron/cache/memcache/memcache.go +++ b/vendor/gitea.com/go-chi/cache/memcache/memcache.go @@ -21,7 +21,7 @@ import ( "github.com/bradfitz/gomemcache/memcache" "github.com/unknwon/com" - "gitea.com/macaron/cache" + "gitea.com/go-chi/cache" ) // MemcacheCacher represents a memcache cache adapter implementation. diff --git a/vendor/gitea.com/macaron/cache/memcache/memcache.goconvey b/vendor/gitea.com/go-chi/cache/memcache/memcache.goconvey similarity index 100% rename from vendor/gitea.com/macaron/cache/memcache/memcache.goconvey rename to vendor/gitea.com/go-chi/cache/memcache/memcache.goconvey diff --git a/vendor/gitea.com/macaron/cache/memory.go b/vendor/gitea.com/go-chi/cache/memory.go similarity index 100% rename from vendor/gitea.com/macaron/cache/memory.go rename to vendor/gitea.com/go-chi/cache/memory.go diff --git a/vendor/gitea.com/macaron/cache/utils.go b/vendor/gitea.com/go-chi/cache/utils.go similarity index 100% rename from vendor/gitea.com/macaron/cache/utils.go rename to vendor/gitea.com/go-chi/cache/utils.go diff --git a/vendor/gitea.com/macaron/captcha/.drone.yml b/vendor/gitea.com/go-chi/captcha/.drone.yml similarity index 100% rename from vendor/gitea.com/macaron/captcha/.drone.yml rename to vendor/gitea.com/go-chi/captcha/.drone.yml diff --git a/vendor/gitea.com/macaron/captcha/LICENSE b/vendor/gitea.com/go-chi/captcha/LICENSE similarity index 100% rename from vendor/gitea.com/macaron/captcha/LICENSE rename to vendor/gitea.com/go-chi/captcha/LICENSE diff --git a/vendor/gitea.com/macaron/captcha/README.md b/vendor/gitea.com/go-chi/captcha/README.md similarity index 100% rename from vendor/gitea.com/macaron/captcha/README.md rename to vendor/gitea.com/go-chi/captcha/README.md diff --git a/vendor/gitea.com/macaron/captcha/captcha.go b/vendor/gitea.com/go-chi/captcha/captcha.go similarity index 77% rename from vendor/gitea.com/macaron/captcha/captcha.go rename to vendor/gitea.com/go-chi/captcha/captcha.go index 283db3b43f6a6..9d7e1f2ccbc25 100644 --- a/vendor/gitea.com/macaron/captcha/captcha.go +++ b/vendor/gitea.com/go-chi/captcha/captcha.go @@ -20,11 +20,11 @@ import ( "fmt" "html/template" "image/color" + "net/http" "path" "strings" - "gitea.com/macaron/cache" - "gitea.com/macaron/macaron" + "gitea.com/go-chi/cache" "github.com/unknwon/com" ) @@ -40,7 +40,7 @@ var ( // Captcha represents a captcha service. type Captcha struct { - store cache.Cache + Store cache.Cache SubURL string URLPrefix string FieldIdName string @@ -75,22 +75,17 @@ func (c *Captcha) CreateHTML() template.HTML { `, c.FieldIdName, value, c.SubURL, c.URLPrefix)) } -// DEPRECATED -func (c *Captcha) CreateHtml() template.HTML { - return c.CreateHTML() -} - // create a new captcha id func (c *Captcha) CreateCaptcha() (string, error) { id := string(com.RandomCreateBytes(15)) - if err := c.store.Put(c.key(id), c.genRandChars(), c.Expiration); err != nil { + if err := c.Store.Put(c.key(id), c.genRandChars(), c.Expiration); err != nil { return "", err } return id, nil } // verify from a request -func (c *Captcha) VerifyReq(req macaron.Request) bool { +func (c *Captcha) VerifyReq(req *http.Request) bool { req.ParseForm() return c.Verify(req.Form.Get(c.FieldIdName), req.Form.Get(c.FieldCaptchaName)) } @@ -105,13 +100,13 @@ func (c *Captcha) Verify(id string, challenge string) bool { key := c.key(id) - if v, ok := c.store.Get(key).(string); ok { + if v, ok := c.Store.Get(key).(string); ok { chars = v } else { return false } - defer c.store.Delete(key) + defer c.Store.Delete(key) if len(chars) != len(challenge) { return false @@ -191,7 +186,8 @@ func prepareOptions(options []Options) Options { } // NewCaptcha initializes and returns a captcha with given options. -func NewCaptcha(opt Options) *Captcha { +func NewCaptcha(opts ...Options) *Captcha { + opt := prepareOptions(opts) return &Captcha{ SubURL: opt.SubURL, URLPrefix: opt.URLPrefix, @@ -209,45 +205,44 @@ func NewCaptcha(opt Options) *Captcha { // Captchaer is a middleware that maps a captcha.Captcha service into the Macaron handler chain. // An single variadic captcha.Options struct can be optionally provided to configure. // This should be register after cache.Cacher. -func Captchaer(options ...Options) macaron.Handler { - return func(ctx *macaron.Context, cache cache.Cache) { - cpt := NewCaptcha(prepareOptions(options)) - cpt.store = cache - - if strings.HasPrefix(ctx.Req.URL.Path, cpt.URLPrefix) { - var chars string - id := path.Base(ctx.Req.URL.Path) - if i := strings.Index(id, "."); i > -1 { - id = id[:i] - } - key := cpt.key(id) - - // Reload captcha. - if len(ctx.Query("reload")) > 0 { - chars = cpt.genRandChars() - if err := cpt.store.Put(key, chars, cpt.Expiration); err != nil { - ctx.Status(500) - ctx.Write([]byte("captcha reload error")) - panic(fmt.Errorf("reload captcha: %v", err)) +func Captchaer(cpt *Captcha) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + if strings.HasPrefix(req.URL.Path, cpt.URLPrefix) { + var chars string + id := path.Base(req.URL.Path) + if i := strings.Index(id, "."); i > -1 { + id = id[:i] } - } else { - if v, ok := cpt.store.Get(key).(string); ok { - chars = v + key := cpt.key(id) + + reloads := req.URL.Query()["reload"] + // Reload captcha. + if len(reloads) > 0 && len(reloads[0]) > 0 { + chars = cpt.genRandChars() + if err := cpt.Store.Put(key, chars, cpt.Expiration); err != nil { + w.WriteHeader(500) + w.Write([]byte("captcha reload error")) + panic(fmt.Errorf("reload captcha: %v", err)) + } } else { - ctx.Status(404) - ctx.Write([]byte("captcha not found")) - return + if v, ok := cpt.Store.Get(key).(string); ok { + chars = v + } else { + w.WriteHeader(404) + w.Write([]byte("captcha not found")) + return + } } - } - ctx.Status(200) - if _, err := NewImage([]byte(chars), cpt.StdWidth, cpt.StdHeight, cpt.ColorPalette).WriteTo(ctx.Resp); err != nil { - panic(fmt.Errorf("write captcha: %v", err)) + w.WriteHeader(200) + if _, err := NewImage([]byte(chars), cpt.StdWidth, cpt.StdHeight, cpt.ColorPalette).WriteTo(w); err != nil { + panic(fmt.Errorf("write captcha: %v", err)) + } + return } - return - } - ctx.Data["Captcha"] = cpt - ctx.Map(cpt) + next.ServeHTTP(w, req) + }) } } diff --git a/vendor/gitea.com/macaron/toolbox/go.mod b/vendor/gitea.com/go-chi/captcha/go.mod similarity index 55% rename from vendor/gitea.com/macaron/toolbox/go.mod rename to vendor/gitea.com/go-chi/captcha/go.mod index f54b8074cad62..adbf9ffb40daa 100644 --- a/vendor/gitea.com/macaron/toolbox/go.mod +++ b/vendor/gitea.com/go-chi/captcha/go.mod @@ -1,9 +1,10 @@ -module gitea.com/macaron/toolbox +module gitea.com/go-chi/captcha go 1.11 require ( - gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb + gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e + github.com/go-chi/chi v1.5.1 github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e ) diff --git a/vendor/gitea.com/macaron/captcha/go.sum b/vendor/gitea.com/go-chi/captcha/go.sum similarity index 85% rename from vendor/gitea.com/macaron/captcha/go.sum rename to vendor/gitea.com/go-chi/captcha/go.sum index 6c6f0e4b6618c..ab69564a0cae1 100644 --- a/vendor/gitea.com/macaron/captcha/go.sum +++ b/vendor/gitea.com/go-chi/captcha/go.sum @@ -1,20 +1,19 @@ -gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76 h1:mMsMEg90c5KXQgRWsH8D6GHXfZIW1RAe5S9VYIb12lM= -gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76/go.mod h1:NFHb9Of+LUnU86bU20CiXXg6ZlgCJ4XytP14UsHOXFs= -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ= -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs= +gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e h1:zgPGaf3kXP0cVm9J0l8ZA2+XDzILYATg0CXbihR6N+o= +gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e/go.mod h1:k2V/gPDEtXGjjMGuBJiapffAXTv76H4snSmlJRLUhH0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-chi/chi v1.5.1 h1:kfTK3Cxd/dkMu/rKs5ZceWYp+t5CtiE7vmaTv3LjC6w= +github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k= github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -31,7 +30,7 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY= github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= @@ -47,8 +46,6 @@ github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6x github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -69,8 +66,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.44.2 h1:N6kNUPqiIyxP+s/aINPzRvNpcTVV30qLC0t6ZjZFlUU= gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/vendor/gitea.com/macaron/captcha/image.go b/vendor/gitea.com/go-chi/captcha/image.go similarity index 100% rename from vendor/gitea.com/macaron/captcha/image.go rename to vendor/gitea.com/go-chi/captcha/image.go diff --git a/vendor/gitea.com/macaron/captcha/siprng.go b/vendor/gitea.com/go-chi/captcha/siprng.go similarity index 100% rename from vendor/gitea.com/macaron/captcha/siprng.go rename to vendor/gitea.com/go-chi/captcha/siprng.go diff --git a/vendor/gitea.com/lunny/log/.gitignore b/vendor/gitea.com/lunny/log/.gitignore deleted file mode 100644 index 3a11644b45701..0000000000000 --- a/vendor/gitea.com/lunny/log/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -log.db -*.log -logs -.vscode \ No newline at end of file diff --git a/vendor/gitea.com/lunny/log/LICENSE b/vendor/gitea.com/lunny/log/LICENSE deleted file mode 100644 index c9338f8293393..0000000000000 --- a/vendor/gitea.com/lunny/log/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2014 - 2016 lunny -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the {organization} nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/gitea.com/lunny/log/README.md b/vendor/gitea.com/lunny/log/README.md deleted file mode 100644 index be63a4d373b2a..0000000000000 --- a/vendor/gitea.com/lunny/log/README.md +++ /dev/null @@ -1,51 +0,0 @@ -## log - -[![](https://goreportcard.com/badge/gitea.com/lunny/log)](https://goreportcard.com/report/gitea.com/lunny/log) -[![GoDoc](https://godoc.org/gitea.com/lunny/log?status.png)](https://godoc.org/gitea.com/lunny/log) - -[简体中文](https://gitea.com/lunny/log/blob/master/README_CN.md) - -# Installation - -``` -go get gitea.com/lunny/log -``` - -# Features - -* Add color support for unix console -* Implemented dbwriter to save log to database -* Implemented FileWriter to save log to file by date or time. -* Location configuration - -# Example - -For Single File: -```Go -f, _ := os.Create("my.log") -log.Std.SetOutput(f) -``` - -For Multiple Writer: -```Go -f, _ := os.Create("my.log") -log.Std.SetOutput(io.MultiWriter(f, os.Stdout)) -``` - -For log files by date or time: -```Go -w := log.NewFileWriter(log.FileOptions{ - ByType:log.ByDay, - Dir:"./logs", -}) -log.Std.SetOutput(w) -``` - -# About - -This repo is an extension of Golang log. - -# LICENSE - - BSD License - [http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/) diff --git a/vendor/gitea.com/lunny/log/README_CN.md b/vendor/gitea.com/lunny/log/README_CN.md deleted file mode 100644 index 29cd6c1ca494e..0000000000000 --- a/vendor/gitea.com/lunny/log/README_CN.md +++ /dev/null @@ -1,54 +0,0 @@ -## log - -[![](https://goreportcard.com/badge/gitea.com/lunny/log)](https://goreportcard.com/report/gitea.com/lunny/log) -[![GoDoc](https://godoc.org/gitea.com/lunny/log?status.png)](https://godoc.org/gitea.com/lunny/log) - -[English](https://gitea.com/lunny/log/blob/master/README.md) - -# 安装 - -``` -go get gitea.com/lunny/log -``` - -# 特性 - -* 对unix增加控制台颜色支持 -* 实现了保存log到数据库支持 -* 实现了保存log到按日期的文件支持 -* 实现了设置日期的地区 - -# 例子 - -保存到单个文件: - -```Go -f, _ := os.Create("my.log") -log.Std.SetOutput(f) -``` - -保存到数据库: - -```Go -f, _ := os.Create("my.log") -log.Std.SetOutput(io.MultiWriter(f, os.Stdout)) -``` - -保存到按时间分隔的文件: - -```Go -w := log.NewFileWriter(log.FileOptions{ - ByType:log.ByDay, - Dir:"./logs", -}) -log.Std.SetOutput(w) -``` - -# 关于 - -本 Log 是在 golang 的 log 之上的扩展 - -# LICENSE - - BSD License - [http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/) diff --git a/vendor/gitea.com/lunny/log/dbwriter.go b/vendor/gitea.com/lunny/log/dbwriter.go deleted file mode 100644 index e8ff00bd89643..0000000000000 --- a/vendor/gitea.com/lunny/log/dbwriter.go +++ /dev/null @@ -1,36 +0,0 @@ -package log - -import ( - "database/sql" - "time" -) - -type DBWriter struct { - db *sql.DB - stmt *sql.Stmt - content chan []byte -} - -func NewDBWriter(db *sql.DB) (*DBWriter, error) { - _, err := db.Exec("CREATE TABLE IF NOT EXISTS log (id int, content text, created datetime)") - if err != nil { - return nil, err - } - stmt, err := db.Prepare("INSERT INTO log (content, created) values (?, ?)") - if err != nil { - return nil, err - } - return &DBWriter{db, stmt, make(chan []byte, 1000)}, nil -} - -func (w *DBWriter) Write(p []byte) (n int, err error) { - _, err = w.stmt.Exec(string(p), time.Now()) - if err == nil { - n = len(p) - } - return -} - -func (w *DBWriter) Close() { - w.stmt.Close() -} diff --git a/vendor/gitea.com/lunny/log/filewriter.go b/vendor/gitea.com/lunny/log/filewriter.go deleted file mode 100644 index f0bb4d1df1b20..0000000000000 --- a/vendor/gitea.com/lunny/log/filewriter.go +++ /dev/null @@ -1,112 +0,0 @@ -package log - -import ( - "io" - "os" - "path/filepath" - "sync" - "time" -) - -var _ io.Writer = &Files{} - -type ByType int - -const ( - ByDay ByType = iota - ByHour - ByMonth -) - -var ( - formats = map[ByType]string{ - ByDay: "2006-01-02", - ByHour: "2006-01-02-15", - ByMonth: "2006-01", - } -) - -func SetFileFormat(t ByType, format string) { - formats[t] = format -} - -func (b ByType) Format() string { - return formats[b] -} - -type Files struct { - FileOptions - f *os.File - lastFormat string - lock sync.Mutex -} - -type FileOptions struct { - Dir string - ByType ByType - Loc *time.Location -} - -func prepareFileOption(opts []FileOptions) FileOptions { - var opt FileOptions - if len(opts) > 0 { - opt = opts[0] - } - if opt.Dir == "" { - opt.Dir = "./" - } - err := os.MkdirAll(opt.Dir, os.ModePerm) - if err != nil { - panic(err.Error()) - } - - if opt.Loc == nil { - opt.Loc = time.Local - } - return opt -} - -func NewFileWriter(opts ...FileOptions) *Files { - opt := prepareFileOption(opts) - return &Files{ - FileOptions: opt, - } -} - -func (f *Files) getFile() (*os.File, error) { - var err error - t := time.Now().In(f.Loc) - if f.f == nil { - f.lastFormat = t.Format(f.ByType.Format()) - f.f, err = os.OpenFile(filepath.Join(f.Dir, f.lastFormat+".log"), - os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) - return f.f, err - } - if f.lastFormat != t.Format(f.ByType.Format()) { - f.f.Close() - f.lastFormat = t.Format(f.ByType.Format()) - f.f, err = os.OpenFile(filepath.Join(f.Dir, f.lastFormat+".log"), - os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) - return f.f, err - } - return f.f, nil -} - -func (f *Files) Write(bs []byte) (int, error) { - f.lock.Lock() - defer f.lock.Unlock() - - w, err := f.getFile() - if err != nil { - return 0, err - } - return w.Write(bs) -} - -func (f *Files) Close() { - if f.f != nil { - f.f.Close() - f.f = nil - } - f.lastFormat = "" -} diff --git a/vendor/gitea.com/lunny/log/go.mod b/vendor/gitea.com/lunny/log/go.mod deleted file mode 100644 index f756706435b6a..0000000000000 --- a/vendor/gitea.com/lunny/log/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module gitea.com/lunny/log - -go 1.12 - -require github.com/mattn/go-sqlite3 v1.10.0 diff --git a/vendor/gitea.com/lunny/log/go.sum b/vendor/gitea.com/lunny/log/go.sum deleted file mode 100644 index 263c18737ee31..0000000000000 --- a/vendor/gitea.com/lunny/log/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= diff --git a/vendor/gitea.com/lunny/log/logext.go b/vendor/gitea.com/lunny/log/logext.go deleted file mode 100644 index 215c45f309358..0000000000000 --- a/vendor/gitea.com/lunny/log/logext.go +++ /dev/null @@ -1,595 +0,0 @@ -package log - -import ( - "bytes" - "fmt" - "io" - "os" - "runtime" - "strings" - "sync" - "time" -) - -// These flags define which text to prefix to each log entry generated by the Logger. -const ( - // Bits or'ed together to control what's printed. There is no control over the - // order they appear (the order listed here) or the format they present (as - // described in the comments). A colon appears after these items: - // 2009/0123 01:23:23.123123 /a/b/c/d.go:23: message - Ldate = 1 << iota // the date: 2009/0123 - Ltime // the time: 01:23:23 - Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. - Llongfile // full file name and line number: /a/b/c/d.go:23 - Lshortfile // final file name element and line number: d.go:23. overrides Llongfile - Lmodule // module name - Llevel // level: 0(Debug), 1(Info), 2(Warn), 3(Error), 4(Panic), 5(Fatal) - Llongcolor // color will start [info] end of line - Lshortcolor // color only include [info] - LstdFlags = Ldate | Ltime // initial values for the standard logger - //Ldefault = Llevel | LstdFlags | Lshortfile | Llongcolor -) // [prefix][time][level][module][shortfile|longfile] - -func Ldefault() int { - if runtime.GOOS == "windows" { - return Llevel | LstdFlags | Lshortfile - } - return Llevel | LstdFlags | Lshortfile | Llongcolor -} - -func Version() string { - return "0.2.0.1121" -} - -const ( - Lall = iota -) -const ( - Ldebug = iota - Linfo - Lwarn - Lerror - Lpanic - Lfatal - Lnone -) - -const ( - ForeBlack = iota + 30 //30 - ForeRed //31 - ForeGreen //32 - ForeYellow //33 - ForeBlue //34 - ForePurple //35 - ForeCyan //36 - ForeWhite //37 -) - -const ( - BackBlack = iota + 40 //40 - BackRed //41 - BackGreen //42 - BackYellow //43 - BackBlue //44 - BackPurple //45 - BackCyan //46 - BackWhite //47 -) - -var levels = []string{ - "[Debug]", - "[Info]", - "[Warn]", - "[Error]", - "[Panic]", - "[Fatal]", -} - -// MUST called before all logs -func SetLevels(lvs []string) { - levels = lvs -} - -var colors = []int{ - ForeCyan, - ForeGreen, - ForeYellow, - ForeRed, - ForePurple, - ForeBlue, -} - -// MUST called before all logs -func SetColors(cls []int) { - colors = cls -} - -// A Logger represents an active logging object that generates lines of -// output to an io.Writer. Each logging operation makes a single call to -// the Writer's Write method. A Logger can be used simultaneously from -// multiple goroutines; it guarantees to serialize access to the Writer. -type Logger struct { - mu sync.Mutex // ensures atomic writes; protects the following fields - prefix string // prefix to write at beginning of each line - flag int // properties - Level int - out io.Writer // destination for output - buf bytes.Buffer // for accumulating text to write - levelStats [6]int64 - loc *time.Location -} - -// New creates a new Logger. The out variable sets the -// destination to which log data will be written. -// The prefix appears at the beginning of each generated log line. -// The flag argument defines the logging properties. -func New(out io.Writer, prefix string, flag int) *Logger { - l := &Logger{out: out, prefix: prefix, Level: 1, flag: flag, loc: time.Local} - if out != os.Stdout { - l.flag = RmColorFlags(l.flag) - } - return l -} - -var Std = New(os.Stderr, "", Ldefault()) - -// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. -// Knows the buffer has capacity. -func itoa(buf *bytes.Buffer, i int, wid int) { - var u uint = uint(i) - if u == 0 && wid <= 1 { - buf.WriteByte('0') - return - } - - // Assemble decimal in reverse order. - var b [32]byte - bp := len(b) - for ; u > 0 || wid > 0; u /= 10 { - bp-- - wid-- - b[bp] = byte(u%10) + '0' - } - - // avoid slicing b to avoid an allocation. - for bp < len(b) { - buf.WriteByte(b[bp]) - bp++ - } -} - -func moduleOf(file string) string { - pos := strings.LastIndex(file, "/") - if pos != -1 { - pos1 := strings.LastIndex(file[:pos], "/src/") - if pos1 != -1 { - return file[pos1+5 : pos] - } - } - return "UNKNOWN" -} - -func (l *Logger) formatHeader(buf *bytes.Buffer, t time.Time, - file string, line int, lvl int, reqId string) { - if l.prefix != "" { - buf.WriteString(l.prefix) - } - if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 { - if l.flag&Ldate != 0 { - year, month, day := t.Date() - itoa(buf, year, 4) - buf.WriteByte('/') - itoa(buf, int(month), 2) - buf.WriteByte('/') - itoa(buf, day, 2) - buf.WriteByte(' ') - } - if l.flag&(Ltime|Lmicroseconds) != 0 { - hour, min, sec := t.Clock() - itoa(buf, hour, 2) - buf.WriteByte(':') - itoa(buf, min, 2) - buf.WriteByte(':') - itoa(buf, sec, 2) - if l.flag&Lmicroseconds != 0 { - buf.WriteByte('.') - itoa(buf, t.Nanosecond()/1e3, 6) - } - buf.WriteByte(' ') - } - } - if reqId != "" { - buf.WriteByte('[') - buf.WriteString(reqId) - buf.WriteByte(']') - buf.WriteByte(' ') - } - - if l.flag&(Lshortcolor|Llongcolor) != 0 { - buf.WriteString(fmt.Sprintf("\033[1;%dm", colors[lvl])) - } - if l.flag&Llevel != 0 { - buf.WriteString(levels[lvl]) - buf.WriteByte(' ') - } - if l.flag&Lshortcolor != 0 { - buf.WriteString("\033[0m") - } - - if l.flag&Lmodule != 0 { - buf.WriteByte('[') - buf.WriteString(moduleOf(file)) - buf.WriteByte(']') - buf.WriteByte(' ') - } - if l.flag&(Lshortfile|Llongfile) != 0 { - if l.flag&Lshortfile != 0 { - short := file - for i := len(file) - 1; i > 0; i-- { - if file[i] == '/' { - short = file[i+1:] - break - } - } - file = short - } - buf.WriteString(file) - buf.WriteByte(':') - itoa(buf, line, -1) - buf.WriteByte(' ') - } -} - -// Output writes the output for a logging event. The string s contains -// the text to print after the prefix specified by the flags of the -// Logger. A newline is appended if the last character of s is not -// already a newline. Calldepth is used to recover the PC and is -// provided for generality, although at the moment on all pre-defined -// paths it will be 2. -func (l *Logger) Output(reqId string, lvl int, calldepth int, s string) error { - if lvl < l.Level { - return nil - } - now := time.Now().In(l.loc) // get this early. - var file string - var line int - l.mu.Lock() - defer l.mu.Unlock() - if l.flag&(Lshortfile|Llongfile|Lmodule) != 0 { - // release lock while getting caller info - it's expensive. - l.mu.Unlock() - var ok bool - _, file, line, ok = runtime.Caller(calldepth) - if !ok { - file = "???" - line = 0 - } - l.mu.Lock() - } - l.levelStats[lvl]++ - l.buf.Reset() - l.formatHeader(&l.buf, now, file, line, lvl, reqId) - l.buf.WriteString(s) - if l.flag&Llongcolor != 0 { - l.buf.WriteString("\033[0m") - } - if len(s) > 0 && s[len(s)-1] != '\n' { - l.buf.WriteByte('\n') - } - _, err := l.out.Write(l.buf.Bytes()) - return err -} - -// ----------------------------------------- - -// Printf calls l.Output to print to the logger. -// Arguments are handled in the manner of fmt.Printf. -func (l *Logger) Printf(format string, v ...interface{}) { - l.Output("", Linfo, 2, fmt.Sprintf(format, v...)) -} - -// Print calls l.Output to print to the logger. -// Arguments are handled in the manner of fmt.Print. -func (l *Logger) Print(v ...interface{}) { - l.Output("", Linfo, 2, fmt.Sprint(v...)) -} - -// Println calls l.Output to print to the logger. -// Arguments are handled in the manner of fmt.Println. -func (l *Logger) Println(v ...interface{}) { - l.Output("", Linfo, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- - -func (l *Logger) Debugf(format string, v ...interface{}) { - l.Output("", Ldebug, 2, fmt.Sprintf(format, v...)) -} - -func (l *Logger) Debug(v ...interface{}) { - l.Output("", Ldebug, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- -func (l *Logger) Infof(format string, v ...interface{}) { - l.Output("", Linfo, 2, fmt.Sprintf(format, v...)) -} - -func (l *Logger) Info(v ...interface{}) { - l.Output("", Linfo, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- -func (l *Logger) Warnf(format string, v ...interface{}) { - l.Output("", Lwarn, 2, fmt.Sprintf(format, v...)) -} - -func (l *Logger) Warn(v ...interface{}) { - l.Output("", Lwarn, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- - -func (l *Logger) Errorf(format string, v ...interface{}) { - l.Output("", Lerror, 2, fmt.Sprintf(format, v...)) -} - -func (l *Logger) Error(v ...interface{}) { - l.Output("", Lerror, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- - -func (l *Logger) Fatal(v ...interface{}) { - l.Output("", Lfatal, 2, fmt.Sprintln(v...)) - os.Exit(1) -} - -// Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1). -func (l *Logger) Fatalf(format string, v ...interface{}) { - l.Output("", Lfatal, 2, fmt.Sprintf(format, v...)) - os.Exit(1) -} - -// ----------------------------------------- -// Panic is equivalent to l.Print() followed by a call to panic(). -func (l *Logger) Panic(v ...interface{}) { - s := fmt.Sprintln(v...) - l.Output("", Lpanic, 2, s) - panic(s) -} - -// Panicf is equivalent to l.Printf() followed by a call to panic(). -func (l *Logger) Panicf(format string, v ...interface{}) { - s := fmt.Sprintf(format, v...) - l.Output("", Lpanic, 2, s) - panic(s) -} - -// ----------------------------------------- -func (l *Logger) Stack(v ...interface{}) { - s := fmt.Sprint(v...) - s += "\n" - buf := make([]byte, 1024*1024) - n := runtime.Stack(buf, true) - s += string(buf[:n]) - s += "\n" - l.Output("", Lerror, 2, s) -} - -// ----------------------------------------- -func (l *Logger) Stat() (stats []int64) { - l.mu.Lock() - v := l.levelStats - l.mu.Unlock() - return v[:] -} - -// Flags returns the output flags for the logger. -func (l *Logger) Flags() int { - l.mu.Lock() - defer l.mu.Unlock() - return l.flag -} - -func RmColorFlags(flag int) int { - // for un std out, it should not show color since almost them don't support - if flag&Llongcolor != 0 { - flag = flag ^ Llongcolor - } - if flag&Lshortcolor != 0 { - flag = flag ^ Lshortcolor - } - return flag -} - -func (l *Logger) Location() *time.Location { - return l.loc -} - -func (l *Logger) SetLocation(loc *time.Location) { - l.loc = loc -} - -// SetFlags sets the output flags for the logger. -func (l *Logger) SetFlags(flag int) { - l.mu.Lock() - defer l.mu.Unlock() - if l.out != os.Stdout { - flag = RmColorFlags(flag) - } - l.flag = flag -} - -// Prefix returns the output prefix for the logger. -func (l *Logger) Prefix() string { - l.mu.Lock() - defer l.mu.Unlock() - return l.prefix -} - -// SetPrefix sets the output prefix for the logger. -func (l *Logger) SetPrefix(prefix string) { - l.mu.Lock() - defer l.mu.Unlock() - l.prefix = prefix -} - -// SetOutputLevel sets the output level for the logger. -func (l *Logger) SetOutputLevel(lvl int) { - l.mu.Lock() - defer l.mu.Unlock() - l.Level = lvl -} - -func (l *Logger) OutputLevel() int { - return l.Level -} - -func (l *Logger) SetOutput(w io.Writer) { - l.mu.Lock() - defer l.mu.Unlock() - l.out = w - if w != os.Stdout { - l.flag = RmColorFlags(l.flag) - } -} - -// SetOutput sets the output destination for the standard logger. -func SetOutput(w io.Writer) { - Std.SetOutput(w) -} - -func SetLocation(loc *time.Location) { - Std.SetLocation(loc) -} - -func Location() *time.Location { - return Std.Location() -} - -// Flags returns the output flags for the standard logger. -func Flags() int { - return Std.Flags() -} - -// SetFlags sets the output flags for the standard logger. -func SetFlags(flag int) { - Std.SetFlags(flag) -} - -// Prefix returns the output prefix for the standard logger. -func Prefix() string { - return Std.Prefix() -} - -// SetPrefix sets the output prefix for the standard logger. -func SetPrefix(prefix string) { - Std.SetPrefix(prefix) -} - -func SetOutputLevel(lvl int) { - Std.SetOutputLevel(lvl) -} - -func OutputLevel() int { - return Std.OutputLevel() -} - -// ----------------------------------------- - -// Print calls Output to print to the standard logger. -// Arguments are handled in the manner of fmt.Print. -func Print(v ...interface{}) { - Std.Output("", Linfo, 2, fmt.Sprintln(v...)) -} - -// Printf calls Output to print to the standard logger. -// Arguments are handled in the manner of fmt.Printf. -func Printf(format string, v ...interface{}) { - Std.Output("", Linfo, 2, fmt.Sprintf(format, v...)) -} - -// Println calls Output to print to the standard logger. -// Arguments are handled in the manner of fmt.Println. -func Println(v ...interface{}) { - Std.Output("", Linfo, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- - -func Debugf(format string, v ...interface{}) { - Std.Output("", Ldebug, 2, fmt.Sprintf(format, v...)) -} - -func Debug(v ...interface{}) { - Std.Output("", Ldebug, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- - -func Infof(format string, v ...interface{}) { - Std.Output("", Linfo, 2, fmt.Sprintf(format, v...)) -} - -func Info(v ...interface{}) { - Std.Output("", Linfo, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- - -func Warnf(format string, v ...interface{}) { - Std.Output("", Lwarn, 2, fmt.Sprintf(format, v...)) -} - -func Warn(v ...interface{}) { - Std.Output("", Lwarn, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- - -func Errorf(format string, v ...interface{}) { - Std.Output("", Lerror, 2, fmt.Sprintf(format, v...)) -} - -func Error(v ...interface{}) { - Std.Output("", Lerror, 2, fmt.Sprintln(v...)) -} - -// ----------------------------------------- - -// Fatal is equivalent to Print() followed by a call to os.Exit(1). -func Fatal(v ...interface{}) { - Std.Output("", Lfatal, 2, fmt.Sprintln(v...)) -} - -// Fatalf is equivalent to Printf() followed by a call to os.Exit(1). -func Fatalf(format string, v ...interface{}) { - Std.Output("", Lfatal, 2, fmt.Sprintf(format, v...)) -} - -// ----------------------------------------- - -// Panic is equivalent to Print() followed by a call to panic(). -func Panic(v ...interface{}) { - Std.Output("", Lpanic, 2, fmt.Sprintln(v...)) -} - -// Panicf is equivalent to Printf() followed by a call to panic(). -func Panicf(format string, v ...interface{}) { - Std.Output("", Lpanic, 2, fmt.Sprintf(format, v...)) -} - -// ----------------------------------------- - -func Stack(v ...interface{}) { - s := fmt.Sprint(v...) - s += "\n" - buf := make([]byte, 1024*1024) - n := runtime.Stack(buf, true) - s += string(buf[:n]) - s += "\n" - Std.Output("", Lerror, 2, s) -} - -// ----------------------------------------- diff --git a/vendor/gitea.com/lunny/nodb/.gitignore b/vendor/gitea.com/lunny/nodb/.gitignore deleted file mode 100644 index 8f4051772ab95..0000000000000 --- a/vendor/gitea.com/lunny/nodb/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -build -*.pyc -.DS_Store -nohup.out -build_config.mk -var -.vscode diff --git a/vendor/gitea.com/lunny/nodb/LICENSE b/vendor/gitea.com/lunny/nodb/LICENSE deleted file mode 100644 index 7ece9fdf5a64c..0000000000000 --- a/vendor/gitea.com/lunny/nodb/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 siddontang - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/vendor/gitea.com/lunny/nodb/README.md b/vendor/gitea.com/lunny/nodb/README.md deleted file mode 100644 index 673424338a7ee..0000000000000 --- a/vendor/gitea.com/lunny/nodb/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# NoDB - -[中文](https://gitea.com/lunny/nodb/blob/master/README_CN.md) - -Nodb is a fork of [ledisdb](https://github.com/siddontang/ledisdb) and shrink version. It's get rid of all C or other language codes and only keep Go's. It aims to provide a nosql database library rather than a redis like server. So if you want a redis like server, ledisdb is the best choose. - -Nodb is a pure Go and high performance NoSQL database library. It supports some data structure like kv, list, hash, zset, bitmap, set. - -Nodb now use [goleveldb](https://github.com/syndtr/goleveldb) as backend to store data. - -## Features - -+ Rich data structure: KV, List, Hash, ZSet, Bitmap, Set. -+ Stores lots of data, over the memory limit. -+ Supports expiration and ttl. -+ Easy to embed in your own Go application. - -## Install - - go get gitea.com/lunny/nodb - -## Package Example - -### Open And Select database -```go -import( - "gitea.com/lunny/nodb" - "gitea.com/lunny/nodb/config" -) - -cfg := new(config.Config) -cfg.DataDir = "./" -dbs, err := nodb.Open(cfg) -if err != nil { - fmt.Printf("nodb: error opening db: %v", err) -} - -db, _ := dbs.Select(0) -``` -### KV - -KV is the most basic nodb type like any other key-value database. -```go -err := db.Set(key, value) -value, err := db.Get(key) -``` -### List - -List is simply lists of values, sorted by insertion order. -You can push or pop value on the list head (left) or tail (right). -```go -err := db.LPush(key, value1) -err := db.RPush(key, value2) -value1, err := db.LPop(key) -value2, err := db.RPop(key) -``` -### Hash - -Hash is a map between fields and values. -```go -n, err := db.HSet(key, field1, value1) -n, err := db.HSet(key, field2, value2) -value1, err := db.HGet(key, field1) -value2, err := db.HGet(key, field2) -``` -### ZSet - -ZSet is a sorted collections of values. -Every member of zset is associated with score, a int64 value which used to sort, from smallest to greatest score. -Members are unique, but score may be same. -```go -n, err := db.ZAdd(key, ScorePair{score1, member1}, ScorePair{score2, member2}) -ay, err := db.ZRangeByScore(key, minScore, maxScore, 0, -1) -``` -## Links - -+ [Ledisdb Official Website](http://ledisdb.com) -+ [GoDoc](https://godoc.org/gitea.com/lunny/nodb) - - -## Thanks - -Gmail: siddontang@gmail.com diff --git a/vendor/gitea.com/lunny/nodb/README_CN.md b/vendor/gitea.com/lunny/nodb/README_CN.md deleted file mode 100644 index adbf51dcec509..0000000000000 --- a/vendor/gitea.com/lunny/nodb/README_CN.md +++ /dev/null @@ -1,80 +0,0 @@ -# NoDB - -[English](https://gitea.com/lunny/nodb/blob/master/README.md) - -Nodb 是 [ledisdb](https://github.com/siddontang/ledisdb) 的克隆和缩减版本。该版本去掉了所有C和其它语言的依赖,只保留Go语言的。目标是提供一个Nosql数据库的开发库而不是提供一个像Redis那样的服务器。因此如果你想要的是一个独立服务器,你可以直接选择ledisdb。 - -Nodb 是一个纯Go的高性能 NoSQL 数据库。他支持 kv, list, hash, zset, bitmap, set 等数据结构。 - -Nodb 当前底层使用 (goleveldb)[https://github.com/syndtr/goleveldb] 来存储数据。 - -## 特性 - -+ 丰富的数据结构支持: KV, List, Hash, ZSet, Bitmap, Set。 -+ 永久存储并且不受内存的限制。 -+ 高性能那个。 -+ 可以方便的嵌入到你的应用程序中。 - -## 安装 - - go get gitea.com/lunny/nodb - -## 例子 - -### 打开和选择数据库 -```go -import( - "gitea.com/lunny/nodb" - "gitea.com/lunny/nodb/config" -) - -cfg := new(config.Config) -cfg.DataDir = "./" -dbs, err := nodb.Open(cfg) -if err != nil { - fmt.Printf("nodb: error opening db: %v", err) -} -db, _ := dbs.Select(0) -``` -### KV - -KV 是最基础的功能,和其它Nosql一样。 -```go -err := db.Set(key, value) -value, err := db.Get(key) -``` -### List - -List 是一些值的简单列表,按照插入的顺序排列。你可以从左或右push和pop值。 -```go -err := db.LPush(key, value1) -err := db.RPush(key, value2) -value1, err := db.LPop(key) -value2, err := db.RPop(key) -``` -### Hash - -Hash 是一个field和value对应的map。 -```go -n, err := db.HSet(key, field1, value1) -n, err := db.HSet(key, field2, value2) -value1, err := db.HGet(key, field1) -value2, err := db.HGet(key, field2) -``` -### ZSet - -ZSet 是一个排序的值集合。zset的每个成员对应一个score,这是一个int64的值用于从小到大排序。成员不可重复,但是score可以相同。 -```go -n, err := db.ZAdd(key, ScorePair{score1, member1}, ScorePair{score2, member2}) -ay, err := db.ZRangeByScore(key, minScore, maxScore, 0, -1) -``` - -## 链接 - -+ [Ledisdb Official Website](http://ledisdb.com) -+ [GoDoc](https://godoc.org/gitea.com/lunny/nodb) - - -## 感谢 - -Gmail: siddontang@gmail.com diff --git a/vendor/gitea.com/lunny/nodb/batch.go b/vendor/gitea.com/lunny/nodb/batch.go deleted file mode 100644 index e2bc28995b057..0000000000000 --- a/vendor/gitea.com/lunny/nodb/batch.go +++ /dev/null @@ -1,106 +0,0 @@ -package nodb - -import ( - "sync" - - "gitea.com/lunny/nodb/store" -) - -type batch struct { - l *Nodb - - store.WriteBatch - - sync.Locker - - logs [][]byte - - tx *Tx -} - -func (b *batch) Commit() error { - b.l.commitLock.Lock() - defer b.l.commitLock.Unlock() - - err := b.WriteBatch.Commit() - - if b.l.binlog != nil { - if err == nil { - if b.tx == nil { - b.l.binlog.Log(b.logs...) - } else { - b.tx.logs = append(b.tx.logs, b.logs...) - } - } - b.logs = [][]byte{} - } - - return err -} - -func (b *batch) Lock() { - b.Locker.Lock() -} - -func (b *batch) Unlock() { - if b.l.binlog != nil { - b.logs = [][]byte{} - } - b.WriteBatch.Rollback() - b.Locker.Unlock() -} - -func (b *batch) Put(key []byte, value []byte) { - if b.l.binlog != nil { - buf := encodeBinLogPut(key, value) - b.logs = append(b.logs, buf) - } - b.WriteBatch.Put(key, value) -} - -func (b *batch) Delete(key []byte) { - if b.l.binlog != nil { - buf := encodeBinLogDelete(key) - b.logs = append(b.logs, buf) - } - b.WriteBatch.Delete(key) -} - -type dbBatchLocker struct { - l *sync.Mutex - wrLock *sync.RWMutex -} - -func (l *dbBatchLocker) Lock() { - l.wrLock.RLock() - l.l.Lock() -} - -func (l *dbBatchLocker) Unlock() { - l.l.Unlock() - l.wrLock.RUnlock() -} - -type txBatchLocker struct { -} - -func (l *txBatchLocker) Lock() {} -func (l *txBatchLocker) Unlock() {} - -type multiBatchLocker struct { -} - -func (l *multiBatchLocker) Lock() {} -func (l *multiBatchLocker) Unlock() {} - -func (l *Nodb) newBatch(wb store.WriteBatch, locker sync.Locker, tx *Tx) *batch { - b := new(batch) - b.l = l - b.WriteBatch = wb - - b.tx = tx - b.Locker = locker - - b.logs = [][]byte{} - return b -} diff --git a/vendor/gitea.com/lunny/nodb/binlog.go b/vendor/gitea.com/lunny/nodb/binlog.go deleted file mode 100644 index 50a9e9d290fda..0000000000000 --- a/vendor/gitea.com/lunny/nodb/binlog.go +++ /dev/null @@ -1,391 +0,0 @@ -package nodb - -import ( - "bufio" - "encoding/binary" - "fmt" - "io" - "io/ioutil" - "os" - "path" - "strconv" - "strings" - "sync" - "time" - - "gitea.com/lunny/log" - "gitea.com/lunny/nodb/config" -) - -type BinLogHead struct { - CreateTime uint32 - BatchId uint32 - PayloadLen uint32 -} - -func (h *BinLogHead) Len() int { - return 12 -} - -func (h *BinLogHead) Write(w io.Writer) error { - if err := binary.Write(w, binary.BigEndian, h.CreateTime); err != nil { - return err - } - - if err := binary.Write(w, binary.BigEndian, h.BatchId); err != nil { - return err - } - - if err := binary.Write(w, binary.BigEndian, h.PayloadLen); err != nil { - return err - } - - return nil -} - -func (h *BinLogHead) handleReadError(err error) error { - if err == io.EOF { - return io.ErrUnexpectedEOF - } else { - return err - } -} - -func (h *BinLogHead) Read(r io.Reader) error { - var err error - if err = binary.Read(r, binary.BigEndian, &h.CreateTime); err != nil { - return err - } - - if err = binary.Read(r, binary.BigEndian, &h.BatchId); err != nil { - return h.handleReadError(err) - } - - if err = binary.Read(r, binary.BigEndian, &h.PayloadLen); err != nil { - return h.handleReadError(err) - } - - return nil -} - -func (h *BinLogHead) InSameBatch(ho *BinLogHead) bool { - if h.CreateTime == ho.CreateTime && h.BatchId == ho.BatchId { - return true - } else { - return false - } -} - -/* -index file format: -ledis-bin.00001 -ledis-bin.00002 -ledis-bin.00003 - -log file format - -Log: Head|PayloadData - -Head: createTime|batchId|payloadData - -*/ - -type BinLog struct { - sync.Mutex - - path string - - cfg *config.BinLogConfig - - logFile *os.File - - logWb *bufio.Writer - - indexName string - logNames []string - lastLogIndex int64 - - batchId uint32 - - ch chan struct{} -} - -func NewBinLog(cfg *config.Config) (*BinLog, error) { - l := new(BinLog) - - l.cfg = &cfg.BinLog - l.cfg.Adjust() - - l.path = path.Join(cfg.DataDir, "binlog") - - if err := os.MkdirAll(l.path, os.ModePerm); err != nil { - return nil, err - } - - l.logNames = make([]string, 0, 16) - - l.ch = make(chan struct{}) - - if err := l.loadIndex(); err != nil { - return nil, err - } - - return l, nil -} - -func (l *BinLog) flushIndex() error { - data := strings.Join(l.logNames, "\n") - - bakName := fmt.Sprintf("%s.bak", l.indexName) - f, err := os.OpenFile(bakName, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - log.Errorf("create binlog bak index error %s", err.Error()) - return err - } - - if _, err := f.WriteString(data); err != nil { - log.Errorf("write binlog index error %s", err.Error()) - f.Close() - return err - } - - f.Close() - - if err := os.Rename(bakName, l.indexName); err != nil { - log.Errorf("rename binlog bak index error %s", err.Error()) - return err - } - - return nil -} - -func (l *BinLog) loadIndex() error { - l.indexName = path.Join(l.path, fmt.Sprintf("ledis-bin.index")) - if _, err := os.Stat(l.indexName); os.IsNotExist(err) { - //no index file, nothing to do - } else { - indexData, err := ioutil.ReadFile(l.indexName) - if err != nil { - return err - } - - lines := strings.Split(string(indexData), "\n") - for _, line := range lines { - line = strings.Trim(line, "\r\n ") - if len(line) == 0 { - continue - } - - if _, err := os.Stat(path.Join(l.path, line)); err != nil { - log.Errorf("load index line %s error %s", line, err.Error()) - return err - } else { - l.logNames = append(l.logNames, line) - } - } - } - if l.cfg.MaxFileNum > 0 && len(l.logNames) > l.cfg.MaxFileNum { - //remove oldest logfile - if err := l.Purge(len(l.logNames) - l.cfg.MaxFileNum); err != nil { - return err - } - } - - var err error - if len(l.logNames) == 0 { - l.lastLogIndex = 1 - } else { - lastName := l.logNames[len(l.logNames)-1] - - if l.lastLogIndex, err = strconv.ParseInt(path.Ext(lastName)[1:], 10, 64); err != nil { - log.Errorf("invalid logfile name %s", err.Error()) - return err - } - - //like mysql, if server restart, a new binlog will create - l.lastLogIndex++ - } - - return nil -} - -func (l *BinLog) getLogFile() string { - return l.FormatLogFileName(l.lastLogIndex) -} - -func (l *BinLog) openNewLogFile() error { - var err error - lastName := l.getLogFile() - - logPath := path.Join(l.path, lastName) - if l.logFile, err = os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY, 0666); err != nil { - log.Errorf("open new logfile error %s", err.Error()) - return err - } - - if l.cfg.MaxFileNum > 0 && len(l.logNames) == l.cfg.MaxFileNum { - l.purge(1) - } - - l.logNames = append(l.logNames, lastName) - - if l.logWb == nil { - l.logWb = bufio.NewWriterSize(l.logFile, 1024) - } else { - l.logWb.Reset(l.logFile) - } - - if err = l.flushIndex(); err != nil { - return err - } - - return nil -} - -func (l *BinLog) checkLogFileSize() bool { - if l.logFile == nil { - return false - } - - st, _ := l.logFile.Stat() - if st.Size() >= int64(l.cfg.MaxFileSize) { - l.closeLog() - return true - } - - return false -} - -func (l *BinLog) closeLog() { - l.lastLogIndex++ - - l.logFile.Close() - l.logFile = nil -} - -func (l *BinLog) purge(n int) { - for i := 0; i < n; i++ { - logPath := path.Join(l.path, l.logNames[i]) - os.Remove(logPath) - } - - copy(l.logNames[0:], l.logNames[n:]) - l.logNames = l.logNames[0 : len(l.logNames)-n] -} - -func (l *BinLog) Close() { - if l.logFile != nil { - l.logFile.Close() - l.logFile = nil - } -} - -func (l *BinLog) LogNames() []string { - return l.logNames -} - -func (l *BinLog) LogFileName() string { - return l.getLogFile() -} - -func (l *BinLog) LogFilePos() int64 { - if l.logFile == nil { - return 0 - } else { - st, _ := l.logFile.Stat() - return st.Size() - } -} - -func (l *BinLog) LogFileIndex() int64 { - return l.lastLogIndex -} - -func (l *BinLog) FormatLogFileName(index int64) string { - return fmt.Sprintf("ledis-bin.%07d", index) -} - -func (l *BinLog) FormatLogFilePath(index int64) string { - return path.Join(l.path, l.FormatLogFileName(index)) -} - -func (l *BinLog) LogPath() string { - return l.path -} - -func (l *BinLog) Purge(n int) error { - l.Lock() - defer l.Unlock() - - if len(l.logNames) == 0 { - return nil - } - - if n >= len(l.logNames) { - n = len(l.logNames) - //can not purge current log file - if l.logNames[n-1] == l.getLogFile() { - n = n - 1 - } - } - - l.purge(n) - - return l.flushIndex() -} - -func (l *BinLog) PurgeAll() error { - l.Lock() - defer l.Unlock() - - l.closeLog() - return l.openNewLogFile() -} - -func (l *BinLog) Log(args ...[]byte) error { - l.Lock() - defer l.Unlock() - - var err error - - if l.logFile == nil { - if err = l.openNewLogFile(); err != nil { - return err - } - } - - head := &BinLogHead{} - - head.CreateTime = uint32(time.Now().Unix()) - head.BatchId = l.batchId - - l.batchId++ - - for _, data := range args { - head.PayloadLen = uint32(len(data)) - - if err := head.Write(l.logWb); err != nil { - return err - } - - if _, err := l.logWb.Write(data); err != nil { - return err - } - } - - if err = l.logWb.Flush(); err != nil { - log.Errorf("write log error %s", err.Error()) - return err - } - - l.checkLogFileSize() - - close(l.ch) - l.ch = make(chan struct{}) - - return nil -} - -func (l *BinLog) Wait() <-chan struct{} { - return l.ch -} diff --git a/vendor/gitea.com/lunny/nodb/binlog_util.go b/vendor/gitea.com/lunny/nodb/binlog_util.go deleted file mode 100644 index 22124dda07d84..0000000000000 --- a/vendor/gitea.com/lunny/nodb/binlog_util.go +++ /dev/null @@ -1,215 +0,0 @@ -package nodb - -import ( - "encoding/binary" - "errors" - "fmt" - "strconv" -) - -var ( - errBinLogDeleteType = errors.New("invalid bin log delete type") - errBinLogPutType = errors.New("invalid bin log put type") - errBinLogCommandType = errors.New("invalid bin log command type") -) - -func encodeBinLogDelete(key []byte) []byte { - buf := make([]byte, 1+len(key)) - buf[0] = BinLogTypeDeletion - copy(buf[1:], key) - return buf -} - -func decodeBinLogDelete(sz []byte) ([]byte, error) { - if len(sz) < 1 || sz[0] != BinLogTypeDeletion { - return nil, errBinLogDeleteType - } - - return sz[1:], nil -} - -func encodeBinLogPut(key []byte, value []byte) []byte { - buf := make([]byte, 3+len(key)+len(value)) - buf[0] = BinLogTypePut - pos := 1 - binary.BigEndian.PutUint16(buf[pos:], uint16(len(key))) - pos += 2 - copy(buf[pos:], key) - pos += len(key) - copy(buf[pos:], value) - - return buf -} - -func decodeBinLogPut(sz []byte) ([]byte, []byte, error) { - if len(sz) < 3 || sz[0] != BinLogTypePut { - return nil, nil, errBinLogPutType - } - - keyLen := int(binary.BigEndian.Uint16(sz[1:])) - if 3+keyLen > len(sz) { - return nil, nil, errBinLogPutType - } - - return sz[3 : 3+keyLen], sz[3+keyLen:], nil -} - -func FormatBinLogEvent(event []byte) (string, error) { - logType := uint8(event[0]) - - var err error - var k []byte - var v []byte - - var buf []byte = make([]byte, 0, 1024) - - switch logType { - case BinLogTypePut: - k, v, err = decodeBinLogPut(event) - buf = append(buf, "PUT "...) - case BinLogTypeDeletion: - k, err = decodeBinLogDelete(event) - buf = append(buf, "DELETE "...) - default: - err = errInvalidBinLogEvent - } - - if err != nil { - return "", err - } - - if buf, err = formatDataKey(buf, k); err != nil { - return "", err - } - - if v != nil && len(v) != 0 { - buf = append(buf, fmt.Sprintf(" %q", v)...) - } - - return String(buf), nil -} - -func formatDataKey(buf []byte, k []byte) ([]byte, error) { - if len(k) < 2 { - return nil, errInvalidBinLogEvent - } - - buf = append(buf, fmt.Sprintf("DB:%2d ", k[0])...) - buf = append(buf, fmt.Sprintf("%s ", TypeName[k[1]])...) - - db := new(DB) - db.index = k[0] - - //to do format at respective place - - switch k[1] { - case KVType: - if key, err := db.decodeKVKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - } - case HashType: - if key, field, err := db.hDecodeHashKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - buf = append(buf, ' ') - buf = strconv.AppendQuote(buf, String(field)) - } - case HSizeType: - if key, err := db.hDecodeSizeKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - } - case ListType: - if key, seq, err := db.lDecodeListKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - buf = append(buf, ' ') - buf = strconv.AppendInt(buf, int64(seq), 10) - } - case LMetaType: - if key, err := db.lDecodeMetaKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - } - case ZSetType: - if key, m, err := db.zDecodeSetKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - buf = append(buf, ' ') - buf = strconv.AppendQuote(buf, String(m)) - } - case ZSizeType: - if key, err := db.zDecodeSizeKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - } - case ZScoreType: - if key, m, score, err := db.zDecodeScoreKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - buf = append(buf, ' ') - buf = strconv.AppendQuote(buf, String(m)) - buf = append(buf, ' ') - buf = strconv.AppendInt(buf, score, 10) - } - case BitType: - if key, seq, err := db.bDecodeBinKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - buf = append(buf, ' ') - buf = strconv.AppendUint(buf, uint64(seq), 10) - } - case BitMetaType: - if key, err := db.bDecodeMetaKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - } - case SetType: - if key, member, err := db.sDecodeSetKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - buf = append(buf, ' ') - buf = strconv.AppendQuote(buf, String(member)) - } - case SSizeType: - if key, err := db.sDecodeSizeKey(k); err != nil { - return nil, err - } else { - buf = strconv.AppendQuote(buf, String(key)) - } - case ExpTimeType: - if tp, key, t, err := db.expDecodeTimeKey(k); err != nil { - return nil, err - } else { - buf = append(buf, TypeName[tp]...) - buf = append(buf, ' ') - buf = strconv.AppendQuote(buf, String(key)) - buf = append(buf, ' ') - buf = strconv.AppendInt(buf, t, 10) - } - case ExpMetaType: - if tp, key, err := db.expDecodeMetaKey(k); err != nil { - return nil, err - } else { - buf = append(buf, TypeName[tp]...) - buf = append(buf, ' ') - buf = strconv.AppendQuote(buf, String(key)) - } - default: - return nil, errInvalidBinLogEvent - } - - return buf, nil -} diff --git a/vendor/gitea.com/lunny/nodb/config/config.go b/vendor/gitea.com/lunny/nodb/config/config.go deleted file mode 100644 index 01ca070ccb359..0000000000000 --- a/vendor/gitea.com/lunny/nodb/config/config.go +++ /dev/null @@ -1,135 +0,0 @@ -package config - -import ( - "io/ioutil" - - "github.com/pelletier/go-toml" -) - -type Size int - -const ( - DefaultAddr string = "127.0.0.1:6380" - DefaultHttpAddr string = "127.0.0.1:11181" - - DefaultDBName string = "goleveldb" - - DefaultDataDir string = "./data" -) - -const ( - MaxBinLogFileSize int = 1024 * 1024 * 1024 - MaxBinLogFileNum int = 10000 - - DefaultBinLogFileSize int = MaxBinLogFileSize - DefaultBinLogFileNum int = 10 -) - -type LevelDBConfig struct { - Compression bool `toml:"compression"` - BlockSize int `toml:"block_size"` - WriteBufferSize int `toml:"write_buffer_size"` - CacheSize int `toml:"cache_size"` - MaxOpenFiles int `toml:"max_open_files"` -} - -type LMDBConfig struct { - MapSize int `toml:"map_size"` - NoSync bool `toml:"nosync"` -} - -type BinLogConfig struct { - MaxFileSize int `toml:"max_file_size"` - MaxFileNum int `toml:"max_file_num"` -} - -type Config struct { - DataDir string `toml:"data_dir"` - - DBName string `toml:"db_name"` - - LevelDB LevelDBConfig `toml:"leveldb"` - - LMDB LMDBConfig `toml:"lmdb"` - - BinLog BinLogConfig `toml:"binlog"` - - SlaveOf string `toml:"slaveof"` - - AccessLog string `toml:"access_log"` -} - -func NewConfigWithFile(fileName string) (*Config, error) { - data, err := ioutil.ReadFile(fileName) - if err != nil { - return nil, err - } - - return NewConfigWithData(data) -} - -func NewConfigWithData(data []byte) (*Config, error) { - cfg := NewConfigDefault() - - err := toml.Unmarshal(data, cfg) - if err != nil { - return nil, err - } - - return cfg, nil -} - -func NewConfigDefault() *Config { - cfg := new(Config) - - cfg.DataDir = DefaultDataDir - - cfg.DBName = DefaultDBName - - // disable binlog - cfg.BinLog.MaxFileNum = 0 - cfg.BinLog.MaxFileSize = 0 - - // disable replication - cfg.SlaveOf = "" - - // disable access log - cfg.AccessLog = "" - - cfg.LMDB.MapSize = 20 * 1024 * 1024 - cfg.LMDB.NoSync = true - - return cfg -} - -func (cfg *LevelDBConfig) Adjust() { - if cfg.CacheSize <= 0 { - cfg.CacheSize = 4 * 1024 * 1024 - } - - if cfg.BlockSize <= 0 { - cfg.BlockSize = 4 * 1024 - } - - if cfg.WriteBufferSize <= 0 { - cfg.WriteBufferSize = 4 * 1024 * 1024 - } - - if cfg.MaxOpenFiles < 1024 { - cfg.MaxOpenFiles = 1024 - } -} - -func (cfg *BinLogConfig) Adjust() { - if cfg.MaxFileSize <= 0 { - cfg.MaxFileSize = DefaultBinLogFileSize - } else if cfg.MaxFileSize > MaxBinLogFileSize { - cfg.MaxFileSize = MaxBinLogFileSize - } - - if cfg.MaxFileNum <= 0 { - cfg.MaxFileNum = DefaultBinLogFileNum - } else if cfg.MaxFileNum > MaxBinLogFileNum { - cfg.MaxFileNum = MaxBinLogFileNum - } -} diff --git a/vendor/gitea.com/lunny/nodb/config/config.toml b/vendor/gitea.com/lunny/nodb/config/config.toml deleted file mode 100644 index 2a3a2466e006b..0000000000000 --- a/vendor/gitea.com/lunny/nodb/config/config.toml +++ /dev/null @@ -1,45 +0,0 @@ -# LedisDB configuration - -# Server listen address -addr = "127.0.0.1:6380" - -# Server http listen address, set empty to disable -http_addr = "127.0.0.1:11181" - -# Data store path, all ledisdb's data will be saved here -data_dir = "/tmp/ledis_server" - -# Log server command, set empty to disable -access_log = "" - -# Set slaveof to enable replication from master, empty, no replication -slaveof = "" - -# Choose which backend storage to use, now support: -# -# leveldb -# rocksdb -# goleveldb -# lmdb -# boltdb -# hyperleveldb -# memory -# -db_name = "leveldb" - -[leveldb] -compression = false -block_size = 32768 -write_buffer_size = 67108864 -cache_size = 524288000 -max_open_files = 1024 - -[lmdb] -map_size = 524288000 -nosync = true - -[binlog] -max_file_size = 0 -max_file_num = 0 - - diff --git a/vendor/gitea.com/lunny/nodb/const.go b/vendor/gitea.com/lunny/nodb/const.go deleted file mode 100644 index 446dae634edec..0000000000000 --- a/vendor/gitea.com/lunny/nodb/const.go +++ /dev/null @@ -1,98 +0,0 @@ -package nodb - -import ( - "errors" -) - -const ( - NoneType byte = 0 - KVType byte = 1 - HashType byte = 2 - HSizeType byte = 3 - ListType byte = 4 - LMetaType byte = 5 - ZSetType byte = 6 - ZSizeType byte = 7 - ZScoreType byte = 8 - BitType byte = 9 - BitMetaType byte = 10 - SetType byte = 11 - SSizeType byte = 12 - - maxDataType byte = 100 - - ExpTimeType byte = 101 - ExpMetaType byte = 102 -) - -var ( - TypeName = map[byte]string{ - KVType: "kv", - HashType: "hash", - HSizeType: "hsize", - ListType: "list", - LMetaType: "lmeta", - ZSetType: "zset", - ZSizeType: "zsize", - ZScoreType: "zscore", - BitType: "bit", - BitMetaType: "bitmeta", - SetType: "set", - SSizeType: "ssize", - ExpTimeType: "exptime", - ExpMetaType: "expmeta", - } -) - -const ( - defaultScanCount int = 10 -) - -var ( - errKeySize = errors.New("invalid key size") - errValueSize = errors.New("invalid value size") - errHashFieldSize = errors.New("invalid hash field size") - errSetMemberSize = errors.New("invalid set member size") - errZSetMemberSize = errors.New("invalid zset member size") - errExpireValue = errors.New("invalid expire value") -) - -const ( - //we don't support too many databases - MaxDBNumber uint8 = 16 - - //max key size - MaxKeySize int = 1024 - - //max hash field size - MaxHashFieldSize int = 1024 - - //max zset member size - MaxZSetMemberSize int = 1024 - - //max set member size - MaxSetMemberSize int = 1024 - - //max value size - MaxValueSize int = 10 * 1024 * 1024 -) - -var ( - ErrScoreMiss = errors.New("zset score miss") -) - -const ( - BinLogTypeDeletion uint8 = 0x0 - BinLogTypePut uint8 = 0x1 - BinLogTypeCommand uint8 = 0x2 -) - -const ( - DBAutoCommit uint8 = 0x0 - DBInTransaction uint8 = 0x1 - DBInMulti uint8 = 0x2 -) - -var ( - Version = "0.1" -) diff --git a/vendor/gitea.com/lunny/nodb/doc.go b/vendor/gitea.com/lunny/nodb/doc.go deleted file mode 100644 index 2f7df33ffd035..0000000000000 --- a/vendor/gitea.com/lunny/nodb/doc.go +++ /dev/null @@ -1,61 +0,0 @@ -// package nodb is a high performance embedded NoSQL. -// -// nodb supports various data structure like kv, list, hash and zset like redis. -// -// Other features include binlog replication, data with a limited time-to-live. -// -// Usage -// -// First create a nodb instance before use: -// -// l := nodb.Open(cfg) -// -// cfg is a Config instance which contains configuration for nodb use, -// like DataDir (root directory for nodb working to store data). -// -// After you create a nodb instance, you can select a DB to store you data: -// -// db, _ := l.Select(0) -// -// DB must be selected by a index, nodb supports only 16 databases, so the index range is [0-15]. -// -// KV -// -// KV is the most basic nodb type like any other key-value database. -// -// err := db.Set(key, value) -// value, err := db.Get(key) -// -// List -// -// List is simply lists of values, sorted by insertion order. -// You can push or pop value on the list head (left) or tail (right). -// -// err := db.LPush(key, value1) -// err := db.RPush(key, value2) -// value1, err := db.LPop(key) -// value2, err := db.RPop(key) -// -// Hash -// -// Hash is a map between fields and values. -// -// n, err := db.HSet(key, field1, value1) -// n, err := db.HSet(key, field2, value2) -// value1, err := db.HGet(key, field1) -// value2, err := db.HGet(key, field2) -// -// ZSet -// -// ZSet is a sorted collections of values. -// Every member of zset is associated with score, a int64 value which used to sort, from smallest to greatest score. -// Members are unique, but score may be same. -// -// n, err := db.ZAdd(key, ScorePair{score1, member1}, ScorePair{score2, member2}) -// ay, err := db.ZRangeByScore(key, minScore, maxScore, 0, -1) -// -// Binlog -// -// nodb supports binlog, so you can sync binlog to another server for replication. If you want to open binlog support, set UseBinLog to true in config. -// -package nodb diff --git a/vendor/gitea.com/lunny/nodb/dump.go b/vendor/gitea.com/lunny/nodb/dump.go deleted file mode 100644 index 3c9722e00db68..0000000000000 --- a/vendor/gitea.com/lunny/nodb/dump.go +++ /dev/null @@ -1,200 +0,0 @@ -package nodb - -import ( - "bufio" - "bytes" - "encoding/binary" - "io" - "os" - - "github.com/siddontang/go-snappy/snappy" -) - -//dump format -// fileIndex(bigendian int64)|filePos(bigendian int64) -// |keylen(bigendian int32)|key|valuelen(bigendian int32)|value...... -// -//key and value are both compressed for fast transfer dump on network using snappy - -type BinLogAnchor struct { - LogFileIndex int64 - LogPos int64 -} - -func (m *BinLogAnchor) WriteTo(w io.Writer) error { - if err := binary.Write(w, binary.BigEndian, m.LogFileIndex); err != nil { - return err - } - - if err := binary.Write(w, binary.BigEndian, m.LogPos); err != nil { - return err - } - return nil -} - -func (m *BinLogAnchor) ReadFrom(r io.Reader) error { - err := binary.Read(r, binary.BigEndian, &m.LogFileIndex) - if err != nil { - return err - } - - err = binary.Read(r, binary.BigEndian, &m.LogPos) - if err != nil { - return err - } - - return nil -} - -func (l *Nodb) DumpFile(path string) error { - f, err := os.Create(path) - if err != nil { - return err - } - defer f.Close() - - return l.Dump(f) -} - -func (l *Nodb) Dump(w io.Writer) error { - m := new(BinLogAnchor) - - var err error - - l.wLock.Lock() - defer l.wLock.Unlock() - - if l.binlog != nil { - m.LogFileIndex = l.binlog.LogFileIndex() - m.LogPos = l.binlog.LogFilePos() - } - - wb := bufio.NewWriterSize(w, 4096) - if err = m.WriteTo(wb); err != nil { - return err - } - - it := l.ldb.NewIterator() - it.SeekToFirst() - - compressBuf := make([]byte, 4096) - - var key []byte - var value []byte - for ; it.Valid(); it.Next() { - key = it.RawKey() - value = it.RawValue() - - if key, err = snappy.Encode(compressBuf, key); err != nil { - return err - } - - if err = binary.Write(wb, binary.BigEndian, uint16(len(key))); err != nil { - return err - } - - if _, err = wb.Write(key); err != nil { - return err - } - - if value, err = snappy.Encode(compressBuf, value); err != nil { - return err - } - - if err = binary.Write(wb, binary.BigEndian, uint32(len(value))); err != nil { - return err - } - - if _, err = wb.Write(value); err != nil { - return err - } - } - - if err = wb.Flush(); err != nil { - return err - } - - compressBuf = nil - - return nil -} - -func (l *Nodb) LoadDumpFile(path string) (*BinLogAnchor, error) { - f, err := os.Open(path) - if err != nil { - return nil, err - } - defer f.Close() - - return l.LoadDump(f) -} - -func (l *Nodb) LoadDump(r io.Reader) (*BinLogAnchor, error) { - l.wLock.Lock() - defer l.wLock.Unlock() - - info := new(BinLogAnchor) - - rb := bufio.NewReaderSize(r, 4096) - - err := info.ReadFrom(rb) - if err != nil { - return nil, err - } - - var keyLen uint16 - var valueLen uint32 - - var keyBuf bytes.Buffer - var valueBuf bytes.Buffer - - deKeyBuf := make([]byte, 4096) - deValueBuf := make([]byte, 4096) - - var key, value []byte - - for { - if err = binary.Read(rb, binary.BigEndian, &keyLen); err != nil && err != io.EOF { - return nil, err - } else if err == io.EOF { - break - } - - if _, err = io.CopyN(&keyBuf, rb, int64(keyLen)); err != nil { - return nil, err - } - - if key, err = snappy.Decode(deKeyBuf, keyBuf.Bytes()); err != nil { - return nil, err - } - - if err = binary.Read(rb, binary.BigEndian, &valueLen); err != nil { - return nil, err - } - - if _, err = io.CopyN(&valueBuf, rb, int64(valueLen)); err != nil { - return nil, err - } - - if value, err = snappy.Decode(deValueBuf, valueBuf.Bytes()); err != nil { - return nil, err - } - - if err = l.ldb.Put(key, value); err != nil { - return nil, err - } - - keyBuf.Reset() - valueBuf.Reset() - } - - deKeyBuf = nil - deValueBuf = nil - - //if binlog enable, we will delete all binlogs and open a new one for handling simply - if l.binlog != nil { - l.binlog.PurgeAll() - } - - return info, nil -} diff --git a/vendor/gitea.com/lunny/nodb/go.mod b/vendor/gitea.com/lunny/nodb/go.mod deleted file mode 100644 index ae0ed81f3a45d..0000000000000 --- a/vendor/gitea.com/lunny/nodb/go.mod +++ /dev/null @@ -1,11 +0,0 @@ -module gitea.com/lunny/nodb - -go 1.12 - -require ( - gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e - github.com/mattn/go-sqlite3 v1.11.0 // indirect - github.com/pelletier/go-toml v1.8.1 - github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d - github.com/syndtr/goleveldb v1.0.0 -) diff --git a/vendor/gitea.com/lunny/nodb/go.sum b/vendor/gitea.com/lunny/nodb/go.sum deleted file mode 100644 index 91ae7d1656d98..0000000000000 --- a/vendor/gitea.com/lunny/nodb/go.sum +++ /dev/null @@ -1,42 +0,0 @@ -gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e h1:r1en/D7xJmcY24VkHkjkcJFa+7ZWubVWPBrvsHkmHxk= -gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e/go.mod h1:uJEsN4LQpeGYRCjuPXPZBClU7N5pWzGuyF4uqLpE/e0= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d h1:qQWKKOvHN7Q9c6GdmUteCef2F9ubxMpxY1IKwpIKz68= -github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY= -github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/gitea.com/lunny/nodb/info.go b/vendor/gitea.com/lunny/nodb/info.go deleted file mode 100644 index 3fd37e3d44549..0000000000000 --- a/vendor/gitea.com/lunny/nodb/info.go +++ /dev/null @@ -1,24 +0,0 @@ -package nodb - -// todo, add info - -// type Keyspace struct { -// Kvs int `json:"kvs"` -// KvExpires int `json:"kv_expires"` - -// Lists int `json:"lists"` -// ListExpires int `json:"list_expires"` - -// Bitmaps int `json:"bitmaps"` -// BitmapExpires int `json:"bitmap_expires"` - -// ZSets int `json:"zsets"` -// ZSetExpires int `json:"zset_expires"` - -// Hashes int `json:"hashes"` -// HashExpires int `json:"hahsh_expires"` -// } - -// type Info struct { -// KeySpaces [MaxDBNumber]Keyspace -// } diff --git a/vendor/gitea.com/lunny/nodb/multi.go b/vendor/gitea.com/lunny/nodb/multi.go deleted file mode 100644 index ca581ce9a232c..0000000000000 --- a/vendor/gitea.com/lunny/nodb/multi.go +++ /dev/null @@ -1,73 +0,0 @@ -package nodb - -import ( - "errors" - "fmt" -) - -var ( - ErrNestMulti = errors.New("nest multi not supported") - ErrMultiDone = errors.New("multi has been closed") -) - -type Multi struct { - *DB -} - -func (db *DB) IsInMulti() bool { - return db.status == DBInMulti -} - -// begin a mutli to execute commands, -// it will block any other write operations before you close the multi, unlike transaction, mutli can not rollback -func (db *DB) Multi() (*Multi, error) { - if db.IsInMulti() { - return nil, ErrNestMulti - } - - m := new(Multi) - - m.DB = new(DB) - m.DB.status = DBInMulti - - m.DB.l = db.l - - m.l.wLock.Lock() - - m.DB.sdb = db.sdb - - m.DB.bucket = db.sdb - - m.DB.index = db.index - - m.DB.kvBatch = m.newBatch() - m.DB.listBatch = m.newBatch() - m.DB.hashBatch = m.newBatch() - m.DB.zsetBatch = m.newBatch() - m.DB.binBatch = m.newBatch() - m.DB.setBatch = m.newBatch() - - return m, nil -} - -func (m *Multi) newBatch() *batch { - return m.l.newBatch(m.bucket.NewWriteBatch(), &multiBatchLocker{}, nil) -} - -func (m *Multi) Close() error { - if m.bucket == nil { - return ErrMultiDone - } - m.l.wLock.Unlock() - m.bucket = nil - return nil -} - -func (m *Multi) Select(index int) error { - if index < 0 || index >= int(MaxDBNumber) { - return fmt.Errorf("invalid db index %d", index) - } - - m.DB.index = uint8(index) - return nil -} diff --git a/vendor/gitea.com/lunny/nodb/nodb.go b/vendor/gitea.com/lunny/nodb/nodb.go deleted file mode 100644 index b487579411348..0000000000000 --- a/vendor/gitea.com/lunny/nodb/nodb.go +++ /dev/null @@ -1,128 +0,0 @@ -package nodb - -import ( - "fmt" - "sync" - "time" - - "gitea.com/lunny/nodb/config" - "gitea.com/lunny/nodb/store" - "gitea.com/lunny/log" -) - -type Nodb struct { - cfg *config.Config - - ldb *store.DB - dbs [MaxDBNumber]*DB - - quit chan struct{} - jobs *sync.WaitGroup - - binlog *BinLog - - wLock sync.RWMutex //allow one write at same time - commitLock sync.Mutex //allow one write commit at same time -} - -func Open(cfg *config.Config) (*Nodb, error) { - if len(cfg.DataDir) == 0 { - cfg.DataDir = config.DefaultDataDir - } - - ldb, err := store.Open(cfg) - if err != nil { - return nil, err - } - - l := new(Nodb) - - l.quit = make(chan struct{}) - l.jobs = new(sync.WaitGroup) - - l.ldb = ldb - - if cfg.BinLog.MaxFileNum > 0 && cfg.BinLog.MaxFileSize > 0 { - l.binlog, err = NewBinLog(cfg) - if err != nil { - return nil, err - } - } else { - l.binlog = nil - } - - for i := uint8(0); i < MaxDBNumber; i++ { - l.dbs[i] = l.newDB(i) - } - - l.activeExpireCycle() - - return l, nil -} - -func (l *Nodb) Close() { - close(l.quit) - l.jobs.Wait() - - l.ldb.Close() - - if l.binlog != nil { - l.binlog.Close() - l.binlog = nil - } -} - -func (l *Nodb) Select(index int) (*DB, error) { - if index < 0 || index >= int(MaxDBNumber) { - return nil, fmt.Errorf("invalid db index %d", index) - } - - return l.dbs[index], nil -} - -func (l *Nodb) FlushAll() error { - for index, db := range l.dbs { - if _, err := db.FlushAll(); err != nil { - log.Errorf("flush db %d error %s", index, err.Error()) - } - } - - return nil -} - -// very dangerous to use -func (l *Nodb) DataDB() *store.DB { - return l.ldb -} - -func (l *Nodb) activeExpireCycle() { - var executors []*elimination = make([]*elimination, len(l.dbs)) - for i, db := range l.dbs { - executors[i] = db.newEliminator() - } - - l.jobs.Add(1) - go func() { - tick := time.NewTicker(1 * time.Second) - end := false - done := make(chan struct{}) - for !end { - select { - case <-tick.C: - go func() { - for _, eli := range executors { - eli.active() - } - done <- struct{}{} - }() - <-done - case <-l.quit: - end = true - break - } - } - - tick.Stop() - l.jobs.Done() - }() -} diff --git a/vendor/gitea.com/lunny/nodb/nodb_db.go b/vendor/gitea.com/lunny/nodb/nodb_db.go deleted file mode 100644 index 76922be159613..0000000000000 --- a/vendor/gitea.com/lunny/nodb/nodb_db.go +++ /dev/null @@ -1,171 +0,0 @@ -package nodb - -import ( - "fmt" - "sync" - - "gitea.com/lunny/nodb/store" -) - -type ibucket interface { - Get(key []byte) ([]byte, error) - - Put(key []byte, value []byte) error - Delete(key []byte) error - - NewIterator() *store.Iterator - - NewWriteBatch() store.WriteBatch - - RangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator - RevRangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator - RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator - RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator -} - -type DB struct { - l *Nodb - - sdb *store.DB - - bucket ibucket - - index uint8 - - kvBatch *batch - listBatch *batch - hashBatch *batch - zsetBatch *batch - binBatch *batch - setBatch *batch - - status uint8 -} - -func (l *Nodb) newDB(index uint8) *DB { - d := new(DB) - - d.l = l - - d.sdb = l.ldb - - d.bucket = d.sdb - - d.status = DBAutoCommit - d.index = index - - d.kvBatch = d.newBatch() - d.listBatch = d.newBatch() - d.hashBatch = d.newBatch() - d.zsetBatch = d.newBatch() - d.binBatch = d.newBatch() - d.setBatch = d.newBatch() - - return d -} - -func (db *DB) newBatch() *batch { - return db.l.newBatch(db.bucket.NewWriteBatch(), &dbBatchLocker{l: &sync.Mutex{}, wrLock: &db.l.wLock}, nil) -} - -func (db *DB) Index() int { - return int(db.index) -} - -func (db *DB) IsAutoCommit() bool { - return db.status == DBAutoCommit -} - -func (db *DB) FlushAll() (drop int64, err error) { - all := [...](func() (int64, error)){ - db.flush, - db.lFlush, - db.hFlush, - db.zFlush, - db.bFlush, - db.sFlush} - - for _, flush := range all { - if n, e := flush(); e != nil { - err = e - return - } else { - drop += n - } - } - - return -} - -func (db *DB) newEliminator() *elimination { - eliminator := newEliminator(db) - - eliminator.regRetireContext(KVType, db.kvBatch, db.delete) - eliminator.regRetireContext(ListType, db.listBatch, db.lDelete) - eliminator.regRetireContext(HashType, db.hashBatch, db.hDelete) - eliminator.regRetireContext(ZSetType, db.zsetBatch, db.zDelete) - eliminator.regRetireContext(BitType, db.binBatch, db.bDelete) - eliminator.regRetireContext(SetType, db.setBatch, db.sDelete) - - return eliminator -} - -func (db *DB) flushRegion(t *batch, minKey []byte, maxKey []byte) (drop int64, err error) { - it := db.bucket.RangeIterator(minKey, maxKey, store.RangeROpen) - for ; it.Valid(); it.Next() { - t.Delete(it.RawKey()) - drop++ - if drop&1023 == 0 { - if err = t.Commit(); err != nil { - return - } - } - } - it.Close() - return -} - -func (db *DB) flushType(t *batch, dataType byte) (drop int64, err error) { - var deleteFunc func(t *batch, key []byte) int64 - var metaDataType byte - switch dataType { - case KVType: - deleteFunc = db.delete - metaDataType = KVType - case ListType: - deleteFunc = db.lDelete - metaDataType = LMetaType - case HashType: - deleteFunc = db.hDelete - metaDataType = HSizeType - case ZSetType: - deleteFunc = db.zDelete - metaDataType = ZSizeType - case BitType: - deleteFunc = db.bDelete - metaDataType = BitMetaType - case SetType: - deleteFunc = db.sDelete - metaDataType = SSizeType - default: - return 0, fmt.Errorf("invalid data type: %s", TypeName[dataType]) - } - - var keys [][]byte - keys, err = db.scan(metaDataType, nil, 1024, false, "") - for len(keys) != 0 || err != nil { - for _, key := range keys { - deleteFunc(t, key) - db.rmExpire(t, dataType, key) - - } - - if err = t.Commit(); err != nil { - return - } else { - drop += int64(len(keys)) - } - keys, err = db.scan(metaDataType, nil, 1024, false, "") - } - return -} diff --git a/vendor/gitea.com/lunny/nodb/replication.go b/vendor/gitea.com/lunny/nodb/replication.go deleted file mode 100644 index c2153f4282c65..0000000000000 --- a/vendor/gitea.com/lunny/nodb/replication.go +++ /dev/null @@ -1,312 +0,0 @@ -package nodb - -import ( - "bufio" - "bytes" - "errors" - "io" - "os" - "time" - - "gitea.com/lunny/log" - "gitea.com/lunny/nodb/store/driver" -) - -const ( - maxReplBatchNum = 100 - maxReplLogSize = 1 * 1024 * 1024 -) - -var ( - ErrSkipEvent = errors.New("skip to next event") -) - -var ( - errInvalidBinLogEvent = errors.New("invalid binglog event") - errInvalidBinLogFile = errors.New("invalid binlog file") -) - -type replBatch struct { - wb driver.IWriteBatch - events [][]byte - l *Nodb - - lastHead *BinLogHead -} - -func (b *replBatch) Commit() error { - b.l.commitLock.Lock() - defer b.l.commitLock.Unlock() - - err := b.wb.Commit() - if err != nil { - b.Rollback() - return err - } - - if b.l.binlog != nil { - if err = b.l.binlog.Log(b.events...); err != nil { - b.Rollback() - return err - } - } - - b.events = [][]byte{} - b.lastHead = nil - - return nil -} - -func (b *replBatch) Rollback() error { - b.wb.Rollback() - b.events = [][]byte{} - b.lastHead = nil - return nil -} - -func (l *Nodb) replicateEvent(b *replBatch, event []byte) error { - if len(event) == 0 { - return errInvalidBinLogEvent - } - - b.events = append(b.events, event) - - logType := uint8(event[0]) - switch logType { - case BinLogTypePut: - return l.replicatePutEvent(b, event) - case BinLogTypeDeletion: - return l.replicateDeleteEvent(b, event) - default: - return errInvalidBinLogEvent - } -} - -func (l *Nodb) replicatePutEvent(b *replBatch, event []byte) error { - key, value, err := decodeBinLogPut(event) - if err != nil { - return err - } - - b.wb.Put(key, value) - - return nil -} - -func (l *Nodb) replicateDeleteEvent(b *replBatch, event []byte) error { - key, err := decodeBinLogDelete(event) - if err != nil { - return err - } - - b.wb.Delete(key) - - return nil -} - -func ReadEventFromReader(rb io.Reader, f func(head *BinLogHead, event []byte) error) error { - head := &BinLogHead{} - var err error - - for { - if err = head.Read(rb); err != nil { - if err == io.EOF { - break - } else { - return err - } - } - - var dataBuf bytes.Buffer - - if _, err = io.CopyN(&dataBuf, rb, int64(head.PayloadLen)); err != nil { - return err - } - - err = f(head, dataBuf.Bytes()) - if err != nil && err != ErrSkipEvent { - return err - } - } - - return nil -} - -func (l *Nodb) ReplicateFromReader(rb io.Reader) error { - b := new(replBatch) - - b.wb = l.ldb.NewWriteBatch() - b.l = l - - f := func(head *BinLogHead, event []byte) error { - if b.lastHead == nil { - b.lastHead = head - } else if !b.lastHead.InSameBatch(head) { - if err := b.Commit(); err != nil { - log.Fatalf("replication error %s, skip to next", err.Error()) - return ErrSkipEvent - } - b.lastHead = head - } - - err := l.replicateEvent(b, event) - if err != nil { - log.Fatalf("replication error %s, skip to next", err.Error()) - return ErrSkipEvent - } - return nil - } - - err := ReadEventFromReader(rb, f) - if err != nil { - b.Rollback() - return err - } - return b.Commit() -} - -func (l *Nodb) ReplicateFromData(data []byte) error { - rb := bytes.NewReader(data) - - err := l.ReplicateFromReader(rb) - - return err -} - -func (l *Nodb) ReplicateFromBinLog(filePath string) error { - f, err := os.Open(filePath) - if err != nil { - return err - } - - rb := bufio.NewReaderSize(f, 4096) - - err = l.ReplicateFromReader(rb) - - f.Close() - - return err -} - -// try to read events, if no events read, try to wait the new event singal until timeout seconds -func (l *Nodb) ReadEventsToTimeout(info *BinLogAnchor, w io.Writer, timeout int) (n int, err error) { - lastIndex := info.LogFileIndex - lastPos := info.LogPos - - n = 0 - if l.binlog == nil { - //binlog not supported - info.LogFileIndex = 0 - info.LogPos = 0 - return - } - - n, err = l.ReadEventsTo(info, w) - if err == nil && info.LogFileIndex == lastIndex && info.LogPos == lastPos { - //no events read - select { - case <-l.binlog.Wait(): - case <-time.After(time.Duration(timeout) * time.Second): - } - return l.ReadEventsTo(info, w) - } - return -} - -func (l *Nodb) ReadEventsTo(info *BinLogAnchor, w io.Writer) (n int, err error) { - n = 0 - if l.binlog == nil { - //binlog not supported - info.LogFileIndex = 0 - info.LogPos = 0 - return - } - - index := info.LogFileIndex - offset := info.LogPos - - filePath := l.binlog.FormatLogFilePath(index) - - var f *os.File - f, err = os.Open(filePath) - if os.IsNotExist(err) { - lastIndex := l.binlog.LogFileIndex() - - if index == lastIndex { - //no binlog at all - info.LogPos = 0 - } else { - //slave binlog info had lost - info.LogFileIndex = -1 - } - } - - if err != nil { - if os.IsNotExist(err) { - err = nil - } - return - } - - defer f.Close() - - var fileSize int64 - st, _ := f.Stat() - fileSize = st.Size() - - if fileSize == info.LogPos { - return - } - - if _, err = f.Seek(offset, os.SEEK_SET); err != nil { - //may be invliad seek offset - return - } - - var lastHead *BinLogHead = nil - - head := &BinLogHead{} - - batchNum := 0 - - for { - if err = head.Read(f); err != nil { - if err == io.EOF { - //we will try to use next binlog - if index < l.binlog.LogFileIndex() { - info.LogFileIndex += 1 - info.LogPos = 0 - } - err = nil - return - } else { - return - } - - } - - if lastHead == nil { - lastHead = head - batchNum++ - } else if !lastHead.InSameBatch(head) { - lastHead = head - batchNum++ - if batchNum > maxReplBatchNum || n > maxReplLogSize { - return - } - } - - if err = head.Write(w); err != nil { - return - } - - if _, err = io.CopyN(w, f, int64(head.PayloadLen)); err != nil { - return - } - - n += (head.Len() + int(head.PayloadLen)) - info.LogPos = info.LogPos + int64(head.Len()) + int64(head.PayloadLen) - } - - return -} diff --git a/vendor/gitea.com/lunny/nodb/scan.go b/vendor/gitea.com/lunny/nodb/scan.go deleted file mode 100644 index fc0bdfb113848..0000000000000 --- a/vendor/gitea.com/lunny/nodb/scan.go +++ /dev/null @@ -1,144 +0,0 @@ -package nodb - -import ( - "bytes" - "errors" - "regexp" - - "gitea.com/lunny/nodb/store" -) - -var errDataType = errors.New("error data type") -var errMetaKey = errors.New("error meta key") - -// Seek search the prefix key -func (db *DB) Seek(key []byte) (*store.Iterator, error) { - return db.seek(KVType, key) -} - -func (db *DB) seek(dataType byte, key []byte) (*store.Iterator, error) { - var minKey []byte - var err error - - if len(key) > 0 { - if err = checkKeySize(key); err != nil { - return nil, err - } - if minKey, err = db.encodeMetaKey(dataType, key); err != nil { - return nil, err - } - - } else { - if minKey, err = db.encodeMinKey(dataType); err != nil { - return nil, err - } - } - - it := db.bucket.NewIterator() - it.Seek(minKey) - return it, nil -} - -func (db *DB) MaxKey() ([]byte, error) { - return db.encodeMaxKey(KVType) -} - -func (db *DB) Key(it *store.Iterator) ([]byte, error) { - return db.decodeMetaKey(KVType, it.Key()) -} - -func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool, match string) ([][]byte, error) { - var minKey, maxKey []byte - var err error - var r *regexp.Regexp - - if len(match) > 0 { - if r, err = regexp.Compile(match); err != nil { - return nil, err - } - } - - if len(key) > 0 { - if err = checkKeySize(key); err != nil { - return nil, err - } - if minKey, err = db.encodeMetaKey(dataType, key); err != nil { - return nil, err - } - - } else { - if minKey, err = db.encodeMinKey(dataType); err != nil { - return nil, err - } - } - - if maxKey, err = db.encodeMaxKey(dataType); err != nil { - return nil, err - } - - if count <= 0 { - count = defaultScanCount - } - - v := make([][]byte, 0, count) - - it := db.bucket.NewIterator() - it.Seek(minKey) - - if !inclusive { - if it.Valid() && bytes.Equal(it.RawKey(), minKey) { - it.Next() - } - } - - for i := 0; it.Valid() && i < count && bytes.Compare(it.RawKey(), maxKey) < 0; it.Next() { - if k, err := db.decodeMetaKey(dataType, it.Key()); err != nil { - continue - } else if r != nil && !r.Match(k) { - continue - } else { - v = append(v, k) - i++ - } - } - it.Close() - return v, nil -} - -func (db *DB) encodeMinKey(dataType byte) ([]byte, error) { - return db.encodeMetaKey(dataType, nil) -} - -func (db *DB) encodeMaxKey(dataType byte) ([]byte, error) { - k, err := db.encodeMetaKey(dataType, nil) - if err != nil { - return nil, err - } - k[len(k)-1] = dataType + 1 - return k, nil -} - -func (db *DB) encodeMetaKey(dataType byte, key []byte) ([]byte, error) { - switch dataType { - case KVType: - return db.encodeKVKey(key), nil - case LMetaType: - return db.lEncodeMetaKey(key), nil - case HSizeType: - return db.hEncodeSizeKey(key), nil - case ZSizeType: - return db.zEncodeSizeKey(key), nil - case BitMetaType: - return db.bEncodeMetaKey(key), nil - case SSizeType: - return db.sEncodeSizeKey(key), nil - default: - return nil, errDataType - } -} -func (db *DB) decodeMetaKey(dataType byte, ek []byte) ([]byte, error) { - if len(ek) < 2 || ek[0] != db.index || ek[1] != dataType { - return nil, errMetaKey - } - return ek[2:], nil -} diff --git a/vendor/gitea.com/lunny/nodb/store/db.go b/vendor/gitea.com/lunny/nodb/store/db.go deleted file mode 100644 index fb0cf2decb720..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/db.go +++ /dev/null @@ -1,61 +0,0 @@ -package store - -import ( - "gitea.com/lunny/nodb/store/driver" -) - -type DB struct { - driver.IDB -} - -func (db *DB) NewIterator() *Iterator { - it := new(Iterator) - it.it = db.IDB.NewIterator() - - return it -} - -func (db *DB) NewWriteBatch() WriteBatch { - return db.IDB.NewWriteBatch() -} - -func (db *DB) NewSnapshot() (*Snapshot, error) { - var err error - s := &Snapshot{} - if s.ISnapshot, err = db.IDB.NewSnapshot(); err != nil { - return nil, err - } - - return s, nil -} - -func (db *DB) RangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator { - return NewRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1}) -} - -func (db *DB) RevRangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator { - return NewRevRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1}) -} - -//count < 0, unlimit. -// -//offset must >= 0, if < 0, will get nothing. -func (db *DB) RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator { - return NewRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count}) -} - -//count < 0, unlimit. -// -//offset must >= 0, if < 0, will get nothing. -func (db *DB) RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator { - return NewRevRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count}) -} - -func (db *DB) Begin() (*Tx, error) { - tx, err := db.IDB.Begin() - if err != nil { - return nil, err - } - - return &Tx{tx}, nil -} diff --git a/vendor/gitea.com/lunny/nodb/store/driver/batch.go b/vendor/gitea.com/lunny/nodb/store/driver/batch.go deleted file mode 100644 index 6b79c21c48d1f..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/driver/batch.go +++ /dev/null @@ -1,39 +0,0 @@ -package driver - -type BatchPuter interface { - BatchPut([]Write) error -} - -type Write struct { - Key []byte - Value []byte -} - -type WriteBatch struct { - batch BatchPuter - wb []Write -} - -func (w *WriteBatch) Put(key, value []byte) { - if value == nil { - value = []byte{} - } - w.wb = append(w.wb, Write{key, value}) -} - -func (w *WriteBatch) Delete(key []byte) { - w.wb = append(w.wb, Write{key, nil}) -} - -func (w *WriteBatch) Commit() error { - return w.batch.BatchPut(w.wb) -} - -func (w *WriteBatch) Rollback() error { - w.wb = w.wb[0:0] - return nil -} - -func NewWriteBatch(puter BatchPuter) IWriteBatch { - return &WriteBatch{puter, []Write{}} -} diff --git a/vendor/gitea.com/lunny/nodb/store/driver/driver.go b/vendor/gitea.com/lunny/nodb/store/driver/driver.go deleted file mode 100644 index 6da67df083627..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/driver/driver.go +++ /dev/null @@ -1,67 +0,0 @@ -package driver - -import ( - "errors" -) - -var ( - ErrTxSupport = errors.New("transaction is not supported") -) - -type IDB interface { - Close() error - - Get(key []byte) ([]byte, error) - - Put(key []byte, value []byte) error - Delete(key []byte) error - - NewIterator() IIterator - - NewWriteBatch() IWriteBatch - - NewSnapshot() (ISnapshot, error) - - Begin() (Tx, error) -} - -type ISnapshot interface { - Get(key []byte) ([]byte, error) - NewIterator() IIterator - Close() -} - -type IIterator interface { - Close() error - - First() - Last() - Seek(key []byte) - - Next() - Prev() - - Valid() bool - - Key() []byte - Value() []byte -} - -type IWriteBatch interface { - Put(key []byte, value []byte) - Delete(key []byte) - Commit() error - Rollback() error -} - -type Tx interface { - Get(key []byte) ([]byte, error) - Put(key []byte, value []byte) error - Delete(key []byte) error - - NewIterator() IIterator - NewWriteBatch() IWriteBatch - - Commit() error - Rollback() error -} diff --git a/vendor/gitea.com/lunny/nodb/store/driver/store.go b/vendor/gitea.com/lunny/nodb/store/driver/store.go deleted file mode 100644 index a64d226156f11..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/driver/store.go +++ /dev/null @@ -1,46 +0,0 @@ -package driver - -import ( - "fmt" - - "gitea.com/lunny/nodb/config" -) - -type Store interface { - String() string - Open(path string, cfg *config.Config) (IDB, error) - Repair(path string, cfg *config.Config) error -} - -var dbs = map[string]Store{} - -func Register(s Store) { - name := s.String() - if _, ok := dbs[name]; ok { - panic(fmt.Errorf("store %s is registered", s)) - } - - dbs[name] = s -} - -func ListStores() []string { - s := []string{} - for k, _ := range dbs { - s = append(s, k) - } - - return s -} - -func GetStore(cfg *config.Config) (Store, error) { - if len(cfg.DBName) == 0 { - cfg.DBName = config.DefaultDBName - } - - s, ok := dbs[cfg.DBName] - if !ok { - return nil, fmt.Errorf("store %s is not registered", cfg.DBName) - } - - return s, nil -} diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/batch.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/batch.go deleted file mode 100644 index b17e85e750d71..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/goleveldb/batch.go +++ /dev/null @@ -1,27 +0,0 @@ -package goleveldb - -import ( - "github.com/syndtr/goleveldb/leveldb" -) - -type WriteBatch struct { - db *DB - wbatch *leveldb.Batch -} - -func (w *WriteBatch) Put(key, value []byte) { - w.wbatch.Put(key, value) -} - -func (w *WriteBatch) Delete(key []byte) { - w.wbatch.Delete(key) -} - -func (w *WriteBatch) Commit() error { - return w.db.db.Write(w.wbatch, nil) -} - -func (w *WriteBatch) Rollback() error { - w.wbatch.Reset() - return nil -} diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/const.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/const.go deleted file mode 100644 index 2fffa7c82bb44..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/goleveldb/const.go +++ /dev/null @@ -1,4 +0,0 @@ -package goleveldb - -const DBName = "goleveldb" -const MemDBName = "memory" diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/db.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/db.go deleted file mode 100644 index a3c98e9e180a0..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/goleveldb/db.go +++ /dev/null @@ -1,187 +0,0 @@ -package goleveldb - -import ( - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/cache" - "github.com/syndtr/goleveldb/leveldb/filter" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/storage" - - "gitea.com/lunny/nodb/config" - "gitea.com/lunny/nodb/store/driver" - - "os" -) - -const defaultFilterBits int = 10 - -type Store struct { -} - -func (s Store) String() string { - return DBName -} - -type MemStore struct { -} - -func (s MemStore) String() string { - return MemDBName -} - -type DB struct { - path string - - cfg *config.LevelDBConfig - - db *leveldb.DB - - opts *opt.Options - - iteratorOpts *opt.ReadOptions - - cache cache.Cache - - filter filter.Filter -} - -func (s Store) Open(path string, cfg *config.Config) (driver.IDB, error) { - if err := os.MkdirAll(path, os.ModePerm); err != nil { - return nil, err - } - - db := new(DB) - db.path = path - db.cfg = &cfg.LevelDB - - db.initOpts() - - var err error - db.db, err = leveldb.OpenFile(db.path, db.opts) - - if err != nil { - return nil, err - } - - return db, nil -} - -func (s Store) Repair(path string, cfg *config.Config) error { - db, err := leveldb.RecoverFile(path, newOptions(&cfg.LevelDB)) - if err != nil { - return err - } - - db.Close() - return nil -} - -func (s MemStore) Open(path string, cfg *config.Config) (driver.IDB, error) { - db := new(DB) - db.path = path - db.cfg = &cfg.LevelDB - - db.initOpts() - - var err error - db.db, err = leveldb.Open(storage.NewMemStorage(), db.opts) - if err != nil { - return nil, err - } - - return db, nil -} - -func (s MemStore) Repair(path string, cfg *config.Config) error { - return nil -} - -func (db *DB) initOpts() { - db.opts = newOptions(db.cfg) - - db.iteratorOpts = &opt.ReadOptions{} - db.iteratorOpts.DontFillCache = true -} - -func newOptions(cfg *config.LevelDBConfig) *opt.Options { - opts := &opt.Options{} - opts.ErrorIfMissing = false - - cfg.Adjust() - - //opts.BlockCacher = cache.NewLRU(cfg.CacheSize) - opts.BlockCacheCapacity = cfg.CacheSize - - //we must use bloomfilter - opts.Filter = filter.NewBloomFilter(defaultFilterBits) - - if !cfg.Compression { - opts.Compression = opt.NoCompression - } else { - opts.Compression = opt.SnappyCompression - } - - opts.BlockSize = cfg.BlockSize - opts.WriteBuffer = cfg.WriteBufferSize - - return opts -} - -func (db *DB) Close() error { - return db.db.Close() -} - -func (db *DB) Put(key, value []byte) error { - return db.db.Put(key, value, nil) -} - -func (db *DB) Get(key []byte) ([]byte, error) { - v, err := db.db.Get(key, nil) - if err == leveldb.ErrNotFound { - return nil, nil - } - return v, nil -} - -func (db *DB) Delete(key []byte) error { - return db.db.Delete(key, nil) -} - -func (db *DB) NewWriteBatch() driver.IWriteBatch { - wb := &WriteBatch{ - db: db, - wbatch: new(leveldb.Batch), - } - return wb -} - -func (db *DB) NewIterator() driver.IIterator { - it := &Iterator{ - db.db.NewIterator(nil, db.iteratorOpts), - } - - return it -} - -func (db *DB) Begin() (driver.Tx, error) { - return nil, driver.ErrTxSupport -} - -func (db *DB) NewSnapshot() (driver.ISnapshot, error) { - snapshot, err := db.db.GetSnapshot() - if err != nil { - return nil, err - } - - s := &Snapshot{ - db: db, - snp: snapshot, - } - - return s, nil -} - -func init() { - driver.Register(Store{}) - driver.Register(MemStore{}) -} diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/iterator.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/iterator.go deleted file mode 100644 index c1fd8b5573bb8..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/goleveldb/iterator.go +++ /dev/null @@ -1,49 +0,0 @@ -package goleveldb - -import ( - "github.com/syndtr/goleveldb/leveldb/iterator" -) - -type Iterator struct { - it iterator.Iterator -} - -func (it *Iterator) Key() []byte { - return it.it.Key() -} - -func (it *Iterator) Value() []byte { - return it.it.Value() -} - -func (it *Iterator) Close() error { - if it.it != nil { - it.it.Release() - it.it = nil - } - return nil -} - -func (it *Iterator) Valid() bool { - return it.it.Valid() -} - -func (it *Iterator) Next() { - it.it.Next() -} - -func (it *Iterator) Prev() { - it.it.Prev() -} - -func (it *Iterator) First() { - it.it.First() -} - -func (it *Iterator) Last() { - it.it.Last() -} - -func (it *Iterator) Seek(key []byte) { - it.it.Seek(key) -} diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/snapshot.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/snapshot.go deleted file mode 100644 index ddf40f7d17526..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/goleveldb/snapshot.go +++ /dev/null @@ -1,26 +0,0 @@ -package goleveldb - -import ( - "gitea.com/lunny/nodb/store/driver" - "github.com/syndtr/goleveldb/leveldb" -) - -type Snapshot struct { - db *DB - snp *leveldb.Snapshot -} - -func (s *Snapshot) Get(key []byte) ([]byte, error) { - return s.snp.Get(key, s.db.iteratorOpts) -} - -func (s *Snapshot) NewIterator() driver.IIterator { - it := &Iterator{ - s.snp.NewIterator(nil, s.db.iteratorOpts), - } - return it -} - -func (s *Snapshot) Close() { - s.snp.Release() -} diff --git a/vendor/gitea.com/lunny/nodb/store/iterator.go b/vendor/gitea.com/lunny/nodb/store/iterator.go deleted file mode 100644 index df0311863fc09..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/iterator.go +++ /dev/null @@ -1,327 +0,0 @@ -package store - -import ( - "bytes" - - "gitea.com/lunny/nodb/store/driver" -) - -const ( - IteratorForward uint8 = 0 - IteratorBackward uint8 = 1 -) - -const ( - RangeClose uint8 = 0x00 - RangeLOpen uint8 = 0x01 - RangeROpen uint8 = 0x10 - RangeOpen uint8 = 0x11 -) - -// min must less or equal than max -// -// range type: -// -// close: [min, max] -// open: (min, max) -// lopen: (min, max] -// ropen: [min, max) -// -type Range struct { - Min []byte - Max []byte - - Type uint8 -} - -type Limit struct { - Offset int - Count int -} - -type Iterator struct { - it driver.IIterator -} - -// Returns a copy of key. -func (it *Iterator) Key() []byte { - k := it.it.Key() - if k == nil { - return nil - } - - return append([]byte{}, k...) -} - -// Returns a copy of value. -func (it *Iterator) Value() []byte { - v := it.it.Value() - if v == nil { - return nil - } - - return append([]byte{}, v...) -} - -// Returns a reference of key. -// you must be careful that it will be changed after next iterate. -func (it *Iterator) RawKey() []byte { - return it.it.Key() -} - -// Returns a reference of value. -// you must be careful that it will be changed after next iterate. -func (it *Iterator) RawValue() []byte { - return it.it.Value() -} - -// Copy key to b, if b len is small or nil, returns a new one. -func (it *Iterator) BufKey(b []byte) []byte { - k := it.RawKey() - if k == nil { - return nil - } - if b == nil { - b = []byte{} - } - - b = b[0:0] - return append(b, k...) -} - -// Copy value to b, if b len is small or nil, returns a new one. -func (it *Iterator) BufValue(b []byte) []byte { - v := it.RawValue() - if v == nil { - return nil - } - - if b == nil { - b = []byte{} - } - - b = b[0:0] - return append(b, v...) -} - -func (it *Iterator) Close() { - if it.it != nil { - it.it.Close() - it.it = nil - } -} - -func (it *Iterator) Valid() bool { - return it.it.Valid() -} - -func (it *Iterator) Next() { - it.it.Next() -} - -func (it *Iterator) Prev() { - it.it.Prev() -} - -func (it *Iterator) SeekToFirst() { - it.it.First() -} - -func (it *Iterator) SeekToLast() { - it.it.Last() -} - -func (it *Iterator) Seek(key []byte) { - it.it.Seek(key) -} - -// Finds by key, if not found, nil returns. -func (it *Iterator) Find(key []byte) []byte { - it.Seek(key) - if it.Valid() { - k := it.RawKey() - if k == nil { - return nil - } else if bytes.Equal(k, key) { - return it.Value() - } - } - - return nil -} - -// Finds by key, if not found, nil returns, else a reference of value returns. -// you must be careful that it will be changed after next iterate. -func (it *Iterator) RawFind(key []byte) []byte { - it.Seek(key) - if it.Valid() { - k := it.RawKey() - if k == nil { - return nil - } else if bytes.Equal(k, key) { - return it.RawValue() - } - } - - return nil -} - -type RangeLimitIterator struct { - it *Iterator - - r *Range - l *Limit - - step int - - //0 for IteratorForward, 1 for IteratorBackward - direction uint8 -} - -func (it *RangeLimitIterator) Key() []byte { - return it.it.Key() -} - -func (it *RangeLimitIterator) Value() []byte { - return it.it.Value() -} - -func (it *RangeLimitIterator) RawKey() []byte { - return it.it.RawKey() -} - -func (it *RangeLimitIterator) RawValue() []byte { - return it.it.RawValue() -} - -func (it *RangeLimitIterator) BufKey(b []byte) []byte { - return it.it.BufKey(b) -} - -func (it *RangeLimitIterator) BufValue(b []byte) []byte { - return it.it.BufValue(b) -} - -func (it *RangeLimitIterator) Valid() bool { - if it.l.Offset < 0 { - return false - } else if !it.it.Valid() { - return false - } else if it.l.Count >= 0 && it.step >= it.l.Count { - return false - } - - if it.direction == IteratorForward { - if it.r.Max != nil { - r := bytes.Compare(it.it.RawKey(), it.r.Max) - if it.r.Type&RangeROpen > 0 { - return !(r >= 0) - } else { - return !(r > 0) - } - } - } else { - if it.r.Min != nil { - r := bytes.Compare(it.it.RawKey(), it.r.Min) - if it.r.Type&RangeLOpen > 0 { - return !(r <= 0) - } else { - return !(r < 0) - } - } - } - - return true -} - -func (it *RangeLimitIterator) Next() { - it.step++ - - if it.direction == IteratorForward { - it.it.Next() - } else { - it.it.Prev() - } -} - -func (it *RangeLimitIterator) Close() { - it.it.Close() -} - -func NewRangeLimitIterator(i *Iterator, r *Range, l *Limit) *RangeLimitIterator { - return rangeLimitIterator(i, r, l, IteratorForward) -} - -func NewRevRangeLimitIterator(i *Iterator, r *Range, l *Limit) *RangeLimitIterator { - return rangeLimitIterator(i, r, l, IteratorBackward) -} - -func NewRangeIterator(i *Iterator, r *Range) *RangeLimitIterator { - return rangeLimitIterator(i, r, &Limit{0, -1}, IteratorForward) -} - -func NewRevRangeIterator(i *Iterator, r *Range) *RangeLimitIterator { - return rangeLimitIterator(i, r, &Limit{0, -1}, IteratorBackward) -} - -func rangeLimitIterator(i *Iterator, r *Range, l *Limit, direction uint8) *RangeLimitIterator { - it := new(RangeLimitIterator) - - it.it = i - - it.r = r - it.l = l - it.direction = direction - - it.step = 0 - - if l.Offset < 0 { - return it - } - - if direction == IteratorForward { - if r.Min == nil { - it.it.SeekToFirst() - } else { - it.it.Seek(r.Min) - - if r.Type&RangeLOpen > 0 { - if it.it.Valid() && bytes.Equal(it.it.RawKey(), r.Min) { - it.it.Next() - } - } - } - } else { - if r.Max == nil { - it.it.SeekToLast() - } else { - it.it.Seek(r.Max) - - if !it.it.Valid() { - it.it.SeekToLast() - } else { - if !bytes.Equal(it.it.RawKey(), r.Max) { - it.it.Prev() - } - } - - if r.Type&RangeROpen > 0 { - if it.it.Valid() && bytes.Equal(it.it.RawKey(), r.Max) { - it.it.Prev() - } - } - } - } - - for i := 0; i < l.Offset; i++ { - if it.it.Valid() { - if it.direction == IteratorForward { - it.it.Next() - } else { - it.it.Prev() - } - } - } - - return it -} diff --git a/vendor/gitea.com/lunny/nodb/store/snapshot.go b/vendor/gitea.com/lunny/nodb/store/snapshot.go deleted file mode 100644 index 0d804e87be704..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/snapshot.go +++ /dev/null @@ -1,16 +0,0 @@ -package store - -import ( - "gitea.com/lunny/nodb/store/driver" -) - -type Snapshot struct { - driver.ISnapshot -} - -func (s *Snapshot) NewIterator() *Iterator { - it := new(Iterator) - it.it = s.ISnapshot.NewIterator() - - return it -} diff --git a/vendor/gitea.com/lunny/nodb/store/store.go b/vendor/gitea.com/lunny/nodb/store/store.go deleted file mode 100644 index 687e40daf52db..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/store.go +++ /dev/null @@ -1,51 +0,0 @@ -package store - -import ( - "fmt" - "os" - "path" - "gitea.com/lunny/nodb/config" - "gitea.com/lunny/nodb/store/driver" - - _ "gitea.com/lunny/nodb/store/goleveldb" -) - -func getStorePath(cfg *config.Config) string { - return path.Join(cfg.DataDir, fmt.Sprintf("%s_data", cfg.DBName)) -} - -func Open(cfg *config.Config) (*DB, error) { - s, err := driver.GetStore(cfg) - if err != nil { - return nil, err - } - - path := getStorePath(cfg) - - if err := os.MkdirAll(path, os.ModePerm); err != nil { - return nil, err - } - - idb, err := s.Open(path, cfg) - if err != nil { - return nil, err - } - - db := &DB{idb} - - return db, nil -} - -func Repair(cfg *config.Config) error { - s, err := driver.GetStore(cfg) - if err != nil { - return err - } - - path := getStorePath(cfg) - - return s.Repair(path, cfg) -} - -func init() { -} diff --git a/vendor/gitea.com/lunny/nodb/store/tx.go b/vendor/gitea.com/lunny/nodb/store/tx.go deleted file mode 100644 index 3bcb5a9392a5d..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/tx.go +++ /dev/null @@ -1,42 +0,0 @@ -package store - -import ( - "gitea.com/lunny/nodb/store/driver" -) - -type Tx struct { - driver.Tx -} - -func (tx *Tx) NewIterator() *Iterator { - it := new(Iterator) - it.it = tx.Tx.NewIterator() - - return it -} - -func (tx *Tx) NewWriteBatch() WriteBatch { - return tx.Tx.NewWriteBatch() -} - -func (tx *Tx) RangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator { - return NewRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1}) -} - -func (tx *Tx) RevRangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator { - return NewRevRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1}) -} - -//count < 0, unlimit. -// -//offset must >= 0, if < 0, will get nothing. -func (tx *Tx) RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator { - return NewRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count}) -} - -//count < 0, unlimit. -// -//offset must >= 0, if < 0, will get nothing. -func (tx *Tx) RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator { - return NewRevRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count}) -} diff --git a/vendor/gitea.com/lunny/nodb/store/writebatch.go b/vendor/gitea.com/lunny/nodb/store/writebatch.go deleted file mode 100644 index 9419ec51a0991..0000000000000 --- a/vendor/gitea.com/lunny/nodb/store/writebatch.go +++ /dev/null @@ -1,9 +0,0 @@ -package store - -import ( - "gitea.com/lunny/nodb/store/driver" -) - -type WriteBatch interface { - driver.IWriteBatch -} diff --git a/vendor/gitea.com/lunny/nodb/t_bit.go b/vendor/gitea.com/lunny/nodb/t_bit.go deleted file mode 100644 index 92ea831718ac5..0000000000000 --- a/vendor/gitea.com/lunny/nodb/t_bit.go +++ /dev/null @@ -1,922 +0,0 @@ -package nodb - -import ( - "encoding/binary" - "errors" - "sort" - "time" - - "gitea.com/lunny/nodb/store" -) - -const ( - OPand uint8 = iota + 1 - OPor - OPxor - OPnot -) - -type BitPair struct { - Pos int32 - Val uint8 -} - -type segBitInfo struct { - Seq uint32 - Off uint32 - Val uint8 -} - -type segBitInfoArray []segBitInfo - -const ( - // byte - segByteWidth uint32 = 9 - segByteSize uint32 = 1 << segByteWidth - - // bit - segBitWidth uint32 = segByteWidth + 3 - segBitSize uint32 = segByteSize << 3 - - maxByteSize uint32 = 8 << 20 - maxSegCount uint32 = maxByteSize / segByteSize - - minSeq uint32 = 0 - maxSeq uint32 = uint32((maxByteSize << 3) - 1) -) - -var bitsInByte = [256]int32{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, - 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, - 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, - 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, - 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, - 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, - 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, - 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, - 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, - 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, - 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8} - -var fillBits = [...]uint8{1, 3, 7, 15, 31, 63, 127, 255} - -var emptySegment []byte = make([]byte, segByteSize, segByteSize) - -var fillSegment []byte = func() []byte { - data := make([]byte, segByteSize, segByteSize) - for i := uint32(0); i < segByteSize; i++ { - data[i] = 0xff - } - return data -}() - -var errBinKey = errors.New("invalid bin key") -var errOffset = errors.New("invalid offset") -var errDuplicatePos = errors.New("duplicate bit pos") - -func getBit(sz []byte, offset uint32) uint8 { - index := offset >> 3 - if index >= uint32(len(sz)) { - return 0 // error("overflow") - } - - offset -= index << 3 - return sz[index] >> offset & 1 -} - -func setBit(sz []byte, offset uint32, val uint8) bool { - if val != 1 && val != 0 { - return false // error("invalid val") - } - - index := offset >> 3 - if index >= uint32(len(sz)) { - return false // error("overflow") - } - - offset -= index << 3 - if sz[index]>>offset&1 != val { - sz[index] ^= (1 << offset) - } - return true -} - -func (datas segBitInfoArray) Len() int { - return len(datas) -} - -func (datas segBitInfoArray) Less(i, j int) bool { - res := (datas)[i].Seq < (datas)[j].Seq - if !res && (datas)[i].Seq == (datas)[j].Seq { - res = (datas)[i].Off < (datas)[j].Off - } - return res -} - -func (datas segBitInfoArray) Swap(i, j int) { - datas[i], datas[j] = datas[j], datas[i] -} - -func (db *DB) bEncodeMetaKey(key []byte) []byte { - mk := make([]byte, len(key)+2) - mk[0] = db.index - mk[1] = BitMetaType - - copy(mk[2:], key) - return mk -} - -func (db *DB) bDecodeMetaKey(bkey []byte) ([]byte, error) { - if len(bkey) < 2 || bkey[0] != db.index || bkey[1] != BitMetaType { - return nil, errBinKey - } - - return bkey[2:], nil -} - -func (db *DB) bEncodeBinKey(key []byte, seq uint32) []byte { - bk := make([]byte, len(key)+8) - - pos := 0 - bk[pos] = db.index - pos++ - bk[pos] = BitType - pos++ - - binary.BigEndian.PutUint16(bk[pos:], uint16(len(key))) - pos += 2 - - copy(bk[pos:], key) - pos += len(key) - - binary.BigEndian.PutUint32(bk[pos:], seq) - - return bk -} - -func (db *DB) bDecodeBinKey(bkey []byte) (key []byte, seq uint32, err error) { - if len(bkey) < 8 || bkey[0] != db.index { - err = errBinKey - return - } - - keyLen := binary.BigEndian.Uint16(bkey[2:4]) - if int(keyLen+8) != len(bkey) { - err = errBinKey - return - } - - key = bkey[4 : 4+keyLen] - seq = uint32(binary.BigEndian.Uint32(bkey[4+keyLen:])) - return -} - -func (db *DB) bCapByteSize(seq uint32, off uint32) uint32 { - var offByteSize uint32 = (off >> 3) + 1 - if offByteSize > segByteSize { - offByteSize = segByteSize - } - - return seq<= 0 { - offset += int32((uint32(tailSeq)<> segBitWidth - off &= (segBitSize - 1) - return -} - -func (db *DB) bGetMeta(key []byte) (tailSeq int32, tailOff int32, err error) { - var v []byte - - mk := db.bEncodeMetaKey(key) - v, err = db.bucket.Get(mk) - if err != nil { - return - } - - if v != nil { - tailSeq = int32(binary.LittleEndian.Uint32(v[0:4])) - tailOff = int32(binary.LittleEndian.Uint32(v[4:8])) - } else { - tailSeq = -1 - tailOff = -1 - } - return -} - -func (db *DB) bSetMeta(t *batch, key []byte, tailSeq uint32, tailOff uint32) { - ek := db.bEncodeMetaKey(key) - - buf := make([]byte, 8) - binary.LittleEndian.PutUint32(buf[0:4], tailSeq) - binary.LittleEndian.PutUint32(buf[4:8], tailOff) - - t.Put(ek, buf) - return -} - -func (db *DB) bUpdateMeta(t *batch, key []byte, seq uint32, off uint32) (tailSeq uint32, tailOff uint32, err error) { - var tseq, toff int32 - var update bool = false - - if tseq, toff, err = db.bGetMeta(key); err != nil { - return - } else if tseq < 0 { - update = true - } else { - tailSeq = uint32(MaxInt32(tseq, 0)) - tailOff = uint32(MaxInt32(toff, 0)) - update = (seq > tailSeq || (seq == tailSeq && off > tailOff)) - } - - if update { - db.bSetMeta(t, key, seq, off) - tailSeq = seq - tailOff = off - } - return -} - -func (db *DB) bDelete(t *batch, key []byte) (drop int64) { - mk := db.bEncodeMetaKey(key) - t.Delete(mk) - - minKey := db.bEncodeBinKey(key, minSeq) - maxKey := db.bEncodeBinKey(key, maxSeq) - it := db.bucket.RangeIterator(minKey, maxKey, store.RangeClose) - for ; it.Valid(); it.Next() { - t.Delete(it.RawKey()) - drop++ - } - it.Close() - - return drop -} - -func (db *DB) bGetSegment(key []byte, seq uint32) ([]byte, []byte, error) { - bk := db.bEncodeBinKey(key, seq) - segment, err := db.bucket.Get(bk) - if err != nil { - return bk, nil, err - } - return bk, segment, nil -} - -func (db *DB) bAllocateSegment(key []byte, seq uint32) ([]byte, []byte, error) { - bk, segment, err := db.bGetSegment(key, seq) - if err == nil && segment == nil { - segment = make([]byte, segByteSize, segByteSize) - } - return bk, segment, err -} - -func (db *DB) bIterator(key []byte) *store.RangeLimitIterator { - sk := db.bEncodeBinKey(key, minSeq) - ek := db.bEncodeBinKey(key, maxSeq) - return db.bucket.RangeIterator(sk, ek, store.RangeClose) -} - -func (db *DB) bSegAnd(a []byte, b []byte, res *[]byte) { - if a == nil || b == nil { - *res = nil - return - } - - data := *res - if data == nil { - data = make([]byte, segByteSize, segByteSize) - *res = data - } - - for i := uint32(0); i < segByteSize; i++ { - data[i] = a[i] & b[i] - } - return -} - -func (db *DB) bSegOr(a []byte, b []byte, res *[]byte) { - if a == nil || b == nil { - if a == nil && b == nil { - *res = nil - } else if a == nil { - *res = b - } else { - *res = a - } - return - } - - data := *res - if data == nil { - data = make([]byte, segByteSize, segByteSize) - *res = data - } - - for i := uint32(0); i < segByteSize; i++ { - data[i] = a[i] | b[i] - } - return -} - -func (db *DB) bSegXor(a []byte, b []byte, res *[]byte) { - if a == nil && b == nil { - *res = fillSegment - return - } - - if a == nil { - a = emptySegment - } - - if b == nil { - b = emptySegment - } - - data := *res - if data == nil { - data = make([]byte, segByteSize, segByteSize) - *res = data - } - - for i := uint32(0); i < segByteSize; i++ { - data[i] = a[i] ^ b[i] - } - - return -} - -func (db *DB) bExpireAt(key []byte, when int64) (int64, error) { - t := db.binBatch - t.Lock() - defer t.Unlock() - - if seq, _, err := db.bGetMeta(key); err != nil || seq < 0 { - return 0, err - } else { - db.expireAt(t, BitType, key, when) - if err := t.Commit(); err != nil { - return 0, err - } - } - return 1, nil -} - -func (db *DB) bCountByte(val byte, soff uint32, eoff uint32) int32 { - if soff > eoff { - soff, eoff = eoff, soff - } - - mask := uint8(0) - if soff > 0 { - mask |= fillBits[soff-1] - } - if eoff < 7 { - mask |= (fillBits[7] ^ fillBits[eoff]) - } - mask = fillBits[7] ^ mask - - return bitsInByte[val&mask] -} - -func (db *DB) bCountSeg(key []byte, seq uint32, soff uint32, eoff uint32) (cnt int32, err error) { - if soff >= segBitSize || soff < 0 || - eoff >= segBitSize || eoff < 0 { - return - } - - var segment []byte - if _, segment, err = db.bGetSegment(key, seq); err != nil { - return - } - - if segment == nil { - return - } - - if soff > eoff { - soff, eoff = eoff, soff - } - - headIdx := int(soff >> 3) - endIdx := int(eoff >> 3) - sByteOff := soff - ((soff >> 3) << 3) - eByteOff := eoff - ((eoff >> 3) << 3) - - if headIdx == endIdx { - cnt = db.bCountByte(segment[headIdx], sByteOff, eByteOff) - } else { - cnt = db.bCountByte(segment[headIdx], sByteOff, 7) + - db.bCountByte(segment[endIdx], 0, eByteOff) - } - - // sum up following bytes - for idx, end := headIdx+1, endIdx-1; idx <= end; idx += 1 { - cnt += bitsInByte[segment[idx]] - if idx == end { - break - } - } - - return -} - -func (db *DB) BGet(key []byte) (data []byte, err error) { - if err = checkKeySize(key); err != nil { - return - } - - var ts, to int32 - if ts, to, err = db.bGetMeta(key); err != nil || ts < 0 { - return - } - - var tailSeq, tailOff = uint32(ts), uint32(to) - var capByteSize uint32 = db.bCapByteSize(tailSeq, tailOff) - data = make([]byte, capByteSize, capByteSize) - - minKey := db.bEncodeBinKey(key, minSeq) - maxKey := db.bEncodeBinKey(key, tailSeq) - it := db.bucket.RangeIterator(minKey, maxKey, store.RangeClose) - - var seq, s, e uint32 - for ; it.Valid(); it.Next() { - if _, seq, err = db.bDecodeBinKey(it.RawKey()); err != nil { - data = nil - break - } - - s = seq << segByteWidth - e = MinUInt32(s+segByteSize, capByteSize) - copy(data[s:e], it.RawValue()) - } - it.Close() - - return -} - -func (db *DB) BDelete(key []byte) (drop int64, err error) { - if err = checkKeySize(key); err != nil { - return - } - - t := db.binBatch - t.Lock() - defer t.Unlock() - - drop = db.bDelete(t, key) - db.rmExpire(t, BitType, key) - - err = t.Commit() - return -} - -func (db *DB) BSetBit(key []byte, offset int32, val uint8) (ori uint8, err error) { - if err = checkKeySize(key); err != nil { - return - } - - // todo : check offset - var seq, off uint32 - if seq, off, err = db.bParseOffset(key, offset); err != nil { - return 0, err - } - - var bk, segment []byte - if bk, segment, err = db.bAllocateSegment(key, seq); err != nil { - return 0, err - } - - if segment != nil { - ori = getBit(segment, off) - if setBit(segment, off, val) { - t := db.binBatch - t.Lock() - defer t.Unlock() - - t.Put(bk, segment) - if _, _, e := db.bUpdateMeta(t, key, seq, off); e != nil { - err = e - return - } - - err = t.Commit() - } - } - - return -} - -func (db *DB) BMSetBit(key []byte, args ...BitPair) (place int64, err error) { - if err = checkKeySize(key); err != nil { - return - } - - // (ps : so as to aviod wasting memory copy while calling db.Get() and batch.Put(), - // here we sequence the params by pos, so that we can merge the execution of - // diff pos setting which targets on the same segment respectively. ) - - // #1 : sequence request data - var argCnt = len(args) - var bitInfos segBitInfoArray = make(segBitInfoArray, argCnt) - var seq, off uint32 - - for i, info := range args { - if seq, off, err = db.bParseOffset(key, info.Pos); err != nil { - return - } - - bitInfos[i].Seq = seq - bitInfos[i].Off = off - bitInfos[i].Val = info.Val - } - - sort.Sort(bitInfos) - - for i := 1; i < argCnt; i++ { - if bitInfos[i].Seq == bitInfos[i-1].Seq && bitInfos[i].Off == bitInfos[i-1].Off { - return 0, errDuplicatePos - } - } - - // #2 : execute bit set in order - t := db.binBatch - t.Lock() - defer t.Unlock() - - var curBinKey, curSeg []byte - var curSeq, maxSeq, maxOff uint32 - - for _, info := range bitInfos { - if curSeg != nil && info.Seq != curSeq { - t.Put(curBinKey, curSeg) - curSeg = nil - } - - if curSeg == nil { - curSeq = info.Seq - if curBinKey, curSeg, err = db.bAllocateSegment(key, info.Seq); err != nil { - return - } - - if curSeg == nil { - continue - } - } - - if setBit(curSeg, info.Off, info.Val) { - maxSeq = info.Seq - maxOff = info.Off - place++ - } - } - - if curSeg != nil { - t.Put(curBinKey, curSeg) - } - - // finally, update meta - if place > 0 { - if _, _, err = db.bUpdateMeta(t, key, maxSeq, maxOff); err != nil { - return - } - - err = t.Commit() - } - - return -} - -func (db *DB) BGetBit(key []byte, offset int32) (uint8, error) { - if seq, off, err := db.bParseOffset(key, offset); err != nil { - return 0, err - } else { - _, segment, err := db.bGetSegment(key, seq) - if err != nil { - return 0, err - } - - if segment == nil { - return 0, nil - } else { - return getBit(segment, off), nil - } - } -} - -// func (db *DB) BGetRange(key []byte, start int32, end int32) ([]byte, error) { -// section := make([]byte) - -// return -// } - -func (db *DB) BCount(key []byte, start int32, end int32) (cnt int32, err error) { - var sseq, soff uint32 - if sseq, soff, err = db.bParseOffset(key, start); err != nil { - return - } - - var eseq, eoff uint32 - if eseq, eoff, err = db.bParseOffset(key, end); err != nil { - return - } - - if sseq > eseq || (sseq == eseq && soff > eoff) { - sseq, eseq = eseq, sseq - soff, eoff = eoff, soff - } - - var segCnt int32 - if eseq == sseq { - if segCnt, err = db.bCountSeg(key, sseq, soff, eoff); err != nil { - return 0, err - } - - cnt = segCnt - - } else { - if segCnt, err = db.bCountSeg(key, sseq, soff, segBitSize-1); err != nil { - return 0, err - } else { - cnt += segCnt - } - - if segCnt, err = db.bCountSeg(key, eseq, 0, eoff); err != nil { - return 0, err - } else { - cnt += segCnt - } - } - - // middle segs - var segment []byte - skey := db.bEncodeBinKey(key, sseq) - ekey := db.bEncodeBinKey(key, eseq) - - it := db.bucket.RangeIterator(skey, ekey, store.RangeOpen) - for ; it.Valid(); it.Next() { - segment = it.RawValue() - for _, bt := range segment { - cnt += bitsInByte[bt] - } - } - it.Close() - - return -} - -func (db *DB) BTail(key []byte) (int32, error) { - // effective length of data, the highest bit-pos set in history - tailSeq, tailOff, err := db.bGetMeta(key) - if err != nil { - return 0, err - } - - tail := int32(-1) - if tailSeq >= 0 { - tail = int32(uint32(tailSeq)< maxDstSeq || (seq == maxDstSeq && off > maxDstOff) { - maxDstSeq = seq - maxDstOff = off - } - } - - if (op == OPnot && validKeyNum != 1) || - (op != OPnot && validKeyNum < 2) { - return // with not enough existing source key - } - - var srcIdx int - for srcIdx = 0; srcIdx < keyNum; srcIdx++ { - if srckeys[srcIdx] != nil { - break - } - } - - // init - data - var segments = make([][]byte, maxDstSeq+1) - - if op == OPnot { - // ps : - // ( ~num == num ^ 0x11111111 ) - // we init the result segments with all bit set, - // then we can calculate through the way of 'xor'. - - // ahead segments bin format : 1111 ... 1111 - for i := uint32(0); i < maxDstSeq; i++ { - segments[i] = fillSegment - } - - // last segment bin format : 1111..1100..0000 - var tailSeg = make([]byte, segByteSize, segByteSize) - var fillByte = fillBits[7] - var tailSegLen = db.bCapByteSize(uint32(0), maxDstOff) - for i := uint32(0); i < tailSegLen-1; i++ { - tailSeg[i] = fillByte - } - tailSeg[tailSegLen-1] = fillBits[maxDstOff-(tailSegLen-1)<<3] - segments[maxDstSeq] = tailSeg - - } else { - // ps : init segments by data corresponding to the 1st valid source key - it := db.bIterator(srckeys[srcIdx]) - for ; it.Valid(); it.Next() { - if _, seq, err = db.bDecodeBinKey(it.RawKey()); err != nil { - // to do ... - it.Close() - return - } - segments[seq] = it.Value() - } - it.Close() - srcIdx++ - } - - // operation with following keys - var res []byte - for i := srcIdx; i < keyNum; i++ { - if srckeys[i] == nil { - continue - } - - it := db.bIterator(srckeys[i]) - for idx, end := uint32(0), false; !end; it.Next() { - end = !it.Valid() - if !end { - if _, seq, err = db.bDecodeBinKey(it.RawKey()); err != nil { - // to do ... - it.Close() - return - } - } else { - seq = maxDstSeq + 1 - } - - // todo : - // operation 'and' can be optimize here : - // if seq > max_segments_idx, this loop can be break, - // which can avoid cost from Key() and bDecodeBinKey() - - for ; idx < seq; idx++ { - res = nil - exeOp(segments[idx], nil, &res) - segments[idx] = res - } - - if !end { - res = it.Value() - exeOp(segments[seq], res, &res) - segments[seq] = res - idx++ - } - } - it.Close() - } - - // clear the old data in case - db.bDelete(t, dstkey) - db.rmExpire(t, BitType, dstkey) - - // set data - db.bSetMeta(t, dstkey, maxDstSeq, maxDstOff) - - var bk []byte - for seq, segt := range segments { - if segt != nil { - bk = db.bEncodeBinKey(dstkey, uint32(seq)) - t.Put(bk, segt) - } - } - - err = t.Commit() - if err == nil { - // blen = int32(db.bCapByteSize(maxDstOff, maxDstOff)) - blen = int32(maxDstSeq< MaxKeySize || len(key) == 0 { - return errKeySize - } else if len(field) > MaxHashFieldSize || len(field) == 0 { - return errHashFieldSize - } - return nil -} - -func (db *DB) hEncodeSizeKey(key []byte) []byte { - buf := make([]byte, len(key)+2) - - buf[0] = db.index - buf[1] = HSizeType - - copy(buf[2:], key) - return buf -} - -func (db *DB) hDecodeSizeKey(ek []byte) ([]byte, error) { - if len(ek) < 2 || ek[0] != db.index || ek[1] != HSizeType { - return nil, errHSizeKey - } - - return ek[2:], nil -} - -func (db *DB) hEncodeHashKey(key []byte, field []byte) []byte { - buf := make([]byte, len(key)+len(field)+1+1+2+1) - - pos := 0 - buf[pos] = db.index - pos++ - buf[pos] = HashType - pos++ - - binary.BigEndian.PutUint16(buf[pos:], uint16(len(key))) - pos += 2 - - copy(buf[pos:], key) - pos += len(key) - - buf[pos] = hashStartSep - pos++ - copy(buf[pos:], field) - - return buf -} - -func (db *DB) hDecodeHashKey(ek []byte) ([]byte, []byte, error) { - if len(ek) < 5 || ek[0] != db.index || ek[1] != HashType { - return nil, nil, errHashKey - } - - pos := 2 - keyLen := int(binary.BigEndian.Uint16(ek[pos:])) - pos += 2 - - if keyLen+5 > len(ek) { - return nil, nil, errHashKey - } - - key := ek[pos : pos+keyLen] - pos += keyLen - - if ek[pos] != hashStartSep { - return nil, nil, errHashKey - } - - pos++ - field := ek[pos:] - return key, field, nil -} - -func (db *DB) hEncodeStartKey(key []byte) []byte { - return db.hEncodeHashKey(key, nil) -} - -func (db *DB) hEncodeStopKey(key []byte) []byte { - k := db.hEncodeHashKey(key, nil) - - k[len(k)-1] = hashStopSep - - return k -} - -func (db *DB) hSetItem(key []byte, field []byte, value []byte) (int64, error) { - t := db.hashBatch - - ek := db.hEncodeHashKey(key, field) - - var n int64 = 1 - if v, _ := db.bucket.Get(ek); v != nil { - n = 0 - } else { - if _, err := db.hIncrSize(key, 1); err != nil { - return 0, err - } - } - - t.Put(ek, value) - return n, nil -} - -// ps : here just focus on deleting the hash data, -// any other likes expire is ignore. -func (db *DB) hDelete(t *batch, key []byte) int64 { - sk := db.hEncodeSizeKey(key) - start := db.hEncodeStartKey(key) - stop := db.hEncodeStopKey(key) - - var num int64 = 0 - it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1) - for ; it.Valid(); it.Next() { - t.Delete(it.Key()) - num++ - } - it.Close() - - t.Delete(sk) - return num -} - -func (db *DB) hExpireAt(key []byte, when int64) (int64, error) { - t := db.hashBatch - t.Lock() - defer t.Unlock() - - if hlen, err := db.HLen(key); err != nil || hlen == 0 { - return 0, err - } else { - db.expireAt(t, HashType, key, when) - if err := t.Commit(); err != nil { - return 0, err - } - } - return 1, nil -} - -func (db *DB) HLen(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - return Int64(db.bucket.Get(db.hEncodeSizeKey(key))) -} - -func (db *DB) HSet(key []byte, field []byte, value []byte) (int64, error) { - if err := checkHashKFSize(key, field); err != nil { - return 0, err - } else if err := checkValueSize(value); err != nil { - return 0, err - } - - t := db.hashBatch - t.Lock() - defer t.Unlock() - - n, err := db.hSetItem(key, field, value) - if err != nil { - return 0, err - } - - //todo add binlog - - err = t.Commit() - return n, err -} - -func (db *DB) HGet(key []byte, field []byte) ([]byte, error) { - if err := checkHashKFSize(key, field); err != nil { - return nil, err - } - - return db.bucket.Get(db.hEncodeHashKey(key, field)) -} - -func (db *DB) HMset(key []byte, args ...FVPair) error { - t := db.hashBatch - t.Lock() - defer t.Unlock() - - var err error - var ek []byte - var num int64 = 0 - for i := 0; i < len(args); i++ { - if err := checkHashKFSize(key, args[i].Field); err != nil { - return err - } else if err := checkValueSize(args[i].Value); err != nil { - return err - } - - ek = db.hEncodeHashKey(key, args[i].Field) - - if v, err := db.bucket.Get(ek); err != nil { - return err - } else if v == nil { - num++ - } - - t.Put(ek, args[i].Value) - } - - if _, err = db.hIncrSize(key, num); err != nil { - return err - } - - //todo add binglog - err = t.Commit() - return err -} - -func (db *DB) HMget(key []byte, args ...[]byte) ([][]byte, error) { - var ek []byte - - it := db.bucket.NewIterator() - defer it.Close() - - r := make([][]byte, len(args)) - for i := 0; i < len(args); i++ { - if err := checkHashKFSize(key, args[i]); err != nil { - return nil, err - } - - ek = db.hEncodeHashKey(key, args[i]) - - r[i] = it.Find(ek) - } - - return r, nil -} - -func (db *DB) HDel(key []byte, args ...[]byte) (int64, error) { - t := db.hashBatch - - var ek []byte - var v []byte - var err error - - t.Lock() - defer t.Unlock() - - it := db.bucket.NewIterator() - defer it.Close() - - var num int64 = 0 - for i := 0; i < len(args); i++ { - if err := checkHashKFSize(key, args[i]); err != nil { - return 0, err - } - - ek = db.hEncodeHashKey(key, args[i]) - - v = it.RawFind(ek) - if v == nil { - continue - } else { - num++ - t.Delete(ek) - } - } - - if _, err = db.hIncrSize(key, -num); err != nil { - return 0, err - } - - err = t.Commit() - - return num, err -} - -func (db *DB) hIncrSize(key []byte, delta int64) (int64, error) { - t := db.hashBatch - sk := db.hEncodeSizeKey(key) - - var err error - var size int64 = 0 - if size, err = Int64(db.bucket.Get(sk)); err != nil { - return 0, err - } else { - size += delta - if size <= 0 { - size = 0 - t.Delete(sk) - db.rmExpire(t, HashType, key) - } else { - t.Put(sk, PutInt64(size)) - } - } - - return size, nil -} - -func (db *DB) HIncrBy(key []byte, field []byte, delta int64) (int64, error) { - if err := checkHashKFSize(key, field); err != nil { - return 0, err - } - - t := db.hashBatch - var ek []byte - var err error - - t.Lock() - defer t.Unlock() - - ek = db.hEncodeHashKey(key, field) - - var n int64 = 0 - if n, err = StrInt64(db.bucket.Get(ek)); err != nil { - return 0, err - } - - n += delta - - _, err = db.hSetItem(key, field, StrPutInt64(n)) - if err != nil { - return 0, err - } - - err = t.Commit() - - return n, err -} - -func (db *DB) HGetAll(key []byte) ([]FVPair, error) { - if err := checkKeySize(key); err != nil { - return nil, err - } - - start := db.hEncodeStartKey(key) - stop := db.hEncodeStopKey(key) - - v := make([]FVPair, 0, 16) - - it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1) - for ; it.Valid(); it.Next() { - _, f, err := db.hDecodeHashKey(it.Key()) - if err != nil { - return nil, err - } - - v = append(v, FVPair{Field: f, Value: it.Value()}) - } - - it.Close() - - return v, nil -} - -func (db *DB) HKeys(key []byte) ([][]byte, error) { - if err := checkKeySize(key); err != nil { - return nil, err - } - - start := db.hEncodeStartKey(key) - stop := db.hEncodeStopKey(key) - - v := make([][]byte, 0, 16) - - it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1) - for ; it.Valid(); it.Next() { - _, f, err := db.hDecodeHashKey(it.Key()) - if err != nil { - return nil, err - } - v = append(v, f) - } - - it.Close() - - return v, nil -} - -func (db *DB) HValues(key []byte) ([][]byte, error) { - if err := checkKeySize(key); err != nil { - return nil, err - } - - start := db.hEncodeStartKey(key) - stop := db.hEncodeStopKey(key) - - v := make([][]byte, 0, 16) - - it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1) - for ; it.Valid(); it.Next() { - _, _, err := db.hDecodeHashKey(it.Key()) - if err != nil { - return nil, err - } - - v = append(v, it.Value()) - } - - it.Close() - - return v, nil -} - -func (db *DB) HClear(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - t := db.hashBatch - t.Lock() - defer t.Unlock() - - num := db.hDelete(t, key) - db.rmExpire(t, HashType, key) - - err := t.Commit() - return num, err -} - -func (db *DB) HMclear(keys ...[]byte) (int64, error) { - t := db.hashBatch - t.Lock() - defer t.Unlock() - - for _, key := range keys { - if err := checkKeySize(key); err != nil { - return 0, err - } - - db.hDelete(t, key) - db.rmExpire(t, HashType, key) - } - - err := t.Commit() - return int64(len(keys)), err -} - -func (db *DB) hFlush() (drop int64, err error) { - t := db.hashBatch - - t.Lock() - defer t.Unlock() - - return db.flushType(t, HashType) -} - -func (db *DB) HScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) { - return db.scan(HSizeType, key, count, inclusive, match) -} - -func (db *DB) HExpire(key []byte, duration int64) (int64, error) { - if duration <= 0 { - return 0, errExpireValue - } - - return db.hExpireAt(key, time.Now().Unix()+duration) -} - -func (db *DB) HExpireAt(key []byte, when int64) (int64, error) { - if when <= time.Now().Unix() { - return 0, errExpireValue - } - - return db.hExpireAt(key, when) -} - -func (db *DB) HTTL(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return -1, err - } - - return db.ttl(HashType, key) -} - -func (db *DB) HPersist(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - t := db.hashBatch - t.Lock() - defer t.Unlock() - - n, err := db.rmExpire(t, HashType, key) - if err != nil { - return 0, err - } - - err = t.Commit() - return n, err -} diff --git a/vendor/gitea.com/lunny/nodb/t_kv.go b/vendor/gitea.com/lunny/nodb/t_kv.go deleted file mode 100644 index 82a12f7027a5e..0000000000000 --- a/vendor/gitea.com/lunny/nodb/t_kv.go +++ /dev/null @@ -1,387 +0,0 @@ -package nodb - -import ( - "errors" - "time" -) - -type KVPair struct { - Key []byte - Value []byte -} - -var errKVKey = errors.New("invalid encode kv key") - -func checkKeySize(key []byte) error { - if len(key) > MaxKeySize || len(key) == 0 { - return errKeySize - } - return nil -} - -func checkValueSize(value []byte) error { - if len(value) > MaxValueSize { - return errValueSize - } - - return nil -} - -func (db *DB) encodeKVKey(key []byte) []byte { - ek := make([]byte, len(key)+2) - ek[0] = db.index - ek[1] = KVType - copy(ek[2:], key) - return ek -} - -func (db *DB) decodeKVKey(ek []byte) ([]byte, error) { - if len(ek) < 2 || ek[0] != db.index || ek[1] != KVType { - return nil, errKVKey - } - - return ek[2:], nil -} - -func (db *DB) encodeKVMinKey() []byte { - ek := db.encodeKVKey(nil) - return ek -} - -func (db *DB) encodeKVMaxKey() []byte { - ek := db.encodeKVKey(nil) - ek[len(ek)-1] = KVType + 1 - return ek -} - -func (db *DB) incr(key []byte, delta int64) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - var err error - key = db.encodeKVKey(key) - - t := db.kvBatch - - t.Lock() - defer t.Unlock() - - var n int64 - n, err = StrInt64(db.bucket.Get(key)) - if err != nil { - return 0, err - } - - n += delta - - t.Put(key, StrPutInt64(n)) - - //todo binlog - - err = t.Commit() - return n, err -} - -// ps : here just focus on deleting the key-value data, -// any other likes expire is ignore. -func (db *DB) delete(t *batch, key []byte) int64 { - key = db.encodeKVKey(key) - t.Delete(key) - return 1 -} - -func (db *DB) setExpireAt(key []byte, when int64) (int64, error) { - t := db.kvBatch - t.Lock() - defer t.Unlock() - - if exist, err := db.Exists(key); err != nil || exist == 0 { - return 0, err - } else { - db.expireAt(t, KVType, key, when) - if err := t.Commit(); err != nil { - return 0, err - } - } - return 1, nil -} - -func (db *DB) Decr(key []byte) (int64, error) { - return db.incr(key, -1) -} - -func (db *DB) DecrBy(key []byte, decrement int64) (int64, error) { - return db.incr(key, -decrement) -} - -func (db *DB) Del(keys ...[]byte) (int64, error) { - if len(keys) == 0 { - return 0, nil - } - - codedKeys := make([][]byte, len(keys)) - for i, k := range keys { - codedKeys[i] = db.encodeKVKey(k) - } - - t := db.kvBatch - t.Lock() - defer t.Unlock() - - for i, k := range keys { - t.Delete(codedKeys[i]) - db.rmExpire(t, KVType, k) - } - - err := t.Commit() - return int64(len(keys)), err -} - -func (db *DB) Exists(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - var err error - key = db.encodeKVKey(key) - - var v []byte - v, err = db.bucket.Get(key) - if v != nil && err == nil { - return 1, nil - } - - return 0, err -} - -func (db *DB) Get(key []byte) ([]byte, error) { - if err := checkKeySize(key); err != nil { - return nil, err - } - - key = db.encodeKVKey(key) - - return db.bucket.Get(key) -} - -func (db *DB) GetSet(key []byte, value []byte) ([]byte, error) { - if err := checkKeySize(key); err != nil { - return nil, err - } else if err := checkValueSize(value); err != nil { - return nil, err - } - - key = db.encodeKVKey(key) - - t := db.kvBatch - - t.Lock() - defer t.Unlock() - - oldValue, err := db.bucket.Get(key) - if err != nil { - return nil, err - } - - t.Put(key, value) - //todo, binlog - - err = t.Commit() - - return oldValue, err -} - -func (db *DB) Incr(key []byte) (int64, error) { - return db.incr(key, 1) -} - -func (db *DB) IncrBy(key []byte, increment int64) (int64, error) { - return db.incr(key, increment) -} - -func (db *DB) MGet(keys ...[]byte) ([][]byte, error) { - values := make([][]byte, len(keys)) - - it := db.bucket.NewIterator() - defer it.Close() - - for i := range keys { - if err := checkKeySize(keys[i]); err != nil { - return nil, err - } - - values[i] = it.Find(db.encodeKVKey(keys[i])) - } - - return values, nil -} - -func (db *DB) MSet(args ...KVPair) error { - if len(args) == 0 { - return nil - } - - t := db.kvBatch - - var err error - var key []byte - var value []byte - - t.Lock() - defer t.Unlock() - - for i := 0; i < len(args); i++ { - if err := checkKeySize(args[i].Key); err != nil { - return err - } else if err := checkValueSize(args[i].Value); err != nil { - return err - } - - key = db.encodeKVKey(args[i].Key) - - value = args[i].Value - - t.Put(key, value) - - //todo binlog - } - - err = t.Commit() - return err -} - -func (db *DB) Set(key []byte, value []byte) error { - if err := checkKeySize(key); err != nil { - return err - } else if err := checkValueSize(value); err != nil { - return err - } - - var err error - key = db.encodeKVKey(key) - - t := db.kvBatch - - t.Lock() - defer t.Unlock() - - t.Put(key, value) - - err = t.Commit() - - return err -} - -func (db *DB) SetNX(key []byte, value []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } else if err := checkValueSize(value); err != nil { - return 0, err - } - - var err error - key = db.encodeKVKey(key) - - var n int64 = 1 - - t := db.kvBatch - - t.Lock() - defer t.Unlock() - - if v, err := db.bucket.Get(key); err != nil { - return 0, err - } else if v != nil { - n = 0 - } else { - t.Put(key, value) - - //todo binlog - - err = t.Commit() - } - - return n, err -} - -func (db *DB) flush() (drop int64, err error) { - t := db.kvBatch - t.Lock() - defer t.Unlock() - return db.flushType(t, KVType) -} - -//if inclusive is true, scan range [key, inf) else (key, inf) -func (db *DB) Scan(key []byte, count int, inclusive bool, match string) ([][]byte, error) { - return db.scan(KVType, key, count, inclusive, match) -} - -func (db *DB) Expire(key []byte, duration int64) (int64, error) { - if duration <= 0 { - return 0, errExpireValue - } - - return db.setExpireAt(key, time.Now().Unix()+duration) -} - -func (db *DB) ExpireAt(key []byte, when int64) (int64, error) { - if when <= time.Now().Unix() { - return 0, errExpireValue - } - - return db.setExpireAt(key, when) -} - -func (db *DB) TTL(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return -1, err - } - - return db.ttl(KVType, key) -} - -func (db *DB) Persist(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - t := db.kvBatch - t.Lock() - defer t.Unlock() - n, err := db.rmExpire(t, KVType, key) - if err != nil { - return 0, err - } - - err = t.Commit() - return n, err -} - -func (db *DB) Lock() { - t := db.kvBatch - t.Lock() -} - -func (db *DB) Remove(key []byte) bool { - if len(key) == 0 { - return false - } - t := db.kvBatch - t.Delete(db.encodeKVKey(key)) - _, err := db.rmExpire(t, KVType, key) - if err != nil { - return false - } - return true -} - -func (db *DB) Commit() error { - t := db.kvBatch - return t.Commit() -} - -func (db *DB) Unlock() { - t := db.kvBatch - t.Unlock() -} diff --git a/vendor/gitea.com/lunny/nodb/t_list.go b/vendor/gitea.com/lunny/nodb/t_list.go deleted file mode 100644 index 6e66604d6d52e..0000000000000 --- a/vendor/gitea.com/lunny/nodb/t_list.go +++ /dev/null @@ -1,492 +0,0 @@ -package nodb - -import ( - "encoding/binary" - "errors" - "time" - - "gitea.com/lunny/nodb/store" -) - -const ( - listHeadSeq int32 = 1 - listTailSeq int32 = 2 - - listMinSeq int32 = 1000 - listMaxSeq int32 = 1<<31 - 1000 - listInitialSeq int32 = listMinSeq + (listMaxSeq-listMinSeq)/2 -) - -var errLMetaKey = errors.New("invalid lmeta key") -var errListKey = errors.New("invalid list key") -var errListSeq = errors.New("invalid list sequence, overflow") - -func (db *DB) lEncodeMetaKey(key []byte) []byte { - buf := make([]byte, len(key)+2) - buf[0] = db.index - buf[1] = LMetaType - - copy(buf[2:], key) - return buf -} - -func (db *DB) lDecodeMetaKey(ek []byte) ([]byte, error) { - if len(ek) < 2 || ek[0] != db.index || ek[1] != LMetaType { - return nil, errLMetaKey - } - - return ek[2:], nil -} - -func (db *DB) lEncodeListKey(key []byte, seq int32) []byte { - buf := make([]byte, len(key)+8) - - pos := 0 - buf[pos] = db.index - pos++ - buf[pos] = ListType - pos++ - - binary.BigEndian.PutUint16(buf[pos:], uint16(len(key))) - pos += 2 - - copy(buf[pos:], key) - pos += len(key) - - binary.BigEndian.PutUint32(buf[pos:], uint32(seq)) - - return buf -} - -func (db *DB) lDecodeListKey(ek []byte) (key []byte, seq int32, err error) { - if len(ek) < 8 || ek[0] != db.index || ek[1] != ListType { - err = errListKey - return - } - - keyLen := int(binary.BigEndian.Uint16(ek[2:])) - if keyLen+8 != len(ek) { - err = errListKey - return - } - - key = ek[4 : 4+keyLen] - seq = int32(binary.BigEndian.Uint32(ek[4+keyLen:])) - return -} - -func (db *DB) lpush(key []byte, whereSeq int32, args ...[]byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - var headSeq int32 - var tailSeq int32 - var size int32 - var err error - - t := db.listBatch - t.Lock() - defer t.Unlock() - - metaKey := db.lEncodeMetaKey(key) - headSeq, tailSeq, size, err = db.lGetMeta(nil, metaKey) - if err != nil { - return 0, err - } - - var pushCnt int = len(args) - if pushCnt == 0 { - return int64(size), nil - } - - var seq int32 = headSeq - var delta int32 = -1 - if whereSeq == listTailSeq { - seq = tailSeq - delta = 1 - } - - // append elements - if size > 0 { - seq += delta - } - - for i := 0; i < pushCnt; i++ { - ek := db.lEncodeListKey(key, seq+int32(i)*delta) - t.Put(ek, args[i]) - } - - seq += int32(pushCnt-1) * delta - if seq <= listMinSeq || seq >= listMaxSeq { - return 0, errListSeq - } - - // set meta info - if whereSeq == listHeadSeq { - headSeq = seq - } else { - tailSeq = seq - } - - db.lSetMeta(metaKey, headSeq, tailSeq) - - err = t.Commit() - return int64(size) + int64(pushCnt), err -} - -func (db *DB) lpop(key []byte, whereSeq int32) ([]byte, error) { - if err := checkKeySize(key); err != nil { - return nil, err - } - - t := db.listBatch - t.Lock() - defer t.Unlock() - - var headSeq int32 - var tailSeq int32 - var err error - - metaKey := db.lEncodeMetaKey(key) - headSeq, tailSeq, _, err = db.lGetMeta(nil, metaKey) - if err != nil { - return nil, err - } - - var value []byte - - var seq int32 = headSeq - if whereSeq == listTailSeq { - seq = tailSeq - } - - itemKey := db.lEncodeListKey(key, seq) - value, err = db.bucket.Get(itemKey) - if err != nil { - return nil, err - } - - if whereSeq == listHeadSeq { - headSeq += 1 - } else { - tailSeq -= 1 - } - - t.Delete(itemKey) - size := db.lSetMeta(metaKey, headSeq, tailSeq) - if size == 0 { - db.rmExpire(t, HashType, key) - } - - err = t.Commit() - return value, err -} - -// ps : here just focus on deleting the list data, -// any other likes expire is ignore. -func (db *DB) lDelete(t *batch, key []byte) int64 { - mk := db.lEncodeMetaKey(key) - - var headSeq int32 - var tailSeq int32 - var err error - - it := db.bucket.NewIterator() - defer it.Close() - - headSeq, tailSeq, _, err = db.lGetMeta(it, mk) - if err != nil { - return 0 - } - - var num int64 = 0 - startKey := db.lEncodeListKey(key, headSeq) - stopKey := db.lEncodeListKey(key, tailSeq) - - rit := store.NewRangeIterator(it, &store.Range{startKey, stopKey, store.RangeClose}) - for ; rit.Valid(); rit.Next() { - t.Delete(rit.RawKey()) - num++ - } - - t.Delete(mk) - - return num -} - -func (db *DB) lGetMeta(it *store.Iterator, ek []byte) (headSeq int32, tailSeq int32, size int32, err error) { - var v []byte - if it != nil { - v = it.Find(ek) - } else { - v, err = db.bucket.Get(ek) - } - if err != nil { - return - } else if v == nil { - headSeq = listInitialSeq - tailSeq = listInitialSeq - size = 0 - return - } else { - headSeq = int32(binary.LittleEndian.Uint32(v[0:4])) - tailSeq = int32(binary.LittleEndian.Uint32(v[4:8])) - size = tailSeq - headSeq + 1 - } - return -} - -func (db *DB) lSetMeta(ek []byte, headSeq int32, tailSeq int32) int32 { - t := db.listBatch - - var size int32 = tailSeq - headSeq + 1 - if size < 0 { - // todo : log error + panic - } else if size == 0 { - t.Delete(ek) - } else { - buf := make([]byte, 8) - - binary.LittleEndian.PutUint32(buf[0:4], uint32(headSeq)) - binary.LittleEndian.PutUint32(buf[4:8], uint32(tailSeq)) - - t.Put(ek, buf) - } - - return size -} - -func (db *DB) lExpireAt(key []byte, when int64) (int64, error) { - t := db.listBatch - t.Lock() - defer t.Unlock() - - if llen, err := db.LLen(key); err != nil || llen == 0 { - return 0, err - } else { - db.expireAt(t, ListType, key, when) - if err := t.Commit(); err != nil { - return 0, err - } - } - return 1, nil -} - -func (db *DB) LIndex(key []byte, index int32) ([]byte, error) { - if err := checkKeySize(key); err != nil { - return nil, err - } - - var seq int32 - var headSeq int32 - var tailSeq int32 - var err error - - metaKey := db.lEncodeMetaKey(key) - - it := db.bucket.NewIterator() - defer it.Close() - - headSeq, tailSeq, _, err = db.lGetMeta(it, metaKey) - if err != nil { - return nil, err - } - - if index >= 0 { - seq = headSeq + index - } else { - seq = tailSeq + index + 1 - } - - sk := db.lEncodeListKey(key, seq) - v := it.Find(sk) - - return v, nil -} - -func (db *DB) LLen(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - ek := db.lEncodeMetaKey(key) - _, _, size, err := db.lGetMeta(nil, ek) - return int64(size), err -} - -func (db *DB) LPop(key []byte) ([]byte, error) { - return db.lpop(key, listHeadSeq) -} - -func (db *DB) LPush(key []byte, arg1 []byte, args ...[]byte) (int64, error) { - var argss = [][]byte{arg1} - argss = append(argss, args...) - return db.lpush(key, listHeadSeq, argss...) -} - -func (db *DB) LRange(key []byte, start int32, stop int32) ([][]byte, error) { - if err := checkKeySize(key); err != nil { - return nil, err - } - - var headSeq int32 - var llen int32 - var err error - - metaKey := db.lEncodeMetaKey(key) - - it := db.bucket.NewIterator() - defer it.Close() - - if headSeq, _, llen, err = db.lGetMeta(it, metaKey); err != nil { - return nil, err - } - - if start < 0 { - start = llen + start - } - if stop < 0 { - stop = llen + stop - } - if start < 0 { - start = 0 - } - - if start > stop || start >= llen { - return [][]byte{}, nil - } - - if stop >= llen { - stop = llen - 1 - } - - limit := (stop - start) + 1 - headSeq += start - - v := make([][]byte, 0, limit) - - startKey := db.lEncodeListKey(key, headSeq) - rit := store.NewRangeLimitIterator(it, - &store.Range{ - Min: startKey, - Max: nil, - Type: store.RangeClose}, - &store.Limit{ - Offset: 0, - Count: int(limit)}) - - for ; rit.Valid(); rit.Next() { - v = append(v, rit.Value()) - } - - return v, nil -} - -func (db *DB) RPop(key []byte) ([]byte, error) { - return db.lpop(key, listTailSeq) -} - -func (db *DB) RPush(key []byte, arg1 []byte, args ...[]byte) (int64, error) { - var argss = [][]byte{arg1} - argss = append(argss, args...) - return db.lpush(key, listTailSeq, argss...) -} - -func (db *DB) LClear(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - t := db.listBatch - t.Lock() - defer t.Unlock() - - num := db.lDelete(t, key) - db.rmExpire(t, ListType, key) - - err := t.Commit() - return num, err -} - -func (db *DB) LMclear(keys ...[]byte) (int64, error) { - t := db.listBatch - t.Lock() - defer t.Unlock() - - for _, key := range keys { - if err := checkKeySize(key); err != nil { - return 0, err - } - - db.lDelete(t, key) - db.rmExpire(t, ListType, key) - - } - - err := t.Commit() - return int64(len(keys)), err -} - -func (db *DB) lFlush() (drop int64, err error) { - t := db.listBatch - t.Lock() - defer t.Unlock() - return db.flushType(t, ListType) -} - -func (db *DB) LExpire(key []byte, duration int64) (int64, error) { - if duration <= 0 { - return 0, errExpireValue - } - - return db.lExpireAt(key, time.Now().Unix()+duration) -} - -func (db *DB) LExpireAt(key []byte, when int64) (int64, error) { - if when <= time.Now().Unix() { - return 0, errExpireValue - } - - return db.lExpireAt(key, when) -} - -func (db *DB) LTTL(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return -1, err - } - - return db.ttl(ListType, key) -} - -func (db *DB) LPersist(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - t := db.listBatch - t.Lock() - defer t.Unlock() - - n, err := db.rmExpire(t, ListType, key) - if err != nil { - return 0, err - } - - err = t.Commit() - return n, err -} - -func (db *DB) LScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) { - return db.scan(LMetaType, key, count, inclusive, match) -} - -func (db *DB) lEncodeMinKey() []byte { - return db.lEncodeMetaKey(nil) -} - -func (db *DB) lEncodeMaxKey() []byte { - ek := db.lEncodeMetaKey(nil) - ek[len(ek)-1] = LMetaType + 1 - return ek -} diff --git a/vendor/gitea.com/lunny/nodb/t_set.go b/vendor/gitea.com/lunny/nodb/t_set.go deleted file mode 100644 index 0ff33e991ac27..0000000000000 --- a/vendor/gitea.com/lunny/nodb/t_set.go +++ /dev/null @@ -1,601 +0,0 @@ -package nodb - -import ( - "encoding/binary" - "errors" - "time" - - "gitea.com/lunny/nodb/store" -) - -var errSetKey = errors.New("invalid set key") -var errSSizeKey = errors.New("invalid ssize key") - -const ( - setStartSep byte = ':' - setStopSep byte = setStartSep + 1 - UnionType byte = 51 - DiffType byte = 52 - InterType byte = 53 -) - -func checkSetKMSize(key []byte, member []byte) error { - if len(key) > MaxKeySize || len(key) == 0 { - return errKeySize - } else if len(member) > MaxSetMemberSize || len(member) == 0 { - return errSetMemberSize - } - return nil -} - -func (db *DB) sEncodeSizeKey(key []byte) []byte { - buf := make([]byte, len(key)+2) - - buf[0] = db.index - buf[1] = SSizeType - - copy(buf[2:], key) - return buf -} - -func (db *DB) sDecodeSizeKey(ek []byte) ([]byte, error) { - if len(ek) < 2 || ek[0] != db.index || ek[1] != SSizeType { - return nil, errSSizeKey - } - - return ek[2:], nil -} - -func (db *DB) sEncodeSetKey(key []byte, member []byte) []byte { - buf := make([]byte, len(key)+len(member)+1+1+2+1) - - pos := 0 - buf[pos] = db.index - pos++ - buf[pos] = SetType - pos++ - - binary.BigEndian.PutUint16(buf[pos:], uint16(len(key))) - pos += 2 - - copy(buf[pos:], key) - pos += len(key) - - buf[pos] = setStartSep - pos++ - copy(buf[pos:], member) - - return buf -} - -func (db *DB) sDecodeSetKey(ek []byte) ([]byte, []byte, error) { - if len(ek) < 5 || ek[0] != db.index || ek[1] != SetType { - return nil, nil, errSetKey - } - - pos := 2 - keyLen := int(binary.BigEndian.Uint16(ek[pos:])) - pos += 2 - - if keyLen+5 > len(ek) { - return nil, nil, errSetKey - } - - key := ek[pos : pos+keyLen] - pos += keyLen - - if ek[pos] != hashStartSep { - return nil, nil, errSetKey - } - - pos++ - member := ek[pos:] - return key, member, nil -} - -func (db *DB) sEncodeStartKey(key []byte) []byte { - return db.sEncodeSetKey(key, nil) -} - -func (db *DB) sEncodeStopKey(key []byte) []byte { - k := db.sEncodeSetKey(key, nil) - - k[len(k)-1] = setStopSep - - return k -} - -func (db *DB) sFlush() (drop int64, err error) { - - t := db.setBatch - t.Lock() - defer t.Unlock() - - return db.flushType(t, SetType) -} - -func (db *DB) sDelete(t *batch, key []byte) int64 { - sk := db.sEncodeSizeKey(key) - start := db.sEncodeStartKey(key) - stop := db.sEncodeStopKey(key) - - var num int64 = 0 - it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1) - for ; it.Valid(); it.Next() { - t.Delete(it.RawKey()) - num++ - } - - it.Close() - - t.Delete(sk) - return num -} - -func (db *DB) sIncrSize(key []byte, delta int64) (int64, error) { - t := db.setBatch - sk := db.sEncodeSizeKey(key) - - var err error - var size int64 = 0 - if size, err = Int64(db.bucket.Get(sk)); err != nil { - return 0, err - } else { - size += delta - if size <= 0 { - size = 0 - t.Delete(sk) - db.rmExpire(t, SetType, key) - } else { - t.Put(sk, PutInt64(size)) - } - } - - return size, nil -} - -func (db *DB) sExpireAt(key []byte, when int64) (int64, error) { - t := db.setBatch - t.Lock() - defer t.Unlock() - - if scnt, err := db.SCard(key); err != nil || scnt == 0 { - return 0, err - } else { - db.expireAt(t, SetType, key, when) - if err := t.Commit(); err != nil { - return 0, err - } - - } - - return 1, nil -} - -func (db *DB) sSetItem(key []byte, member []byte) (int64, error) { - t := db.setBatch - ek := db.sEncodeSetKey(key, member) - - var n int64 = 1 - if v, _ := db.bucket.Get(ek); v != nil { - n = 0 - } else { - if _, err := db.sIncrSize(key, 1); err != nil { - return 0, err - } - } - - t.Put(ek, nil) - return n, nil -} - -func (db *DB) SAdd(key []byte, args ...[]byte) (int64, error) { - t := db.setBatch - t.Lock() - defer t.Unlock() - - var err error - var ek []byte - var num int64 = 0 - for i := 0; i < len(args); i++ { - if err := checkSetKMSize(key, args[i]); err != nil { - return 0, err - } - - ek = db.sEncodeSetKey(key, args[i]) - - if v, err := db.bucket.Get(ek); err != nil { - return 0, err - } else if v == nil { - num++ - } - - t.Put(ek, nil) - } - - if _, err = db.sIncrSize(key, num); err != nil { - return 0, err - } - - err = t.Commit() - return num, err - -} - -func (db *DB) SCard(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - sk := db.sEncodeSizeKey(key) - - return Int64(db.bucket.Get(sk)) -} - -func (db *DB) sDiffGeneric(keys ...[]byte) ([][]byte, error) { - destMap := make(map[string]bool) - - members, err := db.SMembers(keys[0]) - if err != nil { - return nil, err - } - - for _, m := range members { - destMap[String(m)] = true - } - - for _, k := range keys[1:] { - members, err := db.SMembers(k) - if err != nil { - return nil, err - } - - for _, m := range members { - if _, ok := destMap[String(m)]; !ok { - continue - } else if ok { - delete(destMap, String(m)) - } - } - // O - A = O, O is zero set. - if len(destMap) == 0 { - return nil, nil - } - } - - slice := make([][]byte, len(destMap)) - idx := 0 - for k, v := range destMap { - if !v { - continue - } - slice[idx] = []byte(k) - idx++ - } - - return slice, nil -} - -func (db *DB) SDiff(keys ...[]byte) ([][]byte, error) { - v, err := db.sDiffGeneric(keys...) - return v, err -} - -func (db *DB) SDiffStore(dstKey []byte, keys ...[]byte) (int64, error) { - n, err := db.sStoreGeneric(dstKey, DiffType, keys...) - return n, err -} - -func (db *DB) sInterGeneric(keys ...[]byte) ([][]byte, error) { - destMap := make(map[string]bool) - - members, err := db.SMembers(keys[0]) - if err != nil { - return nil, err - } - - for _, m := range members { - destMap[String(m)] = true - } - - for _, key := range keys[1:] { - if err := checkKeySize(key); err != nil { - return nil, err - } - - members, err := db.SMembers(key) - if err != nil { - return nil, err - } else if len(members) == 0 { - return nil, err - } - - tempMap := make(map[string]bool) - for _, member := range members { - if err := checkKeySize(member); err != nil { - return nil, err - } - if _, ok := destMap[String(member)]; ok { - tempMap[String(member)] = true //mark this item as selected - } - } - destMap = tempMap //reduce the size of the result set - if len(destMap) == 0 { - return nil, nil - } - } - - slice := make([][]byte, len(destMap)) - idx := 0 - for k, v := range destMap { - if !v { - continue - } - - slice[idx] = []byte(k) - idx++ - } - - return slice, nil - -} - -func (db *DB) SInter(keys ...[]byte) ([][]byte, error) { - v, err := db.sInterGeneric(keys...) - return v, err - -} - -func (db *DB) SInterStore(dstKey []byte, keys ...[]byte) (int64, error) { - n, err := db.sStoreGeneric(dstKey, InterType, keys...) - return n, err -} - -func (db *DB) SIsMember(key []byte, member []byte) (int64, error) { - ek := db.sEncodeSetKey(key, member) - - var n int64 = 1 - if v, err := db.bucket.Get(ek); err != nil { - return 0, err - } else if v == nil { - n = 0 - } - return n, nil -} - -func (db *DB) SMembers(key []byte) ([][]byte, error) { - if err := checkKeySize(key); err != nil { - return nil, err - } - - start := db.sEncodeStartKey(key) - stop := db.sEncodeStopKey(key) - - v := make([][]byte, 0, 16) - - it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1) - for ; it.Valid(); it.Next() { - _, m, err := db.sDecodeSetKey(it.Key()) - if err != nil { - return nil, err - } - - v = append(v, m) - } - - it.Close() - - return v, nil -} - -func (db *DB) SRem(key []byte, args ...[]byte) (int64, error) { - t := db.setBatch - t.Lock() - defer t.Unlock() - - var ek []byte - var v []byte - var err error - - it := db.bucket.NewIterator() - defer it.Close() - - var num int64 = 0 - for i := 0; i < len(args); i++ { - if err := checkSetKMSize(key, args[i]); err != nil { - return 0, err - } - - ek = db.sEncodeSetKey(key, args[i]) - - v = it.RawFind(ek) - if v == nil { - continue - } else { - num++ - t.Delete(ek) - } - } - - if _, err = db.sIncrSize(key, -num); err != nil { - return 0, err - } - - err = t.Commit() - return num, err - -} - -func (db *DB) sUnionGeneric(keys ...[]byte) ([][]byte, error) { - dstMap := make(map[string]bool) - - for _, key := range keys { - if err := checkKeySize(key); err != nil { - return nil, err - } - - members, err := db.SMembers(key) - if err != nil { - return nil, err - } - - for _, member := range members { - dstMap[String(member)] = true - } - } - - slice := make([][]byte, len(dstMap)) - idx := 0 - for k, v := range dstMap { - if !v { - continue - } - slice[idx] = []byte(k) - idx++ - } - - return slice, nil -} - -func (db *DB) SUnion(keys ...[]byte) ([][]byte, error) { - v, err := db.sUnionGeneric(keys...) - return v, err -} - -func (db *DB) SUnionStore(dstKey []byte, keys ...[]byte) (int64, error) { - n, err := db.sStoreGeneric(dstKey, UnionType, keys...) - return n, err -} - -func (db *DB) sStoreGeneric(dstKey []byte, optType byte, keys ...[]byte) (int64, error) { - if err := checkKeySize(dstKey); err != nil { - return 0, err - } - - t := db.setBatch - t.Lock() - defer t.Unlock() - - db.sDelete(t, dstKey) - - var err error - var ek []byte - var v [][]byte - - switch optType { - case UnionType: - v, err = db.sUnionGeneric(keys...) - case DiffType: - v, err = db.sDiffGeneric(keys...) - case InterType: - v, err = db.sInterGeneric(keys...) - } - - if err != nil { - return 0, err - } - - for _, m := range v { - if err := checkSetKMSize(dstKey, m); err != nil { - return 0, err - } - - ek = db.sEncodeSetKey(dstKey, m) - - if _, err := db.bucket.Get(ek); err != nil { - return 0, err - } - - t.Put(ek, nil) - } - - var num = int64(len(v)) - sk := db.sEncodeSizeKey(dstKey) - t.Put(sk, PutInt64(num)) - - if err = t.Commit(); err != nil { - return 0, err - } - return num, nil -} - -func (db *DB) SClear(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - t := db.setBatch - t.Lock() - defer t.Unlock() - - num := db.sDelete(t, key) - db.rmExpire(t, SetType, key) - - err := t.Commit() - return num, err -} - -func (db *DB) SMclear(keys ...[]byte) (int64, error) { - t := db.setBatch - t.Lock() - defer t.Unlock() - - for _, key := range keys { - if err := checkKeySize(key); err != nil { - return 0, err - } - - db.sDelete(t, key) - db.rmExpire(t, SetType, key) - } - - err := t.Commit() - return int64(len(keys)), err -} - -func (db *DB) SExpire(key []byte, duration int64) (int64, error) { - if duration <= 0 { - return 0, errExpireValue - } - - return db.sExpireAt(key, time.Now().Unix()+duration) - -} - -func (db *DB) SExpireAt(key []byte, when int64) (int64, error) { - if when <= time.Now().Unix() { - return 0, errExpireValue - } - - return db.sExpireAt(key, when) - -} - -func (db *DB) STTL(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return -1, err - } - - return db.ttl(SetType, key) -} - -func (db *DB) SPersist(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - t := db.setBatch - t.Lock() - defer t.Unlock() - - n, err := db.rmExpire(t, SetType, key) - if err != nil { - return 0, err - } - err = t.Commit() - return n, err -} - -func (db *DB) SScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) { - return db.scan(SSizeType, key, count, inclusive, match) -} diff --git a/vendor/gitea.com/lunny/nodb/t_ttl.go b/vendor/gitea.com/lunny/nodb/t_ttl.go deleted file mode 100644 index f0007dc809709..0000000000000 --- a/vendor/gitea.com/lunny/nodb/t_ttl.go +++ /dev/null @@ -1,195 +0,0 @@ -package nodb - -import ( - "encoding/binary" - "errors" - "time" - - "gitea.com/lunny/nodb/store" -) - -var ( - errExpMetaKey = errors.New("invalid expire meta key") - errExpTimeKey = errors.New("invalid expire time key") -) - -type retireCallback func(*batch, []byte) int64 - -type elimination struct { - db *DB - exp2Tx []*batch - exp2Retire []retireCallback -} - -var errExpType = errors.New("invalid expire type") - -func (db *DB) expEncodeTimeKey(dataType byte, key []byte, when int64) []byte { - buf := make([]byte, len(key)+11) - - buf[0] = db.index - buf[1] = ExpTimeType - buf[2] = dataType - pos := 3 - - binary.BigEndian.PutUint64(buf[pos:], uint64(when)) - pos += 8 - - copy(buf[pos:], key) - - return buf -} - -func (db *DB) expEncodeMetaKey(dataType byte, key []byte) []byte { - buf := make([]byte, len(key)+3) - - buf[0] = db.index - buf[1] = ExpMetaType - buf[2] = dataType - pos := 3 - - copy(buf[pos:], key) - - return buf -} - -func (db *DB) expDecodeMetaKey(mk []byte) (byte, []byte, error) { - if len(mk) <= 3 || mk[0] != db.index || mk[1] != ExpMetaType { - return 0, nil, errExpMetaKey - } - - return mk[2], mk[3:], nil -} - -func (db *DB) expDecodeTimeKey(tk []byte) (byte, []byte, int64, error) { - if len(tk) < 11 || tk[0] != db.index || tk[1] != ExpTimeType { - return 0, nil, 0, errExpTimeKey - } - - return tk[2], tk[11:], int64(binary.BigEndian.Uint64(tk[3:])), nil -} - -func (db *DB) expire(t *batch, dataType byte, key []byte, duration int64) { - db.expireAt(t, dataType, key, time.Now().Unix()+duration) -} - -func (db *DB) expireAt(t *batch, dataType byte, key []byte, when int64) { - mk := db.expEncodeMetaKey(dataType, key) - tk := db.expEncodeTimeKey(dataType, key, when) - - t.Put(tk, mk) - t.Put(mk, PutInt64(when)) -} - -func (db *DB) ttl(dataType byte, key []byte) (t int64, err error) { - mk := db.expEncodeMetaKey(dataType, key) - - if t, err = Int64(db.bucket.Get(mk)); err != nil || t == 0 { - t = -1 - } else { - t -= time.Now().Unix() - if t <= 0 { - t = -1 - } - // if t == -1 : to remove ???? - } - - return t, err -} - -func (db *DB) rmExpire(t *batch, dataType byte, key []byte) (int64, error) { - mk := db.expEncodeMetaKey(dataType, key) - if v, err := db.bucket.Get(mk); err != nil { - return 0, err - } else if v == nil { - return 0, nil - } else if when, err2 := Int64(v, nil); err2 != nil { - return 0, err2 - } else { - tk := db.expEncodeTimeKey(dataType, key, when) - t.Delete(mk) - t.Delete(tk) - return 1, nil - } -} - -func (db *DB) expFlush(t *batch, dataType byte) (err error) { - minKey := make([]byte, 3) - minKey[0] = db.index - minKey[1] = ExpTimeType - minKey[2] = dataType - - maxKey := make([]byte, 3) - maxKey[0] = db.index - maxKey[1] = ExpMetaType - maxKey[2] = dataType + 1 - - _, err = db.flushRegion(t, minKey, maxKey) - err = t.Commit() - return -} - -////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////// - -func newEliminator(db *DB) *elimination { - eli := new(elimination) - eli.db = db - eli.exp2Tx = make([]*batch, maxDataType) - eli.exp2Retire = make([]retireCallback, maxDataType) - return eli -} - -func (eli *elimination) regRetireContext(dataType byte, t *batch, onRetire retireCallback) { - - // todo .. need to ensure exist - mapExpMetaType[expType] - - eli.exp2Tx[dataType] = t - eli.exp2Retire[dataType] = onRetire -} - -// call by outside ... (from *db to another *db) -func (eli *elimination) active() { - now := time.Now().Unix() - db := eli.db - dbGet := db.bucket.Get - - minKey := db.expEncodeTimeKey(NoneType, nil, 0) - maxKey := db.expEncodeTimeKey(maxDataType, nil, now) - - it := db.bucket.RangeLimitIterator(minKey, maxKey, store.RangeROpen, 0, -1) - for ; it.Valid(); it.Next() { - tk := it.RawKey() - mk := it.RawValue() - - dt, k, _, err := db.expDecodeTimeKey(tk) - if err != nil { - continue - } - - t := eli.exp2Tx[dt] - onRetire := eli.exp2Retire[dt] - if tk == nil || onRetire == nil { - continue - } - - t.Lock() - - if exp, err := Int64(dbGet(mk)); err == nil { - // check expire again - if exp <= now { - onRetire(t, k) - t.Delete(tk) - t.Delete(mk) - - t.Commit() - } - - } - - t.Unlock() - } - it.Close() - - return -} diff --git a/vendor/gitea.com/lunny/nodb/t_zset.go b/vendor/gitea.com/lunny/nodb/t_zset.go deleted file mode 100644 index 91e30049e0e85..0000000000000 --- a/vendor/gitea.com/lunny/nodb/t_zset.go +++ /dev/null @@ -1,943 +0,0 @@ -package nodb - -import ( - "bytes" - "encoding/binary" - "errors" - "time" - - "gitea.com/lunny/nodb/store" -) - -const ( - MinScore int64 = -1<<63 + 1 - MaxScore int64 = 1<<63 - 1 - InvalidScore int64 = -1 << 63 - - AggregateSum byte = 0 - AggregateMin byte = 1 - AggregateMax byte = 2 -) - -type ScorePair struct { - Score int64 - Member []byte -} - -var errZSizeKey = errors.New("invalid zsize key") -var errZSetKey = errors.New("invalid zset key") -var errZScoreKey = errors.New("invalid zscore key") -var errScoreOverflow = errors.New("zset score overflow") -var errInvalidAggregate = errors.New("invalid aggregate") -var errInvalidWeightNum = errors.New("invalid weight number") -var errInvalidSrcKeyNum = errors.New("invalid src key number") - -const ( - zsetNScoreSep byte = '<' - zsetPScoreSep byte = zsetNScoreSep + 1 - zsetStopScoreSep byte = zsetPScoreSep + 1 - - zsetStartMemSep byte = ':' - zsetStopMemSep byte = zsetStartMemSep + 1 -) - -func checkZSetKMSize(key []byte, member []byte) error { - if len(key) > MaxKeySize || len(key) == 0 { - return errKeySize - } else if len(member) > MaxZSetMemberSize || len(member) == 0 { - return errZSetMemberSize - } - return nil -} - -func (db *DB) zEncodeSizeKey(key []byte) []byte { - buf := make([]byte, len(key)+2) - buf[0] = db.index - buf[1] = ZSizeType - - copy(buf[2:], key) - return buf -} - -func (db *DB) zDecodeSizeKey(ek []byte) ([]byte, error) { - if len(ek) < 2 || ek[0] != db.index || ek[1] != ZSizeType { - return nil, errZSizeKey - } - - return ek[2:], nil -} - -func (db *DB) zEncodeSetKey(key []byte, member []byte) []byte { - buf := make([]byte, len(key)+len(member)+5) - - pos := 0 - buf[pos] = db.index - pos++ - - buf[pos] = ZSetType - pos++ - - binary.BigEndian.PutUint16(buf[pos:], uint16(len(key))) - pos += 2 - - copy(buf[pos:], key) - pos += len(key) - - buf[pos] = zsetStartMemSep - pos++ - - copy(buf[pos:], member) - - return buf -} - -func (db *DB) zDecodeSetKey(ek []byte) ([]byte, []byte, error) { - if len(ek) < 5 || ek[0] != db.index || ek[1] != ZSetType { - return nil, nil, errZSetKey - } - - keyLen := int(binary.BigEndian.Uint16(ek[2:])) - if keyLen+5 > len(ek) { - return nil, nil, errZSetKey - } - - key := ek[4 : 4+keyLen] - - if ek[4+keyLen] != zsetStartMemSep { - return nil, nil, errZSetKey - } - - member := ek[5+keyLen:] - return key, member, nil -} - -func (db *DB) zEncodeStartSetKey(key []byte) []byte { - k := db.zEncodeSetKey(key, nil) - return k -} - -func (db *DB) zEncodeStopSetKey(key []byte) []byte { - k := db.zEncodeSetKey(key, nil) - k[len(k)-1] = zsetStartMemSep + 1 - return k -} - -func (db *DB) zEncodeScoreKey(key []byte, member []byte, score int64) []byte { - buf := make([]byte, len(key)+len(member)+14) - - pos := 0 - buf[pos] = db.index - pos++ - - buf[pos] = ZScoreType - pos++ - - binary.BigEndian.PutUint16(buf[pos:], uint16(len(key))) - pos += 2 - - copy(buf[pos:], key) - pos += len(key) - - if score < 0 { - buf[pos] = zsetNScoreSep - } else { - buf[pos] = zsetPScoreSep - } - - pos++ - binary.BigEndian.PutUint64(buf[pos:], uint64(score)) - pos += 8 - - buf[pos] = zsetStartMemSep - pos++ - - copy(buf[pos:], member) - return buf -} - -func (db *DB) zEncodeStartScoreKey(key []byte, score int64) []byte { - return db.zEncodeScoreKey(key, nil, score) -} - -func (db *DB) zEncodeStopScoreKey(key []byte, score int64) []byte { - k := db.zEncodeScoreKey(key, nil, score) - k[len(k)-1] = zsetStopMemSep - return k -} - -func (db *DB) zDecodeScoreKey(ek []byte) (key []byte, member []byte, score int64, err error) { - if len(ek) < 14 || ek[0] != db.index || ek[1] != ZScoreType { - err = errZScoreKey - return - } - - keyLen := int(binary.BigEndian.Uint16(ek[2:])) - if keyLen+14 > len(ek) { - err = errZScoreKey - return - } - - key = ek[4 : 4+keyLen] - pos := 4 + keyLen - - if (ek[pos] != zsetNScoreSep) && (ek[pos] != zsetPScoreSep) { - err = errZScoreKey - return - } - pos++ - - score = int64(binary.BigEndian.Uint64(ek[pos:])) - pos += 8 - - if ek[pos] != zsetStartMemSep { - err = errZScoreKey - return - } - - pos++ - - member = ek[pos:] - return -} - -func (db *DB) zSetItem(t *batch, key []byte, score int64, member []byte) (int64, error) { - if score <= MinScore || score >= MaxScore { - return 0, errScoreOverflow - } - - var exists int64 = 0 - ek := db.zEncodeSetKey(key, member) - - if v, err := db.bucket.Get(ek); err != nil { - return 0, err - } else if v != nil { - exists = 1 - - if s, err := Int64(v, err); err != nil { - return 0, err - } else { - sk := db.zEncodeScoreKey(key, member, s) - t.Delete(sk) - } - } - - t.Put(ek, PutInt64(score)) - - sk := db.zEncodeScoreKey(key, member, score) - t.Put(sk, []byte{}) - - return exists, nil -} - -func (db *DB) zDelItem(t *batch, key []byte, member []byte, skipDelScore bool) (int64, error) { - ek := db.zEncodeSetKey(key, member) - if v, err := db.bucket.Get(ek); err != nil { - return 0, err - } else if v == nil { - //not exists - return 0, nil - } else { - //exists - if !skipDelScore { - //we must del score - if s, err := Int64(v, err); err != nil { - return 0, err - } else { - sk := db.zEncodeScoreKey(key, member, s) - t.Delete(sk) - } - } - } - - t.Delete(ek) - - return 1, nil -} - -func (db *DB) zDelete(t *batch, key []byte) int64 { - delMembCnt, _ := db.zRemRange(t, key, MinScore, MaxScore, 0, -1) - // todo : log err - return delMembCnt -} - -func (db *DB) zExpireAt(key []byte, when int64) (int64, error) { - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - if zcnt, err := db.ZCard(key); err != nil || zcnt == 0 { - return 0, err - } else { - db.expireAt(t, ZSetType, key, when) - if err := t.Commit(); err != nil { - return 0, err - } - } - return 1, nil -} - -func (db *DB) ZAdd(key []byte, args ...ScorePair) (int64, error) { - if len(args) == 0 { - return 0, nil - } - - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - var num int64 = 0 - for i := 0; i < len(args); i++ { - score := args[i].Score - member := args[i].Member - - if err := checkZSetKMSize(key, member); err != nil { - return 0, err - } - - if n, err := db.zSetItem(t, key, score, member); err != nil { - return 0, err - } else if n == 0 { - //add new - num++ - } - } - - if _, err := db.zIncrSize(t, key, num); err != nil { - return 0, err - } - - //todo add binlog - err := t.Commit() - return num, err -} - -func (db *DB) zIncrSize(t *batch, key []byte, delta int64) (int64, error) { - sk := db.zEncodeSizeKey(key) - - size, err := Int64(db.bucket.Get(sk)) - if err != nil { - return 0, err - } else { - size += delta - if size <= 0 { - size = 0 - t.Delete(sk) - db.rmExpire(t, ZSetType, key) - } else { - t.Put(sk, PutInt64(size)) - } - } - - return size, nil -} - -func (db *DB) ZCard(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - sk := db.zEncodeSizeKey(key) - return Int64(db.bucket.Get(sk)) -} - -func (db *DB) ZScore(key []byte, member []byte) (int64, error) { - if err := checkZSetKMSize(key, member); err != nil { - return InvalidScore, err - } - - var score int64 = InvalidScore - - k := db.zEncodeSetKey(key, member) - if v, err := db.bucket.Get(k); err != nil { - return InvalidScore, err - } else if v == nil { - return InvalidScore, ErrScoreMiss - } else { - if score, err = Int64(v, nil); err != nil { - return InvalidScore, err - } - } - - return score, nil -} - -func (db *DB) ZRem(key []byte, members ...[]byte) (int64, error) { - if len(members) == 0 { - return 0, nil - } - - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - var num int64 = 0 - for i := 0; i < len(members); i++ { - if err := checkZSetKMSize(key, members[i]); err != nil { - return 0, err - } - - if n, err := db.zDelItem(t, key, members[i], false); err != nil { - return 0, err - } else if n == 1 { - num++ - } - } - - if _, err := db.zIncrSize(t, key, -num); err != nil { - return 0, err - } - - err := t.Commit() - return num, err -} - -func (db *DB) ZIncrBy(key []byte, delta int64, member []byte) (int64, error) { - if err := checkZSetKMSize(key, member); err != nil { - return InvalidScore, err - } - - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - ek := db.zEncodeSetKey(key, member) - - var oldScore int64 = 0 - v, err := db.bucket.Get(ek) - if err != nil { - return InvalidScore, err - } else if v == nil { - db.zIncrSize(t, key, 1) - } else { - if oldScore, err = Int64(v, err); err != nil { - return InvalidScore, err - } - } - - newScore := oldScore + delta - if newScore >= MaxScore || newScore <= MinScore { - return InvalidScore, errScoreOverflow - } - - sk := db.zEncodeScoreKey(key, member, newScore) - t.Put(sk, []byte{}) - t.Put(ek, PutInt64(newScore)) - - if v != nil { - // so as to update score, we must delete the old one - oldSk := db.zEncodeScoreKey(key, member, oldScore) - t.Delete(oldSk) - } - - err = t.Commit() - return newScore, err -} - -func (db *DB) ZCount(key []byte, min int64, max int64) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - minKey := db.zEncodeStartScoreKey(key, min) - maxKey := db.zEncodeStopScoreKey(key, max) - - rangeType := store.RangeROpen - - it := db.bucket.RangeLimitIterator(minKey, maxKey, rangeType, 0, -1) - var n int64 = 0 - for ; it.Valid(); it.Next() { - n++ - } - it.Close() - - return n, nil -} - -func (db *DB) zrank(key []byte, member []byte, reverse bool) (int64, error) { - if err := checkZSetKMSize(key, member); err != nil { - return 0, err - } - - k := db.zEncodeSetKey(key, member) - - it := db.bucket.NewIterator() - defer it.Close() - - if v := it.Find(k); v == nil { - return -1, nil - } else { - if s, err := Int64(v, nil); err != nil { - return 0, err - } else { - var rit *store.RangeLimitIterator - - sk := db.zEncodeScoreKey(key, member, s) - - if !reverse { - minKey := db.zEncodeStartScoreKey(key, MinScore) - - rit = store.NewRangeIterator(it, &store.Range{minKey, sk, store.RangeClose}) - } else { - maxKey := db.zEncodeStopScoreKey(key, MaxScore) - rit = store.NewRevRangeIterator(it, &store.Range{sk, maxKey, store.RangeClose}) - } - - var lastKey []byte = nil - var n int64 = 0 - - for ; rit.Valid(); rit.Next() { - n++ - - lastKey = rit.BufKey(lastKey) - } - - if _, m, _, err := db.zDecodeScoreKey(lastKey); err == nil && bytes.Equal(m, member) { - n-- - return n, nil - } - } - } - - return -1, nil -} - -func (db *DB) zIterator(key []byte, min int64, max int64, offset int, count int, reverse bool) *store.RangeLimitIterator { - minKey := db.zEncodeStartScoreKey(key, min) - maxKey := db.zEncodeStopScoreKey(key, max) - - if !reverse { - return db.bucket.RangeLimitIterator(minKey, maxKey, store.RangeClose, offset, count) - } else { - return db.bucket.RevRangeLimitIterator(minKey, maxKey, store.RangeClose, offset, count) - } -} - -func (db *DB) zRemRange(t *batch, key []byte, min int64, max int64, offset int, count int) (int64, error) { - if len(key) > MaxKeySize { - return 0, errKeySize - } - - it := db.zIterator(key, min, max, offset, count, false) - var num int64 = 0 - for ; it.Valid(); it.Next() { - sk := it.RawKey() - _, m, _, err := db.zDecodeScoreKey(sk) - if err != nil { - continue - } - - if n, err := db.zDelItem(t, key, m, true); err != nil { - return 0, err - } else if n == 1 { - num++ - } - - t.Delete(sk) - } - it.Close() - - if _, err := db.zIncrSize(t, key, -num); err != nil { - return 0, err - } - - return num, nil -} - -func (db *DB) zRange(key []byte, min int64, max int64, offset int, count int, reverse bool) ([]ScorePair, error) { - if len(key) > MaxKeySize { - return nil, errKeySize - } - - if offset < 0 { - return []ScorePair{}, nil - } - - nv := 64 - if count > 0 { - nv = count - } - - v := make([]ScorePair, 0, nv) - - var it *store.RangeLimitIterator - - //if reverse and offset is 0, count < 0, we may use forward iterator then reverse - //because store iterator prev is slower than next - if !reverse || (offset == 0 && count < 0) { - it = db.zIterator(key, min, max, offset, count, false) - } else { - it = db.zIterator(key, min, max, offset, count, true) - } - - for ; it.Valid(); it.Next() { - _, m, s, err := db.zDecodeScoreKey(it.Key()) - //may be we will check key equal? - if err != nil { - continue - } - - v = append(v, ScorePair{Member: m, Score: s}) - } - it.Close() - - if reverse && (offset == 0 && count < 0) { - for i, j := 0, len(v)-1; i < j; i, j = i+1, j-1 { - v[i], v[j] = v[j], v[i] - } - } - - return v, nil -} - -func (db *DB) zParseLimit(key []byte, start int, stop int) (offset int, count int, err error) { - if start < 0 || stop < 0 { - //refer redis implementation - var size int64 - size, err = db.ZCard(key) - if err != nil { - return - } - - llen := int(size) - - if start < 0 { - start = llen + start - } - if stop < 0 { - stop = llen + stop - } - - if start < 0 { - start = 0 - } - - if start >= llen { - offset = -1 - return - } - } - - if start > stop { - offset = -1 - return - } - - offset = start - count = (stop - start) + 1 - return -} - -func (db *DB) ZClear(key []byte) (int64, error) { - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - rmCnt, err := db.zRemRange(t, key, MinScore, MaxScore, 0, -1) - if err == nil { - err = t.Commit() - } - - return rmCnt, err -} - -func (db *DB) ZMclear(keys ...[]byte) (int64, error) { - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - for _, key := range keys { - if _, err := db.zRemRange(t, key, MinScore, MaxScore, 0, -1); err != nil { - return 0, err - } - } - - err := t.Commit() - - return int64(len(keys)), err -} - -func (db *DB) ZRange(key []byte, start int, stop int) ([]ScorePair, error) { - return db.ZRangeGeneric(key, start, stop, false) -} - -//min and max must be inclusive -//if no limit, set offset = 0 and count = -1 -func (db *DB) ZRangeByScore(key []byte, min int64, max int64, - offset int, count int) ([]ScorePair, error) { - return db.ZRangeByScoreGeneric(key, min, max, offset, count, false) -} - -func (db *DB) ZRank(key []byte, member []byte) (int64, error) { - return db.zrank(key, member, false) -} - -func (db *DB) ZRemRangeByRank(key []byte, start int, stop int) (int64, error) { - offset, count, err := db.zParseLimit(key, start, stop) - if err != nil { - return 0, err - } - - var rmCnt int64 - - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - rmCnt, err = db.zRemRange(t, key, MinScore, MaxScore, offset, count) - if err == nil { - err = t.Commit() - } - - return rmCnt, err -} - -//min and max must be inclusive -func (db *DB) ZRemRangeByScore(key []byte, min int64, max int64) (int64, error) { - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - rmCnt, err := db.zRemRange(t, key, min, max, 0, -1) - if err == nil { - err = t.Commit() - } - - return rmCnt, err -} - -func (db *DB) ZRevRange(key []byte, start int, stop int) ([]ScorePair, error) { - return db.ZRangeGeneric(key, start, stop, true) -} - -func (db *DB) ZRevRank(key []byte, member []byte) (int64, error) { - return db.zrank(key, member, true) -} - -//min and max must be inclusive -//if no limit, set offset = 0 and count = -1 -func (db *DB) ZRevRangeByScore(key []byte, min int64, max int64, offset int, count int) ([]ScorePair, error) { - return db.ZRangeByScoreGeneric(key, min, max, offset, count, true) -} - -func (db *DB) ZRangeGeneric(key []byte, start int, stop int, reverse bool) ([]ScorePair, error) { - offset, count, err := db.zParseLimit(key, start, stop) - if err != nil { - return nil, err - } - - return db.zRange(key, MinScore, MaxScore, offset, count, reverse) -} - -//min and max must be inclusive -//if no limit, set offset = 0 and count = -1 -func (db *DB) ZRangeByScoreGeneric(key []byte, min int64, max int64, - offset int, count int, reverse bool) ([]ScorePair, error) { - - return db.zRange(key, min, max, offset, count, reverse) -} - -func (db *DB) zFlush() (drop int64, err error) { - t := db.zsetBatch - t.Lock() - defer t.Unlock() - return db.flushType(t, ZSetType) -} - -func (db *DB) ZExpire(key []byte, duration int64) (int64, error) { - if duration <= 0 { - return 0, errExpireValue - } - - return db.zExpireAt(key, time.Now().Unix()+duration) -} - -func (db *DB) ZExpireAt(key []byte, when int64) (int64, error) { - if when <= time.Now().Unix() { - return 0, errExpireValue - } - - return db.zExpireAt(key, when) -} - -func (db *DB) ZTTL(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return -1, err - } - - return db.ttl(ZSetType, key) -} - -func (db *DB) ZPersist(key []byte) (int64, error) { - if err := checkKeySize(key); err != nil { - return 0, err - } - - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - n, err := db.rmExpire(t, ZSetType, key) - if err != nil { - return 0, err - } - - err = t.Commit() - return n, err -} - -func getAggregateFunc(aggregate byte) func(int64, int64) int64 { - switch aggregate { - case AggregateSum: - return func(a int64, b int64) int64 { - return a + b - } - case AggregateMax: - return func(a int64, b int64) int64 { - if a > b { - return a - } - return b - } - case AggregateMin: - return func(a int64, b int64) int64 { - if a > b { - return b - } - return a - } - } - return nil -} - -func (db *DB) ZUnionStore(destKey []byte, srcKeys [][]byte, weights []int64, aggregate byte) (int64, error) { - - var destMap = map[string]int64{} - aggregateFunc := getAggregateFunc(aggregate) - if aggregateFunc == nil { - return 0, errInvalidAggregate - } - if len(srcKeys) < 1 { - return 0, errInvalidSrcKeyNum - } - if weights != nil { - if len(srcKeys) != len(weights) { - return 0, errInvalidWeightNum - } - } else { - weights = make([]int64, len(srcKeys)) - for i := 0; i < len(weights); i++ { - weights[i] = 1 - } - } - - for i, key := range srcKeys { - scorePairs, err := db.ZRange(key, 0, -1) - if err != nil { - return 0, err - } - for _, pair := range scorePairs { - if score, ok := destMap[String(pair.Member)]; !ok { - destMap[String(pair.Member)] = pair.Score * weights[i] - } else { - destMap[String(pair.Member)] = aggregateFunc(score, pair.Score*weights[i]) - } - } - } - - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - db.zDelete(t, destKey) - - for member, score := range destMap { - if err := checkZSetKMSize(destKey, []byte(member)); err != nil { - return 0, err - } - - if _, err := db.zSetItem(t, destKey, score, []byte(member)); err != nil { - return 0, err - } - } - - var num = int64(len(destMap)) - sk := db.zEncodeSizeKey(destKey) - t.Put(sk, PutInt64(num)) - - //todo add binlog - if err := t.Commit(); err != nil { - return 0, err - } - return num, nil -} - -func (db *DB) ZInterStore(destKey []byte, srcKeys [][]byte, weights []int64, aggregate byte) (int64, error) { - - aggregateFunc := getAggregateFunc(aggregate) - if aggregateFunc == nil { - return 0, errInvalidAggregate - } - if len(srcKeys) < 1 { - return 0, errInvalidSrcKeyNum - } - if weights != nil { - if len(srcKeys) != len(weights) { - return 0, errInvalidWeightNum - } - } else { - weights = make([]int64, len(srcKeys)) - for i := 0; i < len(weights); i++ { - weights[i] = 1 - } - } - - var destMap = map[string]int64{} - scorePairs, err := db.ZRange(srcKeys[0], 0, -1) - if err != nil { - return 0, err - } - for _, pair := range scorePairs { - destMap[String(pair.Member)] = pair.Score * weights[0] - } - - for i, key := range srcKeys[1:] { - scorePairs, err := db.ZRange(key, 0, -1) - if err != nil { - return 0, err - } - tmpMap := map[string]int64{} - for _, pair := range scorePairs { - if score, ok := destMap[String(pair.Member)]; ok { - tmpMap[String(pair.Member)] = aggregateFunc(score, pair.Score*weights[i+1]) - } - } - destMap = tmpMap - } - - t := db.zsetBatch - t.Lock() - defer t.Unlock() - - db.zDelete(t, destKey) - - for member, score := range destMap { - if err := checkZSetKMSize(destKey, []byte(member)); err != nil { - return 0, err - } - if _, err := db.zSetItem(t, destKey, score, []byte(member)); err != nil { - return 0, err - } - } - - var num int64 = int64(len(destMap)) - sk := db.zEncodeSizeKey(destKey) - t.Put(sk, PutInt64(num)) - //todo add binlog - if err := t.Commit(); err != nil { - return 0, err - } - return num, nil -} - -func (db *DB) ZScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) { - return db.scan(ZSizeType, key, count, inclusive, match) -} diff --git a/vendor/gitea.com/lunny/nodb/tx.go b/vendor/gitea.com/lunny/nodb/tx.go deleted file mode 100644 index e56b4c0d391dd..0000000000000 --- a/vendor/gitea.com/lunny/nodb/tx.go +++ /dev/null @@ -1,113 +0,0 @@ -package nodb - -import ( - "errors" - "fmt" - - "gitea.com/lunny/nodb/store" -) - -var ( - ErrNestTx = errors.New("nest transaction not supported") - ErrTxDone = errors.New("Transaction has already been committed or rolled back") -) - -type Tx struct { - *DB - - tx *store.Tx - - logs [][]byte -} - -func (db *DB) IsTransaction() bool { - return db.status == DBInTransaction -} - -// Begin a transaction, it will block all other write operations before calling Commit or Rollback. -// You must be very careful to prevent long-time transaction. -func (db *DB) Begin() (*Tx, error) { - if db.IsTransaction() { - return nil, ErrNestTx - } - - tx := new(Tx) - - tx.DB = new(DB) - tx.DB.l = db.l - - tx.l.wLock.Lock() - - tx.DB.sdb = db.sdb - - var err error - tx.tx, err = db.sdb.Begin() - if err != nil { - tx.l.wLock.Unlock() - return nil, err - } - - tx.DB.bucket = tx.tx - - tx.DB.status = DBInTransaction - - tx.DB.index = db.index - - tx.DB.kvBatch = tx.newBatch() - tx.DB.listBatch = tx.newBatch() - tx.DB.hashBatch = tx.newBatch() - tx.DB.zsetBatch = tx.newBatch() - tx.DB.binBatch = tx.newBatch() - tx.DB.setBatch = tx.newBatch() - - return tx, nil -} - -func (tx *Tx) Commit() error { - if tx.tx == nil { - return ErrTxDone - } - - tx.l.commitLock.Lock() - err := tx.tx.Commit() - tx.tx = nil - - if len(tx.logs) > 0 { - tx.l.binlog.Log(tx.logs...) - } - - tx.l.commitLock.Unlock() - - tx.l.wLock.Unlock() - - tx.DB.bucket = nil - - return err -} - -func (tx *Tx) Rollback() error { - if tx.tx == nil { - return ErrTxDone - } - - err := tx.tx.Rollback() - tx.tx = nil - - tx.l.wLock.Unlock() - tx.DB.bucket = nil - - return err -} - -func (tx *Tx) newBatch() *batch { - return tx.l.newBatch(tx.tx.NewWriteBatch(), &txBatchLocker{}, tx) -} - -func (tx *Tx) Select(index int) error { - if index < 0 || index >= int(MaxDBNumber) { - return fmt.Errorf("invalid db index %d", index) - } - - tx.DB.index = uint8(index) - return nil -} diff --git a/vendor/gitea.com/lunny/nodb/util.go b/vendor/gitea.com/lunny/nodb/util.go deleted file mode 100644 index d5949a96e6dd6..0000000000000 --- a/vendor/gitea.com/lunny/nodb/util.go +++ /dev/null @@ -1,113 +0,0 @@ -package nodb - -import ( - "encoding/binary" - "errors" - "reflect" - "strconv" - "unsafe" -) - -var errIntNumber = errors.New("invalid integer") - -// no copy to change slice to string -// use your own risk -func String(b []byte) (s string) { - pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) - pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) - pstring.Data = pbytes.Data - pstring.Len = pbytes.Len - return -} - -// no copy to change string to slice -// use your own risk -func Slice(s string) (b []byte) { - pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) - pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) - pbytes.Data = pstring.Data - pbytes.Len = pstring.Len - pbytes.Cap = pstring.Len - return -} - -func Int64(v []byte, err error) (int64, error) { - if err != nil { - return 0, err - } else if v == nil || len(v) == 0 { - return 0, nil - } else if len(v) != 8 { - return 0, errIntNumber - } - - return int64(binary.LittleEndian.Uint64(v)), nil -} - -func PutInt64(v int64) []byte { - var b []byte - pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) - pbytes.Data = uintptr(unsafe.Pointer(&v)) - pbytes.Len = 8 - pbytes.Cap = 8 - return b -} - -func StrInt64(v []byte, err error) (int64, error) { - if err != nil { - return 0, err - } else if v == nil { - return 0, nil - } else { - return strconv.ParseInt(String(v), 10, 64) - } -} - -func StrInt32(v []byte, err error) (int32, error) { - if err != nil { - return 0, err - } else if v == nil { - return 0, nil - } else { - res, err := strconv.ParseInt(String(v), 10, 32) - return int32(res), err - } -} - -func StrInt8(v []byte, err error) (int8, error) { - if err != nil { - return 0, err - } else if v == nil { - return 0, nil - } else { - res, err := strconv.ParseInt(String(v), 10, 8) - return int8(res), err - } -} - -func StrPutInt64(v int64) []byte { - return strconv.AppendInt(nil, v, 10) -} - -func MinUInt32(a uint32, b uint32) uint32 { - if a > b { - return b - } else { - return a - } -} - -func MaxUInt32(a uint32, b uint32) uint32 { - if a > b { - return a - } else { - return b - } -} - -func MaxInt32(a int32, b int32) int32 { - if a > b { - return a - } else { - return b - } -} diff --git a/vendor/gitea.com/macaron/binding/README.md b/vendor/gitea.com/macaron/binding/README.md deleted file mode 100644 index aeaa57193999b..0000000000000 --- a/vendor/gitea.com/macaron/binding/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# binding [![Build Status](https://travis-ci.org/go-macaron/binding.svg?branch=master)](https://travis-ci.org/go-macaron/binding) [![Sourcegraph](https://sourcegraph.com/github.com/go-macaron/binding/-/badge.svg)](https://sourcegraph.com/github.com/go-macaron/binding?badge) - -Middleware binding provides request data binding and validation for [Macaron](https://github.com/go-macaron/macaron). - -### Installation - - go get github.com/go-macaron/binding - -## Getting Help - -- [API Reference](https://gowalker.org/github.com/go-macaron/binding) -- [Documentation](http://go-macaron.com/docs/middlewares/binding) - -## Credits - -This package is a modified version of [martini-contrib/binding](https://github.com/martini-contrib/binding). - -## License - -This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/binding/go.sum b/vendor/gitea.com/macaron/binding/go.sum deleted file mode 100644 index 56302b6a5f723..0000000000000 --- a/vendor/gitea.com/macaron/binding/go.sum +++ /dev/null @@ -1,30 +0,0 @@ -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ= -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM= -github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/vendor/gitea.com/macaron/captcha/go.mod b/vendor/gitea.com/macaron/captcha/go.mod deleted file mode 100644 index 6980787b99f7a..0000000000000 --- a/vendor/gitea.com/macaron/captcha/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module gitea.com/macaron/captcha - -go 1.11 - -require ( - gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76 - gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb - github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 - github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e -) diff --git a/vendor/gitea.com/macaron/cors/.drone.yml b/vendor/gitea.com/macaron/cors/.drone.yml deleted file mode 100644 index 39499f444a57d..0000000000000 --- a/vendor/gitea.com/macaron/cors/.drone.yml +++ /dev/null @@ -1,9 +0,0 @@ -kind: pipeline -name: default - -steps: -- name: test - image: golang:1.11 - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic diff --git a/vendor/gitea.com/macaron/cors/.gitignore b/vendor/gitea.com/macaron/cors/.gitignore deleted file mode 100644 index f1c181ec9c5c9..0000000000000 --- a/vendor/gitea.com/macaron/cors/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out diff --git a/vendor/gitea.com/macaron/cors/README.md b/vendor/gitea.com/macaron/cors/README.md deleted file mode 100644 index 5ef70e3579f69..0000000000000 --- a/vendor/gitea.com/macaron/cors/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# cors - -[![Build Status](https://drone.gitea.com/api/badges/macaron/cors/status.svg)](https://drone.gitea.com/macaron/cors) - -Package cors is a middleware that handles CORS requests & headers for Macaron. diff --git a/vendor/gitea.com/macaron/cors/cors.go b/vendor/gitea.com/macaron/cors/cors.go deleted file mode 100644 index 2d0613f2bc283..0000000000000 --- a/vendor/gitea.com/macaron/cors/cors.go +++ /dev/null @@ -1,169 +0,0 @@ -package cors - -import ( - "fmt" - "log" - "net/http" - "net/url" - "strconv" - "strings" - - macaron "gitea.com/macaron/macaron" -) - -const version = "0.1.1" - -const anyDomain = "!*" - -// Version returns the version of this module -func Version() string { - return version -} - -/* -Options to configure the CORS middleware read from the [cors] section of the ini configuration file. - -SCHEME may be http or https as accepted schemes or the '*' wildcard to accept any scheme. - -ALLOW_DOMAIN may be a comma separated list of domains that are allowed to run CORS requests -Special values are the a single '*' wildcard that will allow any domain to send requests without -credentials and the special '!*' wildcard which will reply with requesting domain in the 'access-control-allow-origin' -header and hence allow requess from any domain *with* credentials. - -ALLOW_SUBDOMAIN set to true accepts requests from any subdomain of ALLOW_DOMAIN. - -METHODS may be a comma separated list of HTTP-methods to be accepted. - -MAX_AGE_SECONDS may be the duration in secs for which the response is cached (default 600). -ref: https://stackoverflow.com/questions/54300997/is-it-possible-to-cache-http-options-response?noredirect=1#comment95790277_54300997 -ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age - -ALLOW_CREDENTIALS set to false rejects any request with credentials. -*/ -type Options struct { - Section string - Scheme string - AllowDomain []string - AllowSubdomain bool - Methods []string - MaxAgeSeconds int - AllowCredentials bool -} - -func prepareOptions(options []Options) Options { - var opt Options - if len(options) > 0 { - opt = options[0] - } - - if len(opt.Section) == 0 { - opt.Section = "cors" - } - sec := macaron.Config().Section(opt.Section) - - if len(opt.Scheme) == 0 { - opt.Scheme = sec.Key("SCHEME").MustString("http") - } - if len(opt.AllowDomain) == 0 { - opt.AllowDomain = sec.Key("ALLOW_DOMAIN").Strings(",") - if len(opt.AllowDomain) == 0 { - opt.AllowDomain = []string{"*"} - } - } - if !opt.AllowSubdomain { - opt.AllowSubdomain = sec.Key("ALLOW_SUBDOMAIN").MustBool(false) - } - if len(opt.Methods) == 0 { - opt.Methods = sec.Key("METHODS").Strings(",") - if len(opt.Methods) == 0 { - opt.Methods = []string{ - http.MethodGet, - http.MethodHead, - http.MethodPost, - http.MethodPut, - http.MethodPatch, - http.MethodDelete, - http.MethodOptions, - } - } - } - if opt.MaxAgeSeconds <= 0 { - opt.MaxAgeSeconds = sec.Key("MAX_AGE_SECONDS").MustInt(600) - } - if !opt.AllowCredentials { - opt.AllowCredentials = sec.Key("ALLOW_CREDENTIALS").MustBool(true) - } - - return opt -} - -// CORS responds to preflight requests with adequat access-control-* respond headers -// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin -// https://fetch.spec.whatwg.org/#cors-protocol-and-credentials -func CORS(options ...Options) macaron.Handler { - opt := prepareOptions(options) - return func(ctx *macaron.Context, log *log.Logger) { - reqOptions := ctx.Req.Method == http.MethodOptions - - headers := map[string]string{ - "access-control-allow-methods": strings.Join(opt.Methods, ","), - "access-control-allow-headers": ctx.Req.Header.Get("access-control-request-headers"), - "access-control-max-age": strconv.Itoa(opt.MaxAgeSeconds), - } - if opt.AllowDomain[0] == "*" { - headers["access-control-allow-origin"] = "*" - } else { - origin := ctx.Req.Header.Get("Origin") - if reqOptions && origin == "" { - respErrorf(ctx, log, http.StatusBadRequest, "missing origin header in CORS request") - return - } - - u, err := url.Parse(origin) - if err != nil { - respErrorf(ctx, log, http.StatusBadRequest, "Failed to parse CORS origin header. Reason: %v", err) - return - } - - ok := false - for _, d := range opt.AllowDomain { - if u.Hostname() == d || (opt.AllowSubdomain && strings.HasSuffix(u.Hostname(), "."+d)) || d == anyDomain { - ok = true - break - } - } - if ok { - if opt.Scheme != "*" { - u.Scheme = opt.Scheme - } - headers["access-control-allow-origin"] = u.String() - headers["access-control-allow-credentials"] = strconv.FormatBool(opt.AllowCredentials) - headers["vary"] = "Origin" - } - if reqOptions && !ok { - respErrorf(ctx, log, http.StatusBadRequest, "CORS request from prohibited domain %v", origin) - return - } - } - ctx.Resp.Before(func(w macaron.ResponseWriter) { - for k, v := range headers { - w.Header().Set(k, v) - } - }) - if reqOptions { - ctx.Resp.WriteHeader(200) // return response - return - } - } -} - -func respErrorf(ctx *macaron.Context, log *log.Logger, statusCode int, format string, a ...interface{}) { - msg := fmt.Sprintf(format, a...) - log.Println(msg) - ctx.WriteHeader(statusCode) - _, err := ctx.Write([]byte(msg)) - if err != nil { - panic(err) - } - return -} diff --git a/vendor/gitea.com/macaron/cors/go.mod b/vendor/gitea.com/macaron/cors/go.mod deleted file mode 100644 index 418aab88de2aa..0000000000000 --- a/vendor/gitea.com/macaron/cors/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module gitea.com/macaron/cors - -go 1.11 - -require gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827 diff --git a/vendor/gitea.com/macaron/cors/go.sum b/vendor/gitea.com/macaron/cors/go.sum deleted file mode 100644 index e3bcd933dc96f..0000000000000 --- a/vendor/gitea.com/macaron/cors/go.sum +++ /dev/null @@ -1,31 +0,0 @@ -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ= -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827 h1:/rT4MEFjhdViy2BFWKUwbC0JSNSziEbBCM7q4/B9qgo= -gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827/go.mod h1:/rvxMjIkOq4BM8uPUb+VHuU02ZfAO6R4+wD//tiCiRw= -github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 h1:1B7wb36fHLSwZfHg6ngZhhtIEHQjiC5H4p7qQGBEffg= -github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/vendor/gitea.com/macaron/csrf/.drone.yml b/vendor/gitea.com/macaron/csrf/.drone.yml deleted file mode 100644 index 1db7ea30e3abf..0000000000000 --- a/vendor/gitea.com/macaron/csrf/.drone.yml +++ /dev/null @@ -1,24 +0,0 @@ -kind: pipeline -name: go1-1-1 - -steps: -- name: test - image: golang:1.11 - environment: - GOPROXY: https://goproxy.cn - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic - ---- -kind: pipeline -name: go1-1-2 - -steps: -- name: test - image: golang:1.12 - environment: - GOPROXY: https://goproxy.cn - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic \ No newline at end of file diff --git a/vendor/gitea.com/macaron/csrf/LICENSE b/vendor/gitea.com/macaron/csrf/LICENSE deleted file mode 100644 index 8405e89a0b120..0000000000000 --- a/vendor/gitea.com/macaron/csrf/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/csrf/README.md b/vendor/gitea.com/macaron/csrf/README.md deleted file mode 100644 index 3295bd5f9ad3c..0000000000000 --- a/vendor/gitea.com/macaron/csrf/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# csrf [![Build Status](https://drone.gitea.com/api/badges/macaron/csrf/status.svg)](https://drone.gitea.com/macaron/csrf) - -Middleware csrf generates and validates CSRF tokens for [Macaron](https://gitea.com/macaron/macaron). - -[API Reference](https://gowalker.org/gitea.com/macaron/csrf) - -### Installation - - go get gitea.com/macaron/csrf - -## Getting Help - -- [API Reference](https://gowalker.org/gitea.com/macaron/csrf) -- [Documentation](http://go-macaron.com/docs/middlewares/csrf) - -## License - -This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/csrf/go.mod b/vendor/gitea.com/macaron/csrf/go.mod deleted file mode 100644 index 946cb6afff24d..0000000000000 --- a/vendor/gitea.com/macaron/csrf/go.mod +++ /dev/null @@ -1,12 +0,0 @@ -module gitea.com/macaron/csrf - -go 1.11 - -require ( - gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb - gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705 - github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c // indirect - github.com/smartystreets/assertions v1.0.1 // indirect - github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 - github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e -) diff --git a/vendor/gitea.com/macaron/csrf/go.sum b/vendor/gitea.com/macaron/csrf/go.sum deleted file mode 100644 index 7919c9f8c3167..0000000000000 --- a/vendor/gitea.com/macaron/csrf/go.sum +++ /dev/null @@ -1,83 +0,0 @@ -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ= -gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA= -gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs= -gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705 h1:mvkQGAlON1Z6Y8pqa/+FpYIskk54mazuECUfZK5oTg0= -gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705/go.mod h1:1ujH0jD6Ca4iK9NL0Q2a7fG2chvXx5hVa7hBfABwpkA= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= -github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= -github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc= -github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ= -github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= -github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY= -github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= -github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM= -github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/gitea.com/macaron/gzip/.drone.yml b/vendor/gitea.com/macaron/gzip/.drone.yml deleted file mode 100644 index 087a19664cf56..0000000000000 --- a/vendor/gitea.com/macaron/gzip/.drone.yml +++ /dev/null @@ -1,24 +0,0 @@ -kind: pipeline -name: go1-14 - -steps: -- name: test - image: golang:1.14 - environment: - GOPROXY: https://goproxy.cn - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic - ---- -kind: pipeline -name: go1-15 - -steps: -- name: test - image: golang:1.15 - environment: - GOPROXY: https://goproxy.cn - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic \ No newline at end of file diff --git a/vendor/gitea.com/macaron/gzip/README.md b/vendor/gitea.com/macaron/gzip/README.md deleted file mode 100644 index e09c4a9d8c3a2..0000000000000 --- a/vendor/gitea.com/macaron/gzip/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# gzip - -Middleware gzip provides gzip comparess middleware for [Macaron](https://gitea.com/macaron/macaron). - -### Installation - - go get gitea.com/macaron/gzip - -## Getting Help - -- [API Reference](https://godoc.org/gitea.com/macaron/gzip) - -## Credits - -This package is a modified version of [go-macaron gzip](github.com/go-macaron/gzip). - -## License - -This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/gzip/go.mod b/vendor/gitea.com/macaron/gzip/go.mod deleted file mode 100644 index 877ee7e37a393..0000000000000 --- a/vendor/gitea.com/macaron/gzip/go.mod +++ /dev/null @@ -1,11 +0,0 @@ -module gitea.com/macaron/gzip - -go 1.12 - -require ( - gitea.com/macaron/macaron v1.5.0 - github.com/klauspost/compress v1.9.2 - github.com/stretchr/testify v1.4.0 - golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect - gopkg.in/ini.v1 v1.60.1 // indirect -) diff --git a/vendor/gitea.com/macaron/gzip/go.sum b/vendor/gitea.com/macaron/gzip/go.sum deleted file mode 100644 index b34055da3ec02..0000000000000 --- a/vendor/gitea.com/macaron/gzip/go.sum +++ /dev/null @@ -1,48 +0,0 @@ -gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a h1:aOKEXkDTnh4euoH0so/THLXeHtQuqHmDPb1xEk6Ehok= -gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.5.0 h1:TvWEcHw1/zaHlo0GTuKEukLh3A99+QsU2mjBrXLXjVQ= -gitea.com/macaron/macaron v1.5.0/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY= -github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= -github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.60.1 h1:P5y5shSkb0CFe44qEeMBgn8JLow09MP17jlJHanke5g= -gopkg.in/ini.v1 v1.60.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/gitea.com/macaron/gzip/gzip.go b/vendor/gitea.com/macaron/gzip/gzip.go deleted file mode 100644 index cd93e03f68510..0000000000000 --- a/vendor/gitea.com/macaron/gzip/gzip.go +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright 2019 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package gzip - -import ( - "bufio" - "errors" - "fmt" - "io" - "net" - "net/http" - "regexp" - "strconv" - "strings" - "sync" - - "gitea.com/macaron/macaron" - "github.com/klauspost/compress/gzip" -) - -const ( - acceptEncodingHeader = "Accept-Encoding" - contentEncodingHeader = "Content-Encoding" - contentLengthHeader = "Content-Length" - contentTypeHeader = "Content-Type" - rangeHeader = "Range" - varyHeader = "Vary" -) - -const ( - // MinSize is the minimum size of content we will compress - MinSize = 1400 -) - -// noopClosers are io.Writers with a shim to prevent early closure -type noopCloser struct { - io.Writer -} - -func (noopCloser) Close() error { return nil } - -// WriterPool is a gzip writer pool to reduce workload on creation of -// gzip writers -type WriterPool struct { - pool sync.Pool - compressionLevel int -} - -// NewWriterPool creates a new pool -func NewWriterPool(compressionLevel int) *WriterPool { - return &WriterPool{pool: sync.Pool{ - // New will return nil, we'll manage the creation of new - // writers in the middleware - New: func() interface{} { return nil }, - }, - compressionLevel: compressionLevel} -} - -// Get a writer from the pool - or create one if not available -func (wp *WriterPool) Get(rw macaron.ResponseWriter) *gzip.Writer { - ret := wp.pool.Get() - if ret == nil { - ret, _ = gzip.NewWriterLevel(rw, wp.compressionLevel) - } else { - ret.(*gzip.Writer).Reset(rw) - } - return ret.(*gzip.Writer) -} - -// Put returns a writer to the pool -func (wp *WriterPool) Put(w *gzip.Writer) { - wp.pool.Put(w) -} - -var writerPool WriterPool - -// Options represents the configuration for the gzip middleware -type Options struct { - CompressionLevel int -} - -func validateCompressionLevel(level int) bool { - return level == gzip.DefaultCompression || - level == gzip.ConstantCompression || - (level >= gzip.BestSpeed && level <= gzip.BestCompression) -} - -func validate(options []Options) Options { - // Default to level 4 compression (Best results seem to be between 4 and 6) - opt := Options{CompressionLevel: 4} - if len(options) > 0 { - opt = options[0] - } - if !validateCompressionLevel(opt.CompressionLevel) { - opt.CompressionLevel = 4 - } - return opt -} - -// Middleware creates a macaron.Handler to proxy the response -func Middleware(options ...Options) macaron.Handler { - opt := validate(options) - writerPool = *NewWriterPool(opt.CompressionLevel) - regex := regexp.MustCompile(`bytes=(\d+)\-.*`) - - return func(ctx *macaron.Context) { - // If the client won't accept gzip or x-gzip don't compress - if !strings.Contains(ctx.Req.Header.Get(acceptEncodingHeader), "gzip") && - !strings.Contains(ctx.Req.Header.Get(acceptEncodingHeader), "x-gzip") { - return - } - - // If the client is asking for a specific range of bytes - don't compress - if rangeHdr := ctx.Req.Header.Get(rangeHeader); rangeHdr != "" { - - match := regex.FindStringSubmatch(rangeHdr) - if len(match) > 1 { - return - } - } - - // OK we should proxy the response writer - // We are still not necessarily going to compress... - proxyWriter := &ProxyResponseWriter{ - internal: ctx.Resp, - } - defer proxyWriter.Close() - - ctx.Resp = proxyWriter - ctx.MapTo(proxyWriter, (*http.ResponseWriter)(nil)) - - // Check if render middleware has been registered, - // if yes, we need to modify ResponseWriter for it as well. - if _, ok := ctx.Render.(*macaron.DummyRender); !ok { - ctx.Render.SetResponseWriter(proxyWriter) - } - - ctx.Next() - ctx.Resp = proxyWriter.internal - } -} - -// ProxyResponseWriter is a wrapped macaron ResponseWriter that may compress its contents -type ProxyResponseWriter struct { - writer io.WriteCloser - internal macaron.ResponseWriter - stopped bool - - code int - buf []byte -} - -// Header returns the header map -func (proxy *ProxyResponseWriter) Header() http.Header { - return proxy.internal.Header() -} - -// Status returns the status code of the response or 0 if the response has not been written. -func (proxy *ProxyResponseWriter) Status() int { - if proxy.code != 0 { - return proxy.code - } - return proxy.internal.Status() -} - -// Written returns whether or not the ResponseWriter has been written. -func (proxy *ProxyResponseWriter) Written() bool { - if proxy.code != 0 { - return true - } - return proxy.internal.Written() -} - -// Size returns the size of the response body. -func (proxy *ProxyResponseWriter) Size() int { - return proxy.internal.Size() -} - -// Before allows for a function to be called before the ResponseWriter has been written to. This is -// useful for setting headers or any other operations that must happen before a response has been written. -func (proxy *ProxyResponseWriter) Before(before macaron.BeforeFunc) { - proxy.internal.Before(before) -} - -// Write appends data to the proxied gzip writer. -func (proxy *ProxyResponseWriter) Write(b []byte) (int, error) { - // if writer is initialized, use the writer - if proxy.writer != nil { - return proxy.writer.Write(b) - } - - proxy.buf = append(proxy.buf, b...) - - var ( - contentLength, _ = strconv.Atoi(proxy.Header().Get(contentLengthHeader)) - contentType = proxy.Header().Get(contentTypeHeader) - contentEncoding = proxy.Header().Get(contentEncodingHeader) - ) - - // OK if an encoding hasn't been chosen, and content length > 1400 - // and content type isn't a compressed type - if contentEncoding == "" && - (contentLength == 0 || contentLength >= MinSize) && - (contentType == "" || !compressedContentType(contentType)) { - // If current buffer is less than the min size and a Content-Length isn't set, then wait - if len(proxy.buf) < MinSize && contentLength == 0 { - return len(b), nil - } - - // If the Content-Length is larger than minSize or the current buffer is larger than minSize, then continue. - if contentLength >= MinSize || len(proxy.buf) >= MinSize { - // if we don't know the content type, infer it - if contentType == "" { - contentType = http.DetectContentType(proxy.buf) - proxy.Header().Set(contentTypeHeader, contentType) - } - // If the Content-Type is not compressed - Compress! - if !compressedContentType(contentType) { - if err := proxy.startGzip(); err != nil { - return 0, err - } - return len(b), nil - } - } - } - // If we got here, we should not GZIP this response. - if err := proxy.startPlain(); err != nil { - return 0, err - } - return len(b), nil -} - -func (proxy *ProxyResponseWriter) startGzip() error { - // Set the content-encoding and vary headers. - proxy.Header().Set(contentEncodingHeader, "gzip") - proxy.Header().Set(varyHeader, acceptEncodingHeader) - - // if the Content-Length is already set, then calls to Write on gzip - // will fail to set the Content-Length header since its already set - // See: https://github.com/golang/go/issues/14975. - proxy.Header().Del(contentLengthHeader) - - // Write the header to gzip response. - if proxy.code != 0 { - proxy.internal.WriteHeader(proxy.code) - // Ensure that no other WriteHeader's happen - proxy.code = 0 - } - - // Initialize and flush the buffer into the gzip response if there are any bytes. - // If there aren't any, we shouldn't initialize it yet because on Close it will - // write the gzip header even if nothing was ever written. - if len(proxy.buf) > 0 { - // Initialize the GZIP response. - proxy.writer = writerPool.Get(proxy.internal) - - return proxy.writeBuf() - } - return nil -} - -func (proxy *ProxyResponseWriter) startPlain() error { - if proxy.code != 0 { - proxy.internal.WriteHeader(proxy.code) - proxy.code = 0 - } - proxy.stopped = true - proxy.writer = noopCloser{proxy.internal} - return proxy.writeBuf() -} - -func (proxy *ProxyResponseWriter) writeBuf() error { - if proxy.buf == nil { - return nil - } - - n, err := proxy.writer.Write(proxy.buf) - - // This should never happen (per io.Writer docs), but if the write didn't - // accept the entire buffer but returned no specific error, we have no clue - // what's going on, so abort just to be safe. - if err == nil && n < len(proxy.buf) { - err = io.ErrShortWrite - } - proxy.buf = nil - return err -} - -// WriteHeader will ensure that we have setup the writer before we write the header -func (proxy *ProxyResponseWriter) WriteHeader(code int) { - if proxy.code == 0 { - proxy.code = code - } -} - -// Close the writer -func (proxy *ProxyResponseWriter) Close() error { - if proxy.stopped { - return nil - } - - if proxy.writer == nil { - err := proxy.startPlain() - if err != nil { - return fmt.Errorf("GzipMiddleware: write to regular responseWriter at close gets error: %q", err.Error()) - } - } - - err := proxy.writer.Close() - - if poolWriter, ok := proxy.writer.(*gzip.Writer); ok { - writerPool.Put(poolWriter) - } - - proxy.writer = nil - proxy.stopped = true - return err -} - -// Flush the writer -func (proxy *ProxyResponseWriter) Flush() { - if proxy.writer == nil { - return - } - - if gw, ok := proxy.writer.(*gzip.Writer); ok { - gw.Flush() - } - - proxy.internal.Flush() -} - -// Push implements http.Pusher for HTTP/2 Push purposes -func (proxy *ProxyResponseWriter) Push(target string, opts *http.PushOptions) error { - pusher, ok := proxy.internal.(http.Pusher) - if !ok { - return errors.New("the ResponseWriter doesn't support the Pusher interface") - } - return pusher.Push(target, opts) -} - -// Hijack implements http.Hijacker. If the underlying ResponseWriter is a -// Hijacker, its Hijack method is returned. Otherwise an error is returned. -func (proxy *ProxyResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { - hijacker, ok := proxy.internal.(http.Hijacker) - if !ok { - return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface") - } - return hijacker.Hijack() -} - -// verify Hijacker interface implementation -var _ http.Hijacker = &ProxyResponseWriter{} - -func compressedContentType(contentType string) bool { - switch contentType { - case "application/zip": - return true - case "application/x-gzip": - return true - case "application/gzip": - return true - default: - return false - } -} diff --git a/vendor/gitea.com/macaron/i18n/.drone.yml b/vendor/gitea.com/macaron/i18n/.drone.yml deleted file mode 100644 index 72eebbb496c94..0000000000000 --- a/vendor/gitea.com/macaron/i18n/.drone.yml +++ /dev/null @@ -1,24 +0,0 @@ -kind: pipeline -name: golang-1-14 - -steps: -- name: test - image: golang:1.14 - environment: - GOPROXY: https://goproxy.cn - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic - ---- -kind: pipeline -name: golang-1-15 - -steps: -- name: test - image: golang:1.15 - environment: - GOPROXY: https://goproxy.cn - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic \ No newline at end of file diff --git a/vendor/gitea.com/macaron/i18n/.gitignore b/vendor/gitea.com/macaron/i18n/.gitignore deleted file mode 100644 index a09c56df5c7fd..0000000000000 --- a/vendor/gitea.com/macaron/i18n/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/.idea diff --git a/vendor/gitea.com/macaron/i18n/LICENSE b/vendor/gitea.com/macaron/i18n/LICENSE deleted file mode 100644 index 8405e89a0b120..0000000000000 --- a/vendor/gitea.com/macaron/i18n/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/i18n/README.md b/vendor/gitea.com/macaron/i18n/README.md deleted file mode 100644 index bff89d9b6c8f9..0000000000000 --- a/vendor/gitea.com/macaron/i18n/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# i18n [![Build Status](https://drone.gitea.com/api/badges/macaron/i18n/status.svg)](https://drone.gitea.com/macaron/i18n) [![](http://gocover.io/_badge/github.com/go-macaron/i18n)](http://gocover.io/github.com/go-macaron/i18n) - -Middleware i18n provides app Internationalization and Localization for [Macaron](https://gitea.com/macaron/macaron). - -### Installation - - go get gitea.com/macaron/i18n - -## Getting Help - -- [API Reference](https://gowalker.org/gitea.com/macaron/i18n) -- [Documentation](http://go-macaron.com/docs/middlewares/i18n) - -## License - -This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/i18n/go.mod b/vendor/gitea.com/macaron/i18n/go.mod deleted file mode 100644 index 59336d341435c..0000000000000 --- a/vendor/gitea.com/macaron/i18n/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module gitea.com/macaron/i18n - -go 1.11 - -require ( - gitea.com/macaron/macaron v1.5.0 - github.com/stretchr/testify v1.4.0 - github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6 - golang.org/x/text v0.3.2 -) diff --git a/vendor/gitea.com/macaron/i18n/go.sum b/vendor/gitea.com/macaron/i18n/go.sum deleted file mode 100644 index 73db18b25b298..0000000000000 --- a/vendor/gitea.com/macaron/i18n/go.sum +++ /dev/null @@ -1,52 +0,0 @@ -gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a h1:aOKEXkDTnh4euoH0so/THLXeHtQuqHmDPb1xEk6Ehok= -gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.5.0 h1:TvWEcHw1/zaHlo0GTuKEukLh3A99+QsU2mjBrXLXjVQ= -gitea.com/macaron/macaron v1.5.0/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM= -github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= -github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6 h1:sRrkJEHtNoaSvyXMbRgofEOX4/3gMiraevQKJdIBhYE= -github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6/go.mod h1:+5rDk6sDGpl3azws3O+f+GpFSyN9GVr0K8cvQLQM2ZQ= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag= -gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag= -gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/gitea.com/macaron/i18n/i18n.go b/vendor/gitea.com/macaron/i18n/i18n.go deleted file mode 100644 index 3624aaee53264..0000000000000 --- a/vendor/gitea.com/macaron/i18n/i18n.go +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -// Package i18n provides an Internationalization and Localization middleware for Macaron applications. -package i18n - -import ( - "fmt" - "log" - "os" - "path" - "strings" - - "gitea.com/macaron/macaron" - "github.com/unknwon/i18n" - "golang.org/x/text/language" -) - -const _VERSION = "0.4.0" - -func Version() string { - return _VERSION -} - -// isFile returns true if given path is a file, -// or returns false when it's a directory or does not exist. -func isFile(filePath string) bool { - f, e := os.Stat(filePath) - if e != nil { - return false - } - return !f.IsDir() -} - -// initLocales initializes language type list and Accept-Language header matcher. -func initLocales(opt Options) language.Matcher { - tags := make([]language.Tag, len(opt.Langs)) - for i, lang := range opt.Langs { - tags[i] = language.Raw.Make(lang) - fname := fmt.Sprintf(opt.Format, lang) - // Append custom locale file. - custom := []interface{}{} - customPath := path.Join(opt.CustomDirectory, fname) - if isFile(customPath) { - custom = append(custom, customPath) - } - - var locale interface{} - if data, ok := opt.Files[fname]; ok { - locale = data - } else { - locale = path.Join(opt.Directory, fname) - } - - err := i18n.SetMessageWithDesc(lang, opt.Names[i], locale, custom...) - if err != nil && err != i18n.ErrLangAlreadyExist { - log.Printf("ERROR: failed to set message file(%s) for language %s: %v", lang, opt.Names[i], err) - } - } - return language.NewMatcher(tags) -} - -// A Locale describles the information of localization. -type Locale struct { - i18n.Locale -} - -// Language returns language current locale represents. -func (l Locale) Language() string { - return l.Lang -} - -// Options represents a struct for specifying configuration options for the i18n middleware. -type Options struct { - // Suburl of path. Default is empty. - SubURL string - // Directory to load locale files. Default is "conf/locale" - Directory string - // File stores actual data of locale files. Used for in-memory purpose. - Files map[string][]byte - // Custom directory to overload locale files. Default is "custom/conf/locale" - CustomDirectory string - // Langauges that will be supported, order is meaningful. - Langs []string - // Human friendly names corresponding to Langs list. - Names []string - // Default language locale, leave empty to remain unset. - DefaultLang string - // Locale file naming style. Default is "locale_%s.ini". - Format string - // Name of language parameter name in URL. Default is "lang". - Parameter string - // Redirect when user uses get parameter to specify language. - Redirect bool - // Name that maps into template variable. Default is "i18n". - TmplName string - // Configuration section name. Default is "i18n". - Section string - // Domain used for `lang` cookie. Default is "" - CookieDomain string - // Set the Secure flag on the `lang` cookie. Default is disabled. - Secure bool - // Set the HTTP Only flag on the `lang` cookie. Default is disabled. - CookieHttpOnly bool -} - -func prepareOptions(options []Options) Options { - var opt Options - if len(options) > 0 { - opt = options[0] - } - - if len(opt.Section) == 0 { - opt.Section = "i18n" - } - sec := macaron.Config().Section(opt.Section) - - opt.SubURL = strings.TrimSuffix(opt.SubURL, "/") - - if len(opt.Langs) == 0 { - opt.Langs = sec.Key("LANGS").Strings(",") - } - if len(opt.Names) == 0 { - opt.Names = sec.Key("NAMES").Strings(",") - } - if len(opt.Langs) == 0 { - panic("no language is specified") - } else if len(opt.Langs) != len(opt.Names) { - panic("length of langs is not same as length of names") - } - i18n.SetDefaultLang(opt.DefaultLang) - - if len(opt.Directory) == 0 { - opt.Directory = sec.Key("DIRECTORY").MustString("conf/locale") - } - if len(opt.CustomDirectory) == 0 { - opt.CustomDirectory = sec.Key("CUSTOM_DIRECTORY").MustString("custom/conf/locale") - } - if len(opt.Format) == 0 { - opt.Format = sec.Key("FORMAT").MustString("locale_%s.ini") - } - if len(opt.Parameter) == 0 { - opt.Parameter = sec.Key("PARAMETER").MustString("lang") - } - if !opt.Redirect { - opt.Redirect = sec.Key("REDIRECT").MustBool() - } - if len(opt.TmplName) == 0 { - opt.TmplName = sec.Key("TMPL_NAME").MustString("i18n") - } - - return opt -} - -type LangType struct { - Lang, Name string -} - -// I18n is a middleware provides localization layer for your application. -// Paramenter langs must be in the form of "en-US", "zh-CN", etc. -// Otherwise it may not recognize browser input. -func I18n(options ...Options) macaron.Handler { - opt := prepareOptions(options) - m := initLocales(opt) - return func(ctx *macaron.Context) { - isNeedRedir := false - hasCookie := false - - // 1. Check URL arguments. - lang := ctx.Query(opt.Parameter) - - // 2. Get language information from cookies. - if len(lang) == 0 { - lang = ctx.GetCookie("lang") - hasCookie = true - } else { - isNeedRedir = true - } - - // Check again in case someone modify by purpose. - if !i18n.IsExist(lang) { - lang = "" - isNeedRedir = false - hasCookie = false - } - - // 3. Get language information from 'Accept-Language'. - // The first element in the list is chosen to be the default language automatically. - if len(lang) == 0 { - tags, _, _ := language.ParseAcceptLanguage(ctx.Req.Header.Get("Accept-Language")) - tag, _, _ := m.Match(tags...) - lang = tag.String() - isNeedRedir = false - } - - curLang := LangType{ - Lang: lang, - } - - // Save language information in cookies. - if !hasCookie { - ctx.SetCookie("lang", curLang.Lang, 1<<31-1, "/"+strings.TrimPrefix(opt.SubURL, "/"), opt.CookieDomain, opt.Secure, opt.CookieHttpOnly) - } - - restLangs := make([]LangType, 0, i18n.Count()-1) - langs := i18n.ListLangs() - names := i18n.ListLangDescs() - for i, v := range langs { - if lang != v { - restLangs = append(restLangs, LangType{v, names[i]}) - } else { - curLang.Name = names[i] - } - } - - // Set language properties. - locale := Locale{Locale: i18n.Locale{Lang: lang}} - ctx.Map(locale) - ctx.Locale = locale - ctx.Data[opt.TmplName] = locale - ctx.Data["Tr"] = i18n.Tr - ctx.Data["Lang"] = locale.Lang - ctx.Data["LangName"] = curLang.Name - ctx.Data["AllLangs"] = append([]LangType{curLang}, restLangs...) - ctx.Data["RestLangs"] = restLangs - - if opt.Redirect && isNeedRedir { - ctx.Redirect(opt.SubURL + path.Clean(ctx.Req.RequestURI[:strings.Index(ctx.Req.RequestURI, "?")])) - } - } -} diff --git a/vendor/gitea.com/macaron/inject/.drone.yml b/vendor/gitea.com/macaron/inject/.drone.yml deleted file mode 100644 index 4db3bab5350ca..0000000000000 --- a/vendor/gitea.com/macaron/inject/.drone.yml +++ /dev/null @@ -1,20 +0,0 @@ -kind: pipeline -name: go1-1-1 - -steps: -- name: test - image: golang:1.11 - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic - ---- -kind: pipeline -name: go1-1-2 - -steps: -- name: test - image: golang:1.12 - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic diff --git a/vendor/gitea.com/macaron/inject/LICENSE b/vendor/gitea.com/macaron/inject/LICENSE deleted file mode 100644 index 37ec93a14fdcd..0000000000000 --- a/vendor/gitea.com/macaron/inject/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/gitea.com/macaron/inject/README.md b/vendor/gitea.com/macaron/inject/README.md deleted file mode 100644 index 5ed58bae52cec..0000000000000 --- a/vendor/gitea.com/macaron/inject/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# inject [![Build Status](https://drone.gitea.com/api/badges/macaron/inject/status.svg)](https://drone.gitea.com/macaron/inject) [![](http://gocover.io/_badge/gitea.com/macaron/inject)](http://gocover.io/gitea.com/macaron/inject) - -Package inject provides utilities for mapping and injecting dependencies in various ways. - -**This a modified version of [codegangsta/inject](https://github.com/codegangsta/inject) for special purpose of Macaron** - -**Please use the original version if you need dependency injection feature** - -## License - -This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/inject/go.mod b/vendor/gitea.com/macaron/inject/go.mod deleted file mode 100644 index 7d885b7008830..0000000000000 --- a/vendor/gitea.com/macaron/inject/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module gitea.com/macaron/inject - -go 1.11 - -require github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 diff --git a/vendor/gitea.com/macaron/inject/go.sum b/vendor/gitea.com/macaron/inject/go.sum deleted file mode 100644 index 6a9ccb166c28c..0000000000000 --- a/vendor/gitea.com/macaron/inject/go.sum +++ /dev/null @@ -1,13 +0,0 @@ -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= diff --git a/vendor/gitea.com/macaron/inject/inject.go b/vendor/gitea.com/macaron/inject/inject.go deleted file mode 100644 index 1c1f98eaaa001..0000000000000 --- a/vendor/gitea.com/macaron/inject/inject.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2013 Jeremy Saenz -// Copyright 2015 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -// Package inject provides utilities for mapping and injecting dependencies in various ways. -package inject - -import ( - "fmt" - "reflect" -) - -// Injector represents an interface for mapping and injecting dependencies into structs -// and function arguments. -type Injector interface { - Applicator - Invoker - TypeMapper - // SetParent sets the parent of the injector. If the injector cannot find a - // dependency in its Type map it will check its parent before returning an - // error. - SetParent(Injector) -} - -// Applicator represents an interface for mapping dependencies to a struct. -type Applicator interface { - // Maps dependencies in the Type map to each field in the struct - // that is tagged with 'inject'. Returns an error if the injection - // fails. - Apply(interface{}) error -} - -// Invoker represents an interface for calling functions via reflection. -type Invoker interface { - // Invoke attempts to call the interface{} provided as a function, - // providing dependencies for function arguments based on Type. Returns - // a slice of reflect.Value representing the returned values of the function. - // Returns an error if the injection fails. - Invoke(interface{}) ([]reflect.Value, error) -} - -// FastInvoker represents an interface in order to avoid the calling function via reflection. -// -// example: -// type handlerFuncHandler func(http.ResponseWriter, *http.Request) error -// func (f handlerFuncHandler)Invoke([]interface{}) ([]reflect.Value, error){ -// ret := f(p[0].(http.ResponseWriter), p[1].(*http.Request)) -// return []reflect.Value{reflect.ValueOf(ret)}, nil -// } -// -// type funcHandler func(int, string) -// func (f funcHandler)Invoke([]interface{}) ([]reflect.Value, error){ -// f(p[0].(int), p[1].(string)) -// return nil, nil -// } -type FastInvoker interface { - // Invoke attempts to call the ordinary functions. If f is a function - // with the appropriate signature, f.Invoke([]interface{}) is a Call that calls f. - // Returns a slice of reflect.Value representing the returned values of the function. - // Returns an error if the injection fails. - Invoke([]interface{}) ([]reflect.Value, error) -} - -// IsFastInvoker check interface is FastInvoker -func IsFastInvoker(h interface{}) bool { - _, ok := h.(FastInvoker) - return ok -} - -// TypeMapper represents an interface for mapping interface{} values based on type. -type TypeMapper interface { - // Maps the interface{} value based on its immediate type from reflect.TypeOf. - Map(interface{}) TypeMapper - // Maps the interface{} value based on the pointer of an Interface provided. - // This is really only useful for mapping a value as an interface, as interfaces - // cannot at this time be referenced directly without a pointer. - MapTo(interface{}, interface{}) TypeMapper - // Provides a possibility to directly insert a mapping based on type and value. - // This makes it possible to directly map type arguments not possible to instantiate - // with reflect like unidirectional channels. - Set(reflect.Type, reflect.Value) TypeMapper - // Returns the Value that is mapped to the current type. Returns a zeroed Value if - // the Type has not been mapped. - GetVal(reflect.Type) reflect.Value -} - -type injector struct { - values map[reflect.Type]reflect.Value - parent Injector -} - -// InterfaceOf dereferences a pointer to an Interface type. -// It panics if value is not an pointer to an interface. -func InterfaceOf(value interface{}) reflect.Type { - t := reflect.TypeOf(value) - - for t.Kind() == reflect.Ptr { - t = t.Elem() - } - - if t.Kind() != reflect.Interface { - panic("Called inject.InterfaceOf with a value that is not a pointer to an interface. (*MyInterface)(nil)") - } - - return t -} - -// New returns a new Injector. -func New() Injector { - return &injector{ - values: make(map[reflect.Type]reflect.Value), - } -} - -// Invoke attempts to call the interface{} provided as a function, -// providing dependencies for function arguments based on Type. -// Returns a slice of reflect.Value representing the returned values of the function. -// Returns an error if the injection fails. -// It panics if f is not a function -func (inj *injector) Invoke(f interface{}) ([]reflect.Value, error) { - t := reflect.TypeOf(f) - switch v := f.(type) { - case FastInvoker: - return inj.fastInvoke(v, t, t.NumIn()) - default: - return inj.callInvoke(f, t, t.NumIn()) - } -} - -func (inj *injector) fastInvoke(f FastInvoker, t reflect.Type, numIn int) ([]reflect.Value, error) { - var in []interface{} - if numIn > 0 { - in = make([]interface{}, numIn) // Panic if t is not kind of Func - var argType reflect.Type - var val reflect.Value - for i := 0; i < numIn; i++ { - argType = t.In(i) - val = inj.GetVal(argType) - if !val.IsValid() { - return nil, fmt.Errorf("Value not found for type %v", argType) - } - - in[i] = val.Interface() - } - } - return f.Invoke(in) -} - -// callInvoke reflect.Value.Call -func (inj *injector) callInvoke(f interface{}, t reflect.Type, numIn int) ([]reflect.Value, error) { - var in []reflect.Value - if numIn > 0 { - in = make([]reflect.Value, numIn) - var argType reflect.Type - var val reflect.Value - for i := 0; i < numIn; i++ { - argType = t.In(i) - val = inj.GetVal(argType) - if !val.IsValid() { - return nil, fmt.Errorf("Value not found for type %v", argType) - } - - in[i] = val - } - } - return reflect.ValueOf(f).Call(in), nil -} - -// Maps dependencies in the Type map to each field in the struct -// that is tagged with 'inject'. -// Returns an error if the injection fails. -func (inj *injector) Apply(val interface{}) error { - v := reflect.ValueOf(val) - - for v.Kind() == reflect.Ptr { - v = v.Elem() - } - - if v.Kind() != reflect.Struct { - return nil // Should not panic here ? - } - - t := v.Type() - - for i := 0; i < v.NumField(); i++ { - f := v.Field(i) - structField := t.Field(i) - if f.CanSet() && (structField.Tag == "inject" || structField.Tag.Get("inject") != "") { - ft := f.Type() - v := inj.GetVal(ft) - if !v.IsValid() { - return fmt.Errorf("Value not found for type %v", ft) - } - - f.Set(v) - } - - } - - return nil -} - -// Maps the concrete value of val to its dynamic type using reflect.TypeOf, -// It returns the TypeMapper registered in. -func (i *injector) Map(val interface{}) TypeMapper { - i.values[reflect.TypeOf(val)] = reflect.ValueOf(val) - return i -} - -func (i *injector) MapTo(val interface{}, ifacePtr interface{}) TypeMapper { - i.values[InterfaceOf(ifacePtr)] = reflect.ValueOf(val) - return i -} - -// Maps the given reflect.Type to the given reflect.Value and returns -// the Typemapper the mapping has been registered in. -func (i *injector) Set(typ reflect.Type, val reflect.Value) TypeMapper { - i.values[typ] = val - return i -} - -func (i *injector) GetVal(t reflect.Type) reflect.Value { - val := i.values[t] - - if val.IsValid() { - return val - } - - // no concrete types found, try to find implementors - // if t is an interface - if t.Kind() == reflect.Interface { - for k, v := range i.values { - if k.Implements(t) { - val = v - break - } - } - } - - // Still no type found, try to look it up on the parent - if !val.IsValid() && i.parent != nil { - val = i.parent.GetVal(t) - } - - return val - -} - -func (i *injector) SetParent(parent Injector) { - i.parent = parent -} diff --git a/vendor/gitea.com/macaron/macaron/.drone.yml b/vendor/gitea.com/macaron/macaron/.drone.yml deleted file mode 100644 index 06a3e7d853270..0000000000000 --- a/vendor/gitea.com/macaron/macaron/.drone.yml +++ /dev/null @@ -1,12 +0,0 @@ -kind: pipeline -name: default - -steps: -- name: test - image: golang:1.13 - environment: - GOPROXY: https://goproxy.cn - commands: - - go get -u - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic diff --git a/vendor/gitea.com/macaron/macaron/.gitignore b/vendor/gitea.com/macaron/macaron/.gitignore deleted file mode 100644 index fc5aca3e479cf..0000000000000 --- a/vendor/gitea.com/macaron/macaron/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -macaron.sublime-project -macaron.sublime-workspace -.idea diff --git a/vendor/gitea.com/macaron/macaron/LICENSE b/vendor/gitea.com/macaron/macaron/LICENSE deleted file mode 100644 index c8a16eb2eb9cf..0000000000000 --- a/vendor/gitea.com/macaron/macaron/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright 2014 The Macaron Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/gitea.com/macaron/macaron/README.md b/vendor/gitea.com/macaron/macaron/README.md deleted file mode 100644 index 34830c8b17204..0000000000000 --- a/vendor/gitea.com/macaron/macaron/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# Macaron - -[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/go-macaron/macaron/Go?logo=github&style=for-the-badge)](https://github.com/go-macaron/macaron/actions?query=workflow%3AGo) -[![codecov](https://img.shields.io/codecov/c/github/go-macaron/macaron/master?logo=codecov&style=for-the-badge)](https://codecov.io/gh/go-macaron/macaron) -[![GoDoc](https://img.shields.io/badge/GoDoc-Reference-blue?style=for-the-badge&logo=go)](https://pkg.go.dev/gopkg.in/macaron.v1?tab=doc) -[![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg?style=for-the-badge&logo=sourcegraph)](https://sourcegraph.com/github.com/go-macaron/macaron) - -![Macaron Logo](https://raw.githubusercontent.com/go-macaron/macaron/v1/macaronlogo.png) - -Package macaron is a high productive and modular web framework in Go. - -## Getting Started - -The minimum requirement of Go is **1.6**. - -To install Macaron: - - go get gitea.com/macaron/macaron - -The very basic usage of Macaron: - -```go -package main - -import "gitea.com/macaron/macaron" - -func main() { - m := macaron.Classic() - m.Get("/", func() string { - return "Hello world!" - }) - m.Run() -} -``` - -## Features - -- Powerful routing with suburl. -- Flexible routes combinations. -- Unlimited nested group routers. -- Directly integrate with existing services. -- Dynamically change template files at runtime. -- Allow to use in-memory template and static files. -- Easy to plugin/unplugin features with modular design. -- Handy dependency injection powered by [inject](https://github.com/codegangsta/inject). -- Better router layer and less reflection make faster speed. - -## Middlewares - -Middlewares allow you easily plugin/unplugin features for your Macaron applications. - -There are already many [middlewares](https://github.com/go-macaron) to simplify your work: - -- render - Go template engine -- static - Serves static files -- [gzip](https://github.com/go-macaron/gzip) - Gzip compression to all responses -- [binding](https://github.com/go-macaron/binding) - Request data binding and validation -- [i18n](https://github.com/go-macaron/i18n) - Internationalization and Localization -- [cache](https://github.com/go-macaron/cache) - Cache manager -- [session](https://github.com/go-macaron/session) - Session manager -- [csrf](https://github.com/go-macaron/csrf) - Generates and validates csrf tokens -- [captcha](https://github.com/go-macaron/captcha) - Captcha service -- [pongo2](https://github.com/go-macaron/pongo2) - Pongo2 template engine support -- [sockets](https://github.com/go-macaron/sockets) - WebSockets channels binding -- [bindata](https://github.com/go-macaron/bindata) - Embed binary data as static and template files -- [toolbox](https://github.com/go-macaron/toolbox) - Health check, pprof, profile and statistic services -- [oauth2](https://github.com/go-macaron/oauth2) - OAuth 2.0 backend -- [authz](https://github.com/go-macaron/authz) - ACL/RBAC/ABAC authorization based on Casbin -- [switcher](https://github.com/go-macaron/switcher) - Multiple-site support -- [method](https://github.com/go-macaron/method) - HTTP method override -- [permissions2](https://github.com/xyproto/permissions2) - Cookies, users and permissions -- [renders](https://github.com/go-macaron/renders) - Beego-like render engine(Macaron has built-in template engine, this is another option) -- [piwik](https://github.com/veecue/piwik-middleware) - Server-side piwik analytics - -## Use Cases - -- [Gogs](https://gogs.io): A painless self-hosted Git Service -- [Grafana](http://grafana.org/): The open platform for beautiful analytics and monitoring -- [Peach](https://peachdocs.org): A modern web documentation server -- [Go Walker](https://gowalker.org): Go online API documentation -- [Switch](https://gopm.io): Gopm registry -- [Critical Stack Intel](https://intel.criticalstack.com/): A 100% free intel marketplace from Critical Stack, Inc. - -## Getting Help - -- [API Reference](https://gowalker.org/gitea.com/macaron/macaron) -- [Documentation](https://go-macaron.com) -- [FAQs](https://go-macaron.com/docs/faqs) - -## Credits - -- Basic design of [Martini](https://github.com/go-martini/martini). -- Logo is modified by [@insionng](https://github.com/insionng) based on [Tribal Dragon](http://xtremeyamazaki.deviantart.com/art/Tribal-Dragon-27005087). - -## License - -This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text. diff --git a/vendor/gitea.com/macaron/macaron/context.go b/vendor/gitea.com/macaron/macaron/context.go deleted file mode 100644 index cf545eb46218b..0000000000000 --- a/vendor/gitea.com/macaron/macaron/context.go +++ /dev/null @@ -1,563 +0,0 @@ -// Copyright 2014 The Macaron Authors -// Copyright 2020 The Gitea Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import ( - "crypto/sha256" - "encoding/hex" - "html/template" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "net/url" - "os" - "path" - "path/filepath" - "reflect" - "strconv" - "strings" - "time" - - "gitea.com/macaron/inject" - "github.com/unknwon/com" - "golang.org/x/crypto/pbkdf2" -) - -// Locale reprents a localization interface. -type Locale interface { - Language() string - Tr(string, ...interface{}) string -} - -// RequestBody represents a request body. -type RequestBody struct { - reader io.ReadCloser -} - -// Bytes reads and returns content of request body in bytes. -func (rb *RequestBody) Bytes() ([]byte, error) { - return ioutil.ReadAll(rb.reader) -} - -// String reads and returns content of request body in string. -func (rb *RequestBody) String() (string, error) { - data, err := rb.Bytes() - return string(data), err -} - -// ReadCloser returns a ReadCloser for request body. -func (rb *RequestBody) ReadCloser() io.ReadCloser { - return rb.reader -} - -// Request represents an HTTP request received by a server or to be sent by a client. -type Request struct { - *http.Request -} - -// Body returns a RequestBody for the request -func (r *Request) Body() *RequestBody { - return &RequestBody{r.Request.Body} -} - -// ContextInvoker is an inject.FastInvoker wrapper of func(ctx *Context). -type ContextInvoker func(ctx *Context) - -// Invoke implements inject.FastInvoker - in the context of a func(ctx *Context) this simply calls the function -func (invoke ContextInvoker) Invoke(params []interface{}) ([]reflect.Value, error) { - invoke(params[0].(*Context)) - return nil, nil -} - -// Context represents the runtime context of current request of Macaron instance. -// It is the integration of most frequently used middlewares and helper methods. -type Context struct { - inject.Injector - handlers []Handler - action Handler - index int - - *Router - Req Request - Resp ResponseWriter - params Params - Render - Locale - Data map[string]interface{} -} - -func (ctx *Context) handler() Handler { - if ctx.index < len(ctx.handlers) { - return ctx.handlers[ctx.index] - } - if ctx.index == len(ctx.handlers) { - return ctx.action - } - panic("invalid index for context handler") -} - -// Next runs the next handler in the context chain -func (ctx *Context) Next() { - ctx.index++ - ctx.run() -} - -// Written returns whether the context response has been written to -func (ctx *Context) Written() bool { - return ctx.Resp.Written() -} - -func (ctx *Context) run() { - for ctx.index <= len(ctx.handlers) { - vals, err := ctx.Invoke(ctx.handler()) - if err != nil { - panic(err) - } - ctx.index++ - - // if the handler returned something, write it to the http response - if len(vals) > 0 { - ev := ctx.GetVal(reflect.TypeOf(ReturnHandler(nil))) - handleReturn := ev.Interface().(ReturnHandler) - handleReturn(ctx, vals) - } - - if ctx.Written() { - return - } - } -} - -// RemoteAddr returns more real IP address. -func (ctx *Context) RemoteAddr() string { - addr := ctx.Req.Header.Get("X-Real-IP") - if len(addr) == 0 { - addr = ctx.Req.Header.Get("X-Forwarded-For") - if addr == "" { - addr = ctx.Req.RemoteAddr - if i := strings.LastIndex(addr, ":"); i > -1 { - addr = addr[:i] - } - } - } - return addr -} - -func (ctx *Context) renderHTML(status int, setName, tplName string, data ...interface{}) { - if len(data) <= 0 { - ctx.Render.HTMLSet(status, setName, tplName, ctx.Data) - } else if len(data) == 1 { - ctx.Render.HTMLSet(status, setName, tplName, data[0]) - } else { - ctx.Render.HTMLSet(status, setName, tplName, data[0], data[1].(HTMLOptions)) - } -} - -// HTML renders the HTML with default template set. -func (ctx *Context) HTML(status int, name string, data ...interface{}) { - ctx.renderHTML(status, DEFAULT_TPL_SET_NAME, name, data...) -} - -// HTMLSet renders the HTML with given template set name. -func (ctx *Context) HTMLSet(status int, setName, tplName string, data ...interface{}) { - ctx.renderHTML(status, setName, tplName, data...) -} - -// Redirect sends a redirect response -func (ctx *Context) Redirect(location string, status ...int) { - code := http.StatusFound - if len(status) == 1 { - code = status[0] - } - - http.Redirect(ctx.Resp, ctx.Req.Request, location, code) -} - -// MaxMemory is the maximum amount of memory to use when parsing a multipart form. -// Set this to whatever value you prefer; default is 10 MB. -var MaxMemory = int64(1024 * 1024 * 10) - -func (ctx *Context) parseForm() { - if ctx.Req.Form != nil { - return - } - - contentType := ctx.Req.Header.Get(_CONTENT_TYPE) - if (ctx.Req.Method == "POST" || ctx.Req.Method == "PUT") && - len(contentType) > 0 && strings.Contains(contentType, "multipart/form-data") { - _ = ctx.Req.ParseMultipartForm(MaxMemory) - } else { - _ = ctx.Req.ParseForm() - } -} - -// Query querys form parameter. -func (ctx *Context) Query(name string) string { - ctx.parseForm() - return ctx.Req.Form.Get(name) -} - -// QueryTrim querys and trims spaces form parameter. -func (ctx *Context) QueryTrim(name string) string { - return strings.TrimSpace(ctx.Query(name)) -} - -// QueryStrings returns a list of results by given query name. -func (ctx *Context) QueryStrings(name string) []string { - ctx.parseForm() - - vals, ok := ctx.Req.Form[name] - if !ok { - return []string{} - } - return vals -} - -// QueryEscape returns escapred query result. -func (ctx *Context) QueryEscape(name string) string { - return template.HTMLEscapeString(ctx.Query(name)) -} - -// QueryBool returns query result in bool type. -func (ctx *Context) QueryBool(name string) bool { - v, _ := strconv.ParseBool(ctx.Query(name)) - return v -} - -// QueryInt returns query result in int type. -func (ctx *Context) QueryInt(name string) int { - return com.StrTo(ctx.Query(name)).MustInt() -} - -// QueryInt64 returns query result in int64 type. -func (ctx *Context) QueryInt64(name string) int64 { - return com.StrTo(ctx.Query(name)).MustInt64() -} - -// QueryFloat64 returns query result in float64 type. -func (ctx *Context) QueryFloat64(name string) float64 { - v, _ := strconv.ParseFloat(ctx.Query(name), 64) - return v -} - -// Params returns value of given param name. -// e.g. ctx.Params(":uid") or ctx.Params("uid") -func (ctx *Context) Params(name string) string { - if len(name) == 0 { - return "" - } - if len(name) > 1 && name[0] != ':' { - name = ":" + name - } - return ctx.params[name] -} - -// AllParams returns all params. -func (ctx *Context) AllParams() Params { - return ctx.params -} - -// SetParams sets value of param with given name. -func (ctx *Context) SetParams(name, val string) { - if name != "*" && !strings.HasPrefix(name, ":") { - name = ":" + name - } - ctx.params[name] = val -} - -// ReplaceAllParams replace all current params with given params -func (ctx *Context) ReplaceAllParams(params Params) { - ctx.params = params -} - -// ParamsEscape returns escapred params result. -// e.g. ctx.ParamsEscape(":uname") -func (ctx *Context) ParamsEscape(name string) string { - return template.HTMLEscapeString(ctx.Params(name)) -} - -// ParamsInt returns params result in int type. -// e.g. ctx.ParamsInt(":uid") -func (ctx *Context) ParamsInt(name string) int { - return com.StrTo(ctx.Params(name)).MustInt() -} - -// ParamsInt64 returns params result in int64 type. -// e.g. ctx.ParamsInt64(":uid") -func (ctx *Context) ParamsInt64(name string) int64 { - return com.StrTo(ctx.Params(name)).MustInt64() -} - -// ParamsFloat64 returns params result in int64 type. -// e.g. ctx.ParamsFloat64(":uid") -func (ctx *Context) ParamsFloat64(name string) float64 { - v, _ := strconv.ParseFloat(ctx.Params(name), 64) - return v -} - -// GetFile returns information about user upload file by given form field name. -func (ctx *Context) GetFile(name string) (multipart.File, *multipart.FileHeader, error) { - return ctx.Req.FormFile(name) -} - -// SaveToFile reads a file from request by field name and saves to given path. -func (ctx *Context) SaveToFile(name, savePath string) error { - fr, _, err := ctx.GetFile(name) - if err != nil { - return err - } - defer fr.Close() - - fw, err := os.OpenFile(savePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) - if err != nil { - return err - } - defer fw.Close() - - _, err = io.Copy(fw, fr) - return err -} - -// SetCookie sets given cookie value to response header. -// FIXME: IE support? http://golanghome.com/post/620#reply2 -func (ctx *Context) SetCookie(name string, value string, others ...interface{}) { - cookie := http.Cookie{} - cookie.Name = name - cookie.Value = url.QueryEscape(value) - - if len(others) > 0 { - switch v := others[0].(type) { - case int: - cookie.MaxAge = v - case int64: - cookie.MaxAge = int(v) - case int32: - cookie.MaxAge = int(v) - case func(*http.Cookie): - v(&cookie) - } - } - - cookie.Path = "/" - if len(others) > 1 { - if v, ok := others[1].(string); ok && len(v) > 0 { - cookie.Path = v - } else if v, ok := others[1].(func(*http.Cookie)); ok { - v(&cookie) - } - } - - if len(others) > 2 { - if v, ok := others[2].(string); ok && len(v) > 0 { - cookie.Domain = v - } else if v, ok := others[1].(func(*http.Cookie)); ok { - v(&cookie) - } - } - - if len(others) > 3 { - switch v := others[3].(type) { - case bool: - cookie.Secure = v - case func(*http.Cookie): - v(&cookie) - default: - if others[3] != nil { - cookie.Secure = true - } - } - } - - if len(others) > 4 { - if v, ok := others[4].(bool); ok && v { - cookie.HttpOnly = true - } else if v, ok := others[1].(func(*http.Cookie)); ok { - v(&cookie) - } - } - - if len(others) > 5 { - if v, ok := others[5].(time.Time); ok { - cookie.Expires = v - cookie.RawExpires = v.Format(time.UnixDate) - } else if v, ok := others[1].(func(*http.Cookie)); ok { - v(&cookie) - } - } - - if len(others) > 6 { - for _, other := range others[6:] { - if v, ok := other.(func(*http.Cookie)); ok { - v(&cookie) - } - } - } - - ctx.Resp.Header().Add("Set-Cookie", cookie.String()) -} - -// GetCookie returns given cookie value from request header. -func (ctx *Context) GetCookie(name string) string { - cookie, err := ctx.Req.Cookie(name) - if err != nil { - return "" - } - val, _ := url.QueryUnescape(cookie.Value) - return val -} - -// GetCookieInt returns cookie result in int type. -func (ctx *Context) GetCookieInt(name string) int { - return com.StrTo(ctx.GetCookie(name)).MustInt() -} - -// GetCookieInt64 returns cookie result in int64 type. -func (ctx *Context) GetCookieInt64(name string) int64 { - return com.StrTo(ctx.GetCookie(name)).MustInt64() -} - -// GetCookieFloat64 returns cookie result in float64 type. -func (ctx *Context) GetCookieFloat64(name string) float64 { - v, _ := strconv.ParseFloat(ctx.GetCookie(name), 64) - return v -} - -var defaultCookieSecret string - -// SetDefaultCookieSecret sets global default secure cookie secret. -func (m *Macaron) SetDefaultCookieSecret(secret string) { - defaultCookieSecret = secret -} - -// SetSecureCookie sets given cookie value to response header with default secret string. -func (ctx *Context) SetSecureCookie(name, value string, others ...interface{}) { - ctx.SetSuperSecureCookie(defaultCookieSecret, name, value, others...) -} - -// GetSecureCookie returns given cookie value from request header with default secret string. -func (ctx *Context) GetSecureCookie(key string) (string, bool) { - return ctx.GetSuperSecureCookie(defaultCookieSecret, key) -} - -// SetSuperSecureCookie sets given cookie value to response header with secret string. -func (ctx *Context) SetSuperSecureCookie(secret, name, value string, others ...interface{}) { - key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New) - text, err := com.AESGCMEncrypt(key, []byte(value)) - if err != nil { - panic("error encrypting cookie: " + err.Error()) - } - - ctx.SetCookie(name, hex.EncodeToString(text), others...) -} - -// GetSuperSecureCookie returns given cookie value from request header with secret string. -func (ctx *Context) GetSuperSecureCookie(secret, name string) (string, bool) { - val := ctx.GetCookie(name) - if val == "" { - return "", false - } - - text, err := hex.DecodeString(val) - if err != nil { - return "", false - } - - key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New) - text, err = com.AESGCMDecrypt(key, text) - return string(text), err == nil -} - -func (ctx *Context) setRawContentHeader() { - ctx.Resp.Header().Set("Content-Description", "Raw content") - ctx.Resp.Header().Set("Content-Type", "text/plain") - ctx.Resp.Header().Set("Expires", "0") - ctx.Resp.Header().Set("Cache-Control", "must-revalidate") - ctx.Resp.Header().Set("Pragma", "public") -} - -// ServeContent serves given content to response. -func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) { - modtime := time.Now() - for _, p := range params { - switch v := p.(type) { - case time.Time: - modtime = v - } - } - - ctx.setRawContentHeader() - http.ServeContent(ctx.Resp, ctx.Req.Request, name, modtime, r) -} - -// ServeFileContent serves given file as content to response. -func (ctx *Context) ServeFileContent(file string, names ...string) { - var name string - if len(names) > 0 { - name = names[0] - } else { - name = path.Base(file) - } - - f, err := os.Open(file) - if err != nil { - if Env == PROD { - http.Error(ctx.Resp, "Internal Server Error", 500) - } else { - http.Error(ctx.Resp, err.Error(), 500) - } - return - } - defer f.Close() - - ctx.setRawContentHeader() - http.ServeContent(ctx.Resp, ctx.Req.Request, name, time.Now(), f) -} - -// ServeFile serves given file to response. -func (ctx *Context) ServeFile(file string, names ...string) { - var name string - if len(names) > 0 { - name = names[0] - } else { - name = path.Base(file) - } - ctx.Resp.Header().Set("Content-Description", "File Transfer") - ctx.Resp.Header().Set("Content-Type", "application/octet-stream") - ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+name) - ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary") - ctx.Resp.Header().Set("Expires", "0") - ctx.Resp.Header().Set("Cache-Control", "must-revalidate") - ctx.Resp.Header().Set("Pragma", "public") - http.ServeFile(ctx.Resp, ctx.Req.Request, file) -} - -// ChangeStaticPath changes static path from old to new one. -func (ctx *Context) ChangeStaticPath(oldPath, newPath string) { - if !filepath.IsAbs(oldPath) { - oldPath = filepath.Join(Root, oldPath) - } - dir := statics.Get(oldPath) - if dir != nil { - statics.Delete(oldPath) - - if !filepath.IsAbs(newPath) { - newPath = filepath.Join(Root, newPath) - } - *dir = http.Dir(newPath) - statics.Set(dir) - } -} diff --git a/vendor/gitea.com/macaron/macaron/go.mod b/vendor/gitea.com/macaron/macaron/go.mod deleted file mode 100644 index 4741454ed4e31..0000000000000 --- a/vendor/gitea.com/macaron/macaron/go.mod +++ /dev/null @@ -1,12 +0,0 @@ -module gitea.com/macaron/macaron - -go 1.11 - -require ( - gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a - github.com/smartystreets/assertions v1.0.1 // indirect - github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 - github.com/unknwon/com v1.0.1 - golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 - gopkg.in/ini.v1 v1.44.0 -) diff --git a/vendor/gitea.com/macaron/macaron/go.sum b/vendor/gitea.com/macaron/macaron/go.sum deleted file mode 100644 index bd41a79152f91..0000000000000 --- a/vendor/gitea.com/macaron/macaron/go.sum +++ /dev/null @@ -1,31 +0,0 @@ -gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a h1:aOKEXkDTnh4euoH0so/THLXeHtQuqHmDPb1xEk6Ehok= -gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= -github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/vendor/gitea.com/macaron/macaron/logger.go b/vendor/gitea.com/macaron/macaron/logger.go deleted file mode 100644 index 34178d78a6a4a..0000000000000 --- a/vendor/gitea.com/macaron/macaron/logger.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2013 Martini Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import ( - "fmt" - "log" - "net/http" - "reflect" - "runtime" - "time" -) - -var ( - ColorLog = true - LogTimeFormat = "2006-01-02 15:04:05" -) - -func init() { - ColorLog = runtime.GOOS != "windows" -} - -// LoggerInvoker is an inject.FastInvoker wrapper of func(ctx *Context, log *log.Logger). -type LoggerInvoker func(ctx *Context, log *log.Logger) - -func (invoke LoggerInvoker) Invoke(params []interface{}) ([]reflect.Value, error) { - invoke(params[0].(*Context), params[1].(*log.Logger)) - return nil, nil -} - -// Logger returns a middleware handler that logs the request as it goes in and the response as it goes out. -func Logger() Handler { - return func(ctx *Context, log *log.Logger) { - start := time.Now() - - log.Printf("%s: Started %s %s for %s", time.Now().Format(LogTimeFormat), ctx.Req.Method, ctx.Req.RequestURI, ctx.RemoteAddr()) - - rw := ctx.Resp.(ResponseWriter) - ctx.Next() - - content := fmt.Sprintf("%s: Completed %s %s %v %s in %v", time.Now().Format(LogTimeFormat), ctx.Req.Method, ctx.Req.RequestURI, rw.Status(), http.StatusText(rw.Status()), time.Since(start)) - if ColorLog { - switch rw.Status() { - case 200, 201, 202: - content = fmt.Sprintf("\033[1;32m%s\033[0m", content) - case 301, 302: - content = fmt.Sprintf("\033[1;37m%s\033[0m", content) - case 304: - content = fmt.Sprintf("\033[1;33m%s\033[0m", content) - case 401, 403: - content = fmt.Sprintf("\033[4;31m%s\033[0m", content) - case 404: - content = fmt.Sprintf("\033[1;31m%s\033[0m", content) - case 500: - content = fmt.Sprintf("\033[1;36m%s\033[0m", content) - } - } - log.Println(content) - } -} diff --git a/vendor/gitea.com/macaron/macaron/macaron.go b/vendor/gitea.com/macaron/macaron/macaron.go deleted file mode 100644 index 5326093dce1bf..0000000000000 --- a/vendor/gitea.com/macaron/macaron/macaron.go +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -// Package macaron is a high productive and modular web framework in Go. -package macaron - -import ( - "io" - "log" - "net/http" - "os" - "reflect" - "strings" - "sync" - - "github.com/unknwon/com" - "gopkg.in/ini.v1" - - "gitea.com/macaron/inject" -) - -const _VERSION = "1.3.2.1216" - -func Version() string { - return _VERSION -} - -// Handler can be any callable function. -// Macaron attempts to inject services into the handler's argument list, -// and panics if an argument could not be fullfilled via dependency injection. -type Handler interface{} - -// handlerFuncInvoker is an inject.FastInvoker wrapper of func(http.ResponseWriter, *http.Request). -type handlerFuncInvoker func(http.ResponseWriter, *http.Request) - -func (invoke handlerFuncInvoker) Invoke(params []interface{}) ([]reflect.Value, error) { - invoke(params[0].(http.ResponseWriter), params[1].(*http.Request)) - return nil, nil -} - -// internalServerErrorInvoker is an inject.FastInvoker wrapper of func(rw http.ResponseWriter, err error). -type internalServerErrorInvoker func(rw http.ResponseWriter, err error) - -func (invoke internalServerErrorInvoker) Invoke(params []interface{}) ([]reflect.Value, error) { - invoke(params[0].(http.ResponseWriter), params[1].(error)) - return nil, nil -} - -// validateAndWrapHandler makes sure a handler is a callable function, it panics if not. -// When the handler is also potential to be any built-in inject.FastInvoker, -// it wraps the handler automatically to have some performance gain. -func validateAndWrapHandler(h Handler) Handler { - if reflect.TypeOf(h).Kind() != reflect.Func { - panic("Macaron handler must be a callable function") - } - - if !inject.IsFastInvoker(h) { - switch v := h.(type) { - case func(*Context): - return ContextInvoker(v) - case func(*Context, *log.Logger): - return LoggerInvoker(v) - case func(http.ResponseWriter, *http.Request): - return handlerFuncInvoker(v) - case func(http.ResponseWriter, error): - return internalServerErrorInvoker(v) - } - } - return h -} - -// validateAndWrapHandlers preforms validation and wrapping for each input handler. -// It accepts an optional wrapper function to perform custom wrapping on handlers. -func validateAndWrapHandlers(handlers []Handler, wrappers ...func(Handler) Handler) []Handler { - var wrapper func(Handler) Handler - if len(wrappers) > 0 { - wrapper = wrappers[0] - } - - wrappedHandlers := make([]Handler, len(handlers)) - for i, h := range handlers { - h = validateAndWrapHandler(h) - if wrapper != nil && !inject.IsFastInvoker(h) { - h = wrapper(h) - } - wrappedHandlers[i] = h - } - - return wrappedHandlers -} - -// Macaron represents the top level web application. -// inject.Injector methods can be invoked to map services on a global level. -type Macaron struct { - inject.Injector - befores []BeforeHandler - handlers []Handler - action Handler - - hasURLPrefix bool - urlPrefix string // For suburl support. - *Router - - logger *log.Logger -} - -// NewWithLogger creates a bare bones Macaron instance. -// Use this method if you want to have full control over the middleware that is used. -// You can specify logger output writer with this function. -func NewWithLogger(out io.Writer) *Macaron { - m := &Macaron{ - Injector: inject.New(), - action: func() {}, - Router: NewRouter(), - logger: log.New(out, "[Macaron] ", 0), - } - m.Router.m = m - m.Map(m.logger) - m.Map(defaultReturnHandler()) - m.NotFound(http.NotFound) - m.InternalServerError(func(rw http.ResponseWriter, err error) { - http.Error(rw, err.Error(), 500) - }) - return m -} - -// New creates a bare bones Macaron instance. -// Use this method if you want to have full control over the middleware that is used. -func New() *Macaron { - return NewWithLogger(os.Stdout) -} - -// Classic creates a classic Macaron with some basic default middleware: -// macaron.Logger, macaron.Recovery and macaron.Static. -func Classic() *Macaron { - m := New() - m.Use(Logger()) - m.Use(Recovery()) - m.Use(Static("public")) - return m -} - -// Handlers sets the entire middleware stack with the given Handlers. -// This will clear any current middleware handlers, -// and panics if any of the handlers is not a callable function -func (m *Macaron) Handlers(handlers ...Handler) { - m.handlers = make([]Handler, 0) - for _, handler := range handlers { - m.Use(handler) - } -} - -// Action sets the handler that will be called after all the middleware has been invoked. -// This is set to macaron.Router in a macaron.Classic(). -func (m *Macaron) Action(handler Handler) { - handler = validateAndWrapHandler(handler) - m.action = handler -} - -// BeforeHandler represents a handler executes at beginning of every request. -// Macaron stops future process when it returns true. -type BeforeHandler func(rw http.ResponseWriter, req *http.Request) bool - -func (m *Macaron) Before(handler BeforeHandler) { - m.befores = append(m.befores, handler) -} - -// Use adds a middleware Handler to the stack, -// and panics if the handler is not a callable func. -// Middleware Handlers are invoked in the order that they are added. -func (m *Macaron) Use(handler Handler) { - handler = validateAndWrapHandler(handler) - m.handlers = append(m.handlers, handler) -} - -func (m *Macaron) createContext(rw http.ResponseWriter, req *http.Request) *Context { - c := &Context{ - Injector: inject.New(), - handlers: m.handlers, - action: m.action, - index: 0, - Router: m.Router, - Req: Request{req}, - Resp: NewResponseWriter(req.Method, rw), - Render: &DummyRender{rw}, - Data: make(map[string]interface{}), - } - c.SetParent(m) - c.Map(c) - c.MapTo(c.Resp, (*http.ResponseWriter)(nil)) - c.Map(req) - return c -} - -// ServeHTTP is the HTTP Entry point for a Macaron instance. -// Useful if you want to control your own HTTP server. -// Be aware that none of middleware will run without registering any router. -func (m *Macaron) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - if m.hasURLPrefix { - req.URL.Path = strings.TrimPrefix(req.URL.Path, m.urlPrefix) - } - for _, h := range m.befores { - if h(rw, req) { - return - } - } - m.Router.ServeHTTP(rw, req) -} - -func GetDefaultListenInfo() (string, int) { - host := os.Getenv("HOST") - if len(host) == 0 { - host = "0.0.0.0" - } - port := com.StrTo(os.Getenv("PORT")).MustInt() - if port == 0 { - port = 4000 - } - return host, port -} - -// Run the http server. Listening on os.GetEnv("PORT") or 4000 by default. -func (m *Macaron) Run(args ...interface{}) { - host, port := GetDefaultListenInfo() - if len(args) == 1 { - switch arg := args[0].(type) { - case string: - host = arg - case int: - port = arg - } - } else if len(args) >= 2 { - if arg, ok := args[0].(string); ok { - host = arg - } - if arg, ok := args[1].(int); ok { - port = arg - } - } - - addr := host + ":" + com.ToStr(port) - logger := m.GetVal(reflect.TypeOf(m.logger)).Interface().(*log.Logger) - logger.Printf("listening on %s (%s)\n", addr, safeEnv()) - logger.Fatalln(http.ListenAndServe(addr, m)) -} - -// SetURLPrefix sets URL prefix of router layer, so that it support suburl. -func (m *Macaron) SetURLPrefix(prefix string) { - m.urlPrefix = prefix - m.hasURLPrefix = len(m.urlPrefix) > 0 -} - -// ____ ____ .__ ___. .__ -// \ \ / /____ _______|__|____ \_ |__ | | ____ ______ -// \ Y /\__ \\_ __ \ \__ \ | __ \| | _/ __ \ / ___/ -// \ / / __ \| | \/ |/ __ \| \_\ \ |_\ ___/ \___ \ -// \___/ (____ /__| |__(____ /___ /____/\___ >____ > -// \/ \/ \/ \/ \/ - -const ( - DEV = "development" - PROD = "production" - TEST = "test" -) - -var ( - // Env is the environment that Macaron is executing in. - // The MACARON_ENV is read on initialization to set this variable. - Env = DEV - envLock sync.Mutex - - // Path of work directory. - // You must set this value yourself - Root string - - // Flash applies to current request. - FlashNow bool - - // Configuration convention object. - cfg *ini.File -) - -func setENV(e string) { - envLock.Lock() - defer envLock.Unlock() - - if len(e) > 0 { - Env = e - } -} - -func safeEnv() string { - envLock.Lock() - defer envLock.Unlock() - - return Env -} - -func init() { - setENV(os.Getenv("MACARON_ENV")) -} - -// SetConfig sets data sources for configuration. -func SetConfig(source interface{}, others ...interface{}) (_ *ini.File, err error) { - cfg, err = ini.Load(source, others...) - return Config(), err -} - -// Config returns configuration convention object. -// It returns an empty object if there is no one available. -func Config() *ini.File { - if cfg == nil { - return ini.Empty() - } - return cfg -} diff --git a/vendor/gitea.com/macaron/macaron/macaronlogo.png b/vendor/gitea.com/macaron/macaron/macaronlogo.png deleted file mode 100644 index 399759769a8d7f5549d550baccdd2ea5716e2bac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88924 zcmd?P1CwRlwk^8SuC#62&aAX;+jeH9ZL`ugDs9`gZCkItv(LR}zy0q01#d>oh`CyC zt&ff|VvUJ#d08`n;k@ehD#V0BQB>|9G;ArzTMU< zy&5u7C-uwhhPg{mKQzF`FrfR@*rkX7k!skao5x>P;apy7EFGD@cCT*Z`6zwzj(EPS z+>%{PXA4GUYiwIzRMK~%0iH-Sf8*A7C941$Y`_H$cPr(t2>^FsfQGHid%O^9-GqTX zSaO)iiwkQfpd2eY>J#?&oB+GA?hwxB^zo~ARqkSRet%*KRAv*A!{U-+DdC9;*dM9W z#-Gm!-}^nB7L%j>G?_U)=(oWqDhek_P(k75?ZG_$>Tz_&&_TY7yS^A~ReX(8ER*Ng@f$vjc7*M&v>=hv z(GzT}u_I|d4Q9c1kaaIGQXGVHE;Nfj9Ro0pJ{*o8vpvWb0U*dv904Q+giajTLICuS zAm7U0Dag12$V6z9;236~UvxkB86BB?A>6Kyt+VZ!647fo+%@-_> zLo0+&|G9*KtqJKNBq+~;0x~ER9*2-1@H#_Qia`}vo+l*F`#|iB)dr~(_?8PXL%;(5 z3FIAwm{Lt#(@;;8{ZLjN6myl?^)lKY(eAu(cFi=i+uy23D)aNgcKNo z1eq08hs3@W{u!rE0)$9t6;D(MTqcqc_oEQIHCjC0;Q$0YG|wOn18oR%KU5=X*HG19 z$xxDEG0iAVRT}+>%@l#z|23e$cn)QH_ngY z9?U%)d!H5zZ6;gRYS3o*<*0VQ^M1HpvRn5Ksx6f30Qg>~8^d3OUC_QbzIfZQ_(R>~ zaZs9|RsryYDFh_eB+3X_kjIdpL5O`U3jU>X&O{*y9s}BjlyxyHf*le#WU`4U5+Nk$ ziX@cj4gSg!mP9&aykwn(iKAS`VvZOZ0=jb5Bsm0nr0@y+@<|kAC~}fGB0pDUIVD>K zJOn(1iWK2WZ5Pzb)7r8$d2gorGmA6IKOs7L!(l3DVMXKXXICb$M08a7~V+r$Skx?G(DP28YS9u8hi~(4KQ_^ zhO^qY{6;SkGxqxz}h&7;PuGTLp|?n`g(44v9dw07C{>8Br0MDJwpj1at` z?xCGOo>!b*DcXa)7ZJ}-c3Y-yqxK=ly~yk4B}%rlG^Qx0;HC;-V9{^T7icjYXB~E1 za2(_5jOn8E-0kxgRMwOCHP7EBWR|0kT?cFiHdlC8KU?0Z;icf?#Uh83N)nH;reSo$ zQft)W)oPj(o(-=puS@v2_`><3`H;I@yDGftUkpBhKV9E8@0V|m-K@vdfNl=>F4xFv=`8Te|`wL2J=9%!s?*DIbqPzuvC&=c(kav z`?$M-(i(~g3k|f3$BxX6h($)DNujxkj*1P6EQ-m9c!{KnNTsUNXw)BwMrlS76!W6t zW21VJxH^_S&uvPD?qBRd?_bd|Yp2v-tT{FwmW@wW$LaNII8fnXzk3b_ikUHazr*GEG?TYoC- zcG6C1{jeUiMzy}&G_9|)Tu&v^oqaSM-;3CjBi%?i-`4O}d)=IP3cBnpdMbK%+i`_- z+t@s9yH`&))X-g>sov44I-I!6ziVz+yXaCi&~ng+w}>^4ZD1<>(1)_qp>Z9Y5#e2aO8%Mi)HI_Rp_#X|u@v4^$Y$Xs?X`XCH=l(&g-gr-`}@~J)Khv! z{g|25bo>-*=5Nj%H=nzoL&3L^;pm}UYR-IZ4F_{s)wR`IH(Mx#k*(rJ#J{G5q*EXG}_Vu4B`&BVrVBW`XI`8ybPi@|ZG2dC( zAd%p2S9D!o-?|&Tr`}tivk+zQy8IKK9G~W&Mi=|}HLygrCpqFOHVe(#wQ2!ZWh_55w`N7jiFh z$vM&dZoi;D?%c_2OpmsogYMs%xHNqJ?kS<{#WkD&02t(dP9Q)=CI$ciGHIc#?yN2& z&1Ga~LuX)YXJ|s_Ze#zK4FK@CbN#)vF>y8^aJR9xb>ed8CHgN0*Wc@ZV0t2g|Drfs z@e--a$P)PbB6DYFdoFrBdxPEJmG1}1tYCfdIYS|<-%X9IUyTPNawIr(3HgiV}`94+jfE$nOw{_$&IXy@Y0 zOGNa~K>z#r?>KGj|Mx()PXC?N-~8y^4eaR|=@{t$PaR zWdB(HCHt>p{3}MDzZK<@u`{+X^$<32HsNDpU}T|XWT0haR%T$~VrAlDVdkO#56=H& z_+M%vM-u~QJ4ac(~@1p;c zKa>BAhLMeng^`Pa?ce18;{2QXpTcm-Ia-+f?bttk;bY{X|NmhB$=6Ucak8^^`7b^@ z(|-&89sEzh|L|38Eu8uOm*hX-|5T~}kDc#-5A*NfzX|^76qk^lwVk7qy@8R*KWY3Y z^q*{b3wIN1bzut|6I-YM%AA3L;lEY?Y5G4(HU96?e>45Jl!yMG3IA^k;9sljztF$S zix2v5lm6FI<%3Q-Ui$<91OO7kg39hd7v2zlDuavP8+V@T&EBaoEWK!hA;BUF2r#9! z6l}u12`l-t^x;skzx0rz!?8ZG2Qgp_jcf=AfcpXh;FOiQXvUwqYM$@Dvs$m|>@4#0 zR|mOkubaw_r#`MY&89L9q+zhYSfI^OW+-wM1Pc5_fue!`{|U@YQV=-TzgaF`j-iMb zC4I42p~Wz#N1kyx$py2gBt!L+$w<0vqz@)>z>+hYQ9XkhOy9?Zt%ZvM1p`Y$%$MdV z?ChW*s8bD+B`1eR$r$$Eskdz>)#s6tmdQjF`AJdkGWf|r=R&+7h3wfWd2o(V?y|0{ z_bFCJ)%}s683ont0JnzlH4{6ScOK>@S}$fj<5nUd1*ED|`dO&!X3Lw^LlwwzQEE^@ zh6_zd>Q^VHBnS?Qj^-x{lS!d@|I9%#){unEw~jmDNZb#1=b$V;a3{cuB-7xDha5mU zT%1I7-A)HeO5{oUb5x`_clUTcXt*s=7ClMBYCT_>G%li@F_ec3{n=)P16SL2{+pZT zQ5LEirKQLbdR692h;w52Gw8>U~77&fCqlgDjarsu zZHhaS27U|~wRe|*)#@>A^aLx9_~RzG{Z(a$_MZ0Nq1)o>!1cY9%DnWf{1!X6x816E z0nnagKjaT5SS^)*<-pRZTce?UeRQWBTg3@M`E`W@$5k477$GViTRnHab}P142O{;$I))4IDp;(`Vr*E zjVT}>q(b}!8)?!lr3(|Zl)@KM>}l#|k;7Fwnu=|ozx<*&>SPY3S5~xBsHn4oG%ay3 z;v3q*|5d{QPvm7rXl*elY9Ilqcfi6R4And8I_)q<^qzgs;7t<64_PQfxlv=r!UrM) zu*eXdRXYE+yzD*ysFRHh2^W-gObT$lKx zeZ9nL_Hf=UxFooQk_zVm5JF%Dt0@bkG|;(_V#qXD(SO{LDitNgBf}&Fzz#S85D{c3 zrvM_K&}H%hYLiSKEfwY*B_?G9IdMJb8w;FS$eA9iqJsQi3cx9+K*pl>-k!B4iZr7M z2EGE~#Z5rk{4t`)_$;0QIUNoPIT5_+#DU6^nP9f_jnKKp{%T|vZ5OZ47n(Xvy!_h{ z4slee=1bLy2_L(S#n^H<3>$^W)99pipiIlR6NdGJK!SPd5y3=4orV|JOs zMeVPm&fo>mqQOC!Pr-^o+DJdU;^L%#!F}0_P@s5yZ=+u3)MAIcEc6{s2A+hi$}N{` z0O(VPJj#Mj4TnEnlju~%s<Z4qFJ^)X|W0cTPySi zOn>B)>I66j3~xE$Mo7vcg@YXwcOX0cL3vQ+7KqKt;{fphNI!63VtY;;QDyy~#xX9? z6aJV=fAWN>?q(GPQH+NaLVD9mXlz>aB@Wo z+8hyt(DGpc^%yb}#sCVTA(>zhR`)h0EIHbb!fKmC^dgYo$pf`;fh+1i>gqZQNqX1I z`DS9iU7&CHUiE5%RsF9;fl{TMqcbU8fy)f;ADF*b{|uBSN-5>r^D(P?4mx`tK}ZJo z87LkMh~&a1t%EX>>>?uEwAcwpW^h;A>W)k_`+HNXTxyj*)eJlD*rCL#$L(NvjtrhKn^r0y(!N*qD z4-1O8t6qK?15L{9P+-bDW0O{AYH+Dg;LoDXso!20WM>a;Rtfpes&i-h+4@OfKLugs zQUK!d;zKG2S;9PgK_0jW@KhF9RbgQE39tZQ+y`DHTe5!nHVE%LWu7I3SYfvTqP)po zd3&jm{pt!k$LkNvLvr1wk6!QtP{MmLcqZq=*uyajMyjq?mnPR9Ug83Ev|0gEqVqCWOmt7H}oUZkBS(SUtv^z#G?X) z!QY)mT)$@uVK+#u5z;+C&L)K&Qd1D?H)I0;I6!VJ+jwjnN*91=bA{R;1WFy+DJhKkc1* z-JBd1w$_y*cwMkEg6>v09~~5dYf*OmAQAgl+9f{$%9NB!{4SGoZ}Du257dH5bm3a{ zkC$Hn7*Qf9!#sU`i8Ine-o4a;j+oR4AovA8nE*cv-#~Mg0H>blv}W4$sGw%C{=8Uk zyy=X!v$4nX>&{=;mZ#h8#h~JTnDJ5cs05a>$u@n!N9h=cl6CJu#hp&CTg&Fqf7}=i z=4P1uW%{^87mUoIq=23hsN$}Z+bu?Nj(%Y9=+D^KZ+f)NT65_zrG=c}tTIh91ral% zg$swj29!rR=>q7fg1=|zQ=_0Z8QsQQbVajtUDqb0?;1fykgi_?ZhbrLb!Ukhwf`n8 z`SCIw)AhNJUX*-8i?RYyYOAi`n>U*K?xJYMLte>T#}*qqh!oxe>i};_wui#dhT^AK z8;B4|os#Gd>k_BSWS}V>H3(3wvZ<4QnfDv6cXk_WTFm)wawb*`^}svDN6q{S78xcr zRxk5Iir%fp1Qb_m0OsNk_o^652O5Kf4-t-S2X~@zUk2iDRpPmSeYNSbE-W zEk3G9rTgyUJuq?lAE~kF`qp;a6Frr}^=9hXYEqSHp)lL*`Lx7%lJ0Vxl%ahAyFV~Y zN#X*4HTt472R1kGV8B$pG_|%h8|+u1pUyrP)06WY!;N;wRoQGLd%wcKv$>R+3tUs3 za-;WD@;U7i?5&_+&7O5zytg_B(X~BBHCBUzQ_m(-oZvKCTP4E0dl5Kl>_Mr0T9_f@ zkHiQqoh%Xj;^k%8zS00-X5#}i6)Fw$6EGXf84-=*N%PK_40)l#7-6nFDpqDS5 zl(|4l&t#kMavT<0JQhd;I4<%!?Hvvciv(NKQ7Q3TK_hFwd@@?4&Vo=*XOn@UN|ozk zos@ne36N>gs1^^4M>Mjx6B~S6>PfAy!|46)PNMx_KFxENf0Q}cB)BXt;tot)tF+_n zQ?|wp{IeS{ZH$kf@ zO@`*w%8ar5`QESnvZz_tqabSX+X;ePgh0d!YFw>qj;19%uGWAWlT(p~(tqT4*~0f= z!=BVt*CUdb?$x4al~;e!VW>GMa2W6o$>=G-|}61A;BahmUZRe zWswDqy)rNd)tHh(NyRaO0+Mlv{t!*qYOc|2im2Scb(Wr5r`HrjHrlF#De7F9W%Z33)$iCsyFig+8}p zKXCQ!bmMJ$Ab&`YS>*x#R37g`8MpqG`>(WBiz+)S;`vJs4yr%*2VgUToX3f`Q0A*5 zzZa=6ay7ym*e@Si*K@M?ud7-sCsc}-#NRV2l3wt{{8C|dk~z7@S4hE9r{3pPmS~Py z!Xo?kYDb=5KPl7P1@(`6z*JK6bJavdPFnWl-6euGGy?bzVv3Q%eJ8e7-q4@M4Sdc( z4#?Un8&Fb^HDCBpW&r2!@|W#Jh^CcV%YFsqsPx)oUx_@V!GMov5y$;lAm@llXB!HaA8fOf2 zk@e5{NE2_s6igenG-t}C!piv&U;W$N1|F|(Sv~i(bowQ1lcl_2k@z&J|Czp#%1!_c zJW3$-Vvr!xVLlEyawl!_m;J*Q`t-E~a|GJbj~=n|1o`FBmz*y z0hPRZAsC|K3${q(0gKW`1DXA+i0vxGnsl$A#ys z-P$LZ62(rX z1XSgQ`FB%(>V;{cu1Fgx=CEFC#C0p3(^*;{u)Nb3 zd8L!iixXG5?YkNocjTlLrMCwkRG*1~Z+llh6oz7=+)QTXaWy!LQ#^FZi(Zq3j zs;l|$=b_Ai`GDH2X9x=ijt`R_)yNiFV0vihD1mO1+4DmpZc|r~t7PuAf_XLVH81j6 zy?L85`p2EWTaO>IIoA&?^ZGYuhc3ty`7gpFClu8-Hlbm|sk8bvb--#11(X2)J@719 zS1xOsCB@|f+tT;@y|NPiV6k5Yw-WWsr%T%`I8vVQ{PKu9&W=jVURGBRd7MRLozgxH zQ%kEhLkKDeafP8SZZe0}Vq0y-H#KEjpcC8cgA5$Zf8?hZBE82Qv8fz$00=u;0f;Me z{W&vTurPCKlGM+Y_b9_(W{-`Wyzd{gam)4iRo6j`7C1~q&!U3o1%B!sUkw`&57MY6 zW)eqX%eWE4cE6e1-064^63H;};j#tZPlf+(D!JnK-}NpGF4e}^Y4AV3g%cl(Lj;mM zh-Wbt(7EXD3BC5pbFXtX1W%dX8@;1M{*5ygdR zT&Vo;{49C4cGbD(OZl|q@J&PXM)HaZd$kd5LwbeEBHdwN$Jd` zMF{QhhAbbJe@4lblr~wPF#Md-`F?*B`TT~A5k)bbBzijQF(h!1D@>7c;$@yi^K0nS zl?O>C$o_na!Q;I=`c+Q?&v1Uo7gv0zzr=_!9x0uR{U9I#(=rQeOe&}(ii0B4AAaMx z2wQ`4ITBY(0NTw^Lv>hT^HeQmx^V6FV@Fcr z@C@Rp*!Krbr~Sk>&1)ywi^1^@Ot6uB>v+S47%H;GjzLPi*VJ`#4)H07O)_oX$f8}$ zdA%tf84p|8^~w9v38YL3&=S0RU3xu_TBn*5ZgE}CQv{lK!7?_pp(Hj)a;$Q~mpCX% zHFT324LP@zbknleMl_tS`*WKTehJk~t|G5i`JU?N2QEmI=lr4+-O277(Bg&o*tj@+ zId$rC^kn_-?=m+o@W$8t3HbFs zA}eVbX0beTs^9!eT-{Nz=qfiK$4j!~)HGl9nac&WMUyfaZl&O9!ZwQQLRr93Ml9== zOWaDkD3#h*J_gd$Viddr2v$hXo2OyfpW1^t>E7)-jQyzH*$;54 z2U|L>KCxiwTugY^+#k+p0-e7C#57Qf{UG0Po3lC)!w1TD81r;&V2~a;YRH; zdRM8%VsP`Cjt4tZLr%G1roz%PXDR97rP%hBPfg7Mo~~xfJLRhI~1i7t=EfdKj|w8J=EG&aTUe{s>VXkYsI;{d6uBNnxaNhQeT@# zD`2alcmPBc4Ljx!NKpe7g2G6#LfGw|`g}LTd%IA0ni|Y<)Aq5Cw3(}m(N!l+vSS`4 z$9`->u60>q+{py*F$v-{If#O9`a$d$F&|*aVNx=rfcT3nnuacU&plljGO6NY+v&nN zHiW}BDCdE5@HnU#1VP?l0@U(1)KscXsXla9r9NF_?iRkc@z=^8JO#Y$cf*U!aww-W z60#WI?bhJnCpa(JAyT7g=$d!GnT%G!ePK5(^zzL=5d_Y>e~@Gq8$bpw(d zu+~9^DG*Z@fP`ZqzQAjjQ36dw2o1^&C8V98EI39$8DP&Rj6%RsHyfDQT|gjEXxMHT zq%HXs3XgXmiA@rr)%#? zKusKDa*=(*#~#DCbbwflN1}4YYscS*Z6EYn4msgh0zsJ!cj>~)*v{h3Am|2RVImqo zI%%(*yokf0O!hsi@@+;W$#?ggYxr&$)LN{}hPmaJs}0f1a8Joir-Gox#ASV&&!Fo` zIu|l$!fosejr)Aye)Z^oIDsLQOGmhrOcu`vuPI)IoN0j^W%gBeTr{I)E7cm{Bidh+ znZo8;ZPn=Q($L|k=&5*%tfp<%xP-ZSm8_m~)kmG;v+(LqkG9wJqWewX8~=pRVkoCS zF5=*r70IaITON}+!?`J&7*53064I&@;>C=g1xHx1Lv3G05TI;d^{d#;BqBt1mo}so zgdXz;-_OSPkzGy)Vo!cQ)ni4HRFzAztv(xqmM`H@qwYJpp{hP%%^@gCmjN_#s0BtRUO>Q@TGwqnKjkCS> zn#3@1E%f+ox74ENXS!bu%>1IEWuBX4*l@L7hbjuk0_22O{yOc2ZwjMl9Y$hC)YYIjYQQ8bGQ425Gpe19``W5Cm5zY3Q5T$L3RnzCI=Z9`>|NlmCXM3ctin=Y@n#^ z0!}jtYLlGa6FiG1&A(`pyP1#MZr2OGcGb;VEpp`=k(w#Be+p%K>tGr+CZ%?77|x`~ zm?>cJMmxT%=;FIBJ~hSrQQ1df`+SXnsBb07E17gFULexhzR-Pr_RI(b=H8dxMZ+fN zc>3IdRR--N4k``5IiBD43QHe1s0%X_`uCgeqi;fSrG?hH7LswUFb)_T5f%%JzQtkJ zq+tr}D1z1c>!kO!EbphCs!{oGZ$^rW9Ybn3>L9Sw`50s$8Th1)g%;e~ z6QD1pA`cXv9!@pec~(1E5kj8Awp&2k&8OFipRsuVz9J7Pm|SV0O148xB>yn+*byKX z>?y)b614{{bRuMum5SY_!^_~*0bXfVIP~t$k+Fue(;!4KFGg=|CZCf&w!D8#Ecs($ z-KEHUsb-*2k5ko+=m3+OTP7TrabEL$Z{KwUGoAeo2

QJx8u(c;{O@hHqa*uT;M%@1 zKHMCt?5>lRK{-f35=T}q6|R=IsKqUQvfQb$27`vavM9QEdGT@U4mhd*BCs?%!CsF& zP?UTCARCWRZEwN-2>OB2J{(`L4X1SUZRF#_X^tJCk znJG$jpEN>Dp&aYe1zLFh+ZCYRTU{kY|Mn8@tMzi|mnWn*?s9jSPS zSeo3--Zb=nWURyGVlkO<>;^WJ8jGa4fO-Dy>g7{@$J(<7U&P&WmiYG?9tk0Y;`&H#{_1mj{ItC2zB576L<+1`R%^8qMZZL%PV0- z97bB*i4%X?xotc5tjw8fa}`QK)OdxuP8mhN(bo&7mY8KqBBsN^WxoFCW8-#FW(&i* zqD6+(KuD~IvYTi{e4FQl@lzg*iE5Ytq_O`ix0|&^A*34j2pTkBovB~Mtn@Jr6SzQv z0RzT4A&FYc`p*>I_y7x{UvRAeB6FAn0Aob_4{4qLNE&1$ayh0yHvcpzt*0oe01MLw z(+LUZ#u8q}`$Gi(9vXI0SRaKT)JWil(DL-Ei1)3w{;LPMa6`D1Y&!)hwjAucxAe4Pdsz$8NAkX1H&7r=CnXq7TM%={E(0v# zqjVHRIYN%i;FeSw0P6r(%qIl?ta_kC4;U9Zts?^ ztp3rtpr27b$0P}AK*+${B9}E32|t0Yq#^-mOj$4zJ%UWBLdAqzCA^Tdk`8jq=lSJ3 z@yjef40pz`PPm*1G1l&@nDv43tP?xk0pMgn6fmLSex!3w4ptjcVuom?OYduX5afZK zO;2;d-&%%ig=p~uLZ+xo%-5JN&_r)mcQqz&86IVc=ecjmDJP_Ld>X7l0EV^{3zc2C^K5_p3K|yH(z|7g=P|`1|8;h-CCpEE>Y{;+7t;7B6=Vl4=ZUv0e zq6kO3J@fjBJS&=cpljQ}n-e?gi@J9*+ku~1Z#%K<)!rO#;z2c-W?Sr+tLYKYaa6;{ z4(Clu1lrKs;!W5#kou3xDA)=2*-@aXO5Phlm~kmf^<6ePXanyvmr~dIRv1u`4?tBV zqaNrLok`9F@_C;Z%*F}=15pS4b)_MP_sh8Ch~gKi&(GGcDK(=LoIzEE#WIn-NaB)t zF>8<@oiYFew=_4mI!3A8p0~5jlYCBnH!?ZDes#L3U6!!51dsgbugW8cXU9&C7ZR1c zT+nN*USP_E0jgDov*~q5{=(7%xy5?B2Tiz4m`$lQ(~HYGrg=Zi2+xW3ZMKBflNGii z%;U~~(4mdfjXV)~)Z{oscWY9y`JHYx#6;Yw3yKVlh-f^>4D2w$bzZ)g*}ZowC1%gK9}U5u}injzFq5tn0R9 zwfR8f-Ah#Jgmjne;ughGao6JM^)a^aB1CAVU7tYPQqDO~kOKzzwSBz)IDHD4+6BAM zj0IU}1EN)EFj7N?R#25En2U`dl`A}-w9i>@T_+Q~U4!Sbi0WmS1@vY?ylNk?{4AA( zq6WU^K=Q~G)a(ikcVCDT3TGqdn==O`j*)*e~tYfjMc-P-o;p*9VBYF-L$Sp-KE8r|= zA2_cz0w>)rsG@Vs9X4maUl&Kvs;y|GU7t;&6H*1`!c#B{>L@JE;lYf=AXoD?eq%2n zj=MU&%;_UPG#dF0*wSeyl5Tu;*s7;TDX1KC z>D#HclId1;G7cxatEP~HLeW!bMqEd-+seJRTiknu9u7&UUmYndRtp=8wQTWgm7R~W zG?tHw8vSSL6^z`yl6s@qBf{4@fLSp+u-E^(as6k;JxP~l1PXEiC) z{Wv)S8%2@E*VI8r!{t{t#Cl+J&Bc2w{7Tu;M!6WJ?A&e=CRJIg>1N($`l16@uVrmq z;?qS!sj=xI)Hybw;lJVu+7;9G{*&CB9ld)}4X)pa$LoT1wbe!Q&LfOcs;%>Qa(wK|<3j z7`?uDt1x!`noem;2@*Vd!;f;ny0BoB55X``(eUyfq@}jyxG!s9<#YjU9G)4;1O0eg zGik&(aJ_AKbCqkbi&5EDZ+GgutB}pEiTLHE_9rmd_vyX^JNB$@mOA6Eqt|}Jl4<0~ zz1F+;IOn_1dpfvXrJc_8jc0xmKDjdP&z)?A&HX@6k3($n15?=)wE3(cr&!TQy9JWe zyfL#g(Lh^I7%L`xXtU_gJh@KW=eM@%J_-FX;DIsY%zY$LB)kEEuT)_m@%1u( zjM^=B*w%IxMW|wz1DNT9EkWRa4@XTseB?ZXgEyr_xs|`IDq_LIV`Q*nEM<^0?QJsC z?W(j$ruW}TH6HTot^#Ay6J*An`Kag+{kY6Gj0!(hpF!z+59Nn1l^ z>I#@wU80rMaHIpw4CZws-qqtKGzEiE0D}jhYw(lbWtQfuQlm7kLd%}O@|()T z@^#>1uV8G0@`t9xosnqnWOyXV0_3Pam@Fl#>-O_li;wTQ?M~(@{FB>PJt&RK+jGL} z`c!|2rW7>~W3{~6(ikNO9xfmOUK;&RWq{lB(KchL+Y zR)@py^psQ3wJ}v%Zag{@OJx&}l2kwX9Uh8Yi>I@;!$)|m`unTR&5e-7cWIXNsC>>d ztKavQtMX41SsT;bMzNT-n!Fxm2NV45O^a1w{-DZ9Wzgyz0sR7-MIVBK-=j{dBN_pch2+)_wRh?NQEfJ7b;rGqcj+?G!%gsN7|rl7WzGnv z09GhZ%C-AF|I7u>kmT$xK7~x0CUwAN9dKeL*Xo_Ou8Xs|52f221wZ6}wx)9B=C_nM zUNd&dYi#R8A|i_bq^Zs_X~2Hj2z-g3W`_O~Xq(k8>Y88e@>-_|m%k8?pSx%82qKM- z@4ZL{#A`(ce>wQj+LvPjooU`YFgxUEp;sz$bkDl|pknoHxoBSW||E33v|s`!RzFX(b;8YXp3)o%&#HT;LTtg^@Gjbe7phn?l^7pordYR#UblJcNy z0}+mYTxgTEu5)}>XZWd4vzfOVJhfZXlHI7#LGn1y093*|s%qu{4+q?8B@&f z$G>enX+R(tdzTqNzJmMx2hh93OJ7q<gpqMh}A5zZRWFdbBjX z75WJH9_7MBu3?vP{fYpojQR2Le1xr#nPMh1)+QAhGFzjQ`iOxPj^^T&NaN34XR}c;GsXQmvKAG(R&|u zbP*gAyN$85G;N|^>Fuz*VV8f|?H(9?)o#ZG_?LPDW&J69Q*$+Y+F!f^2xDLw{v=vA zNL0!`s?o!ne`iU8rO#n@o*y^sq(4TEiYN``!B7Im*06;VixPVhO|gD)+i2 z2HEHwfps%G=+wuZ{`E{C_d}o#n#CiBJ^`ZX-srkHit0(Uyzrs{dS%wF`Y)kQ_Li^c zSMH|TlIi=>M?#0rm%>D(jtSVAjJ5_tgC{>9bhh@7P9g9vs_Zx@VT^^R{)@p^y&|F?~#CoJmE#ghaxKV4~gx3$oj@Z=e zsHdLIZ;)X`^mg|)tab8Tp3ftTKZtnOfra`zyL&KSb?OT(B{oiQ>Z|HV7r5z%2Y$)m zcd`2PXk^x6-kxY4-kf}tleS+saQ(qAy9Mn9LU0NyLI>w9-WRH?VYkD29jp=c1udQ3 zZn--ebaee{T|@xctxKbiAf?HDQ^Y#4LXw}6LTdrB*=*cz^?*U=8_DjpqfYJ}^nVKu z_db(@e?~WFNV-n1I}f|dnT{-ZoaA0KWy>mIKaoW@*#rod)Sp!{72_s9(lgi^E8NIh zgg}tvmc2qPCYzEv%P8~j|Tg+tG03~5zHLPv)3f#0J?}joLSY-KO9GYQFYhdIfD7Ma}87hOyd^k9i2m)#&aQ!K$gL%&NVCXsVU>pd`3vI zdcCT+jaA?OM5vW2t*Ua#bC{?#tj`P8n1aDV zb6V+3dz;M)4OSgqrcC;h&~_}DjW(BOsH4L{y?ZYck*xm9P@{%h$*!I&5!?@UheSBC z)&FYeLf>CTk;Ug0gk~?F862)#@D;&vW`~GC$Qw$BV_*jf22bQqg^8$oO}N1UI7R#5ToR6J^Y~GG{|^9CK&`*|l;O()Oys_>DC+|P7L`mT(dgzS zD%aHMX~lvJ2mHC1jM!0CbJmi}27kDJ(H)VyVjye%^t-*})o&JyxxFr^Yi@xnAzGQC zw3#%00Im3d!hBf@xBTO^iwE4J_S>%5q(i9_y}KhmsAAcKx3-?EmrTpIw}oh{C>Zz9 zH=p!Y=={*lV&F@bsJmjp@+D`or|+uI^%If6ne^Y^etw60H-1{XncZ$EowwRJ{1+ zr9-ZzbT_;7rNN^2{BK8T+3PoYT(hH{NbFT_YO|C59}E2wx}IuMj{5^%0VDCv>O=_as2# z6=7BS2X#{m;1I?yC=uZl|5XkgKi> z)`o$}2d7HYD;MqjN8#Z9zi#nH;($S!vc?cqfGK_C=!pE)!K(rmKc?#tOD5ylHk&N@ zTEBYw?1B@iI(W_jlIqsgL&nF{I=*bvny5MNIC8lRKm0On+Q@+#B*4re8w@3UBJ7=1 zHeulFYX9x(?b~1dI=a{X9v%tz)R$_1W@Gl)T;n%&VX4TEJ*LQ8DD_(!aAX*2G#JDj z87^rze=%ai{iUB~`rz(F2bHCMVx{%!{{6oKpVqG>5Qt`*&3X$9*1WlP-HGh4rOoOf z%lx8U{?5*EPK)_JQKO@(PkDsDE4vH^hTscEckZ)$mY-WMC+VgEaM3!89fqU40}e(pC)t@$3V!Zv+%!+JTt zV4%+*rfEa&Oi?X|j+uZ()KCG9$H5Q%qyI6~p@-8Ud+V$3dGY+-|4>0uEwZa0RW82h z-hUr`>S-lwJ%Twa02de_Dffm;^(Va@%sa&1=9H(#??3UwtB$M4?3Z1=jhXdJcd5)< zN7Ol&Lol#Xli%L?mRGP&zz#R*O(VFNLW7TH1X;1uB6zB|TvLAYsJW{6u|GqPBvYICx`9-(F_YwI-f^j(sTJ)bj{(L4dmY0>K3pVWj z@})7CjA87nrp&VTS8w&6DjKWT6W`r^Zjr-$m)>H&P|h-Amttu7BUn+4!3+~Fl#E)c zD8ze+H2NDw+8sOJP1Sq@R~SGRe0@7y(O;gsRe;IWrSI>?X8 z9bEX@*H;fX{+JirgV+uO`;$`c9eGpc%7t=FUsD{8Q+TF6r;inFuwe@OYW}@q-7w}F z=fy*+Jdb{ms&tu0Dosv*^xZK9eTOV*ia-|&a|imskP$5!gUwnK@dCR;b_$`jua56` z2CsZKYbVtiZ8~xTUL@_loGN{D>n~$E>x9ad_5_@u?O7v;rjtklpH@P+we}wbRxXHC zPY)kXT*^K{1*=QuSDY<~y6II-t=KCI{5O;#3BNnu>PikC71!Evi7NP#tr%sV~|2e1&B~Mxa2zL6ztn17C;~{AmfTTWi-m zG3SjD04s8B>?N8JjX8HpgK0kj9trrnSv2|BxxTuZwGNwJqIbC8$m#T%r4ubtJ}673 zOK>;{y`dNDJw=nX=af^AzKoKTDC<4Xi7yz;nFJfA&c$6nde08+lXS1zh7_X*aKEnZ9~qw{CkZIU_a zS^LKLqs~ydD@t6tsG`(nFgzJDII?Roiz7n}B?N_xMMhnTf}CtQ)>2#d)w)l|Y<6Ao z&6V#~{@Phk{EywO9`rT%D+lMsOQn)g4(Y7&vz-K1U%ouHAJx}QU{#)>DBr8nFpQrk zk(IeCZI*EP+dD@W=iC2k%E=ub1|_`yNDBU3;HMr86%~S@{199zxutL8f`$Oy2OaQ? z{?juhKE+iMsOjiVX5avZOdtgdMp&M|@$Tv~tL{C2&0TA&O^=M|iRr>a<7(74pFii* ziwB=@!U7M;Jg|c2<)aX)CFh_x6&2tlGA!kRTpDj~T>DH( zVfW-dGPtD+U;XNB!BITEzO|kEhX*oK!#N4aRI9&3hc<^sF1UQ?YL%80qdSBnlf%Nx zOY1%ar%v}Q^h|~*cw_=A8Z}e)-JvIx)F9v)SrEw8>zz_Vj@9lodZgsrY6xU@}!*&YO_%J#k*9gfJ zmQ&C+U~;f-$CB6HdUFJU)#Sw$*V?Vtf7GI97RpFYWaNOx*F zjd}9Njy?}hG7|QKml*7>1oG~HACw}%;{&My6+EEClnwn+8v0YggPxHD4!hcfWHYeK z&pGAaj6Gy|WJIr!i$fsA*ne<=^QHFCJ1QTgtZ`g=?J4hs+FC!hS`37s2j#LTSE>^2 z1TBaBRa-t-F}>-FPj0T?@bNv~%FWLP>ucN0j;s+Ey|tBeh>UE|=-6!nbr*7Tgs|v} zhEYf^&{-hm`XH7Wo8of&oJm=`Nz&hHeB5!U^4m03p1WxFFy^5 zYvLPQXNGl-;SDX#+-oQeBD^&IrNLKTbm|hUy|(H`_N=Rpl4D zk}{^@Q@&^{vcsmgoMg3HS+uc<1JFzEo1FWr+l7e^Jz z2vl$IP6?eX$rdy1@CD=vU`-b>0hK9$g!M&sV6&3Wb2Rk~Mzo1=8Ua5vQLo?6gLw>E$;OC0tm)OL`b(R*+8 z2V(a8oPm>zlmB=Pu2?4xWqi|%wGG$&V$Whx-jz7gIl^` zdCk36tLgWmGuzVa4RYY44hxBlcU~%kcL3_m>2q)@oH;TX^%7ihv2e2wi~n0c4!Awb zTbo_5IWE>MxvOXM&HC0zHvf8Wz z9mU1N;D3&uB>;S!3*cOrC?@jFf>gPw^5(f0^qalEi37q-s_vCbt8cXG#GEg8)s=lV z?c|D%7xnwMd(9X(;){eWCxTbId363nl;!FV_i|q0@wytT8n@2#;6er*yqGOKkU8BzEH3>1VxwO;%qN z&5kLU^kN}=(y$#^2k=0g16avo4y+>^cW=M>{b?g+^RgcQu=vKI{XX*P?Y-Olfw%$s zd+JZ9rV3UGI~Fj@Ay0VShHuW@a`%|E>Wt9dbXyIm=v1pYR-D=vSANn-(a7(inz%+Wm{u=0u}*DrA$iAIV;*0OU!|@ zyoTL7rgwnVZHw*Gj_$WCVsiFw^#x*jbS9e3;i)iOzy(6bW|Z_HckJs8UymcOqA%w@ z+c`o1K&A@({w4phOfrqCI!h+K*vY~Xwb+c?hnf6 zWVXW~8=@gr`{g&!J@xQ2C(gZS@Rcf95pWQ#XmFDrN%@0wIn)WjAZ+-bi{6`kR^bS5 zRl^pu0sET*$p`c+8bf+IA^uQU^o$%b8V)JhV}ao z#U)w;%&1yC07kf+_xkuj5AWL1v?=C*b#GzbWkUw{|M150+J90caDLAvgAtn6B*0gi z*U?DI0Ajhp084sbQ`@d>tFra@n!w|rQE&JKr5{G(p8{6EQeJjOYKqa#0yt8xk43dN zZ2fY&A>8gZ!$mBqB&a0>6bLv(#rV*7EuBVb$WPQws~Zj zVWB_dq`0SHfCI;ed~W6^03MJ8>YZ5nJ9HV*$2v)7MvQxO?nMG76>k zQCc-n{mG*wnJQfR=8mzyy!YbIErmr_)dnJ|HlLq1uOLM~r$NUE>^R{-MHc#Ti`gXF z;r_XO+s;)VuUIwawabp3#@_hdmJTxmD9X#ATqjx)ppYV8`4bXUClV)bTf7~Mc38tZ z@2|Ng(e8`tjL>PZQ~}lXnhgyW#$Mh%`|YKd2kKjWW`hKyM(nSOx)8`OTKuKk+5(Qp$Kd%1mzZ@+DA^Rh+rHq?iG-pwX#R*Uz| z2PIF7A8IZLE|9r~F|S7v2J8Ht-+XztDD zEUtV=&MLUP8b+t^jLAJk@R5az(v%u`U2s}Wtf9L4&Na7R@Mh*3M9LSX@EJe_z#cZ; zu)OMtK79(`jaZxms^Oj!(|Q7sN-?HX5~P2XaY^*RR5$r?Pvv2Mz*tj#+r~9(X3V)@ zK*{=hFJ9`xj2wLcsIHvj`F3-I)Z^m@MhIByT@%;2+ug4ltN;qVu8<18__zXWjIdG9 z9=ZPO+RDoR!2)iWKhdk9`d|#f+Jx3X+p}$dVh=3qtqdGx#*5OsR?Xrd^u}dZ%?UL% zR@u#ZV=SIbRJVrXhQi#@xBbtAcTsc_W{tSt6*JC!D(Pul0{cCQ#(_#8(yziPV%)F=T$qtdx0`MqawuozJnpXA<~a!;W~5{pv!hBVD;);j zh_U%s4F8wAw((1=1+$5K`+BZhglHI#>+`bAw~RRUL5in(D5Y}}*%dD9OLx%cpGRvB z$wUnttz6q0O2i#GgYCJw$72!%a&L-%qySyK?UbBa4~u;f&*PFKxA>YRyRTU=aoD}J zO)ZbmbM&1~Tp8UvLPBcPta8pV?cBBPPJOsNjENtJw_f8XN(DMJ5NM_<)AD^8anY(h`hH>VW)1LO&3(5_#DUmW=ow`RtA{Yxztf z#G7w>A+A~Jul3(o<^V`e@YGd2yzZ{^%BKt|emAJI=hk_AQS8b9VC{q`&+G;S(ZVbTH0rUyPXk;dZ*YX${lX~i_Uw>!H@ZVAz?#4Gg^k~p3 z91j%D?^gb%PmiMVu*ErOce4lUc#~vI1)VdcQbVT;0{9L5)C|7Uv3%7kKJY(ya@A+v8g~>rZWudYFGb~DU?8mH0M=aJ^iL7+ zg}U(ksm@RyNmw?SvSd5282|d_F$9|Qp41AcVA#^;T@v?2Xaa?=A4CMn6AC38qg<#~ zn1{?}XAp$I8pgs{z$siv`F?uCsUM-QP@2pXYLQ38k;M2C^qZ}JDBT(lc>kPh$1Y49 zu#_g#FB#!AfTpq_|B<=o>A5~sp-Y#eLAM7i)u402yp1y=qV@D9pEm*B74OW{6G_2q zvsh#)&|0~4>d7hp)Q%+*e#1Q+h^Rm7*V0GTjxe(qieQrUhrLEDRCtVitm9RxX{YlJ=oAs<`Q7#wR`G+VyaLUtLpe?!j#E+sr z&vuj10Jccr%6p_0IUA9F7rYYq>D(Azh8T=sVCoDd>@SP+s4g8JCAv65LwSj!`dB*c zln3F4_6vvA0tLLXoQe7`edyeNe>^1H2VFMo*n5Z!o%D!Zh%R{7-8f(duN(s{Z{9|0 zDki8k!$)1bq%Zc3{d;NEr51u zZZ+m@X}Z^nSB{Ai(s3%}!7uuxSP$Q9iKKK-$=r{7Qh&qur_0f%gXR9VHh0D6G!5%w zuH+e*q{7zny}ZHJI5w8#woF86G7yELQBL_=SFXDGtXHTF>(h&852-z*H(Kw4>#K6LvXNl35z!Dod;i-Fl=dZ`^pqrP!wdHD^ z*?uDyON0A^>tK$k&@@5o3D8S8%tjeYDZC$k`Naf8ZzC3-fS5q5taKDtl3u-N=dT@3 z=Rf?Ck+slnIRdZ>>1m)7=&6BvAjz3z!~newI82tZ>tWTh%U!*~9T$(R`%kEk+bN?g{)V zeT%~u&Plh2XbEO8$wsr`c*I^>!b;Mbw>@c(#53YnUHDkI1Y!Bu7r%HV*I9IBLrW{U zS%NtYJ{F)QcH52z(aD@roVctzRSBaj(WA>D=%Esa(4RW;34e;z>Z47aLtyL#r z%gY)UefPa77(_%9JvpJLifO0R$d~6ZOKDY<%jA1XPrHI|Dz!anY6M>L!_OeFvk(kWsIk$8e( zot&fhuwgeyJ&OL4%E`NfoIgsxQE_qcL>-eFF^+WJX}s ziQXk8B^;fqD;vIucs(K7MvYe;v8cXe8qy9f%aEOW+N3m>MNS5(9_6c)v>$KY@hQYY z4;WdvPf0hMB2XU64_#$E;FtUkeJn^W)#>G9=46+OQX4C)x4Lwp_OJm& zpjm0UN4T%U64ClL4~xcyUyh!${%F#d9wyG4ia0Ex+X7bkNH7ox`3CvUknC^xVxqaNnM0izUP3aCPV8AJ9X3$EMyIKMf0+|$aL9kGaYzGj0 zp3+-77O~+`3Y|bmhW+kVkAEGNadJ`a9}||GYPM?BIH14(^OS) z=SRQ3aES|?6)8LwGX|_{eC*?%H!iRK+>lp%eMO5mf$}ihN%}d;SskhTqSL5LKjv|W z7SPDECZ^ZdV{gBzra-tE{?G$3zzTuAYi(_ZLA!f<*oR#(5O|NKlOGuHC5MWsGgwiU zt~8FUzh_KUDju)GZubO|N|VxMCgC(N0ow;>wqqLIQb7(jXS`_*u1hQ9;mAfzc%j`W zC!IP?5rq~VIUUDZJ#M0BaOv^MF2T)&O zP_%sZ%aPTiUfeJ^Dd?`RZEXj)C&3Le@Cvi}Wb%N~9L>+p65Vx`&n~-u#6K})1+q6H zJq_)AJo?oQr`>c+uQdrr!Ew9b?LmT)j(c$E7@TO8(p>e>F);TGU?mQsCE?@_+kY9v z!fcDt6!u7o+KTlJU#+|UnTH-d`Ps2YojU)Dla%E``vIB5+Huv<0X-es?4{2R>7u9% zf-O2BQO_TO4=1BxG<*2{9t3`AeTu5b!iOlfK?dK2_&ja;H{Em<%+-fHb1DMwN&p7| zlU7k88!SbO)&Xuj$`SpePB<<7sQm9@ptT;(3*pg0>Ax5^B&Em=t?jg#$W>$KZ5XU@ zS$k~a{@cXqmVi}~R+MJz&3A+(TXqn#H`ix?nlv8h1>`tv*d8JHuPv_YD@(XJz#(pL zmGMSYqfvvbpBfSj1cWF@l;l{DwFkZLqW3#!geW711{@{kdLx)YGFFsrz0+FU8;(4U zLZL+`%Q^8)wHFGBa;$QammWlle^0CIy(Hpy= z#4xI8%dB+%=|RZLQU@k3_M^Y!!PE0&${!q@@B z=fjwlz4O;C1eQM?>)(M`V5C@(Ul9!z;wf!}I0-w@gbwPItA_MdEP~VTd{bJF1yxsj zItfq1DWNt$eN^vd-o`!RhzTN%Z1BCX$48hotD{o<`bhqPO&g5|_SA2h;t}89ofadB z$Q^nB;aI?H?$bi(yKipv`SvWqLAN8LIFrF3 z>q0H~*<`q%g`2|0!fSPoL;iG?es5{kudVFTe)_ z{d9~9OcN{H$4kLL$Qau8_3Dt)?!BfxAW*v32d>!J2Dt1u&qjBo*w7Qkw;6PtM}6JxH!)A?4-Uj z+p5I-IsMW*r}n;o!|6|ro%_`XAfZ8JOFlLs>GHyU*zbs>eIoe^XyJ>2uS>OX3m}XKK1k^66pJ$WhUmfm zGB5k>(qpbaK&da|KD8r3GlAs*D~fmB;vIiC<@LOqJU*ZuWKV|OPmn2&YToGI{yn-F#qFmIBwVAB`mQqZw-xz2Ngh0;;zitrdsJd#{y3XXXNUkUG4|Wm>rwvZ2ylt#`Q{~HVu3G&U_QbC?QaR*pp&8;7>BrcN zcg+8vz3%|5s>uGnua~^{^3n^THwA2N#LJNCFbq_wqg z3^v4JrC4n8WsiqB*hHGms!jU$yj}71h+Q&uB~$|r4K`o{Y5f42-{wA@GJ4J#dg5HL zEv>>p6hsiQ1fGG2v1a5Mf|dRYr;hCU?4`x)N^REku0B6VYG@1-dDI3X$-K18>wP*S zgqJZXgdfp>)o5sIG3n3AwuWxHZt|wL$6wm%E+mf>7=vB)&JF`=K*e#H8J$Je)R!p{ zx$Ycz0(o(K%Tc_?KV^1tD68t6&|vmdY+bcx<;wd?9~&YNqOd0ghpIItlDviKnOPaP zo!Mok#cDmJ<98L4YOCu0^ZCa5^^&Vkt+HaKWWK+Xj4>7Jj8!G#I&@Y6@a@`F(h*^` z&3E3SPfyjwyjV7Y8k_he8BsMAOtlYco0+Vpu890Xet@?T67i4^L;$43RPx8$^1qDr znyv-vYI>%W0W-nS@-|s?rW7m9Ax|&Fp#;A_RS;AbsOvs`ys;Y|c{SCM_JY?R1j3Rh z57-aWQZ^iNW~Qga;x_;`&nheP#}L*bc9f<)gU}ARu|61;h;2nD#2KA1fmJ(rxNY>- z@7eq|^DKnkP6;m#DPWau6qemxSn578e+NN5M=CZXrK=w5U_KaZBRqNjaXHLKA7Nw{MhG+Ar^;KQcdTU9c~#h zt^Bml_f!v@JM#274KI9sS=ZxF_#|#fNr}XwicNQx%&hU1KwcbvDwV~uxVQuPbSw>< ztTo4mWpA9fM#KYN{7N0U*EmmvzC^5r|hW-Br|hb3@&h_4!*l} z{%%d*%AKHC*2NQvZGL~K6lUA~EE{5bT|-oAySYC0Y3WUxdd6KhwfqTfGU^86qPLs4 z3qo91ANtm4Y7Qp*X#jG=H(<3-iuCu=)`(vlFMsBsNBbo>lTbVVlIA z7Y5Y838fF)^4blD_H`WrLndkBg> zL`m|%A;ShNhrNRM>9I@Tb0C&k|hC6#B_YBrmY>W835UX!0=a`gM-+%FRe?$ET z4zm#hO(DCPq5Qwk;A3iF306#_i^ENrK327J$FfC>`U6=#ibp|Gma=IWIH16_&?WoJ z$7wfA+cwsgo^kV@Y9HJ{#FEf*kMD_TlO9WIelRVkr#8RENOQ}UPh_=gGbz1g%V{ue zJgsGyPTyqOO%ImdbcbM(kw1+0SO&H3*5QR)XYF`by6uZ>AS)`ks&=dPA|6DFpmg%~ zW7o7CHg(&ZJx}U1!;)r`_H5WNCs0#0*NRnCPB=^}e=?Dc_;5{>C`qer$7lSGnsu@) z1=>P*MFEfkB;_3$R(t{BCvgfaf%2f74Y0z1(|N!qMl{yrFTP^cAi_me_4%V<^nV9ojVcr!S}*Bu@FsdP!f^Rs0;t0kC0&f?3#NTMn;D+BX+ z!_q0AjA=LT?g3-3ow9kF)}HhD#u{JJ6AUGU!m5m|M0uzZ>m&~++@PY|K@!h!I&>*e z+4S$+`1b0#GtQV))a~3$PU_NT_|&b_ZkVyNIy)z8XgG+4M|=)D4TF5-g&2AQ8PdQX zEDLM0QcSvrvNaPvxwym0YahL0CMg||h+0)HB~w0qVrRd%{G{8j>a*J3y3NSyC?sjH z6s*OHC+e+(dk9T16i&E3zIbJWFSe^85ZfJyCM!a*WMy0%tMkXCiVE%&DDjC3;d6Zc zV7VJ8%2Lqs#(RdJQ+DltH&QSQu5vHpQuL+-@^X@$v1W3Pmzr|Cs{05Pt9On(}wG!FsRJVBl6A5yuvQs3qaXRD~{i zBh$@MHlg$Sj|jh<4gZK*{7RWFc@I>An=%bC>-ut^gw4*}=OQ~Ah3VH=hSRCH$Lpuf z9@*nUK$m1IbN$s$sA|CX7`L=l+Z4y@oqkO!WmYZC(ef!*9pCoM_ZIiJYLfTNx}n!a z()h)WYiyZ6Ml9)_w^Y|fAUz>>Ckg_4gd$~d%GYRa+;c2p`$;l4&87`iZ(p)u!@B!6 zxrTnv%3U;J?d|P4c6=RMwxu0aHH<=Piplt{e2`B#;-5ufVIgjX>0~=_L*=G5qo>{2 z+l7=;A&^yxj4*gBwjq%s$-@fUpdQEn5KGI+sf3UM)=k0U3M!CDi&YeX7vd5JA;8z_ zA~~5>Q%&iH8J}Ew`~W1<4*zD$za zYtoh7rpq~^6tu%=)Z9h235Cj1pYeRjN2|KGI=NL(PQ-=sp5dvZvLT!t3&9P)}(oe-{7zXqfljl9V+xg5dcrE6^mcduIOs)Ha3f;?-eFYWDdp!msVUmVin2GS4?q2OJZK65clCnxD;l4M z3$CK{jJ!_%a0C=x98OIYR#(ZK-3BZtWn(dC3btMQ8gRY9uu?#}f!jxlnTFM&lS%0z)Bqih#c^6hYyU%+CsRp-qB%)2F3c zO?4YKuLrU!Vx~9F-0@MHlUokmykbYr>IX0X%SltWe4d)0du>faARL0;8O+`EZIhAJ z_pZ6S=X)C(-}+$2n(qLMO1z2^6uAe^E|itNSu)(+Q4`L{w%@L`+hF@R7(+)Co7M?X zrCDX55~h1&q=q#3j7GpGSoPRdkc=Wzyr9BgK8r#{By&^a7(vwLgyjl<#n$hWmX!RQ z<2$rFDG~c%@vw2d07HLMU0KMVB-E@c5ipI0eD4|!-r<sZUM1 zuLDT_rn2RK1bF@ru!J*Rh?xHDqjDeh~9ZNtboE$fW{bzKyqSs*wc;13z)@alS+rCTFmoyhfVgKZZFda ziwj~P;5l1X9u-V22hQpss1uNVY27=^o*}a8@yW)_D<-Wy>-_f@cVwzLx1G0Y)=g*q z1KwZGsM)yUQA@DCKEsis1B(RVrjid%>`mDA7fZt`pw3(CSuuZ3A(0gY>jFW-ADx_9 zJ{ENuB|6~Hn|nWL&M)W!YtfR)16!+WmOZn5$%5O%J2x*k`WxfvRKrz^E(2;2rf@*ovvS3U<1gyiMLKa@{MOk!rrYyc3@xt$52lwl4MPT2N?w9-BGe<;RTk&Rdx zg~7&s#8XK(}Fhto8|B|5<`MUgq9jIA0qNE`qfY$b`Yc004w8 zOg3rjeVE`9+95gr8kbVSP5D&+`2#|;r?849LT_h?6dyQlY0qF>*S*p2qw#z#0m;G2 z8Pj0_m*cOa`IxY*%CHZ$aR8u_{4WL~?Dx@%LXF;X_m;|930mbs(-*QGY`uv}xklry zR~E0yGZ^iz9iEuv3HxI(1S4!&9f+#pU?Fn_@-9{Y@6Msh%^%Mk+4Iq%lgs`Ni@^^_ z8jI6rb@)eqvvox%8k+Fw^K0Li77b~beQV(}()qU*55Dc5FS2slbgO~KAKKhvuK@at zr#Y;8$z9dBU_r@++n>F05v@5uuudvcj8pY9WpZ5;Kkl{pozgPW?g_)oPyMFSH>V8i zIT~qzazuEi^Zhci1+S61V$t0t8t zQEv-&-Jt>@lw>ts+O~K*nVPN*d;D>Hr=r%NARE4bK-!6}v zB|%|P^#KAuvFW`DF$tu_448+KC(abiP>g`34k=Y<=zYQaD|AzaokA-WPvkuCuP8GX z3lzNgQw5E%mqpoUA{_iE#gW!atT+J%02_txT3;xbh}s;jPtEPt7gWJyI%g@7LHfHw zs@Wqfm0Sg$FA8d{m>|O#q!4-_urC@h{G3QmFhFGzNhQmWOW(>20g)|}br?|k8wCHr$Ys(x$NtRkVc zeQLXczXm*w((+Yn2CsVPGNHr7l~bvBoo-@L7kau`zFm@*EAJ7WM1CUl8@r@kyO}#a zHrwq(Ll8{Y)cK=2XpN9kGiY_KPk}$hHJi3B>y@38)LR_77*+v5@@gnlOxJ4+b?etm zEh*jj+NM!OlxK+z-HMJ^T)OF#oZGKG=Tk#={>haY|<4HMw?y7%3 zs3iJxo>Ucwsy&;&%rV+VTa2cxNF+iki_!=JGvUKpjaj1~g1gCCHH9ive^-G0A!OYl ze<2YI$j|&SQ>>W0FK+-@3V|u8D>(;lUr7b|s!v8{{_wX;%D6IhDEpn%rP<3ayz-f_ z!P%wK124_o2BT!m6Ux!-@<)d7g^Vf&6$dE_J*(<^TccsQ% zSqH?XgFdLv7;2Q(EM0h+jI5G|w@-!Xnf(Qj=`K)>-2dqI`U>YQUT_wX62-IGIB$g^ zzn~A16;_}?St$VBdtyG~$NG_UiUh-}dA)m?ta<`*y;W~C_6WnI0CY(NwJq9&d5HYf zHWGJyRm9^lA7GgjEeUo~Z!)!F6b1P>aajI&15_L+d@ps4tkfnWQ!wGe^o-0Fayf(+ zN$WwaWBcX>=Zu|~B`8shx8ECJ&6>heh36+2^Un=Q#`eCDKM8kQg8UaqADzqsQEe<3 z5=sn;x!a!)#-G4cuuLF*&xITbZXj;kQC%-VdagJzrFa)36Mq~u;N3MQIA>vuJP=SS zNeTRM2nf*$u1ImIfnyD9lRgGT&Tp5knR;d6*~0=ls}zm}q9(moZ1zQZ4cQ<%eu3$k zXl9DVkeR0W29_YtpEm525^2(NTk9^mGAUQ~8Nxza*ncYqpttb z^1?excCB~U);|qhUVVzqJ_s(qdgvX_7G7wqx$AvG$c|SCMZAnA1>k^u1SA>92ZR&& zK^Q~y3xu_^db1cH{oi@?c#Xl(9|pi z@0K2kw{I0y;q9L`sN4)xPd+p09XDVtixUd}vFl%0Buzvdjtsjtaz23c39Y7-D3j9f z1+-?3u(G-oD*a4zc>qQ>0XppM#X2^+D4380tP$wI4%Y6h+9sCLRg07d176p4>ypH7 zX%^eFK8?*1j5Y|l6gznn;=#2%bmZ3Hh+svUp5s~!3JfozGI2x%#}_J?gtZ8`Hx6%> zUcI?eI&V`S2=S?sfbqz*%!}g^WC;oZ0yfkILQ#X$VaQC6eIQ-<%8AmqcY9{MGjsga z4`;s^^ftax@|WIYNF^yUE0M>34^)&z=UT4OY{v7=E?FH!AgiLHB06IS64u?2*|puZ zo?VUi>MZb}qSIq0g=L6HL<)r?iFnWhnNU(^fVEbrd$GotMp1Vbh`gck4{M!%$-2mCL_*~nR0|go3{`L$rg7%BF1op|?EUze-k#Olwq5hze@=LWnGL~y zK%Rd!D7b~}u?rLx7a_dg)f-cgOlqz9P(@bql}JsBPV|34p8qOf{{#up zci3O>r7(jLoou(5InD&Ic!X}2w$T^BB2cnV;p=m9*}o`i_&p)>yB2mhA66*!7Io`t z$vG{mF}CrCLhM}v6Ue<&(wd+`6^}-Q?evn-CBOPDb2x(_7cwWk zPqdDR!1XWgRa7RYl4oir-usr^ynGjpdEs5)C?%6jeK3`pp*q0!=7SNhhrM=CFP0H- z?w-Q^ZR`HpzgSxRZ&^18h*qiAA)UA_iQ96x@^k!Kb35KVeOpORhfbgPEY9{J?8t@? z9V-k8*qun|iKGBL0Y6Ilu?aE?bq5IgYkYd2+pWh2W1taW2aP6zr9?wowxMO4f-5EI zy?TG6yEp~giAeGCYt$dL=(R*pWWLbX0c63-3-}-r^MidbO%iO~7YkNC9`XmKS>V(I zhNB@mp-nNZF7B?Cwr$%XbnCcSzz;8cb51w#a%cGc0W_QPA(8c9TT)=X21Lr~dVE&M$}_q!H$ zSRd9~POXjU28J|dbZ{7yVH7$XxDv91T3ysvxqHW^IgBom<{orFQ-(vXtj~KtoD_~} z23EpA8Ta{#2?Tkvd*g&4ZqTviyQZjpZbg!P?s>`NG6KWM#R>t~$26%^2aAXm&ziDs z8Z;tr9I)EO!JhDiV8X`gXnpx7_fbXw?y$^+_XWqLrajcNpe8A+dw1a}=X7khB%ax# z_ZI9U3P48!I#&=)X*F2+!~`ltQ`megVRxY>2F-O%R+_^Q+*Q7D+`nGC08cC6$B*A8 z;7h6|NT(Jlw%b^jg^QN_GgP%JVlwDpyNhUu|73S%coH_^T8URQ(UUX0Y*~m|m)&QHy2>E%rm+I59v@ml_Z$coF5Gl&S zh4|+|F6Ec;%s~zWIP_+*9UZz?O5Cv%#*s3qfB!<1n8BPk}C#`G7KIY*gS&hbvA_hA>$%qcG;3pZBEP(x8zEk3q&acD@q=YAEIFS^CQ5_v3J#1oWLXZc6 z6>Qz3phF%M%l+8Ai)Tu%VuUfN7}Qi{ikVGDZ5G^-Wf`$i8lw;>>NKVZo=|~~qI@ufhPt4}_$F z?vxH*f%OJYZDjYd#qWN6QTy&aFB-5}Z_sy$P`E8vT1wxNT3BC=nKN@cUNfom){1|P zEc4aZk9XLxaTcDd#pfw-6rcRFYd#lgfYJ5w81xA$#okY!FSsWX3<%5($s{~e?@F#% zS^6YDxev?=32(%p)XXWiVSX%CArk=@0$(kYO~Eo*BqQZB@At-wGytkL7KKbLxRps& z_hG#L(+5oITrGsMM<|(y%&?hFnAO-N1yzi3sL?cHVu2!a;fYWp6|3^UBU{)k5mwQ} zVo|R??|t7HeY2|<+em=0gbaus3f&KaKgcJ5p_w(X2J{#1f``F3`KHJw{J$AiihYhUzuT-<&Y1xaX7+ zy>3Q%fmS)0{dG2{8EP2R$AJh62nzulDD{n4NJw$mA3{3a=S3&pnQFBfxqXOr zmGQVhC-OBBhyVcE4eBV|4;iT0z3ZDBo}J9}Ggfce2Bk$ev^X@BP1fwJcygob%B5Uv zC}aYJD<>?!(wLfdoG;+VS|e6(nVI9kxVFG_RT5Z_t^9F0@5-eGzH3FOm1`+n#$--#5=q@0_!UPXu0k3iC zPdT$YGg@?bfqM427cZ#2T}tM_@`66%g+4?e=rLF||Vv^*Do}Gp&${ z{6*zhO|d61o^G@1OyNeUar3rUW={U>WogQ5+kRSqe(i6eu97s96EA#w!O7{_+1J!= z*;2E+Y}2T@_YV93`3n|^wx&QTp;l4qlK_P>k4?G`rerLI$hl z^aR+!xGyAcGzX<%B9P$=zgYoq1~CKCqkk9 zdxG^B0oWaFA(_Ep?yT7Lyd-_oAkxfTXQ zP0x5VfJNd&Jd8a_a$Df2{wwEw?*)STS-co@8d8n^KvXDn|4~Yi;=7ySK^3p;-nnH_ zi}tokv%!=rlt|H+xr$3)w_&|iZ%%~zp!(m}WO1aSiR6{Vk=fWFnBw`R9q}f^&SLbnxso!5sD?^kxfo}3Mm|!g_QfZTmVZ^?$yjV z=oqa&ATyGQt^WFk9dkA>o!7@#yX$Wbs~KrPXfZ7l1M6Wi02$&#>o$QlZ=pD(QZpd83*6Rtvp5w_15iLB0eX?Az3EoG<|I$1!$*x#sup+JWe ztlm@n(FJX~)vj6g^3Jsz<~24pR-W_P>=V~KK4j5`r9WIQHB|dd@Zv~iTLMEq$!Ed` z?H9A#QgpuE<%_<(@vK+zT<+|SRFZHl>eg>s{dv(z)TRdJgd!}wd-L+j39GJxu)iDh zyoACjpZZuo%SWqDV@e2C_ z#VuMXzJPA+D27qNh{;IuLrsOwS@=pxp~MO0cL~jp!a@h81%-Uq7%RM~pY9DoexS8IS3W2DBYi;$xvXYZu)VdgfCmA*q-hTK`nuB zx7#fG;I3^A6W{yvZ@4X=eEpgC$`IXq{Ndp%rgWLMttzQE*dWJ4OA3HCC5S^p1xMF< zO~5N{-MIO2J~;L5W$c5|UN`oa%6IGq?f`Jj1qxz ziLaP}KvX>Qh9~&}5v6=DBIS5oVr0Q*r9qo;hu2DL-h`_#L4C`Umw4mYfeWUG$_rFhssM*wH;p@GQdlDqV}$A^}-{&3}Hqt=+~35Q_u z4(-A|&QXaVPRf1LH4<>_(WXG;YPLloZR*U?hyu1pJE0 zD3$81#?+2G;rRs-Kvo(!$k6LdA$MfM@`aZXSrL)IDFl?Xj$j~$#UMl{5^^w7Y|4h? z{S}gg`hx&1-%(8M7`n7;IU$;!@2qZcN3lK#-c~2+d=1jZ)oVsb)1E75z2W3NPNe68 z_WdXzNx&z0{gh1~nR8pV-wjKqkP*^~!`?ClFk#NwmSU)0yZnvC4_-V=Af+L)=Ki9a z&LnGiBVUl~jJ%=h;lgZx?dX9|>9Pu1x$El1hH!bkk|_mxlG{%-qPWDT;1T_TV8sJp z2QFrxdf*YZSxMe-a2|6QT_RLvgxrny$ASz2mCK1oyz^kZ2@|^xGDAVvVtrYo2|-R9 z(^xW0mh_YH#>_&gL|Xy`ceLS0EZVGsD!9US*+R~MZgNXrJ|&evG? z8q2HsQOrVEZSqVuCaD~XwnRL6xErDy*%N6)awdFO#G}A1yA_+S87&u6HMl*l~v*n2f-lJv`h< zIe9IF46J5dwV(*e!m7yXx-ZtfXlvDe=pG;|DvlCY5q2v4Kpe%eKh5CXv1R>N*PSku zV~f`{J!a8zQm}!nv#1v~sGs-N+;go?=N(n>?hO<~1yzxhEhCx>_o8ih<`W#uNSG!? zHD;*MbLWA014pjtLcdEN_tZ+&6?g-)^1w+mMI!& zH0X`cXcd(~pMw4#mg(c+!0N>hUL-746c-(Rs(>*2KNrxhLY|8G7c$HhaG%H3UD2O- z;9v@1p$T)ysrAZaWsu>BbskJ{8q(>X>xS$uMaec5Iye`inzFzD3aeg5f+Dh3T)}U6YK4OWRSG8;7`g>PBI(QD-t?TOxPVVZO2-fl^fi0n#sLbxe|9i(r zy6o0nYJ7pHU@-|Xrcg4+i71K@qWwtKVfP3WLSxeO*QP%g^ZCApaYxEMg-{qZNdj?7 z@j!soRaBVUIS5k!NzML*H#IO-#LrH~qYF)9q~Mm|#veqovU)>OI-$cW;~m^t!M<^{ z!PKk}7Ufs`;IrSD-v%s12h8ZekVW9y73vY@BP;%fs0#_mpI-|y!V$SMItg#gJd*1cDao=Vx68svQCMt2X4$2Bp?L(LC z4*45PQk|(E4nFVP?Ojgmu_CWyXK2J13~h)esCHpUg(6AS#?`M)8gg=<1@{d25L6ZV zsU}Hhtc7oUf5wf|wyrR>>Ns?#+Xq+5!WKPDw+JjEI<-J1aD1EPuxo2KuOC0__P#Ik zvo==EYt_AF)|{3d+ML9DWhUn(WVgWcDC6qlH7;v@n@cO|VaPCxQU2`frCsw zL-8@0VKr&8b-{o=ShYq|zjZ=o*^&$A+;+}jY3*dJxKW6`S1zP_9jT}&Uy$&-{j^^t zvmiiLxUg`qi>KPRY5fKv_c|1d5~4~+@jxmT<5vSKr?1SIIlFLAOe3?XuDs(qI$;m-MBb}%ORkurZn4Wg{9%wY zuf?d{9;j3#;-amH{6rHWJtnib)oj!{;vp$T7aeR#jX5X<@8;eX4RRE^F!YFl-qgv{{G%B;*$ri=ni)Eo#jyr;EG!TL=rr}x|b z>LV+Dk}+7zpQ|6ZMxhQaPz_HFFYh>h)kd??)ZGgg>xk8%@^OdNs*l%JeY_Q0Sd>*U z!Jhmi-#_4n#EDX$x#f~{(pk?=ywskabv$P9Yzt!2q8WhItpPxETmSA`}LIQ3N6@=$jdQ+c#}49&*cIM2gkW3&zYj+hR|>rxqrs zZ3bN~6K53`CS@zCnrQ!bzCS-JKYwB^Hcny3Kmt?|MCeE)4zkj%14_5h(DzQCI(2ye z3;I7{O>1#Nqt_d=VnrrWQ{kPvY}p6QH{kQtnqet}j)K@AumvGC!1p5_#Sd8>h8g`? zgOCrqqz%vBS=almAJDgr*|0%If1pZxU_k~F5vxW+jrR|K4+Y$2MPao|+bU)}knksk zFy`6$6?{V03i2z;iR0^Vh{37;ESDkn_9ZfHW+~*Ub*adT@-KyDfk1daGcpD~%VLJHXmkxU7t~pZ9wPMGkVmSo zt^bH69vTbFl)q0P@>RYqxZsf?pG~{9k83J^Kvtil27cB8$Vxl-qa}lH{C3L^>Fqjw z5=_nQR9^3iK?qLFFI#CPC<#R6jEzar47<$`*|oKz_?o|;FG))(Nue>noE8Nyhf>nC zkqEbZVE#ZTSX2S^j#H!OzBc#VmTg+kXf&njeW5752MJR&Dl&}2j)RT6tld@74a=5Z zQTOIuUtz1&ZrXiEn?_+uTJqM_zV3PDwld~BXLH3)T|DN7>YRkWqmR~C*GzkU?5BLD zngr(cv2Y*=DEkWW7?O?EX7p{2L*B8uAs>LrZ#sk4bz=_lWPWtzSfazQus=R<30_v7 z1Y6Q6h`nkMS_=U#1`PqEF;ZhKnpnfSs_f%0>rI)J>&&kP5@zT2I&Z>4 zM+qERVuk?N6>@;sCJ;|XTV|vilHRH%^Y1zT4UunA5xqzMDn+C!*(GC+E)j5#0EPh40yy>w>F;CZjjKDS-RHd8&ORH-o#jA3GFLWazl%a1S| zsI`C%+_>zAt5>+Loh9Pqu>cfyrF3Yv26u1WJayz5&&f5xv1(@s?zTgmpy0Jk3RSx& zN}J!W5w^9^L`~_AT^tYs>Ld%+d^MIU#5m-E!-z`KFjXYQw3_w>FTQB0xbME89_{=g`-j;8X<*sz~I6da)E^z z`2OO1bf&bIH`j)xJwZ>*0f7k=-UOhD{wS>Fna41OVQ#9!kP@y5Y}vH>CS)!sk9}oT z2P_Z|R8lw`46L<4I0*zuJ*24BsMp2Z0q)t06;cfV@|lC>^LsxNt93B-Wfi3=^oKuA6RGrb4AJU?3tbq_RxmZUU@H=!0XaO}d1^I8;q>9IKV zZXheLnb`BmoaNj}VbK|Fnn^G1S-a-(C9Z3~7=v|@TTvdgC6cLGsqhT6zIMU146h5h#i;hYU zPRvclK3?(o)vH`wKsZKS?FH_y zT&arL@vv{J&Y0c+S9NLFuEQZoY63cj)GDU*(9#-Nl^vM#`IUkW@o}?}VKsedT-RPQ zSi}k&a0!Ql;G5yji(7PRcUP^cWLz<9v-6A*q+us5e1DFa1Mtk(N_xTg%$sW~;8F`h zj}&YvfSQ6BXd*dh2l1x-I#~_)+mix;`oFJw?#3BhsS-L{BJ)E#bX_N#a{;9mg5DJt z8li0s1y^V&mMwZ{kZ_=&Y7QS-jz=jKHxq->Bjrd~^?!TrnZv(aKPkU;tHs*9b`N>1 z867L4dT9q7%6j2U0_-jAbBR?teiMP_S<$^#dBLNQp)PL(Ja_U_uPDks| zY$z=C17jLpD;N*KErFuJh3LRZ0{{iHBHMR7_eg_C3wBiE79YbDaRduT)WW*n{!CS>XcwlUJBQ` zW0V=<2b0E-Q4vOf1gTP9ix0%d;0}Rc2R=q`r(UDp0~>nJ8?7@167lKDJz!4GBJ-Q(DqtT zWV3J^X!6O3w*OwEA+;?iZc>eVsp3(Hc1hArmmBp`BHQa}cvBkx*v4bBD}d#&0~VFA z@B~?II39~_1`FOrnNvhxKu<`75?Y-(scn7OS^tI?nhnBIJ>+1?6z;dgz>ud}^jfGJ zV1-bR={K>P-{>M)KYBEJv?g)d>vLP$wEELw4!pr=G+o^oHuT!w(3o^+B?Bod4lD*S z00?Ojfq39L6q7I;vAZnds|z<&350bhx?OUPdygu0XmvQc=}Z<=G8B&KqCssa;QNlL zRKexmH-5h>4rChib5VYF(X(mS3?KNY$?mu#mYQSUiT!!epgRW26>74;w*r~4ZiJQ+ z06)U2DTepB!y<0XV$kc;OggEibm@oR-hA%$e1qksHP|)WTGQ{9IsIUhYs?<-_%KJT z!K$A?fNYXL9O@IEKmsx`ZorgRZkq~W4dff*OCmBD7t3V+4Ly3G*$~K(0BO;+Jh#^< z8@I)yqAsvHfvY}eoZP{Utw!^fE&C@Q6p!Bf86x4a!y!SS6!2t1gEqO-j0U585eqN! zyJ!QN1P7bno)Lv}r9_GRV9!-dk6no!7q8=X6n81NZXq1S7%o1N0B@rZNC%OqYX>QOu7&2JVD18Ns?GLmQSp zHe@4NPz2>IIn92L>Ohed50i9mp>e^vg*oLKA9Q|_QV8PY5GrM(W4jW!bAa89N;kZkU(l{qvDcEW3Bsf@`uR^}Q!EEc zDq2ytcv+MxuA15ncMxKVl_=-{oyl8)n7F-&6gJul-v-q8^T00#QuH?(>)o-(-7o*8 zT&BQ|tqlGgQipP{PPp+{bThqlqLYY0Lh74TIrq#4^-@db1xkz)N>evFl>84TO>>c9 zHEo}Py{QZcQt=JMFg)QO5F; zj5`t7h%I0%o`X6jSyLsuGrhn3=y!H=fB{Xxw9rhy_rn&~7O(jtvt5U;8qFDPw^Y?f zX{(9~p8x?>-T^D3Bm!E%TEI@Qf=$oluYf!Wx>5Q>PO4oW-Bq?><*aFaiL8j|kwQ~= zdl78$gOa=HotzPa`p*v8Go5hvC7hMlJL}BX=HJ2;Os`O7$!ILmNF_#=>4!Ri zPHz~%G!$?nQbxdxIEsPtBT^rf9}RqG-etoId#y<3v>mkB6HUT3w{DI zus-5ey;sgM=pZ|UO7S)w@697@sqT&v~nQz!WnX@Ig|VW=MPbY$m@z5M+J!_e*tB4b#Z zrF$Z!miqUtcGqYQ ztD_T|2f`XXTK+(j!wS#Ba3&1%CV&J#nf;a;&#_2I3Wp=*jN6CBVuuvwepftx<=Cz3 zOZuf5<9@7~qZjX;dcnm|&q~+YY0{WH<&&(@+C}a1vh-kWFkTbMD(L>y!FNr|jNEV9 zKlN41Z|@!$=GF}i{QbgbdrhS`%aJms=#w?`FL`g#kbZB>YKMAQw6VZ87~wz@!XjfZ zNY8&Kp7PYB)~vJ3b@UpM`7?;^Cdw+=Ri7?@HM>p6uj&n{SzD{>qFUf2BRlpyU5S- zN)`{15?smH^TuQAlZoi&?6g$L6H7wNAejLBm&|vVwa#eu!kV%r7c97cz?BQ{?%hwS z-uQ7FAg~OFLubd*$C`R?cz4L$zFVtS-<|#P^q#_;Fy$osAg$twMX=RWYHWCB=;}sK z!wbobR%c_!&u8}3oK=HASyQf0$+)2rHqbFp4Z#Q$9E^5HPIjiSNKm5KXS}c>bmB07g%wiU~LJ!`iNCKP?;?rnb2v(&6h5WrWbVES=SiF z8mWPDvAt#e@>)fVL{uiTNedkx4ai;^c17a7=}Dnsh-kgxNOF5nlZa)t>zCiP`v<3Y zXumz|ZFo}Ddhh&nq+oh19|Z!%irP+~p(BJPVo=#vxI{m?pr*(Q1za8EeB0f#p<=YH{D~8RC~MR zW}4w@TkB6?ex&W3m zDMQ1cPeio_yka~-)UkJ=T-76e1VV+{gs@N5?~U&+>UUz-(vUr`S6PiaMiaphcI()o zL=ThUsa%U5Cj%Jq>IJYx9L5b3nK0Uy5^9LKOMiUli??1oW%eEY9zdc-vYalkWQDHY zXcU^7IW>C0+jB2H|EyD22W?p$cQv@7U!DN6V*dO2W4!WXolsuV4uckE_wJpRK)o*` z6~?8pXvli7{;U_0iC>y7p-E2$wcZ_N)mzpq|8DDs_4jOCy6{=no(lrU!qI}jXpwPc zWmy2I$_JY%@@@zA8zBe9j!xlhSDVL#s*qm1bc7EF7cd{;!hS8gM8cFB1ae7WvkcOL z6Oe}yZHmX@(fXS8vxJpVmm~vl-~5CS9)s8Ax?yh18=pQiufvJAW?54&P0h}3wWhi; za#qXC0R!Itel+AQqbQ@Ade?>6NuuGlnXfwE_j>QN?EJIrCR@jlSDRM>#drh!NS>mN zwt%^Y+QQK#Ix3T%_40R}p^Tb__ZH*5`24xkuRHHNZL!mo*{dcPjKL%?>r8f3ETe!- zhUpDM2i8-yEyU|16)00Hc0mbLa!Hqcu<#CBTGned8oSg`2V3kqXxgJgk;*}Rc`0f} ziI0%nVSsZR0ps}`)F{xf7Ph;rdJAlh`O4SLUG@F%beKkuhR)mE1gSa7 zkofA5af=@|XJ$WLr%%f&xl~iazd|Hf=?D{#Se={Y}{EPiyd0?pQhNo7=XO{@uMgiG|35rP*-}vGkbC8z5Uj_`8tYUdvO>MxN*(opo`+~6x@0xtW znXgI3Pwz7Kzi@fnWb7pc!x;ZUfr3lDTx*B_M4c23!}%aWO;!nFk6e(K>1DfISAMkY zMN4k0dv~}4QZN>Xo1hCzDh7iX$Oxe1wHVTS5tj^S`8mD$zzBja!=9oK@7}tlY{Qy| zRy=+EB-U0&R8Tnq(de4f8!L}}g!1XBPk+(vxXzv4HRQJLxvSnIg~CFhuLpYh)j&W{ zJp!JhWBJ%9?cTWZ{f#f)D&YTh@sp?Z_{T?==6C4)SY~dk?qRKkTXy2mgil%x=De(S zC#~P|&coZe3d${k!o=~x1@FIFpJNGr6#`FVrUqARhB;i2VMbNU|> zGz*qc{RXVCrOKv438OTb=oeDt(;BocBd;9f|)@*n@ zQ`1-zH$&CH?wEPnzo(x|iix^kNCTn$M4i}&C}cBoro3mXu#rH$3AS+K-!EGb4u+;U z^4h<8>HAB+8uY=BV>R~NJF471355v<2}B8DFk@*}i&5WL;a#<6g|PgP^~NvvKJKUb zhZIG&OkJiQ^6|3q=DfD|ZmjhtVCsX4n1ThAI}rPsJQs?4aV_5ywj`=3s{*3ZIifzP zZr##XClBkTDLXMw`*Xkl!kI6w?Z1#nsnCKvtq{NfkoQ$#;*1!-oJ`R0M1%4^nAVh#8bPHa90m znDKEaQAh2>LEUTuwA}5qU9>Mt!D~`1_!paKMP)ffA1r{H0rnL8Sujl5ny)Ly_lS_lf+}kvEJ{^H;FSnTn19t#Npa=IW&b!{Z@na8$+*l6 zCA#uDs91o7rxrKyDNUHeCYHvjjYyt~ZFkqce&;3*7+JMJ$?bnQ5m^!0A`9)6x*k60Ye`;)2J&fT7X6l(B5UM10Nu0V`@m)8diw383` z=(19626x%2DbsE~mlhU8TU|1yD8B6NTcr!%UG$XAVr)@-ZI6+7HooT*pIw*MqTq&z zGpkQVe#`6ozxDkz!1FUsG-_F5ujVh17ww`+wB8{$c{44MmZIFKzIyC@2oM-8h9Hd) zXaailFiICWDamawH#_WOam5y^_=UgL4VdgVg=U4YzzW+*)S!>yg9!{G0ZLkg5L;d$ zl&PLW`&ilTI@KO%DRkG`uZzdxMg9nEK|P7x&;9^1)qGlcrY(9vR<*G8-t6mHx`{%V#DsTNjq? zsf}_Kka8%2tWXCTZsH@wm*GPZhXAk=vJtx6vRd@EL`ZV4U-H(hyZS$fr#@9qMbj** zMNY8U(uHr#xjZu```Kh#{&7`)SaGPsCT1Wod9$)8;-CkmZrs%wgXIK+Dd?7}maTkt z&ixlXiWigW#8OfMRT3btK+wCYb(b?A9r}6cNjod{TtEM>{l+7HeERiIopIV}Jx4^6 z`jOIKKAwSzM&4JtPw5j$8Do(OlZ!;^(1lOG;H`OmQ&P->%Nx8exbD_$X;Q=3=e=W> z2ZsQi>@o$^83UwKIVuHNg_Al`@z{3oT>kf`>>z)5P%$#ht=ed9jngLKK~MlH;s_E{ zAS^1Sxi}*qdJu9dOs&|?GfDuRtRQCH!^wkFvrwJD>|8%*`|yhj2i^G1Nx5yiRl6a- zfeR{|$%w@h4a~BHBEfJ(m+eUFjw+ggtjNkTux#;F;_h${6tF9l;NbDgrzNu56mG7n zivU>}nJHO6A_f(1a$z`%3qC^{d@=0B#IhU?z1F=eSiWJ+jVqoQ_9?3(*h~!t>7YvH zj8cT^XW6g*^tD$^8F|;&C-hQnohOElsx?Be&N5|6m<8+;_H)Y>KfPY3%?7dx@7c1w zbj6Z8H@x_lufI#YJrQwp@YmFK-a`?Bxu=sTtUgMTcZ z{(-~=58$|@Zni$@IH^mk+pr)zXYL(^YY`nBBJV(85)m$acm565^xXGM`R$~ZWh>e* zlcWLE8B-Cmn(o;7;1Ez({;)XXQyFWuGn3DT?@I3ZwI4i}|NUvRKv?Q$K%2oVcpZ#7 zQVH@{BUngbX#yhMC>&kl>hKOgI9yF*;OzTb0$B+~*uA4<*0^(ez3}b7v#e<&G-*&m z^;Fk!F*7A2KL<`fBl-C`y@q_cdUKtp@!8oMmW-8Nf;C32BnTSkFiYQOP!ArrFrPs*FO1}9y;v%-9kQ@36u@+8;KDMW9_2jSrd%ZO2xfLo^MK)7qmt1|M zSl|E5>XTcLKQ@t?+h&W~3*{);{0kdJMpWuIpiI$FxL42WB_3hVLM)Xlj}fobux{PE zv+wTz2p-ppa#1Zw-g_ozHVVz|!sW-V8qFnFHteoz$gpbdn%w+?$^GA)bIFXq^!d8a z8{c=HQ(9dMin&fID)PtMj?8bSNY`neHuP;6{SIF>s;DEJNV8 zj<8>cU$YWI;?uD~7L}GcLc#-MKpqfKNavmaNhM8r{YL~+Ig0GWz3Bc6Z`wHT%aeVZ z7mrvxXW|*_=6!yi-o0aE=N!ASzG8Ek$LsS-p->;G5k{sM_(6vsG~7GKFzACtFX}Q2 zZrlnTD-(2`*jb3M=+3Or4E6S>r&BV~FnxiK| z=KGhu_x<1V+P3}9ZO&}7xwa8D+Tzraz$R&y@w1;Ok8i2<-~}ygASKi!C?nI?@2cOj zc+M3-RyX5mtwPPAf3uCb%8$r}u`zx31= zOS?b&-wu$x$LHNQ@UJ^JZ+IeXN$VKNXw%PY&%49#$iF|}EV!}OlzGY)DB}4e(WFI_ zG;V{IM58tL?6z&%EbjNptbUX$vMy?&$Ib_afa)Lytr}sY$t{N~r3E=5VvMT$Y7d;z z|M;YNHJ0#%tqeS+?+SRx2f;S{kKcPlUKgwxs2-Oz3Y?;*6dN2%nK8~%<;O2{KmF;? z?+u1y<@2Ao`s2L?9#CesH_3jkxEUMlYZUteA2j5&zjsrW8(bZ1>+Q?_0ag^rsfZpI z@;{IZT?9ZwCXwf~>AhQ5e>LllzL4-pG1_q#W`uFGk4(p0^zpJ!&ADwZFK_UJ)%5}~ z!ZJ0|P(CIHrD2p4vfr1m5=kIfk6Gb7HVs}2yk)DtoN-5=yYZmHMFIZk(UP)gpyc2_rDAX5blO0ZdyN;c|nNal43$8AHAf;=UE@ds=o_F_@Th4uT&V3h; z>h|{!%UT|H!aK3F7Ur6I_$`7x8$Gn+VU0oNfl`7Q=wAWvmP=e@Z+ObKCNb{3_#rejG9mr9OO*ZjJNw} zqJ3YUe!j(#`OhuYZfr!3YiNHN`HDB21nPvBfE1%irbAeTL@?GY<=RX-&&DP1&Hn2} zq;QgjE|(<=qn^gHLvM0%@JH`Fx7w3JoB^bC=Pikn1%$Xi4xC%H5p zDLQ1|R=vH>4mu!W&dF-fXGpnOk=IbxSwL3US^wK6lmmavVLj1EF4*>h z-6>U8M7eHP+1|dOdJikNqnH>v?jmPsM^?@!RSByUj>2QL4xWENep5~* z0<*{e&t+KH$w|8#b=|*W3p#`kP1(1Y6=7A`pj)tl%=f%L&JKnHfyY%imGc z5ET|3kiUwo)FzS3L%A#uH)=e~2HOd{lR7ESLFLme8<#Bj?#A8k{e3}GnbhI>wJ=)F z_T-1(Z-Etzf*2f;5aF|5K*>!{J6_oi=ZLb!i-+5?@*3;4DXAIOoWfLlR^e3>R+UNN z&TrjMu;Nh#zzmp zjKY4v{(w<>)VZK$g|INI!&D0Zpg=$!5HdB9G|4Trw;BJa7CUIU`v~_Bn(kl^f%McB z!2u_qFu`xm%B;b58!Jsd3uMK9B2zwl=^q(d3i3$8Np>>NZqznxTJh4{2QHS8)jq;| z6&`4Mst?40!IC;+|q*}!(2s5Dsn`p6pf?C;~tOTb|Y?qs(iXhBY_3{ zY}Q@Iwa zidP?8iu$N8cJ;ds1t=F}0)FV(9{yn!#P!U}mZ3wwn5{H$0|!m8;xbsXoHBIppkAlTN5UEmVrI zcYK1H5M2Z|ppJ5ARtO6k|3N)e17vv#AOMJn@qq(YeuRz(H$FFWl=VM1nXC6G$j4lX zi{GCAyp&pS=5`p}Gh@5WUS!4DOi-NyK`RxPxUS>>l%bndbhugrbmlKVu3 z_UZ5{vO4wI&rfOBw%x1-Lwf3-29H2iKcU{5zJwGVZrC18adHIwr@;DXiryTkmv(Pl z|G*EA4t{}2gj{GpR25euyNp8R5!RKIh_h5!m~cVOiXD6Ct1=m9;=4e9&m3> zXDlD9f!@u_-VoP9IlHQpd%l3YK3AnvV~ zzBy-*IV1Bmw=vD>g|R_yGukWc7gUz6!RL#mW#)9bUMu3NKgc(=1J_|~s8XyMjg z0#et9!r??kCSVR?Cx{85L_osOT~V9a#xZuG>g zuMjXOCi3_K*=oURb_^CmWrVW4G%4+tQ4= zS>Lx7^up@l4N$Y)1*GQ#o;AayMHfkL>LsN(+f)VPlH2R2WmL%OSRw=4TMqbK?e4~a zl$YZC*Ot#`7vyB;+@F73j~8luFr6KWMzQS(&R$`e5$|Y#wvarL40v?amAgktQ~y=z z+Pl?A47X*E4tfAN%fQ@MCrmBye>@9|8q~PQN1XS{^h<2E^nb-H8J&0gV^WpJCk0~l z@N!K@4#{L|P^xK3x3{ir(WTp7-i!SINLEn&d^$2AX9J--3>08Dn)-kfC9iP+wEa!d zN9m$jA*^^z^1+f4$@nH9uqRRYivhJ4VG%-d7duK|`D3!BCO(y02VOexv2aRmt4avK ztz-p>weh_;;j;z)Mg`S4Ix3^4aUzzJmTE{;Z(aG_orQz=1&WfZkdw%!XoTR~e0tYz z-*~J!*}EIuQ43^Ndy&q~!lasES>J%|(us!2en>wq$h zlHR@9tYCPe*V~WpbyGuil?3H?M8WemdOwWwNsaYE@PG+=WRWQ=rJecRYQVa=HV_WS zg3b*6l}|nR<>%LSKl99|CWP!QI=*htXld{Sf-pry{}e#1aA6PIYDuHfC>c}jX6CVv z9-rEac;2T3wWR<3EMTt4?*@*UKUSBLF>+5(D{bFZ50@zk4OB+7sX9p?NoW#It6Aqv zHu`q1`hMWnw;%qVI&%015-)pk!~b5T-=4#0`PFzrW5IR@d5i*T1RSOWv4<61Lm(`b zWBTod9r#W5m}V0&AvRJ5qYfJZ41ffK1e&xOb~yD>v#IlustBncDl+zbc47~WIrZL( zx<<(e%Q}K3!iW`vR&)?Sfr_3Y4`jjzn=maFy`gcBf5x;aLs2J>oL`f$TQd>XQd!r_ z-(NgF>df!7v)--9#pEwwUZkYd9}AG<7>_jgL7O>Bl?8jSKCx@*-0Oj??#C0cae0}d zCL!nc%VWvhxuX1O?~i|SXX)~?J-(2%zNRsYj|K$f9ZVV_&v4V{EE_!?6*YVUgBUe<1 z5*3Z!xD8vINHqh(*n^6R0VZ`b%t?4MD!+rsidJnE9XZyoSp;Dy05yR=n}yqOsBne) zi+(`}vV9OO3~V0F3abrwG|M>TyyF^8fE`lwAO#lGC!&paATwKsyDr2S{{J#G$$YZ2 zTfgWvIHf=|29waRucg323|Iw;$o)iq0JxA+5!NAU%Gci{efiJzoSpZTA%RuHkkBMA zeXHadLuRYN+khm@nxvqth>cWaAfEwWW-Wg51ucJ485G`f4EoygZOi9;Te$4$5g)pc zFW43BA+7=n!++8b?^c*%!4jvk?L}gYKl}ih)hO}Sg>TIr6H9G*(b9_Q zh#pjx1=J%3w%95~ZXV`q<7p`=8eO1a-cr}Kf7$<`SO~(g%-tu}_obNK7YC6HrkCSF%-s zfD=ZeL7xRo<=wRWOM5}b3qm@pB_79mB&yUjNRSw$m~K<8C)y#W-M~R(7cJVpwQR)l zr-rZh&K_6Ga_0X1s%OrBbN)qHSZVdZM1{j(J{QriXVnz`qRwQWXD*NbKklvrK#C%3 zcTe}^na!CT4IrS15e3ZQJUu=13}?=s0pp1%iv$B0PK=ndCnn6NsEb*0T5{f;XLl!0 z&&>aQ)!n-*$z23o|AL+FuCA_Juikt0Lbt-gb2sr@WAbg2PJg%aUydi+dcyRtZnb#x zuUuYMqj_QDp7kfN;%;DO3|LHgIX z+G^p3YSo$^1{M!T6mjZTLdF3cOYm_qDv;NfQ<1EEG+e{~{}F9S>c0Fy3fWUK$JRyB zWTH)AOzG2F%nRaLI%p8gEX;g7gG7sGc)Zp`?dA=0#t0KJ(##bT%(VcFA!#Wp1dur3 zn)H;sg4b#ib|HLfrSK_IVZL#pwET)^b%%E$a4B=cbmfNZX+O+i12+fOytt4ZHmk(}vp3C~Ry;fB-)CNV?DW|$XLmo~ z!Y#G+FuzQdM!i?eGC@XKS69?(JyUXr^%~$Q?*8J>v(|6kaObkZ^8^5BEZcZ@sw?d) zpPC{iE!M&K&JMCL!loGuU9=ddhsl$k`EHi-%y(~pa@A3j3jxuwOc`4HQ#|hcM~IBz z6!z$cKK`pUz01^G2p>tsYz}h48wpAAGeaubk?*_mHhJ_JCx$GETh`!5k9IPgy;-u9)QEYF%9ZA6{lIOIJ@V|d1 zoEgKa>H=}dUkZT2*+7(n{lFh_!8G9=yGMnwd$-msRj*%p9a8wjDWGoLPc(b>%57v)PlUKYB2E?$x3)=WQkmu)C7vS70)OWAOdg`QyPr? z77UJY9Soo_;phVSWAZ1{tx%f@*3`oDVF0yCXd!=bN$I+mmQKCqUFQ4M^~c?G!ZSY} znU~eGPlc~B3aLdgFZ~}*&a^J4|pV3=Zhc1((e)v2xchZI59skVF zOKcfggA)4^H$tvqYojhyvPWX$XZAX?9P~UcC?exzAH`o`bdO0F1b% zsFIwI*Z2$u%%pe)cwNny2goWJh(&|zz~tUM`^Qg9P*S-Uag2Ac)YpJP%P<=VLgI}g&{-(Fcbh+5FQ3QJ{fQLt-OBk`_2Kd457Hj@|r+O z@7{hKd8b9Oy$iYpSXK-O7QmH7wb*;0!Skuk@OvBHDZa<#D$>a+i`|(zrj}xN)NY{7 z?3UTBH?@^i(-8yM9@4sGrdqYiRqrmHdim$Z;xb4HNeFJ@)J{8c%FLrI-i+(E)cVLX z(yd{z7-P}1A6oO~6Q3~wC6JmKY1Z(DMX#E`iXsxG1iqfK1HV8CxtI{bvKA?^t7?BA zNI{QHff2zKH~ldAVy+3A*cId)R-Qccsu?OQkT!hr`P-)*fAZPi6lC|#tpbCdekrh# z5$0hHQ_U1|K$tE7^oc-CnH=@ie}Sk-Autat=2$Em`U!g2gGqh~>0`WX8_bi#WIVFI zq#-1wW_5q$#K*pbB)a^#A+6uiuWi5k)jfD$Cf{)X-hBy!@Y3rdt@ z&RrPSqTl#^b>ATEYLp`CyY&Xf;&&;Gh9D?L$6|GLx5BGcG#-;+{X%5LKDAkJ)U3q) zaesqgx|?pncB!o2_^5L*-8ljXI3a0*OiHO8G(8n}O{j!EfjKO|)_9_T>6-J`n6LQw zrw!C!W93IZ^vT~eXZql3c!{w>Cxc97PGrtc-072CzleL9Zh@Fpjh?ref z$*LB07^Z0(6o5eu0;sF&Bkkh`nZZ)aU$x5pOv~`B=Ji{o%T~jU3^|ey|%2TPAjf!z_nic1<&6j z{`-oC__r1H@gJ*$$psCPeQmS7Z>5%YcF3Chlq0?Ck`tf!?u+C8^W`NdMI5|vBg5eS zuJvMyDS%~|8^;j|<`7j7M4se7!ha>)$t5e7Ouk0nY{qla?wQaz02arsP#iTUA;M4# zQiQGL8WJOlEi?(&@-RTB<}=D$(SMJ12=m`tVWc!tpz(Hh>ZOfwE8sCXI!43Mdhrh} z6~KgZz-ToPjCi`!CPka-o~U^B?v-3n<`Fu-$Fu0b;~xIxyretph{~pB=;X=3u9yLG zW!`$GdfuW8@gq*?T+j=&HdQpw{_tfAga*Ze-3`2v>>8a{S+a4(f0bYz4pM;rz;~l+ zQTJiJ$^QX{kTfwB#_?V(x{n@T_4W0~9#OaSyUUfz)w7*-8yBaAYRbGeRbb#Cqa-aF z_1D$by~FP$NVE4&A1eA2r;c&TV#Ok%wT<6@qLVF!g+_0R)ZzybF$MWF$FyiQkiE2= zyjNk&!7J*cpB}a*ZgYovtKdr~04Q!vrgp!2RkbhfhBIBU@gSY(Z_)33;D-d&ykZC8 zI3Vx>2M?BPMOL%H#D(c?H5~vi4S&35L0&5t@j2i>=HkywL>s7PO)!vHQq!P)TUsAq zR43WXqAAB~j{Fx+c;fqo!>4{MY<>~=QzlFl^gDiJ*_sd53@Xc(>2+pX=+Y_{Pf%AA z`cw!80wV5r^G|01SQ1TZux(a3UgE;`3vVt6T(aUyp=GG&sQvjga=gCK#j8K*4|zeH zJVCzBd0MGd*9ucSSrR7^g2ROFYA6m;BYGlcdjISWO^e=GRijF5ZBg6yAr{ zJapZ>XhYQpIlz>H7-+@jIG9;B7yxGL>?u2CEV%gmNf$m}bmMWy7hON{K&_$TJ~+$e zT!EKrD~^`6(lt-ttSdPe7RF82YBtp-xs-&|SXc8p^ENOheQLES48X(2c}9_sQeSf{ z;?C)E;uH7YA->TCU)!YCZ+TiuzSZGV-W#F1(xJUQITpQebKsw#xXU6~lKmbWZ zK~%~(h_GY;pk=FQeq2kgtn+C_Tk5pZkZYjbmGk9s)4zHQ#flA$a}M_%4yFlnMN#_^ z80na?-X2)e+U4#M|x$iWD33jLTX0Ng%NwYtjk^L8!kt?1p{It0Z>F|aN@>OTsV^m`#%i7 zb^j)TeH0e90IU`=bLuB&C*7F`S2sadi}k z9DCNIjGb}S(BJ0YFk$;b(qMK=U*B-t74eES%hJ4F9FMw2NK#rF0TX8YcITvlLDHd! za^-y8vZd}ym_*687B-xg7W%jiX=8-hqx^4sj6!6UY*Ytw4%!0SdH5cUPqH##-TTm^tW5w{{ zFo^&Ou*xF2>~>3*H$~}|o~m|9O;rj~QeKP+8?U?{gTzF7escb%&$(XyzTR4L(R{+GY?t>)9`STIAp zPJ%5bq~cLY8$@5?LH``SFa<-+1A;AO<RUox$yl(zYSY`J^%J&4($X^mkiw3E zkcFi&6xO27jO@Yt4W&58uj>X(*35s{zysfGvSsC!HTz@mo(LUCFv`)xIwmD)7+N{g z<57BL02n!wQdYd7!V@U{)?T~%MQio)skYjc<8Xh6wYGS&y>8{x4&S&xi{{x4AYMaCSfD*hjw+*d^M} z`Oty21I2An0{8~{&2qme5C?!KObP>F^00$4Sn=2!d1lA+ta#okjBXT!MkNSjl&z)!4Y2S{NMp%jfe}*4&*s!?jDrjns z;H(~pqU4S8Kj)+VBW4!w`3PzAM5f29NP&j=%cfoZ6B{VVETg5^@r50&gU3EMFmACQ zR^JQ-Tm54;Nu-5o%W0ifINsrNe+!s!)+_z?XUAN0SJVEv0a9ZrskSh*{0QBG4)nX zYvnBuUo7GUuxf*i8aab}6J8KZ7j&RC!V zY{noQIw|JPJ9>3xL(FS<+@{mc@hhpEg#P6|H{q=0(V_ z$|!$Fmy|vi-QCZf-}g|rH{(o~&3kOvlcAI}G=Yl*KbROgos)#26g@={qR$=ZW+uCM z?KoP#!U+%>m6C(+dO16mu;hneR1y6m z<|^kCO2kP85scV6@wkV7It{=w{r>rUWu=@D(lJF2xJwg;@ki&0$VnF5rt0oP!QM&$rAvO zg%d9z`S}DEQnKhH-0cKdwXKe0J;Xcjflw@Dk7wew5xfrm50H`gX)%_k))^A&2 zMW&08;?5g=XC}VP!<=KM2ndF*wls&rQo2pu@6bD6*!P$FE?q&AJNxZo%Z#%JM31`v zz0)n8?7LQiZ{>o>2u}o~P!IIj>}nSe4cb>V$I5HpsM);u<#jJiB#@%uN=qn&*abx@ zOm>KA7J0m=f!wtI<%zI*Bk}La{D0hjaKXUglly0OJ7IG}FbPbDPE7@1<><8nt7Ia} z?X;xJ&6}#0eR_Vhep8vOq&UM3N1tqWr*vcC?FLpzYa#}Ax2tztRx-lqA6OR@{X>l3 z4$RLIhX;dT(2Y_*X*~t+IL~3rg)sdbv0AH-&flndi+m4#@_6ToA!Hb&$ zI3S8cXc9vQlG@T8CZg3qbx%JOj`qDNMjs zR3ynobMOT^h2M>&zku;0AvG$`uaF)*amd}TPwtV`f9$3PD!s=cJgjFT775bR*+!Z} zmEz65M>oIr@Q=(x4==3}*WbWi&D7@A+yt$vcb_me*I1$ng0MIoLIS|&gk6QQPBKiKXoB z4%yTBndIP+lcyZ4sjeQ4&0%tofnu{{{1C37z4(tuebrz?gA9?BbU9!!I3BE6QuN7s zrZ%xs-qSufP3|6X_iKX_7IpuoP!NC+cA<FIETS>J< zq*%?GcYc~ZbDZ?eYZTxl+|hy5*`pJJq+}!mHZCz2sF{Gx+Vq*pS7zY1_y+F*xFEVh z%xLk%^Y0pT*Xw~EIr~grTN^_Ch)i;_aBaXe56EOy3rdM-gczL!d;PZJVks^FAIoYd z_R4P=%o9R57a1HyQ(%lhOey}7+3&DIa!`tIEdNN-6`u{nL;rgB|8^#TC2g49Kt?;% zHeyS#-=BliVX=n!gNn+5NKDGIE8OW!iEFW}cYn9+!5l~EdE4D-Cj?Y1kVJz9?GzYm zB(TykDjmV+G}Hl$J~^&!yIwum=JE~*R&R{1 zpZnc)cqL?wX3qQ-Iry7(Hy5O$+6M)bs*oe#!Ms?N%oOBd0%TCC!*$H5kAJC9*Q0tmpaQQBJjP$whnq6rlO!%;*CX`0 z@zLB~U3(93*c@GO;%3vL5#Rs5oA(vI^b5y)Y)QY8bDBxg0uRo3<4hTX0gm%1$ zKrm1n)B)SbmS_x`P)3`#YA@q=XXsP_%UfUwgleIssx?Ba3K#+xG6YG0g#=*a4XeA) zA>&@@4jr+LCjVh~cE}#i3yRLzFSl0)*>Iu&5dr7$0AqE;REJBV3k@*X3bh0PqhJ&ym6c?$A?hn%CrF4r z&4&;*-o>BvhTdXROU>{8S9eB^v}yUgYs=m!TucmPCNYSP1gt#aNS4|$R>$!)B1nd| zSdi#5_P#15EVce{(wUNXxu!a$2H2XfsP;p|HxbXW+pM{;y{=WReDlX~XA)>O2mo_7 zvE6L}6|Hsx*oZOP@1|$+yLRt!wqkdmj_vq>m~6`mS#b2i@rDu0Za|{@#Ew zg&87!_9H ziJIc+x0W&ep5{Zaj9m&KqbQ`=?e;edBH_^a>*vnCXXS$zKQDm9uNm#_%AO4LA|MJ! zOnUba0Hc155HEpQ1w*_<&w@}O02@AwYJ-3QLCsE96)43lkK39C3(tWK%f~LBa^ZbU zJ@m?FxSk0#&5Z=z40m2LB>}*QU3heZl1KrDP878d*<~i?03@_wIfwdQw!lA&Htt)04iyLs`{aHBh&e2V`5D+4z zo{h-6B~K$?z7q_0@F5bh$Ofct6nVEHHMcJ7k9{65ichg7d)HKyj$3r^xf2-yAi)b; z+p#c0Pww=jo)xvF(6TKAyFl+CCuYX}W1kWKg_Te_6{I^BY9cSyqo&8I8>(0Ra)tm_ z{AToMg}RUY%&Y{lK2%Qd=!T4Yu^&VrUUg)3`?*fd{l^NwHRGqs#`qd2bNk^q1BTM2 zEQp|FE0O{=9HkPxv7(ZOc*xo190-2$ki}}AtQHw6U5&NtU$aFTf+<#2rGBX>n&yfr z2PVr|tOu@oyjiIZTun9uu+M{Is+;DF2#m$N0>6wJ7t}5&XCT9UamE?yZwxn!5jIA|}XT@ygb7v3c1h9G2hicXo zB^=jiW(EJzJ~oh3OWf;oOhoY+v1laR+Tc`N3sth6Z4VuaVIPcf-jp8sF#O?-!#F;2 zLbvft@x8d}`LhhY9Nv(b595gBO$b1!Gl@laGt15uD8PuWD4u-Y_p2VdT(@|N1%yhn zt2!2dtqJn{@XInJo9nE4U{_>25KCeI@JIYJp4pFqcrw-n(&?^1#rhv+6dtgTw)h>htIaXTv?OI`qdXyjmTk0UNDu^tQhjrBCna7^| z#GIew-mbT;Y*MYXz(CP_Dl&ufE|^&Y${>GZc#R^(yvIE(P$)^;{L-3u%#nTm5tHBh z2Y~`@s1=g&iOS)CY6VP|QT_}6090^+niuoS7|?sTzD5jl%^m6@Yzzh;PKCYSgPO7K zfG~*7mH7~;!m%&FR&+j}NA6*j9G1b*`2g1by5Lzd>ibEFLLr#O`Z=B)4E*;;qe&<&0?4I-+eGt^vrO}X| z(a+{su!Imy+IIzJW%X@Y{_|}o9wDv#dNcV|hNFm1GmuYE3 zekcV-6^kWkfdK;{bFp(g#JF&jcrPB!7y5gB6a|!!w)kR_>P#mI>?G!9n$Cev%ocM8 z6IlwaAds;Zi`AO2+nMj^VjTnLeR~5>W105wdtcixmbCQuL4Xzj3!=rW8z4J)4^~)) zO-7pA$a=Lm_gzod`4&6mRoI**KU}l|(k~m_R)Ox4BoYB!$#?_;Y!-)mlo9nOxq!Q_ zqs%ZXVC@b|lmJ+4mRK6b4CRv^BPO%{V8)1d3Cx~t8azUe!RG4G=PMx=J~qDBZ@DlS zr(ca*fx%MB2=Z>i9{2wj(>>etQJV;0K|-|P==(poAnwXMq@pPRI}ewCgpR&XImLz0*SZhLXaNz;oK#Jt^ZSy&a4*7%y^ z84x=Fq_U9YEoD=aKOR!k`W|uL2bVA%T*r$xB((5q ztPs={^P){2*oYK(q7`YFzN5j!+GShD@R*vSKu8rnVpt3|T+AA$4H92ku)d*kxi}%* zD}u&o#I}>aqb=L*>A}Y$x?3dqEy?J7w*z*Jz(-^;91k9AHbWdBDXT{@j#9w9cKV>t zM@i~?s1qt2DG4~%z~Bo8CMN;gCZ?!ElC(K{yG`FS;}DqeUDLc)r@y@Pmw#V!0-|b&SsCB!MY0~)hzda(9tD!EOOJl@ zs^!cBzb~zik$!?bD`6g4$4rPVp*Wl)!7@gIWTqdC>;Md*=}dFhh1s$$<~;#KQi6(A zvNniZRL?m~A&nR*P;E%MGzzg+?1#)95QWnDNlmud?DmvACaoE;qQm_}iGF^Ibv6>G zq|`|jOfqH!Y5Ii6ZbMvr*~aIlREco_^O@=Qbm)Wt3qVL0Tmi6ak;Xh_^;OYNNhZ1RKC>965fdETiD8@V$6P1g{ zxM`WVJk5jb7F7NU0S9pvV%PB649)dR8sv80CpCh(#omVH|wRs=X)k z{c~Vgm=9Fz5n~U4(Sa~>#CVZ@)YMOJjkt1qmNo}8(}up@SL7U#X9YPcnA&j%D=HTL z?=1kU@)AJ?>L-DsL?HyqdLSG-?b8XijBanP4La1~y2e-*P82b?Api7n;NWwtVQ~Tb zijqusxh*s$(;K8__w-c7Wp~KH=BP1ij11Bn-|&V90?pwFaABoiugfRr7U{e*Btj<` zpO_yK1A-|SKp4f%x&gZBm-hYw2p57sNck&GQitp0Aa*qdG=v5%-0=J@YvCeBQ9J|} zvv@}BvCyHx-ea}cDq~Y{G1gr6y&7%SY%l{U7}V$zY-bkO97@EjFesGKV?G1B5*pWGaJJ)X~c8t%+EAO+!Kqb?=dtnYxlH%|;h&9%$r zh_KKA$!BJ7W~AqVCy}q1T1I&|0v8h=&7GC`cFI7E2Jm>$UH?6|>zG&j3c#hG zEdOS8Ny>4d554V$gDkGJdp9@uAy<^t9e$X7gAHz@YYR8#&JUjOJQKhVEZI!>#Bz)w(9l22t5BI3YM_*zG6stWE(BOfOJfxCUUuYX74&Tt>ye>K3Cd55 zaI*C?2welVV29gUJ^MMkP|B`- z(kTHJR2n$eQt?AKtb|#%6)6q}j!`)p7#75%(g{D@j3zA36PeCju)Oc=A(60X1_feN z6)oa_{UUAzAmdv$R>V^lC?N;o4=!P`QfOAi;ix#`$9;=V;i6eHise|S+79^`Sk4rk zW#-%Zz^SeGBj0iLhatcU7OI}FICcNX9j2^vU z!Z{Z$obdP47CnFMkYq*i!`)nQDbr!KP=u5qhhxM^z`P&_m555vZMQr6GnN4g^nG!@ ziE-5B74`Ip#|ao7cqM9*2zrzLNeflox<$QT%aOo@B!{slcQxG7uDPbXi+eJA~aX_=~& zf?lT&xaIlbBwtJ&y&Y6nSVQ2u5u z`(&l6sgd$kzLnpOUR3zEg=%d!Xlc}rl^ywSO~P|^$k zjIfiA7sedG2OMl3s(|O%9k(LDY%v5x0YwN&&=h?_5G%toxG843c3)8!L!7~;$@Y^P zLXd6;Ym5g5%o_))3C=I@m%o*MKpV(!Hpt?3m+?Cic2~k*x7Ch#}iISRqs!0awy4akhz#moMH(0#e8U;nk~I-R*MO>@1_J}PKPx}}_g9yhSg)YId2dx1_OxCoD)^6q7FX3sIJ zYWxYfsUq1d`dst}J_J@1&+~dzi?3w){KCIq&%6pJOyEW2P5bu5wD!62*+IvTIB{{E zk~Ls%Wlby-HsF~+j3#afWXP~jbvP|OVAU^Cv2^7*?vKRVwJ4JA~MZm@h z9|UXxCYlM5c*|!2OZX!mjAy<>fJ44S5K>cCN9t*OHc@xp1IrX>`I4zuejfs{rG(XS%zoER z>cNGNoqn6V31p~$c-X&R9BEI@duCl-5C#)*;DHL5fSYyUDV-Ba;3@G&scOyq>ky@T z3o@_=l7Y-;=$PpT^z7UJlj=lz*5VppEDtXE2r$Hu=>sY?;q))x>s50tjWPemMOQ7E zash#=pGKo+*B9ci&>nH?k{+F^nwG2=NI^=T;{#pDz*h$p0mDPT)&GmM1U zoTv4;U~IlX-CGxF3mNUN-t<6<1$-&6N691=d9oztZ~kEv7_a9mDK*V-Dr|L~I^?z) zLj;Mn8{9%|HPB?pm;i^bS|IpV>2~~RXf>eixgcSC`uu(=Zcok3?l$l*{Ag>;a5QW| z5y%X>{n^7jUHX2xIqFgxBat{n1RxWox1Zg@e!)?Fyi0~xiq@AtxbgXM-wFo3Vg11* z0}uN53&*7O9K4`H^LAYU?=;z}Y~_iWK5BY~A^82>Co@G&iBy!V{r26%S3P#^4599X zaoSqfaNC9!!qTh2zNBFF+Oh6LGl361De2QduPS?vfKNK`mdCrIANpWJk0)YLA4o+3 z+w^gTFKwI^GF|)ORg1?ZH7?ozS{I1W$!m)eJ;=d$8oU%K$w*P@E0fE_=Cc>cLAIsy z0xVR{lr_=<4YQm{2+RQ0@qHcZIlv|Xf-4-y#F(y3Rzn`kWm7D~F@q3J+X z&)+D6<**F1ERcn=KdNaVM}{pUulwz+2G#s`Ul2@uFhS(xez(7N)4;KBU=A`{UqN4=%XHKURADM`~AX+{}{{fP0Yb00}mee;>fhTzF%&Nx~CurD!&tES&PN7h0=XTbb3 z_-cXyF9uOe2%R@2J2D1YQ?pazk*1}x#RkDI8?#QJiLipI1tPwUx-vVhfVLx0<%h|R zobcbHq87)#HNhbG#k5|5rHANsokn@9JU2WD z1S@NQ8F$Y4h>FA5m?8mlAZA4jZU5^Y9*~mN`|~X^kEJvai~+L}z>0lHu?5I!Vpovk z`{blqE%ocans?6`qmWOT5HdCFpW(T^0k*Gbr4-8k$=G~1^aOz`qZHN{&5o5B1$EE_%Budx4IK5VUWbjYL{Z4*bSPb@*a{@FZgQg)z zP=r7~aS90~Yl}77*wDD0NBpob8el@78nlF+5z zxm`H{{mYvII1#g+c*w2Od+i}ornNf1^Ujnn(;6xlDB;EgWNx@$wSgm?lw#6}&6H0f z7+4qQBTh(_Dt{muw|Wmeyzq@P_#WhonBcs}4lO(-Z+>CyPm!wicNf6GTmo(abc_nQ zGkYUH0m6)XEM7SR<_^vNdh>g~BAt1AS7In!w9I#x0>~hYpRffrV$#fOmCT+GKqDn%mFz*o|0(3i3a=e46UZD@_~zf!d-VSX7?E>T zgJ1JN;g}ea=w4h1tays&u|eJncCBhx&;KXb?pws^G;F{ReMZ+6-2eKg4(z(m&@U_F z9{Yx7zm^7pP>2_Ze3%FBlhE5s?vvqCdqBhOkINHi>b)cOsNo9rpv+#&| z6KDv9V;G^bB(-%+2vx3|n+(-`59{s&8bk1-2rOKjKucN~zr?p3S|;Clz*rFz zJn;G{*)hp}Mpbi2g2@}6U=m_Mj!a5`FAAnvSj9Q0UB6S(TQAU6kvmO));iGQeA3BPl09Cz-a&O?V{b6n=p)r?3O+;W-XBRQYY+C z0r?TLpYxKF(|j_anEq_kfe#3DXNqAHRmeq#5!o(vymli#6@uYb5>JNHk zq^f=>@QV41c;;f3XFlj2k0oVulV9`Ma`H|bdD6Q`X5*=tfoXN9U%B9krEn1(Gv)o8 zY`OiOSWzF9K*c4XZq?y=2VaKbn?X1HXJA6LA6XCnCG2ymaLbj1@jaU(HMcM7D-}X8 zbku#b?sOIOo4GOSQp*E@csekvID3Tsi+^1FuxLRhyQMoISySnXtJXh%=jSHhN(WZ3 zZFTZr(XVp8V@ecaKn5GX?hF+*E%{?s)gs7xa_z9`RI$cU0ce|O5H>6$e`2# zOS7cK*0_YdFJSqcPH2k`hIz05>A(sP;+?n%COI%mWkaK1i@I_K95wNsD_Gm1@RP@@ z5#ZWtw7_EK-t+g1EVb*F^vO)O!gMnA+w_dg@_5BZ{3B_Y3j0i}YkXS3o^!}a|M}{B z>GZq05z{I}y@@rL1?=D|(jYBlmxM7p>j~37eO}4#{YY_r1g@!If*2TLL=qIu4zk#O z^oHYvX=Euazvo#|N2cPBX%HQz+!IcY6>8JzNZav`d@)PT>OEy?U0kXQh2vgW`!IP; z>|X*J%pY1=O?FRFfm1D>u2P?tt zch*&IIa^x&>c)g@y_n8;$>YQxjzkbJ)XMo! ztB7uALnbcJPu zp+JmT0%oBNJcYGrN8kw?Fg>JnTb!vE)#CIDygb1SMgtU>#=)s^;<)19YHlJaF;Nq7|s;uMGLMqiNeo0B%G##x=^e%NgVQ(ZG8Hgxf`Fle&%8Kym6YQdiSqr4kpPUXBrhp5fOjg66S51 z9p6qlEm0uv1ROZz?w1db$o8Yk;egj+(V6Xh0io?ghSMg=F+Z{HCc&oJ%cp~8W&aES ztEJPM%T~T^3)ctX0!*by02?6|9~kjI&5F~al*<`6QX1K@1;LN@QZVJk!ZoFztKoVu zyDgNqCX_N^hF%l#%tnf43dq8?5|}YLkLF7QA!0%~BmZ&jbbhq8iVA^;0Z7Vz9((Et zwSN85KACB7?;(RQgA_Hh7J2IZDDr0%Zaknomew?An`7Q=wP3%QCp%xo7bw=u0Xr7< zWI1LqjqQzkVAfrlGpiTP2Xk?rRi<7fT1-db>Wi4X3Lz?<>1MmE~r&Qpg zVM(j=X!u$@q)~E9n|#el*icG%&@KWNpmp(7ms`n-)vo#Fj^l=)xDbGiiA}WBb?Y0m z?tLyO?AvYFG0WD6oer88rVgM0SonZM8ZlLzAje_BP!U+G`4aJD8b_d;=OWK4-64fH zEqZXt)JyL$%CdkzCPRN!d^T$8=btsZdz>`Cq9zLa>NYaE39Xn1frbiaslC%76Iilj z{IZ8GzZWn9HJO07y8&3CD6_r8?s@x~h_~mHORJjVUf6iY31B<}{nypnxOCyTlMh4E z(2zTyJ5u%b`hIae&4b1m$ znmx!%6atZtJP5&N#j9s8op9Rm?a33L?XmEuz_8f*B58uCYs6pmf+rckE~2aI@Es@( z83$aNUxD=@NA}f>`=gkGEPLlc?B-bJQ2z=xz3;)XpCECuD7eP-b!My*GtSHqFNyt# zKM{xZ4$kamc)C|p@}B8-(ZoIkR-E+aC%h6^jnw&1wF@VlH8Qes-oxD-nv~=5D3l$d z1T!b6S-x2Y$sh<0Dz;?YvI5xFl7_fcX30LX+0$cOEVb7M@wA?^W8Pk~6X|{4Y4Y^A zwJe!&$fAZsvbff#!MuhrJV$0X^Mwit{B}cTDyeNmQ6{ir^>!Q}USI%POV0z3e6>+d zb<~j=3=qMMih&pQ0n1}ufn|sS886=9O3?*3j^w+#fQ_yF@wPU=N^S$J9LGQO*(VWa z9)XpXX#ubzzJ&bPH)OCw##`eA)^*vl4AFcZi=+F1&({*^Z~rO zXm~BsK`0R>ioJOgd`T}hjJO6;kUSFE2~;*23Vg-)Ci{W+I|@aHdY3J;|1|+6)f1+7^|H|gmJ}80K*72fm`8i^+)-J(BmU0=uuOrvhpzmeHQxMlwi~J^z=GKcWEMLB z!M6DPP|kFoci_JsC=e5!XnH3MCSRekY|Z;>s9tm8^oc;jtg5l*Fl88}Pn^~`BNZa} z2^OiPBpBA9*XHSWz@cyAtyQ$$V7i-m3UWu6UQaH0@RD097k>4Zlwj$meh_qo_g)!B z+E@jh9??q`pAs;z7OB8y2^2Q^8sooIHE2K91d~72#iSo=Bhru6!Q{Nk25nPgQ(T26 z2af)El53D;dK(BxK*mb3XsDPO)AbcDe7XG~_(3|>bIjC_pALJw9aaqS1TW;pbiR}h zxCv175=a#xLp<=0=X&G(w3{7CAf=S;i)h0(v7Ef9}?Xp5vTF0z*(uVD~Y=^O|4_^+s(`-Xp_JpAw;^HI}!vXA6RunD3{u97Rv8PTbX^i13ijvA? zjK?{T)MR+>x);Z;5E&X~n#BEfe$4fewg2#QLrNM%8N$F`fdr!i1PKhRF5Lx-|DopB z@p)9o+y&=zJGt$hs6P|HYB@?Re(;~K+avXx(w$C)yb(@NE(&_pDa9_K$?j|V{PWhF z&WvT5WLvbZ^a+m)HaHfvvFgMM)BzWljvhFP#2?x!(&533BZdi=P}W6Q)bP-9*@!70 zOeTw`P+xPu23lBTWR@G{*DsrP*)1Es{qMnQ<+7RiQd0saiK-XYFUb!H!+HT>0yE$r z>qM-MK$0*GFZDl^FX9ky0yy)^x<-HrXSi@I9;jKqWZISgV~cjUQv)+h5?G=Bqwf3g z;bdl?I~GRGP_p5 zTB-|rI81{e!(Stqb&YTE!5Clhg3sFo09~;@Ab*`uJvUSa;1vfQ%XP#6fS>T%Y^ozt z+gP#wo97t!M~O19Y%~0+0G3o(2<1@0p9v&G4bNt}guQp&P8Oyvts*vsBU(^N%>!Rq z$iZm3sP*#4{`I~Ts9T)tb;&eu!uqw$GTfL8pO}LPB98G)$2c8G5TrP9 z7`Ct~2$ZYuSm=X|DFmwrYAWPsZ3VOlFksUOm<%xv-)GM+T0HsOvrFd89Hx{nemW~& z+t4T7rRJr06%ZLRyvArD03EDfQKTr_tcR!pYq9-5zJPzAWSR|(7hlB_NTyps5MT#S ztw9#TrVz&iMsOm>WwUg*1`?UjK>>Cl02Mo> zNt0rk0FJ#pP;lO|@R>yu&N@OWE?UQV!!`?b8MYmgAtN97{5!w9`{_TH`(nTn(NBn!`-b-kdWP1QIBfeMaWl&u<~0j zt<@FLI&k8o5LomY z0XA9K0<3g(nVxCKP5u0vfHQB%&n2}nVy8$aut)N}fH@{1(UjL_XvLE#P{wG+Oh|2fZij;R{T)R0hT8@RK==>YND1%9cb|$(^pmb30euu zbl?g^H#fy4$x;6&l^;C13Ghqi*s{vo4@ub+>`f@H8!6AHQr63uAvh>WI$#;l5ruoQ zs+BXC#~&%m(6$YKI)KH2AhfUh_?0p_+WcIO7dsF13)v7ZAu9yln!+KiSa?Q?4(PZU=|8_*h_wO8*+&piBt6|-o zf~2oD2f872+R4stsoOU9dIaU3x~I6UE`Ld&YW1SaP*b5$&AKB9vX4w}1G|up9QVp8 z$38rJX(XlB%?qnT2^{^BH%YQnU{HQ7q2+s=swY$-%^!E+>Gss@g-O*0D+yBA3uAfx zGMuWdX65XKFH9b~X2uJKJi{7>%T zvCEjx0K~H7QInCZ+}@XO3E0wTyb|(z!bc$BSrPzEb;jxwq4L#_uzdM9l*&!348teA zdqqG=+qcFah&#X|GqFqXQvm?o0RMqE)<0jkT<8rNeAf=PZ?`Ak{si9b#q8b;XReqa zW_)?^SC2X)b&YUo4;?Qut%)83*T?DkddL|?W#aM^3!f7hL!A zt&1j|bG)?S`!(!W(PpWTWU-J<>w4LJeUCZ&(z$h(oPmofh*{|*m020~aWH8S_N=t3 zH6JW~@M59%q^mjY3}ew7)1hDVap5;fg&6RmV_&|&lG6RLAIl*Si?QpUn`zCG>dQ0Z zm5XxSkl}~Zm70*%yRq4kSppx5E=&@t8&OVoiViYLFn>#x_D={sS=3{J9~9CG)}FZ`a~$FHyV zX(_5joQSp57j63WU>Q%_#Oq&BE(b!N2{4T8EQydvZ)<$@go-X9UXnqLpEfO5uhz#}O-22$O|Sfu=h2RF@-N!u?w)vDI6`EtpWb521tY`0T4aOQ43${#66RQ-hV zkg=~`ZcXd*cAPR2cCM8f!bG!-=6ZHL$8?j;+AOYph`b1c9Bg7p19kpTA=VP z$Ya13oM2kze(tCg-1NgC8(x|?PngEp3BWSPe)yzW6B}(^#-T5C+xEuB0AGo*9?(1W z1UJ7?Jn5|SiE)cfOmyrY|MTlL@Wkd{7#Yj;4*n=HGw$qE0LQZY;1aqi-9MJ?Pl^B{8=WfJ-Nmw|a+cHB8$8DdT;c z3)dodV8|>d;>hOU{1l7TU;e*u?l|Qvyb72$qqgdB=D<&-!MDBgOkP331qsFBi^P%z zO%}IQTt{HVLqnsWwjZ~AsYjB*Lcvowi;&Xcv;YSp0(+$UDPm1T(jW;h)xy^v9En1) zDk)ROid<$LtAc?;(1M!967QLjraBroZQk(Zi>Ld(e_!ax_5Ih36TPV^kNB&%+`abM z+l7pfu^0(ll9(Ho!tvuJVp)gY_44VCjPCDO#60pED2)s24WgCeN3;eymfC*U;MDrH za~4k;eLV7r{np}d+x+(3C*`46&S)_^Gh*_rDVEG$cUCt=rDRiieKJ`8epAWf=gVe3 z`qPmU-@iNP=z8y>@&;&hNNON1CwqGp*#$SLB|%jM21`~*tRDcZy>ZP8%OAMlvfrBD z#I8w#!-+{xNB2XPL8{%OX~@Mmvp}x_ZByi4j!2?;^SmLY5WCs^ebBz1+EJ?Q%)A{X z?R@d(ZZY7tSMG_V?>k`~u`EMfN2rxRrl=Ptdx28>*$;P~atcs>vZdJ&eWrGzCYfzH z;Fjkm$OS|0DXwYO+!SCm>xgQj^5#?PRm8VGZVgPxsK(q*0!v8@&CgI^x_4dW+7;)l zoH1sh;8y|PH`P)^E_xp&rT(X79eCEc)2z9DE-H^$rBYv01jY@lP>B&%U)h1%sZC2o z%=dsz$p|n3KoQU|#$Rm!06+jqL_t*Sx;72Jqm@(gryx!T#UGGCYj|wh%s9X7qw=^Tphd;wgf{qE93zN~qC;az1C8gl;b$(SU zgYIQIFjtaOEQfXEj?fIOV&4pp)#2Z~aN)gwKNeBGwpb9Je@FNgfM=1?{$pMmkdc+~ zvMa00(DIU!)xr9bw;JBO{)L7HX$#*E9P{+SuAF}JmN!5PLW7}W7^LWu;&;;9!tZVy#gq&b}6W$6}4Ns~iHMcr86 zmkj|veUl^xe@P@2*v4*9{hPjggtd2qb%2`icPckV3Sd}0SfJM|@Hpwa=v=Q=iZ+zpizJnzA9g~zihjX(A9m+UM}}ngMQdt(k_$SD1Xc{> z0YiOBbw=x&YKp&lkZ~rjnD?C}hz{y3mFaLjKoS}gwm$B!o|5BMA@F7aimT5N{*pno zr5Ss-Et3pHhd9kK`w68~bOtl~jk_0%(L^Z@!U`~kO2GaW1DxfIZhQ=_j z5c14$yDa_F?TXvCZgJJZFOMyL?3!_+G3XofG*N&yTymAN<-*QjVDkX-oFw?{6#|NPUWSyL!P8<3!=fAV9W+DX11cF%vuN9=jWQ00aj zZW!>qca~R*)o;4To7=r!gP>MZARK|0XsgAy{=?PNuX&7lquo2>vzbDol9G};tuhK3 znk49PV7BH)5yMG)ehO@ihH4+F`slfhVm@GfG4IY4*r|W^pid0!IRnSNKext`JG2Vc z4|q(==?M}BRtY3+U|u?$S#Fu~!#!u-MaKZ*s*nJH2!D7wM!4e&h(4#ZJj|N`ZjnrMflNzvx?q1Eq)Bsm zX}EUt)YVVi@HmnRyXtMMPcYwBs3Y>i4;bTxZ@-=7f*)}8!-wSb8u-4?mRqo>vK|Kf zpc^kv!3;7GUz7at1AFbB;!)GJ>ZV2SOgU6q_R}f~mHu9{#%7hwe(QDpvtuz4tJXb! z#q;JnUbz_*o;?$o;n{4Xz#NC%`pl`$oP9r@UkzzDsL94~V%ax4&FXAgKYQ8z|2Y28 zi66}>(=z`W1k=5%rLJu0#4`pVtNPy}1vRCC6Ji=1&JG1rG$0YF+cZ8Mq5%-t#rnZ$;6M2lc1u!O zS=%JV)Ra4h-t_oE1Xi3-9V%rnCFV{^lOL;|8Z#qawdMt=msmnc3njA=&>;SyO`>^v z6UCdBAMu*+iC5|WTHfJ?lN38QJkBMR`K7h7%@J>gJ%8U>BPPB30MijeAwU-sRy^Z0 z3zJvyyWm)1`6HL#w0QhqhG-=VC#D9r6nD2pq`pw+$?>KrHVBr6LDd8yK@|YDL`HVo zKe}uWLh(P8R1#LJP0ptKcJNHP+hbB{U~_SF%iM8GCY*jCfEBTZMBnQ_wG&tsTseK; zLASo*MjUGYYgjEX0gyrjRerI-e793g zkJkihmd!bRcLOWb5n+V*bvs?X94==cK2VZhh?Nk)qP{%IMEw=EvHN-d?(NFx@xtb2 z3l19~!vS|;y)(U5r+?Er0IR{4V|PatcO!=k{ge#nUD znC^RZVNV$Po3O4v*eb?=wA=xpS|DY+P;O({L_7vWo}Ca_v1z}t6Eex4BXE&J*eEgJ z&bMd!-97)lxy}~@16~LPk^xWkk{)R(YFD-4habkCJX~*;V2E-Nbgt04yIBT}ee0WW zYQLkwbAZnl$;vHHM`GGmxy>-*w#`%9MEbq)5(t~XK7EiQ@WSrPfV@=65v*9)P`=^n z#s9fZ$V?d+2Z5#DM+97u%5Gz4%+~G98xQmLJm56dnRXof8upj$9#>p(06Ty%+*TDK zkY!e|CMC(?#;8RLuZQ)_ZyPojzg;$S+IM&f)B*?-7McIMO7*kpH$-|~`^1nmPwJD4 zXMKI5wE6`&PsErRBr64i4NTcFa?<-xCsVs$w7NDVRYE;Wc*topvb+VN1ts%1bmSbC zZuYR$xZ>-RHoYEngf$?SgXK(g~)K?-b8C90}7e)i1K&GSEBJ^0oauCn9}dOF-(D@98epS%9~f4{YL ze*A9hfQ<_WuX1wuy4nbvV4yfsovN_AAoHf$;o+H<$_qNXU zk9+QvSjMh&M`1D0YlPCppZvSa!DpZ1vAJF0m@ei(-U&7kb#p_LmR^v3R)HTBUi*B^ArEIiX=h+!C zXlo1U$SCo?C3VX*B<@97sT43?VHF_xQ)zvC|ID0&vbx&mj+pq)BXjQl`#m6!{G9Nk zCKO>|3EjiQOlH*zxS}QR{pVZ6@Xul&d`RD(Lr&RO@n-h7TisnPR`A*_fL^+`Cl0)# zejIq!MgqPKHLJc`*zoPFwfHWKKN0jrz9O04(AzR|`q`0GU>&`B_5IQB^Sw@BB^IbG zLu#EKZLW$H0Si0$mKi5|a=Skfu;unzP~HemOdO_g;4DIijxFsa@FYLbYqMIqI%AT5 zq?FUz7Ra`(F>d``z#Rq<1Y?U*8;q%TM7RT_hI(%J{GaI3dyuzX8D5FBB`_=^ecp zr&(2XpX|P4Mm_M^sge59+cDv1AuEj-Y!Qqo7SS#l0IC37fJCE5!?)n*(dd3T9$7MX z&1(FaMYrcFNKIX|B0-7j!sK|$PQ?aXdiUV0{YHEqcV{}+FZk(2=2co3QgG1>Jvb-G z*l`JG_Slk$Lt03FraPy*@*FSs9OS|jXzD11U z{KrzdyOlv(inD)W`Ganrada}Jz}{T4s)o;|Nu9Qs(NU9TedM?0k6Kn<4`3xH3sO_8 zXQaBkarvA&%#u=f9-f<7A9?FWo~@8^1J{;-OsCe48z zm%@mY{tiJ%v3pvo+D)zd<%hdYJsgealE!x!%}yB1Nn{&v)c*UPdFv1Lw*0ix#wLiC z!Vg1BeRnX7Y*kB|t#7t^gGUvqVag;)^0^OA&kEeI0J5Y4KFpE+)USZQv7I z3C=!*h?V4kbeknsI{&T}({Gq!04u%xwjXu$-X!18C`=pDzt6{kX5W)*pSu1HW^+j4 ztZ!i+=cuL)zg)BWk;|TDzcF55t2nnlYSM=v`RxTKEGnxf<5lVdo|P+HR=sKQ*Jm_; z{Dc5j-oH)B?9r!dQFBAxe>Oiq<~gGu*tB0amKnDOHe0+OKIxOss^pxL){+!7WUlxU z;v?})Se(sG)NUxAd^#EJL2N`8Zbq%ybiO;*{r^=MY48QQo_G5p-aey#Ss%6o_XP`+ zggjbGwH*q`4KB!3Q$i*8eK-DZV@;sYSv$h4pYxO(5AAo*$Pa_g{G4?S0fAAp%r3M` zAI#qv(w21FZ!LLSN`8kG~%UebrC>{J>>GErwrn(GzQ+gV>of zN24n32Kwal$Ta;!GRai^=za0He%<>Wa$n4ubyjKADS3jh-2d%U2b2|kR?6~*jd^l} zJG<+@HFy3=rI7aA1Yd!$G^@bNp^)WbnzqZ>>k(7NO@i)TXSk=74*F1aAyu-)5?fmJHvqRFL z6LO9|=lb^ntd3Y%QX91bFYJ?vl2pF7q#&c62NdvedqH zcagyt`%NHg3fB&w@b--%ckf3RP+H!SggTT_TL5+qhv@y&R5;R@d)kI)Z~xewV@%SS zgE^+1xsDyKo7wsM-TdPHTK2#@)fI3x==Mf3V&ewlLFHzr@C z!-ego56m`!W8HtqZSQ^ocUC>t!e1VQ|8%2sTh{{()d#m7L)?FgFmd3R||Gnb1aqk{^_p4{y+?kig6!(d~ zq+42E2XRlJO({5<7fd4oGTPQeZ#xN~V8RmHKig|nYF5r#Hub_YM5^6{Ntk0Y_~sWc zP3eE=^WloMZ`qobOj6PZ+z_^;URjawN@Tv%->|<|GJgiKACkIcGDw6l$?R{7dFDO zHPmka(*B(=}L zb#+ZK_~-*j0ll;pNwjqZ$;;70%Z(Ya!z(dTl3EZ)&|oA$>6zk@c?52a)Yq$t$Y;rD z@cX9f@;M8i97Em};YYhd_ULQ#_WQr~t^+WNGW&m1w%7DV3!x@d3pUiCr(X5Wf(q(c z?(7A7MF}G6*$Xy21;q-Y=y_-Pdm071pp=9VN&=*p&2F;2%=~|Eb|=|{as&esoews% zJLM~HzWL32?|WtBq)D97`A1o2neNx6S+=;m%oPZQ2RkhK9I38cCr3Zv&8dHih_>Nv z5gpsq2GbO{>`>lBLgUUCP-lw-QM4KeF%W%*iA7{2?3i?}%CFYmH|<#LhJRq6IWv<@ zGLVsz51F;>-}PMf?^BT+1v$v!tZiUxTK%yiry#@{)?QLE?@A@6)Dbr?m@YVTpRNsA z?Nvx!Jt)m;vc=k1q_yf^gm1o$hM`Ib^u4p}DZqA}XPkV```=WZ!}dmSf5)=JS}P1xJM89vt$ zO2>(ur?7?+&3cn{1TX3fIGt%iSQZbK^!5xNq7qlTeasyUBWRrr@h&d94~N?cXSA_K zq%f@Y0WOhy(hN%s?1z#$?_-SAYt92;TLB6Bsyz?4T;hk01;8OHfs(~mD z<5uw8a2r-kw|;d})eCoglr*3Anh^W*!d=hM{n?9s)RuZPMqd5w?JRrz-5Z+QW2Ey? z^**ElCC*`Djzcv2x8Lli@AlDHo#J|*&jfN9S+0l zX6Qir+}@YOHR`4GWRiZ1xEInD}t-1n~cn=7Z_!;7G%WriXjZ1!UQP~ z5uR))#bK_BBg~5n+X5lh6bzvT85yA&PyU9)1yDN#Mo|3Imnfb;&H}$f{30iAb3a!zpqoW>BMt1q7fn>LLx?nXToo?W!+^B|mWk+dz^bD|~o8S1T!HW%r$Sa*FE9=gM`O^j=+I_0Z- z&t0Y}EqmG4{yjbEZJd9>y??jn6+VuTzox3T4uoov1QAbflIvWeZ(X;0uRttO3lWrn zi?}ZOj{JQx0T{pwSOX3ftQAy*uriN>903r${ed`&%89N*&^X>eXW<+bs1nsH8+yR# z7>z-F!6YA7zpH(r>M7}Grr9KBnV_VpTmMAGyh~@`ytt1h%tX{{e)?8MoGpepTU_+; zS#K_C)eSgjV@rED&uP;;gfI&=ZCq6U#Vd~;e9DY#!@AV7o5BXfNRP1;hTsw%4R4h# ze)cA|{madJ(hqupVl@^2cin$g|9be1Panmc!&iLg2K{4Q(gYD1zM6`Gs54aiL)pEj zABMJJdj?T3t~%M1t{f2OU`qVLOP3gsTX_3BYZ_Q;n%hs29T5^1L#LaG2%0gI!6=Ng zg@e($m4|%y|)N|xq?-V0U z?xzWT5bXnAe@!iOJbZR^&IyznMlTE@_cq9J9h zs1q|_aFfsRq78CA4Dq8?z>->bL*4hQpSf-g#-JG1DoXeAav3+f8-A-?(&*{e4^AC( z;u`SEm<~l{6Vhl6D}%dym^|$#DkDpBMqybSS}TqFN8%;USw8_ zg(0dmI9Hqz^#ZCq4M>&q#@ZiO&TC#$vWfbeJQtD{iFAl@^;umk^@z>zh9G+@Rc{5- zVMUyiN2eH(Md-WpE9YPL;sN(E?!}Ero;$s`tpA;=>ZV3r`Rpt?cYH}teHKN;ME2vz zNXYnEa?|IZ-~PvAl~E>%UO&gEyTsE8&ZBO>_N2P1%CD}-|`Q@jKa!)Ji-iO|_NE`zmMg^!~Zh>q* zW@hl$w+EZ5=5C&U?SnY1gd9o$cyFry-{&ggE+-GU__3Q(tkx<1P-HC^4VY6ivJW!a zQYLa{hq0x(xv9COX>r~9Z{A~{KDXtto1Z((=p1-al!-@#MTgFfP|z*@AZrVSi3i0J zhJ;8727MOqi$?uzUq!>=P2fNSCcQ4rW;Kttr=*Y5>2=KKYI^>QS*K7!j7Z`IOd_sA z$Ybt)XPHYk;Lq#e@QnydIz+)x3ehT<&|8VkWlyhv`25RDk_>R;XZ5eYdpg7V*Qj>h zTN~AvI6ZB&DAsj>?QA3E4<%WklL5 zsiWbwibwx86Q^uZI@F~C=!^bQ(=xm2aYKGooK*Gn<;xS5a>CR(rwz}{IMeQM3IcHyWQb1zIuNx3c-i*0JH*>?P91TVb!Sy?y#5-xJgU2omn zVH|MF4|VPsZ1M!fI24tr_ErO(Hl5AC?d$S?oH-f0$*rp2m@w=}i(U!{JFB2y?dzJ% z_M%&tu67ynhSYmJuv3Y9uhUpW%uj!eiyfSoB3OLY4}M-U^~Si(pYqi1J!{Y#LM2VA zL#}^jnm%>#GmTQJeRH!Xn4g(y%#!NXe|_i4MW~W=8aqtD;)Jz7HEBNLk4e8+1u!}cL_zOCz!DAY79 zcMy$L7qkqkRfN4&OWECjCVQ)GAX1;Ml=cmMdsoY@=2q`&=|^X)4|B@#e;t=|#Oa?k z%1)=tABY(!Qwv_{3PDKj$Gty1$Hp7|TW=|yb>=@3A|>gKdi&hWeK$=wQLIX9Xh-xs|7>Y2^`sUR)Ry=<3gP31>xF|tRq*8>C zpk?$u;h%YVXT;Fqmpy(X0$@x|vFZQIIfp*>O*0Hdq^Jy#Qk0ssh=k}HlEq-;^F&|7 zv*DBD>XtmTVkg|V(o%o>v;Sw~0YD*D={R)y%-@?v9P{tZejO$rveY2K0wEGjD7*k+ zO~iAD=UA}Hv;DH=C1*aP+Pdt+A#_?#A2IWdg^`ru=Y3z(7J}=pV1*bI51Asf5W+xD z%0c9owu-C2zUP7`y7XKXC!T9L=Fs2%1<(KVm??EirPpL~g`zU~;HjGX9#<+q zcR4wBd0=O?^kQEEaw*me;+Qk1Q4hmZa17ph7xOl~(Nw--LF<2C`L46ZE{?f#*FO2u z)s7|qnnfQNa>q<=^!QjfszifINJ#r@S4u zaM37-=(5AfYO(fc@^9%B-x7mHASh2?pa^S=qm@|8#+tdDKC_9%2E z{hLY)8neQ^;~;^RN&}j4MQIk!!Fhv%6!}pWbWTHR)~KyNF2AVq=_~)K&IcNr`m#LY zwiixf*1@l@a!JlG%sEtpTWSk!$_R}pjZ8BOQvI4a8|Phi=YEq6sFVAls5IRVO&xGe zbSkJvUG?mPNUe4K`j(EUL5{&sEv}TNw`3R*Dk&boA*q;bo~_fry6^ng_6caI+z_%M zA3FO#6#;8rZmeP5sz~eBMf!|_i{Uponqofj@Eb(LNY0DZrA&)iC@^-k*KH_0eCwk7 z*LUNz)cQsokvDPL%<3QfaB>TUBAm!0IC0lQbD-Q6Wg_B%gD(#^&MvX`HOr=NS^Cs# zYX2xn!#0;!&R`i*cUv^|jQy}pS}`7ccFAgfP@<;!60T2vYEjrS(KeVfV7G*U3v+I4* zYZ|}u!W(tXf(6lx!t>!w95r&1sIH_DXi-KNy! z54z!{iyQ@G=hv=Zxv28-zh8|0k>Oz8=o?;qg{6%=77O_ByNg8hoFq`Xt$e3d%oE-2 zmg<$isrcueE2knX3DUunR3)o6J0oX2_n4SB@#^(W@cEM<`I0E8zUFb_?n?3m*~3eA zSKV%psiIQ8-NX+x`YQrWTdw-ZWqV*(e4tYRGfwBq3E|QLodAdTtmu$ z(>c9mf~>c}w#p3qeHux;d&FrW*E|zrJ{IMXV^K7b12XhXacaUwj&cq#&fko@*fq~@ ze(H*AadBr7h-9$hQu9A3_ZkEw{!qdktN9hFB?7B_L|`zsZTR>42hX7lK&0T?VL?XO z-;e(!&&Pf|jGxf;q?=lJ!%J@lQ%0S(rNt95B6=lFDf+0OWdLYRaB@uVuRinhIp;6# zOLjX^S8P(rvUl;4KIHqmPR*rJo%q0qmXB^c$%n6o;g>viw=Qka)e&o+-sKCij!;+* zhohnV6pJxebT@4N{=?%N-g%;&u8S8;*tp@Oq3F7W?@C!kCvIr=NU)|x$|;zJV{q}u zMm@j#R-GJVDNWCmB9G#f-RZr$*U$=OFI7F6RB53wu96Smhs?-rNqS z=}dpSr?KLxE68CujtaeR=BHkfY^s$B zT8<1|gAEq@Sj4^`!t=Te=(}LQ9COK`jx}vtR{p!`gBO&beJaqXFR>$UdHzJ%KKQ-$ z9eUVtb%7N%90z$0xfSg?Q^)4d*WW+=MC=arv7@&-#-Dww&dHy>BR^{gx>$W~^bIe6 z5>6ReOyUlABfS$mmc8EAlhta5{m4^XpjPx~FqE{9tI@{>+g|6+ozQ@7c z{G@9L3<0DhT4BvY;0M{vVw%OkY`7UlxbnKUSJc+m)n2jvrCZ)fh&(;JzMB^M{1AYv z1YQPx69YZ2WT#t!#lgigPk{|5-~Q6ns3q@>vUZW{2nJz;))iS*v9-dg@!&Lv&eE~v z+w%LT9fuM6eyLzZcaP?XR)_*!N>y9YO|O0&bQDa2-BScQ?{1(4Css*9c7?;UU}5d8 zzUQ;q({5KT$Mw5&P~9z&E7%Znvq}X>u5f;anT)B!_IrWAZJKU2~;9Ab=7NM z-t^*}vZQ*l^3R@mv@vDCWX@nN3d{N&yVd06f*q!s`kE^m7v1vu&Q^zpo;T+LQ*Pno zA?rZvwzdvA9E-+a9|VOlSvhnmUua^4paL0!m@d|+YdeIR6xo_-bs>yGb07$@nL%vc zInWX4Aa0cmMYOU?u(R`Us9RA1j<{Ky!N7ESe29IBL5&>pAXA2Sy{Dz_rRIg#J&C;? zDi_kNlArH~5}Ex$)x~L%$pcy4U|Cw4knIqhk@^oyXa4z2H0bHJ zQnyzxhHVB?mS*6rj{r@V|1%`|66hfBlS& z`rX8Wlg_xzU`Z{OjgG7koN>LO2y|m1*cc(GJCJC63KzA>ZL@0{rRS@kI)g$Y4~1*f z(pXBtgbgllRFGndb2aJ15;2$L0^}ky2WmEl^!7B#Ho)27?jTzwm{rO=Wrrq^qe4%q z3Sf#Z2D0f;EM{iw18&*hvN+Pb@%itcpZl$Ha?d~Kml&C^FrsiJJ&*On-$^e!?%2ED ze#U3Yz4-h3cEpyEU@wQjjGzrsjp#&RH5fW8TVQ+Dx_htu4P%X4lCJNEqu=u`Yk;*A zS|x#&v*^ZGJ_H1Fc&Wy?=-AwJF(uNlX4@AFPOARTl7_^}4!L!y z&*M&7*~KmetY+alWfh7YH1q9M4MNt$I!}8P>Z6$1C>rvewzxrM#EW2g(RM+O`FTkS zN1+ziTg?M}t@Zw|-+%9qN1lAz-9Bsnk*n*Pl%Bw1oMl^0NC}UX^pM*n%AuvfrY#?B z`(|0AFLT_Ww1I`iI&0b?oX%Xpiw0YOGcYR*H&abAYpPuRT*b3jUy>M;vGAJb-;lG% zoV?xTBQQc>#CY@=#H5mP%qD(_*tTs`>1#LH$4r@QaAaQ@GG#M&Ak5q$2-T3P(V;|Y zdwLGz(~w>Su7z+iyaFkX#5x0xN|B+M)ydlUTqAGh}uOtXUCJ;Iu{(~tt6Eh<3i@&DA+fu*n zk*11Gk9bx*-KNkX0q(n?<^jAL`m4pzUqQJ(@sj(-+Xs((t5HrHTG8x=e=8GJgRb~P z3J(W~i$V+(&7Ljal|L|zY_;ltO<+YgGER#F_?G^xUF*_mu~FA9ToTI|eL51EM)_Dw zh$nrB_bwjgL5}9wtYW^&FX;jemwh(p-1&4g3HbJSC@OnD;hJav5=k5Vc3Ep!9&Trx z!B@L7YH$pftl4&Wh2Z(dKZpt<*6j5DMqi+{=H9CLGv*yTXXz6@)8KQzM|vj%02X$M z%mPI=iF(L>92J0Ggb4&7ssU)1%F1lh7RVxpdn$Zk)bl(aqnZ z^GP0-K>?*pa4ngXGg;h7Zl1hDkKvbJH{>!H_ge;Efo z@iUb9+b=n*WPR1-TNj+m>;sMJLPYXc+bvnIx zNG7-ef9?EF0>2)?)X`?ehwT<5TR(v z?3{umHU)^+q>}|iR;O8jnBzjEBY=Q(mA=-kOSb;=#uu>Hb9Bkl=l$jZXKnR_nO!d` zMzmJIqyYx_Vzj+d4td`E;;m&5v9cvD!_Y}12K{E*-^7#wf0azB*-U4K$OpX(q`ow} zjpaD>EYeuXwpVYtYU}gY?9|R|7vocQ$ASDa0M%ZI*}JQFe;tE6~-_ zNlmF>w7X_i4r{{o3ubs7BOWC#&eT?RW!a;bJgFR8^{wfMqJdYKY_@~o2W>($%cDa2 zw3N-R07bHl+5}D{UqgqP@UAK**gBH{M3=fLycBz4)B(bMI-G# zcdOT8G)J?Cj>$AQQ%{fahCj4M&8)1sJxW36lz0T>l0pED_)d9NBS(Ss41v1VKvVU( zKg_#I%?h0{q=`MKh*F3s`r#Se)Me%&f=`O^BN>)T4jp|`7)IS z)=uR*Ej|QbA@4Mq#9Vy{5#HC_xbeB`DVi$S%RbAis8rYA{%C;JyE_IYY1{%ir=i+6rO=Zw8-{>{$OlkaP6?Er3Yuv!l?mp>R2c$uR} zmXx~8s1x~NPCXy2`u_S&&t3bl0+ekj($uMBpSaTuEPU44_dlAE>X>M^*$2f0z2u8X zQNKQISZx3bU!<_2l|WcmC=3~Km9!!V@QMyjap<#IYp`|Onj<$of9ntGICj6qqCvk^ zmhXOK-Hw8*QX|J=ziG-{Z_Nvtb1z))3bQt(WwRvWuPg5WoIo!-@(av!*mU-AW5BoR zt24JP{>Q%*4xMf`ElK=}3oUYKWzQ)f(~3?4P*xz?<&m&SdTn^dh(kBEy5VmJ<#)nn zhT>|&jY14XLekeYVR=ke-YFB$pL?+Esk#_-d`L~Iz|^z((z0fnzpQ2bm#b1zhBBj` z545#Z)T`&Y>o)y2Y|Zj-j#|yJFoH2bEJd?I45CH^j<;DBlbB(IvCg(1?W@Sov$~cI_Fs)+xt!>_bV?d6{YO6T`*ZiP_x+yJ}ii?kB#jIFDVjpEZWYJAI z_u|nO6ovw)|8k3Ze@j8jqpp4YXkEter(HsN(ds(4#6fk~U0;P*^)R-I;x-OVcj%0s z&FgDFUwn?|>$g@>J-{j$eEhn>ie`$&VG$Mfq9loS1|&0mQqCCpw^}4K#Y&u#8eDZO zCJ~W7urG>aSxveEn@q9D7goG;_lUbJ||A%2az{*`xAat8gW zX2s%R+m}7DS&e%&>~Hs8s2_aT^A&DMPJxq5I@uFoHBbt+Bd~X1tGB-5o^6ZnR8}g{ zJl$snG_dV;88H3Mvu(MfZj+48!k8h21;Y{I>SS zLmABD^Q+|qC_xD8;$$sTX1_TntWUdkYf#T>kjaQl7Ra7YB@nn)5&>f-olY3!Fap)( zUFBO8?9*LhB_)=|rIvC9Ns*4FTXH29SU^G=>26rMyFrxhM?!=J>0XeKkVZnfLFC8# zcf9j)KF)p5TxZVAHAlGPzke7a9(26jn;e^Ooz7joM6b}dP%j~s8__>KceRsNG?Htx zWv&+oQYaK9y4hZb15SRDL3!O^2t~yFSYq~j=8OoO@M%_01UMGPloi5?tEF~KNCOtK z?9HxOz{Ju)4L8Ue|FHSp3NQ{NwpCU zBy*}lzhPAsoP`9Zsx#sLarfagllqxv>JrB;c;wz9Witx*mZP!Ga$mZ1E_~s)Ehb>> za^K#qx=j-3+1YxUqDJX-S)N-UuKyeC(q%mQ{JMdhn#JHI9RGQ_q2qcl{7)4m8y?H^ zv_Prh)6=FGh2OS$+THrt*)4YKT-cNPJF8@QgKGY~1ggF_q~nt211+ETynOSe`gV>V z8gh_Jh@OffhZI0$rxsHQBZNQ2331G;*Erh7r`>S>B>#P^FfbNybs+b7MWET8@RSg{ z8g)OgyQ$6vCHWcmU+vxL#)jnKHd94GBSaBGH?y~myw49!{|dk!+^yNY&1qrue}=pe zP4IcY%VaE8C!9x>pZhoD0PVQT>kUXY^!sIqriil9&^ zTe&{5=Q_FTAHs#-3@{aXEG;|pCQU2xE|b;M{5AL;L(7bvlY)-f2EuX6$hgN&&D#nX zYn^utt}sWG^(A*iTfP-f;Nt3~y&KKn109ukp+$RKF4W5?SkNrzYQbqU zF|}G$Sg6I*@6y0F`%Ud#5|(^7Jon@;e$tQgtM9D^4r#}K!Zu1a%T4mAi*PCEmJ)m& zdizKV21xUo>w6gD88%V)|Mt?A;2kcDZ|`K|wDuqAI@ZspZI&6Y2R$E!)#F<`1Fp&= zA9((1N@@l?2&G%NzzWB6fEUF*5iz=|rd?u{ZsYDOfwqRJc&ofB8S-gBUy4Z_rNSaM zr2`k_ppYEheEWMkd9+%?SAJJ#6*Gm;_GNg$SLi)hQsHSTN8K%aRQl^Cc)G|n@pjbb zz479LN=@bq2?_nC}`*SyjY>oS3^|M zOvA_HF4CFD*82!E^{&cs@2akN@*B@1JA|E|el>{^?mD*lRp60mR%qDTNrmA>;%G{WIhn3+45d#D{M6b^Oz;wvg-Cj#a*AeG zQ~shJI|T88hHGEQNLq}QssA#&YRB}7K&S1f&m1M1?<*?a?#E>) zzSX@KpCNK8imKk7djfy;tK_uegNh2coWty4^Br5&x9_}SZe3>?KF2FE9(qMN32 z5vJ2AF;s$T=-aC(FbF93jEg9S8)U*4gS}wTePg|Os)a6XAZede?zJ$ z@3?a2`7qd!G#CG)0RW+O+7p%42ZqX;(<;G6sl@b9XJ-I6uL+hJw=!nnV+demt zdsKCuG-@2pmFr{d3=(HFE+%;$tHR}ZI4I(AwHQP3oZMH2 zinPoIRh(Lkdd#d^??hAHnWo{1IfMcc`qe%g4Cxcg%IjUj`tKpDjN`PAh%iaZ&%?;8 zYO@0)XzH!3IVL?FkwvN@6(leJ1k3>L*IQKuQ6x|0{U*|3Kz!PJjvormwB?gG5G` z%QO%W$S%(i_h920_yug{nJ|K)(momwseY=fp;zbl@BdQhmI-$+>^qop3KA!fUUtYbeVAuW zFXHLc%m2KK(FZ$V5E9aCth_{(=qG=GAp{{6FT-eXT%y10{Na{67EIl|4+kR7q_X{f z3FIkG;8BCDiaY$HWyn=`z25Fx)My_pAFv@6>~vGS{n_94{-TrO`=_$s2|;;ZsMjd!u3A-EzxPgiWyVaD#D9Up{YcC ziloj?d@EXjJvsM zC_MHi=FszRQufkhRf)Oi9)%$XmQt6Db($Q#HjiNjqM!-7sc|BKjc6$h%dBTOSv*c1 zfihYd8*AAwXJx0cS=UeKBQF7R^d!d&Me z*5mhGz=0ez=_;!ui23==M+DDDvp>`0Q7v;Dx^cEyip{Q`LD3QOzmScCiCz2V+VDc; zbeKFjr7CU3cn$Y7$_1e9^-Ys7fDLH8^6U0TM49n|SgBhhXx=7$oM%gL6%jupsXx~> z5$P4IHwxqIOVxZ)O17aX@D%n?t?T5s_B9i8{;6!>689@=y2zs79KzA}C{$SG3I-?UuYBwll3eKQ3_yoJv{}s8hA8 zYm<=qp6@%^2753sbuv~d$W4S;Nco-r$8S7d>@*ZirNC5z-Ot9xr{7CX)w;8t+^Wpt z9)>DSD9jssw|~6 z6Uf_pza3&>bNj@dK&VBov{l0!`^w4Nb|coSBUCpnBJo`V(_Qma6y+qKiZuF$qDsdh zAcc|7d|tF^;&BGn%3(bw);nNmkUBR2X|UCk2b=dkgI!*W3@8XE7icc5hs3y0}4R8dZKbwCM{>>{nmlFS}nsjC7c1PXHmF} z2x67YK4LDAm&-BWe6}wBi=K3wYxm2|^wj|+<9k-fpAFe7IW9bEAONvERp@qOvwX`b zcepdsVC11QnH3Vn9nSZ9aF2apx_`RSSHPPcPV+T{=G??T1GoyTMUx%i@3kstlRd3L zb|+AU%sNW@i#{a0ND3*KabmB<8PVD%h}Kis+WJ6{-|&DYcFYX658d#>&MLo&>sc=l zd%jSUHWc*DCyB-R2W<46G^C#{A;G2n#2jON2>2mYs&d4Cw>(CfnRFXh|#Vx(061+5Zagp(lya74+Gs*On$=*hp2=Up!*sV zbESq1_54|y-sMpX*?ekYwUDh^A$4PhzF-dLFUbqV>`i%K#`L?n@W+WtSQYTMvNZ>O zLw?Fvstj-=vZBeIwKhxA2X(J;KLXxaAFSw&4B-*s0}CRUHkygjZQ6;8t+;v=g)ODPX_$9_)F+WLmu z2-zl7EAhD%HT0?&i`gj>tPSz~&@qNw)m49D9pgi8-)p1 zR0rDd(DI14f^v=mVztKKC}?>SPUn@&)B5kt3}l`5YglHatqc%X_yqpymGDM>TdO}s zgScDVtI0aQgSV4HW406teMcV3_8>)VZ%UtmEao)sQ;Nv|USB)`rpoxm$?_ zZ{OZ(-E!|x19bp*<4aH~BB`i@o8B|Gq}$q`G#o%bs2)Fm+>MXaCIR+nhZWISk!zI- z?j>>IRI*00P5W9V34aQ^f>rW%$DF^{{P=}Fyh#A-)h@Z_Xew=C%$Amt{HqY6sqQ0C z4C_ZO`=<&9%-ANvbaN?2V4Sk!Fms$}T7qGk(7DP}$gO$s$ zzAXD@;g^!^lJFOvz}2o+Hu-SYd($C0H4(BxWt7o>r*2xohlTK42B2#DPgnN#LV-Vd zDHOfuEV@>u_w!l&Lac*yhT@G}esbpFiE_T;-2bJ{qc{!Qj`nnwj2B=C+7Mc+U6`Ia zN^v+Wx@$gqAN6cQfkBNNXgwJ{8vYWYOW8mHS5?Q$RAkErdQmI*pW+86tv_^oLkrw< z#$#W=&|1%OWM13JQYn{*CMW>-LA;IlImv9A7$}QFeF}t_fY0EWR0F=AVv<9MEUvn0 z3-lZ)1+b!But<#I7zR*m^h5@$eJZC-nPN(4*}Ldq7_!nJiv|W&MUl2-_8YZyncPgN z$0Wf@>UAicV*Fo!mAxyEYCf2d!Mf=DN33D5aftIuwmLLw zD^1ui-_+ng@i&=P{u3FIl1d?tKL8YsCQiSH;A(Zp-YTZb-A_7G*7G-l`&DoO=f*c` zVnG&b>p{Dq;M@{TIiO6ch!pl@ut78t0c8cKjBE-JowiU;?GfbfSz1Q+>nc-=%N zC*F(M6c}(MfjTM&1+agKl}&QZBYA&xK<4)nU=&6P;GCHq1}?tsUD*FO-FiOzaOQ2G z-@zep`6JFz-w15Gc%3FP>05ST!~0wdyEgWuj~KSKj(PS&Z0hXua$q=%<1s-VMoN?; zhsg31rCb)Q8aw!=hb3G(s06{jF3CkOLF@R@`QHt}y{g?QWbdE$ zwg8v-`Kim1SXZY-RokhRZ;v2bK9VMNln6uhZjc&Eg-bhEH_>hpCmeh4URtKT)T7k- zxmHQ=+xK1ylKNv-Opj7Tei#C!lZ25G3D61z#afRDE zGh*J4x5(=M!>q68-%-iGe%`+`D*+}~CsP85X{s4nAQV}^ae6W2xcEE$&pXpUXRrTz za>)dw{61`fvK2qcFEynVOqB8omwc#q4Sji`^$VHHOwf<5GWi=ln38y+{F3*Kn=Bs2 zNfjmq9qyS2nFiOW0G>48>QOKTf|ie?rf50Gsy^1ao3=~=J;LL{lah2;40?Lv##zZz zV@lj{_z18CV;~d_?DyFupL?DX*txRh#78`9wRLF%U)IF?7svbIz(_0KP zNXqhkPM{{v&~CJ4>?W`gyg`^Z)F;#yFcXa z1wo~EcwzL8DW4hfwj`k|Dn|-!hN1up5q1EmY>zoPK>-_C2O-~t*hQAUUbbn~5_icAxq@2~ZCK7?{5q zSS_IXyvc~jD`R>krdGf86qBv{p~z?=`Qnp9g5XDN%W6KA`tOw8P}dTwcDD}<*w~m7 zwlI%~P`%zb@-z8C1x8*2QZ^OR$ea(oq!jqV0;N9nDSbl7522E4zs%gT9lY%-3w~m7e>r=Qn!p8N^G7~XXJEGt z19%?gz~7)|W#qe_ffPZp6*j|ZAZ&Ku!Z$WSScI6boDAv0u8Md*93h)RNf;iE;smFM zX?GvR%+}RG{5U}?gS>B&@f(({pdsl2P%eesV?S=LG(&RP*Or_-MTzjh;z!81PvdKO z=WX!n&0`(?1i|xj!yaAlj2L7VjJ@U@bPmujBIU{+Yi;adkI@wj(Rm{Cp5W$|8!9VK z&v!vpac3+^kGyCR_guXc=Fe0`m$7>^Ry)kORin_H+N!oy0P=v{g*RQzCE7Bj!HQV% p*z~|xgtnBE&x`*5I?mq`{*{K!WUL0&oY4UuO+`UdzE&0)`ajOt5gh;k diff --git a/vendor/gitea.com/macaron/macaron/recovery.go b/vendor/gitea.com/macaron/macaron/recovery.go deleted file mode 100644 index 1d301f721890f..0000000000000 --- a/vendor/gitea.com/macaron/macaron/recovery.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2013 Martini Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import ( - "bytes" - "fmt" - "io/ioutil" - "log" - "net/http" - "runtime" - - "gitea.com/macaron/inject" -) - -const ( - panicHtml = ` -PANIC: %s - - - -

PANIC

-
%s
-
%s
- -` -) - -var ( - dunno = []byte("???") - centerDot = []byte("·") - dot = []byte(".") - slash = []byte("/") -) - -// stack returns a nicely formated stack frame, skipping skip frames -func stack(skip int) []byte { - buf := new(bytes.Buffer) // the returned data - // As we loop, we open files and read them. These variables record the currently - // loaded file. - var lines [][]byte - var lastFile string - for i := skip; ; i++ { // Skip the expected number of frames - pc, file, line, ok := runtime.Caller(i) - if !ok { - break - } - // Print this much at least. If we can't find the source, it won't show. - fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc) - if file != lastFile { - data, err := ioutil.ReadFile(file) - if err != nil { - continue - } - lines = bytes.Split(data, []byte{'\n'}) - lastFile = file - } - fmt.Fprintf(buf, "\t%s: %s\n", function(pc), source(lines, line)) - } - return buf.Bytes() -} - -// source returns a space-trimmed slice of the n'th line. -func source(lines [][]byte, n int) []byte { - n-- // in stack trace, lines are 1-indexed but our array is 0-indexed - if n < 0 || n >= len(lines) { - return dunno - } - return bytes.TrimSpace(lines[n]) -} - -// function returns, if possible, the name of the function containing the PC. -func function(pc uintptr) []byte { - fn := runtime.FuncForPC(pc) - if fn == nil { - return dunno - } - name := []byte(fn.Name()) - // The name includes the path name to the package, which is unnecessary - // since the file name is already included. Plus, it has center dots. - // That is, we see - // runtime/debug.*T·ptrmethod - // and want - // *T.ptrmethod - // Also the package path might contains dot (e.g. code.google.com/...), - // so first eliminate the path prefix - if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 { - name = name[lastslash+1:] - } - if period := bytes.Index(name, dot); period >= 0 { - name = name[period+1:] - } - name = bytes.Replace(name, centerDot, dot, -1) - return name -} - -// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one. -// While Martini is in development mode, Recovery will also output the panic as HTML. -func Recovery() Handler { - return func(c *Context, log *log.Logger) { - defer func() { - if err := recover(); err != nil { - stack := stack(3) - log.Printf("PANIC: %s\n%s", err, stack) - - // Lookup the current responsewriter - val := c.GetVal(inject.InterfaceOf((*http.ResponseWriter)(nil))) - res := val.Interface().(http.ResponseWriter) - - // respond with panic message while in development mode - var body []byte - if Env == DEV { - res.Header().Set("Content-Type", "text/html") - body = []byte(fmt.Sprintf(panicHtml, err, err, stack)) - } - - res.WriteHeader(http.StatusInternalServerError) - if nil != body { - _, _ = res.Write(body) - } - } - }() - - c.Next() - } -} diff --git a/vendor/gitea.com/macaron/macaron/render.go b/vendor/gitea.com/macaron/macaron/render.go deleted file mode 100644 index 04687c4f403e9..0000000000000 --- a/vendor/gitea.com/macaron/macaron/render.go +++ /dev/null @@ -1,724 +0,0 @@ -// Copyright 2013 Martini Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import ( - "bytes" - "encoding/json" - "encoding/xml" - "fmt" - "html/template" - "io" - "io/ioutil" - "net/http" - "os" - "path" - "path/filepath" - "strings" - "sync" - "time" - - "github.com/unknwon/com" -) - -const ( - _CONTENT_TYPE = "Content-Type" - _CONTENT_BINARY = "application/octet-stream" - _CONTENT_JSON = "application/json" - _CONTENT_HTML = "text/html" - _CONTENT_PLAIN = "text/plain" - _CONTENT_XHTML = "application/xhtml+xml" - _CONTENT_XML = "text/xml" - _DEFAULT_CHARSET = "UTF-8" -) - -var ( - // Provides a temporary buffer to execute templates into and catch errors. - bufpool = sync.Pool{ - New: func() interface{} { return new(bytes.Buffer) }, - } - - // Included helper functions for use when rendering html - helperFuncs = template.FuncMap{ - "yield": func() (string, error) { - return "", fmt.Errorf("yield called with no layout defined") - }, - "current": func() (string, error) { - return "", nil - }, - } -) - -type ( - // TemplateFile represents a interface of template file that has name and can be read. - TemplateFile interface { - Name() string - Data() []byte - Ext() string - } - // TemplateFileSystem represents a interface of template file system that able to list all files. - TemplateFileSystem interface { - ListFiles() []TemplateFile - Get(string) (io.Reader, error) - } - - // Delims represents a set of Left and Right delimiters for HTML template rendering - Delims struct { - // Left delimiter, defaults to {{ - Left string - // Right delimiter, defaults to }} - Right string - } - - // RenderOptions represents a struct for specifying configuration options for the Render middleware. - RenderOptions struct { - // Directory to load templates. Default is "templates". - Directory string - // Addtional directories to overwite templates. - AppendDirectories []string - // Layout template name. Will not render a layout if "". Default is to "". - Layout string - // Extensions to parse template files from. Defaults are [".tmpl", ".html"]. - Extensions []string - // Funcs is a slice of FuncMaps to apply to the template upon compilation. This is useful for helper functions. Default is []. - Funcs []template.FuncMap - // Delims sets the action delimiters to the specified strings in the Delims struct. - Delims Delims - // Appends the given charset to the Content-Type header. Default is "UTF-8". - Charset string - // Outputs human readable JSON. - IndentJSON bool - // Outputs human readable XML. - IndentXML bool - // Prefixes the JSON output with the given bytes. - PrefixJSON []byte - // Prefixes the XML output with the given bytes. - PrefixXML []byte - // Allows changing of output to XHTML instead of HTML. Default is "text/html" - HTMLContentType string - // TemplateFileSystem is the interface for supporting any implmentation of template file system. - TemplateFileSystem - } - - // HTMLOptions is a struct for overriding some rendering Options for specific HTML call - HTMLOptions struct { - // Layout template name. Overrides Options.Layout. - Layout string - } - - Render interface { - http.ResponseWriter - SetResponseWriter(http.ResponseWriter) - - JSON(int, interface{}) - JSONString(interface{}) (string, error) - RawData(int, []byte) // Serve content as binary - PlainText(int, []byte) // Serve content as plain text - HTML(int, string, interface{}, ...HTMLOptions) - HTMLSet(int, string, string, interface{}, ...HTMLOptions) - HTMLSetString(string, string, interface{}, ...HTMLOptions) (string, error) - HTMLString(string, interface{}, ...HTMLOptions) (string, error) - HTMLSetBytes(string, string, interface{}, ...HTMLOptions) ([]byte, error) - HTMLBytes(string, interface{}, ...HTMLOptions) ([]byte, error) - XML(int, interface{}) - Error(int, ...string) - Status(int) - SetTemplatePath(string, string) - HasTemplateSet(string) bool - } -) - -// TplFile implements TemplateFile interface. -type TplFile struct { - name string - data []byte - ext string -} - -// NewTplFile cerates new template file with given name and data. -func NewTplFile(name string, data []byte, ext string) *TplFile { - return &TplFile{name, data, ext} -} - -func (f *TplFile) Name() string { - return f.name -} - -func (f *TplFile) Data() []byte { - return f.data -} - -func (f *TplFile) Ext() string { - return f.ext -} - -// TplFileSystem implements TemplateFileSystem interface. -type TplFileSystem struct { - files []TemplateFile -} - -// NewTemplateFileSystem creates new template file system with given options. -func NewTemplateFileSystem(opt RenderOptions, omitData bool) TplFileSystem { - fs := TplFileSystem{} - fs.files = make([]TemplateFile, 0, 10) - - // Directories are composed in reverse order because later one overwrites previous ones, - // so once found, we can directly jump out of the loop. - dirs := make([]string, 0, len(opt.AppendDirectories)+1) - for i := len(opt.AppendDirectories) - 1; i >= 0; i-- { - dirs = append(dirs, opt.AppendDirectories[i]) - } - dirs = append(dirs, opt.Directory) - - var err error - for i := range dirs { - // Skip ones that does not exists for symlink test, - // but allow non-symlink ones added after start. - if !com.IsExist(dirs[i]) { - continue - } - - dirs[i], err = filepath.EvalSymlinks(dirs[i]) - if err != nil { - panic("EvalSymlinks(" + dirs[i] + "): " + err.Error()) - } - } - lastDir := dirs[len(dirs)-1] - - // We still walk the last (original) directory because it's non-sense we load templates not exist in original directory. - if err = filepath.Walk(lastDir, func(path string, info os.FileInfo, _ error) error { - r, err := filepath.Rel(lastDir, path) - if err != nil { - return err - } - - ext := GetExt(r) - - for _, extension := range opt.Extensions { - if ext != extension { - continue - } - - var data []byte - if !omitData { - // Loop over candidates of directory, break out once found. - // The file always exists because it's inside the walk function, - // and read original file is the worst case. - for i := range dirs { - path = filepath.Join(dirs[i], r) - if !com.IsFile(path) { - continue - } - - data, err = ioutil.ReadFile(path) - if err != nil { - return err - } - break - } - } - - name := filepath.ToSlash((r[0 : len(r)-len(ext)])) - fs.files = append(fs.files, NewTplFile(name, data, ext)) - } - - return nil - }); err != nil { - panic("NewTemplateFileSystem: " + err.Error()) - } - - return fs -} - -func (fs TplFileSystem) ListFiles() []TemplateFile { - return fs.files -} - -func (fs TplFileSystem) Get(name string) (io.Reader, error) { - for i := range fs.files { - if fs.files[i].Name()+fs.files[i].Ext() == name { - return bytes.NewReader(fs.files[i].Data()), nil - } - } - return nil, fmt.Errorf("file '%s' not found", name) -} - -func PrepareCharset(charset string) string { - if len(charset) != 0 { - return "; charset=" + charset - } - - return "; charset=" + _DEFAULT_CHARSET -} - -func GetExt(s string) string { - index := strings.Index(s, ".") - if index == -1 { - return "" - } - return s[index:] -} - -func compile(opt RenderOptions) *template.Template { - t := template.New(opt.Directory) - t.Delims(opt.Delims.Left, opt.Delims.Right) - // Parse an initial template in case we don't have any. - template.Must(t.Parse("Macaron")) - - if opt.TemplateFileSystem == nil { - opt.TemplateFileSystem = NewTemplateFileSystem(opt, false) - } - - for _, f := range opt.TemplateFileSystem.ListFiles() { - tmpl := t.New(f.Name()) - for _, funcs := range opt.Funcs { - tmpl.Funcs(funcs) - } - // Bomb out if parse fails. We don't want any silent server starts. - template.Must(tmpl.Funcs(helperFuncs).Parse(string(f.Data()))) - } - - return t -} - -const ( - DEFAULT_TPL_SET_NAME = "DEFAULT" -) - -// TemplateSet represents a template set of type *template.Template. -type TemplateSet struct { - lock sync.RWMutex - sets map[string]*template.Template - dirs map[string]string -} - -// NewTemplateSet initializes a new empty template set. -func NewTemplateSet() *TemplateSet { - return &TemplateSet{ - sets: make(map[string]*template.Template), - dirs: make(map[string]string), - } -} - -func (ts *TemplateSet) Set(name string, opt *RenderOptions) *template.Template { - t := compile(*opt) - - ts.lock.Lock() - defer ts.lock.Unlock() - - ts.sets[name] = t - ts.dirs[name] = opt.Directory - return t -} - -func (ts *TemplateSet) Get(name string) *template.Template { - ts.lock.RLock() - defer ts.lock.RUnlock() - - return ts.sets[name] -} - -func (ts *TemplateSet) GetDir(name string) string { - ts.lock.RLock() - defer ts.lock.RUnlock() - - return ts.dirs[name] -} - -func prepareRenderOptions(options []RenderOptions) RenderOptions { - var opt RenderOptions - if len(options) > 0 { - opt = options[0] - } - - // Defaults. - if len(opt.Directory) == 0 { - opt.Directory = "templates" - } - if len(opt.Extensions) == 0 { - opt.Extensions = []string{".tmpl", ".html"} - } - if len(opt.HTMLContentType) == 0 { - opt.HTMLContentType = _CONTENT_HTML - } - - return opt -} - -func ParseTplSet(tplSet string) (tplName string, tplDir string) { - tplSet = strings.TrimSpace(tplSet) - if len(tplSet) == 0 { - panic("empty template set argument") - } - infos := strings.Split(tplSet, ":") - if len(infos) == 1 { - tplDir = infos[0] - tplName = path.Base(tplDir) - } else { - tplName = infos[0] - tplDir = infos[1] - } - - if !com.IsDir(tplDir) { - panic("template set path does not exist or is not a directory") - } - return tplName, tplDir -} - -func renderHandler(opt RenderOptions, tplSets []string) Handler { - cs := PrepareCharset(opt.Charset) - ts := NewTemplateSet() - ts.Set(DEFAULT_TPL_SET_NAME, &opt) - - var tmpOpt RenderOptions - for _, tplSet := range tplSets { - tplName, tplDir := ParseTplSet(tplSet) - tmpOpt = opt - tmpOpt.Directory = tplDir - ts.Set(tplName, &tmpOpt) - } - - return func(ctx *Context) { - r := &TplRender{ - ResponseWriter: ctx.Resp, - TemplateSet: ts, - Opt: &opt, - CompiledCharset: cs, - } - ctx.Data["TmplLoadTimes"] = func() string { - if r.startTime.IsZero() { - return "" - } - return fmt.Sprint(time.Since(r.startTime).Nanoseconds()/1e6) + "ms" - } - - ctx.Render = r - ctx.MapTo(r, (*Render)(nil)) - } -} - -// Renderer is a Middleware that maps a macaron.Render service into the Macaron handler chain. -// An single variadic macaron.RenderOptions struct can be optionally provided to configure -// HTML rendering. The default directory for templates is "templates" and the default -// file extension is ".tmpl" and ".html". -// -// If MACARON_ENV is set to "" or "development" then templates will be recompiled on every request. For more performance, set the -// MACARON_ENV environment variable to "production". -func Renderer(options ...RenderOptions) Handler { - return renderHandler(prepareRenderOptions(options), []string{}) -} - -func Renderers(options RenderOptions, tplSets ...string) Handler { - return renderHandler(prepareRenderOptions([]RenderOptions{options}), tplSets) -} - -type TplRender struct { - http.ResponseWriter - *TemplateSet - Opt *RenderOptions - CompiledCharset string - - startTime time.Time -} - -func (r *TplRender) SetResponseWriter(rw http.ResponseWriter) { - r.ResponseWriter = rw -} - -func (r *TplRender) JSON(status int, v interface{}) { - var ( - result []byte - err error - ) - if r.Opt.IndentJSON { - result, err = json.MarshalIndent(v, "", " ") - } else { - result, err = json.Marshal(v) - } - if err != nil { - http.Error(r, err.Error(), 500) - return - } - - // json rendered fine, write out the result - r.Header().Set(_CONTENT_TYPE, _CONTENT_JSON+r.CompiledCharset) - r.WriteHeader(status) - if len(r.Opt.PrefixJSON) > 0 { - _, _ = r.Write(r.Opt.PrefixJSON) - } - _, _ = r.Write(result) -} - -func (r *TplRender) JSONString(v interface{}) (string, error) { - var result []byte - var err error - if r.Opt.IndentJSON { - result, err = json.MarshalIndent(v, "", " ") - } else { - result, err = json.Marshal(v) - } - if err != nil { - return "", err - } - return string(result), nil -} - -func (r *TplRender) XML(status int, v interface{}) { - var result []byte - var err error - if r.Opt.IndentXML { - result, err = xml.MarshalIndent(v, "", " ") - } else { - result, err = xml.Marshal(v) - } - if err != nil { - http.Error(r, err.Error(), 500) - return - } - - // XML rendered fine, write out the result - r.Header().Set(_CONTENT_TYPE, _CONTENT_XML+r.CompiledCharset) - r.WriteHeader(status) - if len(r.Opt.PrefixXML) > 0 { - _, _ = r.Write(r.Opt.PrefixXML) - } - _, _ = r.Write(result) -} - -func (r *TplRender) data(status int, contentType string, v []byte) { - if r.Header().Get(_CONTENT_TYPE) == "" { - r.Header().Set(_CONTENT_TYPE, contentType) - } - r.WriteHeader(status) - _, _ = r.Write(v) -} - -func (r *TplRender) RawData(status int, v []byte) { - r.data(status, _CONTENT_BINARY, v) -} - -func (r *TplRender) PlainText(status int, v []byte) { - r.data(status, _CONTENT_PLAIN, v) -} - -func (r *TplRender) execute(t *template.Template, name string, data interface{}) (*bytes.Buffer, error) { - buf := bufpool.Get().(*bytes.Buffer) - return buf, t.ExecuteTemplate(buf, name, data) -} - -func (r *TplRender) addYield(t *template.Template, tplName string, data interface{}) { - funcs := template.FuncMap{ - "yield": func() (template.HTML, error) { - buf, err := r.execute(t, tplName, data) - // return safe html here since we are rendering our own template - return template.HTML(buf.String()), err - }, - "current": func() (string, error) { - return tplName, nil - }, - } - t.Funcs(funcs) -} - -func (r *TplRender) renderBytes(setName, tplName string, data interface{}, htmlOpt ...HTMLOptions) (*bytes.Buffer, error) { - t := r.TemplateSet.Get(setName) - if Env == DEV { - opt := *r.Opt - opt.Directory = r.TemplateSet.GetDir(setName) - t = r.TemplateSet.Set(setName, &opt) - } - if t == nil { - return nil, fmt.Errorf("html/template: template \"%s\" is undefined", tplName) - } - - opt := r.prepareHTMLOptions(htmlOpt) - - if len(opt.Layout) > 0 { - r.addYield(t, tplName, data) - tplName = opt.Layout - } - - out, err := r.execute(t, tplName, data) - if err != nil { - return nil, err - } - - return out, nil -} - -func (r *TplRender) renderHTML(status int, setName, tplName string, data interface{}, htmlOpt ...HTMLOptions) { - r.startTime = time.Now() - - out, err := r.renderBytes(setName, tplName, data, htmlOpt...) - if err != nil { - http.Error(r, err.Error(), http.StatusInternalServerError) - return - } - - r.Header().Set(_CONTENT_TYPE, r.Opt.HTMLContentType+r.CompiledCharset) - r.WriteHeader(status) - - if _, err := out.WriteTo(r); err != nil { - out.Reset() - } - bufpool.Put(out) -} - -func (r *TplRender) HTML(status int, name string, data interface{}, htmlOpt ...HTMLOptions) { - r.renderHTML(status, DEFAULT_TPL_SET_NAME, name, data, htmlOpt...) -} - -func (r *TplRender) HTMLSet(status int, setName, tplName string, data interface{}, htmlOpt ...HTMLOptions) { - r.renderHTML(status, setName, tplName, data, htmlOpt...) -} - -func (r *TplRender) HTMLSetBytes(setName, tplName string, data interface{}, htmlOpt ...HTMLOptions) ([]byte, error) { - out, err := r.renderBytes(setName, tplName, data, htmlOpt...) - if err != nil { - return []byte(""), err - } - return out.Bytes(), nil -} - -func (r *TplRender) HTMLBytes(name string, data interface{}, htmlOpt ...HTMLOptions) ([]byte, error) { - return r.HTMLSetBytes(DEFAULT_TPL_SET_NAME, name, data, htmlOpt...) -} - -func (r *TplRender) HTMLSetString(setName, tplName string, data interface{}, htmlOpt ...HTMLOptions) (string, error) { - p, err := r.HTMLSetBytes(setName, tplName, data, htmlOpt...) - return string(p), err -} - -func (r *TplRender) HTMLString(name string, data interface{}, htmlOpt ...HTMLOptions) (string, error) { - p, err := r.HTMLBytes(name, data, htmlOpt...) - return string(p), err -} - -// Error writes the given HTTP status to the current ResponseWriter -func (r *TplRender) Error(status int, message ...string) { - r.WriteHeader(status) - if len(message) > 0 { - _, _ = r.Write([]byte(message[0])) - } -} - -func (r *TplRender) Status(status int) { - r.WriteHeader(status) -} - -func (r *TplRender) prepareHTMLOptions(htmlOpt []HTMLOptions) HTMLOptions { - if len(htmlOpt) > 0 { - return htmlOpt[0] - } - - return HTMLOptions{ - Layout: r.Opt.Layout, - } -} - -func (r *TplRender) SetTemplatePath(setName, dir string) { - if len(setName) == 0 { - setName = DEFAULT_TPL_SET_NAME - } - opt := *r.Opt - opt.Directory = dir - r.TemplateSet.Set(setName, &opt) -} - -func (r *TplRender) HasTemplateSet(name string) bool { - return r.TemplateSet.Get(name) != nil -} - -// DummyRender is used when user does not choose any real render to use. -// This way, we can print out friendly message which asks them to register one, -// instead of ugly and confusing 'nil pointer' panic. -type DummyRender struct { - http.ResponseWriter -} - -func renderNotRegistered() { - panic("middleware render hasn't been registered") -} - -func (r *DummyRender) SetResponseWriter(http.ResponseWriter) { - renderNotRegistered() -} - -func (r *DummyRender) JSON(int, interface{}) { - renderNotRegistered() -} - -func (r *DummyRender) JSONString(interface{}) (string, error) { - renderNotRegistered() - return "", nil -} - -func (r *DummyRender) RawData(int, []byte) { - renderNotRegistered() -} - -func (r *DummyRender) PlainText(int, []byte) { - renderNotRegistered() -} - -func (r *DummyRender) HTML(int, string, interface{}, ...HTMLOptions) { - renderNotRegistered() -} - -func (r *DummyRender) HTMLSet(int, string, string, interface{}, ...HTMLOptions) { - renderNotRegistered() -} - -func (r *DummyRender) HTMLSetString(string, string, interface{}, ...HTMLOptions) (string, error) { - renderNotRegistered() - return "", nil -} - -func (r *DummyRender) HTMLString(string, interface{}, ...HTMLOptions) (string, error) { - renderNotRegistered() - return "", nil -} - -func (r *DummyRender) HTMLSetBytes(string, string, interface{}, ...HTMLOptions) ([]byte, error) { - renderNotRegistered() - return nil, nil -} - -func (r *DummyRender) HTMLBytes(string, interface{}, ...HTMLOptions) ([]byte, error) { - renderNotRegistered() - return nil, nil -} - -func (r *DummyRender) XML(int, interface{}) { - renderNotRegistered() -} - -func (r *DummyRender) Error(int, ...string) { - renderNotRegistered() -} - -func (r *DummyRender) Status(int) { - renderNotRegistered() -} - -func (r *DummyRender) SetTemplatePath(string, string) { - renderNotRegistered() -} - -func (r *DummyRender) HasTemplateSet(string) bool { - renderNotRegistered() - return false -} diff --git a/vendor/gitea.com/macaron/macaron/response_writer.go b/vendor/gitea.com/macaron/macaron/response_writer.go deleted file mode 100644 index eeb35f642e6c5..0000000000000 --- a/vendor/gitea.com/macaron/macaron/response_writer.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2013 Martini Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import ( - "bufio" - "errors" - "net" - "net/http" -) - -// ResponseWriter is a wrapper around http.ResponseWriter that provides extra information about -// the response. It is recommended that middleware handlers use this construct to wrap a responsewriter -// if the functionality calls for it. -type ResponseWriter interface { - http.ResponseWriter - http.Flusher - http.Pusher - // Status returns the status code of the response or 0 if the response has not been written. - Status() int - // Written returns whether or not the ResponseWriter has been written. - Written() bool - // Size returns the size of the response body. - Size() int - // Before allows for a function to be called before the ResponseWriter has been written to. This is - // useful for setting headers or any other operations that must happen before a response has been written. - Before(BeforeFunc) -} - -// BeforeFunc is a function that is called before the ResponseWriter has been written to. -type BeforeFunc func(ResponseWriter) - -// NewResponseWriter creates a ResponseWriter that wraps an http.ResponseWriter -func NewResponseWriter(method string, rw http.ResponseWriter) ResponseWriter { - return &responseWriter{method, rw, 0, 0, nil} -} - -type responseWriter struct { - method string - http.ResponseWriter - status int - size int - beforeFuncs []BeforeFunc -} - -func (rw *responseWriter) WriteHeader(s int) { - rw.callBefore() - rw.ResponseWriter.WriteHeader(s) - rw.status = s -} - -func (rw *responseWriter) Write(b []byte) (size int, err error) { - if !rw.Written() { - // The status will be StatusOK if WriteHeader has not been called yet - rw.WriteHeader(http.StatusOK) - } - if rw.method != "HEAD" { - size, err = rw.ResponseWriter.Write(b) - rw.size += size - } - return size, err -} - -func (rw *responseWriter) Status() int { - return rw.status -} - -func (rw *responseWriter) Size() int { - return rw.size -} - -func (rw *responseWriter) Written() bool { - return rw.status != 0 -} - -func (rw *responseWriter) Before(before BeforeFunc) { - rw.beforeFuncs = append(rw.beforeFuncs, before) -} - -func (rw *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { - hijacker, ok := rw.ResponseWriter.(http.Hijacker) - if !ok { - return nil, nil, errors.New("the ResponseWriter doesn't support the Hijacker interface") - } - return hijacker.Hijack() -} - -//nolint -func (rw *responseWriter) CloseNotify() <-chan bool { - return rw.ResponseWriter.(http.CloseNotifier).CloseNotify() -} - -func (rw *responseWriter) callBefore() { - for i := len(rw.beforeFuncs) - 1; i >= 0; i-- { - rw.beforeFuncs[i](rw) - } -} - -func (rw *responseWriter) Flush() { - flusher, ok := rw.ResponseWriter.(http.Flusher) - if ok { - flusher.Flush() - } -} - -func (rw *responseWriter) Push(target string, opts *http.PushOptions) error { - pusher, ok := rw.ResponseWriter.(http.Pusher) - if !ok { - return errors.New("the ResponseWriter doesn't support the Pusher interface") - } - return pusher.Push(target, opts) -} diff --git a/vendor/gitea.com/macaron/macaron/return_handler.go b/vendor/gitea.com/macaron/macaron/return_handler.go deleted file mode 100644 index 10b2c2283f9bb..0000000000000 --- a/vendor/gitea.com/macaron/macaron/return_handler.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2013 Martini Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import ( - "net/http" - "reflect" - - "gitea.com/macaron/inject" -) - -// ReturnHandler is a service that Martini provides that is called -// when a route handler returns something. The ReturnHandler is -// responsible for writing to the ResponseWriter based on the values -// that are passed into this function. -type ReturnHandler func(*Context, []reflect.Value) - -func canDeref(val reflect.Value) bool { - return val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr -} - -func isError(val reflect.Value) bool { - _, ok := val.Interface().(error) - return ok -} - -func isByteSlice(val reflect.Value) bool { - return val.Kind() == reflect.Slice && val.Type().Elem().Kind() == reflect.Uint8 -} - -func defaultReturnHandler() ReturnHandler { - return func(ctx *Context, vals []reflect.Value) { - rv := ctx.GetVal(inject.InterfaceOf((*http.ResponseWriter)(nil))) - resp := rv.Interface().(http.ResponseWriter) - var respVal reflect.Value - if len(vals) > 1 && vals[0].Kind() == reflect.Int { - resp.WriteHeader(int(vals[0].Int())) - respVal = vals[1] - } else if len(vals) > 0 { - respVal = vals[0] - - if isError(respVal) { - err := respVal.Interface().(error) - if err != nil { - ctx.internalServerError(ctx, err) - } - return - } else if canDeref(respVal) { - if respVal.IsNil() { - return // Ignore nil error - } - } - } - if canDeref(respVal) { - respVal = respVal.Elem() - } - if isByteSlice(respVal) { - _, _ = resp.Write(respVal.Bytes()) - } else { - _, _ = resp.Write([]byte(respVal.String())) - } - } -} diff --git a/vendor/gitea.com/macaron/macaron/router.go b/vendor/gitea.com/macaron/macaron/router.go deleted file mode 100644 index df593d669acc0..0000000000000 --- a/vendor/gitea.com/macaron/macaron/router.go +++ /dev/null @@ -1,380 +0,0 @@ -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import ( - "net/http" - "strings" - "sync" -) - -var ( - // Known HTTP methods. - _HTTP_METHODS = map[string]bool{ - "GET": true, - "POST": true, - "PUT": true, - "DELETE": true, - "PATCH": true, - "OPTIONS": true, - "HEAD": true, - } -) - -// routeMap represents a thread-safe map for route tree. -type routeMap struct { - lock sync.RWMutex - routes map[string]map[string]*Leaf -} - -// NewRouteMap initializes and returns a new routeMap. -func NewRouteMap() *routeMap { - rm := &routeMap{ - routes: make(map[string]map[string]*Leaf), - } - for m := range _HTTP_METHODS { - rm.routes[m] = make(map[string]*Leaf) - } - return rm -} - -// getLeaf returns Leaf object if a route has been registered. -func (rm *routeMap) getLeaf(method, pattern string) *Leaf { - rm.lock.RLock() - defer rm.lock.RUnlock() - - return rm.routes[method][pattern] -} - -// add adds new route to route tree map. -func (rm *routeMap) add(method, pattern string, leaf *Leaf) { - rm.lock.Lock() - defer rm.lock.Unlock() - - rm.routes[method][pattern] = leaf -} - -type group struct { - pattern string - handlers []Handler -} - -// Router represents a Macaron router layer. -type Router struct { - m *Macaron - autoHead bool - routers map[string]*Tree - *routeMap - namedRoutes map[string]*Leaf - - groups []group - notFound http.HandlerFunc - internalServerError func(*Context, error) - - // handlerWrapper is used to wrap arbitrary function from Handler to inject.FastInvoker. - handlerWrapper func(Handler) Handler -} - -func NewRouter() *Router { - return &Router{ - routers: make(map[string]*Tree), - routeMap: NewRouteMap(), - namedRoutes: make(map[string]*Leaf), - } -} - -// SetAutoHead sets the value who determines whether add HEAD method automatically -// when GET method is added. -func (r *Router) SetAutoHead(v bool) { - r.autoHead = v -} - -type Params map[string]string - -// Handle is a function that can be registered to a route to handle HTTP requests. -// Like http.HandlerFunc, but has a third parameter for the values of wildcards (variables). -type Handle func(http.ResponseWriter, *http.Request, Params) - -// Route represents a wrapper of leaf route and upper level router. -type Route struct { - router *Router - leaf *Leaf -} - -// Name sets name of route. -func (r *Route) Name(name string) { - if len(name) == 0 { - panic("route name cannot be empty") - } else if r.router.namedRoutes[name] != nil { - panic("route with given name already exists: " + name) - } - r.router.namedRoutes[name] = r.leaf -} - -// handle adds new route to the router tree. -func (r *Router) handle(method, pattern string, handle Handle) *Route { - method = strings.ToUpper(method) - - var leaf *Leaf - // Prevent duplicate routes. - if leaf = r.getLeaf(method, pattern); leaf != nil { - return &Route{r, leaf} - } - - // Validate HTTP methods. - if !_HTTP_METHODS[method] && method != "*" { - panic("unknown HTTP method: " + method) - } - - // Generate methods need register. - methods := make(map[string]bool) - if method == "*" { - for m := range _HTTP_METHODS { - methods[m] = true - } - } else { - methods[method] = true - } - - // Add to router tree. - for m := range methods { - if t, ok := r.routers[m]; ok { - leaf = t.Add(pattern, handle) - } else { - t := NewTree() - leaf = t.Add(pattern, handle) - r.routers[m] = t - } - r.add(m, pattern, leaf) - } - return &Route{r, leaf} -} - -// Handle registers a new request handle with the given pattern, method and handlers. -func (r *Router) Handle(method string, pattern string, handlers []Handler) *Route { - if len(r.groups) > 0 { - groupPattern := "" - h := make([]Handler, 0) - for _, g := range r.groups { - groupPattern += g.pattern - h = append(h, g.handlers...) - } - - pattern = groupPattern + pattern - h = append(h, handlers...) - handlers = h - } - handlers = validateAndWrapHandlers(handlers, r.handlerWrapper) - - return r.handle(method, pattern, func(resp http.ResponseWriter, req *http.Request, params Params) { - c := r.m.createContext(resp, req) - c.params = params - c.handlers = make([]Handler, 0, len(r.m.handlers)+len(handlers)) - c.handlers = append(c.handlers, r.m.handlers...) - c.handlers = append(c.handlers, handlers...) - c.run() - }) -} - -func (r *Router) Group(pattern string, fn func(), h ...Handler) { - r.groups = append(r.groups, group{pattern, h}) - fn() - r.groups = r.groups[:len(r.groups)-1] -} - -// Get is a shortcut for r.Handle("GET", pattern, handlers) -func (r *Router) Get(pattern string, h ...Handler) (leaf *Route) { - leaf = r.Handle("GET", pattern, h) - if r.autoHead { - r.Head(pattern, h...) - } - return leaf -} - -// Patch is a shortcut for r.Handle("PATCH", pattern, handlers) -func (r *Router) Patch(pattern string, h ...Handler) *Route { - return r.Handle("PATCH", pattern, h) -} - -// Post is a shortcut for r.Handle("POST", pattern, handlers) -func (r *Router) Post(pattern string, h ...Handler) *Route { - return r.Handle("POST", pattern, h) -} - -// Put is a shortcut for r.Handle("PUT", pattern, handlers) -func (r *Router) Put(pattern string, h ...Handler) *Route { - return r.Handle("PUT", pattern, h) -} - -// Delete is a shortcut for r.Handle("DELETE", pattern, handlers) -func (r *Router) Delete(pattern string, h ...Handler) *Route { - return r.Handle("DELETE", pattern, h) -} - -// Options is a shortcut for r.Handle("OPTIONS", pattern, handlers) -func (r *Router) Options(pattern string, h ...Handler) *Route { - return r.Handle("OPTIONS", pattern, h) -} - -// Head is a shortcut for r.Handle("HEAD", pattern, handlers) -func (r *Router) Head(pattern string, h ...Handler) *Route { - return r.Handle("HEAD", pattern, h) -} - -// Any is a shortcut for r.Handle("*", pattern, handlers) -func (r *Router) Any(pattern string, h ...Handler) *Route { - return r.Handle("*", pattern, h) -} - -// Route is a shortcut for same handlers but different HTTP methods. -// -// Example: -// m.Route("/", "GET,POST", h) -func (r *Router) Route(pattern, methods string, h ...Handler) (route *Route) { - for _, m := range strings.Split(methods, ",") { - route = r.Handle(strings.TrimSpace(m), pattern, h) - } - return route -} - -// Combo returns a combo router. -func (r *Router) Combo(pattern string, h ...Handler) *ComboRouter { - return &ComboRouter{r, pattern, h, map[string]bool{}, nil} -} - -// NotFound configurates http.HandlerFunc which is called when no matching route is -// found. If it is not set, http.NotFound is used. -// Be sure to set 404 response code in your handler. -func (r *Router) NotFound(handlers ...Handler) { - handlers = validateAndWrapHandlers(handlers) - r.notFound = func(rw http.ResponseWriter, req *http.Request) { - c := r.m.createContext(rw, req) - c.handlers = make([]Handler, 0, len(r.m.handlers)+len(handlers)) - c.handlers = append(c.handlers, r.m.handlers...) - c.handlers = append(c.handlers, handlers...) - c.run() - } -} - -// InternalServerError configurates handler which is called when route handler returns -// error. If it is not set, default handler is used. -// Be sure to set 500 response code in your handler. -func (r *Router) InternalServerError(handlers ...Handler) { - handlers = validateAndWrapHandlers(handlers) - r.internalServerError = func(c *Context, err error) { - c.index = 0 - c.handlers = handlers - c.Map(err) - c.run() - } -} - -// SetHandlerWrapper sets handlerWrapper for the router. -func (r *Router) SetHandlerWrapper(f func(Handler) Handler) { - r.handlerWrapper = f -} - -func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - if t, ok := r.routers[req.Method]; ok { - // Fast match for static routes - leaf := r.getLeaf(req.Method, req.URL.Path) - if leaf != nil { - leaf.handle(rw, req, nil) - return - } - - h, p, ok := t.Match(req.URL.EscapedPath()) - if ok { - if splat, ok := p["*0"]; ok { - p["*"] = splat // Easy name. - } - h(rw, req, p) - return - } - } - - r.notFound(rw, req) -} - -// URLFor builds path part of URL by given pair values. -func (r *Router) URLFor(name string, pairs ...string) string { - leaf, ok := r.namedRoutes[name] - if !ok { - panic("route with given name does not exists: " + name) - } - return leaf.URLPath(pairs...) -} - -// ComboRouter represents a combo router. -type ComboRouter struct { - router *Router - pattern string - handlers []Handler - methods map[string]bool // Registered methods. - - lastRoute *Route -} - -func (cr *ComboRouter) checkMethod(name string) { - if cr.methods[name] { - panic("method '" + name + "' has already been registered") - } - cr.methods[name] = true -} - -func (cr *ComboRouter) route(fn func(string, ...Handler) *Route, method string, h ...Handler) *ComboRouter { - cr.checkMethod(method) - cr.lastRoute = fn(cr.pattern, append(cr.handlers, h...)...) - return cr -} - -func (cr *ComboRouter) Get(h ...Handler) *ComboRouter { - if cr.router.autoHead { - cr.Head(h...) - } - return cr.route(cr.router.Get, "GET", h...) -} - -func (cr *ComboRouter) Patch(h ...Handler) *ComboRouter { - return cr.route(cr.router.Patch, "PATCH", h...) -} - -func (cr *ComboRouter) Post(h ...Handler) *ComboRouter { - return cr.route(cr.router.Post, "POST", h...) -} - -func (cr *ComboRouter) Put(h ...Handler) *ComboRouter { - return cr.route(cr.router.Put, "PUT", h...) -} - -func (cr *ComboRouter) Delete(h ...Handler) *ComboRouter { - return cr.route(cr.router.Delete, "DELETE", h...) -} - -func (cr *ComboRouter) Options(h ...Handler) *ComboRouter { - return cr.route(cr.router.Options, "OPTIONS", h...) -} - -func (cr *ComboRouter) Head(h ...Handler) *ComboRouter { - return cr.route(cr.router.Head, "HEAD", h...) -} - -// Name sets name of ComboRouter route. -func (cr *ComboRouter) Name(name string) { - if cr.lastRoute == nil { - panic("no corresponding route to be named") - } - cr.lastRoute.Name(name) -} diff --git a/vendor/gitea.com/macaron/macaron/static.go b/vendor/gitea.com/macaron/macaron/static.go deleted file mode 100644 index 04d91d8c9a860..0000000000000 --- a/vendor/gitea.com/macaron/macaron/static.go +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2013 Martini Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import ( - "encoding/base64" - "fmt" - "log" - "net/http" - "path" - "path/filepath" - "strings" - "sync" -) - -// StaticOptions is a struct for specifying configuration options for the macaron.Static middleware. -type StaticOptions struct { - // Prefix is the optional prefix used to serve the static directory content - Prefix string - // SkipLogging will disable [Static] log messages when a static file is served. - SkipLogging bool - // IndexFile defines which file to serve as index if it exists. - IndexFile string - // Expires defines which user-defined function to use for producing a HTTP Expires Header - // https://developers.google.com/speed/docs/insights/LeverageBrowserCaching - Expires func() string - // ETag defines if we should add an ETag header - // https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#validating-cached-responses-with-etags - ETag bool - // FileSystem is the interface for supporting any implmentation of file system. - FileSystem http.FileSystem -} - -// FIXME: to be deleted. -type staticMap struct { - lock sync.RWMutex - data map[string]*http.Dir -} - -func (sm *staticMap) Set(dir *http.Dir) { - sm.lock.Lock() - defer sm.lock.Unlock() - - sm.data[string(*dir)] = dir -} - -func (sm *staticMap) Get(name string) *http.Dir { - sm.lock.RLock() - defer sm.lock.RUnlock() - - return sm.data[name] -} - -func (sm *staticMap) Delete(name string) { - sm.lock.Lock() - defer sm.lock.Unlock() - - delete(sm.data, name) -} - -var statics = staticMap{sync.RWMutex{}, map[string]*http.Dir{}} - -// staticFileSystem implements http.FileSystem interface. -type staticFileSystem struct { - dir *http.Dir -} - -func newStaticFileSystem(directory string) staticFileSystem { - if !filepath.IsAbs(directory) { - directory = filepath.Join(Root, directory) - } - dir := http.Dir(directory) - statics.Set(&dir) - return staticFileSystem{&dir} -} - -func (fs staticFileSystem) Open(name string) (http.File, error) { - return fs.dir.Open(name) -} - -func prepareStaticOption(dir string, opt StaticOptions) StaticOptions { - // Defaults - if len(opt.IndexFile) == 0 { - opt.IndexFile = "index.html" - } - // Normalize the prefix if provided - if opt.Prefix != "" { - // Ensure we have a leading '/' - if opt.Prefix[0] != '/' { - opt.Prefix = "/" + opt.Prefix - } - // Remove any trailing '/' - opt.Prefix = strings.TrimRight(opt.Prefix, "/") - } - if opt.FileSystem == nil { - opt.FileSystem = newStaticFileSystem(dir) - } - return opt -} - -func prepareStaticOptions(dir string, options []StaticOptions) StaticOptions { - var opt StaticOptions - if len(options) > 0 { - opt = options[0] - } - return prepareStaticOption(dir, opt) -} - -func staticHandler(ctx *Context, log *log.Logger, opt StaticOptions) bool { - if ctx.Req.Method != "GET" && ctx.Req.Method != "HEAD" { - return false - } - - file := ctx.Req.URL.Path - // if we have a prefix, filter requests by stripping the prefix - if opt.Prefix != "" { - if !strings.HasPrefix(file, opt.Prefix) { - return false - } - file = file[len(opt.Prefix):] - if file != "" && file[0] != '/' { - return false - } - } - - f, err := opt.FileSystem.Open(file) - if err != nil { - return false - } - defer f.Close() - - fi, err := f.Stat() - if err != nil { - return true // File exists but fail to open. - } - - // Try to serve index file - if fi.IsDir() { - redirPath := path.Clean(ctx.Req.URL.Path) - // path.Clean removes the trailing slash, so we need to add it back when - // the original path has it. - if strings.HasSuffix(ctx.Req.URL.Path, "/") { - redirPath = redirPath + "/" - } - // Redirect if missing trailing slash. - if !strings.HasSuffix(redirPath, "/") { - http.Redirect(ctx.Resp, ctx.Req.Request, redirPath+"/", http.StatusFound) - return true - } - - file = path.Join(file, opt.IndexFile) - f, err = opt.FileSystem.Open(file) - if err != nil { - return false // Discard error. - } - defer f.Close() - - fi, err = f.Stat() - if err != nil || fi.IsDir() { - return true - } - } - - if !opt.SkipLogging { - log.Println("[Static] Serving " + file) - } - - // Add an Expires header to the static content - if opt.Expires != nil { - ctx.Resp.Header().Set("Expires", opt.Expires()) - } - - if opt.ETag { - tag := `"` + GenerateETag(fmt.Sprintf("%d", fi.Size()), fi.Name(), fi.ModTime().UTC().Format(http.TimeFormat)) + `"` - ctx.Resp.Header().Set("ETag", tag) - if ctx.Req.Header.Get("If-None-Match") == tag { - ctx.Resp.WriteHeader(http.StatusNotModified) - return true - } - } - - http.ServeContent(ctx.Resp, ctx.Req.Request, file, fi.ModTime(), f) - return true -} - -// GenerateETag generates an ETag based on size, filename and file modification time -func GenerateETag(fileSize, fileName, modTime string) string { - etag := fileSize + fileName + modTime - return base64.StdEncoding.EncodeToString([]byte(etag)) -} - -// Static returns a middleware handler that serves static files in the given directory. -func Static(directory string, staticOpt ...StaticOptions) Handler { - opt := prepareStaticOptions(directory, staticOpt) - - return func(ctx *Context, log *log.Logger) { - staticHandler(ctx, log, opt) - } -} - -// Statics registers multiple static middleware handlers all at once. -func Statics(opt StaticOptions, dirs ...string) Handler { - if len(dirs) == 0 { - panic("no static directory is given") - } - opts := make([]StaticOptions, len(dirs)) - for i := range dirs { - opts[i] = prepareStaticOption(dirs[i], opt) - } - - return func(ctx *Context, log *log.Logger) { - for i := range opts { - if staticHandler(ctx, log, opts[i]) { - return - } - } - } -} diff --git a/vendor/gitea.com/macaron/macaron/tree.go b/vendor/gitea.com/macaron/macaron/tree.go deleted file mode 100644 index 0ab094dd68032..0000000000000 --- a/vendor/gitea.com/macaron/macaron/tree.go +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright 2015 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import ( - "regexp" - "strings" - - "github.com/unknwon/com" -) - -type patternType int8 - -const ( - _PATTERN_STATIC patternType = iota // /home - _PATTERN_REGEXP // /:id([0-9]+) - _PATTERN_PATH_EXT // /*.* - _PATTERN_HOLDER // /:user - _PATTERN_MATCH_ALL // /* -) - -// Leaf represents a leaf route information. -type Leaf struct { - parent *Tree - - typ patternType - pattern string - rawPattern string // Contains wildcard instead of regexp - wildcards []string - reg *regexp.Regexp - optional bool - - handle Handle -} - -var wildcardPattern = regexp.MustCompile(`:[a-zA-Z0-9]+`) - -func isSpecialRegexp(pattern, regStr string, pos []int) bool { - return len(pattern) >= pos[1]+len(regStr) && pattern[pos[1]:pos[1]+len(regStr)] == regStr -} - -// getNextWildcard tries to find next wildcard and update pattern with corresponding regexp. -func getNextWildcard(pattern string) (wildcard, _ string) { - pos := wildcardPattern.FindStringIndex(pattern) - if pos == nil { - return "", pattern - } - wildcard = pattern[pos[0]:pos[1]] - - // Reach last character or no regexp is given. - if len(pattern) == pos[1] { - return wildcard, strings.Replace(pattern, wildcard, `(.+)`, 1) - } else if pattern[pos[1]] != '(' { - switch { - case isSpecialRegexp(pattern, ":int", pos): - pattern = strings.Replace(pattern, ":int", "([0-9]+)", 1) - case isSpecialRegexp(pattern, ":string", pos): - pattern = strings.Replace(pattern, ":string", "([\\w]+)", 1) - default: - return wildcard, strings.Replace(pattern, wildcard, `(.+)`, 1) - } - } - - // Cut out placeholder directly. - return wildcard, pattern[:pos[0]] + pattern[pos[1]:] -} - -func getWildcards(pattern string) (string, []string) { - wildcards := make([]string, 0, 2) - - // Keep getting next wildcard until nothing is left. - var wildcard string - for { - wildcard, pattern = getNextWildcard(pattern) - if len(wildcard) > 0 { - wildcards = append(wildcards, wildcard) - } else { - break - } - } - - return pattern, wildcards -} - -// getRawPattern removes all regexp but keeps wildcards for building URL path. -func getRawPattern(rawPattern string) string { - rawPattern = strings.Replace(rawPattern, ":int", "", -1) - rawPattern = strings.Replace(rawPattern, ":string", "", -1) - - for { - startIdx := strings.Index(rawPattern, "(") - if startIdx == -1 { - break - } - - closeIdx := strings.Index(rawPattern, ")") - if closeIdx > -1 { - rawPattern = rawPattern[:startIdx] + rawPattern[closeIdx+1:] - } - } - return rawPattern -} - -func checkPattern(pattern string) (typ patternType, rawPattern string, wildcards []string, reg *regexp.Regexp) { - pattern = strings.TrimLeft(pattern, "?") - rawPattern = getRawPattern(pattern) - - if pattern == "*" { - typ = _PATTERN_MATCH_ALL - } else if pattern == "*.*" { - typ = _PATTERN_PATH_EXT - } else if strings.Contains(pattern, ":") { - typ = _PATTERN_REGEXP - pattern, wildcards = getWildcards(pattern) - if pattern == "(.+)" { - typ = _PATTERN_HOLDER - } else { - reg = regexp.MustCompile(pattern) - } - } - return typ, rawPattern, wildcards, reg -} - -func NewLeaf(parent *Tree, pattern string, handle Handle) *Leaf { - typ, rawPattern, wildcards, reg := checkPattern(pattern) - optional := false - if len(pattern) > 0 && pattern[0] == '?' { - optional = true - } - return &Leaf{parent, typ, pattern, rawPattern, wildcards, reg, optional, handle} -} - -// URLPath build path part of URL by given pair values. -func (l *Leaf) URLPath(pairs ...string) string { - if len(pairs)%2 != 0 { - panic("number of pairs does not match") - } - - urlPath := l.rawPattern - parent := l.parent - for parent != nil { - urlPath = parent.rawPattern + "/" + urlPath - parent = parent.parent - } - for i := 0; i < len(pairs); i += 2 { - if len(pairs[i]) == 0 { - panic("pair value cannot be empty: " + com.ToStr(i)) - } else if pairs[i][0] != ':' && pairs[i] != "*" && pairs[i] != "*.*" { - pairs[i] = ":" + pairs[i] - } - urlPath = strings.Replace(urlPath, pairs[i], pairs[i+1], 1) - } - return urlPath -} - -// Tree represents a router tree in Macaron. -type Tree struct { - parent *Tree - - typ patternType - pattern string - rawPattern string - wildcards []string - reg *regexp.Regexp - - subtrees []*Tree - leaves []*Leaf -} - -func NewSubtree(parent *Tree, pattern string) *Tree { - typ, rawPattern, wildcards, reg := checkPattern(pattern) - return &Tree{parent, typ, pattern, rawPattern, wildcards, reg, make([]*Tree, 0, 5), make([]*Leaf, 0, 5)} -} - -func NewTree() *Tree { - return NewSubtree(nil, "") -} - -func (t *Tree) addLeaf(pattern string, handle Handle) *Leaf { - for i := 0; i < len(t.leaves); i++ { - if t.leaves[i].pattern == pattern { - return t.leaves[i] - } - } - - leaf := NewLeaf(t, pattern, handle) - - // Add exact same leaf to grandparent/parent level without optional. - if leaf.optional { - parent := leaf.parent - if parent.parent != nil { - parent.parent.addLeaf(parent.pattern, handle) - } else { - parent.addLeaf("", handle) // Root tree can add as empty pattern. - } - } - - i := 0 - for ; i < len(t.leaves); i++ { - if leaf.typ < t.leaves[i].typ { - break - } - } - - if i == len(t.leaves) { - t.leaves = append(t.leaves, leaf) - } else { - t.leaves = append(t.leaves[:i], append([]*Leaf{leaf}, t.leaves[i:]...)...) - } - return leaf -} - -func (t *Tree) addSubtree(segment, pattern string, handle Handle) *Leaf { - for i := 0; i < len(t.subtrees); i++ { - if t.subtrees[i].pattern == segment { - return t.subtrees[i].addNextSegment(pattern, handle) - } - } - - subtree := NewSubtree(t, segment) - i := 0 - for ; i < len(t.subtrees); i++ { - if subtree.typ < t.subtrees[i].typ { - break - } - } - - if i == len(t.subtrees) { - t.subtrees = append(t.subtrees, subtree) - } else { - t.subtrees = append(t.subtrees[:i], append([]*Tree{subtree}, t.subtrees[i:]...)...) - } - return subtree.addNextSegment(pattern, handle) -} - -func (t *Tree) addNextSegment(pattern string, handle Handle) *Leaf { - pattern = strings.TrimPrefix(pattern, "/") - - i := strings.Index(pattern, "/") - if i == -1 { - return t.addLeaf(pattern, handle) - } - return t.addSubtree(pattern[:i], pattern[i+1:], handle) -} - -func (t *Tree) Add(pattern string, handle Handle) *Leaf { - pattern = strings.TrimSuffix(pattern, "/") - return t.addNextSegment(pattern, handle) -} - -func (t *Tree) matchLeaf(globLevel int, url string, params Params) (Handle, bool) { - url, err := PathUnescape(url) - if err != nil { - return nil, false - } - for i := 0; i < len(t.leaves); i++ { - switch t.leaves[i].typ { - case _PATTERN_STATIC: - if t.leaves[i].pattern == url { - return t.leaves[i].handle, true - } - case _PATTERN_REGEXP: - results := t.leaves[i].reg.FindStringSubmatch(url) - // Number of results and wildcasrd should be exact same. - if len(results)-1 != len(t.leaves[i].wildcards) { - break - } - - for j := 0; j < len(t.leaves[i].wildcards); j++ { - params[t.leaves[i].wildcards[j]] = results[j+1] - } - return t.leaves[i].handle, true - case _PATTERN_PATH_EXT: - j := strings.LastIndex(url, ".") - if j > -1 { - params[":path"] = url[:j] - params[":ext"] = url[j+1:] - } else { - params[":path"] = url - } - return t.leaves[i].handle, true - case _PATTERN_HOLDER: - params[t.leaves[i].wildcards[0]] = url - return t.leaves[i].handle, true - case _PATTERN_MATCH_ALL: - params["*"] = url - params["*"+com.ToStr(globLevel)] = url - return t.leaves[i].handle, true - } - } - return nil, false -} - -func (t *Tree) matchSubtree(globLevel int, segment, url string, params Params) (Handle, bool) { - unescapedSegment, err := PathUnescape(segment) - if err != nil { - return nil, false - } - for i := 0; i < len(t.subtrees); i++ { - switch t.subtrees[i].typ { - case _PATTERN_STATIC: - if t.subtrees[i].pattern == unescapedSegment { - if handle, ok := t.subtrees[i].matchNextSegment(globLevel, url, params); ok { - return handle, true - } - } - case _PATTERN_REGEXP: - results := t.subtrees[i].reg.FindStringSubmatch(unescapedSegment) - if len(results)-1 != len(t.subtrees[i].wildcards) { - break - } - - for j := 0; j < len(t.subtrees[i].wildcards); j++ { - params[t.subtrees[i].wildcards[j]] = results[j+1] - } - if handle, ok := t.subtrees[i].matchNextSegment(globLevel, url, params); ok { - return handle, true - } - case _PATTERN_HOLDER: - if handle, ok := t.subtrees[i].matchNextSegment(globLevel+1, url, params); ok { - params[t.subtrees[i].wildcards[0]] = unescapedSegment - return handle, true - } - case _PATTERN_MATCH_ALL: - if handle, ok := t.subtrees[i].matchNextSegment(globLevel+1, url, params); ok { - params["*"+com.ToStr(globLevel)] = unescapedSegment - return handle, true - } - } - } - - if len(t.leaves) > 0 { - leaf := t.leaves[len(t.leaves)-1] - unescapedURL, err := PathUnescape(segment + "/" + url) - if err != nil { - return nil, false - } - if leaf.typ == _PATTERN_PATH_EXT { - j := strings.LastIndex(unescapedURL, ".") - if j > -1 { - params[":path"] = unescapedURL[:j] - params[":ext"] = unescapedURL[j+1:] - } else { - params[":path"] = unescapedURL - } - return leaf.handle, true - } else if leaf.typ == _PATTERN_MATCH_ALL { - params["*"] = unescapedURL - params["*"+com.ToStr(globLevel)] = unescapedURL - return leaf.handle, true - } - } - return nil, false -} - -func (t *Tree) matchNextSegment(globLevel int, url string, params Params) (Handle, bool) { - i := strings.Index(url, "/") - if i == -1 { - return t.matchLeaf(globLevel, url, params) - } - return t.matchSubtree(globLevel, url[:i], url[i+1:], params) -} - -func (t *Tree) Match(url string) (Handle, Params, bool) { - url = strings.TrimPrefix(url, "/") - url = strings.TrimSuffix(url, "/") - params := make(Params) - handle, ok := t.matchNextSegment(0, url, params) - return handle, params, ok -} - -// MatchTest returns true if given URL is matched by given pattern. -func MatchTest(pattern, url string) bool { - t := NewTree() - t.Add(pattern, nil) - _, _, ok := t.Match(url) - return ok -} diff --git a/vendor/gitea.com/macaron/macaron/util_go17.go b/vendor/gitea.com/macaron/macaron/util_go17.go deleted file mode 100644 index a80c696c7c479..0000000000000 --- a/vendor/gitea.com/macaron/macaron/util_go17.go +++ /dev/null @@ -1,25 +0,0 @@ -// +build !go1.8 - -// Copyright 2017 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import "net/url" - -// PathUnescape unescapes a path. Ideally, this function would use -// url.PathUnescape(..), but the function was not introduced until go1.8. -func PathUnescape(s string) (string, error) { - return url.QueryUnescape(s) -} diff --git a/vendor/gitea.com/macaron/macaron/util_go18.go b/vendor/gitea.com/macaron/macaron/util_go18.go deleted file mode 100644 index d5eb1dfb284e7..0000000000000 --- a/vendor/gitea.com/macaron/macaron/util_go18.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build go1.8 - -// Copyright 2017 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package macaron - -import "net/url" - -// PathUnescape unescapes a path. -func PathUnescape(s string) (string, error) { - return url.PathUnescape(s) -} diff --git a/vendor/gitea.com/macaron/session/.drone.yml b/vendor/gitea.com/macaron/session/.drone.yml deleted file mode 100644 index 717ada4b8f1b3..0000000000000 --- a/vendor/gitea.com/macaron/session/.drone.yml +++ /dev/null @@ -1,11 +0,0 @@ -kind: pipeline -name: default - -steps: -- name: test - image: golang:1.12 - environment: - GOPROXY: https://goproxy.cn - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic \ No newline at end of file diff --git a/vendor/gitea.com/macaron/session/.gitignore b/vendor/gitea.com/macaron/session/.gitignore deleted file mode 100644 index 834722925c9ea..0000000000000 --- a/vendor/gitea.com/macaron/session/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -ledis/tmp.db -nodb/tmp.db -/vendor -/.idea diff --git a/vendor/gitea.com/macaron/session/LICENSE b/vendor/gitea.com/macaron/session/LICENSE deleted file mode 100644 index 8405e89a0b120..0000000000000 --- a/vendor/gitea.com/macaron/session/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/session/README.md b/vendor/gitea.com/macaron/session/README.md deleted file mode 100644 index ebbbff54531cc..0000000000000 --- a/vendor/gitea.com/macaron/session/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# session - -Middleware session provides session management for [Macaron](https://gitea.com/macaron/macaron). It can use many session providers, including memory, file, Redis, Memcache, PostgreSQL, MySQL, Couchbase, Ledis and Nodb. - -### Installation - -The minimum requirement of Go is 1.11 . - - go get gitea.com/macaron/session - -## Getting Help - -- [API Reference](https://gowalker.org/gitea.com/macaron/session) -- [Documentation](https://go-macaron.com/docs/middlewares/session) - -## Credits - -This package is a modified version of [go-macaron/session](github.com/go-macaron/session). - -## License - -This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/session/couchbase/couchbase.go b/vendor/gitea.com/macaron/session/couchbase/couchbase.go deleted file mode 100644 index 25a278d34ce9e..0000000000000 --- a/vendor/gitea.com/macaron/session/couchbase/couchbase.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package session - -import ( - "strings" - "sync" - - "gitea.com/macaron/session" - "github.com/couchbase/go-couchbase" -) - -// CouchbaseSessionStore represents a couchbase session store implementation. -type CouchbaseSessionStore struct { - b *couchbase.Bucket - sid string - lock sync.RWMutex - data map[interface{}]interface{} - maxlifetime int64 -} - -// Set sets value to given key in session. -func (s *CouchbaseSessionStore) Set(key, val interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data[key] = val - return nil -} - -// Get gets value by given key in session. -func (s *CouchbaseSessionStore) Get(key interface{}) interface{} { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.data[key] -} - -// Delete delete a key from session. -func (s *CouchbaseSessionStore) Delete(key interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - delete(s.data, key) - return nil -} - -// ID returns current session ID. -func (s *CouchbaseSessionStore) ID() string { - return s.sid -} - -// Release releases resource and save data to provider. -func (s *CouchbaseSessionStore) Release() error { - defer s.b.Close() - - // Skip encoding if the data is empty - if len(s.data) == 0 { - return nil - } - - data, err := session.EncodeGob(s.data) - if err != nil { - return err - } - - return s.b.Set(s.sid, int(s.maxlifetime), data) -} - -// Flush deletes all session data. -func (s *CouchbaseSessionStore) Flush() error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data = make(map[interface{}]interface{}) - return nil -} - -// CouchbaseProvider represents a couchbase session provider implementation. -type CouchbaseProvider struct { - maxlifetime int64 - connStr string - pool string - bucket string - b *couchbase.Bucket -} - -func (cp *CouchbaseProvider) getBucket() *couchbase.Bucket { - c, err := couchbase.Connect(cp.connStr) - if err != nil { - return nil - } - - pool, err := c.GetPool(cp.pool) - if err != nil { - return nil - } - - bucket, err := pool.GetBucket(cp.bucket) - if err != nil { - return nil - } - - return bucket -} - -// Init initializes memory session provider. -// connStr is couchbase server REST/JSON URL -// e.g. http://host:port/, Pool, Bucket -func (p *CouchbaseProvider) Init(maxlifetime int64, connStr string) error { - p.maxlifetime = maxlifetime - configs := strings.Split(connStr, ",") - if len(configs) > 0 { - p.connStr = configs[0] - } - if len(configs) > 1 { - p.pool = configs[1] - } - if len(configs) > 2 { - p.bucket = configs[2] - } - - return nil -} - -// Read returns raw session store by session ID. -func (p *CouchbaseProvider) Read(sid string) (session.RawStore, error) { - p.b = p.getBucket() - - var doc []byte - - err := p.b.Get(sid, &doc) - var kv map[interface{}]interface{} - if doc == nil { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(doc) - if err != nil { - return nil, err - } - } - - cs := &CouchbaseSessionStore{b: p.b, sid: sid, data: kv, maxlifetime: p.maxlifetime} - return cs, nil -} - -// Exist returns true if session with given ID exists. -func (p *CouchbaseProvider) Exist(sid string) bool { - p.b = p.getBucket() - defer p.b.Close() - - var doc []byte - - if err := p.b.Get(sid, &doc); err != nil || doc == nil { - return false - } else { - return true - } -} - -// Destroy deletes a session by session ID. -func (p *CouchbaseProvider) Destroy(sid string) error { - p.b = p.getBucket() - defer p.b.Close() - - p.b.Delete(sid) - return nil -} - -// Regenerate regenerates a session store from old session ID to new one. -func (p *CouchbaseProvider) Regenerate(oldsid, sid string) (session.RawStore, error) { - p.b = p.getBucket() - - var doc []byte - if err := p.b.Get(oldsid, &doc); err != nil || doc == nil { - p.b.Set(sid, int(p.maxlifetime), "") - } else { - err := p.b.Delete(oldsid) - if err != nil { - return nil, err - } - _, _ = p.b.Add(sid, int(p.maxlifetime), doc) - } - - err := p.b.Get(sid, &doc) - if err != nil { - return nil, err - } - var kv map[interface{}]interface{} - if doc == nil { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(doc) - if err != nil { - return nil, err - } - } - - cs := &CouchbaseSessionStore{b: p.b, sid: sid, data: kv, maxlifetime: p.maxlifetime} - return cs, nil -} - -// Count counts and returns number of sessions. -func (p *CouchbaseProvider) Count() int { - // FIXME - return 0 -} - -// GC calls GC to clean expired sessions. -func (p *CouchbaseProvider) GC() {} - -func init() { - session.Register("couchbase", &CouchbaseProvider{}) -} diff --git a/vendor/gitea.com/macaron/session/file.go b/vendor/gitea.com/macaron/session/file.go deleted file mode 100644 index ce915344fb79f..0000000000000 --- a/vendor/gitea.com/macaron/session/file.go +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package session - -import ( - "fmt" - "io/ioutil" - "log" - "os" - "path" - "path/filepath" - "sync" - "time" - - "github.com/unknwon/com" -) - -// FileStore represents a file session store implementation. -type FileStore struct { - p *FileProvider - sid string - lock sync.RWMutex - data map[interface{}]interface{} -} - -// NewFileStore creates and returns a file session store. -func NewFileStore(p *FileProvider, sid string, kv map[interface{}]interface{}) *FileStore { - return &FileStore{ - p: p, - sid: sid, - data: kv, - } -} - -// Set sets value to given key in session. -func (s *FileStore) Set(key, val interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data[key] = val - return nil -} - -// Get gets value by given key in session. -func (s *FileStore) Get(key interface{}) interface{} { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.data[key] -} - -// Delete delete a key from session. -func (s *FileStore) Delete(key interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - delete(s.data, key) - return nil -} - -// ID returns current session ID. -func (s *FileStore) ID() string { - return s.sid -} - -// Release releases resource and save data to provider. -func (s *FileStore) Release() error { - s.p.lock.Lock() - defer s.p.lock.Unlock() - - // Skip encoding if the data is empty - if len(s.data) == 0 { - return nil - } - - data, err := EncodeGob(s.data) - if err != nil { - return err - } - - return ioutil.WriteFile(s.p.filepath(s.sid), data, 0600) -} - -// Flush deletes all session data. -func (s *FileStore) Flush() error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data = make(map[interface{}]interface{}) - return nil -} - -// FileProvider represents a file session provider implementation. -type FileProvider struct { - lock sync.RWMutex - maxlifetime int64 - rootPath string -} - -// Init initializes file session provider with given root path. -func (p *FileProvider) Init(maxlifetime int64, rootPath string) error { - p.lock.Lock() - p.maxlifetime = maxlifetime - p.rootPath = rootPath - p.lock.Unlock() - return nil -} - -func (p *FileProvider) filepath(sid string) string { - return path.Join(p.rootPath, string(sid[0]), string(sid[1]), sid) -} - -// Read returns raw session store by session ID. -func (p *FileProvider) Read(sid string) (_ RawStore, err error) { - filename := p.filepath(sid) - if err = os.MkdirAll(path.Dir(filename), 0700); err != nil { - return nil, err - } - p.lock.RLock() - defer p.lock.RUnlock() - - var f *os.File - ok := false - if com.IsFile(filename) { - modTime, err := com.FileMTime(filename) - if err != nil { - return nil, err - } - ok = (modTime + p.maxlifetime) >= time.Now().Unix() - } - if ok { - f, err = os.OpenFile(filename, os.O_RDONLY, 0600) - } else { - f, err = os.Create(filename) - } - if err != nil { - return nil, err - } - defer f.Close() - - if err = os.Chtimes(filename, time.Now(), time.Now()); err != nil { - return nil, err - } - - var kv map[interface{}]interface{} - data, err := ioutil.ReadAll(f) - if err != nil { - return nil, err - } - if len(data) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = DecodeGob(data) - if err != nil { - return nil, err - } - } - return NewFileStore(p, sid, kv), nil -} - -// Exist returns true if session with given ID exists. -func (p *FileProvider) Exist(sid string) bool { - p.lock.RLock() - defer p.lock.RUnlock() - return com.IsFile(p.filepath(sid)) -} - -// Destroy deletes a session by session ID. -func (p *FileProvider) Destroy(sid string) error { - p.lock.Lock() - defer p.lock.Unlock() - return os.Remove(p.filepath(sid)) -} - -func (p *FileProvider) regenerate(oldsid, sid string) (err error) { - p.lock.Lock() - defer p.lock.Unlock() - - filename := p.filepath(sid) - if com.IsExist(filename) { - return fmt.Errorf("new sid '%s' already exists", sid) - } - - oldname := p.filepath(oldsid) - if !com.IsFile(oldname) { - data, err := EncodeGob(make(map[interface{}]interface{})) - if err != nil { - return err - } - if err = os.MkdirAll(path.Dir(oldname), 0700); err != nil { - return err - } - if err = ioutil.WriteFile(oldname, data, 0600); err != nil { - return err - } - } - - if err = os.MkdirAll(path.Dir(filename), 0700); err != nil { - return err - } - if err = os.Rename(oldname, filename); err != nil { - return err - } - return nil -} - -// Regenerate regenerates a session store from old session ID to new one. -func (p *FileProvider) Regenerate(oldsid, sid string) (_ RawStore, err error) { - if err := p.regenerate(oldsid, sid); err != nil { - return nil, err - } - - return p.Read(sid) -} - -// Count counts and returns number of sessions. -func (p *FileProvider) Count() int { - count := 0 - if err := filepath.Walk(p.rootPath, func(path string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - - if !fi.IsDir() { - count++ - } - return nil - }); err != nil { - log.Printf("error counting session files: %v", err) - return 0 - } - return count -} - -// GC calls GC to clean expired sessions. -func (p *FileProvider) GC() { - p.lock.RLock() - defer p.lock.RUnlock() - - if !com.IsExist(p.rootPath) { - return - } - - if err := filepath.Walk(p.rootPath, func(path string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - - if !fi.IsDir() && - (fi.ModTime().Unix()+p.maxlifetime) < time.Now().Unix() { - return os.Remove(path) - } - return nil - }); err != nil { - log.Printf("error garbage collecting session files: %v", err) - } -} - -func init() { - Register("file", &FileProvider{}) -} diff --git a/vendor/gitea.com/macaron/session/flash.go b/vendor/gitea.com/macaron/session/flash.go deleted file mode 100644 index 93c461d47aad2..0000000000000 --- a/vendor/gitea.com/macaron/session/flash.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2018 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package session - -import ( - "net/url" - - "gitea.com/macaron/macaron" -) - -type Flash struct { - ctx *macaron.Context - url.Values - ErrorMsg, WarningMsg, InfoMsg, SuccessMsg string -} - -func (f *Flash) set(name, msg string, current ...bool) { - isShow := false - if (len(current) == 0 && macaron.FlashNow) || - (len(current) > 0 && current[0]) { - isShow = true - } - - if isShow { - f.ctx.Data["Flash"] = f - } else { - f.Set(name, msg) - } -} - -func (f *Flash) Error(msg string, current ...bool) { - f.ErrorMsg = msg - f.set("error", msg, current...) -} - -func (f *Flash) Warning(msg string, current ...bool) { - f.WarningMsg = msg - f.set("warning", msg, current...) -} - -func (f *Flash) Info(msg string, current ...bool) { - f.InfoMsg = msg - f.set("info", msg, current...) -} - -func (f *Flash) Success(msg string, current ...bool) { - f.SuccessMsg = msg - f.set("success", msg, current...) -} diff --git a/vendor/gitea.com/macaron/session/go.mod b/vendor/gitea.com/macaron/session/go.mod deleted file mode 100644 index f44315f827751..0000000000000 --- a/vendor/gitea.com/macaron/session/go.mod +++ /dev/null @@ -1,30 +0,0 @@ -module gitea.com/macaron/session - -go 1.11 - -require ( - gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727 - gitea.com/macaron/macaron v1.5.0 - github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 - github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89 - github.com/couchbase/gomemcached v0.1.0 // indirect - github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 // indirect - github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 // indirect - github.com/edsrzf/mmap-go v1.0.0 // indirect - github.com/go-redis/redis v6.15.2+incompatible - github.com/go-sql-driver/mysql v1.4.1 - github.com/golang/snappy v0.0.2 // indirect - github.com/lib/pq v1.2.0 - github.com/pkg/errors v0.8.1 // indirect - github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect - github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92 - github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d // indirect - github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 - github.com/stretchr/testify v1.3.0 // indirect - github.com/unknwon/com v1.0.1 - golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect - golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect - google.golang.org/appengine v1.6.1 // indirect - gopkg.in/ini.v1 v1.62.0 - gopkg.in/yaml.v2 v2.2.2 // indirect -) diff --git a/vendor/gitea.com/macaron/session/go.sum b/vendor/gitea.com/macaron/session/go.sum deleted file mode 100644 index cf76c4e87474c..0000000000000 --- a/vendor/gitea.com/macaron/session/go.sum +++ /dev/null @@ -1,118 +0,0 @@ -gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e h1:r1en/D7xJmcY24VkHkjkcJFa+7ZWubVWPBrvsHkmHxk= -gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e/go.mod h1:uJEsN4LQpeGYRCjuPXPZBClU7N5pWzGuyF4uqLpE/e0= -gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727 h1:ZF2Bd6rqVlwhIDhYiS0uGYcT+GaVNGjuKVJkTNqWMIs= -gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727/go.mod h1:h0OwsgcpJLSYtHcM5+Xciw9OEeuxi6ty4HDiO8C7aIY= -gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM= -gitea.com/macaron/macaron v1.5.0/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY= -github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA= -github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89 h1:uNLXQ6QO1TocD8BaN/KkRki0Xw0brCM1PKl/ZA5pgfs= -github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A= -github.com/couchbase/gomemcached v0.1.0 h1:whUde87n8CScx8ckMp2En5liqAlcuG3aKy/BQeBPu84= -github.com/couchbase/gomemcached v0.1.0/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= -github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 h1:NCqJ6fwen6YP0WlV/IyibaT0kPt3JEI1rA62V/UPKT4= -github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= -github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ= -github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4= -github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw= -github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM= -github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= -github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d h1:qQWKKOvHN7Q9c6GdmUteCef2F9ubxMpxY1IKwpIKz68= -github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY= -github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92 h1:qvsJwGToa8rxb42cDRhkbKeX2H5N8BH+s2aUikGt8mI= -github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= -github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d h1:NVwnfyR3rENtlz62bcrkXME3INVUa4lcdGt+opvxExs= -github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c h1:+EXw7AwNOKzPFXMZ1yNjO40aWCh3PIquJB2fYlv9wcs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/gitea.com/macaron/session/memcache/memcache.go b/vendor/gitea.com/macaron/session/memcache/memcache.go deleted file mode 100644 index ff120975429b5..0000000000000 --- a/vendor/gitea.com/macaron/session/memcache/memcache.go +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package session - -import ( - "fmt" - "strings" - "sync" - - "gitea.com/macaron/session" - "github.com/bradfitz/gomemcache/memcache" -) - -// MemcacheStore represents a memcache session store implementation. -type MemcacheStore struct { - c *memcache.Client - sid string - expire int32 - lock sync.RWMutex - data map[interface{}]interface{} -} - -// NewMemcacheStore creates and returns a memcache session store. -func NewMemcacheStore(c *memcache.Client, sid string, expire int32, kv map[interface{}]interface{}) *MemcacheStore { - return &MemcacheStore{ - c: c, - sid: sid, - expire: expire, - data: kv, - } -} - -func NewItem(sid string, data []byte, expire int32) *memcache.Item { - return &memcache.Item{ - Key: sid, - Value: data, - Expiration: expire, - } -} - -// Set sets value to given key in session. -func (s *MemcacheStore) Set(key, val interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data[key] = val - return nil -} - -// Get gets value by given key in session. -func (s *MemcacheStore) Get(key interface{}) interface{} { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.data[key] -} - -// Delete delete a key from session. -func (s *MemcacheStore) Delete(key interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - delete(s.data, key) - return nil -} - -// ID returns current session ID. -func (s *MemcacheStore) ID() string { - return s.sid -} - -// Release releases resource and save data to provider. -func (s *MemcacheStore) Release() error { - // Skip encoding if the data is empty - if len(s.data) == 0 { - return nil - } - - data, err := session.EncodeGob(s.data) - if err != nil { - return err - } - - return s.c.Set(NewItem(s.sid, data, s.expire)) -} - -// Flush deletes all session data. -func (s *MemcacheStore) Flush() error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data = make(map[interface{}]interface{}) - return nil -} - -// MemcacheProvider represents a memcache session provider implementation. -type MemcacheProvider struct { - c *memcache.Client - expire int32 -} - -// Init initializes memcache session provider. -// connStrs: 127.0.0.1:9090;127.0.0.1:9091 -func (p *MemcacheProvider) Init(expire int64, connStrs string) error { - p.expire = int32(expire) - p.c = memcache.New(strings.Split(connStrs, ";")...) - return nil -} - -// Read returns raw session store by session ID. -func (p *MemcacheProvider) Read(sid string) (session.RawStore, error) { - if !p.Exist(sid) { - if err := p.c.Set(NewItem(sid, []byte(""), p.expire)); err != nil { - return nil, err - } - } - - var kv map[interface{}]interface{} - item, err := p.c.Get(sid) - if err != nil { - return nil, err - } - if len(item.Value) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(item.Value) - if err != nil { - return nil, err - } - } - - return NewMemcacheStore(p.c, sid, p.expire, kv), nil -} - -// Exist returns true if session with given ID exists. -func (p *MemcacheProvider) Exist(sid string) bool { - _, err := p.c.Get(sid) - return err == nil -} - -// Destroy deletes a session by session ID. -func (p *MemcacheProvider) Destroy(sid string) error { - return p.c.Delete(sid) -} - -// Regenerate regenerates a session store from old session ID to new one. -func (p *MemcacheProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) { - if p.Exist(sid) { - return nil, fmt.Errorf("new sid '%s' already exists", sid) - } - - item := NewItem(sid, []byte(""), p.expire) - if p.Exist(oldsid) { - item, err = p.c.Get(oldsid) - if err != nil { - return nil, err - } else if err = p.c.Delete(oldsid); err != nil { - return nil, err - } - item.Key = sid - } - if err = p.c.Set(item); err != nil { - return nil, err - } - - var kv map[interface{}]interface{} - if len(item.Value) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(item.Value) - if err != nil { - return nil, err - } - } - - return NewMemcacheStore(p.c, sid, p.expire, kv), nil -} - -// Count counts and returns number of sessions. -func (p *MemcacheProvider) Count() int { - // FIXME: how come this library does not have Stats method? - return -1 -} - -// GC calls GC to clean expired sessions. -func (p *MemcacheProvider) GC() {} - -func init() { - session.Register("memcache", &MemcacheProvider{}) -} diff --git a/vendor/gitea.com/macaron/session/memcache/memcache.goconvey b/vendor/gitea.com/macaron/session/memcache/memcache.goconvey deleted file mode 100644 index 8485e986e458a..0000000000000 --- a/vendor/gitea.com/macaron/session/memcache/memcache.goconvey +++ /dev/null @@ -1 +0,0 @@ -ignore \ No newline at end of file diff --git a/vendor/gitea.com/macaron/session/memory.go b/vendor/gitea.com/macaron/session/memory.go deleted file mode 100644 index 0769225752e6e..0000000000000 --- a/vendor/gitea.com/macaron/session/memory.go +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package session - -import ( - "container/list" - "fmt" - "sync" - "time" -) - -// MemStore represents a in-memory session store implementation. -type MemStore struct { - sid string - lock sync.RWMutex - data map[interface{}]interface{} - lastAccess time.Time -} - -// NewMemStore creates and returns a memory session store. -func NewMemStore(sid string) *MemStore { - return &MemStore{ - sid: sid, - data: make(map[interface{}]interface{}), - lastAccess: time.Now(), - } -} - -// Set sets value to given key in session. -func (s *MemStore) Set(key, val interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data[key] = val - return nil -} - -// Get gets value by given key in session. -func (s *MemStore) Get(key interface{}) interface{} { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.data[key] -} - -// Delete deletes a key from session. -func (s *MemStore) Delete(key interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - delete(s.data, key) - return nil -} - -// ID returns current session ID. -func (s *MemStore) ID() string { - return s.sid -} - -// Release releases resource and save data to provider. -func (_ *MemStore) Release() error { - return nil -} - -// Flush deletes all session data. -func (s *MemStore) Flush() error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data = make(map[interface{}]interface{}) - return nil -} - -// MemProvider represents a in-memory session provider implementation. -type MemProvider struct { - lock sync.RWMutex - maxLifetime int64 - data map[string]*list.Element - // A priority list whose lastAccess newer gets higer priority. - list *list.List -} - -// Init initializes memory session provider. -func (p *MemProvider) Init(maxLifetime int64, _ string) error { - p.lock.Lock() - p.list = list.New() - p.data = make(map[string]*list.Element) - p.maxLifetime = maxLifetime - p.lock.Unlock() - return nil -} - -// update expands time of session store by given ID. -func (p *MemProvider) update(sid string) error { - p.lock.Lock() - defer p.lock.Unlock() - - if e, ok := p.data[sid]; ok { - e.Value.(*MemStore).lastAccess = time.Now() - p.list.MoveToFront(e) - return nil - } - return nil -} - -// Read returns raw session store by session ID. -func (p *MemProvider) Read(sid string) (_ RawStore, err error) { - p.lock.RLock() - e, ok := p.data[sid] - p.lock.RUnlock() - - // Only restore if the session is still alive. - if ok && (e.Value.(*MemStore).lastAccess.Unix()+p.maxLifetime) >= time.Now().Unix() { - if err = p.update(sid); err != nil { - return nil, err - } - return e.Value.(*MemStore), nil - } - - // Create a new session. - p.lock.Lock() - defer p.lock.Unlock() - if ok { - p.list.Remove(e) - delete(p.data, sid) - } - s := NewMemStore(sid) - p.data[sid] = p.list.PushBack(s) - return s, nil -} - -// Exist returns true if session with given ID exists. -func (p *MemProvider) Exist(sid string) bool { - p.lock.RLock() - defer p.lock.RUnlock() - - _, ok := p.data[sid] - return ok -} - -// Destroy deletes a session by session ID. -func (p *MemProvider) Destroy(sid string) error { - p.lock.Lock() - defer p.lock.Unlock() - - e, ok := p.data[sid] - if !ok { - return nil - } - - p.list.Remove(e) - delete(p.data, sid) - return nil -} - -// Regenerate regenerates a session store from old session ID to new one. -func (p *MemProvider) Regenerate(oldsid, sid string) (RawStore, error) { - if p.Exist(sid) { - return nil, fmt.Errorf("new sid '%s' already exists", sid) - } - - s, err := p.Read(oldsid) - if err != nil { - return nil, err - } - - if err = p.Destroy(oldsid); err != nil { - return nil, err - } - - s.(*MemStore).sid = sid - - p.lock.Lock() - defer p.lock.Unlock() - p.data[sid] = p.list.PushBack(s) - return s, nil -} - -// Count counts and returns number of sessions. -func (p *MemProvider) Count() int { - return p.list.Len() -} - -// GC calls GC to clean expired sessions. -func (p *MemProvider) GC() { - p.lock.RLock() - for { - // No session in the list. - e := p.list.Back() - if e == nil { - break - } - - if (e.Value.(*MemStore).lastAccess.Unix() + p.maxLifetime) < time.Now().Unix() { - p.lock.RUnlock() - p.lock.Lock() - p.list.Remove(e) - delete(p.data, e.Value.(*MemStore).sid) - p.lock.Unlock() - p.lock.RLock() - } else { - break - } - } - p.lock.RUnlock() -} - -func init() { - Register("memory", &MemProvider{}) -} diff --git a/vendor/gitea.com/macaron/session/mysql/mysql.go b/vendor/gitea.com/macaron/session/mysql/mysql.go deleted file mode 100644 index af1cd9dd1b1e2..0000000000000 --- a/vendor/gitea.com/macaron/session/mysql/mysql.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package session - -import ( - "database/sql" - "fmt" - "log" - "sync" - "time" - - "gitea.com/macaron/session" - _ "github.com/go-sql-driver/mysql" -) - -// MysqlStore represents a mysql session store implementation. -type MysqlStore struct { - c *sql.DB - sid string - lock sync.RWMutex - data map[interface{}]interface{} -} - -// NewMysqlStore creates and returns a mysql session store. -func NewMysqlStore(c *sql.DB, sid string, kv map[interface{}]interface{}) *MysqlStore { - return &MysqlStore{ - c: c, - sid: sid, - data: kv, - } -} - -// Set sets value to given key in session. -func (s *MysqlStore) Set(key, val interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data[key] = val - return nil -} - -// Get gets value by given key in session. -func (s *MysqlStore) Get(key interface{}) interface{} { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.data[key] -} - -// Delete delete a key from session. -func (s *MysqlStore) Delete(key interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - delete(s.data, key) - return nil -} - -// ID returns current session ID. -func (s *MysqlStore) ID() string { - return s.sid -} - -// Release releases resource and save data to provider. -func (s *MysqlStore) Release() error { - // Skip encoding if the data is empty - if len(s.data) == 0 { - return nil - } - - data, err := session.EncodeGob(s.data) - if err != nil { - return err - } - - _, err = s.c.Exec("UPDATE session SET data=?, expiry=? WHERE `key`=?", - data, time.Now().Unix(), s.sid) - return err -} - -// Flush deletes all session data. -func (s *MysqlStore) Flush() error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data = make(map[interface{}]interface{}) - return nil -} - -// MysqlProvider represents a mysql session provider implementation. -type MysqlProvider struct { - c *sql.DB - expire int64 -} - -// Init initializes mysql session provider. -// connStr: username:password@protocol(address)/dbname?param=value -func (p *MysqlProvider) Init(expire int64, connStr string) (err error) { - p.expire = expire - - p.c, err = sql.Open("mysql", connStr) - if err != nil { - return err - } - return p.c.Ping() -} - -// Read returns raw session store by session ID. -func (p *MysqlProvider) Read(sid string) (session.RawStore, error) { - now := time.Now().Unix() - var data []byte - expiry := now - err := p.c.QueryRow("SELECT data, expiry FROM session WHERE `key`=?", sid).Scan(&data, &expiry) - if err == sql.ErrNoRows { - _, err = p.c.Exec("INSERT INTO session(`key`,data,expiry) VALUES(?,?,?)", - sid, "", now) - } - if err != nil { - return nil, err - } - - var kv map[interface{}]interface{} - if len(data) == 0 || expiry+p.expire <= now { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(data) - if err != nil { - return nil, err - } - } - - return NewMysqlStore(p.c, sid, kv), nil -} - -// Exist returns true if session with given ID exists. -func (p *MysqlProvider) Exist(sid string) bool { - var data []byte - err := p.c.QueryRow("SELECT data FROM session WHERE `key`=?", sid).Scan(&data) - if err != nil && err != sql.ErrNoRows { - panic("session/mysql: error checking existence: " + err.Error()) - } - return err != sql.ErrNoRows -} - -// Destroy deletes a session by session ID. -func (p *MysqlProvider) Destroy(sid string) error { - _, err := p.c.Exec("DELETE FROM session WHERE `key`=?", sid) - return err -} - -// Regenerate regenerates a session store from old session ID to new one. -func (p *MysqlProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) { - if p.Exist(sid) { - return nil, fmt.Errorf("new sid '%s' already exists", sid) - } - - if !p.Exist(oldsid) { - if _, err = p.c.Exec("INSERT INTO session(`key`,data,expiry) VALUES(?,?,?)", - oldsid, "", time.Now().Unix()); err != nil { - return nil, err - } - } - - if _, err = p.c.Exec("UPDATE session SET `key`=? WHERE `key`=?", sid, oldsid); err != nil { - return nil, err - } - - return p.Read(sid) -} - -// Count counts and returns number of sessions. -func (p *MysqlProvider) Count() (total int) { - if err := p.c.QueryRow("SELECT COUNT(*) AS NUM FROM session").Scan(&total); err != nil { - panic("session/mysql: error counting records: " + err.Error()) - } - return total -} - -// GC calls GC to clean expired sessions. -func (p *MysqlProvider) GC() { - if _, err := p.c.Exec("DELETE FROM session WHERE expiry + ? <= UNIX_TIMESTAMP(NOW())", p.expire); err != nil { - log.Printf("session/mysql: error garbage collecting: %v", err) - } -} - -func init() { - session.Register("mysql", &MysqlProvider{}) -} diff --git a/vendor/gitea.com/macaron/session/mysql/mysql.goconvey b/vendor/gitea.com/macaron/session/mysql/mysql.goconvey deleted file mode 100644 index 8485e986e458a..0000000000000 --- a/vendor/gitea.com/macaron/session/mysql/mysql.goconvey +++ /dev/null @@ -1 +0,0 @@ -ignore \ No newline at end of file diff --git a/vendor/gitea.com/macaron/session/nodb/nodb.go b/vendor/gitea.com/macaron/session/nodb/nodb.go deleted file mode 100644 index 08a73c5490906..0000000000000 --- a/vendor/gitea.com/macaron/session/nodb/nodb.go +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2015 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package session - -import ( - "fmt" - "sync" - - "gitea.com/macaron/session" - "gitea.com/lunny/nodb" - "gitea.com/lunny/nodb/config" -) - -// NodbStore represents a nodb session store implementation. -type NodbStore struct { - c *nodb.DB - sid string - expire int64 - lock sync.RWMutex - data map[interface{}]interface{} -} - -// NewNodbStore creates and returns a ledis session store. -func NewNodbStore(c *nodb.DB, sid string, expire int64, kv map[interface{}]interface{}) *NodbStore { - return &NodbStore{ - c: c, - expire: expire, - sid: sid, - data: kv, - } -} - -// Set sets value to given key in session. -func (s *NodbStore) Set(key, val interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data[key] = val - return nil -} - -// Get gets value by given key in session. -func (s *NodbStore) Get(key interface{}) interface{} { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.data[key] -} - -// Delete delete a key from session. -func (s *NodbStore) Delete(key interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - delete(s.data, key) - return nil -} - -// ID returns current session ID. -func (s *NodbStore) ID() string { - return s.sid -} - -// Release releases resource and save data to provider. -func (s *NodbStore) Release() error { - // Skip encoding if the data is empty - if len(s.data) == 0 { - return nil - } - - data, err := session.EncodeGob(s.data) - if err != nil { - return err - } - - if err = s.c.Set([]byte(s.sid), data); err != nil { - return err - } - _, err = s.c.Expire([]byte(s.sid), s.expire) - return err -} - -// Flush deletes all session data. -func (s *NodbStore) Flush() error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data = make(map[interface{}]interface{}) - return nil -} - -// NodbProvider represents a ledis session provider implementation. -type NodbProvider struct { - c *nodb.DB - expire int64 -} - -// Init initializes nodb session provider. -func (p *NodbProvider) Init(expire int64, configs string) error { - p.expire = expire - - cfg := new(config.Config) - cfg.DataDir = configs - dbs, err := nodb.Open(cfg) - if err != nil { - return fmt.Errorf("session/nodb: error opening db: %v", err) - } - - p.c, err = dbs.Select(0) - return err -} - -// Read returns raw session store by session ID. -func (p *NodbProvider) Read(sid string) (session.RawStore, error) { - if !p.Exist(sid) { - if err := p.c.Set([]byte(sid), []byte("")); err != nil { - return nil, err - } - } - - var kv map[interface{}]interface{} - kvs, err := p.c.Get([]byte(sid)) - if err != nil { - return nil, err - } - if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(kvs) - if err != nil { - return nil, err - } - } - - return NewNodbStore(p.c, sid, p.expire, kv), nil -} - -// Exist returns true if session with given ID exists. -func (p *NodbProvider) Exist(sid string) bool { - count, err := p.c.Exists([]byte(sid)) - return err == nil && count > 0 -} - -// Destroy deletes a session by session ID. -func (p *NodbProvider) Destroy(sid string) error { - _, err := p.c.Del([]byte(sid)) - return err -} - -// Regenerate regenerates a session store from old session ID to new one. -func (p *NodbProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) { - if p.Exist(sid) { - return nil, fmt.Errorf("new sid '%s' already exists", sid) - } - - kvs := make([]byte, 0) - if p.Exist(oldsid) { - if kvs, err = p.c.Get([]byte(oldsid)); err != nil { - return nil, err - } else if _, err = p.c.Del([]byte(oldsid)); err != nil { - return nil, err - } - } - - if err = p.c.Set([]byte(sid), kvs); err != nil { - return nil, err - } else if _, err = p.c.Expire([]byte(sid), p.expire); err != nil { - return nil, err - } - - var kv map[interface{}]interface{} - if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob([]byte(kvs)) - if err != nil { - return nil, err - } - } - - return NewNodbStore(p.c, sid, p.expire, kv), nil -} - -// Count counts and returns number of sessions. -func (p *NodbProvider) Count() int { - // FIXME: how come this library does not have DbSize() method? - return -1 -} - -// GC calls GC to clean expired sessions. -func (p *NodbProvider) GC() {} - -func init() { - session.Register("nodb", &NodbProvider{}) -} diff --git a/vendor/gitea.com/macaron/session/nodb/nodb.goconvey b/vendor/gitea.com/macaron/session/nodb/nodb.goconvey deleted file mode 100644 index 8485e986e458a..0000000000000 --- a/vendor/gitea.com/macaron/session/nodb/nodb.goconvey +++ /dev/null @@ -1 +0,0 @@ -ignore \ No newline at end of file diff --git a/vendor/gitea.com/macaron/session/postgres/postgres.go b/vendor/gitea.com/macaron/session/postgres/postgres.go deleted file mode 100644 index f173021d515cb..0000000000000 --- a/vendor/gitea.com/macaron/session/postgres/postgres.go +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package session - -import ( - "database/sql" - "fmt" - "log" - "sync" - "time" - - "gitea.com/macaron/session" - _ "github.com/lib/pq" -) - -// PostgresStore represents a postgres session store implementation. -type PostgresStore struct { - c *sql.DB - sid string - lock sync.RWMutex - data map[interface{}]interface{} -} - -// NewPostgresStore creates and returns a postgres session store. -func NewPostgresStore(c *sql.DB, sid string, kv map[interface{}]interface{}) *PostgresStore { - return &PostgresStore{ - c: c, - sid: sid, - data: kv, - } -} - -// Set sets value to given key in session. -func (s *PostgresStore) Set(key, value interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data[key] = value - return nil -} - -// Get gets value by given key in session. -func (s *PostgresStore) Get(key interface{}) interface{} { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.data[key] -} - -// Delete delete a key from session. -func (s *PostgresStore) Delete(key interface{}) error { - s.lock.Lock() - defer s.lock.Unlock() - - delete(s.data, key) - return nil -} - -// ID returns current session ID. -func (s *PostgresStore) ID() string { - return s.sid -} - -// save postgres session values to database. -// must call this method to save values to database. -func (s *PostgresStore) Release() error { - // Skip encoding if the data is empty - if len(s.data) == 0 { - return nil - } - - data, err := session.EncodeGob(s.data) - if err != nil { - return err - } - - _, err = s.c.Exec("UPDATE session SET data=$1, expiry=$2 WHERE key=$3", - data, time.Now().Unix(), s.sid) - return err -} - -// Flush deletes all session data. -func (s *PostgresStore) Flush() error { - s.lock.Lock() - defer s.lock.Unlock() - - s.data = make(map[interface{}]interface{}) - return nil -} - -// PostgresProvider represents a postgres session provider implementation. -type PostgresProvider struct { - c *sql.DB - maxlifetime int64 -} - -// Init initializes postgres session provider. -// connStr: user=a password=b host=localhost port=5432 dbname=c sslmode=disable -func (p *PostgresProvider) Init(maxlifetime int64, connStr string) (err error) { - p.maxlifetime = maxlifetime - - p.c, err = sql.Open("postgres", connStr) - if err != nil { - return err - } - return p.c.Ping() -} - -// Read returns raw session store by session ID. -func (p *PostgresProvider) Read(sid string) (session.RawStore, error) { - now := time.Now().Unix() - var data []byte - expiry := now - err := p.c.QueryRow("SELECT data, expiry FROM session WHERE key=$1", sid).Scan(&data, &expiry) - if err == sql.ErrNoRows { - _, err = p.c.Exec("INSERT INTO session(key,data,expiry) VALUES($1,$2,$3)", - sid, "", now) - } - if err != nil { - return nil, err - } - - var kv map[interface{}]interface{} - if len(data) == 0 || expiry+p.maxlifetime <= now { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(data) - if err != nil { - return nil, err - } - } - - return NewPostgresStore(p.c, sid, kv), nil -} - -// Exist returns true if session with given ID exists. -func (p *PostgresProvider) Exist(sid string) bool { - var data []byte - err := p.c.QueryRow("SELECT data FROM session WHERE key=$1", sid).Scan(&data) - if err != nil && err != sql.ErrNoRows { - panic("session/postgres: error checking existence: " + err.Error()) - } - return err != sql.ErrNoRows -} - -// Destroy deletes a session by session ID. -func (p *PostgresProvider) Destroy(sid string) error { - _, err := p.c.Exec("DELETE FROM session WHERE key=$1", sid) - return err -} - -// Regenerate regenerates a session store from old session ID to new one. -func (p *PostgresProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) { - if p.Exist(sid) { - return nil, fmt.Errorf("new sid '%s' already exists", sid) - } - - if !p.Exist(oldsid) { - if _, err = p.c.Exec("INSERT INTO session(key,data,expiry) VALUES($1,$2,$3)", - oldsid, "", time.Now().Unix()); err != nil { - return nil, err - } - } - - if _, err = p.c.Exec("UPDATE session SET key=$1 WHERE key=$2", sid, oldsid); err != nil { - return nil, err - } - - return p.Read(sid) -} - -// Count counts and returns number of sessions. -func (p *PostgresProvider) Count() (total int) { - if err := p.c.QueryRow("SELECT COUNT(*) AS NUM FROM session").Scan(&total); err != nil { - panic("session/postgres: error counting records: " + err.Error()) - } - return total -} - -// GC calls GC to clean expired sessions. -func (p *PostgresProvider) GC() { - if _, err := p.c.Exec("DELETE FROM session WHERE EXTRACT(EPOCH FROM NOW()) - expiry > $1", p.maxlifetime); err != nil { - log.Printf("session/postgres: error garbage collecting: %v", err) - } -} - -func init() { - session.Register("postgres", &PostgresProvider{}) -} diff --git a/vendor/gitea.com/macaron/session/postgres/postgres.goconvey b/vendor/gitea.com/macaron/session/postgres/postgres.goconvey deleted file mode 100644 index 8485e986e458a..0000000000000 --- a/vendor/gitea.com/macaron/session/postgres/postgres.goconvey +++ /dev/null @@ -1 +0,0 @@ -ignore \ No newline at end of file diff --git a/vendor/gitea.com/macaron/session/session.go b/vendor/gitea.com/macaron/session/session.go deleted file mode 100644 index 93f18342d05b4..0000000000000 --- a/vendor/gitea.com/macaron/session/session.go +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -// Package session a middleware that provides the session management of Macaron. -package session - -import ( - "encoding/hex" - "errors" - "fmt" - "net/http" - "net/url" - "time" - - "gitea.com/macaron/macaron" -) - -const _VERSION = "0.6.0" - -func Version() string { - return _VERSION -} - -// RawStore is the interface that operates the session data. -type RawStore interface { - // Set sets value to given key in session. - Set(interface{}, interface{}) error - // Get gets value by given key in session. - Get(interface{}) interface{} - // Delete deletes a key from session. - Delete(interface{}) error - // ID returns current session ID. - ID() string - // Release releases session resource and save data to provider. - Release() error - // Flush deletes all session data. - Flush() error -} - -// Store is the interface that contains all data for one session process with specific ID. -type Store interface { - RawStore - // Read returns raw session store by session ID. - Read(string) (RawStore, error) - // Destroy deletes a session. - Destroy(*macaron.Context) error - // RegenerateId regenerates a session store from old session ID to new one. - RegenerateId(*macaron.Context) (RawStore, error) - // Count counts and returns number of sessions. - Count() int - // GC calls GC to clean expired sessions. - GC() -} - -type store struct { - RawStore - *Manager -} - -var _ Store = &store{} - -// Options represents a struct for specifying configuration options for the session middleware. -type Options struct { - // Name of provider. Default is "memory". - Provider string - // Provider configuration, it's corresponding to provider. - ProviderConfig string - // Cookie name to save session ID. Default is "MacaronSession". - CookieName string - // Cookie path to store. Default is "/". - CookiePath string - // GC interval time in seconds. Default is 3600. - Gclifetime int64 - // Max life time in seconds. Default is whatever GC interval time is. - Maxlifetime int64 - // Use HTTPS only. Default is false. - Secure bool - // Cookie life time. Default is 0. - CookieLifeTime int - // Cookie domain name. Default is empty. - Domain string - // Session ID length. Default is 16. - IDLength int - // Configuration section name. Default is "session". - Section string - // Ignore release for websocket. Default is false. - IgnoreReleaseForWebSocket bool -} - -func prepareOptions(options []Options) Options { - var opt Options - if len(options) > 0 { - opt = options[0] - } - if len(opt.Section) == 0 { - opt.Section = "session" - } - sec := macaron.Config().Section(opt.Section) - - if len(opt.Provider) == 0 { - opt.Provider = sec.Key("PROVIDER").MustString("memory") - } - if len(opt.ProviderConfig) == 0 { - opt.ProviderConfig = sec.Key("PROVIDER_CONFIG").MustString("data/sessions") - } - if len(opt.CookieName) == 0 { - opt.CookieName = sec.Key("COOKIE_NAME").MustString("MacaronSession") - } - if len(opt.CookiePath) == 0 { - opt.CookiePath = sec.Key("COOKIE_PATH").MustString("/") - } - if opt.Gclifetime == 0 { - opt.Gclifetime = sec.Key("GC_INTERVAL_TIME").MustInt64(3600) - } - if opt.Maxlifetime == 0 { - opt.Maxlifetime = sec.Key("MAX_LIFE_TIME").MustInt64(opt.Gclifetime) - } - if !opt.Secure { - opt.Secure = sec.Key("SECURE").MustBool() - } - if opt.CookieLifeTime == 0 { - opt.CookieLifeTime = sec.Key("COOKIE_LIFE_TIME").MustInt() - } - if len(opt.Domain) == 0 { - opt.Domain = sec.Key("DOMAIN").String() - } - if opt.IDLength == 0 { - opt.IDLength = sec.Key("ID_LENGTH").MustInt(16) - } - if !opt.IgnoreReleaseForWebSocket { - opt.IgnoreReleaseForWebSocket = sec.Key("IGNORE_RELEASE_FOR_WEBSOCKET").MustBool() - } - - return opt -} - -// Sessioner is a middleware that maps a session.SessionStore service into the Macaron handler chain. -// An single variadic session.Options struct can be optionally provided to configure. -func Sessioner(options ...Options) macaron.Handler { - opt := prepareOptions(options) - manager, err := NewManager(opt.Provider, opt) - if err != nil { - panic(err) - } - go manager.startGC() - - return func(ctx *macaron.Context) { - sess, err := manager.Start(ctx) - if err != nil { - panic("session(start): " + err.Error()) - } - - // Get flash. - vals, _ := url.ParseQuery(ctx.GetCookie("macaron_flash")) - if len(vals) > 0 { - f := &Flash{Values: vals} - f.ErrorMsg = f.Get("error") - f.SuccessMsg = f.Get("success") - f.InfoMsg = f.Get("info") - f.WarningMsg = f.Get("warning") - ctx.Data["Flash"] = f - ctx.SetCookie("macaron_flash", "", -1, opt.CookiePath) - } - - f := &Flash{ctx, url.Values{}, "", "", "", ""} - ctx.Resp.Before(func(macaron.ResponseWriter) { - if flash := f.Encode(); len(flash) > 0 { - ctx.SetCookie("macaron_flash", flash, 0, opt.CookiePath) - } - }) - - ctx.Map(f) - s := store{ - RawStore: sess, - Manager: manager, - } - - ctx.MapTo(s, (*Store)(nil)) - - ctx.Next() - - if manager.opt.IgnoreReleaseForWebSocket && ctx.Req.Header.Get("Upgrade") == "websocket" { - return - } - - if err = sess.Release(); err != nil { - panic("session(release): " + err.Error()) - } - } -} - -// Provider is the interface that provides session manipulations. -type Provider interface { - // Init initializes session provider. - Init(gclifetime int64, config string) error - // Read returns raw session store by session ID. - Read(sid string) (RawStore, error) - // Exist returns true if session with given ID exists. - Exist(sid string) bool - // Destroy deletes a session by session ID. - Destroy(sid string) error - // Regenerate regenerates a session store from old session ID to new one. - Regenerate(oldsid, sid string) (RawStore, error) - // Count counts and returns number of sessions. - Count() int - // GC calls GC to clean expired sessions. - GC() -} - -var providers = make(map[string]Provider) - -// Register registers a provider. -func Register(name string, provider Provider) { - if provider == nil { - panic("session: cannot register provider with nil value") - } - if _, dup := providers[name]; dup { - panic(fmt.Errorf("session: cannot register provider '%s' twice", name)) - } - providers[name] = provider -} - -// _____ -// / \ _____ ____ _____ ____ ___________ -// / \ / \\__ \ / \\__ \ / ___\_/ __ \_ __ \ -// / Y \/ __ \| | \/ __ \_/ /_/ > ___/| | \/ -// \____|__ (____ /___| (____ /\___ / \___ >__| -// \/ \/ \/ \//_____/ \/ - -// Manager represents a struct that contains session provider and its configuration. -type Manager struct { - provider Provider - opt Options -} - -// NewManager creates and returns a new session manager by given provider name and configuration. -// It panics when given provider isn't registered. -func NewManager(name string, opt Options) (*Manager, error) { - p, ok := providers[name] - if !ok { - return nil, fmt.Errorf("session: unknown provider '%s'(forgotten import?)", name) - } - return &Manager{p, opt}, p.Init(opt.Maxlifetime, opt.ProviderConfig) -} - -// sessionID generates a new session ID with rand string, unix nano time, remote addr by hash function. -func (m *Manager) sessionID() string { - return hex.EncodeToString(generateRandomKey(m.opt.IDLength / 2)) -} - -// validSessionID tests whether a provided session ID is a valid session ID. -func (m *Manager) validSessionID(sid string) (bool, error) { - if len(sid) != m.opt.IDLength { - return false, errors.New("invalid 'sid': " + sid) - } - - for i := range sid { - switch { - case '0' <= sid[i] && sid[i] <= '9': - case 'a' <= sid[i] && sid[i] <= 'f': - default: - return false, errors.New("invalid 'sid': " + sid) - } - } - return true, nil -} - -// Start starts a session by generating new one -// or retrieve existence one by reading session ID from HTTP request if it's valid. -func (m *Manager) Start(ctx *macaron.Context) (RawStore, error) { - sid := ctx.GetCookie(m.opt.CookieName) - valid, _ := m.validSessionID(sid) - if len(sid) > 0 && valid && m.provider.Exist(sid) { - return m.provider.Read(sid) - } - - sid = m.sessionID() - sess, err := m.provider.Read(sid) - if err != nil { - return nil, err - } - - cookie := &http.Cookie{ - Name: m.opt.CookieName, - Value: sid, - Path: m.opt.CookiePath, - HttpOnly: true, - Secure: m.opt.Secure, - Domain: m.opt.Domain, - } - if m.opt.CookieLifeTime >= 0 { - cookie.MaxAge = m.opt.CookieLifeTime - } - http.SetCookie(ctx.Resp, cookie) - ctx.Req.AddCookie(cookie) - return sess, nil -} - -// Read returns raw session store by session ID. -func (m *Manager) Read(sid string) (RawStore, error) { - // Ensure we're trying to read a valid session ID - if _, err := m.validSessionID(sid); err != nil { - return nil, err - } - - return m.provider.Read(sid) -} - -// Destroy deletes a session by given ID. -func (m *Manager) Destroy(ctx *macaron.Context) error { - sid := ctx.GetCookie(m.opt.CookieName) - if len(sid) == 0 { - return nil - } - - if _, err := m.validSessionID(sid); err != nil { - return err - } - - if err := m.provider.Destroy(sid); err != nil { - return err - } - cookie := &http.Cookie{ - Name: m.opt.CookieName, - Path: m.opt.CookiePath, - HttpOnly: true, - Expires: time.Now(), - MaxAge: -1, - } - http.SetCookie(ctx.Resp, cookie) - return nil -} - -// RegenerateId regenerates a session store from old session ID to new one. -func (m *Manager) RegenerateId(ctx *macaron.Context) (sess RawStore, err error) { - sid := m.sessionID() - oldsid := ctx.GetCookie(m.opt.CookieName) - _, err = m.validSessionID(oldsid) - if err != nil { - return nil, err - } - sess, err = m.provider.Regenerate(oldsid, sid) - if err != nil { - return nil, err - } - cookie := &http.Cookie{ - Name: m.opt.CookieName, - Value: sid, - Path: m.opt.CookiePath, - HttpOnly: true, - Secure: m.opt.Secure, - Domain: m.opt.Domain, - } - if m.opt.CookieLifeTime >= 0 { - cookie.MaxAge = m.opt.CookieLifeTime - } - http.SetCookie(ctx.Resp, cookie) - ctx.Req.AddCookie(cookie) - return sess, nil -} - -// Count counts and returns number of sessions. -func (m *Manager) Count() int { - return m.provider.Count() -} - -// GC starts GC job in a certain period. -func (m *Manager) GC() { - m.provider.GC() -} - -// startGC starts GC job in a certain period. -func (m *Manager) startGC() { - m.GC() - time.AfterFunc(time.Duration(m.opt.Gclifetime)*time.Second, func() { m.startGC() }) -} - -// SetSecure indicates whether to set cookie with HTTPS or not. -func (m *Manager) SetSecure(secure bool) { - m.opt.Secure = secure -} diff --git a/vendor/gitea.com/macaron/session/utils.go b/vendor/gitea.com/macaron/session/utils.go deleted file mode 100644 index 762b978cdfaa0..0000000000000 --- a/vendor/gitea.com/macaron/session/utils.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package session - -import ( - "bytes" - "crypto/rand" - "encoding/gob" - "io" - - "github.com/unknwon/com" -) - -func init() { - gob.Register([]interface{}{}) - gob.Register(map[int]interface{}{}) - gob.Register(map[string]interface{}{}) - gob.Register(map[interface{}]interface{}{}) - gob.Register(map[string]string{}) - gob.Register(map[int]string{}) - gob.Register(map[int]int{}) - gob.Register(map[int]int64{}) -} - -func EncodeGob(obj map[interface{}]interface{}) ([]byte, error) { - for _, v := range obj { - gob.Register(v) - } - buf := bytes.NewBuffer(nil) - err := gob.NewEncoder(buf).Encode(obj) - return buf.Bytes(), err -} - -func DecodeGob(encoded []byte) (out map[interface{}]interface{}, err error) { - buf := bytes.NewBuffer(encoded) - err = gob.NewDecoder(buf).Decode(&out) - return out, err -} - -// NOTE: A local copy in case of underlying package change -var alphanum = []byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") - -// generateRandomKey creates a random key with the given strength. -func generateRandomKey(strength int) []byte { - k := make([]byte, strength) - if n, err := io.ReadFull(rand.Reader, k); n != strength || err != nil { - return com.RandomCreateBytes(strength, alphanum...) - } - return k -} diff --git a/vendor/gitea.com/macaron/toolbox/.drone.yml b/vendor/gitea.com/macaron/toolbox/.drone.yml deleted file mode 100644 index 39499f444a57d..0000000000000 --- a/vendor/gitea.com/macaron/toolbox/.drone.yml +++ /dev/null @@ -1,9 +0,0 @@ -kind: pipeline -name: default - -steps: -- name: test - image: golang:1.11 - commands: - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic diff --git a/vendor/gitea.com/macaron/toolbox/.gitignore b/vendor/gitea.com/macaron/toolbox/.gitignore deleted file mode 100644 index c3265c11866f9..0000000000000 --- a/vendor/gitea.com/macaron/toolbox/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -profile/ -/.idea diff --git a/vendor/gitea.com/macaron/toolbox/LICENSE b/vendor/gitea.com/macaron/toolbox/LICENSE deleted file mode 100644 index 8405e89a0b120..0000000000000 --- a/vendor/gitea.com/macaron/toolbox/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/toolbox/README.md b/vendor/gitea.com/macaron/toolbox/README.md deleted file mode 100644 index 75055d5f07a8e..0000000000000 --- a/vendor/gitea.com/macaron/toolbox/README.md +++ /dev/null @@ -1,112 +0,0 @@ -toolbox -======= - -Middleware toolbox provides health chcek, pprof, profile and statistic services for [Macaron](https://gitea.com/macaron/macaron). - -[![Build Status](https://drone.gitea.com/api/badges/macaron/toolbox/status.svg)](https://drone.gitea.com/macaron/toolbox) -[API Reference](https://gowalker.org/gitea.com/macaron/toolbox) - -### Installation - - go get gitea.com/macaron/toolbox - -## Usage - -```go -// main.go -import ( - "gitea.com/macaron/macaron" - "gitea.com/macaron/toolbox" -) - -func main() { - m := macaron.Classic() - m.Use(toolbox.Toolboxer(m)) - m.Run() -} -``` - -Open your browser and visit `http://localhost:4000/debug` to see the effects. - -## Options - -`toolbox.Toolboxer` comes with a variety of configuration options: - -```go -type dummyChecker struct { -} - -func (dc *dummyChecker) Desc() string { - return "Dummy checker" -} - -func (dc *dummyChecker) Check() error { - return nil -} - -// ... -m.Use(toolbox.Toolboxer(m, toolbox.Options{ - URLPrefix: "/debug", // URL prefix for toolbox dashboard - HealthCheckURL: "/healthcheck", // URL for health check request - HealthCheckers: []HealthChecker{ - new(dummyChecker), - }, // Health checkers - HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{ - &toolbox.HealthCheckFuncDesc{ - Desc: "Database connection", - Func: func() error { return "OK" }, - }, - }, // Health check functions - DisableDebug: false, // Turns off all debug functionality when true - PprofURLPrefix: "/debug/pprof/", // URL prefix of pprof - ProfileURLPrefix: "/debug/profile/", // URL prefix of profile - ProfilePath: "profile", // Path store profile files -})) -// ... -``` - -## Route Statistic - -Toolbox also comes with a route call statistic functionality: - -```go -import ( - "os" - "time" - //... - "gitea.com/macaron/toolbox" -) - -func main() { - //... - m.Get("/", func(t toolbox.Toolbox) { - start := time.Now() - - // Other operations. - - t.AddStatistics("GET", "/", time.Since(start)) - }) - - m.Get("/dump", func(t toolbox.Toolbox) { - t.GetMap(os.Stdout) - }) -} -``` - -Output take from test: - -``` -+---------------------------------------------------+------------+------------------+------------------+------------------+------------------+------------------+ -| Request URL | Method | Times | Total Used(s) | Max Used(μs) | Min Used(μs) | Avg Used(μs) | -+---------------------------------------------------+------------+------------------+------------------+------------------+------------------+------------------+ -| /api/user | POST | 2 | 0.000122 | 120.000000 | 2.000000 | 61.000000 | -| /api/user | GET | 1 | 0.000013 | 13.000000 | 13.000000 | 13.000000 | -| /api/user | DELETE | 1 | 0.000001 | 1.400000 | 1.400000 | 1.400000 | -| /api/admin | POST | 1 | 0.000014 | 14.000000 | 14.000000 | 14.000000 | -| /api/user/unknwon | POST | 1 | 0.000012 | 12.000000 | 12.000000 | 12.000000 | -+---------------------------------------------------+------------+------------------+------------------+------------------+------------------+------------------+ -``` - -## License - -This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text. \ No newline at end of file diff --git a/vendor/gitea.com/macaron/toolbox/healthcheck.go b/vendor/gitea.com/macaron/toolbox/healthcheck.go deleted file mode 100644 index 25b5bdfe269df..0000000000000 --- a/vendor/gitea.com/macaron/toolbox/healthcheck.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package toolbox - -import ( - "bytes" -) - -// HealthChecker represents a health check instance. -type HealthChecker interface { - Desc() string - Check() error -} - -// HealthCheckFunc represents a callable function for health check. -type HealthCheckFunc func() error - -// HealthCheckFunc represents a callable function for health check with description. -type HealthCheckFuncDesc struct { - Desc string - Func HealthCheckFunc -} - -type healthCheck struct { - desc string - HealthChecker - check HealthCheckFunc // Not nil if add job as a function. -} - -// AddHealthCheck adds new health check job. -func (t *toolbox) AddHealthCheck(hc HealthChecker) { - t.healthCheckJobs = append(t.healthCheckJobs, &healthCheck{ - HealthChecker: hc, - }) -} - -// AddHealthCheckFunc adds a function as a new health check job. -func (t *toolbox) AddHealthCheckFunc(desc string, fn HealthCheckFunc) { - t.healthCheckJobs = append(t.healthCheckJobs, &healthCheck{ - desc: desc, - check: fn, - }) -} - -func (t *toolbox) handleHealthCheck() string { - if len(t.healthCheckJobs) == 0 { - return "no health check jobs" - } - - var buf bytes.Buffer - var err error - for _, job := range t.healthCheckJobs { - buf.WriteString("* ") - if job.check != nil { - buf.WriteString(job.desc) - err = job.check() - } else { - buf.WriteString(job.Desc()) - err = job.Check() - } - buf.WriteString(": ") - if err == nil { - buf.WriteString("OK") - } else { - buf.WriteString(err.Error()) - } - buf.WriteString("\n") - } - return buf.String() -} diff --git a/vendor/gitea.com/macaron/toolbox/profile.go b/vendor/gitea.com/macaron/toolbox/profile.go deleted file mode 100644 index 359a87fde4cbc..0000000000000 --- a/vendor/gitea.com/macaron/toolbox/profile.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package toolbox - -import ( - "bytes" - "errors" - "fmt" - "io" - "os" - "path" - "runtime" - "runtime/debug" - "runtime/pprof" - "time" - - "gitea.com/macaron/macaron" - "github.com/unknwon/com" -) - -var ( - profilePath string - pid int - startTime = time.Now() - inCPUProfile bool -) - -// StartCPUProfile starts CPU profile monitor. -func StartCPUProfile() error { - if inCPUProfile { - return errors.New("CPU profile has alreday been started!") - } - inCPUProfile = true - - os.MkdirAll(profilePath, os.ModePerm) - f, err := os.Create(path.Join(profilePath, "cpu-"+com.ToStr(pid)+".pprof")) - if err != nil { - panic("fail to record CPU profile: " + err.Error()) - } - pprof.StartCPUProfile(f) - return nil -} - -// StopCPUProfile stops CPU profile monitor. -func StopCPUProfile() error { - if !inCPUProfile { - return errors.New("CPU profile hasn't been started!") - } - pprof.StopCPUProfile() - inCPUProfile = false - return nil -} - -func init() { - pid = os.Getpid() -} - -// DumpMemProf dumps memory profile in pprof. -func DumpMemProf(w io.Writer) { - pprof.WriteHeapProfile(w) -} - -func dumpMemProf() { - os.MkdirAll(profilePath, os.ModePerm) - f, err := os.Create(path.Join(profilePath, "mem-"+com.ToStr(pid)+".memprof")) - if err != nil { - panic("fail to record memory profile: " + err.Error()) - } - runtime.GC() - DumpMemProf(f) - f.Close() -} - -func avg(items []time.Duration) time.Duration { - var sum time.Duration - for _, item := range items { - sum += item - } - return time.Duration(int64(sum) / int64(len(items))) -} - -func dumpGC(memStats *runtime.MemStats, gcstats *debug.GCStats, w io.Writer) { - - if gcstats.NumGC > 0 { - lastPause := gcstats.Pause[0] - elapsed := time.Now().Sub(startTime) - overhead := float64(gcstats.PauseTotal) / float64(elapsed) * 100 - allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds() - - fmt.Fprintf(w, "NumGC:%d Pause:%s Pause(Avg):%s Overhead:%3.2f%% Alloc:%s Sys:%s Alloc(Rate):%s/s Histogram:%s %s %s \n", - gcstats.NumGC, - com.ToStr(lastPause), - com.ToStr(avg(gcstats.Pause)), - overhead, - com.HumaneFileSize(memStats.Alloc), - com.HumaneFileSize(memStats.Sys), - com.HumaneFileSize(uint64(allocatedRate)), - com.ToStr(gcstats.PauseQuantiles[94]), - com.ToStr(gcstats.PauseQuantiles[98]), - com.ToStr(gcstats.PauseQuantiles[99])) - } else { - // while GC has disabled - elapsed := time.Now().Sub(startTime) - allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds() - - fmt.Fprintf(w, "Alloc:%s Sys:%s Alloc(Rate):%s/s\n", - com.HumaneFileSize(memStats.Alloc), - com.HumaneFileSize(memStats.Sys), - com.HumaneFileSize(uint64(allocatedRate))) - } -} - -// DumpGCSummary dumps GC information to io.Writer -func DumpGCSummary(w io.Writer) { - memStats := &runtime.MemStats{} - runtime.ReadMemStats(memStats) - gcstats := &debug.GCStats{PauseQuantiles: make([]time.Duration, 100)} - debug.ReadGCStats(gcstats) - - dumpGC(memStats, gcstats, w) -} - -func handleProfile(ctx *macaron.Context) string { - switch ctx.Query("op") { - case "startcpu": - if err := StartCPUProfile(); err != nil { - return err.Error() - } - case "stopcpu": - if err := StopCPUProfile(); err != nil { - return err.Error() - } - case "mem": - dumpMemProf() - case "gc": - var buf bytes.Buffer - DumpGCSummary(&buf) - return string(buf.Bytes()) - default: - return fmt.Sprintf(`

Available operations:

-
    -
  1. Start CPU profile
  2. -
  3. Stop CPU profile
  4. -
  5. Dump memory profile
  6. -
  7. Dump GC summary
  8. -
`, opt.ProfileURLPrefix) - } - ctx.Redirect(opt.ProfileURLPrefix) - return "" -} diff --git a/vendor/gitea.com/macaron/toolbox/statistic.go b/vendor/gitea.com/macaron/toolbox/statistic.go deleted file mode 100644 index 47e6ab23ee51e..0000000000000 --- a/vendor/gitea.com/macaron/toolbox/statistic.go +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2013 Beego Authors -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package toolbox - -import ( - "encoding/json" - "fmt" - "io" - "strings" - "sync" - "time" -) - -// Statistics struct -type Statistics struct { - RequestUrl string - RequestNum int64 - MinTime time.Duration - MaxTime time.Duration - TotalTime time.Duration -} - -// UrlMap contains several statistics struct to log different data -type UrlMap struct { - lock sync.RWMutex - LengthLimit int // limit the urlmap's length if it's equal to 0 there's no limit - urlmap map[string]map[string]*Statistics -} - -// add statistics task. -// it needs request method, request url and statistics time duration -func (m *UrlMap) AddStatistics(requestMethod, requestUrl string, requesttime time.Duration) { - m.lock.Lock() - defer m.lock.Unlock() - - if method, ok := m.urlmap[requestUrl]; ok { - if s, ok := method[requestMethod]; ok { - s.RequestNum += 1 - if s.MaxTime < requesttime { - s.MaxTime = requesttime - } - if s.MinTime > requesttime { - s.MinTime = requesttime - } - s.TotalTime += requesttime - } else { - nb := &Statistics{ - RequestUrl: requestUrl, - RequestNum: 1, - MinTime: requesttime, - MaxTime: requesttime, - TotalTime: requesttime, - } - m.urlmap[requestUrl][requestMethod] = nb - } - - } else { - if m.LengthLimit > 0 && m.LengthLimit <= len(m.urlmap) { - return - } - methodmap := make(map[string]*Statistics) - nb := &Statistics{ - RequestUrl: requestUrl, - RequestNum: 1, - MinTime: requesttime, - MaxTime: requesttime, - TotalTime: requesttime, - } - methodmap[requestMethod] = nb - m.urlmap[requestUrl] = methodmap - } -} - -// put url statistics result in io.Writer -func (m *UrlMap) GetMap(w io.Writer) { - m.lock.RLock() - defer m.lock.RUnlock() - - sep := fmt.Sprintf("+%s+%s+%s+%s+%s+%s+%s+\n", strings.Repeat("-", 51), strings.Repeat("-", 12), - strings.Repeat("-", 18), strings.Repeat("-", 18), strings.Repeat("-", 18), strings.Repeat("-", 18), strings.Repeat("-", 18)) - fmt.Fprintf(w, sep) - fmt.Fprintf(w, "| % -50s| % -10s | % -16s | % -16s | % -16s | % -16s | % -16s |\n", "Request URL", "Method", "Times", "Total Used(s)", "Max Used(μs)", "Min Used(μs)", "Avg Used(μs)") - fmt.Fprintf(w, sep) - - for k, v := range m.urlmap { - for kk, vv := range v { - fmt.Fprintf(w, "| % -50s| % -10s | % 16d | % 16f | % 16.6f | % 16.6f | % 16.6f |\n", k, - kk, vv.RequestNum, vv.TotalTime.Seconds(), float64(vv.MaxTime.Nanoseconds())/1000, - float64(vv.MinTime.Nanoseconds())/1000, float64(time.Duration(int64(vv.TotalTime)/vv.RequestNum).Nanoseconds())/1000, - ) - } - } - fmt.Fprintf(w, sep) -} - -type URLMapInfo struct { - URL string `json:"url"` - Method string `json:"method"` - Times int64 `json:"times"` - TotalUsed float64 `json:"total_used"` - MaxUsed float64 `json:"max_used"` - MinUsed float64 `json:"min_used"` - AvgUsed float64 `json:"avg_used"` -} - -func (m *UrlMap) JSON(w io.Writer) { - infos := make([]*URLMapInfo, 0, len(m.urlmap)) - for k, v := range m.urlmap { - for kk, vv := range v { - infos = append(infos, &URLMapInfo{ - URL: k, - Method: kk, - Times: vv.RequestNum, - TotalUsed: vv.TotalTime.Seconds(), - MaxUsed: float64(vv.MaxTime.Nanoseconds()) / 1000, - MinUsed: float64(vv.MinTime.Nanoseconds()) / 1000, - AvgUsed: float64(time.Duration(int64(vv.TotalTime)/vv.RequestNum).Nanoseconds()) / 1000, - }) - } - } - - if err := json.NewEncoder(w).Encode(infos); err != nil { - panic("URLMap.JSON: " + err.Error()) - } -} diff --git a/vendor/gitea.com/macaron/toolbox/toolbox.go b/vendor/gitea.com/macaron/toolbox/toolbox.go deleted file mode 100644 index 42e565e45beae..0000000000000 --- a/vendor/gitea.com/macaron/toolbox/toolbox.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2014 The Macaron Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -// Package toolbox is a middleware that provides health check, pprof, profile and statistic services for Macaron. -package toolbox - -import ( - "fmt" - "io" - "net/http" - "net/http/pprof" - "path" - "time" - - "gitea.com/macaron/macaron" -) - -const _VERSION = "0.1.4" - -func Version() string { - return _VERSION -} - -// Toolbox represents a tool box service for Macaron instance. -type Toolbox interface { - AddHealthCheck(HealthChecker) - AddHealthCheckFunc(string, HealthCheckFunc) - AddStatistics(string, string, time.Duration) - GetMap(io.Writer) - JSON(io.Writer) -} - -type toolbox struct { - *UrlMap - healthCheckJobs []*healthCheck -} - -// Options represents a struct for specifying configuration options for the Toolbox middleware. -type Options struct { - // URL prefix for toolbox dashboard. Default is "/debug". - URLPrefix string - // URL for health check request. Default is "/healthcheck". - HealthCheckURL string - // Health checkers. - HealthCheckers []HealthChecker - // Health check functions. - HealthCheckFuncs []*HealthCheckFuncDesc - // URL for URL map json. Default is "/urlmap.json". - URLMapPrefix string - // DisableDebug turns off all debug functionality. - DisableDebug bool - // URL prefix of pprof. Default is "/debug/pprof/". - PprofURLPrefix string - // URL prefix of profile. Default is "/debug/profile/". - ProfileURLPrefix string - // Path store profile files. Default is "profile". - ProfilePath string -} - -var opt Options - -func prepareOptions(options []Options) { - if len(options) > 0 { - opt = options[0] - } - - // Defaults. - if len(opt.URLPrefix) == 0 { - opt.URLPrefix = "/debug" - } - if len(opt.HealthCheckURL) == 0 { - opt.HealthCheckURL = "/healthcheck" - } - if len(opt.URLMapPrefix) == 0 { - opt.URLMapPrefix = "/urlmap.json" - } - if len(opt.PprofURLPrefix) == 0 { - opt.PprofURLPrefix = "/debug/pprof/" - } else if opt.PprofURLPrefix[len(opt.PprofURLPrefix)-1] != '/' { - opt.PprofURLPrefix += "/" - } - if len(opt.ProfileURLPrefix) == 0 { - opt.ProfileURLPrefix = "/debug/profile/" - } else if opt.ProfileURLPrefix[len(opt.ProfileURLPrefix)-1] != '/' { - opt.ProfileURLPrefix += "/" - } - if len(opt.ProfilePath) == 0 { - opt.ProfilePath = path.Join(macaron.Root, "profile") - } -} - -func dashboard() string { - return fmt.Sprintf(`

Toolbox Index:

-
    -
  1. Pprof Information
  2. -
  3. Profile Operations
  4. -
`, opt.PprofURLPrefix, opt.ProfileURLPrefix) -} - -var _ Toolbox = &toolbox{} - -// Toolboxer is a middleware provides health check, pprof, profile and statistic services for your application. -func Toolboxer(m *macaron.Macaron, options ...Options) macaron.Handler { - prepareOptions(options) - t := &toolbox{ - healthCheckJobs: make([]*healthCheck, 0, len(opt.HealthCheckers)+len(opt.HealthCheckFuncs)), - } - - // Dashboard. - m.Get(opt.URLPrefix, dashboard) - - // Health check. - for _, hc := range opt.HealthCheckers { - t.AddHealthCheck(hc) - } - for _, fd := range opt.HealthCheckFuncs { - t.AddHealthCheckFunc(fd.Desc, fd.Func) - } - m.Route(opt.HealthCheckURL, "HEAD,GET", t.handleHealthCheck) - - // URL map. - m.Get(opt.URLMapPrefix, func(rw http.ResponseWriter) { - t.JSON(rw) - }) - - if !opt.DisableDebug { - // Pprof - m.Any(path.Join(opt.PprofURLPrefix, "cmdline"), pprof.Cmdline) - m.Any(path.Join(opt.PprofURLPrefix, "profile"), pprof.Profile) - m.Any(path.Join(opt.PprofURLPrefix, "symbol"), pprof.Symbol) - m.Any(opt.PprofURLPrefix, pprof.Index) - m.Any(path.Join(opt.PprofURLPrefix, "*"), pprof.Index) - - // Profile - profilePath = opt.ProfilePath - m.Get(opt.ProfileURLPrefix, handleProfile) - } - - // Routes statistic. - t.UrlMap = &UrlMap{ - urlmap: make(map[string]map[string]*Statistics), - } - - return func(ctx *macaron.Context) { - ctx.MapTo(t, (*Toolbox)(nil)) - } -} diff --git a/vendor/github.com/NYTimes/gziphandler/.gitignore b/vendor/github.com/NYTimes/gziphandler/.gitignore new file mode 100644 index 0000000000000..1377554ebea6f --- /dev/null +++ b/vendor/github.com/NYTimes/gziphandler/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/vendor/github.com/NYTimes/gziphandler/.travis.yml b/vendor/github.com/NYTimes/gziphandler/.travis.yml new file mode 100644 index 0000000000000..94dfae362d3f5 --- /dev/null +++ b/vendor/github.com/NYTimes/gziphandler/.travis.yml @@ -0,0 +1,10 @@ +language: go +go: + - 1.x + - tip +env: + - GO111MODULE=on +install: + - go mod download +script: + - go test -race -v diff --git a/vendor/github.com/NYTimes/gziphandler/CODE_OF_CONDUCT.md b/vendor/github.com/NYTimes/gziphandler/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000000..cdbca194c3454 --- /dev/null +++ b/vendor/github.com/NYTimes/gziphandler/CODE_OF_CONDUCT.md @@ -0,0 +1,75 @@ +--- +layout: code-of-conduct +version: v1.0 +--- + +This code of conduct outlines our expectations for participants within the **NYTimes/gziphandler** community, as well as steps to reporting unacceptable behavior. We are committed to providing a welcoming and inspiring community for all and expect our code of conduct to be honored. Anyone who violates this code of conduct may be banned from the community. + +Our open source community strives to: + +* **Be friendly and patient.** +* **Be welcoming**: We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, colour, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability. +* **Be considerate**: Your work will be used by other people, and you in turn will depend on the work of others. Any decision you take will affect users and colleagues, and you should take those consequences into account when making decisions. Remember that we're a world-wide community, so you might not be communicating in someone else's primary language. +* **Be respectful**: Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It’s important to remember that a community where people feel uncomfortable or threatened is not a productive one. +* **Be careful in the words that we choose**: we are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. +* **Try to understand why we disagree**: Disagreements, both social and technical, happen all the time. It is important that we resolve disagreements and differing views constructively. Remember that we’re different. The strength of our community comes from its diversity, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn’t mean that they’re wrong. Don’t forget that it is human to err and blaming each other doesn’t get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes. + +## Definitions + +Harassment includes, but is not limited to: + +- Offensive comments related to gender, gender identity and expression, sexual orientation, disability, mental illness, neuro(a)typicality, physical appearance, body size, race, age, regional discrimination, political or religious affiliation +- Unwelcome comments regarding a person’s lifestyle choices and practices, including those related to food, health, parenting, drugs, and employment +- Deliberate misgendering. This includes deadnaming or persistently using a pronoun that does not correctly reflect a person's gender identity. You must address people by the name they give you when not addressing them by their username or handle +- Physical contact and simulated physical contact (eg, textual descriptions like “*hug*” or “*backrub*”) without consent or after a request to stop +- Threats of violence, both physical and psychological +- Incitement of violence towards any individual, including encouraging a person to commit suicide or to engage in self-harm +- Deliberate intimidation +- Stalking or following +- Harassing photography or recording, including logging online activity for harassment purposes +- Sustained disruption of discussion +- Unwelcome sexual attention, including gratuitous or off-topic sexual images or behaviour +- Pattern of inappropriate social contact, such as requesting/assuming inappropriate levels of intimacy with others +- Continued one-on-one communication after requests to cease +- Deliberate “outing” of any aspect of a person’s identity without their consent except as necessary to protect others from intentional abuse +- Publication of non-harassing private communication + +Our open source community prioritizes marginalized people’s safety over privileged people’s comfort. We will not act on complaints regarding: + +- ‘Reverse’ -isms, including ‘reverse racism,’ ‘reverse sexism,’ and ‘cisphobia’ +- Reasonable communication of boundaries, such as “leave me alone,” “go away,” or “I’m not discussing this with you” +- Refusal to explain or debate social justice concepts +- Communicating in a ‘tone’ you don’t find congenial +- Criticizing racist, sexist, cissexist, or otherwise oppressive behavior or assumptions + + +### Diversity Statement + +We encourage everyone to participate and are committed to building a community for all. Although we will fail at times, we seek to treat everyone both as fairly and equally as possible. Whenever a participant has made a mistake, we expect them to take responsibility for it. If someone has been harmed or offended, it is our responsibility to listen carefully and respectfully, and do our best to right the wrong. + +Although this list cannot be exhaustive, we explicitly honor diversity in age, gender, gender identity or expression, culture, ethnicity, language, national origin, political beliefs, profession, race, religion, sexual orientation, socioeconomic status, and technical ability. We will not tolerate discrimination based on any of the protected +characteristics above, including participants with disabilities. + +### Reporting Issues + +If you experience or witness unacceptable behavior—or have any other concerns—please report it by contacting us via **code@nytimes.com**. All reports will be handled with discretion. In your report please include: + +- Your contact information. +- Names (real, nicknames, or pseudonyms) of any individuals involved. If there are additional witnesses, please +include them as well. Your account of what occurred, and if you believe the incident is ongoing. If there is a publicly available record (e.g. a mailing list archive or a public IRC logger), please include a link. +- Any additional information that may be helpful. + +After filing a report, a representative will contact you personally, review the incident, follow up with any additional questions, and make a decision as to how to respond. If the person who is harassing you is part of the response team, they will recuse themselves from handling your incident. If the complaint originates from a member of the response team, it will be handled by a different member of the response team. We will respect confidentiality requests for the purpose of protecting victims of abuse. + +### Attribution & Acknowledgements + +We all stand on the shoulders of giants across many open source communities. We'd like to thank the communities and projects that established code of conducts and diversity statements as our inspiration: + +* [Django](https://www.djangoproject.com/conduct/reporting/) +* [Python](https://www.python.org/community/diversity/) +* [Ubuntu](http://www.ubuntu.com/about/about-ubuntu/conduct) +* [Contributor Covenant](http://contributor-covenant.org/) +* [Geek Feminism](http://geekfeminism.org/about/code-of-conduct/) +* [Citizen Code of Conduct](http://citizencodeofconduct.org/) + +This Code of Conduct was based on https://github.com/todogroup/opencodeofconduct diff --git a/vendor/github.com/NYTimes/gziphandler/CONTRIBUTING.md b/vendor/github.com/NYTimes/gziphandler/CONTRIBUTING.md new file mode 100644 index 0000000000000..b89a9eb4fb287 --- /dev/null +++ b/vendor/github.com/NYTimes/gziphandler/CONTRIBUTING.md @@ -0,0 +1,30 @@ +# Contributing to NYTimes/gziphandler + +This is an open source project started by handful of developers at The New York Times and open to the entire Go community. + +We really appreciate your help! + +## Filing issues + +When filing an issue, make sure to answer these five questions: + +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? + +## Contributing code + +Before submitting changes, please follow these guidelines: + +1. Check the open issues and pull requests for existing discussions. +2. Open an issue to discuss a new feature. +3. Write tests. +4. Make sure code follows the ['Go Code Review Comments'](https://github.com/golang/go/wiki/CodeReviewComments). +5. Make sure your changes pass `go test`. +6. Make sure the entire test suite passes locally and on Travis CI. +7. Open a Pull Request. +8. [Squash your commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) after receiving feedback and add a [great commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). + +Unless otherwise noted, the gziphandler source files are distributed under the Apache 2.0-style license found in the LICENSE.md file. diff --git a/vendor/gitea.com/macaron/cors/LICENSE b/vendor/github.com/NYTimes/gziphandler/LICENSE similarity index 99% rename from vendor/gitea.com/macaron/cors/LICENSE rename to vendor/github.com/NYTimes/gziphandler/LICENSE index 261eeb9e9f8b2..df6192d36f223 100644 --- a/vendor/gitea.com/macaron/cors/LICENSE +++ b/vendor/github.com/NYTimes/gziphandler/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2016-2017 The New York Times Company Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/NYTimes/gziphandler/README.md b/vendor/github.com/NYTimes/gziphandler/README.md new file mode 100644 index 0000000000000..6259acaca799d --- /dev/null +++ b/vendor/github.com/NYTimes/gziphandler/README.md @@ -0,0 +1,56 @@ +Gzip Handler +============ + +This is a tiny Go package which wraps HTTP handlers to transparently gzip the +response body, for clients which support it. Although it's usually simpler to +leave that to a reverse proxy (like nginx or Varnish), this package is useful +when that's undesirable. + +## Install +```bash +go get -u github.com/NYTimes/gziphandler +``` + +## Usage + +Call `GzipHandler` with any handler (an object which implements the +`http.Handler` interface), and it'll return a new handler which gzips the +response. For example: + +```go +package main + +import ( + "io" + "net/http" + "github.com/NYTimes/gziphandler" +) + +func main() { + withoutGz := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + io.WriteString(w, "Hello, World") + }) + + withGz := gziphandler.GzipHandler(withoutGz) + + http.Handle("/", withGz) + http.ListenAndServe("0.0.0.0:8000", nil) +} +``` + + +## Documentation + +The docs can be found at [godoc.org][docs], as usual. + + +## License + +[Apache 2.0][license]. + + + + +[docs]: https://godoc.org/github.com/NYTimes/gziphandler +[license]: https://github.com/NYTimes/gziphandler/blob/master/LICENSE diff --git a/vendor/github.com/NYTimes/gziphandler/go.mod b/vendor/github.com/NYTimes/gziphandler/go.mod new file mode 100644 index 0000000000000..8019012742499 --- /dev/null +++ b/vendor/github.com/NYTimes/gziphandler/go.mod @@ -0,0 +1,5 @@ +module github.com/NYTimes/gziphandler + +go 1.11 + +require github.com/stretchr/testify v1.3.0 diff --git a/vendor/github.com/NYTimes/gziphandler/go.sum b/vendor/github.com/NYTimes/gziphandler/go.sum new file mode 100644 index 0000000000000..4347755afe827 --- /dev/null +++ b/vendor/github.com/NYTimes/gziphandler/go.sum @@ -0,0 +1,7 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/vendor/github.com/NYTimes/gziphandler/gzip.go b/vendor/github.com/NYTimes/gziphandler/gzip.go new file mode 100644 index 0000000000000..c112bbdf81cec --- /dev/null +++ b/vendor/github.com/NYTimes/gziphandler/gzip.go @@ -0,0 +1,532 @@ +package gziphandler // import "github.com/NYTimes/gziphandler" + +import ( + "bufio" + "compress/gzip" + "fmt" + "io" + "mime" + "net" + "net/http" + "strconv" + "strings" + "sync" +) + +const ( + vary = "Vary" + acceptEncoding = "Accept-Encoding" + contentEncoding = "Content-Encoding" + contentType = "Content-Type" + contentLength = "Content-Length" +) + +type codings map[string]float64 + +const ( + // DefaultQValue is the default qvalue to assign to an encoding if no explicit qvalue is set. + // This is actually kind of ambiguous in RFC 2616, so hopefully it's correct. + // The examples seem to indicate that it is. + DefaultQValue = 1.0 + + // DefaultMinSize is the default minimum size until we enable gzip compression. + // 1500 bytes is the MTU size for the internet since that is the largest size allowed at the network layer. + // If you take a file that is 1300 bytes and compress it to 800 bytes, it’s still transmitted in that same 1500 byte packet regardless, so you’ve gained nothing. + // That being the case, you should restrict the gzip compression to files with a size greater than a single packet, 1400 bytes (1.4KB) is a safe value. + DefaultMinSize = 1400 +) + +// gzipWriterPools stores a sync.Pool for each compression level for reuse of +// gzip.Writers. Use poolIndex to covert a compression level to an index into +// gzipWriterPools. +var gzipWriterPools [gzip.BestCompression - gzip.BestSpeed + 2]*sync.Pool + +func init() { + for i := gzip.BestSpeed; i <= gzip.BestCompression; i++ { + addLevelPool(i) + } + addLevelPool(gzip.DefaultCompression) +} + +// poolIndex maps a compression level to its index into gzipWriterPools. It +// assumes that level is a valid gzip compression level. +func poolIndex(level int) int { + // gzip.DefaultCompression == -1, so we need to treat it special. + if level == gzip.DefaultCompression { + return gzip.BestCompression - gzip.BestSpeed + 1 + } + return level - gzip.BestSpeed +} + +func addLevelPool(level int) { + gzipWriterPools[poolIndex(level)] = &sync.Pool{ + New: func() interface{} { + // NewWriterLevel only returns error on a bad level, we are guaranteeing + // that this will be a valid level so it is okay to ignore the returned + // error. + w, _ := gzip.NewWriterLevel(nil, level) + return w + }, + } +} + +// GzipResponseWriter provides an http.ResponseWriter interface, which gzips +// bytes before writing them to the underlying response. This doesn't close the +// writers, so don't forget to do that. +// It can be configured to skip response smaller than minSize. +type GzipResponseWriter struct { + http.ResponseWriter + index int // Index for gzipWriterPools. + gw *gzip.Writer + + code int // Saves the WriteHeader value. + + minSize int // Specifed the minimum response size to gzip. If the response length is bigger than this value, it is compressed. + buf []byte // Holds the first part of the write before reaching the minSize or the end of the write. + ignore bool // If true, then we immediately passthru writes to the underlying ResponseWriter. + + contentTypes []parsedContentType // Only compress if the response is one of these content-types. All are accepted if empty. +} + +type GzipResponseWriterWithCloseNotify struct { + *GzipResponseWriter +} + +func (w GzipResponseWriterWithCloseNotify) CloseNotify() <-chan bool { + return w.ResponseWriter.(http.CloseNotifier).CloseNotify() +} + +// Write appends data to the gzip writer. +func (w *GzipResponseWriter) Write(b []byte) (int, error) { + // GZIP responseWriter is initialized. Use the GZIP responseWriter. + if w.gw != nil { + return w.gw.Write(b) + } + + // If we have already decided not to use GZIP, immediately passthrough. + if w.ignore { + return w.ResponseWriter.Write(b) + } + + // Save the write into a buffer for later use in GZIP responseWriter (if content is long enough) or at close with regular responseWriter. + // On the first write, w.buf changes from nil to a valid slice + w.buf = append(w.buf, b...) + + var ( + cl, _ = strconv.Atoi(w.Header().Get(contentLength)) + ct = w.Header().Get(contentType) + ce = w.Header().Get(contentEncoding) + ) + // Only continue if they didn't already choose an encoding or a known unhandled content length or type. + if ce == "" && (cl == 0 || cl >= w.minSize) && (ct == "" || handleContentType(w.contentTypes, ct)) { + // If the current buffer is less than minSize and a Content-Length isn't set, then wait until we have more data. + if len(w.buf) < w.minSize && cl == 0 { + return len(b), nil + } + // If the Content-Length is larger than minSize or the current buffer is larger than minSize, then continue. + if cl >= w.minSize || len(w.buf) >= w.minSize { + // If a Content-Type wasn't specified, infer it from the current buffer. + if ct == "" { + ct = http.DetectContentType(w.buf) + w.Header().Set(contentType, ct) + } + // If the Content-Type is acceptable to GZIP, initialize the GZIP writer. + if handleContentType(w.contentTypes, ct) { + if err := w.startGzip(); err != nil { + return 0, err + } + return len(b), nil + } + } + } + // If we got here, we should not GZIP this response. + if err := w.startPlain(); err != nil { + return 0, err + } + return len(b), nil +} + +// startGzip initializes a GZIP writer and writes the buffer. +func (w *GzipResponseWriter) startGzip() error { + // Set the GZIP header. + w.Header().Set(contentEncoding, "gzip") + + // if the Content-Length is already set, then calls to Write on gzip + // will fail to set the Content-Length header since its already set + // See: https://github.com/golang/go/issues/14975. + w.Header().Del(contentLength) + + // Write the header to gzip response. + if w.code != 0 { + w.ResponseWriter.WriteHeader(w.code) + // Ensure that no other WriteHeader's happen + w.code = 0 + } + + // Initialize and flush the buffer into the gzip response if there are any bytes. + // If there aren't any, we shouldn't initialize it yet because on Close it will + // write the gzip header even if nothing was ever written. + if len(w.buf) > 0 { + // Initialize the GZIP response. + w.init() + n, err := w.gw.Write(w.buf) + + // This should never happen (per io.Writer docs), but if the write didn't + // accept the entire buffer but returned no specific error, we have no clue + // what's going on, so abort just to be safe. + if err == nil && n < len(w.buf) { + err = io.ErrShortWrite + } + return err + } + return nil +} + +// startPlain writes to sent bytes and buffer the underlying ResponseWriter without gzip. +func (w *GzipResponseWriter) startPlain() error { + if w.code != 0 { + w.ResponseWriter.WriteHeader(w.code) + // Ensure that no other WriteHeader's happen + w.code = 0 + } + w.ignore = true + // If Write was never called then don't call Write on the underlying ResponseWriter. + if w.buf == nil { + return nil + } + n, err := w.ResponseWriter.Write(w.buf) + w.buf = nil + // This should never happen (per io.Writer docs), but if the write didn't + // accept the entire buffer but returned no specific error, we have no clue + // what's going on, so abort just to be safe. + if err == nil && n < len(w.buf) { + err = io.ErrShortWrite + } + return err +} + +// WriteHeader just saves the response code until close or GZIP effective writes. +func (w *GzipResponseWriter) WriteHeader(code int) { + if w.code == 0 { + w.code = code + } +} + +// init graps a new gzip writer from the gzipWriterPool and writes the correct +// content encoding header. +func (w *GzipResponseWriter) init() { + // Bytes written during ServeHTTP are redirected to this gzip writer + // before being written to the underlying response. + gzw := gzipWriterPools[w.index].Get().(*gzip.Writer) + gzw.Reset(w.ResponseWriter) + w.gw = gzw +} + +// Close will close the gzip.Writer and will put it back in the gzipWriterPool. +func (w *GzipResponseWriter) Close() error { + if w.ignore { + return nil + } + + if w.gw == nil { + // GZIP not triggered yet, write out regular response. + err := w.startPlain() + // Returns the error if any at write. + if err != nil { + err = fmt.Errorf("gziphandler: write to regular responseWriter at close gets error: %q", err.Error()) + } + return err + } + + err := w.gw.Close() + gzipWriterPools[w.index].Put(w.gw) + w.gw = nil + return err +} + +// Flush flushes the underlying *gzip.Writer and then the underlying +// http.ResponseWriter if it is an http.Flusher. This makes GzipResponseWriter +// an http.Flusher. +func (w *GzipResponseWriter) Flush() { + if w.gw == nil && !w.ignore { + // Only flush once startGzip or startPlain has been called. + // + // Flush is thus a no-op until we're certain whether a plain + // or gzipped response will be served. + return + } + + if w.gw != nil { + w.gw.Flush() + } + + if fw, ok := w.ResponseWriter.(http.Flusher); ok { + fw.Flush() + } +} + +// Hijack implements http.Hijacker. If the underlying ResponseWriter is a +// Hijacker, its Hijack method is returned. Otherwise an error is returned. +func (w *GzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if hj, ok := w.ResponseWriter.(http.Hijacker); ok { + return hj.Hijack() + } + return nil, nil, fmt.Errorf("http.Hijacker interface is not supported") +} + +// verify Hijacker interface implementation +var _ http.Hijacker = &GzipResponseWriter{} + +// MustNewGzipLevelHandler behaves just like NewGzipLevelHandler except that in +// an error case it panics rather than returning an error. +func MustNewGzipLevelHandler(level int) func(http.Handler) http.Handler { + wrap, err := NewGzipLevelHandler(level) + if err != nil { + panic(err) + } + return wrap +} + +// NewGzipLevelHandler returns a wrapper function (often known as middleware) +// which can be used to wrap an HTTP handler to transparently gzip the response +// body if the client supports it (via the Accept-Encoding header). Responses will +// be encoded at the given gzip compression level. An error will be returned only +// if an invalid gzip compression level is given, so if one can ensure the level +// is valid, the returned error can be safely ignored. +func NewGzipLevelHandler(level int) (func(http.Handler) http.Handler, error) { + return NewGzipLevelAndMinSize(level, DefaultMinSize) +} + +// NewGzipLevelAndMinSize behave as NewGzipLevelHandler except it let the caller +// specify the minimum size before compression. +func NewGzipLevelAndMinSize(level, minSize int) (func(http.Handler) http.Handler, error) { + return GzipHandlerWithOpts(CompressionLevel(level), MinSize(minSize)) +} + +func GzipHandlerWithOpts(opts ...option) (func(http.Handler) http.Handler, error) { + c := &config{ + level: gzip.DefaultCompression, + minSize: DefaultMinSize, + } + + for _, o := range opts { + o(c) + } + + if err := c.validate(); err != nil { + return nil, err + } + + return func(h http.Handler) http.Handler { + index := poolIndex(c.level) + + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add(vary, acceptEncoding) + if acceptsGzip(r) { + gw := &GzipResponseWriter{ + ResponseWriter: w, + index: index, + minSize: c.minSize, + contentTypes: c.contentTypes, + } + defer gw.Close() + + if _, ok := w.(http.CloseNotifier); ok { + gwcn := GzipResponseWriterWithCloseNotify{gw} + h.ServeHTTP(gwcn, r) + } else { + h.ServeHTTP(gw, r) + } + + } else { + h.ServeHTTP(w, r) + } + }) + }, nil +} + +// Parsed representation of one of the inputs to ContentTypes. +// See https://golang.org/pkg/mime/#ParseMediaType +type parsedContentType struct { + mediaType string + params map[string]string +} + +// equals returns whether this content type matches another content type. +func (pct parsedContentType) equals(mediaType string, params map[string]string) bool { + if pct.mediaType != mediaType { + return false + } + // if pct has no params, don't care about other's params + if len(pct.params) == 0 { + return true + } + + // if pct has any params, they must be identical to other's. + if len(pct.params) != len(params) { + return false + } + for k, v := range pct.params { + if w, ok := params[k]; !ok || v != w { + return false + } + } + return true +} + +// Used for functional configuration. +type config struct { + minSize int + level int + contentTypes []parsedContentType +} + +func (c *config) validate() error { + if c.level != gzip.DefaultCompression && (c.level < gzip.BestSpeed || c.level > gzip.BestCompression) { + return fmt.Errorf("invalid compression level requested: %d", c.level) + } + + if c.minSize < 0 { + return fmt.Errorf("minimum size must be more than zero") + } + + return nil +} + +type option func(c *config) + +func MinSize(size int) option { + return func(c *config) { + c.minSize = size + } +} + +func CompressionLevel(level int) option { + return func(c *config) { + c.level = level + } +} + +// ContentTypes specifies a list of content types to compare +// the Content-Type header to before compressing. If none +// match, the response will be returned as-is. +// +// Content types are compared in a case-insensitive, whitespace-ignored +// manner. +// +// A MIME type without any other directive will match a content type +// that has the same MIME type, regardless of that content type's other +// directives. I.e., "text/html" will match both "text/html" and +// "text/html; charset=utf-8". +// +// A MIME type with any other directive will only match a content type +// that has the same MIME type and other directives. I.e., +// "text/html; charset=utf-8" will only match "text/html; charset=utf-8". +// +// By default, responses are gzipped regardless of +// Content-Type. +func ContentTypes(types []string) option { + return func(c *config) { + c.contentTypes = []parsedContentType{} + for _, v := range types { + mediaType, params, err := mime.ParseMediaType(v) + if err == nil { + c.contentTypes = append(c.contentTypes, parsedContentType{mediaType, params}) + } + } + } +} + +// GzipHandler wraps an HTTP handler, to transparently gzip the response body if +// the client supports it (via the Accept-Encoding header). This will compress at +// the default compression level. +func GzipHandler(h http.Handler) http.Handler { + wrapper, _ := NewGzipLevelHandler(gzip.DefaultCompression) + return wrapper(h) +} + +// acceptsGzip returns true if the given HTTP request indicates that it will +// accept a gzipped response. +func acceptsGzip(r *http.Request) bool { + acceptedEncodings, _ := parseEncodings(r.Header.Get(acceptEncoding)) + return acceptedEncodings["gzip"] > 0.0 +} + +// returns true if we've been configured to compress the specific content type. +func handleContentType(contentTypes []parsedContentType, ct string) bool { + // If contentTypes is empty we handle all content types. + if len(contentTypes) == 0 { + return true + } + + mediaType, params, err := mime.ParseMediaType(ct) + if err != nil { + return false + } + + for _, c := range contentTypes { + if c.equals(mediaType, params) { + return true + } + } + + return false +} + +// parseEncodings attempts to parse a list of codings, per RFC 2616, as might +// appear in an Accept-Encoding header. It returns a map of content-codings to +// quality values, and an error containing the errors encountered. It's probably +// safe to ignore those, because silently ignoring errors is how the internet +// works. +// +// See: http://tools.ietf.org/html/rfc2616#section-14.3. +func parseEncodings(s string) (codings, error) { + c := make(codings) + var e []string + + for _, ss := range strings.Split(s, ",") { + coding, qvalue, err := parseCoding(ss) + + if err != nil { + e = append(e, err.Error()) + } else { + c[coding] = qvalue + } + } + + // TODO (adammck): Use a proper multi-error struct, so the individual errors + // can be extracted if anyone cares. + if len(e) > 0 { + return c, fmt.Errorf("errors while parsing encodings: %s", strings.Join(e, ", ")) + } + + return c, nil +} + +// parseCoding parses a single conding (content-coding with an optional qvalue), +// as might appear in an Accept-Encoding header. It attempts to forgive minor +// formatting errors. +func parseCoding(s string) (coding string, qvalue float64, err error) { + for n, part := range strings.Split(s, ";") { + part = strings.TrimSpace(part) + qvalue = DefaultQValue + + if n == 0 { + coding = strings.ToLower(part) + } else if strings.HasPrefix(part, "q=") { + qvalue, err = strconv.ParseFloat(strings.TrimPrefix(part, "q="), 64) + + if qvalue < 0.0 { + qvalue = 0.0 + } else if qvalue > 1.0 { + qvalue = 1.0 + } + } + } + + if coding == "" { + err = fmt.Errorf("empty content-coding") + } + + return +} diff --git a/vendor/github.com/NYTimes/gziphandler/gzip_go18.go b/vendor/github.com/NYTimes/gziphandler/gzip_go18.go new file mode 100644 index 0000000000000..fa9665b7e801a --- /dev/null +++ b/vendor/github.com/NYTimes/gziphandler/gzip_go18.go @@ -0,0 +1,43 @@ +// +build go1.8 + +package gziphandler + +import "net/http" + +// Push initiates an HTTP/2 server push. +// Push returns ErrNotSupported if the client has disabled push or if push +// is not supported on the underlying connection. +func (w *GzipResponseWriter) Push(target string, opts *http.PushOptions) error { + pusher, ok := w.ResponseWriter.(http.Pusher) + if ok && pusher != nil { + return pusher.Push(target, setAcceptEncodingForPushOptions(opts)) + } + return http.ErrNotSupported +} + +// setAcceptEncodingForPushOptions sets "Accept-Encoding" : "gzip" for PushOptions without overriding existing headers. +func setAcceptEncodingForPushOptions(opts *http.PushOptions) *http.PushOptions { + + if opts == nil { + opts = &http.PushOptions{ + Header: http.Header{ + acceptEncoding: []string{"gzip"}, + }, + } + return opts + } + + if opts.Header == nil { + opts.Header = http.Header{ + acceptEncoding: []string{"gzip"}, + } + return opts + } + + if encoding := opts.Header.Get(acceptEncoding); encoding == "" { + opts.Header.Add(acceptEncoding, "gzip") + return opts + } + + return opts +} diff --git a/vendor/github.com/go-chi/cors/LICENSE b/vendor/github.com/go-chi/cors/LICENSE new file mode 100644 index 0000000000000..aee6182f9ac7f --- /dev/null +++ b/vendor/github.com/go-chi/cors/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2014 Olivier Poitrey +Copyright (c) 2016-Present https://github.com/go-chi authors + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/go-chi/cors/README.md b/vendor/github.com/go-chi/cors/README.md new file mode 100644 index 0000000000000..1cd6b7f11e14f --- /dev/null +++ b/vendor/github.com/go-chi/cors/README.md @@ -0,0 +1,39 @@ +# CORS net/http middleware + +[go-chi/cors](https://github.com/go-chi/cors) is a fork of [github.com/rs/cors](https://github.com/rs/cors) that +provides a `net/http` compatible middleware for performing preflight CORS checks on the server side. These headers +are required for using the browser native [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). + +This middleware is designed to be used as a top-level middleware on the [chi](https://github.com/go-chi/chi) router. +Applying with within a `r.Group()` or using `With()` will not work without routes matching `OPTIONS` added. + +## Usage + +```go +func main() { + r := chi.NewRouter() + + // Basic CORS + // for more ideas, see: https://developer.github.com/v3/#cross-origin-resource-sharing + r.Use(cors.Handler(cors.Options{ + // AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts + AllowedOrigins: []string{"*"}, + // AllowOriginFunc: func(r *http.Request, origin string) bool { return true }, + AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, + AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"}, + ExposedHeaders: []string{"Link"}, + AllowCredentials: false, + MaxAge: 300, // Maximum value not ignored by any of major browsers + })) + + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("welcome")) + }) + + http.ListenAndServe(":3000", r) +} +``` + +## Credits + +All credit for the original work of this middleware goes out to [github.com/rs](github.com/rs). diff --git a/vendor/github.com/go-chi/cors/cors.go b/vendor/github.com/go-chi/cors/cors.go new file mode 100644 index 0000000000000..8df81636e3ba6 --- /dev/null +++ b/vendor/github.com/go-chi/cors/cors.go @@ -0,0 +1,400 @@ +// cors package is net/http handler to handle CORS related requests +// as defined by http://www.w3.org/TR/cors/ +// +// You can configure it by passing an option struct to cors.New: +// +// c := cors.New(cors.Options{ +// AllowedOrigins: []string{"foo.com"}, +// AllowedMethods: []string{"GET", "POST", "DELETE"}, +// AllowCredentials: true, +// }) +// +// Then insert the handler in the chain: +// +// handler = c.Handler(handler) +// +// See Options documentation for more options. +// +// The resulting handler is a standard net/http handler. +package cors + +import ( + "log" + "net/http" + "os" + "strconv" + "strings" +) + +// Options is a configuration container to setup the CORS middleware. +type Options struct { + // AllowedOrigins is a list of origins a cross-domain request can be executed from. + // If the special "*" value is present in the list, all origins will be allowed. + // An origin may contain a wildcard (*) to replace 0 or more characters + // (i.e.: http://*.domain.com). Usage of wildcards implies a small performance penalty. + // Only one wildcard can be used per origin. + // Default value is ["*"] + AllowedOrigins []string + + // AllowOriginFunc is a custom function to validate the origin. It takes the origin + // as argument and returns true if allowed or false otherwise. If this option is + // set, the content of AllowedOrigins is ignored. + AllowOriginFunc func(r *http.Request, origin string) bool + + // AllowedMethods is a list of methods the client is allowed to use with + // cross-domain requests. Default value is simple methods (HEAD, GET and POST). + AllowedMethods []string + + // AllowedHeaders is list of non simple headers the client is allowed to use with + // cross-domain requests. + // If the special "*" value is present in the list, all headers will be allowed. + // Default value is [] but "Origin" is always appended to the list. + AllowedHeaders []string + + // ExposedHeaders indicates which headers are safe to expose to the API of a CORS + // API specification + ExposedHeaders []string + + // AllowCredentials indicates whether the request can include user credentials like + // cookies, HTTP authentication or client side SSL certificates. + AllowCredentials bool + + // MaxAge indicates how long (in seconds) the results of a preflight request + // can be cached + MaxAge int + + // OptionsPassthrough instructs preflight to let other potential next handlers to + // process the OPTIONS method. Turn this on if your application handles OPTIONS. + OptionsPassthrough bool + + // Debugging flag adds additional output to debug server side CORS issues + Debug bool +} + +// Logger generic interface for logger +type Logger interface { + Printf(string, ...interface{}) +} + +// Cors http handler +type Cors struct { + // Debug logger + Log Logger + + // Normalized list of plain allowed origins + allowedOrigins []string + + // List of allowed origins containing wildcards + allowedWOrigins []wildcard + + // Optional origin validator function + allowOriginFunc func(r *http.Request, origin string) bool + + // Normalized list of allowed headers + allowedHeaders []string + + // Normalized list of allowed methods + allowedMethods []string + + // Normalized list of exposed headers + exposedHeaders []string + maxAge int + + // Set to true when allowed origins contains a "*" + allowedOriginsAll bool + + // Set to true when allowed headers contains a "*" + allowedHeadersAll bool + + allowCredentials bool + optionPassthrough bool +} + +// New creates a new Cors handler with the provided options. +func New(options Options) *Cors { + c := &Cors{ + exposedHeaders: convert(options.ExposedHeaders, http.CanonicalHeaderKey), + allowOriginFunc: options.AllowOriginFunc, + allowCredentials: options.AllowCredentials, + maxAge: options.MaxAge, + optionPassthrough: options.OptionsPassthrough, + } + if options.Debug && c.Log == nil { + c.Log = log.New(os.Stdout, "[cors] ", log.LstdFlags) + } + + // Normalize options + // Note: for origins and methods matching, the spec requires a case-sensitive matching. + // As it may error prone, we chose to ignore the spec here. + + // Allowed Origins + if len(options.AllowedOrigins) == 0 { + if options.AllowOriginFunc == nil { + // Default is all origins + c.allowedOriginsAll = true + } + } else { + c.allowedOrigins = []string{} + c.allowedWOrigins = []wildcard{} + for _, origin := range options.AllowedOrigins { + // Normalize + origin = strings.ToLower(origin) + if origin == "*" { + // If "*" is present in the list, turn the whole list into a match all + c.allowedOriginsAll = true + c.allowedOrigins = nil + c.allowedWOrigins = nil + break + } else if i := strings.IndexByte(origin, '*'); i >= 0 { + // Split the origin in two: start and end string without the * + w := wildcard{origin[0:i], origin[i+1:]} + c.allowedWOrigins = append(c.allowedWOrigins, w) + } else { + c.allowedOrigins = append(c.allowedOrigins, origin) + } + } + } + + // Allowed Headers + if len(options.AllowedHeaders) == 0 { + // Use sensible defaults + c.allowedHeaders = []string{"Origin", "Accept", "Content-Type"} + } else { + // Origin is always appended as some browsers will always request for this header at preflight + c.allowedHeaders = convert(append(options.AllowedHeaders, "Origin"), http.CanonicalHeaderKey) + for _, h := range options.AllowedHeaders { + if h == "*" { + c.allowedHeadersAll = true + c.allowedHeaders = nil + break + } + } + } + + // Allowed Methods + if len(options.AllowedMethods) == 0 { + // Default is spec's "simple" methods + c.allowedMethods = []string{http.MethodGet, http.MethodPost, http.MethodHead} + } else { + c.allowedMethods = convert(options.AllowedMethods, strings.ToUpper) + } + + return c +} + +// Handler creates a new Cors handler with passed options. +func Handler(options Options) func(next http.Handler) http.Handler { + c := New(options) + return c.Handler +} + +// AllowAll create a new Cors handler with permissive configuration allowing all +// origins with all standard methods with any header and credentials. +func AllowAll() *Cors { + return New(Options{ + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{ + http.MethodHead, + http.MethodGet, + http.MethodPost, + http.MethodPut, + http.MethodPatch, + http.MethodDelete, + }, + AllowedHeaders: []string{"*"}, + AllowCredentials: false, + }) +} + +// Handler apply the CORS specification on the request, and add relevant CORS headers +// as necessary. +func (c *Cors) Handler(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != "" { + c.logf("Handler: Preflight request") + c.handlePreflight(w, r) + // Preflight requests are standalone and should stop the chain as some other + // middleware may not handle OPTIONS requests correctly. One typical example + // is authentication middleware ; OPTIONS requests won't carry authentication + // headers (see #1) + if c.optionPassthrough { + next.ServeHTTP(w, r) + } else { + w.WriteHeader(http.StatusOK) + } + } else { + c.logf("Handler: Actual request") + c.handleActualRequest(w, r) + next.ServeHTTP(w, r) + } + }) +} + +// handlePreflight handles pre-flight CORS requests +func (c *Cors) handlePreflight(w http.ResponseWriter, r *http.Request) { + headers := w.Header() + origin := r.Header.Get("Origin") + + if r.Method != http.MethodOptions { + c.logf("Preflight aborted: %s!=OPTIONS", r.Method) + return + } + // Always set Vary headers + // see https://github.com/rs/cors/issues/10, + // https://github.com/rs/cors/commit/dbdca4d95feaa7511a46e6f1efb3b3aa505bc43f#commitcomment-12352001 + headers.Add("Vary", "Origin") + headers.Add("Vary", "Access-Control-Request-Method") + headers.Add("Vary", "Access-Control-Request-Headers") + + if origin == "" { + c.logf("Preflight aborted: empty origin") + return + } + if !c.isOriginAllowed(r, origin) { + c.logf("Preflight aborted: origin '%s' not allowed", origin) + return + } + + reqMethod := r.Header.Get("Access-Control-Request-Method") + if !c.isMethodAllowed(reqMethod) { + c.logf("Preflight aborted: method '%s' not allowed", reqMethod) + return + } + reqHeaders := parseHeaderList(r.Header.Get("Access-Control-Request-Headers")) + if !c.areHeadersAllowed(reqHeaders) { + c.logf("Preflight aborted: headers '%v' not allowed", reqHeaders) + return + } + if c.allowedOriginsAll { + headers.Set("Access-Control-Allow-Origin", "*") + } else { + headers.Set("Access-Control-Allow-Origin", origin) + } + // Spec says: Since the list of methods can be unbounded, simply returning the method indicated + // by Access-Control-Request-Method (if supported) can be enough + headers.Set("Access-Control-Allow-Methods", strings.ToUpper(reqMethod)) + if len(reqHeaders) > 0 { + + // Spec says: Since the list of headers can be unbounded, simply returning supported headers + // from Access-Control-Request-Headers can be enough + headers.Set("Access-Control-Allow-Headers", strings.Join(reqHeaders, ", ")) + } + if c.allowCredentials { + headers.Set("Access-Control-Allow-Credentials", "true") + } + if c.maxAge > 0 { + headers.Set("Access-Control-Max-Age", strconv.Itoa(c.maxAge)) + } + c.logf("Preflight response headers: %v", headers) +} + +// handleActualRequest handles simple cross-origin requests, actual request or redirects +func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) { + headers := w.Header() + origin := r.Header.Get("Origin") + + // Always set Vary, see https://github.com/rs/cors/issues/10 + headers.Add("Vary", "Origin") + if origin == "" { + c.logf("Actual request no headers added: missing origin") + return + } + if !c.isOriginAllowed(r, origin) { + c.logf("Actual request no headers added: origin '%s' not allowed", origin) + return + } + + // Note that spec does define a way to specifically disallow a simple method like GET or + // POST. Access-Control-Allow-Methods is only used for pre-flight requests and the + // spec doesn't instruct to check the allowed methods for simple cross-origin requests. + // We think it's a nice feature to be able to have control on those methods though. + if !c.isMethodAllowed(r.Method) { + c.logf("Actual request no headers added: method '%s' not allowed", r.Method) + + return + } + if c.allowedOriginsAll { + headers.Set("Access-Control-Allow-Origin", "*") + } else { + headers.Set("Access-Control-Allow-Origin", origin) + } + if len(c.exposedHeaders) > 0 { + headers.Set("Access-Control-Expose-Headers", strings.Join(c.exposedHeaders, ", ")) + } + if c.allowCredentials { + headers.Set("Access-Control-Allow-Credentials", "true") + } + c.logf("Actual response added headers: %v", headers) +} + +// convenience method. checks if a logger is set. +func (c *Cors) logf(format string, a ...interface{}) { + if c.Log != nil { + c.Log.Printf(format, a...) + } +} + +// isOriginAllowed checks if a given origin is allowed to perform cross-domain requests +// on the endpoint +func (c *Cors) isOriginAllowed(r *http.Request, origin string) bool { + if c.allowOriginFunc != nil { + return c.allowOriginFunc(r, origin) + } + if c.allowedOriginsAll { + return true + } + origin = strings.ToLower(origin) + for _, o := range c.allowedOrigins { + if o == origin { + return true + } + } + for _, w := range c.allowedWOrigins { + if w.match(origin) { + return true + } + } + return false +} + +// isMethodAllowed checks if a given method can be used as part of a cross-domain request +// on the endpoint +func (c *Cors) isMethodAllowed(method string) bool { + if len(c.allowedMethods) == 0 { + // If no method allowed, always return false, even for preflight request + return false + } + method = strings.ToUpper(method) + if method == http.MethodOptions { + // Always allow preflight requests + return true + } + for _, m := range c.allowedMethods { + if m == method { + return true + } + } + return false +} + +// areHeadersAllowed checks if a given list of headers are allowed to used within +// a cross-domain request. +func (c *Cors) areHeadersAllowed(requestedHeaders []string) bool { + if c.allowedHeadersAll || len(requestedHeaders) == 0 { + return true + } + for _, header := range requestedHeaders { + header = http.CanonicalHeaderKey(header) + found := false + for _, h := range c.allowedHeaders { + if h == header { + found = true + break + } + } + if !found { + return false + } + } + return true +} diff --git a/vendor/github.com/go-chi/cors/utils.go b/vendor/github.com/go-chi/cors/utils.go new file mode 100644 index 0000000000000..cd24831fcfccf --- /dev/null +++ b/vendor/github.com/go-chi/cors/utils.go @@ -0,0 +1,70 @@ +package cors + +import "strings" + +const toLower = 'a' - 'A' + +type converter func(string) string + +type wildcard struct { + prefix string + suffix string +} + +func (w wildcard) match(s string) bool { + return len(s) >= len(w.prefix+w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix) +} + +// convert converts a list of string using the passed converter function +func convert(s []string, c converter) []string { + out := []string{} + for _, i := range s { + out = append(out, c(i)) + } + return out +} + +// parseHeaderList tokenize + normalize a string containing a list of headers +func parseHeaderList(headerList string) []string { + l := len(headerList) + h := make([]byte, 0, l) + upper := true + // Estimate the number headers in order to allocate the right splice size + t := 0 + for i := 0; i < l; i++ { + if headerList[i] == ',' { + t++ + } + } + headers := make([]string, 0, t) + for i := 0; i < l; i++ { + b := headerList[i] + if b >= 'a' && b <= 'z' { + if upper { + h = append(h, b-toLower) + } else { + h = append(h, b) + } + } else if b >= 'A' && b <= 'Z' { + if !upper { + h = append(h, b+toLower) + } else { + h = append(h, b) + } + } else if b == '-' || (b >= '0' && b <= '9') { + h = append(h, b) + } + + if b == ' ' || b == ',' || i == l-1 { + if len(h) > 0 { + // Flush the found header + headers = append(headers, string(h)) + h = h[:0] + upper = true + } + } else { + upper = b == '-' + } + } + return headers +} diff --git a/vendor/github.com/siddontang/go-snappy/AUTHORS b/vendor/github.com/siddontang/go-snappy/AUTHORS deleted file mode 100644 index 8ddb5b7a2b9c8..0000000000000 --- a/vendor/github.com/siddontang/go-snappy/AUTHORS +++ /dev/null @@ -1,12 +0,0 @@ -# This is the official list of Snappy-Go authors for copyright purposes. -# This file is distinct from the CONTRIBUTORS files. -# See the latter for an explanation. - -# Names should be added to this file as -# Name or Organization -# The email address is not required for organizations. - -# Please keep the list sorted. - -Google Inc. -Jan Mercl <0xjnml@gmail.com> diff --git a/vendor/github.com/siddontang/go-snappy/CONTRIBUTORS b/vendor/github.com/siddontang/go-snappy/CONTRIBUTORS deleted file mode 100644 index 50b69c80ea9b3..0000000000000 --- a/vendor/github.com/siddontang/go-snappy/CONTRIBUTORS +++ /dev/null @@ -1,34 +0,0 @@ -# This is the official list of people who can contribute -# (and typically have contributed) code to the Snappy-Go repository. -# The AUTHORS file lists the copyright holders; this file -# lists people. For example, Google employees are listed here -# but not in AUTHORS, because Google holds the copyright. -# -# The submission process automatically checks to make sure -# that people submitting code are listed in this file (by email address). -# -# Names should be added to this file only after verifying that -# the individual or the individual's organization has agreed to -# the appropriate Contributor License Agreement, found here: -# -# http://code.google.com/legal/individual-cla-v1.0.html -# http://code.google.com/legal/corporate-cla-v1.0.html -# -# The agreement for individuals can be filled out on the web. -# -# When adding J Random Contributor's name to this file, -# either J's name or J's organization's name should be -# added to the AUTHORS file, depending on whether the -# individual or corporate CLA was used. - -# Names should be added to this file like so: -# Name - -# Please keep the list sorted. - -Jan Mercl <0xjnml@gmail.com> -Kai Backman -Marc-Antoine Ruel -Nigel Tao -Rob Pike -Russ Cox diff --git a/vendor/github.com/siddontang/go-snappy/LICENSE b/vendor/github.com/siddontang/go-snappy/LICENSE deleted file mode 100644 index 6050c10f4c8b4..0000000000000 --- a/vendor/github.com/siddontang/go-snappy/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/siddontang/go-snappy/snappy/decode.go b/vendor/github.com/siddontang/go-snappy/snappy/decode.go deleted file mode 100644 index d93c1b9dbfd7c..0000000000000 --- a/vendor/github.com/siddontang/go-snappy/snappy/decode.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2011 The Snappy-Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package snappy - -import ( - "encoding/binary" - "errors" -) - -// ErrCorrupt reports that the input is invalid. -var ErrCorrupt = errors.New("snappy: corrupt input") - -// DecodedLen returns the length of the decoded block. -func DecodedLen(src []byte) (int, error) { - v, _, err := decodedLen(src) - return v, err -} - -// decodedLen returns the length of the decoded block and the number of bytes -// that the length header occupied. -func decodedLen(src []byte) (blockLen, headerLen int, err error) { - v, n := binary.Uvarint(src) - if n == 0 { - return 0, 0, ErrCorrupt - } - if uint64(int(v)) != v { - return 0, 0, errors.New("snappy: decoded block is too large") - } - return int(v), n, nil -} - -// Decode returns the decoded form of src. The returned slice may be a sub- -// slice of dst if dst was large enough to hold the entire decoded block. -// Otherwise, a newly allocated slice will be returned. -// It is valid to pass a nil dst. -func Decode(dst, src []byte) ([]byte, error) { - dLen, s, err := decodedLen(src) - if err != nil { - return nil, err - } - if len(dst) < dLen { - dst = make([]byte, dLen) - } - - var d, offset, length int - for s < len(src) { - switch src[s] & 0x03 { - case tagLiteral: - x := uint(src[s] >> 2) - switch { - case x < 60: - s += 1 - case x == 60: - s += 2 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-1]) - case x == 61: - s += 3 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-2]) | uint(src[s-1])<<8 - case x == 62: - s += 4 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-3]) | uint(src[s-2])<<8 | uint(src[s-1])<<16 - case x == 63: - s += 5 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-4]) | uint(src[s-3])<<8 | uint(src[s-2])<<16 | uint(src[s-1])<<24 - } - length = int(x + 1) - if length <= 0 { - return nil, errors.New("snappy: unsupported literal length") - } - if length > len(dst)-d || length > len(src)-s { - return nil, ErrCorrupt - } - copy(dst[d:], src[s:s+length]) - d += length - s += length - continue - - case tagCopy1: - s += 2 - if s > len(src) { - return nil, ErrCorrupt - } - length = 4 + int(src[s-2])>>2&0x7 - offset = int(src[s-2])&0xe0<<3 | int(src[s-1]) - - case tagCopy2: - s += 3 - if s > len(src) { - return nil, ErrCorrupt - } - length = 1 + int(src[s-3])>>2 - offset = int(src[s-2]) | int(src[s-1])<<8 - - case tagCopy4: - return nil, errors.New("snappy: unsupported COPY_4 tag") - } - - end := d + length - if offset > d || end > len(dst) { - return nil, ErrCorrupt - } - for ; d < end; d++ { - dst[d] = dst[d-offset] - } - } - if d != dLen { - return nil, ErrCorrupt - } - return dst[:d], nil -} diff --git a/vendor/github.com/siddontang/go-snappy/snappy/encode.go b/vendor/github.com/siddontang/go-snappy/snappy/encode.go deleted file mode 100644 index b2371db11c8f0..0000000000000 --- a/vendor/github.com/siddontang/go-snappy/snappy/encode.go +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2011 The Snappy-Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package snappy - -import ( - "encoding/binary" -) - -// We limit how far copy back-references can go, the same as the C++ code. -const maxOffset = 1 << 15 - -// emitLiteral writes a literal chunk and returns the number of bytes written. -func emitLiteral(dst, lit []byte) int { - i, n := 0, uint(len(lit)-1) - switch { - case n < 60: - dst[0] = uint8(n)<<2 | tagLiteral - i = 1 - case n < 1<<8: - dst[0] = 60<<2 | tagLiteral - dst[1] = uint8(n) - i = 2 - case n < 1<<16: - dst[0] = 61<<2 | tagLiteral - dst[1] = uint8(n) - dst[2] = uint8(n >> 8) - i = 3 - case n < 1<<24: - dst[0] = 62<<2 | tagLiteral - dst[1] = uint8(n) - dst[2] = uint8(n >> 8) - dst[3] = uint8(n >> 16) - i = 4 - case int64(n) < 1<<32: - dst[0] = 63<<2 | tagLiteral - dst[1] = uint8(n) - dst[2] = uint8(n >> 8) - dst[3] = uint8(n >> 16) - dst[4] = uint8(n >> 24) - i = 5 - default: - panic("snappy: source buffer is too long") - } - if copy(dst[i:], lit) != len(lit) { - panic("snappy: destination buffer is too short") - } - return i + len(lit) -} - -// emitCopy writes a copy chunk and returns the number of bytes written. -func emitCopy(dst []byte, offset, length int) int { - i := 0 - for length > 0 { - x := length - 4 - if 0 <= x && x < 1<<3 && offset < 1<<11 { - dst[i+0] = uint8(offset>>8)&0x07<<5 | uint8(x)<<2 | tagCopy1 - dst[i+1] = uint8(offset) - i += 2 - break - } - - x = length - if x > 1<<6 { - x = 1 << 6 - } - dst[i+0] = uint8(x-1)<<2 | tagCopy2 - dst[i+1] = uint8(offset) - dst[i+2] = uint8(offset >> 8) - i += 3 - length -= x - } - return i -} - -// Encode returns the encoded form of src. The returned slice may be a sub- -// slice of dst if dst was large enough to hold the entire encoded block. -// Otherwise, a newly allocated slice will be returned. -// It is valid to pass a nil dst. -func Encode(dst, src []byte) ([]byte, error) { - if n := MaxEncodedLen(len(src)); len(dst) < n { - dst = make([]byte, n) - } - - // The block starts with the varint-encoded length of the decompressed bytes. - d := binary.PutUvarint(dst, uint64(len(src))) - - // Return early if src is short. - if len(src) <= 4 { - if len(src) != 0 { - d += emitLiteral(dst[d:], src) - } - return dst[:d], nil - } - - // Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive. - const maxTableSize = 1 << 14 - shift, tableSize := uint(32-8), 1<<8 - for tableSize < maxTableSize && tableSize < len(src) { - shift-- - tableSize *= 2 - } - var table [maxTableSize]int - - // Iterate over the source bytes. - var ( - s int // The iterator position. - t int // The last position with the same hash as s. - lit int // The start position of any pending literal bytes. - ) - for s+3 < len(src) { - // Update the hash table. - b0, b1, b2, b3 := src[s], src[s+1], src[s+2], src[s+3] - h := uint32(b0) | uint32(b1)<<8 | uint32(b2)<<16 | uint32(b3)<<24 - p := &table[(h*0x1e35a7bd)>>shift] - // We need to to store values in [-1, inf) in table. To save - // some initialization time, (re)use the table's zero value - // and shift the values against this zero: add 1 on writes, - // subtract 1 on reads. - t, *p = *p-1, s+1 - // If t is invalid or src[s:s+4] differs from src[t:t+4], accumulate a literal byte. - if t < 0 || s-t >= maxOffset || b0 != src[t] || b1 != src[t+1] || b2 != src[t+2] || b3 != src[t+3] { - s++ - continue - } - // Otherwise, we have a match. First, emit any pending literal bytes. - if lit != s { - d += emitLiteral(dst[d:], src[lit:s]) - } - // Extend the match to be as long as possible. - s0 := s - s, t = s+4, t+4 - for s < len(src) && src[s] == src[t] { - s++ - t++ - } - // Emit the copied bytes. - d += emitCopy(dst[d:], s-t, s-s0) - lit = s - } - - // Emit any final pending literal bytes and return. - if lit != len(src) { - d += emitLiteral(dst[d:], src[lit:]) - } - return dst[:d], nil -} - -// MaxEncodedLen returns the maximum length of a snappy block, given its -// uncompressed length. -func MaxEncodedLen(srcLen int) int { - // Compressed data can be defined as: - // compressed := item* literal* - // item := literal* copy - // - // The trailing literal sequence has a space blowup of at most 62/60 - // since a literal of length 60 needs one tag byte + one extra byte - // for length information. - // - // Item blowup is trickier to measure. Suppose the "copy" op copies - // 4 bytes of data. Because of a special check in the encoding code, - // we produce a 4-byte copy only if the offset is < 65536. Therefore - // the copy op takes 3 bytes to encode, and this type of item leads - // to at most the 62/60 blowup for representing literals. - // - // Suppose the "copy" op copies 5 bytes of data. If the offset is big - // enough, it will take 5 bytes to encode the copy op. Therefore the - // worst case here is a one-byte literal followed by a five-byte copy. - // That is, 6 bytes of input turn into 7 bytes of "compressed" data. - // - // This last factor dominates the blowup, so the final estimate is: - return 32 + srcLen + srcLen/6 -} diff --git a/vendor/github.com/siddontang/go-snappy/snappy/snappy.go b/vendor/github.com/siddontang/go-snappy/snappy/snappy.go deleted file mode 100644 index 2f1b790d0b717..0000000000000 --- a/vendor/github.com/siddontang/go-snappy/snappy/snappy.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2011 The Snappy-Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package snappy implements the snappy block-based compression format. -// It aims for very high speeds and reasonable compression. -// -// The C++ snappy implementation is at http://code.google.com/p/snappy/ -package snappy - -/* -Each encoded block begins with the varint-encoded length of the decoded data, -followed by a sequence of chunks. Chunks begin and end on byte boundaries. The -first byte of each chunk is broken into its 2 least and 6 most significant bits -called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag. -Zero means a literal tag. All other values mean a copy tag. - -For literal tags: - - If m < 60, the next 1 + m bytes are literal bytes. - - Otherwise, let n be the little-endian unsigned integer denoted by the next - m - 59 bytes. The next 1 + n bytes after that are literal bytes. - -For copy tags, length bytes are copied from offset bytes ago, in the style of -Lempel-Ziv compression algorithms. In particular: - - For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12). - The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10 - of the offset. The next byte is bits 0-7 of the offset. - - For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65). - The length is 1 + m. The offset is the little-endian unsigned integer - denoted by the next 2 bytes. - - For l == 3, this tag is a legacy format that is no longer supported. -*/ -const ( - tagLiteral = 0x00 - tagCopy1 = 0x01 - tagCopy2 = 0x02 - tagCopy4 = 0x03 -) diff --git a/vendor/modules.txt b/vendor/modules.txt index 50a603d4b23b2..618e397f40ca3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -7,6 +7,16 @@ code.gitea.io/gitea-vet/checks # code.gitea.io/sdk/gitea v0.13.1 ## explicit code.gitea.io/sdk/gitea +# gitea.com/go-chi/binding v0.0.0-20210113025129-03f1d313373c +## explicit +gitea.com/go-chi/binding +# gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e +## explicit +gitea.com/go-chi/cache +gitea.com/go-chi/cache/memcache +# gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e +## explicit +gitea.com/go-chi/captcha # gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee ## explicit gitea.com/go-chi/session @@ -17,55 +27,11 @@ gitea.com/go-chi/session/postgres # gitea.com/lunny/levelqueue v0.3.0 ## explicit gitea.com/lunny/levelqueue -# gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e -gitea.com/lunny/log -# gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727 -gitea.com/lunny/nodb -gitea.com/lunny/nodb/config -gitea.com/lunny/nodb/store -gitea.com/lunny/nodb/store/driver -gitea.com/lunny/nodb/store/goleveldb -# gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b -## explicit -gitea.com/macaron/binding -# gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b -## explicit -gitea.com/macaron/cache -gitea.com/macaron/cache/memcache -# gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca -## explicit -gitea.com/macaron/captcha -# gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4 -## explicit -gitea.com/macaron/cors -# gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439 -## explicit -gitea.com/macaron/csrf -# gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5 -## explicit -gitea.com/macaron/gzip -# gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60 -## explicit -gitea.com/macaron/i18n -# gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a -## explicit -gitea.com/macaron/inject -# gitea.com/macaron/macaron v1.5.1-0.20201027213641-0db5d4584804 -## explicit -gitea.com/macaron/macaron -# gitea.com/macaron/session v0.0.0-20201103015045-a177a2701dee -## explicit -gitea.com/macaron/session -gitea.com/macaron/session/couchbase -gitea.com/macaron/session/memcache -gitea.com/macaron/session/mysql -gitea.com/macaron/session/nodb -gitea.com/macaron/session/postgres -# gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7 -## explicit -gitea.com/macaron/toolbox # github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c github.com/Azure/go-ntlmssp +# github.com/NYTimes/gziphandler v1.1.1 +## explicit +github.com/NYTimes/gziphandler # github.com/PuerkitoBio/goquery v1.5.1 ## explicit github.com/PuerkitoBio/goquery @@ -274,6 +240,9 @@ github.com/go-asn1-ber/asn1-ber ## explicit github.com/go-chi/chi github.com/go-chi/chi/middleware +# github.com/go-chi/cors v1.1.1 +## explicit +github.com/go-chi/cors # github.com/go-enry/go-enry/v2 v2.6.0 ## explicit github.com/go-enry/go-enry/v2 @@ -709,8 +678,6 @@ github.com/shurcooL/sanitized_anchor_name # github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 ## explicit github.com/shurcooL/vfsgen -# github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d -github.com/siddontang/go-snappy/snappy # github.com/spf13/afero v1.3.2 github.com/spf13/afero github.com/spf13/afero/mem From afbddf1f0e93cf8b38a7244dfd434b448c81037d Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Tue, 26 Jan 2021 15:38:19 +0000 Subject: [PATCH 04/24] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 8e48626327c34..17089acfe2292 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -15,6 +15,7 @@ page=ページ template=テンプレート language=言語 notifications=通知 +active_stopwatch=進行中のタイムトラッカー create_new=作成… user_profile_and_more=プロフィールと設定… signed_in_as=サインイン済み @@ -1070,6 +1071,7 @@ issues.commented_at=`が %s にコメント` issues.delete_comment_confirm=このコメントを削除してよろしいですか? issues.context.copy_link=リンクをコピー issues.context.quote_reply=引用して返信 +issues.context.reference_issue=新しい課題から参照 issues.context.edit=編集 issues.context.delete=削除 issues.no_content=まだ内容がありません From 0f726caf97e4b682172f23fb46d3992f60ed6ed2 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 27 Jan 2021 02:04:20 +0800 Subject: [PATCH 05/24] Fix panic 500 page rendering (#14474) --- routers/routes/web.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/routers/routes/web.go b/routers/routes/web.go index 24336185817f0..6b6322f048fc7 100644 --- a/routers/routes/web.go +++ b/routers/routes/web.go @@ -101,7 +101,6 @@ func NormalRoutes() *web.Route { for _, middle := range commonMiddlewares() { r.Use(middle) } - r.Use(Recovery()) r.Mount("/", WebRoutes()) r.Mount("/api/v1", apiv1.Routes()) @@ -124,6 +123,8 @@ func WebRoutes() *web.Route { Domain: setting.SessionConfig.Domain, })) + r.Use(Recovery()) + r.Use(public.Custom( &public.Options{ SkipLogging: setting.DisableRouterLog, From a598877fdf64a37b20eb1bf4372cbe798fc94486 Mon Sep 17 00:00:00 2001 From: Brad Albright <32200834+bhalbright@users.noreply.github.com> Date: Tue, 26 Jan 2021 15:02:42 -0600 Subject: [PATCH 06/24] Cron job to cleanup hook_task table (#13080) Close **Prune hook_task Table (#10741)** Added a cron job to delete webhook deliveries in the hook_task table. It can be turned on/off and the schedule controlled globally via app.ini. The data can be deleted by either the age of the delivery which is the default or by deleting the all but the most recent deliveries _per webhook_. Note: I had previously submitted pr #11416 but I closed it when I realized that I had deleted per repository instead of per webhook. Also, I decided allowing the settings to be overridden via the ui was overkill. Also this version allows the deletion by age which is probably what most people would want. --- custom/conf/app.example.ini | 15 +++ .../doc/advanced/config-cheat-sheet.en-us.md | 9 ++ models/webhook.go | 87 +++++++++++++ models/webhook_test.go | 114 ++++++++++++++++++ modules/cron/setting.go | 8 ++ modules/cron/tasks_basic.go | 17 +++ options/locale/locale_en-US.ini | 1 + 7 files changed, 251 insertions(+) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index f2b65a0963db6..8bc4a2c20475c 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1023,6 +1023,21 @@ SCHEDULE = @every 24h ; deleted branches than OLDER_THAN ago are subject to deletion OLDER_THAN = 24h +; Cleanup hook_task table +[cron.cleanup_hook_task_table] +; Whether to enable the job +ENABLED = true +; Whether to always run at start up time (if ENABLED) +RUN_AT_START = false +; Time interval for job to run +SCHEDULE = @every 24h +; OlderThan or PerWebhook. How the records are removed, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook). +CLEANUP_TYPE = OlderThan +; If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted. +OLDER_THAN = 168h +; If CLEANUP_TYPE is set to PerWebhook, this is number of hook_task records to keep for a webhook (i.e. keep the most recent x deliveries). +NUMBER_TO_KEEP = 10 + ; Extended cron task - not enabled by default ; Delete all unactivated accounts diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index e8866ab333d6c..1d9326ad6ea78 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -694,6 +694,15 @@ NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false` - `RUN_AT_START`: **true**: Run repository statistics check at start time. - `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository statistics check. +### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`) + +- `ENABLED`: **true**: Enable cleanup hook_task job. +- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED). +- `SCHEDULE`: **@every 24h**: Cron syntax for cleaning hook_task table. +- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook). +- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted. +- `NUMBER_TO_KEEP`: **10**: If CLEANUP_TYPE is set to PerWebhook, this is number of hook_task records to keep for a webhook (i.e. keep the most recent x deliveries). + #### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`) - `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts. diff --git a/models/webhook.go b/models/webhook.go index 5174bb6128c82..c7fcfba49e782 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -6,6 +6,7 @@ package models import ( + "context" "encoding/json" "fmt" "strings" @@ -39,6 +40,26 @@ func ToHookContentType(name string) HookContentType { return hookContentTypes[name] } +// HookTaskCleanupType is the type of cleanup to perform on hook_task +type HookTaskCleanupType int + +const ( + // OlderThan hook_task rows will be cleaned up by the age of the row + OlderThan HookTaskCleanupType = iota + // PerWebhook hook_task rows will be cleaned up by leaving the most recent deliveries for each webhook + PerWebhook +) + +var hookTaskCleanupTypes = map[string]HookTaskCleanupType{ + "OlderThan": OlderThan, + "PerWebhook": PerWebhook, +} + +// ToHookTaskCleanupType returns HookTaskCleanupType by given name. +func ToHookTaskCleanupType(name string) HookTaskCleanupType { + return hookTaskCleanupTypes[name] +} + // Name returns the name of a given web hook's content type func (t HookContentType) Name() string { switch t { @@ -738,3 +759,69 @@ func FindRepoUndeliveredHookTasks(repoID int64) ([]*HookTask, error) { } return tasks, nil } + +// CleanupHookTaskTable deletes rows from hook_task as needed. +func CleanupHookTaskTable(ctx context.Context, cleanupType HookTaskCleanupType, olderThan time.Duration, numberToKeep int) error { + log.Trace("Doing: CleanupHookTaskTable") + + if cleanupType == OlderThan { + deleteOlderThan := time.Now().Add(-olderThan).UnixNano() + deletes, err := x. + Where("is_delivered = ? and delivered < ?", true, deleteOlderThan). + Delete(new(HookTask)) + if err != nil { + return err + } + log.Trace("Deleted %d rows from hook_task", deletes) + } else if cleanupType == PerWebhook { + hookIDs := make([]int64, 0, 10) + err := x.Table("webhook"). + Where("id > 0"). + Cols("id"). + Find(&hookIDs) + if err != nil { + return err + } + for _, hookID := range hookIDs { + select { + case <-ctx.Done(): + return ErrCancelledf("Before deleting hook_task records for hook id %d", hookID) + default: + } + if err = deleteDeliveredHookTasksByWebhook(hookID, numberToKeep); err != nil { + return err + } + } + } + log.Trace("Finished: CleanupHookTaskTable") + return nil +} + +func deleteDeliveredHookTasksByWebhook(hookID int64, numberDeliveriesToKeep int) error { + log.Trace("Deleting hook_task rows for webhook %d, keeping the most recent %d deliveries", hookID, numberDeliveriesToKeep) + var deliveryDates = make([]int64, 0, 10) + err := x.Table("hook_task"). + Where("hook_task.hook_id = ? AND hook_task.is_delivered = ? AND hook_task.delivered is not null", hookID, true). + Cols("hook_task.delivered"). + Join("INNER", "webhook", "hook_task.hook_id = webhook.id"). + OrderBy("hook_task.delivered desc"). + Limit(1, int(numberDeliveriesToKeep)). + Find(&deliveryDates) + if err != nil { + return err + } + + if len(deliveryDates) > 0 { + deletes, err := x. + Where("hook_id = ? and is_delivered = ? and delivered <= ?", hookID, true, deliveryDates[0]). + Delete(new(HookTask)) + if err != nil { + return err + } + log.Trace("Deleted %d hook_task rows for webhook %d", deletes, hookID) + } else { + log.Trace("No hook_task rows to delete for webhook %d", hookID) + } + + return nil +} diff --git a/models/webhook_test.go b/models/webhook_test.go index 20acb4e93c0a2..1baf6ef44bfa5 100644 --- a/models/webhook_test.go +++ b/models/webhook_test.go @@ -5,8 +5,10 @@ package models import ( + "context" "encoding/json" "testing" + "time" api "code.gitea.io/gitea/modules/structs" @@ -223,3 +225,115 @@ func TestUpdateHookTask(t *testing.T) { assert.NoError(t, UpdateHookTask(hook)) AssertExistsAndLoadBean(t, hook) } + +func TestCleanupHookTaskTable_PerWebhook_DeletesDelivered(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + hookTask := &HookTask{ + RepoID: 3, + HookID: 3, + Typ: GITEA, + URL: "http://www.example.com/unit_test", + Payloader: &api.PushPayload{}, + IsDelivered: true, + Delivered: time.Now().UnixNano(), + } + AssertNotExistsBean(t, hookTask) + assert.NoError(t, CreateHookTask(hookTask)) + AssertExistsAndLoadBean(t, hookTask) + + assert.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 0)) + AssertNotExistsBean(t, hookTask) +} + +func TestCleanupHookTaskTable_PerWebhook_LeavesUndelivered(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + hookTask := &HookTask{ + RepoID: 2, + HookID: 4, + Typ: GITEA, + URL: "http://www.example.com/unit_test", + Payloader: &api.PushPayload{}, + IsDelivered: false, + } + AssertNotExistsBean(t, hookTask) + assert.NoError(t, CreateHookTask(hookTask)) + AssertExistsAndLoadBean(t, hookTask) + + assert.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 0)) + AssertExistsAndLoadBean(t, hookTask) +} + +func TestCleanupHookTaskTable_PerWebhook_LeavesMostRecentTask(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + hookTask := &HookTask{ + RepoID: 2, + HookID: 4, + Typ: GITEA, + URL: "http://www.example.com/unit_test", + Payloader: &api.PushPayload{}, + IsDelivered: true, + Delivered: time.Now().UnixNano(), + } + AssertNotExistsBean(t, hookTask) + assert.NoError(t, CreateHookTask(hookTask)) + AssertExistsAndLoadBean(t, hookTask) + + assert.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 1)) + AssertExistsAndLoadBean(t, hookTask) +} + +func TestCleanupHookTaskTable_OlderThan_DeletesDelivered(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + hookTask := &HookTask{ + RepoID: 3, + HookID: 3, + Typ: GITEA, + URL: "http://www.example.com/unit_test", + Payloader: &api.PushPayload{}, + IsDelivered: true, + Delivered: time.Now().AddDate(0, 0, -8).UnixNano(), + } + AssertNotExistsBean(t, hookTask) + assert.NoError(t, CreateHookTask(hookTask)) + AssertExistsAndLoadBean(t, hookTask) + + assert.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0)) + AssertNotExistsBean(t, hookTask) +} + +func TestCleanupHookTaskTable_OlderThan_LeavesUndelivered(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + hookTask := &HookTask{ + RepoID: 2, + HookID: 4, + Typ: GITEA, + URL: "http://www.example.com/unit_test", + Payloader: &api.PushPayload{}, + IsDelivered: false, + } + AssertNotExistsBean(t, hookTask) + assert.NoError(t, CreateHookTask(hookTask)) + AssertExistsAndLoadBean(t, hookTask) + + assert.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0)) + AssertExistsAndLoadBean(t, hookTask) +} + +func TestCleanupHookTaskTable_OlderThan_LeavesTaskEarlierThanAgeToDelete(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + hookTask := &HookTask{ + RepoID: 2, + HookID: 4, + Typ: GITEA, + URL: "http://www.example.com/unit_test", + Payloader: &api.PushPayload{}, + IsDelivered: true, + Delivered: time.Now().AddDate(0, 0, -6).UnixNano(), + } + AssertNotExistsBean(t, hookTask) + assert.NoError(t, CreateHookTask(hookTask)) + AssertExistsAndLoadBean(t, hookTask) + + assert.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0)) + AssertExistsAndLoadBean(t, hookTask) +} diff --git a/modules/cron/setting.go b/modules/cron/setting.go index 5fe9ca6e14d82..d55e5b60ad69e 100644 --- a/modules/cron/setting.go +++ b/modules/cron/setting.go @@ -40,6 +40,14 @@ type UpdateExistingConfig struct { UpdateExisting bool } +// CleanupHookTaskConfig represents a cron task with settings to cleanup hook_task +type CleanupHookTaskConfig struct { + BaseConfig + CleanupType string + OlderThan time.Duration + NumberToKeep int +} + // GetSchedule returns the schedule for the base config func (b *BaseConfig) GetSchedule() string { return b.Schedule diff --git a/modules/cron/tasks_basic.go b/modules/cron/tasks_basic.go index a45704e889394..391cda0f891f5 100644 --- a/modules/cron/tasks_basic.go +++ b/modules/cron/tasks_basic.go @@ -109,6 +109,22 @@ func registerUpdateMigrationPosterID() { }) } +func registerCleanupHookTaskTable() { + RegisterTaskFatal("cleanup_hook_task_table", &CleanupHookTaskConfig{ + BaseConfig: BaseConfig{ + Enabled: true, + RunAtStart: false, + Schedule: "@every 24h", + }, + CleanupType: "OlderThan", + OlderThan: 168 * time.Hour, + NumberToKeep: 10, + }, func(ctx context.Context, _ *models.User, config Config) error { + realConfig := config.(*CleanupHookTaskConfig) + return models.CleanupHookTaskTable(ctx, models.ToHookTaskCleanupType(realConfig.CleanupType), realConfig.OlderThan, realConfig.NumberToKeep) + }) +} + func initBasicTasks() { registerUpdateMirrorTask() registerRepoHealthCheck() @@ -119,4 +135,5 @@ func initBasicTasks() { if !setting.Repository.DisableMigrations { registerUpdateMigrationPosterID() } + registerCleanupHookTaskTable() } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 6c9604bf8babb..1fe43ce29bbf1 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2065,6 +2065,7 @@ dashboard.resync_all_sshprincipals.desc = (Not needed for the built-in SSH serve dashboard.resync_all_hooks = Resynchronize pre-receive, update and post-receive hooks of all repositories. dashboard.reinit_missing_repos = Reinitialize all missing Git repositories for which records exist dashboard.sync_external_users = Synchronize external user data +dashboard.cleanup_hook_task_table = Cleanup hook_task table dashboard.server_uptime = Server Uptime dashboard.current_goroutine = Current Goroutines dashboard.current_memory_usage = Current Memory Usage From d3aa4971c7beadc6c573464ef4359775d2844dab Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 27 Jan 2021 06:47:42 +0800 Subject: [PATCH 07/24] Fix bug because of duplicated join (#14454) * Fix bug because of duplicated join * Move join into setupsession * Fix bug * Fix bug Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lauris BH --- models/issue.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/models/issue.go b/models/issue.go index 1374f82fbd860..a7392633af51f 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1210,7 +1210,7 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) { } if opts.IsArchived != util.OptionalBoolNone { - sess.Join("INNER", "repository", "issue.repo_id = repository.id").And(builder.Eq{"repository.is_archived": opts.IsArchived.IsTrue()}) + sess.And(builder.Eq{"repository.is_archived": opts.IsArchived.IsTrue()}) } if opts.LabelIDs != nil { @@ -1266,6 +1266,8 @@ func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) { sess := x.NewSession() defer sess.Close() + sess.Join("INNER", "repository", "`issue`.repo_id = `repository`.id") + opts.setupSession(sess) countsSlice := make([]*struct { @@ -1292,11 +1294,12 @@ func GetRepoIDsForIssuesOptions(opts *IssuesOptions, user *User) ([]int64, error sess := x.NewSession() defer sess.Close() + sess.Join("INNER", "repository", "`issue`.repo_id = `repository`.id") + opts.setupSession(sess) accessCond := accessibleRepositoryCondition(user) if err := sess.Where(accessCond). - Join("INNER", "repository", "`issue`.repo_id = `repository`.id"). Distinct("issue.repo_id"). Table("issue"). Find(&repoIDs); err != nil { @@ -1311,6 +1314,7 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) { sess := x.NewSession() defer sess.Close() + sess.Join("INNER", "repository", "`issue`.repo_id = `repository`.id") opts.setupSession(sess) sortIssuesSession(sess, opts.SortType, opts.PriorityRepoID) @@ -1338,6 +1342,7 @@ func CountIssues(opts *IssuesOptions) (int64, error) { }, 0, 1) sess.Select("COUNT(issue.id) AS count").Table("issue") + sess.Join("INNER", "repository", "`issue`.repo_id = `repository`.id") opts.setupSession(sess) if err := sess.Find(&countsSlice); err != nil { return 0, fmt.Errorf("Find: %v", err) From 5845c87b314d05573f68d0c010f3d5bd2595dcdb Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Tue, 26 Jan 2021 22:48:54 +0000 Subject: [PATCH 08/24] [skip ci] Updated translations via Crowdin --- options/locale/locale_de-DE.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 76433e6daafe0..fa850029a5856 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -449,6 +449,7 @@ update_language_not_found=Sprache '%s' ist nicht verfügbar. update_profile_success=Dein Profil wurde aktualisiert. change_username=Dein Benutzername wurde geändert. change_username_prompt=Hinweis: Wenn du deinen Benutzernamen änderst, wird auch deine Konto-URL geändert. +change_username_redirect_prompt=Der alte Benutzername wird auf den neuen Benutzernamen weiterleiten, bis er erneut als Benutzername verwendet wird. continue=Weiter cancel=Abbrechen language=Sprache @@ -776,6 +777,7 @@ migrate.github.description=Migriere Daten von Github.com oder Github Enterprise. migrate.git.description=Migriere oder spiegele git-Daten von Git-Services migrate.gitlab.description=Migriere Daten von GitLab.com oder einem selbst gehostetem gitlab Server. migrate.gitea.description=Migriere Daten von Gitea.com oder einem selbst gehostetem Gitea Server. +migrate.gogs.description=Migriere Daten von notabug.org oder einem anderen, selbst gehosteten Gogs Server. mirror_from=Mirror von forked_from=geforkt von @@ -1938,6 +1940,7 @@ settings.visibility.private_shortname=Privat settings.update_settings=Einstellungen speichern settings.update_setting_success=Organisationseinstellungen wurden aktualisiert. settings.change_orgname_prompt=Hinweis: Die Änderung des Organisationsnamens ändert auch ihre URL. +settings.change_orgname_redirect_prompt=Der alte Name wird weiterleiten, bis er wieder beansprucht wird. settings.update_avatar_success=Der Organisationsavatar wurde aktualisiert. settings.delete=Organisation löschen settings.delete_account=Diese Organisation löschen From b2c20b68a08e23bc952402a553d59a4613188bd0 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 27 Jan 2021 04:57:18 +0100 Subject: [PATCH 09/24] Print usefull error if SQLite is used in settings but not supported (#14476) * move log output to points where they are relefant * check explicit of sqlite3 in settings --- routers/init.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/routers/init.go b/routers/init.go index 9d13bc9ed59ab..f5dbfc87d2721 100644 --- a/routers/init.go +++ b/routers/init.go @@ -126,6 +126,7 @@ func GlobalInit(ctx context.Context) { if !setting.InstallLock { log.Fatal("Gitea is not installed") } + if err := git.Init(ctx); err != nil { log.Fatal("Git module init failed: %v", err) } @@ -134,6 +135,7 @@ func GlobalInit(ctx context.Context) { log.Trace("AppWorkPath: %s", setting.AppWorkPath) log.Trace("Custom path: %s", setting.CustomPath) log.Trace("Log path: %s", setting.LogRootPath) + checkRunMode() // Setup i18n translation.InitLocales() @@ -143,6 +145,12 @@ func GlobalInit(ctx context.Context) { highlight.NewContext() external.RegisterParsers() markup.Init() + + if setting.EnableSQLite3 { + log.Info("SQLite3 Supported") + } else if setting.Database.UseSQLite3 { + log.Fatal("SQLite3 is set in settings but NOT Supported") + } if err := initDBEngine(ctx); err == nil { log.Info("ORM engine initialization successful!") } else { @@ -175,11 +183,6 @@ func GlobalInit(ctx context.Context) { } eventsource.GetManager().Init() - if setting.EnableSQLite3 { - log.Info("SQLite3 Supported") - } - checkRunMode() - if setting.SSH.StartBuiltinServer { ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) log.Info("SSH server started on %s:%d. Cipher list (%v), key exchange algorithms (%v), MACs (%v)", setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) From c10503afeccd5172ace7613094dd5fe1e0770c55 Mon Sep 17 00:00:00 2001 From: Jui-Nan Lin Date: Wed, 27 Jan 2021 18:00:35 +0800 Subject: [PATCH 10/24] [Feature] add precise search type for Elastic Search (#12869) * feat: add type query parameters for specifying precise search * feat: add select dropdown in search box Co-authored-by: Lauris BH Co-authored-by: techknowlogick --- modules/context/pagination.go | 1 + modules/indexer/code/bleve.go | 25 ++++++++++++++++++------- modules/indexer/code/elastic_search.go | 13 +++++++++++-- modules/indexer/code/indexer.go | 2 +- modules/indexer/code/indexer_test.go | 2 +- modules/indexer/code/search.go | 4 ++-- modules/indexer/code/wrapped.go | 4 ++-- options/locale/locale_en-US.ini | 4 ++++ routers/home.go | 8 ++++++-- routers/repo/search.go | 6 +++++- templates/explore/code.tmpl | 13 +++++++++++-- templates/repo/search.tmpl | 20 +++++++++++++++----- 12 files changed, 77 insertions(+), 25 deletions(-) diff --git a/modules/context/pagination.go b/modules/context/pagination.go index a6638f40865b6..b678fccd1558a 100644 --- a/modules/context/pagination.go +++ b/modules/context/pagination.go @@ -53,4 +53,5 @@ func (p *Pagination) SetDefaultParams(ctx *Context) { p.AddParam(ctx, "sort", "SortType") p.AddParam(ctx, "q", "Keyword") p.AddParam(ctx, "tab", "TabName") + p.AddParam(ctx, "t", "queryType") } diff --git a/modules/indexer/code/bleve.go b/modules/indexer/code/bleve.go index b0822ad22210b..826efde4c1da5 100644 --- a/modules/indexer/code/bleve.go +++ b/modules/indexer/code/bleve.go @@ -280,12 +280,23 @@ func (b *BleveIndexer) Delete(repoID int64) error { // Search searches for files in the specified repo. // Returns the matching file-paths -func (b *BleveIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) { - phraseQuery := bleve.NewMatchPhraseQuery(keyword) - phraseQuery.FieldVal = "Content" - phraseQuery.Analyzer = repoIndexerAnalyzer +func (b *BleveIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) { + var ( + indexerQuery query.Query + keywordQuery query.Query + ) + + if isMatch { + prefixQuery := bleve.NewPrefixQuery(keyword) + prefixQuery.FieldVal = "Content" + keywordQuery = prefixQuery + } else { + phraseQuery := bleve.NewMatchPhraseQuery(keyword) + phraseQuery.FieldVal = "Content" + phraseQuery.Analyzer = repoIndexerAnalyzer + keywordQuery = phraseQuery + } - var indexerQuery query.Query if len(repoIDs) > 0 { var repoQueries = make([]query.Query, 0, len(repoIDs)) for _, repoID := range repoIDs { @@ -294,10 +305,10 @@ func (b *BleveIndexer) Search(repoIDs []int64, language, keyword string, page, p indexerQuery = bleve.NewConjunctionQuery( bleve.NewDisjunctionQuery(repoQueries...), - phraseQuery, + keywordQuery, ) } else { - indexerQuery = phraseQuery + indexerQuery = keywordQuery } // Save for reuse without language filter diff --git a/modules/indexer/code/elastic_search.go b/modules/indexer/code/elastic_search.go index 0f61c4e59202d..f81dbb34d42be 100644 --- a/modules/indexer/code/elastic_search.go +++ b/modules/indexer/code/elastic_search.go @@ -27,6 +27,10 @@ import ( const ( esRepoIndexerLatestVersion = 1 + // multi-match-types, currently only 2 types are used + // Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types + esMultiMatchTypeBestFields = "best_fields" + esMultiMatchTypePhrasePrefix = "phrase_prefix" ) var ( @@ -330,8 +334,13 @@ func extractAggs(searchResult *elastic.SearchResult) []*SearchResultLanguages { } // Search searches for codes and language stats by given conditions. -func (b *ElasticSearchIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) { - kwQuery := elastic.NewMultiMatchQuery(keyword, "content") +func (b *ElasticSearchIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) { + searchType := esMultiMatchTypeBestFields + if isMatch { + searchType = esMultiMatchTypePhrasePrefix + } + + kwQuery := elastic.NewMultiMatchQuery(keyword, "content").Type(searchType) query := elastic.NewBoolQuery() query = query.Must(kwQuery) if len(repoIDs) > 0 { diff --git a/modules/indexer/code/indexer.go b/modules/indexer/code/indexer.go index 35c298a5486b5..a7d78e9fdc82c 100644 --- a/modules/indexer/code/indexer.go +++ b/modules/indexer/code/indexer.go @@ -43,7 +43,7 @@ type SearchResultLanguages struct { type Indexer interface { Index(repo *models.Repository, sha string, changes *repoChanges) error Delete(repoID int64) error - Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) + Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) Close() } diff --git a/modules/indexer/code/indexer_test.go b/modules/indexer/code/indexer_test.go index 0b4851a48a6e1..8fcb7a0e8a677 100644 --- a/modules/indexer/code/indexer_test.go +++ b/modules/indexer/code/indexer_test.go @@ -64,7 +64,7 @@ func testIndexer(name string, t *testing.T, indexer Indexer) { for _, kw := range keywords { t.Run(kw.Keyword, func(t *testing.T) { - total, res, langs, err := indexer.Search(kw.RepoIDs, "", kw.Keyword, 1, 10) + total, res, langs, err := indexer.Search(kw.RepoIDs, "", kw.Keyword, 1, 10, false) assert.NoError(t, err) assert.EqualValues(t, len(kw.IDs), total) assert.EqualValues(t, kw.Langs, len(langs)) diff --git a/modules/indexer/code/search.go b/modules/indexer/code/search.go index 29ed416541de4..51b7c9427d2d9 100644 --- a/modules/indexer/code/search.go +++ b/modules/indexer/code/search.go @@ -106,12 +106,12 @@ func searchResult(result *SearchResult, startIndex, endIndex int) (*Result, erro } // PerformSearch perform a search on a repository -func PerformSearch(repoIDs []int64, language, keyword string, page, pageSize int) (int, []*Result, []*SearchResultLanguages, error) { +func PerformSearch(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int, []*Result, []*SearchResultLanguages, error) { if len(keyword) == 0 { return 0, nil, nil, nil } - total, results, resultLanguages, err := indexer.Search(repoIDs, language, keyword, page, pageSize) + total, results, resultLanguages, err := indexer.Search(repoIDs, language, keyword, page, pageSize, isMatch) if err != nil { return 0, nil, nil, err } diff --git a/modules/indexer/code/wrapped.go b/modules/indexer/code/wrapped.go index d839544874986..5b19f9c625737 100644 --- a/modules/indexer/code/wrapped.go +++ b/modules/indexer/code/wrapped.go @@ -73,12 +73,12 @@ func (w *wrappedIndexer) Delete(repoID int64) error { return indexer.Delete(repoID) } -func (w *wrappedIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) { +func (w *wrappedIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) { indexer, err := w.get() if err != nil { return 0, nil, nil, err } - return indexer.Search(repoIDs, language, keyword, page, pageSize) + return indexer.Search(repoIDs, language, keyword, page, pageSize, isMatch) } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1fe43ce29bbf1..4083f71147362 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -237,6 +237,8 @@ users = Users organizations = Organizations search = Search code = Code +search.fuzzy = Fuzzy +search.match = Match repo_no_results = No matching repositories found. user_no_results = No matching users found. org_no_results = No matching organizations found. @@ -1462,6 +1464,8 @@ activity.git_stats_deletion_n = %d deletions search = Search search.search_repo = Search repository +search.fuzzy = Fuzzy +search.match = Match search.results = Search results for "%s" in %s settings = Settings diff --git a/routers/home.go b/routers/home.go index d37bf8e31b5d5..f82ee9808b2c4 100644 --- a/routers/home.go +++ b/routers/home.go @@ -299,6 +299,9 @@ func ExploreCode(ctx *context.Context) { page = 1 } + queryType := strings.TrimSpace(ctx.Query("t")) + isMatch := queryType == "match" + var ( repoIDs []int64 err error @@ -342,14 +345,14 @@ func ExploreCode(ctx *context.Context) { ctx.Data["RepoMaps"] = rightRepoMap - total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum) + total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) if err != nil { ctx.ServerError("SearchResults", err) return } // if non-login user or isAdmin, no need to check UnitTypeCode } else if (ctx.User == nil && len(repoIDs) > 0) || isAdmin { - total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum) + total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) if err != nil { ctx.ServerError("SearchResults", err) return @@ -380,6 +383,7 @@ func ExploreCode(ctx *context.Context) { ctx.Data["Keyword"] = keyword ctx.Data["Language"] = language + ctx.Data["queryType"] = queryType ctx.Data["SearchResults"] = searchResults ctx.Data["SearchResultLanguages"] = searchResultLanguages ctx.Data["RequireHighlightJS"] = true diff --git a/routers/repo/search.go b/routers/repo/search.go index e110ae2a72467..42fe3d7584786 100644 --- a/routers/repo/search.go +++ b/routers/repo/search.go @@ -28,14 +28,18 @@ func Search(ctx *context.Context) { if page <= 0 { page = 1 } + queryType := strings.TrimSpace(ctx.Query("t")) + isMatch := queryType == "match" + total, searchResults, searchResultLanguages, err := code_indexer.PerformSearch([]int64{ctx.Repo.Repository.ID}, - language, keyword, page, setting.UI.RepoSearchPagingNum) + language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) if err != nil { ctx.ServerError("SearchResults", err) return } ctx.Data["Keyword"] = keyword ctx.Data["Language"] = language + ctx.Data["queryType"] = queryType ctx.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(ctx.Repo.Repository.Owner.Name, ctx.Repo.Repository.Name) ctx.Data["SearchResults"] = searchResults diff --git a/templates/explore/code.tmpl b/templates/explore/code.tmpl index 1c41dd843f263..2465663a60344 100644 --- a/templates/explore/code.tmpl +++ b/templates/explore/code.tmpl @@ -5,9 +5,19 @@
+
+
+
+ +
+
+
@@ -18,7 +28,7 @@
{{range $term := .SearchResultLanguages}} - + {{$term.Language}}
{{$term.Count}}
@@ -62,4 +72,3 @@
{{template "base/footer" .}} - diff --git a/templates/repo/search.tmpl b/templates/repo/search.tmpl index b66391a5ac5a5..ab9e9be2d6b1c 100644 --- a/templates/repo/search.tmpl +++ b/templates/repo/search.tmpl @@ -5,10 +5,20 @@ @@ -18,7 +28,7 @@
{{range $term := .SearchResultLanguages}} - + {{$term.Language}}
{{$term.Count}}
From 1080b27a395479996957ebc5c483b288aac0d566 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 27 Jan 2021 10:02:09 +0000 Subject: [PATCH 11/24] [skip ci] Updated translations via Crowdin --- options/locale/locale_tr-TR.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 857b5ee62ef61..0649795eb5f67 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -2064,6 +2064,7 @@ dashboard.resync_all_sshprincipals.desc=(Yerleşik SSH sunucusu için gerekli de dashboard.resync_all_hooks=Tüm depoların alma öncesi, güncelleme ve alma sonrası kancalarını yeniden senkronize edin. dashboard.reinit_missing_repos=Kayıtları bulunanlar için tüm eksik Git depolarını yeniden başlat dashboard.sync_external_users=Harici kullanıcı verisini senkronize et +dashboard.cleanup_hook_task_table=Hook_task tablosunu temizleme dashboard.server_uptime=Sunucunun Ayakta Kalma Süresi dashboard.current_goroutine=Güncel Goroutine'ler dashboard.current_memory_usage=Güncel Bellek Kullanımı From cfa57dde66c632d283704fe616010ac280b81f0d Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 27 Jan 2021 20:47:00 +0800 Subject: [PATCH 12/24] Fix bug that username missed on issue list assignee filter (#14481) Co-authored-by: 6543 <6543@obermui.de> --- templates/repo/issue/list.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl index 7b856e60cb6cb..26eb0e27c1349 100644 --- a/templates/repo/issue/list.tmpl +++ b/templates/repo/issue/list.tmpl @@ -71,7 +71,7 @@
{{.i18n.Tr "repo.issues.filter_assginee_no_select"}} {{range .Assignees}} - {{avatar .}} + {{avatar .}} {{.GetDisplayName}} {{end}}
@@ -178,7 +178,7 @@ {{range .Assignees}}
- {{avatar .}} + {{avatar .}} {{.GetDisplayName}}
{{end}} From 2e90a256be87b7536e694c1d49978fcbc91685a7 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 27 Jan 2021 12:48:37 +0000 Subject: [PATCH 13/24] [skip ci] Updated translations via Crowdin --- options/locale/locale_tr-TR.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 0649795eb5f67..e6cd40228cda6 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -237,6 +237,8 @@ users=Kullanıcılar organizations=Organizasyonlar search=Ara code=Kod +search.fuzzy=Belirsiz +search.match=Eşleştir repo_no_results=Eşleşen bir depo bulunamadı. user_no_results=Eşleşen kullanıcı bulunamadı. org_no_results=Eşleşen organizasyon bulunamadı. @@ -1461,6 +1463,8 @@ activity.git_stats_deletion_n=%d silme oldu search=Ara search.search_repo=Depo ara +search.fuzzy=Belirsiz +search.match=Eşleştir search.results="%s" için %s içinde sonuçları ara settings=Ayarlar From af7f71207c3e9f62a873e3d4a0b57cdbfe121bb1 Mon Sep 17 00:00:00 2001 From: PhilAtWysdom Date: Wed, 27 Jan 2021 13:33:32 +0000 Subject: [PATCH 14/24] Fix: url.Values map was not initialized (#14485) Values map was not initialized, leading to error 500 on submission of initial configuration Co-authored-by: 6543 <6543@obermui.de> --- modules/middlewares/flash.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/middlewares/flash.go b/modules/middlewares/flash.go index 38217288e8109..732e1c76ea554 100644 --- a/modules/middlewares/flash.go +++ b/modules/middlewares/flash.go @@ -27,6 +27,9 @@ type Flash struct { } func (f *Flash) set(name, msg string, current ...bool) { + if f.Values == nil { + f.Values = make(map[string][]string) + } isShow := false if (len(current) == 0 && FlashNow) || (len(current) > 0 && current[0]) { From 669ff8e9b1c15d24dd30852588c2dbb3d82e0cd9 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 27 Jan 2021 22:20:42 +0800 Subject: [PATCH 15/24] Fix switch language (#14484) Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lauris BH --- modules/middlewares/locale.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/middlewares/locale.go b/modules/middlewares/locale.go index 7cfba81bda6bf..21980ad486e52 100644 --- a/modules/middlewares/locale.go +++ b/modules/middlewares/locale.go @@ -15,24 +15,22 @@ import ( // Locale handle locale func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale { - hasCookie := false - // 1. Check URL arguments. lang := req.URL.Query().Get("lang") + var changeLang = lang != "" // 2. Get language information from cookies. if len(lang) == 0 { ck, _ := req.Cookie("lang") if ck != nil { lang = ck.Value - hasCookie = true } } // Check again in case someone modify by purpose. if lang != "" && !i18n.IsExist(lang) { lang = "" - hasCookie = false + changeLang = false } // 3. Get language information from 'Accept-Language'. @@ -43,8 +41,8 @@ func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale { lang = tag.String() } - if !hasCookie { - req.AddCookie(NewCookie("lang", lang, 1<<31-1)) + if changeLang { + SetCookie(resp, "lang", lang, 1<<31-1) } return translation.NewLocale(lang) From 41c0776568b3fa1bf825439103085146260e16a8 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 27 Jan 2021 22:56:54 +0800 Subject: [PATCH 16/24] Fix captcha (#14488) Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lauris BH --- modules/cache/cache.go | 20 +--------- modules/context/captcha.go | 2 + modules/context/context.go | 38 ++++++------------- modules/setting/cache.go | 4 ++ routers/routes/web.go | 4 +- routers/user/auth.go | 5 +++ routers/user/auth_openid.go | 2 + templates/user/auth/signup_inner.tmpl | 2 +- .../user/auth/signup_openid_register.tmpl | 2 +- 9 files changed, 30 insertions(+), 49 deletions(-) diff --git a/modules/cache/cache.go b/modules/cache/cache.go index 3f8885ee306ed..609f5a242b8df 100644 --- a/modules/cache/cache.go +++ b/modules/cache/cache.go @@ -27,24 +27,6 @@ func newCache(cacheConfig setting.Cache) (mc.Cache, error) { }) } -// Cache is the interface that operates the cache data. -type Cache interface { - // Put puts value into cache with key and expire time. - Put(key string, val interface{}, timeout int64) error - // Get gets cached value by given key. - Get(key string) interface{} - // Delete deletes cached value by given key. - Delete(key string) error - // Incr increases cached int-type value by given key as a counter. - Incr(key string) error - // Decr decreases cached int-type value by given key as a counter. - Decr(key string) error - // IsExist returns true if cached value exists. - IsExist(key string) bool - // Flush deletes all cached data. - Flush() error -} - // NewContext start cache service func NewContext() error { var err error @@ -59,7 +41,7 @@ func NewContext() error { } // GetCache returns the currently configured cache -func GetCache() Cache { +func GetCache() mc.Cache { return conn } diff --git a/modules/context/captcha.go b/modules/context/captcha.go index 956380ed731d8..b8540136a186d 100644 --- a/modules/context/captcha.go +++ b/modules/context/captcha.go @@ -7,6 +7,7 @@ package context import ( "sync" + "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/setting" "gitea.com/go-chi/captcha" @@ -21,6 +22,7 @@ func GetImageCaptcha() *captcha.Captcha { cpt = captcha.NewCaptcha(captcha.Options{ SubURL: setting.AppSubURL, }) + cpt.Store = cache.GetCache() }) return cpt } diff --git a/modules/context/context.go b/modules/context/context.go index 630129b8c12fc..e5025205c9fd0 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -23,6 +23,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/auth/sso" "code.gitea.io/gitea/modules/base" + mc "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/setting" @@ -499,23 +500,8 @@ func getCsrfOpts() CsrfOptions { // Contexter initializes a classic context for a request. func Contexter() func(next http.Handler) http.Handler { - rnd := templates.HTMLRenderer() - - var c cache.Cache - var err error - if setting.CacheService.Enabled { - c, err = cache.NewCacher(cache.Options{ - Adapter: setting.CacheService.Adapter, - AdapterConfig: setting.CacheService.Conn, - Interval: setting.CacheService.Interval, - }) - if err != nil { - panic(err) - } - } - + var rnd = templates.HTMLRenderer() var csrfOpts = getCsrfOpts() - //var flashEncryptionKey, _ = NewSecret() return func(next http.Handler) http.Handler { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { @@ -524,7 +510,7 @@ func Contexter() func(next http.Handler) http.Handler { var link = setting.AppSubURL + strings.TrimSuffix(req.URL.EscapedPath(), "/") var ctx = Context{ Resp: NewResponse(resp), - Cache: c, + Cache: mc.GetCache(), Locale: locale, Link: link, Render: rnd, @@ -571,16 +557,14 @@ func Contexter() func(next http.Handler) http.Handler { } ctx.Resp.Before(func(resp ResponseWriter) { if flash := f.Encode(); len(flash) > 0 { - if err == nil { - middlewares.SetCookie(resp, "macaron_flash", flash, 0, - setting.SessionConfig.CookiePath, - middlewares.Domain(setting.SessionConfig.Domain), - middlewares.HTTPOnly(true), - middlewares.Secure(setting.SessionConfig.Secure), - //middlewares.SameSite(opt.SameSite), FIXME: we need a samesite config - ) - return - } + middlewares.SetCookie(resp, "macaron_flash", flash, 0, + setting.SessionConfig.CookiePath, + middlewares.Domain(setting.SessionConfig.Domain), + middlewares.HTTPOnly(true), + middlewares.Secure(setting.SessionConfig.Secure), + //middlewares.SameSite(opt.SameSite), FIXME: we need a samesite config + ) + return } ctx.SetCookie("macaron_flash", "", -1, diff --git a/modules/setting/cache.go b/modules/setting/cache.go index af47bd085ab81..618be2482a7b2 100644 --- a/modules/setting/cache.go +++ b/modules/setting/cache.go @@ -68,6 +68,10 @@ func newCacheService() { if CacheService.Enabled { log.Info("Cache Service Enabled") + } else { + log.Warn("Cache Service Disabled so that captcha disabled too") + // captcha depends on cache service + Service.EnableCaptcha = false } sec = Cfg.Section("cache.last_commit") diff --git a/routers/routes/web.go b/routers/routes/web.go index 6b6322f048fc7..cbd7c0b7ca6f3 100644 --- a/routers/routes/web.go +++ b/routers/routes/web.go @@ -161,7 +161,9 @@ func WebRoutes() *web.Route { mailer.InitMailRender(templates.Mailer()) - r.Use(captcha.Captchaer(context.GetImageCaptcha())) + if setting.Service.EnableCaptcha { + r.Use(captcha.Captchaer(context.GetImageCaptcha())) + } // Removed: toolbox.Toolboxer middleware will provide debug informations which seems unnecessary r.Use(context.Contexter()) // Removed: SetAutoHead allow a get request redirect to head if get method is not exist diff --git a/routers/user/auth.go b/routers/user/auth.go index 909d0a2ee5918..bb877767aef8a 100644 --- a/routers/user/auth.go +++ b/routers/user/auth.go @@ -747,6 +747,7 @@ func LinkAccount(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("link_account") ctx.Data["LinkAccountMode"] = true ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha && setting.Service.RequireExternalRegistrationCaptcha + ctx.Data["Captcha"] = context.GetImageCaptcha() ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey @@ -800,6 +801,7 @@ func LinkAccountPostSignIn(ctx *context.Context) { ctx.Data["LinkAccountModeSignIn"] = true ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha && setting.Service.RequireExternalRegistrationCaptcha ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL + ctx.Data["Captcha"] = context.GetImageCaptcha() ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration @@ -885,6 +887,7 @@ func LinkAccountPostRegister(ctx *context.Context) { ctx.Data["LinkAccountModeRegister"] = true ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha && setting.Service.RequireExternalRegistrationCaptcha ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL + ctx.Data["Captcha"] = context.GetImageCaptcha() ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration @@ -1063,6 +1066,7 @@ func SignUp(ctx *context.Context) { ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL + ctx.Data["Captcha"] = context.GetImageCaptcha() ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey @@ -1083,6 +1087,7 @@ func SignUpPost(ctx *context.Context) { ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL + ctx.Data["Captcha"] = context.GetImageCaptcha() ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey diff --git a/routers/user/auth_openid.go b/routers/user/auth_openid.go index 1efcc7eda82c1..3f5c9f7248ce0 100644 --- a/routers/user/auth_openid.go +++ b/routers/user/auth_openid.go @@ -329,6 +329,7 @@ func RegisterOpenID(ctx *context.Context) { ctx.Data["PageIsOpenIDRegister"] = true ctx.Data["EnableOpenIDSignUp"] = setting.Service.EnableOpenIDSignUp ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha + ctx.Data["Captcha"] = context.GetImageCaptcha() ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey @@ -360,6 +361,7 @@ func RegisterOpenIDPost(ctx *context.Context) { ctx.Data["EnableOpenIDSignUp"] = setting.Service.EnableOpenIDSignUp ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL + ctx.Data["Captcha"] = context.GetImageCaptcha() ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey diff --git a/templates/user/auth/signup_inner.tmpl b/templates/user/auth/signup_inner.tmpl index 70fc2947c3233..4e8c0adb4f623 100644 --- a/templates/user/auth/signup_inner.tmpl +++ b/templates/user/auth/signup_inner.tmpl @@ -37,7 +37,7 @@ {{if and .EnableCaptcha (eq .CaptchaType "image")}}
- {{.Captcha.CreateHtml}} + {{.Captcha.CreateHTML}}
diff --git a/templates/user/auth/signup_openid_register.tmpl b/templates/user/auth/signup_openid_register.tmpl index 3138cfe13b509..90af77476b568 100644 --- a/templates/user/auth/signup_openid_register.tmpl +++ b/templates/user/auth/signup_openid_register.tmpl @@ -23,7 +23,7 @@ {{if and .EnableCaptcha (eq .CaptchaType "image")}}
- {{.Captcha.CreateHtml}} + {{.Captcha.CreateHTML}}
From 4c6e0295069a3c2f0df3d9f30560906bc2aa73a8 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Wed, 27 Jan 2021 11:15:39 -0500 Subject: [PATCH 17/24] Use gitea.svg for public/img/gitea-gitea.svg instead of logo.svg (#14479) --- build/generate-svg.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/generate-svg.js b/build/generate-svg.js index 52d2c519ef47b..09e08e48dcb17 100755 --- a/build/generate-svg.js +++ b/build/generate-svg.js @@ -65,7 +65,7 @@ async function main() { await Promise.all([ ...processFiles('../node_modules/@primer/octicons/build/svg/*-16.svg', {prefix: 'octicon'}), ...processFiles('../web_src/svg/*.svg'), - ...processFiles('../assets/logo.svg', {fullName: 'gitea-gitea'}), + ...processFiles('../public/img/gitea.svg', {fullName: 'gitea-gitea'}), ]); } From a51cc6dea41b154b946e982fde6cc1a600210a71 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 28 Jan 2021 01:46:35 +0800 Subject: [PATCH 18/24] Fix access log (#14475) Fix #14121, #14478. The `AccessLog` middleware has to be after `Contexter` or `APIContexter` so that we can get `LoginUserName` if possible. And also there is a **BREAK** change that it removed internal API access log. --- modules/auth/sso/oauth2.go | 3 +- modules/auth/sso/sso.go | 10 ------ modules/auth/sso/sspi_windows.go | 7 ++-- modules/context/access_log.go | 60 ++++++++++++++++++++++++++++++++ modules/context/context.go | 25 +++++++++++++ modules/context/response.go | 10 +++++- modules/middlewares/request.go | 20 +++++++++++ routers/api/v1/api.go | 5 +++ routers/routes/base.go | 53 ---------------------------- routers/routes/web.go | 8 ++--- 10 files changed, 129 insertions(+), 72 deletions(-) create mode 100644 modules/context/access_log.go create mode 100644 modules/middlewares/request.go diff --git a/modules/auth/sso/oauth2.go b/modules/auth/sso/oauth2.go index c3f6f08fb27d2..b6f59dc92420c 100644 --- a/modules/auth/sso/oauth2.go +++ b/modules/auth/sso/oauth2.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/timeutil" ) @@ -121,7 +122,7 @@ func (o *OAuth2) VerifyAuthData(req *http.Request, w http.ResponseWriter, store return nil } - if isInternalPath(req) || !isAPIPath(req) && !isAttachmentDownload(req) { + if middlewares.IsInternalPath(req) || !middlewares.IsAPIPath(req) && !isAttachmentDownload(req) { return nil } diff --git a/modules/auth/sso/sso.go b/modules/auth/sso/sso.go index d54310168eb12..f3788e4c9dd67 100644 --- a/modules/auth/sso/sso.go +++ b/modules/auth/sso/sso.go @@ -94,16 +94,6 @@ func SessionUser(sess SessionStore) *models.User { return user } -// isAPIPath returns true if the specified URL is an API path -func isAPIPath(req *http.Request) bool { - return strings.HasPrefix(req.URL.Path, "/api/") -} - -// isInternalPath returns true if the specified URL is an internal API path -func isInternalPath(req *http.Request) bool { - return strings.HasPrefix(req.URL.Path, "/api/internal/") -} - // isAttachmentDownload check if request is a file download (GET) with URL to an attachment func isAttachmentDownload(req *http.Request) bool { return strings.HasPrefix(req.URL.Path, "/attachments/") && req.Method == "GET" diff --git a/modules/auth/sso/sspi_windows.go b/modules/auth/sso/sspi_windows.go index 448336c07b309..10571d67c544f 100644 --- a/modules/auth/sso/sspi_windows.go +++ b/modules/auth/sso/sspi_windows.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/middlewares" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" @@ -135,7 +136,7 @@ func (s *SSPI) VerifyAuthData(req *http.Request, w http.ResponseWriter, store Da } // Make sure requests to API paths and PWA resources do not create a new session - if !isAPIPath(req) && !isAttachmentDownload(req) { + if !middlewares.IsAPIPath(req) && !isAttachmentDownload(req) { handleSignIn(w, req, sess, user) } @@ -166,9 +167,9 @@ func (s *SSPI) shouldAuthenticate(req *http.Request) (shouldAuth bool) { } else if req.FormValue("auth_with_sspi") == "1" { shouldAuth = true } - } else if isInternalPath(req) { + } else if middlewares.IsInternalPath(req) { shouldAuth = false - } else if isAPIPath(req) || isAttachmentDownload(req) { + } else if middlewares.IsAPIPath(req) || isAttachmentDownload(req) { shouldAuth = true } return diff --git a/modules/context/access_log.go b/modules/context/access_log.go new file mode 100644 index 0000000000000..97bb32f4c5382 --- /dev/null +++ b/modules/context/access_log.go @@ -0,0 +1,60 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package context + +import ( + "bytes" + "html/template" + "net/http" + "time" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" +) + +type routerLoggerOptions struct { + req *http.Request + Identity *string + Start *time.Time + ResponseWriter http.ResponseWriter + Ctx map[string]interface{} +} + +// AccessLogger returns a middleware to log access logger +func AccessLogger() func(http.Handler) http.Handler { + logger := log.GetLogger("access") + logTemplate, _ := template.New("log").Parse(setting.AccessLogTemplate) + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + start := time.Now() + next.ServeHTTP(w, req) + identity := "-" + if val := SignedUserName(req); val != "" { + identity = val + } + rw := w.(ResponseWriter) + + buf := bytes.NewBuffer([]byte{}) + err := logTemplate.Execute(buf, routerLoggerOptions{ + req: req, + Identity: &identity, + Start: &start, + ResponseWriter: rw, + Ctx: map[string]interface{}{ + "RemoteAddr": req.RemoteAddr, + "Req": req, + }, + }) + if err != nil { + log.Error("Could not set up chi access logger: %v", err.Error()) + } + + err = logger.SendLog(log.INFO, "", "", 0, buf.String(), "") + if err != nil { + log.Error("Could not set up chi access logger: %v", err.Error()) + } + }) + } +} diff --git a/modules/context/context.go b/modules/context/context.go index e5025205c9fd0..d02339d5b0c14 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -485,6 +485,31 @@ func GetContext(req *http.Request) *Context { return req.Context().Value(contextKey).(*Context) } +// SignedUserName returns signed user's name via context +func SignedUserName(req *http.Request) string { + if middlewares.IsInternalPath(req) { + return "" + } + if middlewares.IsAPIPath(req) { + ctx, ok := req.Context().Value(apiContextKey).(*APIContext) + if ok { + v := ctx.Data["SignedUserName"] + if res, ok := v.(string); ok { + return res + } + } + } else { + ctx, ok := req.Context().Value(contextKey).(*Context) + if ok { + v := ctx.Data["SignedUserName"] + if res, ok := v.(string); ok { + return res + } + } + } + return "" +} + func getCsrfOpts() CsrfOptions { return CsrfOptions{ Secret: setting.SecretKey, diff --git a/modules/context/response.go b/modules/context/response.go index 1881ec7b332c1..bdbbb97af78ba 100644 --- a/modules/context/response.go +++ b/modules/context/response.go @@ -12,6 +12,7 @@ type ResponseWriter interface { Flush() Status() int Before(func(ResponseWriter)) + Size() int } var ( @@ -21,11 +22,17 @@ var ( // Response represents a response type Response struct { http.ResponseWriter + written int status int befores []func(ResponseWriter) beforeExecuted bool } +// Size return written size +func (r *Response) Size() int { + return r.written +} + // Write writes bytes to HTTP endpoint func (r *Response) Write(bs []byte) (int, error) { if !r.beforeExecuted { @@ -35,8 +42,9 @@ func (r *Response) Write(bs []byte) (int, error) { r.beforeExecuted = true } size, err := r.ResponseWriter.Write(bs) + r.written += size if err != nil { - return 0, err + return size, err } if r.status == 0 { r.WriteHeader(200) diff --git a/modules/middlewares/request.go b/modules/middlewares/request.go new file mode 100644 index 0000000000000..aa3d60be28204 --- /dev/null +++ b/modules/middlewares/request.go @@ -0,0 +1,20 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package middlewares + +import ( + "net/http" + "strings" +) + +// IsAPIPath returns true if the specified URL is an API path +func IsAPIPath(req *http.Request) bool { + return strings.HasPrefix(req.URL.Path, "/api/") +} + +// IsInternalPath returns true if the specified URL is an internal API path +func IsInternalPath(req *http.Request) bool { + return strings.HasPrefix(req.URL.Path, "/api/internal/") +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 593551d770be0..b78c55269edb1 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -553,6 +553,11 @@ func Routes() *web.Route { })) } m.Use(context.APIContexter()) + + if setting.EnableAccessLog { + m.Use(context.AccessLogger()) + } + m.Use(context.ToggleAPI(&context.ToggleOptions{ SignInRequired: setting.Service.RequireSignInView, })) diff --git a/routers/routes/base.go b/routers/routes/base.go index a313032a88a6d..4efb7f01d5c75 100644 --- a/routers/routes/base.go +++ b/routers/routes/base.go @@ -5,7 +5,6 @@ package routes import ( - "bytes" "errors" "fmt" "io" @@ -13,7 +12,6 @@ import ( "os" "path" "strings" - "text/template" "time" "code.gitea.io/gitea/modules/auth/sso" @@ -28,57 +26,6 @@ import ( "gitea.com/go-chi/session" ) -type routerLoggerOptions struct { - req *http.Request - Identity *string - Start *time.Time - ResponseWriter http.ResponseWriter -} - -// SignedUserName returns signed user's name via context -func SignedUserName(req *http.Request) string { - ctx := context.GetContext(req) - if ctx != nil { - v := ctx.Data["SignedUserName"] - if res, ok := v.(string); ok { - return res - } - } - return "" -} - -func accessLogger() func(http.Handler) http.Handler { - logger := log.GetLogger("access") - logTemplate, _ := template.New("log").Parse(setting.AccessLogTemplate) - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - start := time.Now() - next.ServeHTTP(w, req) - identity := "-" - if val := SignedUserName(req); val != "" { - identity = val - } - rw := w - - buf := bytes.NewBuffer([]byte{}) - err := logTemplate.Execute(buf, routerLoggerOptions{ - req: req, - Identity: &identity, - Start: &start, - ResponseWriter: rw, - }) - if err != nil { - log.Error("Could not set up chi access logger: %v", err.Error()) - } - - err = logger.SendLog(log.INFO, "", "", 0, buf.String(), "") - if err != nil { - log.Error("Could not set up chi access logger: %v", err.Error()) - } - }) - } -} - // LoggerHandler is a handler that will log the routing to the default gitea log func LoggerHandler(level log.Level) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { diff --git a/routers/routes/web.go b/routers/routes/web.go index cbd7c0b7ca6f3..3fecb4dbbe05b 100644 --- a/routers/routes/web.go +++ b/routers/routes/web.go @@ -88,10 +88,6 @@ func commonMiddlewares() []func(http.Handler) http.Handler { next.ServeHTTP(resp, req) }) }) - - if setting.EnableAccessLog { - handlers = append(handlers, accessLogger()) - } return handlers } @@ -168,6 +164,10 @@ func WebRoutes() *web.Route { r.Use(context.Contexter()) // Removed: SetAutoHead allow a get request redirect to head if get method is not exist + if setting.EnableAccessLog { + r.Use(context.AccessLogger()) + } + r.Use(user.GetNotificationCount) r.Use(repo.GetActiveStopwatch) r.Use(func(ctx *context.Context) { From fe5266a25b16c45660388ed51cb8f17945509596 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 27 Jan 2021 17:47:55 +0000 Subject: [PATCH 19/24] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 17089acfe2292..4b03451658850 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -449,6 +449,7 @@ update_language_not_found=言語 '%s' は利用できません。 update_profile_success=プロフィールを更新しました。 change_username=ユーザー名を変更しました。 change_username_prompt=注: ユーザー名を変更すると、アカウントのURLも変わります。 +change_username_redirect_prompt=古いユーザー名は、再使用されていない限りリダイレクトします。 continue=続行 cancel=キャンセル language=言語 @@ -1940,6 +1941,7 @@ settings.visibility.private_shortname=プライベート settings.update_settings=設定の更新 settings.update_setting_success=組織の設定を更新しました。 settings.change_orgname_prompt=注: 組織の名称を変更すると、組織のURLも変わります。 +settings.change_orgname_redirect_prompt=古い名前は、再使用されていない限りリダイレクトします。 settings.update_avatar_success=組織のアバターを更新しました。 settings.delete=組織を削除 settings.delete_account=この組織を削除 From a7cfb9f2c3dc239e06e07921d4ebc05252859381 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 27 Jan 2021 22:46:22 +0100 Subject: [PATCH 20/24] Fix JSON Header response (#14499) --- modules/context/context.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/context/context.go b/modules/context/context.go index d02339d5b0c14..adae562c0a8e6 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -356,8 +356,8 @@ func (ctx *Context) Error(status int, contents ...string) { // JSON render content as JSON func (ctx *Context) JSON(status int, content interface{}) { - ctx.Resp.WriteHeader(status) ctx.Resp.Header().Set("Content-Type", "application/json;charset=utf8") + ctx.Resp.WriteHeader(status) if err := json.NewEncoder(ctx.Resp).Encode(content); err != nil { ctx.ServerError("Render JSON failed", err) } From 154b23da0a67e975e435307e47678bf8e8758d25 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 28 Jan 2021 20:29:22 +0800 Subject: [PATCH 21/24] Fix display since time round (#14226) * Fix display since time round * Fix since time * Fix tests --- modules/timeutil/since.go | 97 +++++++++++++++++++++++++++++++++- modules/timeutil/since_test.go | 92 ++++++++++++++++++++------------ 2 files changed, 152 insertions(+), 37 deletions(-) diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go index e6c29c19ffbb4..c0240907ae8df 100644 --- a/modules/timeutil/since.go +++ b/modules/timeutil/since.go @@ -7,6 +7,7 @@ package timeutil import ( "fmt" "html/template" + "math" "strings" "time" @@ -25,7 +26,11 @@ const ( Year = 12 * Month ) -func computeTimeDiff(diff int64, lang string) (int64, string) { +func round(s float64) int64 { + return int64(math.Round(s)) +} + +func computeTimeDiffFloor(diff int64, lang string) (int64, string) { diffStr := "" switch { case diff <= 0: @@ -83,6 +88,94 @@ func computeTimeDiff(diff int64, lang string) (int64, string) { return diff, diffStr } +func computeTimeDiff(diff int64, lang string) (int64, string) { + diffStr := "" + switch { + case diff <= 0: + diff = 0 + diffStr = i18n.Tr(lang, "tool.now") + case diff < 2: + diff = 0 + diffStr = i18n.Tr(lang, "tool.1s") + case diff < 1*Minute: + diffStr = i18n.Tr(lang, "tool.seconds", diff) + diff = 0 + + case diff < Minute+Minute/2: + diff -= 1 * Minute + diffStr = i18n.Tr(lang, "tool.1m") + case diff < 1*Hour: + minutes := round(float64(diff) / Minute) + if minutes > 1 { + diffStr = i18n.Tr(lang, "tool.minutes", minutes) + } else { + diffStr = i18n.Tr(lang, "tool.1m") + } + diff -= diff / Minute * Minute + + case diff < Hour+Hour/2: + diff -= 1 * Hour + diffStr = i18n.Tr(lang, "tool.1h") + case diff < 1*Day: + hours := round(float64(diff) / Hour) + if hours > 1 { + diffStr = i18n.Tr(lang, "tool.hours", hours) + } else { + diffStr = i18n.Tr(lang, "tool.1h") + } + diff -= diff / Hour * Hour + + case diff < Day+Day/2: + diff -= 1 * Day + diffStr = i18n.Tr(lang, "tool.1d") + case diff < 1*Week: + days := round(float64(diff) / Day) + if days > 1 { + diffStr = i18n.Tr(lang, "tool.days", days) + } else { + diffStr = i18n.Tr(lang, "tool.1d") + } + diff -= diff / Day * Day + + case diff < Week+Week/2: + diff -= 1 * Week + diffStr = i18n.Tr(lang, "tool.1w") + case diff < 1*Month: + weeks := round(float64(diff) / Week) + if weeks > 1 { + diffStr = i18n.Tr(lang, "tool.weeks", weeks) + } else { + diffStr = i18n.Tr(lang, "tool.1w") + } + diff -= diff / Week * Week + + case diff < 1*Month+Month/2: + diff -= 1 * Month + diffStr = i18n.Tr(lang, "tool.1mon") + case diff < 1*Year: + months := round(float64(diff) / Month) + if months > 1 { + diffStr = i18n.Tr(lang, "tool.months", months) + } else { + diffStr = i18n.Tr(lang, "tool.1mon") + } + diff -= diff / Month * Month + + case diff < Year+Year/2: + diff -= 1 * Year + diffStr = i18n.Tr(lang, "tool.1y") + default: + years := round(float64(diff) / Year) + if years > 1 { + diffStr = i18n.Tr(lang, "tool.years", years) + } else { + diffStr = i18n.Tr(lang, "tool.1y") + } + diff -= (diff / Year) * Year + } + return diff, diffStr +} + // MinutesToFriendly returns a user friendly string with number of minutes // converted to hours and minutes. func MinutesToFriendly(minutes int, lang string) string { @@ -111,7 +204,7 @@ func timeSincePro(then, now time.Time, lang string) string { break } - diff, diffStr = computeTimeDiff(diff, lang) + diff, diffStr = computeTimeDiffFloor(diff, lang) timeStr += ", " + diffStr } return strings.TrimPrefix(timeStr, ", ") diff --git a/modules/timeutil/since_test.go b/modules/timeutil/since_test.go index 5710e91db5f0b..1379e71c3d67c 100644 --- a/modules/timeutil/since_test.go +++ b/modules/timeutil/since_test.go @@ -5,6 +5,7 @@ package timeutil import ( + "fmt" "os" "testing" "time" @@ -45,27 +46,39 @@ func TestTimeSince(t *testing.T) { // test that each diff in `diffs` yields the expected string test := func(expected string, diffs ...time.Duration) { - for _, diff := range diffs { - actual := timeSince(BaseDate, BaseDate.Add(diff), "en") - assert.Equal(t, i18n.Tr("en", "tool.ago", expected), actual) - actual = timeSince(BaseDate.Add(diff), BaseDate, "en") - assert.Equal(t, i18n.Tr("en", "tool.from_now", expected), actual) - } + t.Run(expected, func(t *testing.T) { + for _, diff := range diffs { + actual := timeSince(BaseDate, BaseDate.Add(diff), "en") + assert.Equal(t, i18n.Tr("en", "tool.ago", expected), actual) + actual = timeSince(BaseDate.Add(diff), BaseDate, "en") + assert.Equal(t, i18n.Tr("en", "tool.from_now", expected), actual) + } + }) } test("1 second", time.Second, time.Second+50*time.Millisecond) test("2 seconds", 2*time.Second, 2*time.Second+50*time.Millisecond) - test("1 minute", time.Minute, time.Minute+30*time.Second) - test("2 minutes", 2*time.Minute, 2*time.Minute+30*time.Second) - test("1 hour", time.Hour, time.Hour+30*time.Minute) - test("2 hours", 2*time.Hour, 2*time.Hour+30*time.Minute) - test("1 day", DayDur, DayDur+12*time.Hour) - test("2 days", 2*DayDur, 2*DayDur+12*time.Hour) + test("1 minute", time.Minute, time.Minute+29*time.Second) + test("2 minutes", 2*time.Minute, time.Minute+30*time.Second) + test("2 minutes", 2*time.Minute, 2*time.Minute+29*time.Second) + test("1 hour", time.Hour, time.Hour+29*time.Minute) + test("2 hours", 2*time.Hour, time.Hour+30*time.Minute) + test("2 hours", 2*time.Hour, 2*time.Hour+29*time.Minute) + test("3 hours", 3*time.Hour, 2*time.Hour+30*time.Minute) + test("1 day", DayDur, DayDur+11*time.Hour) + test("2 days", 2*DayDur, DayDur+12*time.Hour) + test("2 days", 2*DayDur, 2*DayDur+11*time.Hour) + test("3 days", 3*DayDur, 2*DayDur+12*time.Hour) test("1 week", WeekDur, WeekDur+3*DayDur) + test("2 weeks", 2*WeekDur, WeekDur+4*DayDur) test("2 weeks", 2*WeekDur, 2*WeekDur+3*DayDur) - test("1 month", MonthDur, MonthDur+15*DayDur) - test("2 months", 2*MonthDur, 2*MonthDur+15*DayDur) - test("1 year", YearDur, YearDur+6*MonthDur) - test("2 years", 2*YearDur, 2*YearDur+6*MonthDur) + test("3 weeks", 3*WeekDur, 2*WeekDur+4*DayDur) + test("1 month", MonthDur, MonthDur+14*DayDur) + test("2 months", 2*MonthDur, MonthDur+15*DayDur) + test("2 months", 2*MonthDur, 2*MonthDur+14*DayDur) + test("1 year", YearDur, YearDur+5*MonthDur) + test("2 years", 2*YearDur, YearDur+6*MonthDur) + test("2 years", 2*YearDur, 2*YearDur+5*MonthDur) + test("3 years", 3*YearDur, 2*YearDur+6*MonthDur) } func TestTimeSincePro(t *testing.T) { @@ -112,11 +125,11 @@ func TestHtmlTimeSince(t *testing.T) { } test("1 second", time.Second) test("3 minutes", 3*time.Minute+5*time.Second) - test("1 day", DayDur+18*time.Hour) - test("1 week", WeekDur+6*DayDur) - test("3 months", 3*MonthDur+3*WeekDur) + test("1 day", DayDur+11*time.Hour) + test("1 week", WeekDur+3*DayDur) + test("3 months", 3*MonthDur+2*WeekDur) test("2 years", 2*YearDur) - test("3 years", 3*YearDur+11*MonthDur+4*WeekDur) + test("3 years", 2*YearDur+11*MonthDur+4*WeekDur) } func TestComputeTimeDiff(t *testing.T) { @@ -124,26 +137,35 @@ func TestComputeTimeDiff(t *testing.T) { // computeTimeDiff(base + offset) == (offset, str) test := func(base int64, str string, offsets ...int64) { for _, offset := range offsets { - diff, diffStr := computeTimeDiff(base+offset, "en") - assert.Equal(t, offset, diff) - assert.Equal(t, str, diffStr) + t.Run(fmt.Sprintf("%s:%d", str, offset), func(t *testing.T) { + diff, diffStr := computeTimeDiff(base+offset, "en") + assert.Equal(t, offset, diff) + assert.Equal(t, str, diffStr) + }) } } test(0, "now", 0) test(1, "1 second", 0) test(2, "2 seconds", 0) - test(Minute, "1 minute", 0, 1, 30, Minute-1) - test(2*Minute, "2 minutes", 0, Minute-1) - test(Hour, "1 hour", 0, 1, Hour-1) - test(5*Hour, "5 hours", 0, Hour-1) - test(Day, "1 day", 0, 1, Day-1) - test(5*Day, "5 days", 0, Day-1) - test(Week, "1 week", 0, 1, Week-1) - test(3*Week, "3 weeks", 0, 4*Day+25000) - test(Month, "1 month", 0, 1, Month-1) - test(10*Month, "10 months", 0, Month-1) - test(Year, "1 year", 0, Year-1) - test(3*Year, "3 years", 0, Year-1) + test(Minute, "1 minute", 0, 1, 29) + test(Minute, "2 minutes", 30, Minute-1) + test(2*Minute, "2 minutes", 0, 29) + test(2*Minute, "3 minutes", 30, Minute-1) + test(Hour, "1 hour", 0, 1, 29*Minute) + test(Hour, "2 hours", 30*Minute, Hour-1) + test(5*Hour, "5 hours", 0, 29*Minute) + test(Day, "1 day", 0, 1, 11*Hour) + test(Day, "2 days", 12*Hour, Day-1) + test(5*Day, "5 days", 0, 11*Hour) + test(Week, "1 week", 0, 1, 3*Day) + test(Week, "2 weeks", 4*Day, Week-1) + test(3*Week, "3 weeks", 0, 3*Day) + test(Month, "1 month", 0, 1) + test(Month, "2 months", 16*Day, Month-1) + test(10*Month, "10 months", 0, 13*Day) + test(Year, "1 year", 0, 179*Day) + test(Year, "2 years", 180*Day, Year-1) + test(3*Year, "3 years", 0, 179*Day) } func TestMinutesToFriendly(t *testing.T) { From e45bf12a34d04b18f09663f179fb58aca9ffa192 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Thu, 28 Jan 2021 12:31:28 +0000 Subject: [PATCH 22/24] [skip ci] Updated translations via Crowdin --- options/locale/locale_zh-TW.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 6c5a5ebeaa07e..dfe728daf161a 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -1261,7 +1261,7 @@ pulls.is_checking=正在進行合併衝突檢查,請稍後再試。 pulls.required_status_check_failed=未通過某些必要的檢查。 pulls.required_status_check_missing=遺失某些必要的檢查。 pulls.required_status_check_administrator=身為系統管理員,您依然可以進行合併。 -pulls.blocked_by_approvals=此合併請求尚未獲得足夠的核可。需要 %d 個核可,已經獲得 %d 個。 +pulls.blocked_by_approvals=此合併請求尚未獲得足夠的核可。需要 %[2]d 個核可,已經獲得 %[1]d 個。 pulls.blocked_by_rejection=官方審核人員要求修改此合併請求。 pulls.blocked_by_official_review_requests=此合併請求有官方的審核請求。 pulls.blocked_by_outdated_branch=此合併請求因逾期而被阻擋。 From d1353e1f7c9bf648cd72bd9731b4f843b0dc9a86 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Thu, 28 Jan 2021 17:56:38 +0100 Subject: [PATCH 23/24] Vendor Update (#14496) * update code.gitea.io/sdk/gitea v0.13.1 -> v0.13.2 * update github.com/go-swagger/go-swagger v0.25.0 -> v0.26.0 * update github.com/google/uuid v1.1.2 -> v1.2.0 * update github.com/klauspost/compress v1.11.3 -> v1.11.7 * update github.com/lib/pq 083382b7e6fc -> v1.9.0 * update github.com/markbates/goth v1.65.0 -> v1.66.1 * update github.com/mattn/go-sqlite3 v1.14.4 -> v1.14.6 * update github.com/mgechev/revive 246eac737dc7 -> v1.0.3 * update github.com/minio/minio-go/v7 v7.0.6 -> v7.0.7 * update github.com/niklasfasching/go-org v1.3.2 -> v1.4.0 * update github.com/olivere/elastic/v7 v7.0.21 -> v7.0.22 * update github.com/pquerna/otp v1.2.0 -> v1.3.0 * update github.com/xanzy/go-gitlab v0.39.0 -> v0.42.0 * update github.com/yuin/goldmark v1.2.1 -> v1.3.1 --- go.mod | 51 +- go.sum | 194 +- vendor/code.gitea.io/sdk/gitea/admin_cron.go | 4 +- vendor/code.gitea.io/sdk/gitea/client.go | 2 +- vendor/code.gitea.io/sdk/gitea/go.mod | 2 +- vendor/code.gitea.io/sdk/gitea/issue.go | 6 +- .../code.gitea.io/sdk/gitea/issue_comment.go | 2 +- vendor/code.gitea.io/sdk/gitea/issue_label.go | 2 +- .../code.gitea.io/sdk/gitea/issue_reaction.go | 12 +- .../sdk/gitea/issue_subscription.go | 8 +- .../sdk/gitea/issue_tracked_time.go | 14 +- .../code.gitea.io/sdk/gitea/notifications.go | 24 +- vendor/code.gitea.io/sdk/gitea/oauth2.go | 10 +- vendor/code.gitea.io/sdk/gitea/pull.go | 4 +- vendor/code.gitea.io/sdk/gitea/pull_review.go | 12 +- vendor/code.gitea.io/sdk/gitea/release.go | 2 +- vendor/code.gitea.io/sdk/gitea/repo.go | 40 +- vendor/code.gitea.io/sdk/gitea/repo_branch.go | 4 +- .../sdk/gitea/repo_branch_protection.go | 10 +- vendor/code.gitea.io/sdk/gitea/repo_commit.go | 5 +- vendor/code.gitea.io/sdk/gitea/repo_file.go | 2 +- .../code.gitea.io/sdk/gitea/repo_migrate.go | 19 +- .../code.gitea.io/sdk/gitea/repo_transfer.go | 2 +- vendor/code.gitea.io/sdk/gitea/settings.go | 8 +- vendor/code.gitea.io/sdk/gitea/version.go | 26 + .../asaskevich/govalidator/.travis.yml | 22 +- .../asaskevich/govalidator/CODE_OF_CONDUCT.md | 43 + .../github.com/asaskevich/govalidator/LICENSE | 2 +- .../asaskevich/govalidator/README.md | 9 +- .../asaskevich/govalidator/arrays.go | 29 + .../asaskevich/govalidator/converter.go | 33 +- .../github.com/asaskevich/govalidator/go.mod | 2 +- .../asaskevich/govalidator/numerics.go | 37 +- .../asaskevich/govalidator/patterns.go | 4 +- .../asaskevich/govalidator/types.go | 24 +- .../asaskevich/govalidator/validator.go | 297 +- vendor/github.com/fatih/color/README.md | 13 +- vendor/github.com/fatih/color/go.mod | 4 +- vendor/github.com/fatih/color/go.sum | 15 +- .../github.com/felixge/httpsnoop/.gitignore | 0 .../github.com/felixge/httpsnoop/.travis.yml | 6 + .../github.com/felixge/httpsnoop/LICENSE.txt | 19 + vendor/github.com/felixge/httpsnoop/Makefile | 10 + vendor/github.com/felixge/httpsnoop/README.md | 94 + .../felixge/httpsnoop/capture_metrics.go | 84 + vendor/github.com/felixge/httpsnoop/docs.go | 10 + vendor/github.com/felixge/httpsnoop/go.mod | 3 + .../httpsnoop/wrap_generated_gteq_1.8.go | 385 + .../httpsnoop/wrap_generated_lt_1.8.go | 243 + .../go-openapi/analysis/.golangci.yml | 15 +- .../go-openapi/analysis/.travis.yml | 5 +- .../go-openapi/analysis/analyzer.go | 22 +- .../go-openapi/analysis/appveyor.yml | 3 +- .../github.com/go-openapi/analysis/fixer.go | 4 +- .../github.com/go-openapi/analysis/flatten.go | 35 +- vendor/github.com/go-openapi/analysis/go.mod | 25 +- vendor/github.com/go-openapi/analysis/go.sum | 130 +- .../github.com/go-openapi/analysis/schema.go | 2 +- .../go-openapi/errors/.golangci.yml | 21 + .../github.com/go-openapi/errors/.travis.yml | 19 +- vendor/github.com/go-openapi/errors/schema.go | 20 + .../go-openapi/jsonpointer/.travis.yml | 4 +- .../go-openapi/jsonpointer/pointer.go | 60 +- .../go-openapi/jsonreference/.golangci.yml | 41 + .../go-openapi/jsonreference/.travis.yml | 15 +- .../github.com/go-openapi/loads/.golangci.yml | 22 + .../github.com/go-openapi/loads/.travis.yml | 13 +- vendor/github.com/go-openapi/loads/README.md | 1 - vendor/github.com/go-openapi/loads/go.mod | 14 +- vendor/github.com/go-openapi/loads/go.sum | 146 +- vendor/github.com/go-openapi/loads/loaders.go | 137 + vendor/github.com/go-openapi/loads/options.go | 60 + vendor/github.com/go-openapi/loads/spec.go | 178 +- .../go-openapi/runtime/.golangci.yml | 42 + .../github.com/go-openapi/runtime/.travis.yml | 11 +- .../go-openapi/runtime/client_request.go | 50 + vendor/github.com/go-openapi/runtime/go.mod | 1 + vendor/github.com/go-openapi/runtime/go.sum | 2 + .../go-openapi/runtime/interfaces.go | 9 + .../go-openapi/runtime/middleware/context.go | 4 + .../runtime/middleware/denco/router.go | 6 +- .../go-openapi/runtime/middleware/rapidoc.go | 90 + .../go-openapi/runtime/middleware/router.go | 10 + .../github.com/go-openapi/spec/.golangci.yml | 11 + vendor/github.com/go-openapi/spec/.travis.yml | 20 +- vendor/github.com/go-openapi/spec/README.md | 24 +- .../github.com/go-openapi/spec/appveyor.yml | 34 + vendor/github.com/go-openapi/spec/bindata.go | 6 +- vendor/github.com/go-openapi/spec/cache.go | 54 +- .../go-openapi/spec/contact_info.go | 3 + vendor/github.com/go-openapi/spec/errors.go | 18 + vendor/github.com/go-openapi/spec/expander.go | 506 +- vendor/github.com/go-openapi/spec/go.mod | 13 +- vendor/github.com/go-openapi/spec/go.sum | 47 +- vendor/github.com/go-openapi/spec/header.go | 6 + vendor/github.com/go-openapi/spec/items.go | 22 +- vendor/github.com/go-openapi/spec/license.go | 3 + .../github.com/go-openapi/spec/normalizer.go | 41 +- .../github.com/go-openapi/spec/operation.go | 1 - .../github.com/go-openapi/spec/parameter.go | 11 +- .../github.com/go-openapi/spec/properties.go | 91 + vendor/github.com/go-openapi/spec/ref.go | 4 +- vendor/github.com/go-openapi/spec/resolver.go | 128 + vendor/github.com/go-openapi/spec/response.go | 25 +- vendor/github.com/go-openapi/spec/schema.go | 120 +- .../go-openapi/spec/schema_loader.go | 170 +- .../go-openapi/spec/security_scheme.go | 44 +- vendor/github.com/go-openapi/spec/spec.go | 14 +- .../github.com/go-openapi/spec/validations.go | 215 + .../go-openapi/strfmt/.golangci.yml | 11 + .../github.com/go-openapi/strfmt/.travis.yml | 24 +- vendor/github.com/go-openapi/strfmt/date.go | 5 + vendor/github.com/go-openapi/strfmt/format.go | 2 +- vendor/github.com/go-openapi/strfmt/go.mod | 13 +- vendor/github.com/go-openapi/strfmt/go.sum | 127 +- vendor/github.com/go-openapi/strfmt/time.go | 34 +- .../github.com/go-openapi/swag/.golangci.yml | 16 + vendor/github.com/go-openapi/swag/.travis.yml | 26 +- vendor/github.com/go-openapi/swag/README.md | 1 - vendor/github.com/go-openapi/swag/go.mod | 14 +- vendor/github.com/go-openapi/swag/go.sum | 29 +- vendor/github.com/go-openapi/swag/loading.go | 4 +- vendor/github.com/go-openapi/swag/util.go | 6 +- .../go-openapi/validate/.golangci.yml | 14 + .../go-openapi/validate/.travis.yml | 45 +- .../github.com/go-openapi/validate/README.md | 31 +- .../github.com/go-openapi/validate/context.go | 56 + .../go-openapi/validate/default_validator.go | 20 +- .../go-openapi/validate/example_validator.go | 20 +- vendor/github.com/go-openapi/validate/go.mod | 23 +- vendor/github.com/go-openapi/validate/go.sum | 77 + .../github.com/go-openapi/validate/helpers.go | 12 +- .../go-openapi/validate/object_validator.go | 4 +- vendor/github.com/go-openapi/validate/rexp.go | 2 +- .../github.com/go-openapi/validate/schema.go | 2 +- .../go-openapi/validate/schema_props.go | 2 +- vendor/github.com/go-openapi/validate/spec.go | 8 +- .../go-openapi/validate/spec_messages.go | 4 +- vendor/github.com/go-openapi/validate/type.go | 2 +- .../go-openapi/validate/validator.go | 1 - .../github.com/go-openapi/validate/values.go | 22 + .../go-swagger/cmd/swagger/commands/diff.go | 2 +- .../cmd/swagger/commands/diff/checks.go | 266 + .../swagger/commands/diff/compatibility.go | 54 +- .../cmd/swagger/commands/diff/difftypes.go | 187 +- .../cmd/swagger/commands/diff/node.go | 57 +- .../cmd/swagger/commands/diff/reporting.go | 59 +- .../cmd/swagger/commands/diff/schema.go | 126 + .../swagger/commands/diff/spec_analyser.go | 480 +- .../swagger/commands/diff/spec_difference.go | 39 +- .../swagger/commands/diff/type_adapters.go | 119 +- .../go-swagger/cmd/swagger/commands/expand.go | 10 +- .../cmd/swagger/commands/generate.go | 1 + .../cmd/swagger/commands/generate/markdown.go | 33 + .../cmd/swagger/commands/generate/server.go | 2 +- .../cmd/swagger/commands/generate/shared.go | 3 + .../go-swagger/cmd/swagger/commands/mixin.go | 10 +- .../go-swagger/cmd/swagger/commands/serve.go | 2 +- .../cmd/swagger/commands/version.go | 13 +- .../go-swagger/cmd/swagger/swagger.go | 7 +- .../go-swagger/go-swagger/codescan/README.md | 3 + .../go-swagger/codescan/application.go | 6 +- .../go-swagger/go-swagger/codescan/doc.go | 5 + .../go-swagger/go-swagger/codescan/meta.go | 3 +- .../go-swagger/codescan/parameters.go | 3 - .../go-swagger/go-swagger/codescan/parser.go | 27 +- .../go-swagger/codescan/responses.go | 6 + .../go-swagger/go-swagger/codescan/schema.go | 11 +- .../go-swagger/generator/.gitignore | 1 + .../go-swagger/generator/bindata.go | 306 +- .../go-swagger/go-swagger/generator/client.go | 11 +- .../go-swagger/generator/formats.go | 2 +- .../go-swagger/generator/language.go | 2 +- .../go-swagger/go-swagger/generator/model.go | 220 +- .../go-swagger/generator/operation.go | 184 +- .../go-swagger/go-swagger/generator/shared.go | 185 +- .../go-swagger/go-swagger/generator/spec.go | 6 +- .../go-swagger/generator/structs.go | 280 +- .../go-swagger/generator/support.go | 167 +- .../go-swagger/generator/template_repo.go | 260 +- .../go-swagger/go-swagger/generator/types.go | 419 +- .../go-swagger/go-swagger/scan/README.md | 3 + .../go-swagger/go-swagger/scan/classifier.go | 6 +- .../go-swagger/go-swagger/scan/doc.go | 2 + vendor/github.com/google/uuid/hash.go | 4 +- vendor/github.com/google/uuid/sql.go | 2 +- vendor/github.com/google/uuid/uuid.go | 10 +- vendor/github.com/google/uuid/version4.go | 8 + .../github.com/gorilla/handlers/compress.go | 163 +- vendor/github.com/gorilla/handlers/go.mod | 4 + vendor/github.com/gorilla/handlers/go.sum | 2 + .../github.com/gorilla/handlers/handlers.go | 35 +- .../gorilla/handlers/handlers_go18.go | 29 - .../gorilla/handlers/handlers_pre18.go | 7 - vendor/github.com/gorilla/handlers/logging.go | 39 +- .../github.com/gorilla/handlers/recovery.go | 9 +- .../klauspost/compress/flate/gen_inflate.go | 294 - .../klauspost/compress/huff0/README.md | 4 +- .../klauspost/compress/zstd/README.md | 25 +- .../klauspost/compress/zstd/blockdec.go | 2 +- .../klauspost/compress/zstd/blockenc.go | 1 + .../klauspost/compress/zstd/decodeheader.go | 202 + .../klauspost/compress/zstd/decoder.go | 27 +- .../klauspost/compress/zstd/enc_best.go | 484 + .../compress/zstd/encoder_options.go | 20 +- .../klauspost/compress/zstd/seqdec.go | 15 +- .../klauspost/compress/zstd/zstd.go | 12 + vendor/github.com/kr/pretty/formatter.go | 2 +- vendor/github.com/lib/pq/.gitignore | 2 + vendor/github.com/lib/pq/.travis.yml | 1 - vendor/github.com/lib/pq/array.go | 139 + vendor/github.com/lib/pq/conn.go | 114 +- vendor/github.com/lib/pq/conn_go18.go | 22 +- vendor/github.com/lib/pq/copy.go | 4 +- vendor/github.com/lib/pq/error.go | 11 +- .../magiconair/properties/.travis.yml | 4 + .../magiconair/properties/CHANGELOG.md | 23 +- .../properties/{LICENSE => LICENSE.md} | 9 +- .../magiconair/properties/README.md | 1 - .../github.com/magiconair/properties/go.mod | 2 + .../github.com/magiconair/properties/load.go | 5 +- .../magiconair/properties/properties.go | 29 +- vendor/github.com/markbates/goth/README.md | 9 +- vendor/github.com/markbates/goth/go.mod | 2 +- .../goth/providers/discord/discord.go | 6 +- .../mattn/go-colorable/colorable_windows.go | 4 +- vendor/github.com/mattn/go-runewidth/go.mod | 2 + vendor/github.com/mattn/go-runewidth/go.sum | 2 + .../mattn/go-runewidth/runewidth.go | 80 +- vendor/github.com/mattn/go-sqlite3/README.md | 4 +- vendor/github.com/mattn/go-sqlite3/doc.go | 35 +- vendor/github.com/mattn/go-sqlite3/go.mod | 2 +- .../mattn/go-sqlite3/sqlite3-binding.c | 2677 ++- .../mattn/go-sqlite3/sqlite3-binding.h | 79 +- vendor/github.com/mattn/go-sqlite3/sqlite3.go | 35 +- .../mattn/go-sqlite3/sqlite3_opt_vtable.go | 55 +- .../mattn/go-sqlite3/sqlite3_type.go | 4 +- .../go-sqlite3/sqlite3_usleep_windows.go | 4 +- .../github.com/mattn/go-sqlite3/sqlite3ext.h | 4 + .../github.com/minio/md5-simd/LICENSE.Golang | 27 + .../minio/md5-simd/block-generic.go | 2 +- vendor/github.com/minio/minio-go/v7/README.md | 2 +- .../minio/minio-go/v7/api-compose-object.go | 2 +- .../minio/minio-go/v7/api-error-response.go | 2 +- .../minio/minio-go/v7/api-get-options.go | 6 + .../minio/minio-go/v7/api-put-object.go | 2 +- .../minio/minio-go/v7/api-remove.go | 2 +- vendor/github.com/minio/minio-go/v7/api.go | 2 +- .../github.com/minio/minio-go/v7/constants.go | 1 + vendor/github.com/minio/minio-go/v7/go.mod | 1 + vendor/github.com/minio/minio-go/v7/go.sum | 3 + .../minio-go/v7/pkg/encrypt/server-side.go | 2 +- .../minio-go/v7/pkg/lifecycle/lifecycle.go | 28 +- .../v7/pkg/notification/notification.go | 22 +- .../v7/pkg/replication/replication.go | 39 + .../minio/minio-go/v7/post-policy.go | 18 + .../mitchellh/mapstructure/.travis.yml | 9 - .../mitchellh/mapstructure/CHANGELOG.md | 16 + .../mitchellh/mapstructure/decode_hooks.go | 71 +- .../mitchellh/mapstructure/mapstructure.go | 156 +- .../niklasfasching/go-org/org/drawer.go | 2 +- .../niklasfasching/go-org/org/html_writer.go | 15 +- .../github.com/olivere/elastic/v7/client.go | 149 +- .../olivere/elastic/v7/docker-compose.yml | 4 +- vendor/github.com/olivere/elastic/v7/go.mod | 6 +- .../v7/indices_delete_index_template.go | 186 + .../elastic/v7/indices_delete_template.go | 10 +- .../elastic/v7/indices_exists_template.go | 16 +- .../elastic/v7/indices_get_index_template.go | 214 + .../elastic/v7/indices_get_template.go | 10 +- .../elastic/v7/indices_put_index_template.go | 226 + .../elastic/v7/indices_put_template.go | 10 +- .../elastic/v7/xpack_async_search_delete.go | 154 + .../elastic/v7/xpack_async_search_get.go | 178 + .../elastic/v7/xpack_async_search_submit.go | 718 + vendor/github.com/pquerna/otp/.travis.yml | 5 +- vendor/github.com/pquerna/otp/README.md | 2 +- vendor/github.com/pquerna/otp/hotp/hotp.go | 9 +- vendor/github.com/pquerna/otp/otp.go | 16 + vendor/github.com/pquerna/otp/totp/totp.go | 9 +- vendor/github.com/rivo/uniseg/LICENSE.txt | 21 + vendor/github.com/rivo/uniseg/README.md | 62 + vendor/github.com/rivo/uniseg/doc.go | 8 + vendor/github.com/rivo/uniseg/go.mod | 3 + vendor/github.com/rivo/uniseg/grapheme.go | 268 + vendor/github.com/rivo/uniseg/properties.go | 1658 ++ vendor/github.com/spf13/afero/.travis.yml | 2 +- vendor/github.com/spf13/afero/README.md | 7 +- vendor/github.com/spf13/afero/go.mod | 2 +- vendor/github.com/spf13/afero/go.sum | 9 + vendor/github.com/spf13/afero/mem/file.go | 10 +- vendor/github.com/spf13/afero/memmap.go | 28 +- vendor/github.com/spf13/afero/unionFile.go | 17 +- .../github.com/xanzy/go-gitlab/.golangci.yml | 59 + vendor/github.com/xanzy/go-gitlab/.travis.yml | 24 +- .../xanzy/go-gitlab/applications.go | 3 + vendor/github.com/xanzy/go-gitlab/commits.go | 23 +- .../github.com/xanzy/go-gitlab/deployments.go | 11 +- .../xanzy/go-gitlab/event_parsing.go | 7 +- .../xanzy/go-gitlab/event_webhook_types.go | 133 +- vendor/github.com/xanzy/go-gitlab/events.go | 1 + vendor/github.com/xanzy/go-gitlab/gitlab.go | 5 +- .../github.com/xanzy/go-gitlab/group_hooks.go | 3 + .../xanzy/go-gitlab/group_milestones.go | 4 + vendor/github.com/xanzy/go-gitlab/groups.go | 30 +- .../github.com/xanzy/go-gitlab/issue_links.go | 2 + vendor/github.com/xanzy/go-gitlab/issues.go | 1 + vendor/github.com/xanzy/go-gitlab/jobs.go | 70 +- vendor/github.com/xanzy/go-gitlab/notes.go | 35 +- .../github.com/xanzy/go-gitlab/pipelines.go | 19 +- .../xanzy/go-gitlab/project_mirror.go | 1 - vendor/github.com/xanzy/go-gitlab/projects.go | 9 + vendor/github.com/xanzy/go-gitlab/releases.go | 8 +- .../xanzy/go-gitlab/repository_files.go | 2 + vendor/github.com/xanzy/go-gitlab/runners.go | 47 +- vendor/github.com/xanzy/go-gitlab/services.go | 1 + vendor/github.com/xanzy/go-gitlab/users.go | 89 +- vendor/github.com/xanzy/go-gitlab/validate.go | 80 + vendor/github.com/yuin/goldmark/README.md | 88 +- vendor/github.com/yuin/goldmark/ast/ast.go | 28 +- vendor/github.com/yuin/goldmark/ast/block.go | 23 +- vendor/github.com/yuin/goldmark/ast/inline.go | 2 +- .../yuin/goldmark/extension/ast/footnote.go | 35 +- .../yuin/goldmark/extension/footnote.go | 382 +- .../yuin/goldmark/extension/linkify.go | 4 +- .../yuin/goldmark/extension/table.go | 104 +- vendor/github.com/yuin/goldmark/go.mod | 2 +- .../github.com/yuin/goldmark/parser/link.go | 8 - .../github.com/yuin/goldmark/parser/parser.go | 12 + .../yuin/goldmark/parser/raw_html.go | 9 +- vendor/github.com/yuin/goldmark/util/util.go | 16 +- .../bson/bsoncodec/byte_slice_codec.go | 3 + .../bson/bsoncodec/default_value_decoders.go | 119 +- .../bson/bsoncodec/default_value_encoders.go | 33 +- .../mongo-driver/bson/bsoncodec/map_codec.go | 135 +- .../bson/bsoncodec/pointer_codec.go | 9 +- .../mongo-driver/bson/bsoncodec/registry.go | 10 +- .../bson/bsoncodec/slice_codec.go | 7 +- .../bson/bsoncodec/string_codec.go | 4 + .../bson/bsoncodec/struct_codec.go | 187 +- .../mongo-driver/bson/bsoncodec/time_codec.go | 8 +- .../mongo-driver/bson/bsoncodec/uint_codec.go | 4 + .../bson/bsonoptions/map_codec_options.go | 21 +- .../bson/bsonoptions/struct_codec_options.go | 27 +- .../bson/bsonrw/extjson_wrappers.go | 2 +- .../go.mongodb.org/mongo-driver/bson/doc.go | 22 +- .../mongo-driver/bson/primitive/decimal.go | 5 + .../mongo-driver/bson/primitive/objectid.go | 19 +- .../mongo-driver/bson/primitive/primitive.go | 23 +- .../mongo-driver/bson/raw_value.go | 12 +- .../mongo-driver/x/bsonx/bsoncore/bsoncore.go | 7 +- .../mongo-driver/x/bsonx/bsoncore/document.go | 3 +- .../internal/socket/zsys_openbsd_mips64.go | 50 + vendor/golang.org/x/net/publicsuffix/table.go | 19976 ++++++++-------- vendor/golang.org/x/oauth2/README.md | 10 +- vendor/golang.org/x/oauth2/google/google.go | 25 + .../google/internal/externalaccount/aws.go | 230 + .../externalaccount/basecredentials.go | 145 + .../internal/externalaccount/clientauth.go | 41 + .../google/internal/externalaccount/err.go | 18 + .../externalaccount/filecredsource.go | 57 + .../internal/externalaccount/impersonate.go | 83 + .../internal/externalaccount/sts_exchange.go | 98 + .../internal/externalaccount/urlcredsource.go | 71 + vendor/golang.org/x/sys/execabs/execabs.go | 102 + .../x/sys/windows/syscall_windows.go | 29 +- .../golang.org/x/sys/windows/types_windows.go | 240 +- .../x/sys/windows/zsyscall_windows.go | 108 +- .../encoding/simplifiedchinese/hzgb2312.go | 2 +- .../x/text/internal/language/parse.go | 11 +- vendor/golang.org/x/text/unicode/bidi/bidi.go | 221 +- vendor/golang.org/x/text/unicode/bidi/core.go | 63 +- .../x/tools/go/analysis/analysis.go | 4 + .../x/tools/go/analysis/diagnostic.go | 4 + vendor/golang.org/x/tools/go/analysis/doc.go | 4 + .../analysis/internal/analysisflags/help.go | 4 + .../go/analysis/unitchecker/unitchecker112.go | 4 + .../x/tools/go/analysis/validate.go | 4 + .../golang.org/x/tools/go/ast/astutil/util.go | 4 + .../x/tools/go/buildutil/fakecontext.go | 4 + .../golang.org/x/tools/go/buildutil/tags.go | 4 + .../golang.org/x/tools/go/internal/cgo/cgo.go | 2 +- .../x/tools/go/internal/cgo/cgo_pkgconfig.go | 2 +- .../tools/go/internal/packagesdriver/sizes.go | 64 - .../x/tools/go/packages/external.go | 4 +- .../golang.org/x/tools/go/packages/golist.go | 199 +- .../x/tools/go/packages/golist_overlay.go | 25 +- .../golang.org/x/tools/go/packages/visit.go | 4 + vendor/golang.org/x/tools/imports/forward.go | 4 + .../x/tools/internal/event/core/event.go | 2 +- .../x/tools/internal/gocommand/invoke.go | 31 +- .../x/tools/internal/gocommand/version.go | 13 +- .../x/tools/internal/imports/mod.go | 28 +- .../x/tools/internal/imports/mod_cache.go | 4 + .../internal/packagesinternal/packages.go | 4 + .../tools/internal/typesinternal/errorcode.go | 1358 ++ .../typesinternal/errorcode_string.go | 152 + .../x/tools/internal/typesinternal/types.go | 17 + vendor/gopkg.in/yaml.v2/.travis.yml | 1 + vendor/gopkg.in/yaml.v2/apic.go | 6 +- vendor/gopkg.in/yaml.v2/go.mod | 8 +- vendor/gopkg.in/yaml.v2/yaml.go | 14 +- vendor/modules.txt | 99 +- 403 files changed, 29620 insertions(+), 14240 deletions(-) create mode 100644 vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md create mode 100644 vendor/github.com/felixge/httpsnoop/.gitignore create mode 100644 vendor/github.com/felixge/httpsnoop/.travis.yml create mode 100644 vendor/github.com/felixge/httpsnoop/LICENSE.txt create mode 100644 vendor/github.com/felixge/httpsnoop/Makefile create mode 100644 vendor/github.com/felixge/httpsnoop/README.md create mode 100644 vendor/github.com/felixge/httpsnoop/capture_metrics.go create mode 100644 vendor/github.com/felixge/httpsnoop/docs.go create mode 100644 vendor/github.com/felixge/httpsnoop/go.mod create mode 100644 vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go create mode 100644 vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go create mode 100644 vendor/github.com/go-openapi/jsonreference/.golangci.yml create mode 100644 vendor/github.com/go-openapi/loads/loaders.go create mode 100644 vendor/github.com/go-openapi/loads/options.go create mode 100644 vendor/github.com/go-openapi/runtime/.golangci.yml create mode 100644 vendor/github.com/go-openapi/runtime/middleware/rapidoc.go create mode 100644 vendor/github.com/go-openapi/spec/appveyor.yml create mode 100644 vendor/github.com/go-openapi/spec/errors.go create mode 100644 vendor/github.com/go-openapi/spec/properties.go create mode 100644 vendor/github.com/go-openapi/spec/resolver.go create mode 100644 vendor/github.com/go-openapi/spec/validations.go create mode 100644 vendor/github.com/go-openapi/validate/context.go create mode 100644 vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/checks.go create mode 100644 vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/schema.go create mode 100644 vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/markdown.go create mode 100644 vendor/github.com/go-swagger/go-swagger/codescan/README.md create mode 100644 vendor/github.com/go-swagger/go-swagger/codescan/doc.go create mode 100644 vendor/github.com/go-swagger/go-swagger/generator/.gitignore create mode 100644 vendor/github.com/go-swagger/go-swagger/scan/README.md create mode 100644 vendor/github.com/gorilla/handlers/go.sum delete mode 100644 vendor/github.com/gorilla/handlers/handlers_go18.go delete mode 100644 vendor/github.com/gorilla/handlers/handlers_pre18.go delete mode 100644 vendor/github.com/klauspost/compress/flate/gen_inflate.go create mode 100644 vendor/github.com/klauspost/compress/zstd/decodeheader.go create mode 100644 vendor/github.com/klauspost/compress/zstd/enc_best.go rename vendor/github.com/magiconair/properties/{LICENSE => LICENSE.md} (84%) create mode 100644 vendor/github.com/mattn/go-runewidth/go.sum create mode 100644 vendor/github.com/minio/md5-simd/LICENSE.Golang delete mode 100644 vendor/github.com/mitchellh/mapstructure/.travis.yml create mode 100644 vendor/github.com/olivere/elastic/v7/indices_delete_index_template.go create mode 100644 vendor/github.com/olivere/elastic/v7/indices_get_index_template.go create mode 100644 vendor/github.com/olivere/elastic/v7/indices_put_index_template.go create mode 100644 vendor/github.com/olivere/elastic/v7/xpack_async_search_delete.go create mode 100644 vendor/github.com/olivere/elastic/v7/xpack_async_search_get.go create mode 100644 vendor/github.com/olivere/elastic/v7/xpack_async_search_submit.go create mode 100644 vendor/github.com/rivo/uniseg/LICENSE.txt create mode 100644 vendor/github.com/rivo/uniseg/README.md create mode 100644 vendor/github.com/rivo/uniseg/doc.go create mode 100644 vendor/github.com/rivo/uniseg/go.mod create mode 100644 vendor/github.com/rivo/uniseg/grapheme.go create mode 100644 vendor/github.com/rivo/uniseg/properties.go create mode 100644 vendor/github.com/xanzy/go-gitlab/.golangci.yml create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccount/clientauth.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccount/err.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccount/filecredsource.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccount/impersonate.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccount/urlcredsource.go create mode 100644 vendor/golang.org/x/sys/execabs/execabs.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go diff --git a/go.mod b/go.mod index ad10dadd293b5..167403ae05e43 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.14 require ( code.gitea.io/gitea-vet v0.2.1 - code.gitea.io/sdk/gitea v0.13.1 + code.gitea.io/sdk/gitea v0.13.2 gitea.com/go-chi/binding v0.0.0-20210113025129-03f1d313373c gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e @@ -17,6 +17,7 @@ require ( github.com/andybalholm/brotli v1.0.1 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/blevesearch/bleve/v2 v2.0.1 + github.com/boombuler/barcode v1.0.1 // indirect github.com/caddyserver/certmagic v0.12.0 github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/denisenkom/go-mssqldb v0.9.0 @@ -36,14 +37,14 @@ require ( github.com/go-ldap/ldap/v3 v3.2.4 github.com/go-redis/redis/v7 v7.4.0 github.com/go-sql-driver/mysql v1.5.0 - github.com/go-swagger/go-swagger v0.25.0 + github.com/go-swagger/go-swagger v0.26.0 github.com/go-testfixtures/testfixtures/v3 v3.4.1 github.com/gobwas/glob v0.2.3 github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 github.com/gogs/go-gogs-client v0.0.0-20200905025246-8bb8a50cb355 github.com/google/go-github/v32 v32.1.0 - github.com/google/uuid v1.1.2 + github.com/google/uuid v1.2.0 github.com/gorilla/context v1.1.1 github.com/hashicorp/go-retryablehttp v0.6.8 // indirect github.com/hashicorp/go-version v1.2.1 @@ -54,37 +55,37 @@ require ( github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 - github.com/klauspost/compress v1.11.3 + github.com/klauspost/compress v1.11.7 github.com/klauspost/pgzip v1.2.5 // indirect github.com/lafriks/xormstore v1.3.2 - github.com/lib/pq v1.8.1-0.20200908161135-083382b7e6fc + github.com/lib/pq v1.9.0 github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 - github.com/markbates/goth v1.65.0 - github.com/mattn/go-colorable v0.1.7 // indirect + github.com/markbates/goth v1.66.1 github.com/mattn/go-isatty v0.0.12 - github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/mattn/go-sqlite3 v1.14.4 + github.com/mattn/go-runewidth v0.0.10 // indirect + github.com/mattn/go-sqlite3 v1.14.6 github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 - github.com/mgechev/revive v1.0.3-0.20200921231451-246eac737dc7 + github.com/mgechev/revive v1.0.3 github.com/mholt/archiver/v3 v3.5.0 github.com/microcosm-cc/bluemonday v1.0.4 - github.com/minio/minio-go/v7 v7.0.6 + github.com/minio/md5-simd v1.1.1 // indirect + github.com/minio/minio-go/v7 v7.0.7 github.com/mitchellh/go-homedir v1.1.0 github.com/msteinert/pam v0.0.0-20200810204841-913b8f8cdf8b github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 - github.com/niklasfasching/go-org v1.3.2 + github.com/niklasfasching/go-org v1.4.0 github.com/oliamb/cutter v0.2.2 - github.com/olivere/elastic/v7 v7.0.21 + github.com/olivere/elastic/v7 v7.0.22 github.com/pelletier/go-toml v1.8.1 github.com/pierrec/lz4/v4 v4.1.1 // indirect github.com/pkg/errors v0.9.1 - github.com/pquerna/otp v1.2.0 + github.com/pquerna/otp v1.3.0 github.com/prometheus/client_golang v1.8.0 github.com/quasoft/websspi v1.0.0 + github.com/rivo/uniseg v0.2.0 // indirect github.com/sergi/go-diff v1.1.0 github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 - github.com/spf13/viper v1.7.1 // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/stretchr/testify v1.7.0 github.com/syndtr/goleveldb v1.0.0 @@ -97,24 +98,24 @@ require ( github.com/unrolled/render v1.0.3 github.com/urfave/cli v1.22.5 github.com/willf/bitset v1.1.11 // indirect - github.com/xanzy/go-gitlab v0.39.0 + github.com/xanzy/go-gitlab v0.42.0 github.com/yohcop/openid-go v1.0.0 - github.com/yuin/goldmark v1.2.1 + github.com/yuin/goldmark v1.3.1 github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 github.com/yuin/goldmark-meta v1.0.0 go.jolheiser.com/hcaptcha v0.0.4 go.jolheiser.com/pwn v0.0.3 - golang.org/x/crypto v0.0.0-20201217014255-9d1352758620 - golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 - golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 - golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 - golang.org/x/text v0.3.4 - golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect - golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9 + golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad + golang.org/x/net v0.0.0-20210119194325-5f4716e94777 + golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013 + golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c + golang.org/x/text v0.3.5 + golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect + golang.org/x/tools v0.1.0 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/ini.v1 v1.62.0 - gopkg.in/yaml.v2 v2.3.0 + gopkg.in/yaml.v2 v2.4.0 mvdan.cc/xurls/v2 v2.2.0 strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 xorm.io/builder v0.3.7 diff --git a/go.sum b/go.sum index 79cba8d26b944..59808acda1cc7 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= code.gitea.io/gitea-vet v0.2.1 h1:b30by7+3SkmiftK0RjuXqFvZg2q4p68uoPGuxhzBN0s= code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= -code.gitea.io/sdk/gitea v0.13.1 h1:Y7bpH2iO6Q0KhhMJfjP/LZ0AmiYITeRQlCD8b0oYqhk= -code.gitea.io/sdk/gitea v0.13.1/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY= +code.gitea.io/sdk/gitea v0.13.2 h1:wAnT/J7Z62q3fJXbgnecoaOBh8CM1Qq0/DakWxiv4yA= +code.gitea.io/sdk/gitea v0.13.2/go.mod h1:lee2y8LeV3kQb2iK+hHlMqoadL4bp27QOkOV/hawLKg= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gitea.com/go-chi/binding v0.0.0-20210113025129-03f1d313373c h1:NTtrGYjR40WUdkCdn26Y5LGFT52rIkFPkjmtgCAyiTs= gitea.com/go-chi/binding v0.0.0-20210113025129-03f1d313373c/go.mod h1:9bGA9dIsrz+wVQKH1DzvxuAvrudHaQ8Wx8hLme/GVGQ= @@ -82,6 +82,7 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= @@ -103,6 +104,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= @@ -126,9 +128,12 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.34.13/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/aws/aws-sdk-go v1.35.20/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= @@ -167,6 +172,8 @@ github.com/blevesearch/zapx/v15 v15.1.10 h1:kZR3b9jO9l6s2B5UHI+1N1llLzJ4nYikkXQT github.com/blevesearch/zapx/v15 v15.1.10/go.mod h1:4ypq25bwtSQKzwEF1UERyIhmGTbMT3brY/n4NC5gRnM= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA= github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/caddyserver/certmagic v0.12.0 h1:1f7kxykaJkOVVpXJ8ZrC6RAO5F6+kKm9U7dBFbLNeug= @@ -270,8 +277,12 @@ github.com/ethantkoenig/rupture v1.0.0/go.mod h1:GyE9QabHfxA6ch0NZgwsHopRbOLcYjU github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= @@ -331,12 +342,18 @@ github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9sn github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= github.com/go-openapi/analysis v0.19.10 h1:5BHISBAXOc/aJK25irLZnx2D3s6WyYaY9D4gmuz9fdE= github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= +github.com/go-openapi/analysis v0.19.16 h1:Ub9e++M8sDwtHD+S587TYi+6ANBG1NRYGZDihqk0SaY= +github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.6 h1:xZMThgv5SQ7SMbWtKFkCf9bBdvR2iEyw9k3zGZONuys= github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9 h1:9SnKdGhiPZHF3ttwFMiCBEb8jQ4IDdrK+5+a0oTygA4= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= @@ -344,12 +361,14 @@ github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.4 h1:3Vw+rh13uq2JFNxgnMTGE1rnoieU9FmyE1gvnyylsYg= -github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -357,12 +376,18 @@ github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= github.com/go-openapi/loads v0.19.5 h1:jZVYWawIQiA1NBnHla28ktg6hrcfTHsCE+3QLVRBIls= github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= +github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.20.0 h1:Pymw1O8zDmWeNv4kVsHd0W3cvgdp8juRa4U/U/8D/Pk= +github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= -github.com/go-openapi/runtime v0.19.20 h1:J/t+QIjbcoq8WJvjGxRKiFBhqUE8slS9SbmD0Oi/raQ= -github.com/go-openapi/runtime v0.19.20/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= +github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= +github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= +github.com/go-openapi/runtime v0.19.26 h1:K/6PoVNj5WJXUnMk+VEbELeXjtBkCS1UxTDa04tdXE0= +github.com/go-openapi/runtime v0.19.26/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= @@ -370,6 +395,10 @@ github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8 github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/spec v0.19.8 h1:qAdZLh1r6QF/hI/gTq+TJTvsQUodZsM7KLqkAJdiJNg= github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.1 h1:5WNKTzPguDN+79wbJw2UE2q+eX+gUmEFsIKSvnSQJlc= +github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= @@ -378,6 +407,9 @@ github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6 github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/strfmt v0.19.5 h1:0utjKrw+BAh8s57XE9Xz8DUBsVvPmRUB6styvl9wWIM= github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= +github.com/go-openapi/strfmt v0.20.0 h1:l2omNtmNbMc39IGptl9BuXBEKcZfS8zjrTsPKTiJiDM= +github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= @@ -385,11 +417,18 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4azE= github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/go-openapi/swag v0.19.13 h1:233UVgMy1DlmCYYfOiFpta6e2urloh+sEs5id6lyzog= +github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= github.com/go-openapi/validate v0.19.10 h1:tG3SZ5DC5KF4cyt7nqLVcQXGj5A7mpaYkAcNPlDK+Yk= github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= +github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= +github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= +github.com/go-openapi/validate v0.20.1 h1:QGQ5CvK74E28t3DkegGweKR+auemUi5IdpMc4x3UW6s= +github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4= github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4= @@ -401,8 +440,8 @@ github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gG github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-swagger/go-swagger v0.25.0 h1:FxhyrWWV8V/A9P6GtI5szWordAdbb6Y0nqdY/y9So2w= -github.com/go-swagger/go-swagger v0.25.0/go.mod h1:9639ioXrPX9E6BbnbaDklGXjNz7upAXoNBwL4Ok11Vk= +github.com/go-swagger/go-swagger v0.26.0 h1:LM5XTbeRbDdjHRqdA0jchK5Qs3DB2F0R5QmXs1pd/L0= +github.com/go-swagger/go-swagger v0.26.0/go.mod h1:kSAA+pziAr5x68on6TxcxWoIl9GOo1mLsHmfMV2rrCo= github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0= github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0= github.com/go-testfixtures/testfixtures/v3 v3.4.1 h1:Qz9y0wUOXPHzKhK6C79A/menChtEu/xd0Dn5ngVyMD0= @@ -511,8 +550,8 @@ github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hf github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -525,8 +564,8 @@ github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAk github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= -github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -637,7 +676,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -670,8 +710,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8h3jc= -github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.5/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= @@ -687,8 +727,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= @@ -703,8 +743,8 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.8.1-0.20200908161135-083382b7e6fc h1:ERSU1OvZ6MdWhHieo2oT7xwR/HCksqKdgK6iYPU5pHI= -github.com/lib/pq v1.8.1-0.20200908161135-083382b7e6fc/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= +github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libdns/libdns v0.1.0 h1:0ctCOrVJsVzj53mop1angHp/pE3hmAhP7KiHvR0HD04= github.com/libdns/libdns v0.1.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -719,6 +759,8 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY= +github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -727,8 +769,8 @@ github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7 github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA= -github.com/markbates/goth v1.65.0 h1:IbXpMneUhqbxgJ8JP1Ghl8ghlAaVX66jWDAapU1KxqU= -github.com/markbates/goth v1.65.0/go.mod h1:65frybxoeSCfORin51KOKqAKbIh7wREIDvdCkdWj//4= +github.com/markbates/goth v1.66.1 h1:8YIkRxRxiUxhYhHdvriKiJ+mk2itt2ezjf/ABR8U+JI= +github.com/markbates/goth v1.66.1/go.mod h1:57wf4mNb/fy/Cizm8xe4komsQRKPuelTMrm/wGcw3v8= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -736,8 +778,8 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -750,19 +792,19 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= -github.com/mattn/go-sqlite3 v1.14.4 h1:4rQjbDxdu9fSgI/r3KN72G3c2goxknAqHHgPWWs8UlI= -github.com/mattn/go-sqlite3 v1.14.4/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= +github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM= github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= -github.com/mgechev/revive v1.0.3-0.20200921231451-246eac737dc7 h1:ydVkpU/M4/c45yT3e5lzMeguKJm9GxGgsawx4/XlwK0= -github.com/mgechev/revive v1.0.3-0.20200921231451-246eac737dc7/go.mod h1:no/hfevHbndpXR5CaJahkYCfM/FFpmM/dSOwFGU7Z1o= +github.com/mgechev/revive v1.0.3 h1:z3FL6IFFN3JKzHYHD8O1ExH9g/4lAGJ5x1+9rPZgsFg= +github.com/mgechev/revive v1.0.3/go.mod h1:POGGZagSo/0frdr7VeAifzS5Uka0d0GPiM35MsTO8nE= github.com/mholt/acmez v0.1.1 h1:KQODCqk+hBn3O7qfCRPj6L96uG65T5BSS95FKNEqtdA= github.com/mholt/acmez v0.1.1/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM= github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE= @@ -772,10 +814,13 @@ github.com/miekg/dns v1.1.30 h1:Qww6FseFn8PRfw07jueqIXqodm0JKiiKuK0DeXSqfyo= github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4= github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= -github.com/minio/minio-go/v7 v7.0.6 h1:9czXaG0LEZ9s74smSqy0rm034MxngQoP6HTTuSc5GEs= -github.com/minio/minio-go/v7 v7.0.6/go.mod h1:HcIuq+11d/3MfavIPZiswSzfQ1VJ2Lwxp/XLtW46IWQ= +github.com/minio/md5-simd v1.1.1 h1:9ojcLbuZ4gXbB2sX53MKn8JUZ0sB/2wfwsEcRw+I08U= +github.com/minio/md5-simd v1.1.1/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= +github.com/minio/minio-go/v7 v7.0.7 h1:Qld/xb8C1Pwbu0jU46xAceyn9xXKCMW+3XfNbpmTB70= +github.com/minio/minio-go/v7 v7.0.7/go.mod h1:pEZBUa+L2m9oECoIA6IcSK8bv/qggtQVLovjeKK5jYc= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sio v0.2.1/go.mod h1:8b0yPp2avGThviy/+OCJBI6OMpvxoUuiLvE6F1lebhw= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -787,6 +832,10 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -814,8 +863,8 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/niklasfasching/go-org v1.3.2 h1:ZKTSd+GdJYkoZl1pBXLR/k7DRiRXnmB96TRiHmHdzwI= -github.com/niklasfasching/go-org v1.3.2/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU= +github.com/niklasfasching/go-org v1.4.0 h1:qPy4VEdX55f5QcLiaD3X7N/tY5XOgk4y2uEyQa02i7A= +github.com/niklasfasching/go-org v1.4.0/go.mod h1:4FWT4U/Anir9ewjwNpbZIzMjG5RaXFafkyWZNEPRdk8= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= @@ -829,8 +878,8 @@ github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k= github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU= -github.com/olivere/elastic/v7 v7.0.21 h1:58a2pMlLketCsLyKg8kJNJG+OZIFKrSQXX6gJBpqqlg= -github.com/olivere/elastic/v7 v7.0.21/go.mod h1:Kh7iIsXIBl5qRQOBFoylCsXVTtye3keQU2Y/YbR7HD8= +github.com/olivere/elastic/v7 v7.0.22 h1:esBA6JJwvYgfms0EVlH7Z+9J4oQ/WUADF2y/nCNDw7s= +github.com/olivere/elastic/v7 v7.0.22/go.mod h1:VDexNy9NjmtAkrjNoI7tImv7FR4tf5zUA3ickqu5Pc8= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -860,7 +909,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= @@ -882,9 +931,9 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= -github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= +github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ= +github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs= +github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -921,6 +970,10 @@ github.com/quasoft/websspi v1.0.0 h1:5nDgdM5xSur9s+B5w2xQ5kxf5nUGqgFgU4W0aDLZ8Mw github.com/quasoft/websspi v1.0.0/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -975,8 +1028,8 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.3.2 h1:GDarE4TJQI52kYSbSAmLiId1Elfj+xgSDqrUZxFhxlU= -github.com/spf13/afero v1.3.2/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.4.1 h1:asw9sl74539yqavKaglDM5hFpdJVK0Y5Dr/JOgQ89nQ= +github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -990,7 +1043,6 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= @@ -1046,11 +1098,12 @@ github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= -github.com/xanzy/go-gitlab v0.39.0 h1:7aiZ03fJfCdqoHFhsZq/SoVYp2lR91hfYWmiXLOU5Qo= -github.com/xanzy/go-gitlab v0.39.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= +github.com/xanzy/go-gitlab v0.42.0 h1:daNdMFnw2FG+lDRBcX+YLnKbqIKMdefVyVztMHwsFhk= +github.com/xanzy/go-gitlab v0.42.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= @@ -1067,6 +1120,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.1 h1:eVwehsLsZlCJCwXyGLgg+Q4iFWE/eTIMG0e8waCmm/I= +github.com/yuin/goldmark v1.3.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio= github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo= github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM= @@ -1086,8 +1141,9 @@ go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.3.5 h1:S0ZOruh4YGHjD7JoN7mIsTrNjnQbOjrmgrx6l6pZN7I= -go.mongodb.org/mongo-driver v1.3.5/go.mod h1:Ual6Gkco7ZGQw8wE1t4tLnvBsf6yVSM60qW6TgOeJ5c= +go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.4 h1:bsPHfODES+/yx2PCWzUYMH8xj6PVniPI8DQrsJuSXSs= +go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -1095,6 +1151,7 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1122,6 +1179,7 @@ golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1136,8 +1194,9 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201217014255-9d1352758620 h1:3wPMTskHO3+O6jqTEXyFcsnuxMQOqYSaHsDxcbUXpqA= -golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1217,8 +1276,12 @@ golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200930145003-4acb6c075d10/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1227,6 +1290,10 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 h1:Mj83v+wSRNEar42a/MQgxk9X42TdEmrOl9i+y8WbxLo= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013 h1:55H5j7lotzuFCEOKDsMch+fRNUQ9DgtyHOUP31FNqKc= +golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1300,10 +1367,16 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY= -golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1311,17 +1384,20 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1372,16 +1448,18 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20200921210052-fa0125251cc4/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9 h1:sEvmEcJVKBNUvgCUClbUQeHOAa9U0I2Ce1BooMvVCY4= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b h1:Lq5JUTFhiybGVf28jB6QRpqd13/JPOaCnET17PVzYJE= +golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1518,6 +1596,8 @@ gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= diff --git a/vendor/code.gitea.io/sdk/gitea/admin_cron.go b/vendor/code.gitea.io/sdk/gitea/admin_cron.go index 72f77e55ee9b4..99006b696bf28 100644 --- a/vendor/code.gitea.io/sdk/gitea/admin_cron.go +++ b/vendor/code.gitea.io/sdk/gitea/admin_cron.go @@ -25,7 +25,7 @@ type ListCronTaskOptions struct { // ListCronTasks list available cron tasks func (c *Client) ListCronTasks(opt ListCronTaskOptions) ([]*CronTask, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, nil, err } opt.setDefaults() @@ -36,7 +36,7 @@ func (c *Client) ListCronTasks(opt ListCronTaskOptions) ([]*CronTask, *Response, // RunCronTasks run a cron task func (c *Client) RunCronTasks(task string) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, err } _, resp, err := c.getResponse("POST", fmt.Sprintf("/admin/cron/%s", task), jsonHeader, nil) diff --git a/vendor/code.gitea.io/sdk/gitea/client.go b/vendor/code.gitea.io/sdk/gitea/client.go index ca5ee35334a7f..e08bc9edd8467 100644 --- a/vendor/code.gitea.io/sdk/gitea/client.go +++ b/vendor/code.gitea.io/sdk/gitea/client.go @@ -56,7 +56,7 @@ func NewClient(url string, options ...func(*Client)) (*Client, error) { for _, opt := range options { opt(client) } - if err := client.CheckServerVersionConstraint(">=1.10"); err != nil { + if err := client.checkServerVersionGreaterThanOrEqual(version1_10_0); err != nil { return nil, err } return client, nil diff --git a/vendor/code.gitea.io/sdk/gitea/go.mod b/vendor/code.gitea.io/sdk/gitea/go.mod index 7b0d75fd34b57..fe2a46ae06607 100644 --- a/vendor/code.gitea.io/sdk/gitea/go.mod +++ b/vendor/code.gitea.io/sdk/gitea/go.mod @@ -3,6 +3,6 @@ module code.gitea.io/sdk/gitea go 1.12 require ( - github.com/hashicorp/go-version v1.2.0 + github.com/hashicorp/go-version v1.2.1 github.com/stretchr/testify v1.4.0 ) diff --git a/vendor/code.gitea.io/sdk/gitea/issue.go b/vendor/code.gitea.io/sdk/gitea/issue.go index 1b09b3f796284..7eef44711905f 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue.go +++ b/vendor/code.gitea.io/sdk/gitea/issue.go @@ -121,7 +121,7 @@ func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, *Response, error) { link, _ := url.Parse("/repos/issues/search") link.RawQuery = opt.QueryEncode() resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues) - if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { + if e := c.checkServerVersionGreaterThanOrEqual(version1_12_0); e != nil { for i := 0; i < len(issues); i++ { if issues[i].Repository != nil { issues[i].Repository.Owner = strings.Split(issues[i].Repository.FullName, "/")[0] @@ -139,7 +139,7 @@ func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Iss link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues", owner, repo)) link.RawQuery = opt.QueryEncode() resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues) - if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { + if e := c.checkServerVersionGreaterThanOrEqual(version1_12_0); e != nil { for i := 0; i < len(issues); i++ { if issues[i].Repository != nil { issues[i].Repository.Owner = strings.Split(issues[i].Repository.FullName, "/")[0] @@ -153,7 +153,7 @@ func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Iss func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, *Response, error) { issue := new(Issue) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), nil, nil, issue) - if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil && issue.Repository != nil { + if e := c.checkServerVersionGreaterThanOrEqual(version1_12_0); e != nil && issue.Repository != nil { issue.Repository.Owner = strings.Split(issue.Repository.FullName, "/")[0] } return issue, resp, err diff --git a/vendor/code.gitea.io/sdk/gitea/issue_comment.go b/vendor/code.gitea.io/sdk/gitea/issue_comment.go index 50b3532645bb3..4eff850d13f98 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_comment.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_comment.go @@ -68,7 +68,7 @@ func (c *Client) ListRepoIssueComments(owner, repo string, opt ListIssueCommentO // GetIssueComment get a comment for a given repo by id. func (c *Client) GetIssueComment(owner, repo string, id int64) (*Comment, *Response, error) { comment := new(Comment) - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return comment, nil, err } resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, id), nil, nil, &comment) diff --git a/vendor/code.gitea.io/sdk/gitea/issue_label.go b/vendor/code.gitea.io/sdk/gitea/issue_label.go index 1eb3c744f755b..b664dacd1f67c 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_label.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_label.go @@ -71,7 +71,7 @@ func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label, return nil, nil, err } if len(opt.Color) == 6 { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { opt.Color = "#" + opt.Color } } diff --git a/vendor/code.gitea.io/sdk/gitea/issue_reaction.go b/vendor/code.gitea.io/sdk/gitea/issue_reaction.go index a70209a0e3c4d..4ec203c594222 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_reaction.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_reaction.go @@ -20,7 +20,7 @@ type Reaction struct { // GetIssueReactions get a list reactions of an issue func (c *Client) GetIssueReactions(owner, repo string, index int64) ([]*Reaction, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } reactions := make([]*Reaction, 0, 10) @@ -30,7 +30,7 @@ func (c *Client) GetIssueReactions(owner, repo string, index int64) ([]*Reaction // GetIssueCommentReactions get a list of reactions from a comment of an issue func (c *Client) GetIssueCommentReactions(owner, repo string, commentID int64) ([]*Reaction, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } reactions := make([]*Reaction, 0, 10) @@ -45,7 +45,7 @@ type editReactionOption struct { // PostIssueReaction add a reaction to an issue func (c *Client) PostIssueReaction(owner, repo string, index int64, reaction string) (*Reaction, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } reactionResponse := new(Reaction) @@ -61,7 +61,7 @@ func (c *Client) PostIssueReaction(owner, repo string, index int64, reaction str // DeleteIssueReaction remove a reaction from an issue func (c *Client) DeleteIssueReaction(owner, repo string, index int64, reaction string) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, err } body, err := json.Marshal(&editReactionOption{Reaction: reaction}) @@ -74,7 +74,7 @@ func (c *Client) DeleteIssueReaction(owner, repo string, index int64, reaction s // PostIssueCommentReaction add a reaction to a comment of an issue func (c *Client) PostIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Reaction, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } reactionResponse := new(Reaction) @@ -90,7 +90,7 @@ func (c *Client) PostIssueCommentReaction(owner, repo string, commentID int64, r // DeleteIssueCommentReaction remove a reaction from a comment of an issue func (c *Client) DeleteIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, err } body, err := json.Marshal(&editReactionOption{Reaction: reaction}) diff --git a/vendor/code.gitea.io/sdk/gitea/issue_subscription.go b/vendor/code.gitea.io/sdk/gitea/issue_subscription.go index 52e67ed44de74..0af4228c6012a 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_subscription.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_subscription.go @@ -11,7 +11,7 @@ import ( // GetIssueSubscribers get list of users who subscribed on an issue func (c *Client) GetIssueSubscribers(owner, repo string, index int64) ([]*User, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } subscribers := make([]*User, 0, 10) @@ -21,7 +21,7 @@ func (c *Client) GetIssueSubscribers(owner, repo string, index int64) ([]*User, // AddIssueSubscription Subscribe user to issue func (c *Client) AddIssueSubscription(owner, repo string, index int64, user string) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, err } status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil) @@ -39,7 +39,7 @@ func (c *Client) AddIssueSubscription(owner, repo string, index int64, user stri // DeleteIssueSubscription unsubscribe user from issue func (c *Client) DeleteIssueSubscription(owner, repo string, index int64, user string) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, err } status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil) @@ -57,7 +57,7 @@ func (c *Client) DeleteIssueSubscription(owner, repo string, index int64, user s // CheckIssueSubscription check if current user is subscribed to an issue func (c *Client) CheckIssueSubscription(owner, repo string, index int64) (*WatchInfo, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } wi := new(WatchInfo) diff --git a/vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go b/vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go index 481c831d7bc49..9a9922e665095 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go @@ -27,7 +27,7 @@ type TrackedTime struct { // GetUserTrackedTimes list tracked times of a user func (c *Client) GetUserTrackedTimes(owner, repo, user string) ([]*TrackedTime, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } times := make([]*TrackedTime, 0, 10) @@ -37,7 +37,7 @@ func (c *Client) GetUserTrackedTimes(owner, repo, user string) ([]*TrackedTime, // GetRepoTrackedTimes list tracked times of a repository func (c *Client) GetRepoTrackedTimes(owner, repo string) ([]*TrackedTime, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } times := make([]*TrackedTime, 0, 10) @@ -47,7 +47,7 @@ func (c *Client) GetRepoTrackedTimes(owner, repo string) ([]*TrackedTime, *Respo // GetMyTrackedTimes list tracked times of the current user func (c *Client) GetMyTrackedTimes() ([]*TrackedTime, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } times := make([]*TrackedTime, 0, 10) @@ -75,7 +75,7 @@ func (opt AddTimeOption) Validate() error { // AddTime adds time to issue with the given index func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*TrackedTime, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } if err := opt.Validate(); err != nil { @@ -99,7 +99,7 @@ type ListTrackedTimesOptions struct { // ListTrackedTimes list tracked times of a single issue for a given repository func (c *Client) ListTrackedTimes(owner, repo string, index int64, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, nil, err } opt.setDefaults() @@ -110,7 +110,7 @@ func (c *Client) ListTrackedTimes(owner, repo string, index int64, opt ListTrack // ResetIssueTime reset tracked time of a single issue for a given repository func (c *Client) ResetIssueTime(owner, repo string, index int64) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, err } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), nil, nil) @@ -119,7 +119,7 @@ func (c *Client) ResetIssueTime(owner, repo string, index int64) (*Response, err // DeleteTime delete a specific tracked time by id of a single issue for a given repository func (c *Client) DeleteTime(owner, repo string, index, timeID int64) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, err } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times/%d", owner, repo, index, timeID), nil, nil) diff --git a/vendor/code.gitea.io/sdk/gitea/notifications.go b/vendor/code.gitea.io/sdk/gitea/notifications.go index 515a0d4a71280..30b6b6d01c62d 100644 --- a/vendor/code.gitea.io/sdk/gitea/notifications.go +++ b/vendor/code.gitea.io/sdk/gitea/notifications.go @@ -8,6 +8,12 @@ import ( "fmt" "net/url" "time" + + "github.com/hashicorp/go-version" +) + +var ( + version1_12_3, _ = version.NewVersion("1.12.3") ) // NotificationThread expose Notification on API @@ -75,7 +81,7 @@ func (opt *ListNotificationOptions) QueryEncode() string { // Validate the CreateUserOption struct func (opt ListNotificationOptions) Validate(c *Client) error { if len(opt.Status) != 0 { - return c.CheckServerVersionConstraint(">=1.12.3") + return c.checkServerVersionGreaterThanOrEqual(version1_12_3) } return nil } @@ -98,14 +104,14 @@ func (opt *MarkNotificationOptions) QueryEncode() string { // Validate the CreateUserOption struct func (opt MarkNotificationOptions) Validate(c *Client) error { if len(opt.Status) != 0 || len(opt.ToStatus) != 0 { - return c.CheckServerVersionConstraint(">=1.12.3") + return c.checkServerVersionGreaterThanOrEqual(version1_12_3) } return nil } // CheckNotifications list users's notification threads func (c *Client) CheckNotifications() (int64, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return 0, nil, err } new := struct { @@ -118,7 +124,7 @@ func (c *Client) CheckNotifications() (int64, *Response, error) { // GetNotification get notification thread by ID func (c *Client) GetNotification(id int64) (*NotificationThread, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } thread := new(NotificationThread) @@ -129,7 +135,7 @@ func (c *Client) GetNotification(id int64) (*NotificationThread, *Response, erro // ReadNotification mark notification thread as read by ID // It optionally takes a second argument if status has to be set other than 'read' func (c *Client) ReadNotification(id int64, status ...NotifyStatus) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, err } link := fmt.Sprintf("/notifications/threads/%d", id) @@ -142,7 +148,7 @@ func (c *Client) ReadNotification(id int64, status ...NotifyStatus) (*Response, // ListNotifications list users's notification threads func (c *Client) ListNotifications(opt ListNotificationOptions) ([]*NotificationThread, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } if err := opt.Validate(c); err != nil { @@ -157,7 +163,7 @@ func (c *Client) ListNotifications(opt ListNotificationOptions) ([]*Notification // ReadNotifications mark notification threads as read func (c *Client) ReadNotifications(opt MarkNotificationOptions) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, err } if err := opt.Validate(c); err != nil { @@ -171,7 +177,7 @@ func (c *Client) ReadNotifications(opt MarkNotificationOptions) (*Response, erro // ListRepoNotifications list users's notification threads on a specific repo func (c *Client) ListRepoNotifications(owner, reponame string, opt ListNotificationOptions) ([]*NotificationThread, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } if err := opt.Validate(c); err != nil { @@ -186,7 +192,7 @@ func (c *Client) ListRepoNotifications(owner, reponame string, opt ListNotificat // ReadRepoNotifications mark notification threads as read on a specific repo func (c *Client) ReadRepoNotifications(owner, reponame string, opt MarkNotificationOptions) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, err } if err := opt.Validate(c); err != nil { diff --git a/vendor/code.gitea.io/sdk/gitea/oauth2.go b/vendor/code.gitea.io/sdk/gitea/oauth2.go index 80b1547405480..bbdfdafb671be 100644 --- a/vendor/code.gitea.io/sdk/gitea/oauth2.go +++ b/vendor/code.gitea.io/sdk/gitea/oauth2.go @@ -34,7 +34,7 @@ type CreateOauth2Option struct { // CreateOauth2 create an Oauth2 Application and returns a completed Oauth2 object. func (c *Client) CreateOauth2(opt CreateOauth2Option) (*Oauth2, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } body, err := json.Marshal(&opt) @@ -48,7 +48,7 @@ func (c *Client) CreateOauth2(opt CreateOauth2Option) (*Oauth2, *Response, error // UpdateOauth2 a specific Oauth2 Application by ID and return a completed Oauth2 object. func (c *Client) UpdateOauth2(oauth2id int64, opt CreateOauth2Option) (*Oauth2, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } body, err := json.Marshal(&opt) @@ -62,7 +62,7 @@ func (c *Client) UpdateOauth2(oauth2id int64, opt CreateOauth2Option) (*Oauth2, // GetOauth2 a specific Oauth2 Application by ID. func (c *Client) GetOauth2(oauth2id int64) (*Oauth2, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } oauth2s := &Oauth2{} @@ -72,7 +72,7 @@ func (c *Client) GetOauth2(oauth2id int64) (*Oauth2, *Response, error) { // ListOauth2 all of your Oauth2 Applications. func (c *Client) ListOauth2(opt ListOauth2Option) ([]*Oauth2, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } opt.setDefaults() @@ -83,7 +83,7 @@ func (c *Client) ListOauth2(opt ListOauth2Option) ([]*Oauth2, *Response, error) // DeleteOauth2 delete an Oauth2 application by ID func (c *Client) DeleteOauth2(oauth2id int64) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, err } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), nil, nil) diff --git a/vendor/code.gitea.io/sdk/gitea/pull.go b/vendor/code.gitea.io/sdk/gitea/pull.go index 24d70e2fafe5d..c41ab3b01830a 100644 --- a/vendor/code.gitea.io/sdk/gitea/pull.go +++ b/vendor/code.gitea.io/sdk/gitea/pull.go @@ -160,7 +160,7 @@ func (opt EditPullRequestOption) Validate(c *Client) error { return fmt.Errorf("title is empty") } if len(opt.Base) != 0 { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return fmt.Errorf("can not change base gitea to old") } } @@ -229,7 +229,7 @@ func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, *Re // getPullRequestDiffOrPatch gets the patch or diff file as bytes for a PR func (c *Client) getPullRequestDiffOrPatch(owner, repo, kind string, index int64) ([]byte, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { r, _, err2 := c.GetRepo(owner, repo) if err2 != nil { return nil, nil, err diff --git a/vendor/code.gitea.io/sdk/gitea/pull_review.go b/vendor/code.gitea.io/sdk/gitea/pull_review.go index e44dc7df58c93..fc0c22c2d71f3 100644 --- a/vendor/code.gitea.io/sdk/gitea/pull_review.go +++ b/vendor/code.gitea.io/sdk/gitea/pull_review.go @@ -132,7 +132,7 @@ func (opt CreatePullReviewComment) Validate() error { // ListPullReviews lists all reviews of a pull request func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullReviewsOptions) ([]*PullReview, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } opt.setDefaults() @@ -147,7 +147,7 @@ func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullRe // GetPullReview gets a specific review of a pull request func (c *Client) GetPullReview(owner, repo string, index, id int64) (*PullReview, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -158,7 +158,7 @@ func (c *Client) GetPullReview(owner, repo string, index, id int64) (*PullReview // ListPullReviewComments lists all comments of a pull request review func (c *Client) ListPullReviewComments(owner, repo string, index, id int64) ([]*PullReviewComment, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } rcl := make([]*PullReviewComment, 0, 4) @@ -170,7 +170,7 @@ func (c *Client) ListPullReviewComments(owner, repo string, index, id int64) ([] // DeletePullReview delete a specific review from a pull request func (c *Client) DeletePullReview(owner, repo string, index, id int64) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, err } @@ -180,7 +180,7 @@ func (c *Client) DeletePullReview(owner, repo string, index, id int64) (*Respons // CreatePullReview create a review to an pull request func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePullReviewOptions) (*PullReview, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } if err := opt.Validate(); err != nil { @@ -200,7 +200,7 @@ func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePul // SubmitPullReview submit a pending review to an pull request func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt SubmitPullReviewOptions) (*PullReview, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } if err := opt.Validate(); err != nil { diff --git a/vendor/code.gitea.io/sdk/gitea/release.go b/vendor/code.gitea.io/sdk/gitea/release.go index 3440f1c61bb66..d8d28c5bd7d5f 100644 --- a/vendor/code.gitea.io/sdk/gitea/release.go +++ b/vendor/code.gitea.io/sdk/gitea/release.go @@ -57,7 +57,7 @@ func (c *Client) GetRelease(user, repo string, id int64) (*Release, *Response, e // GetReleaseByTag get a release of a repository by tag func (c *Client) GetReleaseByTag(user, repo string, tag string) (*Release, *Response, error) { - if c.CheckServerVersionConstraint(">=1.13.0") != nil { + if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil { return c.fallbackGetReleaseByTag(user, repo, tag) } r := new(Release) diff --git a/vendor/code.gitea.io/sdk/gitea/repo.go b/vendor/code.gitea.io/sdk/gitea/repo.go index c43272487359a..a09f5a651b14d 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo.go +++ b/vendor/code.gitea.io/sdk/gitea/repo.go @@ -73,6 +73,20 @@ const ( RepoTypeMirror RepoType = "mirror" ) +// TrustModel represent how git signatures are handled in a repository +type TrustModel string + +const ( + // TrustModelDefault use TM set by global config + TrustModelDefault TrustModel = "default" + // TrustModelCollaborator gpg signature has to be owned by a repo collaborator + TrustModelCollaborator TrustModel = "collaborator" + // TrustModelCommitter gpg signature has to match committer + TrustModelCommitter TrustModel = "committer" + // TrustModelCollaboratorCommitter gpg signature has to match committer and owned by a repo collaborator + TrustModelCollaboratorCommitter TrustModel = "collaboratorcommitter" +) + // ListReposOptions options for listing repositories type ListReposOptions struct { ListOptions @@ -224,7 +238,7 @@ func (c *Client) SearchRepos(opt SearchRepoOptions) ([]*Repository, *Response, e } else { link.RawQuery = opt.QueryEncode() // IsPrivate only works on gitea >= 1.12.0 - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil && opt.IsPrivate != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil && opt.IsPrivate != nil { if *opt.IsPrivate { // private repos only not supported on gitea <= 1.11.x return nil, nil, err @@ -249,6 +263,8 @@ type CreateRepoOption struct { IssueLabels string `json:"issue_labels"` // Whether the repository should be auto-intialized? AutoInit bool `json:"auto_init"` + // Whether the repository is template + Template bool `json:"template"` // Gitignores to use Gitignores string `json:"gitignores"` // License to use @@ -257,19 +273,35 @@ type CreateRepoOption struct { Readme string `json:"readme"` // DefaultBranch of the repository (used when initializes and in template) DefaultBranch string `json:"default_branch"` + // TrustModel of the repository + TrustModel TrustModel `json:"trust_model"` } // Validate the CreateRepoOption struct -func (opt CreateRepoOption) Validate() error { +func (opt CreateRepoOption) Validate(c *Client) error { if len(strings.TrimSpace(opt.Name)) == 0 { return fmt.Errorf("name is empty") } + if len(opt.Name) > 100 { + return fmt.Errorf("name has more than 100 chars") + } + if len(opt.Description) > 255 { + return fmt.Errorf("name has more than 255 chars") + } + if len(opt.DefaultBranch) > 100 { + return fmt.Errorf("name has more than 100 chars") + } + if len(opt.TrustModel) != 0 { + if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + return err + } + } return nil } // CreateRepo creates a repository for authenticated user. func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, *Response, error) { - if err := opt.Validate(); err != nil { + if err := opt.Validate(c); err != nil { return nil, nil, err } body, err := json.Marshal(&opt) @@ -283,7 +315,7 @@ func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, *Response, error // CreateOrgRepo creates an organization repository for authenticated user. func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, *Response, error) { - if err := opt.Validate(); err != nil { + if err := opt.Validate(c); err != nil { return nil, nil, err } body, err := json.Marshal(&opt) diff --git a/vendor/code.gitea.io/sdk/gitea/repo_branch.go b/vendor/code.gitea.io/sdk/gitea/repo_branch.go index 0d6249e7d014b..6b0eec27e9805 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_branch.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_branch.go @@ -84,7 +84,7 @@ func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, *Response, e // DeleteRepoBranch delete a branch in a repository func (c *Client) DeleteRepoBranch(user, repo, branch string) (bool, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return false, nil, err } status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil) @@ -118,7 +118,7 @@ func (opt CreateBranchOption) Validate() error { // CreateBranch creates a branch for a user's repository func (c *Client) CreateBranch(owner, repo string, opt CreateBranchOption) (*Branch, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, nil, err } if err := opt.Validate(); err != nil { diff --git a/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go b/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go index f4d47deda3000..1e520807a1228 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go @@ -92,7 +92,7 @@ type ListBranchProtectionsOptions struct { // ListBranchProtections list branch protections for a repo func (c *Client) ListBranchProtections(owner, repo string, opt ListBranchProtectionsOptions) ([]*BranchProtection, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } bps := make([]*BranchProtection, 0, opt.PageSize) @@ -104,7 +104,7 @@ func (c *Client) ListBranchProtections(owner, repo string, opt ListBranchProtect // GetBranchProtection gets a branch protection func (c *Client) GetBranchProtection(owner, repo, name string) (*BranchProtection, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } bp := new(BranchProtection) @@ -114,7 +114,7 @@ func (c *Client) GetBranchProtection(owner, repo, name string) (*BranchProtectio // CreateBranchProtection creates a branch protection for a repo func (c *Client) CreateBranchProtection(owner, repo string, opt CreateBranchProtectionOption) (*BranchProtection, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } bp := new(BranchProtection) @@ -128,7 +128,7 @@ func (c *Client) CreateBranchProtection(owner, repo string, opt CreateBranchProt // EditBranchProtection edits a branch protection for a repo func (c *Client) EditBranchProtection(owner, repo, name string, opt EditBranchProtectionOption) (*BranchProtection, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } bp := new(BranchProtection) @@ -142,7 +142,7 @@ func (c *Client) EditBranchProtection(owner, repo, name string, opt EditBranchPr // DeleteBranchProtection deletes a branch protection for a repo func (c *Client) DeleteBranchProtection(owner, repo, name string) (*Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, err } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, nil) diff --git a/vendor/code.gitea.io/sdk/gitea/repo_commit.go b/vendor/code.gitea.io/sdk/gitea/repo_commit.go index e17d0030b9dd9..4b90b9cb65b4f 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_commit.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_commit.go @@ -19,8 +19,9 @@ type Identity struct { // CommitMeta contains meta information of a commit in terms of API. type CommitMeta struct { - URL string `json:"url"` - SHA string `json:"sha"` + URL string `json:"url"` + SHA string `json:"sha"` + Created time.Time `json:"created"` } // CommitUser contains information of a user in the context of a commit. diff --git a/vendor/code.gitea.io/sdk/gitea/repo_file.go b/vendor/code.gitea.io/sdk/gitea/repo_file.go index 94f216fdf9560..b104980a8d287 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_file.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_file.go @@ -182,7 +182,7 @@ func (c *Client) DeleteFile(owner, repo, filepath string, opt DeleteFileOptions) func (c *Client) setDefaultBranchForOldVersions(owner, repo, branch string) (string, error) { if len(branch) == 0 { // Gitea >= 1.12.0 Use DefaultBranch on "", mimic this for older versions - if c.CheckServerVersionConstraint(">=1.12.0") != nil { + if c.checkServerVersionGreaterThanOrEqual(version1_12_0) != nil { r, _, err := c.GetRepo(owner, repo) if err != nil { return "", err diff --git a/vendor/code.gitea.io/sdk/gitea/repo_migrate.go b/vendor/code.gitea.io/sdk/gitea/repo_migrate.go index 583d800d36ff3..518c6ae649e66 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_migrate.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_migrate.go @@ -20,10 +20,10 @@ const ( GitServiceGithub GitServiceType = "github" // GitServiceGitlab represents a gitlab service GitServiceGitlab GitServiceType = "gitlab" + // GitServiceGitea represents a gitea service + GitServiceGitea GitServiceType = "gitea" // Not supported jet - // // GitServiceGitea represents a gitea service - // GitServiceGitea GitServiceType = "gitea" // // GitServiceGogs represents a gogs service // GitServiceGogs GitServiceType = "gogs" ) @@ -51,7 +51,7 @@ type MigrateRepoOption struct { } // Validate the MigrateRepoOption struct -func (opt *MigrateRepoOption) Validate() error { +func (opt *MigrateRepoOption) Validate(c *Client) error { // check user options if len(opt.CloneAddr) == 0 { return fmt.Errorf("CloneAddr required") @@ -69,6 +69,15 @@ func (opt *MigrateRepoOption) Validate() error { if len(opt.AuthToken) == 0 { return fmt.Errorf("github require token authentication") } + case GitServiceGitlab, GitServiceGitea: + if len(opt.AuthToken) == 0 { + return fmt.Errorf("%s require token authentication", opt.Service) + } + // Gitlab is supported since 1.12.0 but api cant handle it until 1.13.0 + // https://github.com/go-gitea/gitea/pull/12672 + if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil { + return fmt.Errorf("migrate from service %s need gitea >= 1.13.0", opt.Service) + } } return nil } @@ -78,11 +87,11 @@ func (opt *MigrateRepoOption) Validate() error { // To migrate a repository for a organization, the authenticated user must be a // owner of the specified organization. func (c *Client) MigrateRepo(opt MigrateRepoOption) (*Repository, *Response, error) { - if err := opt.Validate(); err != nil { + if err := opt.Validate(c); err != nil { return nil, nil, err } - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { if len(opt.AuthToken) != 0 { // gitea <= 1.12 dont understand AuthToken opt.AuthUsername = opt.AuthToken diff --git a/vendor/code.gitea.io/sdk/gitea/repo_transfer.go b/vendor/code.gitea.io/sdk/gitea/repo_transfer.go index aedb0e52690dc..d8d661bc441d9 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_transfer.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_transfer.go @@ -20,7 +20,7 @@ type TransferRepoOption struct { // TransferRepo transfers the ownership of a repository func (c *Client) TransferRepo(owner, reponame string, opt TransferRepoOption) (*Repository, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } body, err := json.Marshal(&opt) diff --git a/vendor/code.gitea.io/sdk/gitea/settings.go b/vendor/code.gitea.io/sdk/gitea/settings.go index 9c39e4e215e1d..9fa0a7ae7e95e 100644 --- a/vendor/code.gitea.io/sdk/gitea/settings.go +++ b/vendor/code.gitea.io/sdk/gitea/settings.go @@ -33,7 +33,7 @@ type GlobalAttachmentSettings struct { // GetGlobalUISettings get global ui settings witch are exposed by API func (c *Client) GetGlobalUISettings() (*GlobalUISettings, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, nil, err } conf := new(GlobalUISettings) @@ -43,7 +43,7 @@ func (c *Client) GetGlobalUISettings() (*GlobalUISettings, *Response, error) { // GetGlobalRepoSettings get global repository settings witch are exposed by API func (c *Client) GetGlobalRepoSettings() (*GlobalRepoSettings, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, nil, err } conf := new(GlobalRepoSettings) @@ -53,7 +53,7 @@ func (c *Client) GetGlobalRepoSettings() (*GlobalRepoSettings, *Response, error) // GetGlobalAPISettings get global api settings witch are exposed by it func (c *Client) GetGlobalAPISettings() (*GlobalAPISettings, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, nil, err } conf := new(GlobalAPISettings) @@ -63,7 +63,7 @@ func (c *Client) GetGlobalAPISettings() (*GlobalAPISettings, *Response, error) { // GetGlobalAttachmentSettings get global repository settings witch are exposed by API func (c *Client) GetGlobalAttachmentSettings() (*GlobalAttachmentSettings, *Response, error) { - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, nil, err } conf := new(GlobalAttachmentSettings) diff --git a/vendor/code.gitea.io/sdk/gitea/version.go b/vendor/code.gitea.io/sdk/gitea/version.go index 57c64dc4107fe..747117ccc2723 100644 --- a/vendor/code.gitea.io/sdk/gitea/version.go +++ b/vendor/code.gitea.io/sdk/gitea/version.go @@ -42,6 +42,32 @@ func (c *Client) CheckServerVersionConstraint(constraint string) error { return nil } +// predefined versions only have to be parsed by library once +var ( + version1_10_0, _ = version.NewVersion("1.10.0") + version1_11_0, _ = version.NewVersion("1.11.0") + version1_12_0, _ = version.NewVersion("1.12.0") + version1_13_0, _ = version.NewVersion("1.13.0") +) + +// checkServerVersionGreaterThanOrEqual is internally used to speed up things and ignore issues with prerelease +func (c *Client) checkServerVersionGreaterThanOrEqual(v *version.Version) error { + c.versionLock.RLock() + if c.serverVersion == nil { + c.versionLock.RUnlock() + if err := c.loadClientServerVersion(); err != nil { + return err + } + } else { + c.versionLock.RUnlock() + } + + if !c.serverVersion.GreaterThanOrEqual(v) { + return fmt.Errorf("gitea server at %s is older than %s", c.url, v.Original()) + } + return nil +} + // loadClientServerVersion init the serverVersion variable func (c *Client) loadClientServerVersion() error { c.versionLock.Lock() diff --git a/vendor/github.com/asaskevich/govalidator/.travis.yml b/vendor/github.com/asaskevich/govalidator/.travis.yml index 17c4d0a710716..bb83c6670df63 100644 --- a/vendor/github.com/asaskevich/govalidator/.travis.yml +++ b/vendor/github.com/asaskevich/govalidator/.travis.yml @@ -1,18 +1,12 @@ -dist: bionic language: go -env: GO111MODULE=on GOFLAGS='-mod vendor' -install: true -email: false - +dist: xenial go: - - 1.10 - - 1.11 - - 1.12 - - 1.13 - - tip + - '1.10' + - '1.11' + - '1.12' + - '1.13' + - 'tip' -before_script: - - go install github.com/golangci/golangci-lint/cmd/golangci-lint script: - - golangci-lint run # run a bunch of code checkers/linters in parallel - - go test -v -race ./... # Run all the tests with the race detector enabled + - go test -coverpkg=./... -coverprofile=coverage.info -timeout=5s + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md b/vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000000..4b462b0d81b17 --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md @@ -0,0 +1,43 @@ +# Contributor Code of Conduct + +This project adheres to [The Code Manifesto](http://codemanifesto.com) +as its guidelines for contributor interactions. + +## The Code Manifesto + +We want to work in an ecosystem that empowers developers to reach their +potential — one that encourages growth and effective collaboration. A space +that is safe for all. + +A space such as this benefits everyone that participates in it. It encourages +new developers to enter our field. It is through discussion and collaboration +that we grow, and through growth that we improve. + +In the effort to create such a place, we hold to these values: + +1. **Discrimination limits us.** This includes discrimination on the basis of + race, gender, sexual orientation, gender identity, age, nationality, + technology and any other arbitrary exclusion of a group of people. +2. **Boundaries honor us.** Your comfort levels are not everyone’s comfort + levels. Remember that, and if brought to your attention, heed it. +3. **We are our biggest assets.** None of us were born masters of our trade. + Each of us has been helped along the way. Return that favor, when and where + you can. +4. **We are resources for the future.** As an extension of #3, share what you + know. Make yourself a resource to help those that come after you. +5. **Respect defines us.** Treat others as you wish to be treated. Make your + discussions, criticisms and debates from a position of respectfulness. Ask + yourself, is it true? Is it necessary? Is it constructive? Anything less is + unacceptable. +6. **Reactions require grace.** Angry responses are valid, but abusive language + and vindictive actions are toxic. When something happens that offends you, + handle it assertively, but be respectful. Escalate reasonably, and try to + allow the offender an opportunity to explain themselves, and possibly + correct the issue. +7. **Opinions are just that: opinions.** Each and every one of us, due to our + background and upbringing, have varying opinions. That is perfectly + acceptable. Remember this: if you respect your own opinions, you should + respect the opinions of others. +8. **To err is human.** You might not intend it, but mistakes do happen and + contribute to build experience. Tolerate honest mistakes, and don't + hesitate to apologize if you make one yourself. diff --git a/vendor/github.com/asaskevich/govalidator/LICENSE b/vendor/github.com/asaskevich/govalidator/LICENSE index 2f9a31fadf678..cacba91024000 100644 --- a/vendor/github.com/asaskevich/govalidator/LICENSE +++ b/vendor/github.com/asaskevich/govalidator/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Alex Saskevich +Copyright (c) 2014-2020 Alex Saskevich Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/asaskevich/govalidator/README.md b/vendor/github.com/asaskevich/govalidator/README.md index 78f999e83417f..39121ea8e37c2 100644 --- a/vendor/github.com/asaskevich/govalidator/README.md +++ b/vendor/github.com/asaskevich/govalidator/README.md @@ -1,7 +1,8 @@ govalidator =========== -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![GoDoc](https://godoc.org/github.com/asaskevich/govalidator?status.png)](https://godoc.org/github.com/asaskevich/govalidator) [![Coverage Status](https://img.shields.io/coveralls/asaskevich/govalidator.svg)](https://coveralls.io/r/asaskevich/govalidator?branch=master) [![wercker status](https://app.wercker.com/status/1ec990b09ea86c910d5f08b0e02c6043/s "wercker status")](https://app.wercker.com/project/bykey/1ec990b09ea86c910d5f08b0e02c6043) -[![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator) [![Go Report Card](https://goreportcard.com/badge/github.com/asaskevich/govalidator)](https://goreportcard.com/report/github.com/asaskevich/govalidator) [![GoSearch](http://go-search.org/badge?id=github.com%2Fasaskevich%2Fgovalidator)](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [![Backers on Open Collective](https://opencollective.com/govalidator/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/govalidator/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield) +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![GoDoc](https://godoc.org/github.com/asaskevich/govalidator?status.png)](https://godoc.org/github.com/asaskevich/govalidator) +[![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator) +[![Coverage](https://codecov.io/gh/asaskevich/govalidator/branch/master/graph/badge.svg)](https://codecov.io/gh/asaskevich/govalidator) [![Go Report Card](https://goreportcard.com/badge/github.com/asaskevich/govalidator)](https://goreportcard.com/report/github.com/asaskevich/govalidator) [![GoSearch](http://go-search.org/badge?id=github.com%2Fasaskevich%2Fgovalidator)](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [![Backers on Open Collective](https://opencollective.com/govalidator/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/govalidator/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield) A package of validators and sanitizers for strings, structs and collections. Based on [validator.js](https://github.com/chriso/validator.js). @@ -279,7 +280,7 @@ type User struct { Age int `valid:"type(int)"` Meta interface{} `valid:"type(string)"` } -result, err := govalidator.ValidateStruct(user{"Bob", 20, "meta"}) +result, err := govalidator.ValidateStruct(User{"Bob", 20, "meta"}) if err != nil { println("error: " + err.Error()) } @@ -392,6 +393,8 @@ Validators with parameters "matches(pattern)": StringMatches, "in(string1|string2|...|stringN)": IsIn, "rsapub(keylength)" : IsRsaPub, +"minstringlength(int): MinStringLength, +"maxstringlength(int): MaxStringLength, ``` Validators with parameters for any type diff --git a/vendor/github.com/asaskevich/govalidator/arrays.go b/vendor/github.com/asaskevich/govalidator/arrays.go index 5bace2654d3bc..3e1da7cb480eb 100644 --- a/vendor/github.com/asaskevich/govalidator/arrays.go +++ b/vendor/github.com/asaskevich/govalidator/arrays.go @@ -9,6 +9,35 @@ type ResultIterator func(interface{}, int) interface{} // ConditionIterator is the function that accepts element of slice/array and its index and returns boolean type ConditionIterator func(interface{}, int) bool +// ReduceIterator is the function that accepts two element of slice/array and returns result of merging those values +type ReduceIterator func(interface{}, interface{}) interface{} + +// Some validates that any item of array corresponds to ConditionIterator. Returns boolean. +func Some(array []interface{}, iterator ConditionIterator) bool { + res := false + for index, data := range array { + res = res || iterator(data, index) + } + return res +} + +// Every validates that every item of array corresponds to ConditionIterator. Returns boolean. +func Every(array []interface{}, iterator ConditionIterator) bool { + res := true + for index, data := range array { + res = res && iterator(data, index) + } + return res +} + +// Reduce boils down a list of values into a single value by ReduceIterator +func Reduce(array []interface{}, iterator ReduceIterator, initialValue interface{}) interface{} { + for _, data := range array { + initialValue = iterator(initialValue, data) + } + return initialValue +} + // Each iterates over the slice and apply Iterator to every item func Each(array []interface{}, iterator Iterator) { for index, data := range array { diff --git a/vendor/github.com/asaskevich/govalidator/converter.go b/vendor/github.com/asaskevich/govalidator/converter.go index cf1e5d569ba01..d68e990fc256f 100644 --- a/vendor/github.com/asaskevich/govalidator/converter.go +++ b/vendor/github.com/asaskevich/govalidator/converter.go @@ -10,7 +10,7 @@ import ( // ToString convert the input to a string. func ToString(obj interface{}) string { res := fmt.Sprintf("%v", obj) - return string(res) + return res } // ToJSON convert the input to a valid JSON string @@ -23,12 +23,27 @@ func ToJSON(obj interface{}) (string, error) { } // ToFloat convert the input string to a float, or 0.0 if the input is not a float. -func ToFloat(str string) (float64, error) { - res, err := strconv.ParseFloat(str, 64) - if err != nil { - res = 0.0 +func ToFloat(value interface{}) (res float64, err error) { + val := reflect.ValueOf(value) + + switch value.(type) { + case int, int8, int16, int32, int64: + res = float64(val.Int()) + case uint, uint8, uint16, uint32, uint64: + res = float64(val.Uint()) + case float32, float64: + res = val.Float() + case string: + res, err = strconv.ParseFloat(val.String(), 64) + if err != nil { + res = 0 + } + default: + err = fmt.Errorf("ToInt: unknown interface type %T", value) + res = 0 } - return res, err + + return } // ToInt convert the input string or any int type to an integer type 64, or 0 if the input is not an integer. @@ -40,6 +55,8 @@ func ToInt(value interface{}) (res int64, err error) { res = val.Int() case uint, uint8, uint16, uint32, uint64: res = int64(val.Uint()) + case float32, float64: + res = int64(val.Float()) case string: if IsInt(val.String()) { res, err = strconv.ParseInt(val.String(), 0, 64) @@ -47,11 +64,11 @@ func ToInt(value interface{}) (res int64, err error) { res = 0 } } else { - err = fmt.Errorf("math: square root of negative number %g", value) + err = fmt.Errorf("ToInt: invalid numeric format %g", value) res = 0 } default: - err = fmt.Errorf("math: square root of negative number %g", value) + err = fmt.Errorf("ToInt: unknown interface type %T", value) res = 0 } diff --git a/vendor/github.com/asaskevich/govalidator/go.mod b/vendor/github.com/asaskevich/govalidator/go.mod index c1ce891dfa031..42d5b1f638577 100644 --- a/vendor/github.com/asaskevich/govalidator/go.mod +++ b/vendor/github.com/asaskevich/govalidator/go.mod @@ -1,3 +1,3 @@ module github.com/asaskevich/govalidator -go 1.12 +go 1.13 diff --git a/vendor/github.com/asaskevich/govalidator/numerics.go b/vendor/github.com/asaskevich/govalidator/numerics.go index 7e6c652e140c6..5041d9e86844c 100644 --- a/vendor/github.com/asaskevich/govalidator/numerics.go +++ b/vendor/github.com/asaskevich/govalidator/numerics.go @@ -2,7 +2,6 @@ package govalidator import ( "math" - "reflect" ) // Abs returns absolute value of number @@ -41,7 +40,7 @@ func IsNonPositive(value float64) bool { return value <= 0 } -// InRange returns true if value lies between left and right border +// InRangeInt returns true if value lies between left and right border func InRangeInt(value, left, right interface{}) bool { value64, _ := ToInt(value) left64, _ := ToInt(left) @@ -52,7 +51,7 @@ func InRangeInt(value, left, right interface{}) bool { return value64 >= left64 && value64 <= right64 } -// InRange returns true if value lies between left and right border +// InRangeFloat32 returns true if value lies between left and right border func InRangeFloat32(value, left, right float32) bool { if left > right { left, right = right, left @@ -60,7 +59,7 @@ func InRangeFloat32(value, left, right float32) bool { return value >= left && value <= right } -// InRange returns true if value lies between left and right border +// InRangeFloat64 returns true if value lies between left and right border func InRangeFloat64(value, left, right float64) bool { if left > right { left, right = right, left @@ -68,20 +67,24 @@ func InRangeFloat64(value, left, right float64) bool { return value >= left && value <= right } -// InRange returns true if value lies between left and right border, generic type to handle int, float32 or float64, all types must the same type +// InRange returns true if value lies between left and right border, generic type to handle int, float32, float64 and string. +// All types must the same type. +// False if value doesn't lie in range or if it incompatible or not comparable func InRange(value interface{}, left interface{}, right interface{}) bool { - - reflectValue := reflect.TypeOf(value).Kind() - reflectLeft := reflect.TypeOf(left).Kind() - reflectRight := reflect.TypeOf(right).Kind() - - if reflectValue == reflect.Int && reflectLeft == reflect.Int && reflectRight == reflect.Int { - return InRangeInt(value.(int), left.(int), right.(int)) - } else if reflectValue == reflect.Float32 && reflectLeft == reflect.Float32 && reflectRight == reflect.Float32 { - return InRangeFloat32(value.(float32), left.(float32), right.(float32)) - } else if reflectValue == reflect.Float64 && reflectLeft == reflect.Float64 && reflectRight == reflect.Float64 { - return InRangeFloat64(value.(float64), left.(float64), right.(float64)) - } else { + switch value.(type) { + case int: + intValue, _ := ToInt(value) + intLeft, _ := ToInt(left) + intRight, _ := ToInt(right) + return InRangeInt(intValue, intLeft, intRight) + case float32, float64: + intValue, _ := ToFloat(value) + intLeft, _ := ToFloat(left) + intRight, _ := ToFloat(right) + return InRangeFloat64(intValue, intLeft, intRight) + case string: + return value.(string) >= left.(string) && value.(string) <= right.(string) + default: return false } } diff --git a/vendor/github.com/asaskevich/govalidator/patterns.go b/vendor/github.com/asaskevich/govalidator/patterns.go index e55451cff5720..106ed94f80ad0 100644 --- a/vendor/github.com/asaskevich/govalidator/patterns.go +++ b/vendor/github.com/asaskevich/govalidator/patterns.go @@ -38,7 +38,7 @@ const ( URLPort string = `(:(\d{1,5}))` URLIP string = `([1-9]\d?|1\d\d|2[01]\d|22[0-3]|24\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-5]))` URLSubdomain string = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))` - URL string = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$` + URL = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$` SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$` WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$` UnixPath string = `^(/[^/\x00]*)+/?$` @@ -49,6 +49,7 @@ const ( hasWhitespace string = ".*[[:space:]]" hasWhitespaceOnly string = "^[[:space:]]+$" IMEI string = "^[0-9a-f]{14}$|^\\d{15}$|^\\d{18}$" + IMSI string = "^\\d{14,15}$" ) // Used by IsFilePath func @@ -102,4 +103,5 @@ var ( rxHasWhitespace = regexp.MustCompile(hasWhitespace) rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly) rxIMEI = regexp.MustCompile(IMEI) + rxIMSI = regexp.MustCompile(IMSI) ) diff --git a/vendor/github.com/asaskevich/govalidator/types.go b/vendor/github.com/asaskevich/govalidator/types.go index b57b666f57c36..54218bf05a2fd 100644 --- a/vendor/github.com/asaskevich/govalidator/types.go +++ b/vendor/github.com/asaskevich/govalidator/types.go @@ -14,8 +14,10 @@ type Validator func(str string) bool // The second parameter should be the context (in the case of validating a struct: the whole object being validated). type CustomTypeValidator func(i interface{}, o interface{}) bool -// ParamValidator is a wrapper for validator functions that accepts additional parameters. +// ParamValidator is a wrapper for validator functions that accept additional parameters. type ParamValidator func(str string, params ...string) bool + +// InterfaceParamValidator is a wrapper for functions that accept variants parameters for an interface value type InterfaceParamValidator func(in interface{}, params ...string) bool type tagOptionsMap map[string]tagOption @@ -72,13 +74,13 @@ var ParamTagMap = map[string]ParamValidator{ // ParamTagRegexMap maps param tags to their respective regexes. var ParamTagRegexMap = map[string]*regexp.Regexp{ - "range": regexp.MustCompile("^range\\((\\d+)\\|(\\d+)\\)$"), - "length": regexp.MustCompile("^length\\((\\d+)\\|(\\d+)\\)$"), - "runelength": regexp.MustCompile("^runelength\\((\\d+)\\|(\\d+)\\)$"), - "stringlength": regexp.MustCompile("^stringlength\\((\\d+)\\|(\\d+)\\)$"), - "in": regexp.MustCompile(`^in\((.*)\)`), - "matches": regexp.MustCompile(`^matches\((.+)\)$`), - "rsapub": regexp.MustCompile("^rsapub\\((\\d+)\\)$"), + "range": regexp.MustCompile("^range\\((\\d+)\\|(\\d+)\\)$"), + "length": regexp.MustCompile("^length\\((\\d+)\\|(\\d+)\\)$"), + "runelength": regexp.MustCompile("^runelength\\((\\d+)\\|(\\d+)\\)$"), + "stringlength": regexp.MustCompile("^stringlength\\((\\d+)\\|(\\d+)\\)$"), + "in": regexp.MustCompile(`^in\((.*)\)`), + "matches": regexp.MustCompile(`^matches\((.+)\)$`), + "rsapub": regexp.MustCompile("^rsapub\\((\\d+)\\)$"), "minstringlength": regexp.MustCompile("^minstringlength\\((\\d+)\\)$"), "maxstringlength": regexp.MustCompile("^maxstringlength\\((\\d+)\\)$"), } @@ -447,10 +449,10 @@ var ISO4217List = []string{ "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "RSD", "RUB", "RWF", - "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "SVC", "SYP", "SZL", + "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "STN", "SVC", "SYP", "SZL", "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", - "UAH", "UGX", "USD", "USN", "UYI", "UYU", "UZS", - "VEF", "VND", "VUV", + "UAH", "UGX", "USD", "USN", "UYI", "UYU", "UYW", "UZS", + "VEF", "VES", "VND", "VUV", "WST", "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XTS", "XUA", "XXX", "YER", diff --git a/vendor/github.com/asaskevich/govalidator/validator.go b/vendor/github.com/asaskevich/govalidator/validator.go index 298f9920d38a3..5c918fc4bc7de 100644 --- a/vendor/github.com/asaskevich/govalidator/validator.go +++ b/vendor/github.com/asaskevich/govalidator/validator.go @@ -32,7 +32,7 @@ var ( const maxURLRuneCount = 2083 const minURLRuneCount = 3 -const RF3339WithoutZone = "2006-01-02T15:04:05" +const rfc3339WithoutZone = "2006-01-02T15:04:05" // SetFieldsRequiredByDefault causes validation to fail when struct fields // do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). @@ -63,13 +63,13 @@ func SetNilPtrAllowedByRequired(value bool) { nilPtrAllowedByRequired = value } -// IsEmail check if the string is an email. +// IsEmail checks if the string is an email. func IsEmail(str string) bool { // TODO uppercase letters are not supported return rxEmail.MatchString(str) } -// IsExistingEmail check if the string is an email of existing domain +// IsExistingEmail checks if the string is an email of existing domain func IsExistingEmail(email string) bool { if len(email) < 6 || len(email) > 254 { @@ -84,13 +84,13 @@ func IsExistingEmail(email string) bool { if len(user) > 64 { return false } - if userDotRegexp.MatchString(user) || !userRegexp.MatchString(user) || !hostRegexp.MatchString(host) { - return false - } switch host { case "localhost", "example.com": return true } + if userDotRegexp.MatchString(user) || !userRegexp.MatchString(user) || !hostRegexp.MatchString(host) { + return false + } if _, err := net.LookupMX(host); err != nil { if _, err := net.LookupIP(host); err != nil { return false @@ -100,7 +100,7 @@ func IsExistingEmail(email string) bool { return true } -// IsURL check if the string is an URL. +// IsURL checks if the string is an URL. func IsURL(str string) bool { if str == "" || utf8.RuneCountInString(str) >= maxURLRuneCount || len(str) <= minURLRuneCount || strings.HasPrefix(str, ".") { return false @@ -124,7 +124,7 @@ func IsURL(str string) bool { return rxURL.MatchString(str) } -// IsRequestURL check if the string rawurl, assuming +// IsRequestURL checks if the string rawurl, assuming // it was received in an HTTP request, is a valid // URL confirm to RFC 3986 func IsRequestURL(rawurl string) bool { @@ -138,7 +138,7 @@ func IsRequestURL(rawurl string) bool { return true } -// IsRequestURI check if the string rawurl, assuming +// IsRequestURI checks if the string rawurl, assuming // it was received in an HTTP request, is an // absolute URI or an absolute path. func IsRequestURI(rawurl string) bool { @@ -146,7 +146,7 @@ func IsRequestURI(rawurl string) bool { return err == nil } -// IsAlpha check if the string contains only letters (a-zA-Z). Empty string is valid. +// IsAlpha checks if the string contains only letters (a-zA-Z). Empty string is valid. func IsAlpha(str string) bool { if IsNull(str) { return true @@ -154,7 +154,7 @@ func IsAlpha(str string) bool { return rxAlpha.MatchString(str) } -//IsUTFLetter check if the string contains only unicode letter characters. +//IsUTFLetter checks if the string contains only unicode letter characters. //Similar to IsAlpha but for all languages. Empty string is valid. func IsUTFLetter(str string) bool { if IsNull(str) { @@ -170,7 +170,7 @@ func IsUTFLetter(str string) bool { } -// IsAlphanumeric check if the string contains only letters and numbers. Empty string is valid. +// IsAlphanumeric checks if the string contains only letters and numbers. Empty string is valid. func IsAlphanumeric(str string) bool { if IsNull(str) { return true @@ -178,7 +178,7 @@ func IsAlphanumeric(str string) bool { return rxAlphanumeric.MatchString(str) } -// IsUTFLetterNumeric check if the string contains only unicode letters and numbers. Empty string is valid. +// IsUTFLetterNumeric checks if the string contains only unicode letters and numbers. Empty string is valid. func IsUTFLetterNumeric(str string) bool { if IsNull(str) { return true @@ -192,7 +192,7 @@ func IsUTFLetterNumeric(str string) bool { } -// IsNumeric check if the string contains only numbers. Empty string is valid. +// IsNumeric checks if the string contains only numbers. Empty string is valid. func IsNumeric(str string) bool { if IsNull(str) { return true @@ -200,7 +200,7 @@ func IsNumeric(str string) bool { return rxNumeric.MatchString(str) } -// IsUTFNumeric check if the string contains only unicode numbers of any kind. +// IsUTFNumeric checks if the string contains only unicode numbers of any kind. // Numbers can be 0-9 but also Fractions ¾,Roman Ⅸ and Hangzhou 〩. Empty string is valid. func IsUTFNumeric(str string) bool { if IsNull(str) { @@ -222,7 +222,7 @@ func IsUTFNumeric(str string) bool { } -// IsUTFDigit check if the string contains only unicode radix-10 decimal digits. Empty string is valid. +// IsUTFDigit checks if the string contains only unicode radix-10 decimal digits. Empty string is valid. func IsUTFDigit(str string) bool { if IsNull(str) { return true @@ -243,22 +243,22 @@ func IsUTFDigit(str string) bool { } -// IsHexadecimal check if the string is a hexadecimal number. +// IsHexadecimal checks if the string is a hexadecimal number. func IsHexadecimal(str string) bool { return rxHexadecimal.MatchString(str) } -// IsHexcolor check if the string is a hexadecimal color. +// IsHexcolor checks if the string is a hexadecimal color. func IsHexcolor(str string) bool { return rxHexcolor.MatchString(str) } -// IsRGBcolor check if the string is a valid RGB color in form rgb(RRR, GGG, BBB). +// IsRGBcolor checks if the string is a valid RGB color in form rgb(RRR, GGG, BBB). func IsRGBcolor(str string) bool { return rxRGBcolor.MatchString(str) } -// IsLowerCase check if the string is lowercase. Empty string is valid. +// IsLowerCase checks if the string is lowercase. Empty string is valid. func IsLowerCase(str string) bool { if IsNull(str) { return true @@ -266,7 +266,7 @@ func IsLowerCase(str string) bool { return str == strings.ToLower(str) } -// IsUpperCase check if the string is uppercase. Empty string is valid. +// IsUpperCase checks if the string is uppercase. Empty string is valid. func IsUpperCase(str string) bool { if IsNull(str) { return true @@ -274,7 +274,7 @@ func IsUpperCase(str string) bool { return str == strings.ToUpper(str) } -// HasLowerCase check if the string contains at least 1 lowercase. Empty string is valid. +// HasLowerCase checks if the string contains at least 1 lowercase. Empty string is valid. func HasLowerCase(str string) bool { if IsNull(str) { return true @@ -282,7 +282,7 @@ func HasLowerCase(str string) bool { return rxHasLowerCase.MatchString(str) } -// HasUpperCase check if the string contains as least 1 uppercase. Empty string is valid. +// HasUpperCase checks if the string contains as least 1 uppercase. Empty string is valid. func HasUpperCase(str string) bool { if IsNull(str) { return true @@ -290,7 +290,7 @@ func HasUpperCase(str string) bool { return rxHasUpperCase.MatchString(str) } -// IsInt check if the string is an integer. Empty string is valid. +// IsInt checks if the string is an integer. Empty string is valid. func IsInt(str string) bool { if IsNull(str) { return true @@ -298,12 +298,12 @@ func IsInt(str string) bool { return rxInt.MatchString(str) } -// IsFloat check if the string is a float. +// IsFloat checks if the string is a float. func IsFloat(str string) bool { return str != "" && rxFloat.MatchString(str) } -// IsDivisibleBy check if the string is a number that's divisible by another. +// IsDivisibleBy checks if the string is a number that's divisible by another. // If second argument is not valid integer or zero, it's return false. // Otherwise, if first argument is not valid integer or zero, it's return true (Invalid string converts to zero). func IsDivisibleBy(str, num string) bool { @@ -316,12 +316,12 @@ func IsDivisibleBy(str, num string) bool { return (p == 0) || (p%q == 0) } -// IsNull check if the string is null. +// IsNull checks if the string is null. func IsNull(str string) bool { return len(str) == 0 } -// IsNotNull check if the string is not null. +// IsNotNull checks if the string is not null. func IsNotNull(str string) bool { return !IsNull(str) } @@ -336,32 +336,32 @@ func HasWhitespace(str string) bool { return len(str) > 0 && rxHasWhitespace.MatchString(str) } -// IsByteLength check if the string's length (in bytes) falls in a range. +// IsByteLength checks if the string's length (in bytes) falls in a range. func IsByteLength(str string, min, max int) bool { return len(str) >= min && len(str) <= max } -// IsUUIDv3 check if the string is a UUID version 3. +// IsUUIDv3 checks if the string is a UUID version 3. func IsUUIDv3(str string) bool { return rxUUID3.MatchString(str) } -// IsUUIDv4 check if the string is a UUID version 4. +// IsUUIDv4 checks if the string is a UUID version 4. func IsUUIDv4(str string) bool { return rxUUID4.MatchString(str) } -// IsUUIDv5 check if the string is a UUID version 5. +// IsUUIDv5 checks if the string is a UUID version 5. func IsUUIDv5(str string) bool { return rxUUID5.MatchString(str) } -// IsUUID check if the string is a UUID (version 3, 4 or 5). +// IsUUID checks if the string is a UUID (version 3, 4 or 5). func IsUUID(str string) bool { return rxUUID.MatchString(str) } -// IsCreditCard check if the string is a credit card. +// IsCreditCard checks if the string is a credit card. func IsCreditCard(str string) bool { sanitized := notNumberRegexp.ReplaceAllString(str, "") if !rxCreditCard.MatchString(sanitized) { @@ -377,7 +377,7 @@ func IsCreditCard(str string) bool { if shouldDouble { tmpNum *= 2 if tmpNum >= 10 { - sum += ((tmpNum % 10) + 1) + sum += (tmpNum % 10) + 1 } else { sum += tmpNum } @@ -390,18 +390,18 @@ func IsCreditCard(str string) bool { return sum%10 == 0 } -// IsISBN10 check if the string is an ISBN version 10. +// IsISBN10 checks if the string is an ISBN version 10. func IsISBN10(str string) bool { return IsISBN(str, 10) } -// IsISBN13 check if the string is an ISBN version 13. +// IsISBN13 checks if the string is an ISBN version 13. func IsISBN13(str string) bool { return IsISBN(str, 13) } -// IsISBN check if the string is an ISBN (version 10 or 13). -// If version value is not equal to 10 or 13, it will be check both variants. +// IsISBN checks if the string is an ISBN (version 10 or 13). +// If version value is not equal to 10 or 13, it will be checks both variants. func IsISBN(str string, version int) bool { sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "") var checksum int32 @@ -435,13 +435,13 @@ func IsISBN(str string, version int) bool { return IsISBN(str, 10) || IsISBN(str, 13) } -// IsJSON check if the string is valid JSON (note: uses json.Unmarshal). +// IsJSON checks if the string is valid JSON (note: uses json.Unmarshal). func IsJSON(str string) bool { var js json.RawMessage return json.Unmarshal([]byte(str), &js) == nil } -// IsMultibyte check if the string contains one or more multibyte chars. Empty string is valid. +// IsMultibyte checks if the string contains one or more multibyte chars. Empty string is valid. func IsMultibyte(str string) bool { if IsNull(str) { return true @@ -449,7 +449,7 @@ func IsMultibyte(str string) bool { return rxMultibyte.MatchString(str) } -// IsASCII check if the string contains ASCII chars only. Empty string is valid. +// IsASCII checks if the string contains ASCII chars only. Empty string is valid. func IsASCII(str string) bool { if IsNull(str) { return true @@ -457,7 +457,7 @@ func IsASCII(str string) bool { return rxASCII.MatchString(str) } -// IsPrintableASCII check if the string contains printable ASCII chars only. Empty string is valid. +// IsPrintableASCII checks if the string contains printable ASCII chars only. Empty string is valid. func IsPrintableASCII(str string) bool { if IsNull(str) { return true @@ -465,7 +465,7 @@ func IsPrintableASCII(str string) bool { return rxPrintableASCII.MatchString(str) } -// IsFullWidth check if the string contains any full-width chars. Empty string is valid. +// IsFullWidth checks if the string contains any full-width chars. Empty string is valid. func IsFullWidth(str string) bool { if IsNull(str) { return true @@ -473,7 +473,7 @@ func IsFullWidth(str string) bool { return rxFullWidth.MatchString(str) } -// IsHalfWidth check if the string contains any half-width chars. Empty string is valid. +// IsHalfWidth checks if the string contains any half-width chars. Empty string is valid. func IsHalfWidth(str string) bool { if IsNull(str) { return true @@ -481,7 +481,7 @@ func IsHalfWidth(str string) bool { return rxHalfWidth.MatchString(str) } -// IsVariableWidth check if the string contains a mixture of full and half-width chars. Empty string is valid. +// IsVariableWidth checks if the string contains a mixture of full and half-width chars. Empty string is valid. func IsVariableWidth(str string) bool { if IsNull(str) { return true @@ -489,12 +489,12 @@ func IsVariableWidth(str string) bool { return rxHalfWidth.MatchString(str) && rxFullWidth.MatchString(str) } -// IsBase64 check if a string is base64 encoded. +// IsBase64 checks if a string is base64 encoded. func IsBase64(str string) bool { return rxBase64.MatchString(str) } -// IsFilePath check is a string is Win or Unix file path and returns it's type. +// IsFilePath checks is a string is Win or Unix file path and returns it's type. func IsFilePath(str string) (bool, int) { if rxWinPath.MatchString(str) { //check windows path limit see: @@ -686,25 +686,25 @@ func IsPort(str string) bool { return false } -// IsIPv4 check if the string is an IP version 4. +// IsIPv4 checks if the string is an IP version 4. func IsIPv4(str string) bool { ip := net.ParseIP(str) return ip != nil && strings.Contains(str, ".") } -// IsIPv6 check if the string is an IP version 6. +// IsIPv6 checks if the string is an IP version 6. func IsIPv6(str string) bool { ip := net.ParseIP(str) return ip != nil && strings.Contains(str, ":") } -// IsCIDR check if the string is an valid CIDR notiation (IPV4 & IPV6) +// IsCIDR checks if the string is an valid CIDR notiation (IPV4 & IPV6) func IsCIDR(str string) bool { _, _, err := net.ParseCIDR(str) return err == nil } -// IsMAC check if a string is valid MAC address. +// IsMAC checks if a string is valid MAC address. // Possible MAC formats: // 01:23:45:67:89:ab // 01:23:45:67:89:ab:cd:ef @@ -722,27 +722,70 @@ func IsHost(str string) bool { return IsIP(str) || IsDNSName(str) } -// IsMongoID check if the string is a valid hex-encoded representation of a MongoDB ObjectId. +// IsMongoID checks if the string is a valid hex-encoded representation of a MongoDB ObjectId. func IsMongoID(str string) bool { return rxHexadecimal.MatchString(str) && (len(str) == 24) } -// IsLatitude check if a string is valid latitude. +// IsLatitude checks if a string is valid latitude. func IsLatitude(str string) bool { return rxLatitude.MatchString(str) } -// IsLongitude check if a string is valid longitude. +// IsLongitude checks if a string is valid longitude. func IsLongitude(str string) bool { return rxLongitude.MatchString(str) } -// IsIMEI check if a string is valid IMEI +// IsIMEI checks if a string is valid IMEI func IsIMEI(str string) bool { return rxIMEI.MatchString(str) } -// IsRsaPublicKey check if a string is valid public key with provided length +// IsIMSI checks if a string is valid IMSI +func IsIMSI(str string) bool { + if !rxIMSI.MatchString(str) { + return false + } + + mcc, err := strconv.ParseInt(str[0:3], 10, 32) + if err != nil { + return false + } + + switch mcc { + case 202, 204, 206, 208, 212, 213, 214, 216, 218, 219: + case 220, 221, 222, 226, 228, 230, 231, 232, 234, 235: + case 238, 240, 242, 244, 246, 247, 248, 250, 255, 257: + case 259, 260, 262, 266, 268, 270, 272, 274, 276, 278: + case 280, 282, 283, 284, 286, 288, 289, 290, 292, 293: + case 294, 295, 297, 302, 308, 310, 311, 312, 313, 314: + case 315, 316, 330, 332, 334, 338, 340, 342, 344, 346: + case 348, 350, 352, 354, 356, 358, 360, 362, 363, 364: + case 365, 366, 368, 370, 372, 374, 376, 400, 401, 402: + case 404, 405, 406, 410, 412, 413, 414, 415, 416, 417: + case 418, 419, 420, 421, 422, 424, 425, 426, 427, 428: + case 429, 430, 431, 432, 434, 436, 437, 438, 440, 441: + case 450, 452, 454, 455, 456, 457, 460, 461, 466, 467: + case 470, 472, 502, 505, 510, 514, 515, 520, 525, 528: + case 530, 536, 537, 539, 540, 541, 542, 543, 544, 545: + case 546, 547, 548, 549, 550, 551, 552, 553, 554, 555: + case 602, 603, 604, 605, 606, 607, 608, 609, 610, 611: + case 612, 613, 614, 615, 616, 617, 618, 619, 620, 621: + case 622, 623, 624, 625, 626, 627, 628, 629, 630, 631: + case 632, 633, 634, 635, 636, 637, 638, 639, 640, 641: + case 642, 643, 645, 646, 647, 648, 649, 650, 651, 652: + case 653, 654, 655, 657, 658, 659, 702, 704, 706, 708: + case 710, 712, 714, 716, 722, 724, 730, 732, 734, 736: + case 738, 740, 742, 744, 746, 748, 750, 995: + return true + default: + return false + } + return true +} + +// IsRsaPublicKey checks if a string is valid public key with provided length func IsRsaPublicKey(str string, keylen int) bool { bb := bytes.NewBufferString(str) pemBytes, err := ioutil.ReadAll(bb) @@ -796,7 +839,7 @@ func toJSONName(tag string) string { return name } -func PrependPathToErrors(err error, path string) error { +func prependPathToErrors(err error, path string) error { switch err2 := err.(type) { case Error: err2.Path = append([]string{path}, err2.Path...) @@ -804,13 +847,18 @@ func PrependPathToErrors(err error, path string) error { case Errors: errors := err2.Errors() for i, err3 := range errors { - errors[i] = PrependPathToErrors(err3, path) + errors[i] = prependPathToErrors(err3, path) } return err2 } return err } +// ValidateArray performs validation according to condition iterator that validates every element of the array +func ValidateArray(array []interface{}, iterator ConditionIterator) bool { + return Every(array, iterator) +} + // ValidateMap use validation map for fields. // result will be equal to `false` if there are any errors. // s is the map containing the data to be validated. @@ -832,7 +880,7 @@ func ValidateMap(s map[string]interface{}, m map[string]interface{}) (bool, erro presentResult = false var err error err = fmt.Errorf("all map keys has to be present in the validation map; got %s", key) - err = PrependPathToErrors(err, key) + err = prependPathToErrors(err, key) errs = append(errs, err) } valueField := reflect.ValueOf(value) @@ -846,13 +894,13 @@ func ValidateMap(s map[string]interface{}, m map[string]interface{}) (bool, erro if v, ok := value.(map[string]interface{}); !ok { mapResult = false err = fmt.Errorf("map validator has to be for the map type only; got %s", valueField.Type().String()) - err = PrependPathToErrors(err, key) + err = prependPathToErrors(err, key) errs = append(errs, err) } else { mapResult, err = ValidateMap(v, subValidator) if err != nil { mapResult = false - err = PrependPathToErrors(err, key) + err = prependPathToErrors(err, key) errs = append(errs, err) } } @@ -863,7 +911,7 @@ func ValidateMap(s map[string]interface{}, m map[string]interface{}) (bool, erro var err error structResult, err = ValidateStruct(valueField.Interface()) if err != nil { - err = PrependPathToErrors(err, key) + err = prependPathToErrors(err, key) errs = append(errs, err) } } @@ -884,13 +932,13 @@ func ValidateMap(s map[string]interface{}, m map[string]interface{}) (bool, erro default: typeResult = false err = fmt.Errorf("map validator has to be either map[string]interface{} or string; got %s", valueField.Type().String()) - err = PrependPathToErrors(err, key) + err = prependPathToErrors(err, key) errs = append(errs, err) } result = result && presentResult && typeResult && resultField && structResult && mapResult index++ } - // check required keys + // checks required keys requiredResult := true for key, value := range m { if schema, ok := value.(string); ok { @@ -949,7 +997,7 @@ func ValidateStruct(s interface{}) (bool, error) { var err error structResult, err = ValidateStruct(valueField.Interface()) if err != nil { - err = PrependPathToErrors(err, typeField.Name) + err = prependPathToErrors(err, typeField.Name) errs = append(errs, err) } } @@ -986,6 +1034,42 @@ func ValidateStruct(s interface{}) (bool, error) { return result, err } +// ValidateStructAsync performs async validation of the struct and returns results through the channels +func ValidateStructAsync(s interface{}) (<-chan bool, <-chan error) { + res := make(chan bool) + errors := make(chan error) + + go func() { + defer close(res) + defer close(errors) + + isValid, isFailed := ValidateStruct(s) + + res <- isValid + errors <- isFailed + }() + + return res, errors +} + +// ValidateMapAsync performs async validation of the map and returns results through the channels +func ValidateMapAsync(s map[string]interface{}, m map[string]interface{}) (<-chan bool, <-chan error) { + res := make(chan bool) + errors := make(chan error) + + go func() { + defer close(res) + defer close(errors) + + isValid, isFailed := ValidateMap(s, m) + + res <- isValid + errors <- isFailed + }() + + return res, errors +} + // parseTagIntoMap parses a struct tag `valid:required~Some error message,length(2|3)` into map[string]string{"required": "Some error message", "length(2|3)": ""} func parseTagIntoMap(tag string) tagOptionsMap { optionsMap := make(tagOptionsMap) @@ -1034,12 +1118,12 @@ func IsSSN(str string) bool { return rxSSN.MatchString(str) } -// IsSemver check if string is valid semantic version +// IsSemver checks if string is valid semantic version func IsSemver(str string) bool { return rxSemver.MatchString(str) } -// IsType check if interface is of some type +// IsType checks if interface is of some type func IsType(v interface{}, params ...string) bool { if len(params) == 1 { typ := params[0] @@ -1048,13 +1132,13 @@ func IsType(v interface{}, params ...string) bool { return false } -// IsTime check if string is valid according to given format +// IsTime checks if string is valid according to given format func IsTime(str string, format string) bool { _, err := time.Parse(format, str) return err == nil } -// IsUnixTime check if string is valid unix timestamp value +// IsUnixTime checks if string is valid unix timestamp value func IsUnixTime(str string) bool { if _, err := strconv.Atoi(str); err == nil { return true @@ -1062,17 +1146,17 @@ func IsUnixTime(str string) bool { return false } -// IsRFC3339 check if string is valid timestamp value according to RFC3339 +// IsRFC3339 checks if string is valid timestamp value according to RFC3339 func IsRFC3339(str string) bool { return IsTime(str, time.RFC3339) } -// IsRFC3339WithoutZone check if string is valid timestamp value according to RFC3339 which excludes the timezone. +// IsRFC3339WithoutZone checks if string is valid timestamp value according to RFC3339 which excludes the timezone. func IsRFC3339WithoutZone(str string) bool { - return IsTime(str, RF3339WithoutZone) + return IsTime(str, rfc3339WithoutZone) } -// IsISO4217 check if string is valid ISO currency code +// IsISO4217 checks if string is valid ISO currency code func IsISO4217(str string) bool { for _, currency := range ISO4217List { if str == currency { @@ -1083,7 +1167,7 @@ func IsISO4217(str string) bool { return false } -// ByteLength check string's length +// ByteLength checks string's length func ByteLength(str string, params ...string) bool { if len(params) == 2 { min, _ := ToInt(params[0]) @@ -1094,13 +1178,13 @@ func ByteLength(str string, params ...string) bool { return false } -// RuneLength check string's length +// RuneLength checks string's length // Alias for StringLength func RuneLength(str string, params ...string) bool { return StringLength(str, params...) } -// IsRsaPub check whether string is valid RSA key +// IsRsaPub checks whether string is valid RSA key // Alias for IsRsaPublicKey func IsRsaPub(str string, params ...string) bool { if len(params) == 1 { @@ -1120,7 +1204,7 @@ func StringMatches(s string, params ...string) bool { return false } -// StringLength check string's length (including multi byte strings) +// StringLength checks string's length (including multi byte strings) func StringLength(str string, params ...string) bool { if len(params) == 2 { @@ -1133,7 +1217,7 @@ func StringLength(str string, params ...string) bool { return false } -// MinStringLength check string's minimum length (including multi byte strings) +// MinStringLength checks string's minimum length (including multi byte strings) func MinStringLength(str string, params ...string) bool { if len(params) == 1 { @@ -1145,7 +1229,7 @@ func MinStringLength(str string, params ...string) bool { return false } -// MaxStringLength check string's maximum length (including multi byte strings) +// MaxStringLength checks string's maximum length (including multi byte strings) func MaxStringLength(str string, params ...string) bool { if len(params) == 1 { @@ -1157,7 +1241,7 @@ func MaxStringLength(str string, params ...string) bool { return false } -// Range check string's length +// Range checks string's length func Range(str string, params ...string) bool { if len(params) == 2 { value, _ := ToFloat(str) @@ -1169,6 +1253,7 @@ func Range(str string, params ...string) bool { return false } +// IsInRaw checks if string is in list of allowed values func IsInRaw(str string, params ...string) bool { if len(params) == 1 { rawParams := params[0] @@ -1181,7 +1266,7 @@ func IsInRaw(str string, params ...string) bool { return false } -// IsIn check if string str is a member of the set of strings params +// IsIn checks if string str is a member of the set of strings params func IsIn(str string, params ...string) bool { for _, param := range params { if str == param { @@ -1219,7 +1304,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options tag := t.Tag.Get(tagName) - // Check if the field should be ignored + // checks if the field should be ignored switch tag { case "": if v.Kind() != reflect.Slice && v.Kind() != reflect.Map { @@ -1238,8 +1323,8 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options options = parseTagIntoMap(tag) } - if !isFieldSet(v) { - // an empty value is not validated, check only required + if isEmptyValue(v) { + // an empty value is not validated, checks only required isValid, resultErr = checkRequired(v, t, options) for key := range options { delete(options, key) @@ -1292,13 +1377,13 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options validator := validatorSpec customMsgExists := len(validatorStruct.customErrorMessage) > 0 - // Check whether the tag looks like '!something' or 'something' + // checks whether the tag looks like '!something' or 'something' if validator[0] == '!' { validator = validator[1:] negate = true } - // Check for interface param validators + // checks for interface param validators for key, value := range InterfaceParamTagRegexMap { ps := value.FindStringSubmatch(validator) if len(ps) == 0 { @@ -1331,20 +1416,20 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.String: - // for each tag option check the map of validator functions + // for each tag option checks the map of validator functions for _, validatorSpec := range optionsOrder { validatorStruct := options[validatorSpec] var negate bool validator := validatorSpec customMsgExists := len(validatorStruct.customErrorMessage) > 0 - // Check whether the tag looks like '!something' or 'something' + // checks whether the tag looks like '!something' or 'something' if validator[0] == '!' { validator = validator[1:] negate = true } - // Check for param validators + // checks for param validators for key, value := range ParamTagRegexMap { ps := value.FindStringSubmatch(validator) if len(ps) == 0 { @@ -1425,7 +1510,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options } else { resultItem, err = ValidateStruct(v.MapIndex(k).Interface()) if err != nil { - err = PrependPathToErrors(err, t.Name+"."+sv[i].Interface().(string)) + err = prependPathToErrors(err, t.Name+"."+sv[i].Interface().(string)) return false, err } } @@ -1445,7 +1530,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options } else { resultItem, err = ValidateStruct(v.Index(i).Interface()) if err != nil { - err = PrependPathToErrors(err, t.Name+"."+strconv.Itoa(i)) + err = prependPathToErrors(err, t.Name+"."+strconv.Itoa(i)) return false, err } } @@ -1459,7 +1544,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options } return ValidateStruct(v.Interface()) case reflect.Ptr: - // If the value is a pointer then check its element + // If the value is a pointer then checks its element if v.IsNil() { return true, nil } @@ -1475,14 +1560,26 @@ func stripParams(validatorString string) string { return paramsRegexp.ReplaceAllString(validatorString, "") } -// isFieldSet returns false for nil pointers, interfaces, maps, and slices. For all other values, it returns true. -func isFieldSet(v reflect.Value) bool { +// isEmptyValue checks whether value empty or not +func isEmptyValue(v reflect.Value) bool { switch v.Kind() { - case reflect.Map, reflect.Slice, reflect.Interface, reflect.Ptr: - return !v.IsNil() - } - - return true + case reflect.String, reflect.Array: + return v.Len() == 0 + case reflect.Map, reflect.Slice: + return v.Len() == 0 || v.IsNil() + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + + return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) } // ErrorByField returns error for specified field of the struct diff --git a/vendor/github.com/fatih/color/README.md b/vendor/github.com/fatih/color/README.md index 42d9abc07ed38..d62e4024aa5aa 100644 --- a/vendor/github.com/fatih/color/README.md +++ b/vendor/github.com/fatih/color/README.md @@ -1,20 +1,11 @@ -# Archived project. No maintenance. - -This project is not maintained anymore and is archived. Feel free to fork and -make your own changes if needed. For more detail read my blog post: [Taking an indefinite sabbatical from my projects](https://arslan.io/2018/10/09/taking-an-indefinite-sabbatical-from-my-projects/) - -Thanks to everyone for their valuable feedback and contributions. - - -# Color [![GoDoc](https://godoc.org/github.com/fatih/color?status.svg)](https://godoc.org/github.com/fatih/color) +# color [![](https://github.com/fatih/color/workflows/build/badge.svg)](https://github.com/fatih/color/actions) [![PkgGoDev](https://pkg.go.dev/badge/github.com/fatih/color)](https://pkg.go.dev/github.com/fatih/color) Color lets you use colorized outputs in terms of [ANSI Escape Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It has support for Windows too! The API can be used in several ways, pick one that suits you. - -![Color](https://i.imgur.com/c1JI0lA.png) +![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg) ## Install diff --git a/vendor/github.com/fatih/color/go.mod b/vendor/github.com/fatih/color/go.mod index bc0df754586f0..78872815ea631 100644 --- a/vendor/github.com/fatih/color/go.mod +++ b/vendor/github.com/fatih/color/go.mod @@ -3,6 +3,6 @@ module github.com/fatih/color go 1.13 require ( - github.com/mattn/go-colorable v0.1.4 - github.com/mattn/go-isatty v0.0.11 + github.com/mattn/go-colorable v0.1.8 + github.com/mattn/go-isatty v0.0.12 ) diff --git a/vendor/github.com/fatih/color/go.sum b/vendor/github.com/fatih/color/go.sum index 44328a8db54c5..54f7c46e8107c 100644 --- a/vendor/github.com/fatih/color/go.sum +++ b/vendor/github.com/fatih/color/go.sum @@ -1,8 +1,7 @@ -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/felixge/httpsnoop/.gitignore b/vendor/github.com/felixge/httpsnoop/.gitignore new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/vendor/github.com/felixge/httpsnoop/.travis.yml b/vendor/github.com/felixge/httpsnoop/.travis.yml new file mode 100644 index 0000000000000..bfc421200d0e2 --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/.travis.yml @@ -0,0 +1,6 @@ +language: go + +go: + - 1.6 + - 1.7 + - 1.8 diff --git a/vendor/github.com/felixge/httpsnoop/LICENSE.txt b/vendor/github.com/felixge/httpsnoop/LICENSE.txt new file mode 100644 index 0000000000000..e028b46a9b042 --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2016 Felix Geisendörfer (felix@debuggable.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/vendor/github.com/felixge/httpsnoop/Makefile b/vendor/github.com/felixge/httpsnoop/Makefile new file mode 100644 index 0000000000000..2d84889aed792 --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/Makefile @@ -0,0 +1,10 @@ +.PHONY: ci generate clean + +ci: clean generate + go test -v ./... + +generate: + go generate . + +clean: + rm -rf *_generated*.go diff --git a/vendor/github.com/felixge/httpsnoop/README.md b/vendor/github.com/felixge/httpsnoop/README.md new file mode 100644 index 0000000000000..ae44137e9b04b --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/README.md @@ -0,0 +1,94 @@ +# httpsnoop + +Package httpsnoop provides an easy way to capture http related metrics (i.e. +response time, bytes written, and http status code) from your application's +http.Handlers. + +Doing this requires non-trivial wrapping of the http.ResponseWriter interface, +which is also exposed for users interested in a more low-level API. + +[![GoDoc](https://godoc.org/github.com/felixge/httpsnoop?status.svg)](https://godoc.org/github.com/felixge/httpsnoop) +[![Build Status](https://travis-ci.org/felixge/httpsnoop.svg?branch=master)](https://travis-ci.org/felixge/httpsnoop) + +## Usage Example + +```go +// myH is your app's http handler, perhaps a http.ServeMux or similar. +var myH http.Handler +// wrappedH wraps myH in order to log every request. +wrappedH := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + m := httpsnoop.CaptureMetrics(myH, w, r) + log.Printf( + "%s %s (code=%d dt=%s written=%d)", + r.Method, + r.URL, + m.Code, + m.Duration, + m.Written, + ) +}) +http.ListenAndServe(":8080", wrappedH) +``` + +## Why this package exists + +Instrumenting an application's http.Handler is surprisingly difficult. + +However if you google for e.g. "capture ResponseWriter status code" you'll find +lots of advise and code examples that suggest it to be a fairly trivial +undertaking. Unfortunately everything I've seen so far has a high chance of +breaking your application. + +The main problem is that a `http.ResponseWriter` often implements additional +interfaces such as `http.Flusher`, `http.CloseNotifier`, `http.Hijacker`, `http.Pusher`, and +`io.ReaderFrom`. So the naive approach of just wrapping `http.ResponseWriter` +in your own struct that also implements the `http.ResponseWriter` interface +will hide the additional interfaces mentioned above. This has a high change of +introducing subtle bugs into any non-trivial application. + +Another approach I've seen people take is to return a struct that implements +all of the interfaces above. However, that's also problematic, because it's +difficult to fake some of these interfaces behaviors when the underlying +`http.ResponseWriter` doesn't have an implementation. It's also dangerous, +because an application may choose to operate differently, merely because it +detects the presence of these additional interfaces. + +This package solves this problem by checking which additional interfaces a +`http.ResponseWriter` implements, returning a wrapped version implementing the +exact same set of interfaces. + +Additionally this package properly handles edge cases such as `WriteHeader` not +being called, or called more than once, as well as concurrent calls to +`http.ResponseWriter` methods, and even calls happening after the wrapped +`ServeHTTP` has already returned. + +Unfortunately this package is not perfect either. It's possible that it is +still missing some interfaces provided by the go core (let me know if you find +one), and it won't work for applications adding their own interfaces into the +mix. + +However, hopefully the explanation above has sufficiently scared you of rolling +your own solution to this problem. httpsnoop may still break your application, +but at least it tries to avoid it as much as possible. + +Anyway, the real problem here is that smuggling additional interfaces inside +`http.ResponseWriter` is a problematic design choice, but it probably goes as +deep as the Go language specification itself. But that's okay, I still prefer +Go over the alternatives ;). + +## Performance + +``` +BenchmarkBaseline-8 20000 94912 ns/op +BenchmarkCaptureMetrics-8 20000 95461 ns/op +``` + +As you can see, using `CaptureMetrics` on a vanilla http.Handler introduces an +overhead of ~500 ns per http request on my machine. However, the margin of +error appears to be larger than that, therefor it should be reasonable to +assume that the overhead introduced by `CaptureMetrics` is absolutely +negligible. + +## License + +MIT diff --git a/vendor/github.com/felixge/httpsnoop/capture_metrics.go b/vendor/github.com/felixge/httpsnoop/capture_metrics.go new file mode 100644 index 0000000000000..4c45b1a8c15f6 --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/capture_metrics.go @@ -0,0 +1,84 @@ +package httpsnoop + +import ( + "io" + "net/http" + "sync" + "time" +) + +// Metrics holds metrics captured from CaptureMetrics. +type Metrics struct { + // Code is the first http response code passed to the WriteHeader func of + // the ResponseWriter. If no such call is made, a default code of 200 is + // assumed instead. + Code int + // Duration is the time it took to execute the handler. + Duration time.Duration + // Written is the number of bytes successfully written by the Write or + // ReadFrom function of the ResponseWriter. ResponseWriters may also write + // data to their underlaying connection directly (e.g. headers), but those + // are not tracked. Therefor the number of Written bytes will usually match + // the size of the response body. + Written int64 +} + +// CaptureMetrics wraps the given hnd, executes it with the given w and r, and +// returns the metrics it captured from it. +func CaptureMetrics(hnd http.Handler, w http.ResponseWriter, r *http.Request) Metrics { + return CaptureMetricsFn(w, func(ww http.ResponseWriter) { + hnd.ServeHTTP(ww, r) + }) +} + +// CaptureMetricsFn wraps w and calls fn with the wrapped w and returns the +// resulting metrics. This is very similar to CaptureMetrics (which is just +// sugar on top of this func), but is a more usable interface if your +// application doesn't use the Go http.Handler interface. +func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metrics { + var ( + start = time.Now() + m = Metrics{Code: http.StatusOK} + headerWritten bool + lock sync.Mutex + hooks = Hooks{ + WriteHeader: func(next WriteHeaderFunc) WriteHeaderFunc { + return func(code int) { + next(code) + lock.Lock() + defer lock.Unlock() + if !headerWritten { + m.Code = code + headerWritten = true + } + } + }, + + Write: func(next WriteFunc) WriteFunc { + return func(p []byte) (int, error) { + n, err := next(p) + lock.Lock() + defer lock.Unlock() + m.Written += int64(n) + headerWritten = true + return n, err + } + }, + + ReadFrom: func(next ReadFromFunc) ReadFromFunc { + return func(src io.Reader) (int64, error) { + n, err := next(src) + lock.Lock() + defer lock.Unlock() + headerWritten = true + m.Written += n + return n, err + } + }, + } + ) + + fn(Wrap(w, hooks)) + m.Duration = time.Since(start) + return m +} diff --git a/vendor/github.com/felixge/httpsnoop/docs.go b/vendor/github.com/felixge/httpsnoop/docs.go new file mode 100644 index 0000000000000..203c35b3c6d10 --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/docs.go @@ -0,0 +1,10 @@ +// Package httpsnoop provides an easy way to capture http related metrics (i.e. +// response time, bytes written, and http status code) from your application's +// http.Handlers. +// +// Doing this requires non-trivial wrapping of the http.ResponseWriter +// interface, which is also exposed for users interested in a more low-level +// API. +package httpsnoop + +//go:generate go run codegen/main.go diff --git a/vendor/github.com/felixge/httpsnoop/go.mod b/vendor/github.com/felixge/httpsnoop/go.mod new file mode 100644 index 0000000000000..73b3946905ab0 --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/go.mod @@ -0,0 +1,3 @@ +module github.com/felixge/httpsnoop + +go 1.13 diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go b/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go new file mode 100644 index 0000000000000..41a20da9eab48 --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go @@ -0,0 +1,385 @@ +// +build go1.8 +// Code generated by "httpsnoop/codegen"; DO NOT EDIT + +package httpsnoop + +import ( + "bufio" + "io" + "net" + "net/http" +) + +// HeaderFunc is part of the http.ResponseWriter interface. +type HeaderFunc func() http.Header + +// WriteHeaderFunc is part of the http.ResponseWriter interface. +type WriteHeaderFunc func(code int) + +// WriteFunc is part of the http.ResponseWriter interface. +type WriteFunc func(b []byte) (int, error) + +// FlushFunc is part of the http.Flusher interface. +type FlushFunc func() + +// CloseNotifyFunc is part of the http.CloseNotifier interface. +type CloseNotifyFunc func() <-chan bool + +// HijackFunc is part of the http.Hijacker interface. +type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) + +// ReadFromFunc is part of the io.ReaderFrom interface. +type ReadFromFunc func(src io.Reader) (int64, error) + +// PushFunc is part of the http.Pusher interface. +type PushFunc func(target string, opts *http.PushOptions) error + +// Hooks defines a set of method interceptors for methods included in +// http.ResponseWriter as well as some others. You can think of them as +// middleware for the function calls they target. See Wrap for more details. +type Hooks struct { + Header func(HeaderFunc) HeaderFunc + WriteHeader func(WriteHeaderFunc) WriteHeaderFunc + Write func(WriteFunc) WriteFunc + Flush func(FlushFunc) FlushFunc + CloseNotify func(CloseNotifyFunc) CloseNotifyFunc + Hijack func(HijackFunc) HijackFunc + ReadFrom func(ReadFromFunc) ReadFromFunc + Push func(PushFunc) PushFunc +} + +// Wrap returns a wrapped version of w that provides the exact same interface +// as w. Specifically if w implements any combination of: +// +// - http.Flusher +// - http.CloseNotifier +// - http.Hijacker +// - io.ReaderFrom +// - http.Pusher +// +// The wrapped version will implement the exact same combination. If no hooks +// are set, the wrapped version also behaves exactly as w. Hooks targeting +// methods not supported by w are ignored. Any other hooks will intercept the +// method they target and may modify the call's arguments and/or return values. +// The CaptureMetrics implementation serves as a working example for how the +// hooks can be used. +func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { + rw := &rw{w: w, h: hooks} + _, i0 := w.(http.Flusher) + _, i1 := w.(http.CloseNotifier) + _, i2 := w.(http.Hijacker) + _, i3 := w.(io.ReaderFrom) + _, i4 := w.(http.Pusher) + switch { + // combination 1/32 + case !i0 && !i1 && !i2 && !i3 && !i4: + return struct { + http.ResponseWriter + }{rw} + // combination 2/32 + case !i0 && !i1 && !i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Pusher + }{rw, rw} + // combination 3/32 + case !i0 && !i1 && !i2 && i3 && !i4: + return struct { + http.ResponseWriter + io.ReaderFrom + }{rw, rw} + // combination 4/32 + case !i0 && !i1 && !i2 && i3 && i4: + return struct { + http.ResponseWriter + io.ReaderFrom + http.Pusher + }{rw, rw, rw} + // combination 5/32 + case !i0 && !i1 && i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + }{rw, rw} + // combination 6/32 + case !i0 && !i1 && i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + http.Pusher + }{rw, rw, rw} + // combination 7/32 + case !i0 && !i1 && i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + io.ReaderFrom + }{rw, rw, rw} + // combination 8/32 + case !i0 && !i1 && i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw} + // combination 9/32 + case !i0 && i1 && !i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.CloseNotifier + }{rw, rw} + // combination 10/32 + case !i0 && i1 && !i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Pusher + }{rw, rw, rw} + // combination 11/32 + case !i0 && i1 && !i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.CloseNotifier + io.ReaderFrom + }{rw, rw, rw} + // combination 12/32 + case !i0 && i1 && !i2 && i3 && i4: + return struct { + http.ResponseWriter + http.CloseNotifier + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw} + // combination 13/32 + case !i0 && i1 && i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Hijacker + }{rw, rw, rw} + // combination 14/32 + case !i0 && i1 && i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Hijacker + http.Pusher + }{rw, rw, rw, rw} + // combination 15/32 + case !i0 && i1 && i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 16/32 + case !i0 && i1 && i2 && i3 && i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Hijacker + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 17/32 + case i0 && !i1 && !i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Flusher + }{rw, rw} + // combination 18/32 + case i0 && !i1 && !i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Flusher + http.Pusher + }{rw, rw, rw} + // combination 19/32 + case i0 && !i1 && !i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Flusher + io.ReaderFrom + }{rw, rw, rw} + // combination 20/32 + case i0 && !i1 && !i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Flusher + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw} + // combination 21/32 + case i0 && !i1 && i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Flusher + http.Hijacker + }{rw, rw, rw} + // combination 22/32 + case i0 && !i1 && i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Flusher + http.Hijacker + http.Pusher + }{rw, rw, rw, rw} + // combination 23/32 + case i0 && !i1 && i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Flusher + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 24/32 + case i0 && !i1 && i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Flusher + http.Hijacker + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 25/32 + case i0 && i1 && !i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + }{rw, rw, rw} + // combination 26/32 + case i0 && i1 && !i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Pusher + }{rw, rw, rw, rw} + // combination 27/32 + case i0 && i1 && !i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 28/32 + case i0 && i1 && !i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 29/32 + case i0 && i1 && i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + }{rw, rw, rw, rw} + // combination 30/32 + case i0 && i1 && i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 31/32 + case i0 && i1 && i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw, rw} + // combination 32/32 + case i0 && i1 && i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw, rw} + } + panic("unreachable") +} + +type rw struct { + w http.ResponseWriter + h Hooks +} + +func (w *rw) Header() http.Header { + f := w.w.(http.ResponseWriter).Header + if w.h.Header != nil { + f = w.h.Header(f) + } + return f() +} + +func (w *rw) WriteHeader(code int) { + f := w.w.(http.ResponseWriter).WriteHeader + if w.h.WriteHeader != nil { + f = w.h.WriteHeader(f) + } + f(code) +} + +func (w *rw) Write(b []byte) (int, error) { + f := w.w.(http.ResponseWriter).Write + if w.h.Write != nil { + f = w.h.Write(f) + } + return f(b) +} + +func (w *rw) Flush() { + f := w.w.(http.Flusher).Flush + if w.h.Flush != nil { + f = w.h.Flush(f) + } + f() +} + +func (w *rw) CloseNotify() <-chan bool { + f := w.w.(http.CloseNotifier).CloseNotify + if w.h.CloseNotify != nil { + f = w.h.CloseNotify(f) + } + return f() +} + +func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { + f := w.w.(http.Hijacker).Hijack + if w.h.Hijack != nil { + f = w.h.Hijack(f) + } + return f() +} + +func (w *rw) ReadFrom(src io.Reader) (int64, error) { + f := w.w.(io.ReaderFrom).ReadFrom + if w.h.ReadFrom != nil { + f = w.h.ReadFrom(f) + } + return f(src) +} + +func (w *rw) Push(target string, opts *http.PushOptions) error { + f := w.w.(http.Pusher).Push + if w.h.Push != nil { + f = w.h.Push(f) + } + return f(target, opts) +} diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go b/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go new file mode 100644 index 0000000000000..36bb59b837c9d --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go @@ -0,0 +1,243 @@ +// +build !go1.8 +// Code generated by "httpsnoop/codegen"; DO NOT EDIT + +package httpsnoop + +import ( + "bufio" + "io" + "net" + "net/http" +) + +// HeaderFunc is part of the http.ResponseWriter interface. +type HeaderFunc func() http.Header + +// WriteHeaderFunc is part of the http.ResponseWriter interface. +type WriteHeaderFunc func(code int) + +// WriteFunc is part of the http.ResponseWriter interface. +type WriteFunc func(b []byte) (int, error) + +// FlushFunc is part of the http.Flusher interface. +type FlushFunc func() + +// CloseNotifyFunc is part of the http.CloseNotifier interface. +type CloseNotifyFunc func() <-chan bool + +// HijackFunc is part of the http.Hijacker interface. +type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) + +// ReadFromFunc is part of the io.ReaderFrom interface. +type ReadFromFunc func(src io.Reader) (int64, error) + +// Hooks defines a set of method interceptors for methods included in +// http.ResponseWriter as well as some others. You can think of them as +// middleware for the function calls they target. See Wrap for more details. +type Hooks struct { + Header func(HeaderFunc) HeaderFunc + WriteHeader func(WriteHeaderFunc) WriteHeaderFunc + Write func(WriteFunc) WriteFunc + Flush func(FlushFunc) FlushFunc + CloseNotify func(CloseNotifyFunc) CloseNotifyFunc + Hijack func(HijackFunc) HijackFunc + ReadFrom func(ReadFromFunc) ReadFromFunc +} + +// Wrap returns a wrapped version of w that provides the exact same interface +// as w. Specifically if w implements any combination of: +// +// - http.Flusher +// - http.CloseNotifier +// - http.Hijacker +// - io.ReaderFrom +// +// The wrapped version will implement the exact same combination. If no hooks +// are set, the wrapped version also behaves exactly as w. Hooks targeting +// methods not supported by w are ignored. Any other hooks will intercept the +// method they target and may modify the call's arguments and/or return values. +// The CaptureMetrics implementation serves as a working example for how the +// hooks can be used. +func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { + rw := &rw{w: w, h: hooks} + _, i0 := w.(http.Flusher) + _, i1 := w.(http.CloseNotifier) + _, i2 := w.(http.Hijacker) + _, i3 := w.(io.ReaderFrom) + switch { + // combination 1/16 + case !i0 && !i1 && !i2 && !i3: + return struct { + http.ResponseWriter + }{rw} + // combination 2/16 + case !i0 && !i1 && !i2 && i3: + return struct { + http.ResponseWriter + io.ReaderFrom + }{rw, rw} + // combination 3/16 + case !i0 && !i1 && i2 && !i3: + return struct { + http.ResponseWriter + http.Hijacker + }{rw, rw} + // combination 4/16 + case !i0 && !i1 && i2 && i3: + return struct { + http.ResponseWriter + http.Hijacker + io.ReaderFrom + }{rw, rw, rw} + // combination 5/16 + case !i0 && i1 && !i2 && !i3: + return struct { + http.ResponseWriter + http.CloseNotifier + }{rw, rw} + // combination 6/16 + case !i0 && i1 && !i2 && i3: + return struct { + http.ResponseWriter + http.CloseNotifier + io.ReaderFrom + }{rw, rw, rw} + // combination 7/16 + case !i0 && i1 && i2 && !i3: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Hijacker + }{rw, rw, rw} + // combination 8/16 + case !i0 && i1 && i2 && i3: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 9/16 + case i0 && !i1 && !i2 && !i3: + return struct { + http.ResponseWriter + http.Flusher + }{rw, rw} + // combination 10/16 + case i0 && !i1 && !i2 && i3: + return struct { + http.ResponseWriter + http.Flusher + io.ReaderFrom + }{rw, rw, rw} + // combination 11/16 + case i0 && !i1 && i2 && !i3: + return struct { + http.ResponseWriter + http.Flusher + http.Hijacker + }{rw, rw, rw} + // combination 12/16 + case i0 && !i1 && i2 && i3: + return struct { + http.ResponseWriter + http.Flusher + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 13/16 + case i0 && i1 && !i2 && !i3: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + }{rw, rw, rw} + // combination 14/16 + case i0 && i1 && !i2 && i3: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 15/16 + case i0 && i1 && i2 && !i3: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + }{rw, rw, rw, rw} + // combination 16/16 + case i0 && i1 && i2 && i3: + return struct { + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw, rw} + } + panic("unreachable") +} + +type rw struct { + w http.ResponseWriter + h Hooks +} + +func (w *rw) Header() http.Header { + f := w.w.(http.ResponseWriter).Header + if w.h.Header != nil { + f = w.h.Header(f) + } + return f() +} + +func (w *rw) WriteHeader(code int) { + f := w.w.(http.ResponseWriter).WriteHeader + if w.h.WriteHeader != nil { + f = w.h.WriteHeader(f) + } + f(code) +} + +func (w *rw) Write(b []byte) (int, error) { + f := w.w.(http.ResponseWriter).Write + if w.h.Write != nil { + f = w.h.Write(f) + } + return f(b) +} + +func (w *rw) Flush() { + f := w.w.(http.Flusher).Flush + if w.h.Flush != nil { + f = w.h.Flush(f) + } + f() +} + +func (w *rw) CloseNotify() <-chan bool { + f := w.w.(http.CloseNotifier).CloseNotify + if w.h.CloseNotify != nil { + f = w.h.CloseNotify(f) + } + return f() +} + +func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { + f := w.w.(http.Hijacker).Hijack + if w.h.Hijack != nil { + f = w.h.Hijack(f) + } + return f() +} + +func (w *rw) ReadFrom(src io.Reader) (int64, error) { + f := w.w.(io.ReaderFrom).ReadFrom + if w.h.ReadFrom != nil { + f = w.h.ReadFrom(f) + } + return f(src) +} diff --git a/vendor/github.com/go-openapi/analysis/.golangci.yml b/vendor/github.com/go-openapi/analysis/.golangci.yml index c3694fc6c0d7f..552a011a3dff8 100644 --- a/vendor/github.com/go-openapi/analysis/.golangci.yml +++ b/vendor/github.com/go-openapi/analysis/.golangci.yml @@ -8,7 +8,7 @@ linters-settings: maligned: suggest-new: true dupl: - threshold: 100 + threshold: 150 goconst: min-len: 2 min-occurrences: 4 @@ -30,3 +30,16 @@ linters: - whitespace - wsl - funlen + - testpackage + - wrapcheck + - nlreturn + - gomnd + - goerr113 + - exhaustivestruct + - errorlint + - nestif + - gofumpt + - godot + - gci + - dogsled + - paralleltest diff --git a/vendor/github.com/go-openapi/analysis/.travis.yml b/vendor/github.com/go-openapi/analysis/.travis.yml index c0196e12a6fb1..bd043d112a122 100644 --- a/vendor/github.com/go-openapi/analysis/.travis.yml +++ b/vendor/github.com/go-openapi/analysis/.travis.yml @@ -1,8 +1,11 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.13.x - 1.14.x +- 1.x +arch: + - amd64 + - ppc64le install: - go get -u gotest.tools/gotestsum language: go diff --git a/vendor/github.com/go-openapi/analysis/analyzer.go b/vendor/github.com/go-openapi/analysis/analyzer.go index 9341002100297..b34f15a2c58ee 100644 --- a/vendor/github.com/go-openapi/analysis/analyzer.go +++ b/vendor/github.com/go-openapi/analysis/analyzer.go @@ -212,7 +212,7 @@ func (s *Spec) initialize() { } } for path, pathItem := range s.AllPaths() { - s.analyzeOperations(path, &pathItem) + s.analyzeOperations(path, &pathItem) //#nosec } for name, parameter := range s.spec.Parameters { @@ -277,7 +277,7 @@ func (s *Spec) analyzeOperations(path string, pi *spec.PathItem) { for i, param := range op.Parameters { refPref := slashpath.Join("/paths", jsonpointer.Escape(path), "parameters", strconv.Itoa(i)) if param.Ref.String() != "" { - s.references.addParamRef(refPref, ¶m) + s.references.addParamRef(refPref, ¶m) //#nosec } if param.Pattern != "" { s.patterns.addParameterPattern(refPref, param.Pattern) @@ -335,7 +335,7 @@ func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) { for i, param := range op.Parameters { refPref := slashpath.Join(prefix, "parameters", strconv.Itoa(i)) if param.Ref.String() != "" { - s.references.addParamRef(refPref, ¶m) + s.references.addParamRef(refPref, ¶m) //#nosec } if param.Pattern != "" { s.patterns.addParameterPattern(refPref, param.Pattern) @@ -368,7 +368,7 @@ func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) { for k, res := range op.Responses.StatusCodeResponses { refPref := slashpath.Join(prefix, "responses", strconv.Itoa(k)) if res.Ref.String() != "" { - s.references.addResponseRef(refPref, &res) + s.references.addResponseRef(refPref, &res) //#nosec } for k, v := range res.Headers { hRefPref := slashpath.Join(refPref, "headers", k) @@ -665,25 +665,25 @@ func (s *Spec) SafeParametersFor(operationID string, callmeOnError ErrorOnParamF } for _, pi := range s.spec.Paths.Paths { if pi.Get != nil && pi.Get.ID == operationID { - return gatherParams(&pi, pi.Get) + return gatherParams(&pi, pi.Get) //#nosec } if pi.Head != nil && pi.Head.ID == operationID { - return gatherParams(&pi, pi.Head) + return gatherParams(&pi, pi.Head) //#nosec } if pi.Options != nil && pi.Options.ID == operationID { - return gatherParams(&pi, pi.Options) + return gatherParams(&pi, pi.Options) //#nosec } if pi.Post != nil && pi.Post.ID == operationID { - return gatherParams(&pi, pi.Post) + return gatherParams(&pi, pi.Post) //#nosec } if pi.Patch != nil && pi.Patch.ID == operationID { - return gatherParams(&pi, pi.Patch) + return gatherParams(&pi, pi.Patch) //#nosec } if pi.Put != nil && pi.Put.ID == operationID { - return gatherParams(&pi, pi.Put) + return gatherParams(&pi, pi.Put) //#nosec } if pi.Delete != nil && pi.Delete.ID == operationID { - return gatherParams(&pi, pi.Delete) + return gatherParams(&pi, pi.Delete) //#nosec } } return nil diff --git a/vendor/github.com/go-openapi/analysis/appveyor.yml b/vendor/github.com/go-openapi/analysis/appveyor.yml index 3239d74416a7d..f5b18767ac02b 100644 --- a/vendor/github.com/go-openapi/analysis/appveyor.yml +++ b/vendor/github.com/go-openapi/analysis/appveyor.yml @@ -17,7 +17,8 @@ environment: stack: go 1.12 test_script: - - go test -v -timeout 20m ./... + - echo "test disabled for now" + #- go test -v -timeout 20m ./... #artifacts: # - path: '%GOPATH%\bin\*.exe' deploy: off diff --git a/vendor/github.com/go-openapi/analysis/fixer.go b/vendor/github.com/go-openapi/analysis/fixer.go index bfe014ca51a8d..286922befc05d 100644 --- a/vendor/github.com/go-openapi/analysis/fixer.go +++ b/vendor/github.com/go-openapi/analysis/fixer.go @@ -50,7 +50,7 @@ func FixEmptyResponseDescriptions(s *spec.Swagger) { } } for k, v := range s.Responses { - FixEmptyDesc(&v) + FixEmptyDesc(&v) //#nosec s.Responses[k] = v } } @@ -60,7 +60,7 @@ func FixEmptyResponseDescriptions(s *spec.Swagger) { func FixEmptyDescs(rs *spec.Responses) { FixEmptyDesc(rs.Default) for k, v := range rs.StatusCodeResponses { - FixEmptyDesc(&v) + FixEmptyDesc(&v) //#nosec rs.StatusCodeResponses[k] = v } } diff --git a/vendor/github.com/go-openapi/analysis/flatten.go b/vendor/github.com/go-openapi/analysis/flatten.go index ab3f949c3022e..cb223c12fed8a 100644 --- a/vendor/github.com/go-openapi/analysis/flatten.go +++ b/vendor/github.com/go-openapi/analysis/flatten.go @@ -156,6 +156,8 @@ func Flatten(opts FlattenOpts) error { return err } + opts.Spec.reload() // re-analyze + // strip current file from $ref's, so we can recognize them as proper definitions // In particular, this works around for issue go-openapi/spec#76: leading absolute file in $ref is stripped if err := normalizeRef(&opts); err != nil { @@ -778,6 +780,9 @@ func rewriteParentRef(spec *swspec.Swagger, key string, ref swspec.Ref) error { } container.Schemas[idx] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}} + case swspec.SchemaProperties: + container[entry] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}} + // NOTE: can't have case *swspec.SchemaOrBool = parent in this case is *Schema default: @@ -1038,7 +1043,7 @@ func nameFromRef(ref swspec.Ref) string { return swag.ToJSONName(bn) } } - return swag.ToJSONName(strings.Replace(u.Host, ".", " ", -1)) + return swag.ToJSONName(strings.ReplaceAll(u.Host, ".", " ")) } func saveSchema(spec *swspec.Swagger, name string, schema *swspec.Schema) { @@ -1155,6 +1160,9 @@ func updateRef(spec interface{}, key string, ref swspec.Ref) error { } container.Schemas[idx] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}} + case swspec.SchemaProperties: + container[entry] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}} + // NOTE: can't have case *swspec.SchemaOrBool = parent in this case is *Schema default: @@ -1206,6 +1214,9 @@ func updateRefWithSchema(spec *swspec.Swagger, key string, sch *swspec.Schema) e } container.Schemas[idx] = *sch + case swspec.SchemaProperties: + container[entry] = *sch + // NOTE: can't have case *swspec.SchemaOrBool = parent in this case is *Schema default: @@ -1741,17 +1752,21 @@ DOWNREF: // leading absolute file in $ref is stripped func normalizeRef(opts *FlattenOpts) error { debugLog("normalizeRef") - opts.Spec.reload() // re-analyze + altered := false for k, w := range opts.Spec.references.allRefs { - if strings.HasPrefix(w.String(), opts.BasePath+definitionsPath) { // may be a mix of / and \, depending on OS - // strip base path from definition - debugLog("stripping absolute path for: %s", w.String()) - if err := updateRef(opts.Swagger(), k, - swspec.MustCreateRef(slashpath.Join(definitionsPath, slashpath.Base(w.String())))); err != nil { - return err - } + if !strings.HasPrefix(w.String(), opts.BasePath+definitionsPath) { // may be a mix of / and \, depending on OS + continue + } + altered = true + // strip base path from definition + debugLog("stripping absolute path for: %s", w.String()) + if err := updateRef(opts.Swagger(), k, + swspec.MustCreateRef(slashpath.Join(definitionsPath, slashpath.Base(w.String())))); err != nil { + return err } } - opts.Spec.reload() // re-analyze + if altered { + opts.Spec.reload() // re-analyze + } return nil } diff --git a/vendor/github.com/go-openapi/analysis/go.mod b/vendor/github.com/go-openapi/analysis/go.mod index 8dea2d99103df..df56b6a7669ec 100644 --- a/vendor/github.com/go-openapi/analysis/go.mod +++ b/vendor/github.com/go-openapi/analysis/go.mod @@ -1,23 +1,14 @@ module github.com/go-openapi/analysis require ( - github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 // indirect - github.com/go-openapi/errors v0.19.3 // indirect - github.com/go-openapi/jsonpointer v0.19.3 - github.com/go-openapi/jsonreference v0.19.3 // indirect - github.com/go-openapi/loads v0.19.0 - github.com/go-openapi/spec v0.19.6 - github.com/go-openapi/strfmt v0.19.4 - github.com/go-openapi/swag v0.19.7 - github.com/kr/pty v1.1.5 // indirect - github.com/mailru/easyjson v0.7.1 // indirect - github.com/stretchr/testify v1.3.0 - go.mongodb.org/mongo-driver v1.3.0 // indirect - golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 // indirect - golang.org/x/net v0.0.0-20200226121028-0de0cce0169b // indirect - golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f // indirect - golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 // indirect - gopkg.in/yaml.v2 v2.2.8 // indirect + github.com/go-openapi/errors v0.19.9 // indirect + github.com/go-openapi/jsonpointer v0.19.5 + github.com/go-openapi/loads v0.19.6 + github.com/go-openapi/spec v0.19.15 + github.com/go-openapi/strfmt v0.19.11 + github.com/go-openapi/swag v0.19.12 + github.com/mitchellh/mapstructure v1.4.0 // indirect + github.com/stretchr/testify v1.6.1 ) go 1.13 diff --git a/vendor/github.com/go-openapi/analysis/go.sum b/vendor/github.com/go-openapi/analysis/go.sum index 82636eaebe040..9eafaed3f5535 100644 --- a/vendor/github.com/go-openapi/analysis/go.sum +++ b/vendor/github.com/go-openapi/analysis/go.sum @@ -4,52 +4,114 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.3 h1:7MGZI1ibQDLasvAz8HuhvYk9eNJbJkCOXWsSjjMS+Zc= github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9 h1:9SnKdGhiPZHF3ttwFMiCBEb8jQ4IDdrK+5+a0oTygA4= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0 h1:wCOBNscACI8L93tt5tvB2zOMkJ098XCw3fP0BY2ybDA= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= +github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= +github.com/go-openapi/loads v0.19.6 h1:6IAtnx22MNSjPocZZ2sV7EjgF6wW5rDC9r6ZkNxjiN8= +github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/runtime v0.19.16 h1:tQMAY5s5BfmmCC31+ufDCsGrr8iO1A8UIdYfDo5ADvs= +github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.6 h1:rMMMj8cV38KVXK7SFc+I2MWClbEfbK705+j+dyqun5g= github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.15 h1:uxh8miNJEfMm8l8ekpY7i39LcORm1xSRtoipEGl1JPk= +github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= github.com/go-openapi/strfmt v0.19.2 h1:clPGfBnJohokno0e+d7hs6Yocrzjlgz6EsQSDncCRnE= github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/strfmt v0.19.3 h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA= github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/strfmt v0.19.4 h1:eRvaqAhpL0IL6Trh5fDsGnGhiXndzHFuA05w6sXH6/g= github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.5 h1:0utjKrw+BAh8s57XE9Xz8DUBsVvPmRUB6styvl9wWIM= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.11 h1:0+YvbNh05rmBkgztd6zHp4OCFn7Mtu30bn46NQo2ZRw= +github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.7 h1:VRuXN2EnMSsZdauzdss6JBC29YotDqG59BZ+tdlIL1s= github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI= +github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= +github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= +github.com/go-openapi/validate v0.19.12 h1:mPLM/bfbd00PGOCJlU0yJL7IulkZ+q9VjPv7U11RMQQ= +github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= @@ -80,11 +142,17 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -97,27 +165,43 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks= +github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -129,8 +213,12 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= go.mongodb.org/mongo-driver v1.0.3 h1:GKoji1ld3tw2aC+GX1wbr/J2fX13yNacEYoJ8Nhr0yU= @@ -139,44 +227,69 @@ go.mongodb.org/mongo-driver v1.1.1 h1:Sq1fR+0c58RME5EoqKdjkiQAmPjmfHlZOoRI6fTUOc go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.3.0 h1:ew6uUIeJOo+qdUUv7LxFCUhtWmVv7ZV/Xuy4FAUsw2E= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE= +go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.4.3 h1:moga+uhicpVshTyaqY9L23E6QqwcHRUv1sqyOsoyOO8= +go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= @@ -184,3 +297,12 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/go-openapi/analysis/schema.go b/vendor/github.com/go-openapi/analysis/schema.go index 398c7806394df..ceb4e564b572e 100644 --- a/vendor/github.com/go-openapi/analysis/schema.go +++ b/vendor/github.com/go-openapi/analysis/schema.go @@ -218,7 +218,7 @@ func (a *AnalyzedSchema) initializeFlags() { (a.schema.Items.Schema != nil || len(a.schema.Items.Schemas) > 0) a.hasAdditionalProps = a.schema.AdditionalProperties != nil && - (a.schema.AdditionalProperties != nil || a.schema.AdditionalProperties.Allows) + (a.schema.AdditionalProperties.Schema != nil || a.schema.AdditionalProperties.Allows) a.hasAdditionalItems = a.schema.AdditionalItems != nil && (a.schema.AdditionalItems.Schema != nil || a.schema.AdditionalItems.Allows) diff --git a/vendor/github.com/go-openapi/errors/.golangci.yml b/vendor/github.com/go-openapi/errors/.golangci.yml index 6badaf1549f84..f9381aee54193 100644 --- a/vendor/github.com/go-openapi/errors/.golangci.yml +++ b/vendor/github.com/go-openapi/errors/.golangci.yml @@ -18,3 +18,24 @@ linters: - maligned - lll - gochecknoglobals + - godox + - gocognit + - whitespace + - wsl + - funlen + - gochecknoglobals + - gochecknoinits + - scopelint + - wrapcheck + - exhaustivestruct + - exhaustive + - nlreturn + - testpackage + - gci + - gofumpt + - goerr113 + - gomnd + - tparallel + - nestif + - godot + - errorlint diff --git a/vendor/github.com/go-openapi/errors/.travis.yml b/vendor/github.com/go-openapi/errors/.travis.yml index 119ec69818584..e4a01bfd4fe91 100644 --- a/vendor/github.com/go-openapi/errors/.travis.yml +++ b/vendor/github.com/go-openapi/errors/.travis.yml @@ -1,8 +1,25 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.13.x - 1.14.x +- 1.x +arch: + - amd64 +jobs: + include: + # only run fast tests on ppc64le + - go: 1.x + arch: ppc64le + script: + - gotestsum -f short-verbose -- ./... + + # include linting job, but only for latest go version and amd64 arch + - go: 1.x + arch: amd64 + install: + go get github.com/golangci/golangci-lint/cmd/golangci-lint + script: + - golangci-lint run --new-from-rev master install: - GO111MODULE=off go get -u gotest.tools/gotestsum language: go diff --git a/vendor/github.com/go-openapi/errors/schema.go b/vendor/github.com/go-openapi/errors/schema.go index 1c0be5f2ac2ff..f4a7d4ac239e4 100644 --- a/vendor/github.com/go-openapi/errors/schema.go +++ b/vendor/github.com/go-openapi/errors/schema.go @@ -25,6 +25,7 @@ const ( typeFailWithData = "%s in %s must be of type %s: %q" typeFailWithError = "%s in %s must be of type %s, because: %s" requiredFail = "%s in %s is required" + readOnlyFail = "%s in %s is readOnly" tooLongMessage = "%s in %s should be at most %d chars long" tooShortMessage = "%s in %s should be at least %d chars long" patternFail = "%s in %s should match '%s'" @@ -41,6 +42,7 @@ const ( typeFailWithDataNoIn = "%s must be of type %s: %q" typeFailWithErrorNoIn = "%s must be of type %s, because: %s" requiredFailNoIn = "%s is required" + readOnlyFailNoIn = "%s is readOnly" tooLongMessageNoIn = "%s should be at most %d chars long" tooShortMessageNoIn = "%s should be at least %d chars long" patternFailNoIn = "%s should match '%s'" @@ -91,6 +93,7 @@ const ( UnallowedPropertyCode FailedAllPatternPropsCode MultipleOfMustBePositiveCode + ReadOnlyFailCode ) // CompositeError is an error that groups several errors together @@ -501,6 +504,23 @@ func Required(name, in string, value interface{}) *Validation { } } +// ReadOnly error for when a value is present in request +func ReadOnly(name, in string, value interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(readOnlyFailNoIn, name) + } else { + msg = fmt.Sprintf(readOnlyFail, name, in) + } + return &Validation{ + code: ReadOnlyFailCode, + Name: name, + In: in, + Value: value, + message: msg, + } +} + // TooLong error for when a string is too long func TooLong(name, in string, max int64, value interface{}) *Validation { var msg string diff --git a/vendor/github.com/go-openapi/jsonpointer/.travis.yml b/vendor/github.com/go-openapi/jsonpointer/.travis.yml index 9aef9184e86d2..03a22fe06fd8a 100644 --- a/vendor/github.com/go-openapi/jsonpointer/.travis.yml +++ b/vendor/github.com/go-openapi/jsonpointer/.travis.yml @@ -1,8 +1,8 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.11.x -- 1.12.x +- 1.14.x +- 1.15.x install: - GO111MODULE=off go get -u gotest.tools/gotestsum env: diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go index b284eb77a6280..7df9853def68c 100644 --- a/vendor/github.com/go-openapi/jsonpointer/pointer.go +++ b/vendor/github.com/go-openapi/jsonpointer/pointer.go @@ -114,16 +114,16 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam rValue := reflect.Indirect(reflect.ValueOf(node)) kind := rValue.Kind() - switch kind { + if rValue.Type().Implements(jsonPointableType) { + r, err := node.(JSONPointable).JSONLookup(decodedToken) + if err != nil { + return nil, kind, err + } + return r, kind, nil + } + switch kind { case reflect.Struct: - if rValue.Type().Implements(jsonPointableType) { - r, err := node.(JSONPointable).JSONLookup(decodedToken) - if err != nil { - return nil, kind, err - } - return r, kind, nil - } nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { return nil, kind, fmt.Errorf("object has no field %q", decodedToken) @@ -161,17 +161,17 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error { rValue := reflect.Indirect(reflect.ValueOf(node)) - switch rValue.Kind() { - case reflect.Struct: - if ns, ok := node.(JSONSetable); ok { // pointer impl - return ns.JSONSet(decodedToken, data) - } + if ns, ok := node.(JSONSetable); ok { // pointer impl + return ns.JSONSet(decodedToken, data) + } - if rValue.Type().Implements(jsonSetableType) { - return node.(JSONSetable).JSONSet(decodedToken, data) - } + if rValue.Type().Implements(jsonSetableType) { + return node.(JSONSetable).JSONSet(decodedToken, data) + } + switch rValue.Kind() { + case reflect.Struct: nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { return fmt.Errorf("object has no field %q", decodedToken) @@ -270,22 +270,22 @@ func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) e rValue := reflect.Indirect(reflect.ValueOf(node)) kind := rValue.Kind() - switch kind { - - case reflect.Struct: - if rValue.Type().Implements(jsonPointableType) { - r, err := node.(JSONPointable).JSONLookup(decodedToken) - if err != nil { - return err - } - fld := reflect.ValueOf(r) - if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr { - node = fld.Addr().Interface() - continue - } - node = r + if rValue.Type().Implements(jsonPointableType) { + r, err := node.(JSONPointable).JSONLookup(decodedToken) + if err != nil { + return err + } + fld := reflect.ValueOf(r) + if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr { + node = fld.Addr().Interface() continue } + node = r + continue + } + + switch kind { + case reflect.Struct: nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { return fmt.Errorf("object has no field %q", decodedToken) diff --git a/vendor/github.com/go-openapi/jsonreference/.golangci.yml b/vendor/github.com/go-openapi/jsonreference/.golangci.yml new file mode 100644 index 0000000000000..f9381aee54193 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonreference/.golangci.yml @@ -0,0 +1,41 @@ +linters-settings: + govet: + check-shadowing: true + golint: + min-confidence: 0 + gocyclo: + min-complexity: 30 + maligned: + suggest-new: true + dupl: + threshold: 100 + goconst: + min-len: 2 + min-occurrences: 4 +linters: + enable-all: true + disable: + - maligned + - lll + - gochecknoglobals + - godox + - gocognit + - whitespace + - wsl + - funlen + - gochecknoglobals + - gochecknoinits + - scopelint + - wrapcheck + - exhaustivestruct + - exhaustive + - nlreturn + - testpackage + - gci + - gofumpt + - goerr113 + - gomnd + - tparallel + - nestif + - godot + - errorlint diff --git a/vendor/github.com/go-openapi/jsonreference/.travis.yml b/vendor/github.com/go-openapi/jsonreference/.travis.yml index 40b90757d8946..05482f4b90cb9 100644 --- a/vendor/github.com/go-openapi/jsonreference/.travis.yml +++ b/vendor/github.com/go-openapi/jsonreference/.travis.yml @@ -1,10 +1,19 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.11.x -- 1.12.x +- 1.14.x +- 1.x install: -- GO111MODULE=off go get -u gotest.tools/gotestsum +- go get gotest.tools/gotestsum +jobs: + include: + # include linting job, but only for latest go version and amd64 arch + - go: 1.x + arch: amd64 + install: + go get github.com/golangci/golangci-lint/cmd/golangci-lint + script: + - golangci-lint run --new-from-rev master env: - GO111MODULE=on language: go diff --git a/vendor/github.com/go-openapi/loads/.golangci.yml b/vendor/github.com/go-openapi/loads/.golangci.yml index 1932914e6d1a7..d48b4a5156e24 100644 --- a/vendor/github.com/go-openapi/loads/.golangci.yml +++ b/vendor/github.com/go-openapi/loads/.golangci.yml @@ -20,3 +20,25 @@ linters: - lll - gochecknoglobals - gochecknoinits + - godox + - gocognit + - whitespace + - wsl + - funlen + - gochecknoglobals + - gochecknoinits + - scopelint + - wrapcheck + - exhaustivestruct + - exhaustive + - nlreturn + - testpackage + - gci + - gofumpt + - goerr113 + - gomnd + - tparallel + - nestif + - godot + - errorlint + - paralleltest diff --git a/vendor/github.com/go-openapi/loads/.travis.yml b/vendor/github.com/go-openapi/loads/.travis.yml index 6bf906ec09455..9a65c1296e365 100644 --- a/vendor/github.com/go-openapi/loads/.travis.yml +++ b/vendor/github.com/go-openapi/loads/.travis.yml @@ -1,11 +1,20 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.13.x - 1.14.x +- 1.x install: -- go get -u gotest.tools/gotestsum +- go get gotest.tools/gotestsum language: go +jobs: + include: + # include linting job, but only for latest go version and amd64 arch + - go: 1.x + arch: amd64 + install: + go get github.com/golangci/golangci-lint/cmd/golangci-lint + script: + - golangci-lint run --new-from-rev master notifications: slack: secure: OxkPwVp35qBTUilgWC8xykSj+sGMcj0h8IIOKD+Rflx2schZVlFfdYdyVBM+s9OqeOfvtuvnR9v1Ye2rPKAvcjWdC4LpRGUsgmItZaI6Um8Aj6+K9udCw5qrtZVfOVmRu8LieH//XznWWKdOultUuniW0MLqw5+II87Gd00RWbCGi0hk0PykHe7uK+PDA2BEbqyZ2WKKYCvfB3j+0nrFOHScXqnh0V05l2E83J4+Sgy1fsPy+1WdX58ZlNBG333ibaC1FS79XvKSmTgKRkx3+YBo97u6ZtUmJa5WZjf2OdLG3KIckGWAv6R5xgxeU31N0Ng8L332w/Edpp2O/M2bZwdnKJ8hJQikXIAQbICbr+lTDzsoNzMdEIYcHpJ5hjPbiUl3Bmd+Jnsjf5McgAZDiWIfpCKZ29tPCEkVwRsOCqkyPRMNMzHHmoja495P5jR+ODS7+J8RFg5xgcnOgpP9D4Wlhztlf5WyZMpkLxTUD+bZq2SRf50HfHFXTkfq22zPl3d1eq0yrLwh/Z/fWKkfb6SyysROL8y6s8u3dpFX1YHSg0BR6i913h4aoZw9B2BG27cafLLTwKYsp2dFo1PWl4O6u9giFJIeqwloZHLKKrwh0cBFhB7RH0I58asxkZpCH6uWjJierahmHe7iS+E6i+9oCHkOZ59hmCYNimIs3hM= diff --git a/vendor/github.com/go-openapi/loads/README.md b/vendor/github.com/go-openapi/loads/README.md index 071cf69ab97c3..8071d6c95c454 100644 --- a/vendor/github.com/go-openapi/loads/README.md +++ b/vendor/github.com/go-openapi/loads/README.md @@ -1,7 +1,6 @@ # Loads OAI specs [![Build Status](https://travis-ci.org/go-openapi/loads.svg?branch=master)](https://travis-ci.org/go-openapi/loads) [![codecov](https://codecov.io/gh/go-openapi/loads/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/loads) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/loads/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/loads?status.svg)](http://godoc.org/github.com/go-openapi/loads) -[![GolangCI](https://golangci.com/badges/github.com/go-openapi/loads.svg)](https://golangci.com) [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/loads)](https://goreportcard.com/report/github.com/go-openapi/loads) Loading of OAI specification documents from local or remote locations. Supports JSON and YAML documents. diff --git a/vendor/github.com/go-openapi/loads/go.mod b/vendor/github.com/go-openapi/loads/go.mod index 54e5d98c921dd..47d216f8c8ad1 100644 --- a/vendor/github.com/go-openapi/loads/go.mod +++ b/vendor/github.com/go-openapi/loads/go.mod @@ -1,11 +1,15 @@ module github.com/go-openapi/loads require ( - github.com/go-openapi/analysis v0.19.10 - github.com/go-openapi/spec v0.19.6 - github.com/go-openapi/swag v0.19.7 - github.com/stretchr/testify v1.3.0 - gopkg.in/yaml.v2 v2.2.8 + github.com/go-openapi/analysis v0.19.16 + github.com/go-openapi/spec v0.20.0 + github.com/go-openapi/strfmt v0.19.11 + github.com/go-openapi/swag v0.19.12 + github.com/go-openapi/validate v0.19.15 + github.com/stretchr/testify v1.6.1 + go.mongodb.org/mongo-driver v1.4.4 // indirect + golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb // indirect + gopkg.in/yaml.v2 v2.4.0 ) go 1.13 diff --git a/vendor/github.com/go-openapi/loads/go.sum b/vendor/github.com/go-openapi/loads/go.sum index ec9a40102592f..5492541726e13 100644 --- a/vendor/github.com/go-openapi/loads/go.sum +++ b/vendor/github.com/go-openapi/loads/go.sum @@ -4,47 +4,121 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= github.com/go-openapi/analysis v0.19.10 h1:5BHISBAXOc/aJK25irLZnx2D3s6WyYaY9D4gmuz9fdE= github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= +github.com/go-openapi/analysis v0.19.16 h1:Ub9e++M8sDwtHD+S587TYi+6ANBG1NRYGZDihqk0SaY= +github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.3 h1:7MGZI1ibQDLasvAz8HuhvYk9eNJbJkCOXWsSjjMS+Zc= github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.7 h1:Lcq+o0mSwCLKACMxZhreVHigB9ebghJ/lrmeaqASbjo= +github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9 h1:9SnKdGhiPZHF3ttwFMiCBEb8jQ4IDdrK+5+a0oTygA4= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= +github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= +github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/runtime v0.19.16 h1:tQMAY5s5BfmmCC31+ufDCsGrr8iO1A8UIdYfDo5ADvs= +github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= +github.com/go-openapi/runtime v0.19.24 h1:TqagMVlRAOTwllE/7hNKx6rQ10O6T8ZzeJdMjSTKaD4= +github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.6 h1:rMMMj8cV38KVXK7SFc+I2MWClbEfbK705+j+dyqun5g= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.0 h1:HGLc8AJ7ynOxwv0Lq4TsnwLsWMawHAYiJIFzbcML86I= +github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/strfmt v0.19.4 h1:eRvaqAhpL0IL6Trh5fDsGnGhiXndzHFuA05w6sXH6/g= github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.5 h1:0utjKrw+BAh8s57XE9Xz8DUBsVvPmRUB6styvl9wWIM= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.11 h1:0+YvbNh05rmBkgztd6zHp4OCFn7Mtu30bn46NQo2ZRw= +github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.7 h1:VRuXN2EnMSsZdauzdss6JBC29YotDqG59BZ+tdlIL1s= github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4azE= +github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI= +github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= +github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= +github.com/go-openapi/validate v0.19.12 h1:mPLM/bfbd00PGOCJlU0yJL7IulkZ+q9VjPv7U11RMQQ= +github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= +github.com/go-openapi/validate v0.19.15 h1:oUHZO8jD7p5oRLANlXF0U8ic9ePBUkDQyRZdN0EhL6M= +github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= @@ -75,11 +149,17 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -92,27 +172,43 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks= +github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -120,56 +216,91 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= go.mongodb.org/mongo-driver v1.0.3 h1:GKoji1ld3tw2aC+GX1wbr/J2fX13yNacEYoJ8Nhr0yU= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.3.0 h1:ew6uUIeJOo+qdUUv7LxFCUhtWmVv7ZV/Xuy4FAUsw2E= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE= +go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.4.3 h1:moga+uhicpVshTyaqY9L23E6QqwcHRUv1sqyOsoyOO8= +go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.4 h1:bsPHfODES+/yx2PCWzUYMH8xj6PVniPI8DQrsJuSXSs= +go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= @@ -178,3 +309,12 @@ gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/go-openapi/loads/loaders.go b/vendor/github.com/go-openapi/loads/loaders.go new file mode 100644 index 0000000000000..9618b0d6d183d --- /dev/null +++ b/vendor/github.com/go-openapi/loads/loaders.go @@ -0,0 +1,137 @@ +package loads + +import ( + "encoding/json" + "errors" + "net/url" + + "github.com/go-openapi/spec" + "github.com/go-openapi/swag" +) + +var ( + // Default chain of loaders, defined at the package level. + // + // By default this matches json and yaml documents. + // + // May be altered with AddLoader(). + loaders *loader + + // Default loader. This expects json documents over local or http/https (no matching). + defaultLoader *loader + + defaultMatcher DocMatcher +) + +func init() { + defaultMatcher = func(_ string) bool { return true } + + defaultLoader = &loader{ + DocLoaderWithMatch: DocLoaderWithMatch{ + Match: defaultMatcher, + Fn: JSONDoc, + }, + } + loaders = defaultLoader + + AddLoader(swag.YAMLMatcher, swag.YAMLDoc) + + // sets the global default loader for go-openapi/spec + spec.PathLoader = loaders.Load +} + +// DocLoader represents a doc loader type +type DocLoader func(string) (json.RawMessage, error) + +// DocMatcher represents a predicate to check if a loader matches +type DocMatcher func(string) bool + +// DocLoaderWithMatch describes a loading function for a given extension match. +type DocLoaderWithMatch struct { + Fn DocLoader + Match DocMatcher +} + +// NewDocLoaderWithMatch builds a DocLoaderWithMatch to be used in load options +func NewDocLoaderWithMatch(fn DocLoader, matcher DocMatcher) DocLoaderWithMatch { + return DocLoaderWithMatch{ + Fn: fn, + Match: matcher, + } +} + +type loader struct { + DocLoaderWithMatch + Next *loader +} + +// WithHead adds a loader at the head of the current stack +func (l *loader) WithHead(head *loader) *loader { + if head == nil { + return l + } + head.Next = l + return head +} + +// WithNext adds a loader at the trail of the current stack +func (l *loader) WithNext(next *loader) *loader { + l.Next = next + return next +} + +// Load the raw document from path +func (l *loader) Load(path string) (json.RawMessage, error) { + specURL, erp := url.Parse(path) + if erp != nil { + return nil, erp + } + + var lastErr error = errors.New("no loader matched") // default error if no match was found + for ldr := l; ldr != nil; ldr = ldr.Next { + if ldr.Match != nil && !ldr.Match(specURL.Path) { + continue + } + + // try then move to next one if there is an error + b, err := ldr.Fn(path) + if err == nil { + return b, nil + } + + lastErr = err + } + + return nil, lastErr +} + +// JSONDoc loads a json document from either a file or a remote url +func JSONDoc(path string) (json.RawMessage, error) { + data, err := swag.LoadFromFileOrHTTP(path) + if err != nil { + return nil, err + } + return json.RawMessage(data), nil +} + +// AddLoader for a document, executed before other previously set loaders. +// +// This sets the configuration at the package level. +// +// The default initial loader at the package level assumes a JSON document. +// +// NOTE: +// * this updates the default loader used by github.com/go-openapi/spec +// * since this sets package level globals, you shouln't call this concurrently +// +func AddLoader(predicate DocMatcher, load DocLoader) { + loaders = loaders.WithHead(&loader{ + DocLoaderWithMatch: DocLoaderWithMatch{ + Match: predicate, + Fn: load, + }, + }) + + // sets the global default loader for go-openapi/spec + spec.PathLoader = loaders.Load +} diff --git a/vendor/github.com/go-openapi/loads/options.go b/vendor/github.com/go-openapi/loads/options.go new file mode 100644 index 0000000000000..b04c847a5f38e --- /dev/null +++ b/vendor/github.com/go-openapi/loads/options.go @@ -0,0 +1,60 @@ +package loads + +type options struct { + loader *loader +} + +func defaultOptions() *options { + return &options{ + loader: loaders, + } +} + +func loaderFromOptions(options []LoaderOption) *loader { + opts := defaultOptions() + for _, apply := range options { + apply(opts) + } + return opts.loader +} + +// LoaderOption allows to fine-tune the spec loader behavior +type LoaderOption func(*options) + +// WithDocLoader sets a custom loader for loading specs +func WithDocLoader(l DocLoader) LoaderOption { + return func(opt *options) { + if l == nil { + return + } + opt.loader = &loader{ + DocLoaderWithMatch: DocLoaderWithMatch{ + Fn: l, + }, + } + } +} + +// WithDocLoaderMatches sets a chain of custom loaders for loading specs +// for different extension matches. +// +// Loaders are executed in the order of provided DocLoaderWithMatch'es. +func WithDocLoaderMatches(l ...DocLoaderWithMatch) LoaderOption { + return func(opt *options) { + var final, prev *loader + for _, ldr := range l { + if ldr.Fn == nil { + continue + } + + if prev == nil { + final = &loader{DocLoaderWithMatch: ldr} + prev = final + continue + } + + prev = prev.WithNext(&loader{DocLoaderWithMatch: ldr}) + } + opt.loader = final + } +} diff --git a/vendor/github.com/go-openapi/loads/spec.go b/vendor/github.com/go-openapi/loads/spec.go index e4b4a3cf7638a..df95a3f08b175 100644 --- a/vendor/github.com/go-openapi/loads/spec.go +++ b/vendor/github.com/go-openapi/loads/spec.go @@ -19,69 +19,16 @@ import ( "encoding/gob" "encoding/json" "fmt" - "net/url" "github.com/go-openapi/analysis" "github.com/go-openapi/spec" "github.com/go-openapi/swag" ) -// JSONDoc loads a json document from either a file or a remote url -func JSONDoc(path string) (json.RawMessage, error) { - data, err := swag.LoadFromFileOrHTTP(path) - if err != nil { - return nil, err - } - return json.RawMessage(data), nil -} - -// DocLoader represents a doc loader type -type DocLoader func(string) (json.RawMessage, error) - -// DocMatcher represents a predicate to check if a loader matches -type DocMatcher func(string) bool - -var ( - loaders *loader - defaultLoader *loader -) - func init() { - defaultLoader = &loader{Match: func(_ string) bool { return true }, Fn: JSONDoc} - loaders = defaultLoader - spec.PathLoader = loaders.Fn - AddLoader(swag.YAMLMatcher, swag.YAMLDoc) - gob.Register(map[string]interface{}{}) gob.Register([]interface{}{}) - //gob.Register(spec.Refable{}) -} - -// AddLoader for a document -func AddLoader(predicate DocMatcher, load DocLoader) { - prev := loaders - loaders = &loader{ - Match: predicate, - Fn: load, - Next: prev, - } - spec.PathLoader = loaders.Fn -} - -type loader struct { - Fn DocLoader - Match DocMatcher - Next *loader -} - -// JSONSpec loads a spec from a json document -func JSONSpec(path string) (*Document, error) { - data, err := JSONDoc(path) - if err != nil { - return nil, err - } - // convert to json - return Analyzed(data, "") + // gob.Register(spec.Refable{}) } // Document represents a swagger spec document @@ -93,10 +40,21 @@ type Document struct { origSpec *spec.Swagger schema *spec.Schema raw json.RawMessage + pathLoader *loader +} + +// JSONSpec loads a spec from a json document +func JSONSpec(path string, options ...LoaderOption) (*Document, error) { + data, err := JSONDoc(path) + if err != nil { + return nil, err + } + // convert to json + return Analyzed(data, "", options...) } // Embedded returns a Document based on embedded specs. No analysis is required -func Embedded(orig, flat json.RawMessage) (*Document, error) { +func Embedded(orig, flat json.RawMessage, options ...LoaderOption) (*Document, error) { var origSpec, flatSpec spec.Swagger if err := json.Unmarshal(orig, &origSpec); err != nil { return nil, err @@ -105,45 +63,26 @@ func Embedded(orig, flat json.RawMessage) (*Document, error) { return nil, err } return &Document{ - raw: orig, - origSpec: &origSpec, - spec: &flatSpec, + raw: orig, + origSpec: &origSpec, + spec: &flatSpec, + pathLoader: loaderFromOptions(options), }, nil } -// Spec loads a new spec document -func Spec(path string) (*Document, error) { - specURL, err := url.Parse(path) +// Spec loads a new spec document from a local or remote path +func Spec(path string, options ...LoaderOption) (*Document, error) { + + b, err := loaderFromOptions(options).Load(path) if err != nil { return nil, err } - var lastErr error - for l := loaders.Next; l != nil; l = l.Next { - if loaders.Match(specURL.Path) { - b, err2 := loaders.Fn(path) - if err2 != nil { - lastErr = err2 - continue - } - doc, err3 := Analyzed(b, "") - if err3 != nil { - return nil, err3 - } - if doc != nil { - doc.specFilePath = path - } - return doc, nil - } - } - if lastErr != nil { - return nil, lastErr - } - b, err := defaultLoader.Fn(path) + + document, err := Analyzed(b, "", options...) if err != nil { return nil, err } - document, err := Analyzed(b, "") if document != nil { document.specFilePath = path } @@ -151,8 +90,8 @@ func Spec(path string) (*Document, error) { return document, err } -// Analyzed creates a new analyzed spec document -func Analyzed(data json.RawMessage, version string) (*Document, error) { +// Analyzed creates a new analyzed spec document for a root json.RawMessage. +func Analyzed(data json.RawMessage, version string, options ...LoaderOption) (*Document, error) { if version == "" { version = "2.0" } @@ -160,24 +99,13 @@ func Analyzed(data json.RawMessage, version string) (*Document, error) { return nil, fmt.Errorf("spec version %q is not supported", version) } - raw := data - trimmed := bytes.TrimSpace(data) - if len(trimmed) > 0 { - if trimmed[0] != '{' && trimmed[0] != '[' { - yml, err := swag.BytesToYAMLDoc(trimmed) - if err != nil { - return nil, fmt.Errorf("analyzed: %v", err) - } - d, err := swag.YAMLToJSON(yml) - if err != nil { - return nil, fmt.Errorf("analyzed: %v", err) - } - raw = d - } + raw, err := trimData(data) // trim blanks, then convert yaml docs into json + if err != nil { + return nil, err } swspec := new(spec.Swagger) - if err := json.Unmarshal(raw, swspec); err != nil { + if err = json.Unmarshal(raw, swspec); err != nil { return nil, err } @@ -187,12 +115,38 @@ func Analyzed(data json.RawMessage, version string) (*Document, error) { } d := &Document{ - Analyzer: analysis.New(swspec), - schema: spec.MustLoadSwagger20Schema(), - spec: swspec, - raw: raw, - origSpec: origsqspec, + Analyzer: analysis.New(swspec), + schema: spec.MustLoadSwagger20Schema(), + spec: swspec, + raw: raw, + origSpec: origsqspec, + pathLoader: loaderFromOptions(options), + } + + return d, nil +} + +func trimData(in json.RawMessage) (json.RawMessage, error) { + trimmed := bytes.TrimSpace(in) + if len(trimmed) == 0 { + return in, nil + } + + if trimmed[0] == '{' || trimmed[0] == '[' { + return trimmed, nil + } + + // assume yaml doc: convert it to json + yml, err := swag.BytesToYAMLDoc(trimmed) + if err != nil { + return nil, fmt.Errorf("analyzed: %v", err) } + + d, err := swag.YAMLToJSON(yml) + if err != nil { + return nil, fmt.Errorf("analyzed: %v", err) + } + return d, nil } @@ -212,6 +166,16 @@ func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) { } } + if expandOptions.PathLoader == nil { + if d.pathLoader != nil { + // use loader from Document options + expandOptions.PathLoader = d.pathLoader.Load + } else { + // use package level loader + expandOptions.PathLoader = loaders.Load + } + } + if err := spec.ExpandSpec(swspec, expandOptions); err != nil { return nil, err } @@ -262,7 +226,7 @@ func (d *Document) OrigSpec() *spec.Swagger { return d.origSpec } -// ResetDefinitions gives a shallow copy with the models reset +// ResetDefinitions gives a shallow copy with the models reset to the original spec func (d *Document) ResetDefinitions() *Document { defs := make(map[string]spec.Schema, len(d.origSpec.Definitions)) for k, v := range d.origSpec.Definitions { diff --git a/vendor/github.com/go-openapi/runtime/.golangci.yml b/vendor/github.com/go-openapi/runtime/.golangci.yml new file mode 100644 index 0000000000000..71629d4ddd709 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/.golangci.yml @@ -0,0 +1,42 @@ +linters-settings: + govet: + check-shadowing: true + golint: + min-confidence: 0 + gocyclo: + min-complexity: 30 + maligned: + suggest-new: true + dupl: + threshold: 100 + goconst: + min-len: 2 + min-occurrences: 4 +linters: + enable-all: true + disable: + - maligned + - lll + - gochecknoglobals + - godox + - gocognit + - whitespace + - wsl + - funlen + - gochecknoglobals + - gochecknoinits + - scopelint + - wrapcheck + - exhaustivestruct + - exhaustive + - nlreturn + - testpackage + - gci + - gofumpt + - goerr113 + - gomnd + - tparallel + - nestif + - godot + - errorlint + - noctx diff --git a/vendor/github.com/go-openapi/runtime/.travis.yml b/vendor/github.com/go-openapi/runtime/.travis.yml index e36276ab3fa7c..78cdc892fa45e 100644 --- a/vendor/github.com/go-openapi/runtime/.travis.yml +++ b/vendor/github.com/go-openapi/runtime/.travis.yml @@ -1,10 +1,19 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.13.x - 1.14.x +- 1.x install: - GO111MODULE=off go get -u gotest.tools/gotestsum +jobs: + include: + # include linting job, but only for latest go version and amd64 arch + - go: 1.x + arch: amd64 + install: + go get github.com/golangci/golangci-lint/cmd/golangci-lint + script: + - golangci-lint run --new-from-rev master language: go notifications: slack: diff --git a/vendor/github.com/go-openapi/runtime/client_request.go b/vendor/github.com/go-openapi/runtime/client_request.go index 6215e0a1c1fcc..3efda34821690 100644 --- a/vendor/github.com/go-openapi/runtime/client_request.go +++ b/vendor/github.com/go-openapi/runtime/client_request.go @@ -101,3 +101,53 @@ func (n *namedReadCloser) Read(p []byte) (int, error) { func (n *namedReadCloser) Name() string { return n.name } + +type TestClientRequest struct { + Headers http.Header + Body interface{} +} + +func (t *TestClientRequest) SetHeaderParam(name string, values ...string) error { + if t.Headers == nil { + t.Headers = make(http.Header) + } + t.Headers.Set(name, values[0]) + return nil +} + +func (t *TestClientRequest) SetQueryParam(_ string, _ ...string) error { return nil } + +func (t *TestClientRequest) SetFormParam(_ string, _ ...string) error { return nil } + +func (t *TestClientRequest) SetPathParam(_ string, _ string) error { return nil } + +func (t *TestClientRequest) SetFileParam(_ string, _ ...NamedReadCloser) error { return nil } + +func (t *TestClientRequest) SetBodyParam(body interface{}) error { + t.Body = body + return nil +} + +func (t *TestClientRequest) SetTimeout(time.Duration) error { + return nil +} + +func (t *TestClientRequest) GetQueryParams() url.Values { return nil } + +func (t *TestClientRequest) GetMethod() string { return "" } + +func (t *TestClientRequest) GetPath() string { return "" } + +func (t *TestClientRequest) GetBody() []byte { return nil } + +func (t *TestClientRequest) GetBodyParam() interface{} { + return t.Body +} + +func (t *TestClientRequest) GetFileParam() map[string][]NamedReadCloser { + return nil +} + +func (t *TestClientRequest) GetHeaderParams() http.Header { + return t.Headers +} diff --git a/vendor/github.com/go-openapi/runtime/go.mod b/vendor/github.com/go-openapi/runtime/go.mod index 3effc2817e688..6fcf0fe65cfcc 100644 --- a/vendor/github.com/go-openapi/runtime/go.mod +++ b/vendor/github.com/go-openapi/runtime/go.mod @@ -9,6 +9,7 @@ require ( github.com/go-openapi/strfmt v0.19.5 github.com/go-openapi/swag v0.19.9 github.com/go-openapi/validate v0.19.10 + github.com/opentracing/opentracing-go v1.2.0 github.com/stretchr/testify v1.6.1 gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect diff --git a/vendor/github.com/go-openapi/runtime/go.sum b/vendor/github.com/go-openapi/runtime/go.sum index 5cadebb499f71..27801d87ffe2a 100644 --- a/vendor/github.com/go-openapi/runtime/go.sum +++ b/vendor/github.com/go-openapi/runtime/go.sum @@ -168,6 +168,8 @@ github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/vendor/github.com/go-openapi/runtime/interfaces.go b/vendor/github.com/go-openapi/runtime/interfaces.go index 65de0aa44b961..e334128683474 100644 --- a/vendor/github.com/go-openapi/runtime/interfaces.go +++ b/vendor/github.com/go-openapi/runtime/interfaces.go @@ -15,6 +15,7 @@ package runtime import ( + "context" "io" "net/http" @@ -101,3 +102,11 @@ type Authorizer interface { type Validatable interface { Validate(strfmt.Registry) error } + +// ContextValidatable types implementing this interface allow customizing their validation +// this will be used instead of the reflective validation based on the spec document. +// the implementations are assumed to have been generated by the swagger tool so they should +// contain all the context validations obtained from the spec +type ContextValidatable interface { + ContextValidate(context.Context, strfmt.Registry) error +} diff --git a/vendor/github.com/go-openapi/runtime/middleware/context.go b/vendor/github.com/go-openapi/runtime/middleware/context.go index fba5748db56eb..250e35fb0e148 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/context.go +++ b/vendor/github.com/go-openapi/runtime/middleware/context.go @@ -435,6 +435,10 @@ func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interfa } if route.Authorizer != nil { if err := route.Authorizer.Authorize(request, usr); err != nil { + if _, ok := err.(errors.Error); ok { + return nil, nil, err + } + return nil, nil, errors.New(http.StatusForbidden, err.Error()) } } diff --git a/vendor/github.com/go-openapi/runtime/middleware/denco/router.go b/vendor/github.com/go-openapi/runtime/middleware/denco/router.go index ecacc31ff6853..5d2691ec3698e 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/denco/router.go +++ b/vendor/github.com/go-openapi/runtime/middleware/denco/router.go @@ -20,6 +20,9 @@ const ( // SeparatorCharacter separates path segments. SeparatorCharacter = '/' + // PathParamCharacter indicates a RESTCONF path param + PathParamCharacter = '=' + // MaxSize is max size of records and internal slice. MaxSize = (1 << 22) - 1 ) @@ -426,8 +429,9 @@ func makeRecords(srcs []Record) (statics, params []*record) { termChar := string(TerminationCharacter) paramPrefix := string(SeparatorCharacter) + string(ParamCharacter) wildcardPrefix := string(SeparatorCharacter) + string(WildcardCharacter) + restconfPrefix := string(PathParamCharacter) + string(ParamCharacter) for _, r := range srcs { - if strings.Contains(r.Key, paramPrefix) || strings.Contains(r.Key, wildcardPrefix) { + if strings.Contains(r.Key, paramPrefix) || strings.Contains(r.Key, wildcardPrefix) ||strings.Contains(r.Key, restconfPrefix){ r.Key += termChar params = append(params, &record{Record: r}) } else { diff --git a/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go b/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go new file mode 100644 index 0000000000000..4be330d6dc342 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go @@ -0,0 +1,90 @@ +package middleware + +import ( + "bytes" + "fmt" + "html/template" + "net/http" + "path" +) + +// RapiDocOpts configures the RapiDoc middlewares +type RapiDocOpts struct { + // BasePath for the UI path, defaults to: / + BasePath string + // Path combines with BasePath for the full UI path, defaults to: docs + Path string + // SpecURL the url to find the spec for + SpecURL string + // RapiDocURL for the js that generates the rapidoc site, defaults to: https://cdn.jsdelivr.net/npm/rapidoc/bundles/rapidoc.standalone.js + RapiDocURL string + // Title for the documentation site, default to: API documentation + Title string +} + +// EnsureDefaults in case some options are missing +func (r *RapiDocOpts) EnsureDefaults() { + if r.BasePath == "" { + r.BasePath = "/" + } + if r.Path == "" { + r.Path = "docs" + } + if r.SpecURL == "" { + r.SpecURL = "/swagger.json" + } + if r.RapiDocURL == "" { + r.RapiDocURL = rapidocLatest + } + if r.Title == "" { + r.Title = "API documentation" + } +} + +// RapiDoc creates a middleware to serve a documentation site for a swagger spec. +// This allows for altering the spec before starting the http listener. +// +func RapiDoc(opts RapiDocOpts, next http.Handler) http.Handler { + opts.EnsureDefaults() + + pth := path.Join(opts.BasePath, opts.Path) + tmpl := template.Must(template.New("rapidoc").Parse(rapidocTemplate)) + + buf := bytes.NewBuffer(nil) + _ = tmpl.Execute(buf, opts) + b := buf.Bytes() + + return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + if r.URL.Path == pth { + rw.Header().Set("Content-Type", "text/html; charset=utf-8") + rw.WriteHeader(http.StatusOK) + + _, _ = rw.Write(b) + return + } + + if next == nil { + rw.Header().Set("Content-Type", "text/plain") + rw.WriteHeader(http.StatusNotFound) + _, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth))) + return + } + next.ServeHTTP(rw, r) + }) +} + +const ( + rapidocLatest = "https://unpkg.com/rapidoc/dist/rapidoc-min.js" + rapidocTemplate = ` + + + {{ .Title }} + + + + + + + +` +) diff --git a/vendor/github.com/go-openapi/runtime/middleware/router.go b/vendor/github.com/go-openapi/runtime/middleware/router.go index 02768bade28db..5052031c8d71f 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/router.go +++ b/vendor/github.com/go-openapi/runtime/middleware/router.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/go-openapi/runtime/security" + "github.com/go-openapi/swag" "github.com/go-openapi/analysis" "github.com/go-openapi/errors" @@ -418,6 +419,15 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper produces := d.analyzer.ProducesFor(operation) parameters := d.analyzer.ParamsFor(method, strings.TrimPrefix(path, bp)) + // add API defaults if not part of the spec + if defConsumes := d.api.DefaultConsumes(); defConsumes != "" && !swag.ContainsStringsCI(consumes, defConsumes) { + consumes = append(consumes, defConsumes) + } + + if defProduces := d.api.DefaultProduces(); defProduces != "" && !swag.ContainsStringsCI(produces, defProduces) { + produces = append(produces, defProduces) + } + record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{ BasePath: bp, PathPattern: path, diff --git a/vendor/github.com/go-openapi/spec/.golangci.yml b/vendor/github.com/go-openapi/spec/.golangci.yml index 4e17ed4979b46..a5e323979961c 100644 --- a/vendor/github.com/go-openapi/spec/.golangci.yml +++ b/vendor/github.com/go-openapi/spec/.golangci.yml @@ -26,3 +26,14 @@ linters: - gocognit - whitespace - wsl + - wrapcheck + - testpackage + - nlreturn + - gomnd + - exhaustivestruct + - goerr113 + - errorlint + - nestif + - godot + - gofumpt + - paralleltest diff --git a/vendor/github.com/go-openapi/spec/.travis.yml b/vendor/github.com/go-openapi/spec/.travis.yml index f1a3f80b35021..e8ceca446b4a3 100644 --- a/vendor/github.com/go-openapi/spec/.travis.yml +++ b/vendor/github.com/go-openapi/spec/.travis.yml @@ -1,8 +1,26 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.13.x - 1.14.x +- 1.x +arch: + - amd64 +jobs: + include: + # only run fast tests on ppc64le + - go: 1.x + arch: ppc64le + script: + - gotestsum -f short-verbose -- ./... + + # include linting job, but only for latest go version and amd64 arch + - go: 1.x + arch: amd64 + install: + go get github.com/golangci/golangci-lint/cmd/golangci-lint + script: + - golangci-lint run --new-from-rev master + install: - GO111MODULE=off go get -u gotest.tools/gotestsum language: go diff --git a/vendor/github.com/go-openapi/spec/README.md b/vendor/github.com/go-openapi/spec/README.md index 6354742cbf625..8d13b70242b4c 100644 --- a/vendor/github.com/go-openapi/spec/README.md +++ b/vendor/github.com/go-openapi/spec/README.md @@ -2,9 +2,29 @@ [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/spec?status.svg)](http://godoc.org/github.com/go-openapi/spec) -[![GolangCI](https://golangci.com/badges/github.com/go-openapi/spec.svg)](https://golangci.com) [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/spec)](https://goreportcard.com/report/github.com/go-openapi/spec) The object model for OpenAPI specification documents. -Currently supports Swagger 2.0. +### FAQ + +* What does this do? + +> 1. This package knows how to marshal and unmarshal Swagger API specifications into a golang object model +> 2. It knows how to resolve $ref and expand them to make a single root documment + +* How does it play with the rest of the go-openapi packages ? + +> 1. This package is at the core of the go-openapi suite of packages and [code generator](https://github.com/go-swagger/go-swagger) +> 2. There is a [spec loading package](https://github.com/go-openapi/loads) to fetch specs as JSON or YAML from local or remote locations +> 3. There is a [spec validation package](https://github.com/go-openapi/validate) built on top of it +> 4. There is a [spec analysis package](https://github.com/go-openapi/analysis) built on top of it, to analyze, flatten, fix and merge spec documents + +* Does this library support OpenAPI 3? + +> No. +> This package currently only supports OpenAPI 2.0 (aka Swagger 2.0). +> There is no plan to make it evolve toward supporting OpenAPI 3.x. +> This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story. +> +> An early attempt to support Swagger 3 may be found at: https://github.com/go-openapi/spec3 diff --git a/vendor/github.com/go-openapi/spec/appveyor.yml b/vendor/github.com/go-openapi/spec/appveyor.yml new file mode 100644 index 0000000000000..e5d28bd1e49d2 --- /dev/null +++ b/vendor/github.com/go-openapi/spec/appveyor.yml @@ -0,0 +1,34 @@ +version: "0.1.{build}" + +clone_folder: C:\go-openapi\spec +shallow_clone: true # for startup speed +pull_requests: + do_not_increment_build_number: true + +#skip_tags: true +#skip_branch_with_pr: true + +# appveyor.yml +build: off + +environment: + GOPATH: c:\gopath + +stack: go 1.12 + +test_script: + - echo "test disabled for now" + #- go test -v -timeout 20m ./... +#artifacts: +# - path: '%GOPATH%\bin\*.exe' +deploy: off + +notifications: + - provider: Slack + incoming_webhook: https://hooks.slack.com/services/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 + auth_token: + secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4= + channel: bots + on_build_success: false + on_build_failure: true + on_build_status_changed: true diff --git a/vendor/github.com/go-openapi/spec/bindata.go b/vendor/github.com/go-openapi/spec/bindata.go index 66b1f32635d68..afc83850c2e87 100644 --- a/vendor/github.com/go-openapi/spec/bindata.go +++ b/vendor/github.com/go-openapi/spec/bindata.go @@ -247,9 +247,9 @@ type bintree struct { } var _bintree = &bintree{nil, map[string]*bintree{ - "jsonschema-draft-04.json": &bintree{jsonschemaDraft04Json, map[string]*bintree{}}, - "v2": &bintree{nil, map[string]*bintree{ - "schema.json": &bintree{v2SchemaJson, map[string]*bintree{}}, + "jsonschema-draft-04.json": {jsonschemaDraft04Json, map[string]*bintree{}}, + "v2": {nil, map[string]*bintree{ + "schema.json": {v2SchemaJson, map[string]*bintree{}}, }}, }} diff --git a/vendor/github.com/go-openapi/spec/cache.go b/vendor/github.com/go-openapi/spec/cache.go index 3fada0daef1bd..122993b44b41b 100644 --- a/vendor/github.com/go-openapi/spec/cache.go +++ b/vendor/github.com/go-openapi/spec/cache.go @@ -14,7 +14,9 @@ package spec -import "sync" +import ( + "sync" +) // ResolutionCache a cache for resolving urls type ResolutionCache interface { @@ -27,12 +29,23 @@ type simpleCache struct { store map[string]interface{} } +func (s *simpleCache) ShallowClone() ResolutionCache { + store := make(map[string]interface{}, len(s.store)) + s.lock.RLock() + for k, v := range s.store { + store[k] = v + } + s.lock.RUnlock() + + return &simpleCache{ + store: store, + } +} + // Get retrieves a cached URI func (s *simpleCache) Get(uri string) (interface{}, bool) { - debugLog("getting %q from resolution cache", uri) s.lock.RLock() v, ok := s.store[uri] - debugLog("got %q from resolution cache: %t", uri, ok) s.lock.RUnlock() return v, ok @@ -45,16 +58,41 @@ func (s *simpleCache) Set(uri string, data interface{}) { s.lock.Unlock() } -var resCache ResolutionCache +var ( + // resCache is a package level cache for $ref resolution and expansion. + // It is initialized lazily by methods that have the need for it: no + // memory is allocated unless some expander methods are called. + // + // It is initialized with JSON schema and swagger schema, + // which do not mutate during normal operations. + // + // All subsequent utilizations of this cache are produced from a shallow + // clone of this initial version. + resCache *simpleCache + onceCache sync.Once -func init() { - resCache = initResolutionCache() + _ ResolutionCache = &simpleCache{} +) + +// initResolutionCache initializes the URI resolution cache. To be wrapped in a sync.Once.Do call. +func initResolutionCache() { + resCache = defaultResolutionCache() } -// initResolutionCache initializes the URI resolution cache -func initResolutionCache() ResolutionCache { +func defaultResolutionCache() *simpleCache { return &simpleCache{store: map[string]interface{}{ "http://swagger.io/v2/schema.json": MustLoadSwagger20Schema(), "http://json-schema.org/draft-04/schema": MustLoadJSONSchemaDraft04(), }} } + +func cacheOrDefault(cache ResolutionCache) ResolutionCache { + onceCache.Do(initResolutionCache) + + if cache != nil { + return cache + } + + // get a shallow clone of the base cache with swagger and json schema + return resCache.ShallowClone() +} diff --git a/vendor/github.com/go-openapi/spec/contact_info.go b/vendor/github.com/go-openapi/spec/contact_info.go index f9bf42e8dd851..2f7bb219b562b 100644 --- a/vendor/github.com/go-openapi/spec/contact_info.go +++ b/vendor/github.com/go-openapi/spec/contact_info.go @@ -28,12 +28,14 @@ type ContactInfo struct { VendorExtensible } +// ContactInfoProps hold the properties of a ContactInfo object type ContactInfoProps struct { Name string `json:"name,omitempty"` URL string `json:"url,omitempty"` Email string `json:"email,omitempty"` } +// UnmarshalJSON hydrates ContactInfo from json func (c *ContactInfo) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &c.ContactInfoProps); err != nil { return err @@ -41,6 +43,7 @@ func (c *ContactInfo) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &c.VendorExtensible) } +// MarshalJSON produces ContactInfo as json func (c ContactInfo) MarshalJSON() ([]byte, error) { b1, err := json.Marshal(c.ContactInfoProps) if err != nil { diff --git a/vendor/github.com/go-openapi/spec/errors.go b/vendor/github.com/go-openapi/spec/errors.go new file mode 100644 index 0000000000000..10a693a5dae64 --- /dev/null +++ b/vendor/github.com/go-openapi/spec/errors.go @@ -0,0 +1,18 @@ +package spec + +import "errors" + +var ( + // ErrUnknownTypeForReference indicates that a resolved reference was found in an unsupported container type + ErrUnknownTypeForReference = errors.New("unknown type for the resolved reference") + + // ErrResolveRefNeedsAPointer indicates that a $ref target must be a valid JSON pointer + ErrResolveRefNeedsAPointer = errors.New("resolve ref: target needs to be a pointer") + + // ErrDerefUnsupportedType indicates that a resolved reference was found in an unsupported container type. + // At the moment, $ref are supported only inside: schemas, parameters, responses, path items + ErrDerefUnsupportedType = errors.New("deref: unsupported type") + + // ErrExpandUnsupportedType indicates that $ref expansion is attempted on some invalid type + ErrExpandUnsupportedType = errors.New("expand: unsupported type. Input should be of type *Parameter or *Response") +) diff --git a/vendor/github.com/go-openapi/spec/expander.go b/vendor/github.com/go-openapi/spec/expander.go index 1f30e7f8b1fc0..8a80e2bb81e92 100644 --- a/vendor/github.com/go-openapi/spec/expander.go +++ b/vendor/github.com/go-openapi/spec/expander.go @@ -17,140 +17,21 @@ package spec import ( "encoding/json" "fmt" - "strings" ) -// ExpandOptions provides options for spec expand +// ExpandOptions provides options for the spec expander. type ExpandOptions struct { - RelativeBase string - SkipSchemas bool - ContinueOnError bool - AbsoluteCircularRef bool -} + RelativeBase string + SkipSchemas bool + ContinueOnError bool + PathLoader func(string) (json.RawMessage, error) `json:"-"` -// ResolveRefWithBase resolves a reference against a context root with preservation of base path -func ResolveRefWithBase(root interface{}, ref *Ref, opts *ExpandOptions) (*Schema, error) { - resolver, err := defaultSchemaLoader(root, opts, nil, nil) - if err != nil { - return nil, err - } - specBasePath := "" - if opts != nil && opts.RelativeBase != "" { - specBasePath, _ = absPath(opts.RelativeBase) - } - - result := new(Schema) - if err := resolver.Resolve(ref, result, specBasePath); err != nil { - return nil, err - } - return result, nil -} - -// ResolveRef resolves a reference against a context root -// ref is guaranteed to be in root (no need to go to external files) -// ResolveRef is ONLY called from the code generation module -func ResolveRef(root interface{}, ref *Ref) (*Schema, error) { - res, _, err := ref.GetPointer().Get(root) - if err != nil { - panic(err) - } - switch sch := res.(type) { - case Schema: - return &sch, nil - case *Schema: - return sch, nil - case map[string]interface{}: - b, _ := json.Marshal(sch) - newSch := new(Schema) - _ = json.Unmarshal(b, newSch) - return newSch, nil - default: - return nil, fmt.Errorf("unknown type for the resolved reference") - } -} - -// ResolveParameter resolves a parameter reference against a context root -func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) { - return ResolveParameterWithBase(root, ref, nil) -} - -// ResolveParameterWithBase resolves a parameter reference against a context root and base path -func ResolveParameterWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Parameter, error) { - resolver, err := defaultSchemaLoader(root, opts, nil, nil) - if err != nil { - return nil, err - } - - result := new(Parameter) - if err := resolver.Resolve(&ref, result, ""); err != nil { - return nil, err - } - return result, nil -} - -// ResolveResponse resolves response a reference against a context root -func ResolveResponse(root interface{}, ref Ref) (*Response, error) { - return ResolveResponseWithBase(root, ref, nil) -} - -// ResolveResponseWithBase resolves response a reference against a context root and base path -func ResolveResponseWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Response, error) { - resolver, err := defaultSchemaLoader(root, opts, nil, nil) - if err != nil { - return nil, err - } - - result := new(Response) - if err := resolver.Resolve(&ref, result, ""); err != nil { - return nil, err - } - return result, nil -} - -// ResolveItems resolves parameter items reference against a context root and base path. -// -// NOTE: stricly speaking, this construct is not supported by Swagger 2.0. -// Similarly, $ref are forbidden in response headers. -func ResolveItems(root interface{}, ref Ref, opts *ExpandOptions) (*Items, error) { - resolver, err := defaultSchemaLoader(root, opts, nil, nil) - if err != nil { - return nil, err - } - basePath := "" - if opts.RelativeBase != "" { - basePath = opts.RelativeBase - } - result := new(Items) - if err := resolver.Resolve(&ref, result, basePath); err != nil { - return nil, err - } - return result, nil -} - -// ResolvePathItem resolves response a path item against a context root and base path -func ResolvePathItem(root interface{}, ref Ref, opts *ExpandOptions) (*PathItem, error) { - resolver, err := defaultSchemaLoader(root, opts, nil, nil) - if err != nil { - return nil, err - } - basePath := "" - if opts.RelativeBase != "" { - basePath = opts.RelativeBase - } - result := new(PathItem) - if err := resolver.Resolve(&ref, result, basePath); err != nil { - return nil, err - } - return result, nil + AbsoluteCircularRef bool } // ExpandSpec expands the references in a swagger spec func ExpandSpec(spec *Swagger, options *ExpandOptions) error { - resolver, err := defaultSchemaLoader(spec, options, nil, nil) - // Just in case this ever returns an error. - if resolver.shouldStopOnError(err) { - return err - } + resolver := defaultSchemaLoader(spec, options, nil, nil) // getting the base path of the spec to adjust all subsequent reference resolutions specBasePath := "" @@ -160,9 +41,10 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error { if options == nil || !options.SkipSchemas { for key, definition := range spec.Definitions { - var def *Schema - var err error - if def, err = expandSchema(definition, []string{fmt.Sprintf("#/definitions/%s", key)}, resolver, specBasePath); resolver.shouldStopOnError(err) { + parentRefs := make([]string, 0, 10) + parentRefs = append(parentRefs, fmt.Sprintf("#/definitions/%s", key)) + def, err := expandSchema(definition, parentRefs, resolver, specBasePath) + if resolver.shouldStopOnError(err) { return err } if def != nil { @@ -189,157 +71,140 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error { if spec.Paths != nil { for key := range spec.Paths.Paths { - path := spec.Paths.Paths[key] - if err := expandPathItem(&path, resolver, specBasePath); resolver.shouldStopOnError(err) { + pth := spec.Paths.Paths[key] + if err := expandPathItem(&pth, resolver, specBasePath); resolver.shouldStopOnError(err) { return err } - spec.Paths.Paths[key] = path + spec.Paths.Paths[key] = pth } } return nil } -const rootBase = "root" -// baseForRoot loads in the cache the root document and produces a fake "root" base path entry +const rootBase = ".root" + +// baseForRoot loads in the cache the root document and produces a fake ".root" base path entry // for further $ref resolution +// +// Setting the cache is optional and this parameter may safely be left to nil. func baseForRoot(root interface{}, cache ResolutionCache) string { - // cache the root document to resolve $ref's - if root != nil { - base, _ := absPath(rootBase) - normalizedBase := normalizeAbsPath(base) - debugLog("setting root doc in cache at: %s", normalizedBase) - if cache == nil { - cache = resCache - } - cache.Set(normalizedBase, root) - return rootBase + if root == nil { + return "" } - return "" + + // cache the root document to resolve $ref's + base, _ := absPath(rootBase) + normalizedBase := normalizeAbsPath(base) + cache.Set(normalizedBase, root) + + return normalizedBase } -// ExpandSchema expands the refs in the schema object with reference to the root object -// go-openapi/validate uses this function -// notice that it is impossible to reference a json schema in a different file other than root +// ExpandSchema expands the refs in the schema object with reference to the root object. +// +// go-openapi/validate uses this function. +// +// Notice that it is impossible to reference a json schema in a different document other than root +// (use ExpandSchemaWithBasePath to resolve external references). +// +// Setting the cache is optional and this parameter may safely be left to nil. func ExpandSchema(schema *Schema, root interface{}, cache ResolutionCache) error { + cache = cacheOrDefault(cache) + if root == nil { + root = schema + } + opts := &ExpandOptions{ // when a root is specified, cache the root as an in-memory document for $ref retrieval RelativeBase: baseForRoot(root, cache), SkipSchemas: false, ContinueOnError: false, - // when no base path is specified, remaining $ref (circular) are rendered with an absolute path - AbsoluteCircularRef: true, } + return ExpandSchemaWithBasePath(schema, cache, opts) } -// ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options +// ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options. +// +// Setting the cache is optional and this parameter may safely be left to nil. func ExpandSchemaWithBasePath(schema *Schema, cache ResolutionCache, opts *ExpandOptions) error { if schema == nil { return nil } + cache = cacheOrDefault(cache) + var basePath string if opts.RelativeBase != "" { basePath, _ = absPath(opts.RelativeBase) } - resolver, err := defaultSchemaLoader(nil, opts, cache, nil) + resolver := defaultSchemaLoader(nil, opts, cache, nil) + + parentRefs := make([]string, 0, 10) + s, err := expandSchema(*schema, parentRefs, resolver, basePath) if err != nil { return err } - - refs := []string{""} - var s *Schema - if s, err = expandSchema(*schema, refs, resolver, basePath); err != nil { - return err + if s != nil { + // guard for when continuing on error + *schema = *s } - *schema = *s + return nil } func expandItems(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) { - if target.Items != nil { - if target.Items.Schema != nil { - t, err := expandSchema(*target.Items.Schema, parentRefs, resolver, basePath) - if err != nil { - return nil, err - } - *target.Items.Schema = *t + if target.Items == nil { + return &target, nil + } + + // array + if target.Items.Schema != nil { + t, err := expandSchema(*target.Items.Schema, parentRefs, resolver, basePath) + if err != nil { + return nil, err } - for i := range target.Items.Schemas { - t, err := expandSchema(target.Items.Schemas[i], parentRefs, resolver, basePath) - if err != nil { - return nil, err - } - target.Items.Schemas[i] = *t + *target.Items.Schema = *t + } + + // tuple + for i := range target.Items.Schemas { + t, err := expandSchema(target.Items.Schemas[i], parentRefs, resolver, basePath) + if err != nil { + return nil, err } + target.Items.Schemas[i] = *t } + return &target, nil } func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) { if target.Ref.String() == "" && target.Ref.IsRoot() { - // normalizing is important newRef := normalizeFileRef(&target.Ref, basePath) target.Ref = *newRef return &target, nil - } // change the base path of resolution when an ID is encountered // otherwise the basePath should inherit the parent's - // important: ID can be relative path if target.ID != "" { - debugLog("schema has ID: %s", target.ID) - // handling the case when id is a folder - // remember that basePath has to be a file - refPath := target.ID - if strings.HasSuffix(target.ID, "/") { - // path.Clean here would not work correctly if basepath is http - refPath = fmt.Sprintf("%s%s", refPath, "placeholder.json") - } - basePath = normalizePaths(refPath, basePath) + basePath, _ = resolver.setSchemaID(target, target.ID, basePath) } - var t *Schema - // if Ref is found, everything else doesn't matter - // Ref also changes the resolution scope of children expandSchema if target.Ref.String() != "" { - // here the resolution scope is changed because a $ref was encountered - normalizedRef := normalizeFileRef(&target.Ref, basePath) - normalizedBasePath := normalizedRef.RemoteURI() - - if resolver.isCircular(normalizedRef, basePath, parentRefs...) { - // this means there is a cycle in the recursion tree: return the Ref - // - circular refs cannot be expanded. We leave them as ref. - // - denormalization means that a new local file ref is set relative to the original basePath - debugLog("shortcut circular ref: basePath: %s, normalizedPath: %s, normalized ref: %s", - basePath, normalizedBasePath, normalizedRef.String()) - if !resolver.options.AbsoluteCircularRef { - target.Ref = *denormalizeFileRef(normalizedRef, normalizedBasePath, resolver.context.basePath) - } else { - target.Ref = *normalizedRef - } - return &target, nil - } + return expandSchemaRef(target, parentRefs, resolver, basePath) + } - debugLog("basePath: %s: calling Resolve with target: %#v", basePath, target) - if err := resolver.Resolve(&target.Ref, &t, basePath); resolver.shouldStopOnError(err) { - return nil, err + for k := range target.Definitions { + tt, err := expandSchema(target.Definitions[k], parentRefs, resolver, basePath) + if resolver.shouldStopOnError(err) { + return &target, err } - - if t != nil { - parentRefs = append(parentRefs, normalizedRef.String()) - var err error - transitiveResolver, err := resolver.transitiveResolver(basePath, target.Ref) - if transitiveResolver.shouldStopOnError(err) { - return nil, err - } - - basePath = resolver.updateBasePath(transitiveResolver, normalizedBasePath) - - return expandSchema(*t, parentRefs, transitiveResolver, basePath) + if tt != nil { + target.Definitions[k] = *tt } } @@ -356,15 +221,21 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba if resolver.shouldStopOnError(err) { return &target, err } - target.AllOf[i] = *t + if t != nil { + target.AllOf[i] = *t + } } + for i := range target.AnyOf { t, err := expandSchema(target.AnyOf[i], parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { return &target, err } - target.AnyOf[i] = *t + if t != nil { + target.AnyOf[i] = *t + } } + for i := range target.OneOf { t, err := expandSchema(target.OneOf[i], parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { @@ -374,6 +245,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba target.OneOf[i] = *t } } + if target.Not != nil { t, err := expandSchema(*target.Not, parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { @@ -383,6 +255,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba *target.Not = *t } } + for k := range target.Properties { t, err := expandSchema(target.Properties[k], parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { @@ -392,6 +265,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba target.Properties[k] = *t } } + if target.AdditionalProperties != nil && target.AdditionalProperties.Schema != nil { t, err := expandSchema(*target.AdditionalProperties.Schema, parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { @@ -401,6 +275,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba *target.AdditionalProperties.Schema = *t } } + for k := range target.PatternProperties { t, err := expandSchema(target.PatternProperties[k], parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { @@ -410,6 +285,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba target.PatternProperties[k] = *t } } + for k := range target.Dependencies { if target.Dependencies[k].Schema != nil { t, err := expandSchema(*target.Dependencies[k].Schema, parentRefs, resolver, basePath) @@ -421,6 +297,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba } } } + if target.AdditionalItems != nil && target.AdditionalItems.Schema != nil { t, err := expandSchema(*target.AdditionalItems.Schema, parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { @@ -430,16 +307,48 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba *target.AdditionalItems.Schema = *t } } - for k := range target.Definitions { - t, err := expandSchema(target.Definitions[k], parentRefs, resolver, basePath) - if resolver.shouldStopOnError(err) { - return &target, err - } - if t != nil { - target.Definitions[k] = *t + return &target, nil +} + +func expandSchemaRef(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) { + // if a Ref is found, all sibling fields are skipped + // Ref also changes the resolution scope of children expandSchema + + // here the resolution scope is changed because a $ref was encountered + normalizedRef := normalizeFileRef(&target.Ref, basePath) + normalizedBasePath := normalizedRef.RemoteURI() + + if resolver.isCircular(normalizedRef, basePath, parentRefs...) { + // this means there is a cycle in the recursion tree: return the Ref + // - circular refs cannot be expanded. We leave them as ref. + // - denormalization means that a new local file ref is set relative to the original basePath + debugLog("short circuit circular ref: basePath: %s, normalizedPath: %s, normalized ref: %s", + basePath, normalizedBasePath, normalizedRef.String()) + if !resolver.options.AbsoluteCircularRef { + target.Ref = *denormalizeFileRef(normalizedRef, normalizedBasePath, resolver.context.basePath) + } else { + target.Ref = *normalizedRef } + return &target, nil } - return &target, nil + + var t *Schema + err := resolver.Resolve(&target.Ref, &t, basePath) + if resolver.shouldStopOnError(err) { + return nil, err + } + + if t == nil { + // guard for when continuing on error + return &target, nil + } + + parentRefs = append(parentRefs, normalizedRef.String()) + transitiveResolver := resolver.transitiveResolver(basePath, target.Ref) + + basePath = resolver.updateBasePath(transitiveResolver, normalizedBasePath) + + return expandSchema(*t, parentRefs, transitiveResolver, basePath) } func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string) error { @@ -447,25 +356,24 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string) return nil } - parentRefs := []string{} + parentRefs := make([]string, 0, 10) if err := resolver.deref(pathItem, parentRefs, basePath); resolver.shouldStopOnError(err) { return err } + if pathItem.Ref.String() != "" { - transitiveResolver, err := resolver.transitiveResolver(basePath, pathItem.Ref) - if transitiveResolver.shouldStopOnError(err) { - return err - } + transitiveResolver := resolver.transitiveResolver(basePath, pathItem.Ref) basePath = transitiveResolver.updateBasePath(resolver, basePath) resolver = transitiveResolver } - pathItem.Ref = Ref{} - for idx := range pathItem.Parameters { - if err := expandParameterOrResponse(&(pathItem.Parameters[idx]), resolver, basePath); resolver.shouldStopOnError(err) { + pathItem.Ref = Ref{} + for i := range pathItem.Parameters { + if err := expandParameterOrResponse(&(pathItem.Parameters[i]), resolver, basePath); resolver.shouldStopOnError(err) { return err } } + ops := []*Operation{ pathItem.Get, pathItem.Head, @@ -480,6 +388,7 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string) return err } } + return nil } @@ -496,42 +405,47 @@ func expandOperation(op *Operation, resolver *schemaLoader, basePath string) err op.Parameters[i] = param } - if op.Responses != nil { - responses := op.Responses - if err := expandParameterOrResponse(responses.Default, resolver, basePath); resolver.shouldStopOnError(err) { + if op.Responses == nil { + return nil + } + + responses := op.Responses + if err := expandParameterOrResponse(responses.Default, resolver, basePath); resolver.shouldStopOnError(err) { + return err + } + + for code := range responses.StatusCodeResponses { + response := responses.StatusCodeResponses[code] + if err := expandParameterOrResponse(&response, resolver, basePath); resolver.shouldStopOnError(err) { return err } - for code := range responses.StatusCodeResponses { - response := responses.StatusCodeResponses[code] - if err := expandParameterOrResponse(&response, resolver, basePath); resolver.shouldStopOnError(err) { - return err - } - responses.StatusCodeResponses[code] = response - } + responses.StatusCodeResponses[code] = response } + return nil } // ExpandResponseWithRoot expands a response based on a root document, not a fetchable document +// +// Notice that it is impossible to reference a json schema in a different document other than root +// (use ExpandResponse to resolve external references). +// +// Setting the cache is optional and this parameter may safely be left to nil. func ExpandResponseWithRoot(response *Response, root interface{}, cache ResolutionCache) error { + cache = cacheOrDefault(cache) opts := &ExpandOptions{ RelativeBase: baseForRoot(root, cache), SkipSchemas: false, ContinueOnError: false, - // when no base path is specified, remaining $ref (circular) are rendered with an absolute path - AbsoluteCircularRef: true, - } - resolver, err := defaultSchemaLoader(root, opts, nil, nil) - if err != nil { - return err } + resolver := defaultSchemaLoader(root, opts, cache, nil) return expandParameterOrResponse(response, resolver, opts.RelativeBase) } // ExpandResponse expands a response based on a basepath -// This is the exported version of expandResponse -// all refs inside response will be resolved relative to basePath +// +// All refs inside response will be resolved relative to basePath func ExpandResponse(response *Response, basePath string) error { var specBasePath string if basePath != "" { @@ -540,27 +454,23 @@ func ExpandResponse(response *Response, basePath string) error { opts := &ExpandOptions{ RelativeBase: specBasePath, } - resolver, err := defaultSchemaLoader(nil, opts, nil, nil) - if err != nil { - return err - } + resolver := defaultSchemaLoader(nil, opts, nil, nil) return expandParameterOrResponse(response, resolver, opts.RelativeBase) } -// ExpandParameterWithRoot expands a parameter based on a root document, not a fetchable document +// ExpandParameterWithRoot expands a parameter based on a root document, not a fetchable document. +// +// Notice that it is impossible to reference a json schema in a different document other than root +// (use ExpandParameter to resolve external references). func ExpandParameterWithRoot(parameter *Parameter, root interface{}, cache ResolutionCache) error { + cache = cacheOrDefault(cache) opts := &ExpandOptions{ RelativeBase: baseForRoot(root, cache), SkipSchemas: false, ContinueOnError: false, - // when no base path is specified, remaining $ref (circular) are rendered with an absolute path - AbsoluteCircularRef: true, - } - resolver, err := defaultSchemaLoader(root, opts, nil, nil) - if err != nil { - return err } + resolver := defaultSchemaLoader(root, opts, cache, nil) return expandParameterOrResponse(parameter, resolver, opts.RelativeBase) } @@ -576,17 +486,17 @@ func ExpandParameter(parameter *Parameter, basePath string) error { opts := &ExpandOptions{ RelativeBase: specBasePath, } - resolver, err := defaultSchemaLoader(nil, opts, nil, nil) - if err != nil { - return err - } + resolver := defaultSchemaLoader(nil, opts, nil, nil) return expandParameterOrResponse(parameter, resolver, opts.RelativeBase) } func getRefAndSchema(input interface{}) (*Ref, *Schema, error) { - var ref *Ref - var sch *Schema + var ( + ref *Ref + sch *Schema + ) + switch refable := input.(type) { case *Parameter: if refable == nil { @@ -601,8 +511,9 @@ func getRefAndSchema(input interface{}) (*Ref, *Schema, error) { ref = &refable.Ref sch = refable.Schema default: - return nil, nil, fmt.Errorf("expand: unsupported type %T. Input should be of type *Parameter or *Response", input) + return nil, nil, fmt.Errorf("unsupported type: %T: %w", input, ErrExpandUnsupportedType) } + return ref, sch, nil } @@ -611,41 +522,70 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa if err != nil { return err } + if ref == nil { return nil } - parentRefs := []string{} - if err := resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) { + + parentRefs := make([]string, 0, 10) + if err = resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) { return err } + ref, sch, _ := getRefAndSchema(input) if ref.String() != "" { - transitiveResolver, err := resolver.transitiveResolver(basePath, *ref) - if transitiveResolver.shouldStopOnError(err) { - return err - } + transitiveResolver := resolver.transitiveResolver(basePath, *ref) basePath = resolver.updateBasePath(transitiveResolver, basePath) resolver = transitiveResolver } - if sch != nil && sch.Ref.String() != "" { - // schema expanded to a $ref in another root - var ern error - sch.Ref, ern = NewRef(normalizePaths(sch.Ref.String(), ref.RemoteURI())) + if sch == nil { + // nothing to be expanded + if ref != nil { + *ref = Ref{} + } + return nil + } + + if sch.Ref.String() != "" { + rebasedRef, ern := NewRef(normalizePaths(sch.Ref.String(), basePath)) if ern != nil { return ern } + + switch { + case resolver.isCircular(&rebasedRef, basePath, parentRefs...): + // this is a circular $ref: stop expansion + if !resolver.options.AbsoluteCircularRef { + sch.Ref = *denormalizeFileRef(&rebasedRef, basePath, resolver.context.basePath) + } else { + sch.Ref = rebasedRef + } + case !resolver.options.SkipSchemas: + // schema expanded to a $ref in another root + sch.Ref = rebasedRef + default: + // skip schema expansion but rebase $ref to schema + sch.Ref = *denormalizeFileRef(&rebasedRef, basePath, resolver.context.basePath) + } } + if ref != nil { *ref = Ref{} } - if !resolver.options.SkipSchemas && sch != nil { + // expand schema + if !resolver.options.SkipSchemas { s, err := expandSchema(*sch, parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { return err } + if s == nil { + // guard for when continuing on error + return nil + } *sch = *s } + return nil } diff --git a/vendor/github.com/go-openapi/spec/go.mod b/vendor/github.com/go-openapi/spec/go.mod index 14e5f2dac3aa0..1717d0836c49e 100644 --- a/vendor/github.com/go-openapi/spec/go.mod +++ b/vendor/github.com/go-openapi/spec/go.mod @@ -1,12 +1,13 @@ module github.com/go-openapi/spec require ( - github.com/go-openapi/jsonpointer v0.19.3 - github.com/go-openapi/jsonreference v0.19.2 - github.com/go-openapi/swag v0.19.5 - github.com/stretchr/testify v1.3.0 - golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect - gopkg.in/yaml.v2 v2.2.4 + github.com/go-openapi/jsonpointer v0.19.5 + github.com/go-openapi/jsonreference v0.19.5 + github.com/go-openapi/swag v0.19.12 + github.com/stretchr/testify v1.6.1 + golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect + golang.org/x/text v0.3.4 // indirect + gopkg.in/yaml.v2 v2.4.0 ) go 1.13 diff --git a/vendor/github.com/go-openapi/spec/go.sum b/vendor/github.com/go-openapi/spec/go.sum index c209ff971206a..730dddba7e975 100644 --- a/vendor/github.com/go-openapi/spec/go.sum +++ b/vendor/github.com/go-openapi/spec/go.sum @@ -2,48 +2,71 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI= +github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/go-openapi/spec/header.go b/vendor/github.com/go-openapi/spec/header.go index 39efe452bb09f..9dfd17b185f86 100644 --- a/vendor/github.com/go-openapi/spec/header.go +++ b/vendor/github.com/go-openapi/spec/header.go @@ -141,6 +141,12 @@ func (h *Header) AllowDuplicates() *Header { return h } +// WithValidations is a fluent method to set header validations +func (h *Header) WithValidations(val CommonValidations) *Header { + h.SetValidations(SchemaValidations{CommonValidations: val}) + return h +} + // MarshalJSON marshal this to JSON func (h Header) MarshalJSON() ([]byte, error) { b1, err := json.Marshal(h.CommonValidations) diff --git a/vendor/github.com/go-openapi/spec/items.go b/vendor/github.com/go-openapi/spec/items.go index 365d1631582a5..e2afb2133b9b0 100644 --- a/vendor/github.com/go-openapi/spec/items.go +++ b/vendor/github.com/go-openapi/spec/items.go @@ -53,22 +53,6 @@ func (s *SimpleSchema) ItemsTypeName() string { return s.Items.TypeName() } -// CommonValidations describe common JSON-schema validations -type CommonValidations struct { - Maximum *float64 `json:"maximum,omitempty"` - ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"` - Minimum *float64 `json:"minimum,omitempty"` - ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"` - MaxLength *int64 `json:"maxLength,omitempty"` - MinLength *int64 `json:"minLength,omitempty"` - Pattern string `json:"pattern,omitempty"` - MaxItems *int64 `json:"maxItems,omitempty"` - MinItems *int64 `json:"minItems,omitempty"` - UniqueItems bool `json:"uniqueItems,omitempty"` - MultipleOf *float64 `json:"multipleOf,omitempty"` - Enum []interface{} `json:"enum,omitempty"` -} - // Items a limited subset of JSON-Schema's items object. // It is used by parameter definitions that are not located in "body". // @@ -180,6 +164,12 @@ func (i *Items) AllowDuplicates() *Items { return i } +// WithValidations is a fluent method to set Items validations +func (i *Items) WithValidations(val CommonValidations) *Items { + i.SetValidations(SchemaValidations{CommonValidations: val}) + return i +} + // UnmarshalJSON hydrates this items instance with the data from JSON func (i *Items) UnmarshalJSON(data []byte) error { var validations CommonValidations diff --git a/vendor/github.com/go-openapi/spec/license.go b/vendor/github.com/go-openapi/spec/license.go index e1529b401c7c5..b42f80368ecad 100644 --- a/vendor/github.com/go-openapi/spec/license.go +++ b/vendor/github.com/go-openapi/spec/license.go @@ -28,11 +28,13 @@ type License struct { VendorExtensible } +// LicenseProps holds the properties of a License object type LicenseProps struct { Name string `json:"name,omitempty"` URL string `json:"url,omitempty"` } +// UnmarshalJSON hydrates License from json func (l *License) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &l.LicenseProps); err != nil { return err @@ -40,6 +42,7 @@ func (l *License) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &l.VendorExtensible) } +// MarshalJSON produces License as json func (l License) MarshalJSON() ([]byte, error) { b1, err := json.Marshal(l.LicenseProps) if err != nil { diff --git a/vendor/github.com/go-openapi/spec/normalizer.go b/vendor/github.com/go-openapi/spec/normalizer.go index b8957e7c0c186..e9010a7d0371b 100644 --- a/vendor/github.com/go-openapi/spec/normalizer.go +++ b/vendor/github.com/go-openapi/spec/normalizer.go @@ -20,9 +20,12 @@ import ( "os" "path" "path/filepath" + "runtime" "strings" ) +const windowsOS = "windows" + // normalize absolute path for cache. // on Windows, drive letters should be converted to lower as scheme in net/url.URL func normalizeAbsPath(path string) string { @@ -71,27 +74,51 @@ func normalizePaths(refPath, base string) string { return baseURL.String() } +// isRoot is a temporary hack to discern windows file ref for ref.IsRoot(). +// TODO: a more thorough change is needed to handle windows file refs. +func isRoot(ref *Ref) bool { + if runtime.GOOS != windowsOS { + return ref.IsRoot() + } + return !filepath.IsAbs(ref.String()) +} + +// isAbs is a temporary hack to discern windows file ref for url IsAbs(). +// TODO: a more thorough change is needed to handle windows file refs. +func isAbs(u *url.URL) bool { + if runtime.GOOS != windowsOS { + return u.IsAbs() + } + if len(u.Scheme) <= 1 { + // drive letter got caught as URI scheme + return false + } + return u.IsAbs() +} + // denormalizePaths returns to simplest notation on file $ref, // i.e. strips the absolute path and sets a path relative to the base path. // // This is currently used when we rewrite ref after a circular ref has been detected func denormalizeFileRef(ref *Ref, relativeBase, originalRelativeBase string) *Ref { - debugLog("denormalizeFileRef for: %s", ref.String()) + debugLog("denormalizeFileRef for: %s (relative: %s, original: %s)", ref.String(), + relativeBase, originalRelativeBase) - if ref.String() == "" || ref.IsRoot() || ref.HasFragmentOnly { + // log.Printf("denormalize: %s, IsRoot: %t,HasFragmentOnly: %t, HasFullURL: %t", ref.String(), ref.IsRoot(), ref.HasFragmentOnly, ref.HasFullURL) + if ref.String() == "" || isRoot(ref) || ref.HasFragmentOnly { return ref } // strip relativeBase from URI relativeBaseURL, _ := url.Parse(relativeBase) relativeBaseURL.Fragment = "" - if relativeBaseURL.IsAbs() && strings.HasPrefix(ref.String(), relativeBase) { + if isAbs(relativeBaseURL) && strings.HasPrefix(ref.String(), relativeBase) { // this should work for absolute URI (e.g. http://...): we have an exact match, just trim prefix r, _ := NewRef(strings.TrimPrefix(ref.String(), relativeBase)) return &r } - if relativeBaseURL.IsAbs() { + if isAbs(relativeBaseURL) { // other absolute URL get unchanged (i.e. with a non-empty scheme) return ref } @@ -111,7 +138,7 @@ func denormalizeFileRef(ref *Ref, relativeBase, originalRelativeBase string) *Re // my normalized ref points to: /mypath/item.json#/target // expected result: item.json#/target parts := strings.Split(ref.String(), "#") - relativePath, err := filepath.Rel(path.Dir(originalRelativeBaseURL.String()), parts[0]) + relativePath, err := filepath.Rel(filepath.Dir(originalRelativeBaseURL.String()), parts[0]) if err != nil { // there is no common ancestor (e.g. different drives on windows) // leaves the ref unchanged @@ -132,8 +159,6 @@ func normalizeFileRef(ref *Ref, relativeBase string) *Ref { return &r } - debugLog("normalizing %s against %s", ref.String(), relativeBase) - s := normalizePaths(ref.String(), relativeBase) r, _ := NewRef(s) return &r @@ -148,5 +173,5 @@ func absPath(fname string) (string, error) { return fname, nil } wd, err := os.Getwd() - return filepath.Join(wd, fname), err + return normalizeAbsPath(filepath.Join(wd, fname)), err } diff --git a/vendor/github.com/go-openapi/spec/operation.go b/vendor/github.com/go-openapi/spec/operation.go index b1ebd59945b76..995ce6acb17bf 100644 --- a/vendor/github.com/go-openapi/spec/operation.go +++ b/vendor/github.com/go-openapi/spec/operation.go @@ -25,7 +25,6 @@ import ( ) func init() { - //gob.Register(map[string][]interface{}{}) gob.Register(map[string]interface{}{}) gob.Register([]interface{}{}) } diff --git a/vendor/github.com/go-openapi/spec/parameter.go b/vendor/github.com/go-openapi/spec/parameter.go index cecdff54568d5..2b2b89b67bf3f 100644 --- a/vendor/github.com/go-openapi/spec/parameter.go +++ b/vendor/github.com/go-openapi/spec/parameter.go @@ -39,8 +39,7 @@ func PathParam(name string) *Parameter { // BodyParam creates a body parameter func BodyParam(name string, schema *Schema) *Parameter { - return &Parameter{ParamProps: ParamProps{Name: name, In: "body", Schema: schema}, - SimpleSchema: SimpleSchema{Type: "object"}} + return &Parameter{ParamProps: ParamProps{Name: name, In: "body", Schema: schema}} } // FormDataParam creates a body parameter @@ -58,7 +57,7 @@ func FileParam(name string) *Parameter { func SimpleArrayParam(name, tpe, fmt string) *Parameter { return &Parameter{ParamProps: ParamProps{Name: name}, SimpleSchema: SimpleSchema{Type: jsonArray, CollectionFormat: "csv", - Items: &Items{SimpleSchema: SimpleSchema{Type: "string", Format: fmt}}}} + Items: &Items{SimpleSchema: SimpleSchema{Type: tpe, Format: fmt}}}} } // ParamRef creates a parameter that's a json reference @@ -278,6 +277,12 @@ func (p *Parameter) AllowDuplicates() *Parameter { return p } +// WithValidations is a fluent method to set parameter validations +func (p *Parameter) WithValidations(val CommonValidations) *Parameter { + p.SetValidations(SchemaValidations{CommonValidations: val}) + return p +} + // UnmarshalJSON hydrates this items instance with the data from JSON func (p *Parameter) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &p.CommonValidations); err != nil { diff --git a/vendor/github.com/go-openapi/spec/properties.go b/vendor/github.com/go-openapi/spec/properties.go new file mode 100644 index 0000000000000..2af13787ab1af --- /dev/null +++ b/vendor/github.com/go-openapi/spec/properties.go @@ -0,0 +1,91 @@ +package spec + +import ( + "bytes" + "encoding/json" + "reflect" + "sort" +) + +// OrderSchemaItem holds a named schema (e.g. from a property of an object) +type OrderSchemaItem struct { + Name string + Schema +} + +// OrderSchemaItems is a sortable slice of named schemas. +// The ordering is defined by the x-order schema extension. +type OrderSchemaItems []OrderSchemaItem + +// MarshalJSON produces a json object with keys defined by the name schemas +// of the OrderSchemaItems slice, keeping the original order of the slice. +func (items OrderSchemaItems) MarshalJSON() ([]byte, error) { + buf := bytes.NewBuffer(nil) + buf.WriteString("{") + for i := range items { + if i > 0 { + buf.WriteString(",") + } + buf.WriteString("\"") + buf.WriteString(items[i].Name) + buf.WriteString("\":") + bs, err := json.Marshal(&items[i].Schema) + if err != nil { + return nil, err + } + buf.Write(bs) + } + buf.WriteString("}") + return buf.Bytes(), nil +} + +func (items OrderSchemaItems) Len() int { return len(items) } +func (items OrderSchemaItems) Swap(i, j int) { items[i], items[j] = items[j], items[i] } +func (items OrderSchemaItems) Less(i, j int) (ret bool) { + ii, oki := items[i].Extensions.GetString("x-order") + ij, okj := items[j].Extensions.GetString("x-order") + if oki { + if okj { + defer func() { + if err := recover(); err != nil { + defer func() { + if err = recover(); err != nil { + ret = items[i].Name < items[j].Name + } + }() + ret = reflect.ValueOf(ii).String() < reflect.ValueOf(ij).String() + } + }() + return reflect.ValueOf(ii).Int() < reflect.ValueOf(ij).Int() + } + return true + } else if okj { + return false + } + return items[i].Name < items[j].Name +} + +// SchemaProperties is a map representing the properties of a Schema object. +// It knows how to transform its keys into an ordered slice. +type SchemaProperties map[string]Schema + +// ToOrderedSchemaItems transforms the map of properties into a sortable slice +func (properties SchemaProperties) ToOrderedSchemaItems() OrderSchemaItems { + items := make(OrderSchemaItems, 0, len(properties)) + for k, v := range properties { + items = append(items, OrderSchemaItem{ + Name: k, + Schema: v, + }) + } + sort.Sort(items) + return items +} + +// MarshalJSON produces properties as json, keeping their order. +func (properties SchemaProperties) MarshalJSON() ([]byte, error) { + if properties == nil { + return []byte("null"), nil + } + return json.Marshal(properties.ToOrderedSchemaItems()) +} diff --git a/vendor/github.com/go-openapi/spec/ref.go b/vendor/github.com/go-openapi/spec/ref.go index 1f31a9ead01f8..b0ef9bd9c9bcc 100644 --- a/vendor/github.com/go-openapi/spec/ref.go +++ b/vendor/github.com/go-openapi/spec/ref.go @@ -48,7 +48,7 @@ type Ref struct { // RemoteURI gets the remote uri part of the ref func (r *Ref) RemoteURI() string { if r.String() == "" { - return r.String() + return "" } u := *r.GetURL() @@ -68,7 +68,7 @@ func (r *Ref) IsValidURI(basepaths ...string) bool { } if r.HasFullURL { - //#nosec + //nolint:noctx,gosec rr, err := http.Get(v) if err != nil { return false diff --git a/vendor/github.com/go-openapi/spec/resolver.go b/vendor/github.com/go-openapi/spec/resolver.go new file mode 100644 index 0000000000000..177292ad238cb --- /dev/null +++ b/vendor/github.com/go-openapi/spec/resolver.go @@ -0,0 +1,128 @@ +package spec + +import ( + "github.com/go-openapi/swag" +) + +func resolveAnyWithBase(root interface{}, ref *Ref, result interface{}, options *ExpandOptions) error { + resolver := defaultSchemaLoader(root, options, nil, nil) + + basePath := "" + if options != nil && options.RelativeBase != "" { + basePath, _ = absPath(options.RelativeBase) + } + + if err := resolver.Resolve(ref, result, basePath); err != nil { + return err + } + + return nil +} + +// ResolveRefWithBase resolves a reference against a context root with preservation of base path +func ResolveRefWithBase(root interface{}, ref *Ref, options *ExpandOptions) (*Schema, error) { + result := new(Schema) + err := resolveAnyWithBase(root, ref, result, options) + if err != nil { + return nil, err + } + + return result, nil +} + +// ResolveRef resolves a reference for a schema against a context root +// ref is guaranteed to be in root (no need to go to external files) +// +// ResolveRef is ONLY called from the code generation module +func ResolveRef(root interface{}, ref *Ref) (*Schema, error) { + res, _, err := ref.GetPointer().Get(root) + if err != nil { + return nil, err + } + + switch sch := res.(type) { + case Schema: + return &sch, nil + case *Schema: + return sch, nil + case map[string]interface{}: + newSch := new(Schema) + if err = swag.DynamicJSONToStruct(sch, newSch); err != nil { + return nil, err + } + return newSch, nil + default: + return nil, ErrUnknownTypeForReference + } +} + +// ResolveParameterWithBase resolves a parameter reference against a context root and base path +func ResolveParameterWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Parameter, error) { + result := new(Parameter) + err := resolveAnyWithBase(root, &ref, result, options) + if err != nil { + return nil, err + } + + return result, nil +} + +// ResolveParameter resolves a parameter reference against a context root +func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) { + return ResolveParameterWithBase(root, ref, nil) +} + +// ResolveResponseWithBase resolves response a reference against a context root and base path +func ResolveResponseWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Response, error) { + result := new(Response) + err := resolveAnyWithBase(root, &ref, result, options) + if err != nil { + return nil, err + } + + return result, nil +} + +// ResolveResponse resolves response a reference against a context root +func ResolveResponse(root interface{}, ref Ref) (*Response, error) { + return ResolveResponseWithBase(root, ref, nil) +} + +// ResolvePathItemWithBase resolves response a path item against a context root and base path +func ResolvePathItemWithBase(root interface{}, ref Ref, options *ExpandOptions) (*PathItem, error) { + result := new(PathItem) + err := resolveAnyWithBase(root, &ref, result, options) + if err != nil { + return nil, err + } + + return result, nil +} + +// ResolvePathItem resolves response a path item against a context root and base path +// +// Deprecated: use ResolvePathItemWithBase instead +func ResolvePathItem(root interface{}, ref Ref, options *ExpandOptions) (*PathItem, error) { + return ResolvePathItemWithBase(root, ref, options) +} + +// ResolveItemsWithBase resolves parameter items reference against a context root and base path. +// +// NOTE: stricly speaking, this construct is not supported by Swagger 2.0. +// Similarly, $ref are forbidden in response headers. +func ResolveItemsWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Items, error) { + result := new(Items) + err := resolveAnyWithBase(root, &ref, result, options) + if err != nil { + return nil, err + } + + return result, nil +} + +// ResolveItems resolves parameter items reference against a context root and base path. +// +// Deprecated: use ResolveItemsWithBase instead +func ResolveItems(root interface{}, ref Ref, options *ExpandOptions) (*Items, error) { + return ResolveItemsWithBase(root, ref, options) +} diff --git a/vendor/github.com/go-openapi/spec/response.go b/vendor/github.com/go-openapi/spec/response.go index 27729c1d93b13..0340b60d845eb 100644 --- a/vendor/github.com/go-openapi/spec/response.go +++ b/vendor/github.com/go-openapi/spec/response.go @@ -23,7 +23,7 @@ import ( // ResponseProps properties specific to a response type ResponseProps struct { - Description string `json:"description,omitempty"` + Description string `json:"description"` Schema *Schema `json:"schema,omitempty"` Headers map[string]Header `json:"headers,omitempty"` Examples map[string]interface{} `json:"examples,omitempty"` @@ -63,10 +63,31 @@ func (r *Response) UnmarshalJSON(data []byte) error { // MarshalJSON converts this items object to JSON func (r Response) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(r.ResponseProps) + var ( + b1 []byte + err error + ) + + if r.Ref.String() == "" { + // when there is no $ref, empty description is rendered as an empty string + b1, err = json.Marshal(r.ResponseProps) + } else { + // when there is $ref inside the schema, description should be omitempty-ied + b1, err = json.Marshal(struct { + Description string `json:"description,omitempty"` + Schema *Schema `json:"schema,omitempty"` + Headers map[string]Header `json:"headers,omitempty"` + Examples map[string]interface{} `json:"examples,omitempty"` + }{ + Description: r.ResponseProps.Description, + Schema: r.ResponseProps.Schema, + Examples: r.ResponseProps.Examples, + }) + } if err != nil { return nil, err } + b2, err := json.Marshal(r.Refable) if err != nil { return nil, err diff --git a/vendor/github.com/go-openapi/spec/schema.go b/vendor/github.com/go-openapi/spec/schema.go index 37858ece9098f..a8d0f737a7a26 100644 --- a/vendor/github.com/go-openapi/spec/schema.go +++ b/vendor/github.com/go-openapi/spec/schema.go @@ -158,41 +158,41 @@ func (r *SchemaURL) fromMap(v map[string]interface{}) error { // SchemaProps describes a JSON schema (draft 4) type SchemaProps struct { - ID string `json:"id,omitempty"` - Ref Ref `json:"-"` - Schema SchemaURL `json:"-"` - Description string `json:"description,omitempty"` - Type StringOrArray `json:"type,omitempty"` - Nullable bool `json:"nullable,omitempty"` - Format string `json:"format,omitempty"` - Title string `json:"title,omitempty"` - Default interface{} `json:"default,omitempty"` - Maximum *float64 `json:"maximum,omitempty"` - ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"` - Minimum *float64 `json:"minimum,omitempty"` - ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"` - MaxLength *int64 `json:"maxLength,omitempty"` - MinLength *int64 `json:"minLength,omitempty"` - Pattern string `json:"pattern,omitempty"` - MaxItems *int64 `json:"maxItems,omitempty"` - MinItems *int64 `json:"minItems,omitempty"` - UniqueItems bool `json:"uniqueItems,omitempty"` - MultipleOf *float64 `json:"multipleOf,omitempty"` - Enum []interface{} `json:"enum,omitempty"` - MaxProperties *int64 `json:"maxProperties,omitempty"` - MinProperties *int64 `json:"minProperties,omitempty"` - Required []string `json:"required,omitempty"` - Items *SchemaOrArray `json:"items,omitempty"` - AllOf []Schema `json:"allOf,omitempty"` - OneOf []Schema `json:"oneOf,omitempty"` - AnyOf []Schema `json:"anyOf,omitempty"` - Not *Schema `json:"not,omitempty"` - Properties map[string]Schema `json:"properties,omitempty"` - AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitempty"` - PatternProperties map[string]Schema `json:"patternProperties,omitempty"` - Dependencies Dependencies `json:"dependencies,omitempty"` - AdditionalItems *SchemaOrBool `json:"additionalItems,omitempty"` - Definitions Definitions `json:"definitions,omitempty"` + ID string `json:"id,omitempty"` + Ref Ref `json:"-"` + Schema SchemaURL `json:"-"` + Description string `json:"description,omitempty"` + Type StringOrArray `json:"type,omitempty"` + Nullable bool `json:"nullable,omitempty"` + Format string `json:"format,omitempty"` + Title string `json:"title,omitempty"` + Default interface{} `json:"default,omitempty"` + Maximum *float64 `json:"maximum,omitempty"` + ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"` + Minimum *float64 `json:"minimum,omitempty"` + ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"` + MaxLength *int64 `json:"maxLength,omitempty"` + MinLength *int64 `json:"minLength,omitempty"` + Pattern string `json:"pattern,omitempty"` + MaxItems *int64 `json:"maxItems,omitempty"` + MinItems *int64 `json:"minItems,omitempty"` + UniqueItems bool `json:"uniqueItems,omitempty"` + MultipleOf *float64 `json:"multipleOf,omitempty"` + Enum []interface{} `json:"enum,omitempty"` + MaxProperties *int64 `json:"maxProperties,omitempty"` + MinProperties *int64 `json:"minProperties,omitempty"` + Required []string `json:"required,omitempty"` + Items *SchemaOrArray `json:"items,omitempty"` + AllOf []Schema `json:"allOf,omitempty"` + OneOf []Schema `json:"oneOf,omitempty"` + AnyOf []Schema `json:"anyOf,omitempty"` + Not *Schema `json:"not,omitempty"` + Properties SchemaProperties `json:"properties,omitempty"` + AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitempty"` + PatternProperties SchemaProperties `json:"patternProperties,omitempty"` + Dependencies Dependencies `json:"dependencies,omitempty"` + AdditionalItems *SchemaOrBool `json:"additionalItems,omitempty"` + Definitions Definitions `json:"definitions,omitempty"` } // SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4) @@ -513,6 +513,56 @@ func (s *Schema) AsUnwrappedXML() *Schema { return s } +// SetValidations defines all schema validations. +// +// NOTE: Required, ReadOnly, AllOf, AnyOf, OneOf and Not are not considered. +func (s *Schema) SetValidations(val SchemaValidations) { + s.Maximum = val.Maximum + s.ExclusiveMaximum = val.ExclusiveMaximum + s.Minimum = val.Minimum + s.ExclusiveMinimum = val.ExclusiveMinimum + s.MaxLength = val.MaxLength + s.MinLength = val.MinLength + s.Pattern = val.Pattern + s.MaxItems = val.MaxItems + s.MinItems = val.MinItems + s.UniqueItems = val.UniqueItems + s.MultipleOf = val.MultipleOf + s.Enum = val.Enum + s.MinProperties = val.MinProperties + s.MaxProperties = val.MaxProperties + s.PatternProperties = val.PatternProperties +} + +// WithValidations is a fluent method to set schema validations +func (s *Schema) WithValidations(val SchemaValidations) *Schema { + s.SetValidations(val) + return s +} + +// Validations returns a clone of the validations for this schema +func (s Schema) Validations() SchemaValidations { + return SchemaValidations{ + CommonValidations: CommonValidations{ + Maximum: s.Maximum, + ExclusiveMaximum: s.ExclusiveMaximum, + Minimum: s.Minimum, + ExclusiveMinimum: s.ExclusiveMinimum, + MaxLength: s.MaxLength, + MinLength: s.MinLength, + Pattern: s.Pattern, + MaxItems: s.MaxItems, + MinItems: s.MinItems, + UniqueItems: s.UniqueItems, + MultipleOf: s.MultipleOf, + Enum: s.Enum, + }, + MinProperties: s.MinProperties, + MaxProperties: s.MaxProperties, + PatternProperties: s.PatternProperties, + } +} + // MarshalJSON marshal this to JSON func (s Schema) MarshalJSON() ([]byte, error) { b1, err := json.Marshal(s.SchemaProps) diff --git a/vendor/github.com/go-openapi/spec/schema_loader.go b/vendor/github.com/go-openapi/spec/schema_loader.go index 02d9966c1ad30..9ea78b5d52cd0 100644 --- a/vendor/github.com/go-openapi/spec/schema_loader.go +++ b/vendor/github.com/go-openapi/spec/schema_loader.go @@ -25,7 +25,14 @@ import ( "github.com/go-openapi/swag" ) -// PathLoader function to use when loading remote refs +// PathLoader is a function to use when loading remote refs. +// +// This is a package level default. It may be overridden or bypassed by +// specifying the loader in ExpandOptions. +// +// NOTE: if you are using the go-openapi/loads package, it will override +// this value with its own default (a loader to retrieve YAML documents as +// well as JSON ones). var PathLoader func(string) (json.RawMessage, error) func init() { @@ -41,19 +48,30 @@ func init() { // resolverContext allows to share a context during spec processing. // At the moment, it just holds the index of circular references found. type resolverContext struct { - // circulars holds all visited circular references, which allows shortcuts. - // NOTE: this is not just a performance improvement: it is required to figure out - // circular references which participate several cycles. + // circulars holds all visited circular references, to shortcircuit $ref resolution. + // // This structure is privately instantiated and needs not be locked against // concurrent access, unless we chose to implement a parallel spec walking. circulars map[string]bool basePath string + loadDoc func(string) (json.RawMessage, error) } -func newResolverContext(originalBasePath string) *resolverContext { +func newResolverContext(expandOptions *ExpandOptions) *resolverContext { + absBase, _ := absPath(expandOptions.RelativeBase) + + // path loader may be overridden from option + var loader func(string) (json.RawMessage, error) + if expandOptions.PathLoader == nil { + loader = PathLoader + } else { + loader = expandOptions.PathLoader + } + return &resolverContext{ circulars: make(map[string]bool), - basePath: originalBasePath, // keep the root base path in context + basePath: absBase, // keep the root base path in context + loadDoc: loader, } } @@ -62,21 +80,20 @@ type schemaLoader struct { options *ExpandOptions cache ResolutionCache context *resolverContext - loadDoc func(string) (json.RawMessage, error) } -func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) (*schemaLoader, error) { +func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) *schemaLoader { if ref.IsRoot() || ref.HasFragmentOnly { - return r, nil + return r } - baseRef, _ := NewRef(basePath) + baseRef := MustCreateRef(basePath) currentRef := normalizeFileRef(&ref, basePath) if strings.HasPrefix(currentRef.String(), baseRef.String()) { - return r, nil + return r } - // Set a new root to resolve against + // set a new root against which to resolve rootURL := currentRef.GetURL() rootURL.Fragment = "" root, _ := r.cache.Get(rootURL.String()) @@ -85,16 +102,13 @@ func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) (*schemaLoad // traversing multiple documents newOptions := r.options newOptions.RelativeBase = rootURL.String() - debugLog("setting new root: %s", newOptions.RelativeBase) return defaultSchemaLoader(root, newOptions, r.cache, r.context) } func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string) string { if transitive != r { - debugLog("got a new resolver") if transitive.options != nil && transitive.options.RelativeBase != "" { basePath, _ = absPath(transitive.options.RelativeBase) - debugLog("new basePath = %s", basePath) } } return basePath @@ -103,17 +117,19 @@ func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string) func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string) error { tgt := reflect.ValueOf(target) if tgt.Kind() != reflect.Ptr { - return fmt.Errorf("resolve ref: target needs to be a pointer") + return ErrResolveRefNeedsAPointer } - refURL := ref.GetURL() - if refURL == nil { + if ref.GetURL() == nil { return nil } - var res interface{} - var data interface{} - var err error + var ( + res interface{} + data interface{} + err error + ) + // Resolve against the root if it isn't nil, and if ref is pointing at the root, or has a fragment only which means // it is pointing somewhere in the root. root := r.root @@ -122,12 +138,11 @@ func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string) root, _, _, _ = r.load(baseRef.GetURL()) } } + if (ref.IsRoot() || ref.HasFragmentOnly) && root != nil { data = root } else { baseRef := normalizeFileRef(ref, basePath) - debugLog("current ref is: %s", ref.String()) - debugLog("current ref normalized file: %s", baseRef.String()) data, _, _, err = r.load(baseRef.GetURL()) if err != nil { return err @@ -150,27 +165,29 @@ func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error) toFetch.Fragment = "" var err error - path := toFetch.String() - if path == rootBase { - path, err = absPath(rootBase) + pth := toFetch.String() + if pth == rootBase { + pth, err = absPath(rootBase) if err != nil { return nil, url.URL{}, false, err } } - normalized := normalizeAbsPath(path) + normalized := normalizeAbsPath(pth) data, fromCache := r.cache.Get(normalized) if !fromCache { - b, err := r.loadDoc(normalized) + b, err := r.context.loadDoc(normalized) if err != nil { - debugLog("unable to load the document: %v", err) - return nil, url.URL{}, false, err + return nil, url.URL{}, false, fmt.Errorf("%s [%s]: %w", pth, normalized, err) } - if err := json.Unmarshal(b, &data); err != nil { + var doc interface{} + if err := json.Unmarshal(b, &doc); err != nil { return nil, url.URL{}, false, err } - r.cache.Set(normalized, data) + r.cache.Set(normalized, doc) + + return doc, toFetch, fromCache, nil } return data, toFetch, fromCache, nil @@ -185,17 +202,20 @@ func (r *schemaLoader) isCircular(ref *Ref, basePath string, parentRefs ...strin foundCycle = true return } - foundCycle = swag.ContainsStringsCI(parentRefs, normalizedRef) + foundCycle = swag.ContainsStringsCI(parentRefs, normalizedRef) // TODO(fred): normalize windows url and remove CI equality if foundCycle { r.context.circulars[normalizedRef] = true } return } -// Resolve resolves a reference against basePath and stores the result in target -// Resolve is not in charge of following references, it only resolves ref by following its URL -// if the schema that ref is referring to has more refs in it. Resolve doesn't resolve them -// if basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct +// Resolve resolves a reference against basePath and stores the result in target. +// +// Resolve is not in charge of following references: it only resolves ref by following its URL. +// +// If the schema the ref is referring to holds nested refs, Resolve doesn't resolve them. +// +// If basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct func (r *schemaLoader) Resolve(ref *Ref, target interface{}, basePath string) error { return r.resolveRef(ref, target, basePath) } @@ -212,30 +232,32 @@ func (r *schemaLoader) deref(input interface{}, parentRefs []string, basePath st case *PathItem: ref = &refable.Ref default: - return fmt.Errorf("deref: unsupported type %T", input) + return fmt.Errorf("unsupported type: %T: %w", input, ErrDerefUnsupportedType) } curRef := ref.String() - if curRef != "" { - normalizedRef := normalizeFileRef(ref, basePath) - normalizedBasePath := normalizedRef.RemoteURI() + if curRef == "" { + return nil + } - if r.isCircular(normalizedRef, basePath, parentRefs...) { - return nil - } + normalizedRef := normalizeFileRef(ref, basePath) + normalizedBasePath := normalizedRef.RemoteURI() - if err := r.resolveRef(ref, input, basePath); r.shouldStopOnError(err) { - return err - } + if r.isCircular(normalizedRef, basePath, parentRefs...) { + return nil + } - // NOTE(fredbi): removed basePath check => needs more testing - if ref.String() != "" && ref.String() != curRef { - parentRefs = append(parentRefs, normalizedRef.String()) - return r.deref(input, parentRefs, normalizedBasePath) - } + if err := r.resolveRef(ref, input, basePath); r.shouldStopOnError(err) { + return err + } + + if ref.String() == "" || ref.String() == curRef { + // done with rereferencing + return nil } - return nil + parentRefs = append(parentRefs, normalizedRef.String()) + return r.deref(input, parentRefs, normalizedBasePath) } func (r *schemaLoader) shouldStopOnError(err error) bool { @@ -250,30 +272,48 @@ func (r *schemaLoader) shouldStopOnError(err error) bool { return false } +func (r *schemaLoader) setSchemaID(target interface{}, id, basePath string) (string, string) { + debugLog("schema has ID: %s", id) + + // handling the case when id is a folder + // remember that basePath has to point to a file + var refPath string + if strings.HasSuffix(id, "/") { + // path.Clean here would not work correctly if there is a scheme (e.g. https://...) + refPath = fmt.Sprintf("%s%s", id, "placeholder.json") + } else { + refPath = id + } + + // updates the current base path + // * important: ID can be a relative path + // * registers target to be fetchable from the new base proposed by this id + newBasePath := normalizePaths(refPath, basePath) + + // store found IDs for possible future reuse in $ref + r.cache.Set(newBasePath, target) + + return newBasePath, refPath +} + func defaultSchemaLoader( root interface{}, expandOptions *ExpandOptions, cache ResolutionCache, - context *resolverContext) (*schemaLoader, error) { + context *resolverContext) *schemaLoader { - if cache == nil { - cache = resCache - } if expandOptions == nil { expandOptions = &ExpandOptions{} } - absBase, _ := absPath(expandOptions.RelativeBase) + if context == nil { - context = newResolverContext(absBase) + context = newResolverContext(expandOptions) } + return &schemaLoader{ root: root, options: expandOptions, - cache: cache, + cache: cacheOrDefault(cache), context: context, - loadDoc: func(path string) (json.RawMessage, error) { - debugLog("fetching document at %q", path) - return PathLoader(path) - }, - }, nil + } } diff --git a/vendor/github.com/go-openapi/spec/security_scheme.go b/vendor/github.com/go-openapi/spec/security_scheme.go index fe353842a6fc4..f7176ef6aecd2 100644 --- a/vendor/github.com/go-openapi/spec/security_scheme.go +++ b/vendor/github.com/go-openapi/spec/security_scheme.go @@ -82,12 +82,12 @@ func OAuth2AccessToken(authorizationURL, tokenURL string) *SecurityScheme { type SecuritySchemeProps struct { Description string `json:"description,omitempty"` Type string `json:"type"` - Name string `json:"name,omitempty"` // api key - In string `json:"in,omitempty"` // api key - Flow string `json:"flow,omitempty"` // oauth2 - AuthorizationURL string `json:"authorizationUrl,omitempty"` // oauth2 - TokenURL string `json:"tokenUrl,omitempty"` // oauth2 - Scopes map[string]string `json:"scopes,omitempty"` // oauth2 + Name string `json:"name,omitempty"` // api key + In string `json:"in,omitempty"` // api key + Flow string `json:"flow,omitempty"` // oauth2 + AuthorizationURL string `json:"authorizationUrl"` // oauth2 + TokenURL string `json:"tokenUrl,omitempty"` // oauth2 + Scopes map[string]string `json:"scopes,omitempty"` // oauth2 } // AddScope adds a scope to this security scheme @@ -120,10 +120,40 @@ func (s SecurityScheme) JSONLookup(token string) (interface{}, error) { // MarshalJSON marshal this to JSON func (s SecurityScheme) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(s.SecuritySchemeProps) + var ( + b1 []byte + err error + ) + + if s.Type == oauth2 { + // when oauth2, empty AuthorizationURL is added as empty string + b1, err = json.Marshal(s.SecuritySchemeProps) + } else { + // when not oauth2, empty AuthorizationURL should be omitted + b1, err = json.Marshal(struct { + Description string `json:"description,omitempty"` + Type string `json:"type"` + Name string `json:"name,omitempty"` // api key + In string `json:"in,omitempty"` // api key + Flow string `json:"flow,omitempty"` // oauth2 + AuthorizationURL string `json:"authorizationUrl,omitempty"` // oauth2 + TokenURL string `json:"tokenUrl,omitempty"` // oauth2 + Scopes map[string]string `json:"scopes,omitempty"` // oauth2 + }{ + Description: s.Description, + Type: s.Type, + Name: s.Name, + In: s.In, + Flow: s.Flow, + AuthorizationURL: s.AuthorizationURL, + TokenURL: s.TokenURL, + Scopes: s.Scopes, + }) + } if err != nil { return nil, err } + b2, err := json.Marshal(s.VendorExtensible) if err != nil { return nil, err diff --git a/vendor/github.com/go-openapi/spec/spec.go b/vendor/github.com/go-openapi/spec/spec.go index 0bb045bc06ad1..7d38b6e6251e4 100644 --- a/vendor/github.com/go-openapi/spec/spec.go +++ b/vendor/github.com/go-openapi/spec/spec.go @@ -14,7 +14,9 @@ package spec -import "encoding/json" +import ( + "encoding/json" +) //go:generate curl -L --progress -o ./schemas/v2/schema.json http://swagger.io/v2/schema.json //go:generate curl -L --progress -o ./schemas/jsonschema-draft-04.json http://json-schema.org/draft-04/schema @@ -28,16 +30,6 @@ const ( JSONSchemaURL = "http://json-schema.org/draft-04/schema#" ) -var ( - jsonSchema *Schema - swaggerSchema *Schema -) - -func init() { - jsonSchema = MustLoadJSONSchemaDraft04() - swaggerSchema = MustLoadSwagger20Schema() -} - // MustLoadJSONSchemaDraft04 panics when Swagger20Schema returns an error func MustLoadJSONSchemaDraft04() *Schema { d, e := JSONSchemaDraft04() diff --git a/vendor/github.com/go-openapi/spec/validations.go b/vendor/github.com/go-openapi/spec/validations.go new file mode 100644 index 0000000000000..6360a8ea77464 --- /dev/null +++ b/vendor/github.com/go-openapi/spec/validations.go @@ -0,0 +1,215 @@ +package spec + +// CommonValidations describe common JSON-schema validations +type CommonValidations struct { + Maximum *float64 `json:"maximum,omitempty"` + ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"` + Minimum *float64 `json:"minimum,omitempty"` + ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"` + MaxLength *int64 `json:"maxLength,omitempty"` + MinLength *int64 `json:"minLength,omitempty"` + Pattern string `json:"pattern,omitempty"` + MaxItems *int64 `json:"maxItems,omitempty"` + MinItems *int64 `json:"minItems,omitempty"` + UniqueItems bool `json:"uniqueItems,omitempty"` + MultipleOf *float64 `json:"multipleOf,omitempty"` + Enum []interface{} `json:"enum,omitempty"` +} + +// SetValidations defines all validations for a simple schema. +// +// NOTE: the input is the larger set of validations available for schemas. +// For simple schemas, MinProperties and MaxProperties are ignored. +func (v *CommonValidations) SetValidations(val SchemaValidations) { + v.Maximum = val.Maximum + v.ExclusiveMaximum = val.ExclusiveMaximum + v.Minimum = val.Minimum + v.ExclusiveMinimum = val.ExclusiveMinimum + v.MaxLength = val.MaxLength + v.MinLength = val.MinLength + v.Pattern = val.Pattern + v.MaxItems = val.MaxItems + v.MinItems = val.MinItems + v.UniqueItems = val.UniqueItems + v.MultipleOf = val.MultipleOf + v.Enum = val.Enum +} + +type clearedValidation struct { + Validation string + Value interface{} +} + +type clearedValidations []clearedValidation + +func (c clearedValidations) apply(cbs []func(string, interface{})) { + for _, cb := range cbs { + for _, cleared := range c { + cb(cleared.Validation, cleared.Value) + } + } +} + +// ClearNumberValidations clears all number validations. +// +// Some callbacks may be set by the caller to capture changed values. +func (v *CommonValidations) ClearNumberValidations(cbs ...func(string, interface{})) { + done := make(clearedValidations, 0, 5) + defer func() { + done.apply(cbs) + }() + + if v.Minimum != nil { + done = append(done, clearedValidation{Validation: "minimum", Value: v.Minimum}) + v.Minimum = nil + } + if v.Maximum != nil { + done = append(done, clearedValidation{Validation: "maximum", Value: v.Maximum}) + v.Maximum = nil + } + if v.ExclusiveMaximum { + done = append(done, clearedValidation{Validation: "exclusiveMaximum", Value: v.ExclusiveMaximum}) + v.ExclusiveMaximum = false + } + if v.ExclusiveMinimum { + done = append(done, clearedValidation{Validation: "exclusiveMinimum", Value: v.ExclusiveMinimum}) + v.ExclusiveMinimum = false + } + if v.MultipleOf != nil { + done = append(done, clearedValidation{Validation: "multipleOf", Value: v.MultipleOf}) + v.MultipleOf = nil + } +} + +// ClearStringValidations clears all string validations. +// +// Some callbacks may be set by the caller to capture changed values. +func (v *CommonValidations) ClearStringValidations(cbs ...func(string, interface{})) { + done := make(clearedValidations, 0, 3) + defer func() { + done.apply(cbs) + }() + + if v.Pattern != "" { + done = append(done, clearedValidation{Validation: "pattern", Value: v.Pattern}) + v.Pattern = "" + } + if v.MinLength != nil { + done = append(done, clearedValidation{Validation: "minLength", Value: v.MinLength}) + v.MinLength = nil + } + if v.MaxLength != nil { + done = append(done, clearedValidation{Validation: "maxLength", Value: v.MaxLength}) + v.MaxLength = nil + } +} + +// ClearArrayValidations clears all array validations. +// +// Some callbacks may be set by the caller to capture changed values. +func (v *CommonValidations) ClearArrayValidations(cbs ...func(string, interface{})) { + done := make(clearedValidations, 0, 3) + defer func() { + done.apply(cbs) + }() + + if v.MaxItems != nil { + done = append(done, clearedValidation{Validation: "maxItems", Value: v.MaxItems}) + v.MaxItems = nil + } + if v.MinItems != nil { + done = append(done, clearedValidation{Validation: "minItems", Value: v.MinItems}) + v.MinItems = nil + } + if v.UniqueItems { + done = append(done, clearedValidation{Validation: "uniqueItems", Value: v.UniqueItems}) + v.UniqueItems = false + } +} + +// Validations returns a clone of the validations for a simple schema. +// +// NOTE: in the context of simple schema objects, MinProperties, MaxProperties +// and PatternProperties remain unset. +func (v CommonValidations) Validations() SchemaValidations { + return SchemaValidations{ + CommonValidations: v, + } +} + +// HasNumberValidations indicates if the validations are for numbers or integers +func (v CommonValidations) HasNumberValidations() bool { + return v.Maximum != nil || v.Minimum != nil || v.MultipleOf != nil +} + +// HasStringValidations indicates if the validations are for strings +func (v CommonValidations) HasStringValidations() bool { + return v.MaxLength != nil || v.MinLength != nil || v.Pattern != "" +} + +// HasArrayValidations indicates if the validations are for arrays +func (v CommonValidations) HasArrayValidations() bool { + return v.MaxItems != nil || v.MinItems != nil || v.UniqueItems +} + +// HasEnum indicates if the validation includes some enum constraint +func (v CommonValidations) HasEnum() bool { + return len(v.Enum) > 0 +} + +// SchemaValidations describes the validation properties of a schema +// +// NOTE: at this moment, this is not embedded in SchemaProps because this would induce a breaking change +// in the exported members: all initializers using litterals would fail. +type SchemaValidations struct { + CommonValidations + + PatternProperties SchemaProperties `json:"patternProperties,omitempty"` + MaxProperties *int64 `json:"maxProperties,omitempty"` + MinProperties *int64 `json:"minProperties,omitempty"` +} + +// HasObjectValidations indicates if the validations are for objects +func (v SchemaValidations) HasObjectValidations() bool { + return v.MaxProperties != nil || v.MinProperties != nil || v.PatternProperties != nil +} + +// SetValidations for schema validations +func (v *SchemaValidations) SetValidations(val SchemaValidations) { + v.CommonValidations.SetValidations(val) + v.PatternProperties = val.PatternProperties + v.MaxProperties = val.MaxProperties + v.MinProperties = val.MinProperties +} + +// Validations for a schema +func (v SchemaValidations) Validations() SchemaValidations { + val := v.CommonValidations.Validations() + val.PatternProperties = v.PatternProperties + val.MinProperties = v.MinProperties + val.MaxProperties = v.MaxProperties + return val +} + +// ClearObjectValidations returns a clone of the validations with all object validations cleared. +// +// Some callbacks may be set by the caller to capture changed values. +func (v *SchemaValidations) ClearObjectValidations(cbs ...func(string, interface{})) { + done := make(clearedValidations, 0, 3) + defer func() { + done.apply(cbs) + }() + + if v.MaxProperties != nil { + done = append(done, clearedValidation{Validation: "maxProperties", Value: v.MaxProperties}) + v.MaxProperties = nil + } + if v.MinProperties != nil { + done = append(done, clearedValidation{Validation: "minProperties", Value: v.MinProperties}) + v.MinProperties = nil + } + if v.PatternProperties != nil { + done = append(done, clearedValidation{Validation: "patternProperties", Value: v.PatternProperties}) + v.PatternProperties = nil + } +} diff --git a/vendor/github.com/go-openapi/strfmt/.golangci.yml b/vendor/github.com/go-openapi/strfmt/.golangci.yml index 03ffa31a4eefa..7ffaa32b9b474 100644 --- a/vendor/github.com/go-openapi/strfmt/.golangci.yml +++ b/vendor/github.com/go-openapi/strfmt/.golangci.yml @@ -25,6 +25,17 @@ linters: - whitespace - wsl - funlen + - wrapcheck + - testpackage + - nlreturn + - gofumpt + - goerr113 + - gci + - gomnd + - godot + - exhaustivestruct + - paralleltest + #- thelper issues: exclude-rules: diff --git a/vendor/github.com/go-openapi/strfmt/.travis.yml b/vendor/github.com/go-openapi/strfmt/.travis.yml index eb962aebcda8b..eaee5b65a93e6 100644 --- a/vendor/github.com/go-openapi/strfmt/.travis.yml +++ b/vendor/github.com/go-openapi/strfmt/.travis.yml @@ -1,13 +1,29 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.11.x -- 1.12.x +- 1.14.x +- 1.x +arch: +- amd64 +jobs: + include: + # only run fast tests on ppc64le + - go: 1.x + arch: ppc64le + script: + - gotestsum -f short-verbose -- ./... + + # include linting job, but only for latest go version and amd64 arch + - go: 1.x + arch: amd64 + install: + go get github.com/golangci/golangci-lint/cmd/golangci-lint + script: + - golangci-lint run --new-from-rev master + install: - GO111MODULE=off go get -u gotest.tools/gotestsum language: go -env: -- GO111MODULE=on notifications: slack: secure: zE5AtIYTpYfQPnTzP+EaQPN7JKtfFAGv6PrJqoIZLOXa8B6zGb6+J1JRNNxWi7faWbyJOxa4FSSsuPsKZMycUK6wlLFIdhDxwqeo7Ew8r6rdZKdfUHQggfNS9wO79ARoNYUDHtmnaBUS+eWSM1YqSc4i99QxyyfuURLOeAaA/q14YbdlTlaw3lrZ0qT92ot1FnVGNOx064zuHtFeUf+jAVRMZ6Q3rvqllwIlPszE6rmHGXBt2VoJxRaBetdwd7FgkcYw9FPXKHhadwC7/75ZAdmxIukhxNMw4Tr5NuPcqNcnbYLenDP7B3lssGVIrP4BRSqekS1d/tqvdvnnFWHMwrNCkSnSc065G5+qWTlXKAemIclgiXXqE2furBNLm05MDdG8fn5epS0UNarkjD+zX336RiqwBlOX4KbF+vPyqcO98CsN0lnd+H6loc9reiTHs37orFFpQ+309av9be2GGsHUsRB9ssIyrewmhAccOmkRtr2dVTZJNFQwa5Kph5TNJuTjnZEwG/xUkEX2YSfwShOsb062JWiflV6PJdnl80pc9Tn7D5sO5Bf9DbijGRJwwP+YiiJtwtr+vsvS+n4sM0b5eqm4UoRo+JJO8ffoJtHS7ItuyRbVQCwEPJ4221WLcf5PquEEDdAPwR+K4Gj8qTXqTDdxOiES1xFUKVgmzhI= diff --git a/vendor/github.com/go-openapi/strfmt/date.go b/vendor/github.com/go-openapi/strfmt/date.go index 15029ffa2fea1..f0b310964d9ab 100644 --- a/vendor/github.com/go-openapi/strfmt/date.go +++ b/vendor/github.com/go-openapi/strfmt/date.go @@ -180,3 +180,8 @@ func (d *Date) UnmarshalBinary(data []byte) error { return nil } + +// Equal checks if two Date instances are equal +func (d Date) Equal(d2 Date) bool { + return time.Time(d).Equal(time.Time(d2)) +} diff --git a/vendor/github.com/go-openapi/strfmt/format.go b/vendor/github.com/go-openapi/strfmt/format.go index ca1cdf862ec2f..3f93a72c86e1f 100644 --- a/vendor/github.com/go-openapi/strfmt/format.go +++ b/vendor/github.com/go-openapi/strfmt/format.go @@ -65,7 +65,7 @@ type NameNormalizer func(string) string // DefaultNameNormalizer removes all dashes func DefaultNameNormalizer(name string) string { - return strings.Replace(name, "-", "", -1) + return strings.ReplaceAll(name, "-", "") } type defaultFormats struct { diff --git a/vendor/github.com/go-openapi/strfmt/go.mod b/vendor/github.com/go-openapi/strfmt/go.mod index eaf75447125b7..6eaa6d7b94933 100644 --- a/vendor/github.com/go-openapi/strfmt/go.mod +++ b/vendor/github.com/go-openapi/strfmt/go.mod @@ -1,15 +1,12 @@ module github.com/go-openapi/strfmt require ( - github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a - github.com/go-openapi/errors v0.19.2 - github.com/go-stack/stack v1.8.0 // indirect - github.com/google/go-cmp v0.3.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef + github.com/go-openapi/errors v0.19.8 github.com/google/uuid v1.1.1 - github.com/mitchellh/mapstructure v1.1.2 - github.com/stretchr/testify v1.3.0 - github.com/tidwall/pretty v1.0.0 // indirect - go.mongodb.org/mongo-driver v1.0.3 + github.com/mitchellh/mapstructure v1.3.3 + github.com/stretchr/testify v1.6.1 + go.mongodb.org/mongo-driver v1.4.3 ) go 1.13 diff --git a/vendor/github.com/go-openapi/strfmt/go.sum b/vendor/github.com/go-openapi/strfmt/go.sum index e53dd37c10a99..a2d360321b65e 100644 --- a/vendor/github.com/go-openapi/strfmt/go.sum +++ b/vendor/github.com/go-openapi/strfmt/go.sum @@ -1,25 +1,130 @@ -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY= -github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -go.mongodb.org/mongo-driver v1.0.3 h1:GKoji1ld3tw2aC+GX1wbr/J2fX13yNacEYoJ8Nhr0yU= -go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +go.mongodb.org/mongo-driver v1.4.3 h1:moga+uhicpVshTyaqY9L23E6QqwcHRUv1sqyOsoyOO8= +go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/go-openapi/strfmt/time.go b/vendor/github.com/go-openapi/strfmt/time.go index 0b2f52d2490a2..425413f7ec96f 100644 --- a/vendor/github.com/go-openapi/strfmt/time.go +++ b/vendor/github.com/go-openapi/strfmt/time.go @@ -55,23 +55,36 @@ func IsDateTime(str string) bool { const ( // RFC3339Millis represents a ISO8601 format to millis instead of to nanos RFC3339Millis = "2006-01-02T15:04:05.000Z07:00" + // RFC3339MillisNoColon represents a ISO8601 format to millis instead of to nanos + RFC3339MillisNoColon = "2006-01-02T15:04:05.000Z0700" // RFC3339Micro represents a ISO8601 format to micro instead of to nano RFC3339Micro = "2006-01-02T15:04:05.000000Z07:00" + // RFC3339MicroNoColon represents a ISO8601 format to micro instead of to nano + RFC3339MicroNoColon = "2006-01-02T15:04:05.000000Z0700" // ISO8601LocalTime represents a ISO8601 format to ISO8601 in local time (no timezone) ISO8601LocalTime = "2006-01-02T15:04:05" // ISO8601TimeWithReducedPrecision represents a ISO8601 format with reduced precision (dropped secs) ISO8601TimeWithReducedPrecision = "2006-01-02T15:04Z" - // ISO8601TimeWithReducedPrecision represents a ISO8601 format with reduced precision and no timezone (dropped seconds + no timezone) + // ISO8601TimeWithReducedPrecisionLocaltime represents a ISO8601 format with reduced precision and no timezone (dropped seconds + no timezone) ISO8601TimeWithReducedPrecisionLocaltime = "2006-01-02T15:04" + // ISO8601TimeUniversalSortableDateTimePattern represents a ISO8601 universal sortable date time pattern. + ISO8601TimeUniversalSortableDateTimePattern = "2006-01-02 15:04:05" // DateTimePattern pattern to match for the date-time format from http://tools.ietf.org/html/rfc3339#section-5.6 DateTimePattern = `^([0-9]{2}):([0-9]{2}):([0-9]{2})(.[0-9]+)?(z|([+-][0-9]{2}:[0-9]{2}))$` ) var ( - dateTimeFormats = []string{RFC3339Micro, RFC3339Millis, time.RFC3339, time.RFC3339Nano, ISO8601LocalTime, ISO8601TimeWithReducedPrecision, ISO8601TimeWithReducedPrecisionLocaltime} - rxDateTime = regexp.MustCompile(DateTimePattern) + rxDateTime = regexp.MustCompile(DateTimePattern) + + // DateTimeFormats is the collection of formats used by ParseDateTime() + DateTimeFormats = []string{RFC3339Micro, RFC3339MicroNoColon, RFC3339Millis, RFC3339MillisNoColon, time.RFC3339, time.RFC3339Nano, ISO8601LocalTime, ISO8601TimeWithReducedPrecision, ISO8601TimeWithReducedPrecisionLocaltime, ISO8601TimeUniversalSortableDateTimePattern} + // MarshalFormat sets the time resolution format used for marshaling time (set to milliseconds) MarshalFormat = RFC3339Millis + + // NormalizeTimeForMarshal provides a normalization function on time befeore marshalling (e.g. time.UTC). + // By default, the time value is not changed. + NormalizeTimeForMarshal = func(t time.Time) time.Time { return t } ) // ParseDateTime parses a string that represents an ISO8601 time or a unix epoch @@ -80,7 +93,7 @@ func ParseDateTime(data string) (DateTime, error) { return NewDateTime(), nil } var lastError error - for _, layout := range dateTimeFormats { + for _, layout := range DateTimeFormats { dd, err := time.Parse(layout, data) if err != nil { lastError = err @@ -106,7 +119,7 @@ func NewDateTime() DateTime { // String converts this time to a string func (t DateTime) String() string { - return time.Time(t).Format(MarshalFormat) + return NormalizeTimeForMarshal(time.Time(t)).Format(MarshalFormat) } // MarshalText implements the text marshaller interface @@ -150,7 +163,7 @@ func (t DateTime) Value() (driver.Value, error) { // MarshalJSON returns the DateTime as JSON func (t DateTime) MarshalJSON() ([]byte, error) { - return json.Marshal(time.Time(t).Format(MarshalFormat)) + return json.Marshal(NormalizeTimeForMarshal(time.Time(t)).Format(MarshalFormat)) } // UnmarshalJSON sets the DateTime from JSON @@ -199,7 +212,7 @@ func (t *DateTime) UnmarshalBSON(data []byte) error { func (t DateTime) MarshalBSONValue() (bsontype.Type, []byte, error) { // UnixNano cannot be used, the result of calling UnixNano on the zero // Time is undefined. - i64 := time.Time(t).Unix() * 1000 + i64 := NormalizeTimeForMarshal(time.Time(t)).Unix() * 1000 buf := make([]byte, 8) binary.LittleEndian.PutUint64(buf, uint64(i64)) @@ -245,7 +258,7 @@ func (t *DateTime) GobDecode(data []byte) error { // MarshalBinary implements the encoding.BinaryMarshaler interface. func (t DateTime) MarshalBinary() ([]byte, error) { - return time.Time(t).MarshalBinary() + return NormalizeTimeForMarshal(time.Time(t)).MarshalBinary() } // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. @@ -261,3 +274,8 @@ func (t *DateTime) UnmarshalBinary(data []byte) error { return nil } + +// Equal checks if two DateTime instances are equal using time.Time's Equal method +func (t DateTime) Equal(t2 DateTime) bool { + return time.Time(t).Equal(time.Time(t2)) +} diff --git a/vendor/github.com/go-openapi/swag/.golangci.yml b/vendor/github.com/go-openapi/swag/.golangci.yml index 625c3d6affe1c..7fae938e64530 100644 --- a/vendor/github.com/go-openapi/swag/.golangci.yml +++ b/vendor/github.com/go-openapi/swag/.golangci.yml @@ -20,3 +20,19 @@ linters: - lll - gochecknoinits - gochecknoglobals + - nlreturn + - testpackage + - wrapcheck + - gomnd + - exhaustive + - exhaustivestruct + - goerr113 + - wsl + - whitespace + - gofumpt + - godot + - nestif + - godox + - funlen + - gci + - gocognit diff --git a/vendor/github.com/go-openapi/swag/.travis.yml b/vendor/github.com/go-openapi/swag/.travis.yml index f1a3f80b35021..fc25a887286c8 100644 --- a/vendor/github.com/go-openapi/swag/.travis.yml +++ b/vendor/github.com/go-openapi/swag/.travis.yml @@ -1,8 +1,32 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.13.x - 1.14.x +- 1.x +arch: +- amd64 +jobs: + include: + # include arch ppc, but only for latest go version - skip testing for race + - go: 1.x + arch: ppc64le + install: ~ + script: + - go test -v + + #- go: 1.x + # arch: arm + # install: ~ + # script: + # - go test -v + + # include linting job, but only for latest go version and amd64 arch + - go: 1.x + arch: amd64 + install: + go get github.com/golangci/golangci-lint/cmd/golangci-lint + script: + - golangci-lint run --new-from-rev master install: - GO111MODULE=off go get -u gotest.tools/gotestsum language: go diff --git a/vendor/github.com/go-openapi/swag/README.md b/vendor/github.com/go-openapi/swag/README.md index eb60ae80abe68..217f6fa5054e3 100644 --- a/vendor/github.com/go-openapi/swag/README.md +++ b/vendor/github.com/go-openapi/swag/README.md @@ -2,7 +2,6 @@ [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag) -[![GolangCI](https://golangci.com/badges/github.com/go-openapi/swag.svg)](https://golangci.com) [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag) Contains a bunch of helper functions for go-openapi and go-swagger projects. diff --git a/vendor/github.com/go-openapi/swag/go.mod b/vendor/github.com/go-openapi/swag/go.mod index 4aef463e425ef..fb29b65b25659 100644 --- a/vendor/github.com/go-openapi/swag/go.mod +++ b/vendor/github.com/go-openapi/swag/go.mod @@ -2,15 +2,17 @@ module github.com/go-openapi/swag require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/kr/pretty v0.1.0 // indirect - github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 - github.com/stretchr/testify v1.3.0 - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect - gopkg.in/yaml.v2 v2.2.4 + github.com/kr/text v0.2.0 // indirect + github.com/mailru/easyjson v0.7.6 + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect + github.com/stretchr/testify v1.6.1 + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect + gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect ) replace github.com/golang/lint => golang.org/x/lint v0.0.0-20190409202823-959b441ac422 replace sourcegraph.com/sourcegraph/go-diff => github.com/sourcegraph/go-diff v0.5.1 -go 1.13 +go 1.11 diff --git a/vendor/github.com/go-openapi/swag/go.sum b/vendor/github.com/go-openapi/swag/go.sum index e8a80bacf0ae1..a45da809afac5 100644 --- a/vendor/github.com/go-openapi/swag/go.sum +++ b/vendor/github.com/go-openapi/swag/go.sum @@ -1,20 +1,29 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading.go index 04160b89ba9de..0bb22df140272 100644 --- a/vendor/github.com/go-openapi/swag/loading.go +++ b/vendor/github.com/go-openapi/swag/loading.go @@ -53,7 +53,7 @@ func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func( return remote } return func(pth string) ([]byte, error) { - upth, err := pathUnescape(pth) + upth, err := pathUnescape(strings.TrimPrefix(pth, `file://`)) if err != nil { return nil, err } @@ -64,7 +64,7 @@ func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func( func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) { return func(path string) ([]byte, error) { client := &http.Client{Timeout: timeout} - req, err := http.NewRequest("GET", path, nil) + req, err := http.NewRequest("GET", path, nil) // nolint: noctx if err != nil { return nil, err } diff --git a/vendor/github.com/go-openapi/swag/util.go b/vendor/github.com/go-openapi/swag/util.go index 9eac16afb2e1b..193702f2cec07 100644 --- a/vendor/github.com/go-openapi/swag/util.go +++ b/vendor/github.com/go-openapi/swag/util.go @@ -31,7 +31,7 @@ var isInitialism func(string) bool // GoNamePrefixFunc sets an optional rule to prefix go names // which do not start with a letter. // -// e.g. to help converting "123" into "{prefix}123" +// e.g. to help convert "123" into "{prefix}123" // // The default is to prefix with "X" var GoNamePrefixFunc func(string) string @@ -91,7 +91,7 @@ func init() { } const ( - //collectionFormatComma = "csv" + // collectionFormatComma = "csv" collectionFormatSpace = "ssv" collectionFormatTab = "tsv" collectionFormatPipe = "pipes" @@ -370,7 +370,7 @@ func IsZero(data interface{}) bool { // AddInitialisms add additional initialisms func AddInitialisms(words ...string) { for _, word := range words { - //commonInitialisms[upper(word)] = true + // commonInitialisms[upper(word)] = true commonInitialisms.add(upper(word)) } // sort again diff --git a/vendor/github.com/go-openapi/validate/.golangci.yml b/vendor/github.com/go-openapi/validate/.golangci.yml index dc8178c809db3..7dbddddfec26f 100644 --- a/vendor/github.com/go-openapi/validate/.golangci.yml +++ b/vendor/github.com/go-openapi/validate/.golangci.yml @@ -26,3 +26,17 @@ linters: - gochecknoglobals - gochecknoinits - scopelint + - wrapcheck + - exhaustivestruct + - exhaustive + - nlreturn + - testpackage + - gci + - gofumpt + - goerr113 + - gomnd + - tparallel + - nestif + - godot + - tparallel + - paralleltest diff --git a/vendor/github.com/go-openapi/validate/.travis.yml b/vendor/github.com/go-openapi/validate/.travis.yml index db0bb78f5d4bd..6fb3fb00563fb 100644 --- a/vendor/github.com/go-openapi/validate/.travis.yml +++ b/vendor/github.com/go-openapi/validate/.travis.yml @@ -1,8 +1,47 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.13.x - 1.14.x +- 1.x +arch: +- amd64 +jobs: + include: + # only run fast tests on ppc64le + - go: 1.x + arch: ppc64le + script: + - gotestsum -f short-verbose -- ./... + + # include large spec validation sample (run once) + - go: 1.x + arch: amd64 + script: + - gotestsum -f short-verbose -- -timeout=30m -args -enable-go-swagger ./... + + # include linting job, but only for latest go version and amd64 arch (run once) + - go: 1.x + arch: amd64 + install: + - GO111MODULE=off go get -u gotest.tools/gotestsum + - go get -u github.com/go-openapi/runtime@master + script: + - gotestsum -f short-verbose -- -timeout=30m github.com/go-openapi/runtime/... + + # include go-openapi/runtime non reg job (run once) + - go: 1.x + arch: amd64 + install: + go get github.com/golangci/golangci-lint/cmd/golangci-lint + script: + - golangci-lint run --new-from-rev master + + # include -race test on short tests only (run once) + - go: 1.x + arch: amd64 + script: + - gotestsum -f short-verbose -- -race ./... + install: - GO111MODULE=off go get -u gotest.tools/gotestsum language: go @@ -10,8 +49,4 @@ notifications: slack: secure: EmObnQuM9Mw8J9vpFaKKHqSMN4Wsr/A9+v7ewAD5cEhA0T1P4m7MbJMiJOhxUhj/X+BFh2DamW+P2lT8mybj5wg8wnkQ2BteKA8Tawi6f9PRw2NRheO8tAi8o/npLnlmet0kc93mn+oLuqHw36w4+j5mkOl2FghkfGiUVhwrhkCP7KXQN+3TU87e+/HzQumlJ3nsE+6terVxkH3PmaUTsS5ONaODZfuxFpfb7RsoEl3skHf6d+tr+1nViLxxly7558Nc33C+W1mr0qiEvMLZ+kJ/CpGWBJ6CUJM3jm6hNe2eMuIPwEK2hxZob8c7n22VPap4K6a0bBRoydoDXaba+2sD7Ym6ivDO/DVyL44VeBBLyIiIBylDGQdZH+6SoWm90Qe/i7tnY/T5Ao5igT8f3cfQY1c3EsTfqmlDfrhmACBmwSlgkdVBLTprHL63JMY24LWmh4jhxsmMRZhCL4dze8su1w6pLN/pD1pGHtKYCEVbdTmaM3PblNRFf12XB7qosmQsgUndH4Vq3bTbU0s1pKjeDhRyLvFzvR0TBbo0pDLEoF1A/i5GVFWa7yLZNUDudQERRh7qv/xBl2excIaQ1sV4DSVm7bAE9l6Kp+yeHQJW2uN6Y3X8wu9gB9nv9l5HBze7wh8KE6PyWAOLYYqZg9/sAtsv/2GcQqXcKFF1zcA= script: -- gotestsum -f short-verbose -- -race ./... - gotestsum -f short-verbose -- -timeout=20m -coverprofile=coverage.txt -covermode=atomic -args -enable-long ./... -- gotestsum -f short-verbose -- -timeout=30m -args -enable-go-swagger ./... -- go get -u github.com/go-openapi/runtime@master -- gotestsum -f short-verbose -- -timeout=30m github.com/go-openapi/runtime/... diff --git a/vendor/github.com/go-openapi/validate/README.md b/vendor/github.com/go-openapi/validate/README.md index 08fb352bcf367..94a1e00b63d7c 100644 --- a/vendor/github.com/go-openapi/validate/README.md +++ b/vendor/github.com/go-openapi/validate/README.md @@ -2,5 +2,34 @@ [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/validate/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/validate?status.svg)](http://godoc.org/github.com/go-openapi/validate) -[![GolangCI](https://golangci.com/badges/github.com/go-openapi/validate.svg)](https://golangci.com) [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/validate)](https://goreportcard.com/report/github.com/go-openapi/validate) + +This package provides helpers to validate Swagger 2.0. specification (aka OpenAPI 2.0). + +Reference can be found here: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md. + +## What's inside? + +* A validator for Swagger specifications +* A validator for JSON schemas draft4 +* Helper functions to validate individual values (used by code generated by [go-swagger](https://github.com/go-swagger/go-swagger)). + * Required, RequiredNumber, RequiredString + * ReadOnly + * UniqueItems, MaxItems, MinItems + * Enum, EnumCase + * Pattern, MinLength, MaxLength + * Minimum, Maximum, MultipleOf + * FormatOf + +[Documentation](https://godoc.org/github.com/go-openapi/validate) + +## FAQ + +* Does this library support OpenAPI 3? + +> No. +> This package currently only supports OpenAPI 2.0 (aka Swagger 2.0). +> There is no plan to make it evolve toward supporting OpenAPI 3.x. +> This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story. +> +> An early attempt to support Swagger 3 may be found at: https://github.com/go-openapi/spec3 diff --git a/vendor/github.com/go-openapi/validate/context.go b/vendor/github.com/go-openapi/validate/context.go new file mode 100644 index 0000000000000..bf02e94629d11 --- /dev/null +++ b/vendor/github.com/go-openapi/validate/context.go @@ -0,0 +1,56 @@ +package validate + +import ( + "context" +) + +// validateCtxKey is the key type of context key in this pkg +type validateCtxKey string + +const ( + operationTypeKey validateCtxKey = "operationTypeKey" +) + +type operationType string + +const ( + request operationType = "request" + response operationType = "response" + none operationType = "none" // not specified in ctx +) + +var operationTypeEnum []operationType = []operationType{request, response, none} + +// WithOperationRequest returns a new context with operationType request +// in context value +func WithOperationRequest(ctx context.Context) context.Context { + return withOperation(ctx, request) +} + +// WithOperationRequest returns a new context with operationType response +// in context value +func WithOperationResponse(ctx context.Context) context.Context { + return withOperation(ctx, response) +} + +func withOperation(ctx context.Context, operation operationType) context.Context { + return context.WithValue(ctx, operationTypeKey, operation) +} + +// extractOperationType extracts the operation type from ctx +// if not specified or of unknown value, return none operation type +func extractOperationType(ctx context.Context) operationType { + v := ctx.Value(operationTypeKey) + if v == nil { + return none + } + res, ok := v.(operationType) + if !ok { + return none + } + // validate the value is in operation enum + if err := Enum("", "", res, operationTypeEnum); err != nil { + return none + } + return res +} diff --git a/vendor/github.com/go-openapi/validate/default_validator.go b/vendor/github.com/go-openapi/validate/default_validator.go index 26d54b7c23b2c..3e0d8c770d3c9 100644 --- a/vendor/github.com/go-openapi/validate/default_validator.go +++ b/vendor/github.com/go-openapi/validate/default_validator.go @@ -107,7 +107,7 @@ func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result { // default values provided must validate against their inline definition (no explicit schema) if param.Default != nil && param.Schema == nil { // check param default value is valid - red := NewParamValidator(¶m, s.KnownFormats).Validate(param.Default) + red := NewParamValidator(¶m, s.KnownFormats).Validate(param.Default) //#nosec if red.HasErrorsOrWarnings() { res.AddErrors(defaultValueDoesNotValidateMsg(param.Name, param.In)) res.Merge(red) @@ -116,7 +116,7 @@ func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result { // Recursively follows Items and Schemas if param.Items != nil { - red := d.validateDefaultValueItemsAgainstSchema(param.Name, param.In, ¶m, param.Items) + red := d.validateDefaultValueItemsAgainstSchema(param.Name, param.In, ¶m, param.Items) //#nosec if red.HasErrorsOrWarnings() { res.AddErrors(defaultValueItemsDoesNotValidateMsg(param.Name, param.In)) res.Merge(red) @@ -141,7 +141,7 @@ func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result { // Same constraint on regular Responses if op.Responses.StatusCodeResponses != nil { // Safeguard for code, r := range op.Responses.StatusCodeResponses { - res.Merge(d.validateDefaultInResponse(&r, "response", path, code, op.ID)) + res.Merge(d.validateDefaultInResponse(&r, "response", path, code, op.ID)) //#nosec } } } else if op.ID != "" { @@ -154,7 +154,7 @@ func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result { // reset explored schemas to get depth-first recursive-proof exploration d.resetVisited() for nm, sch := range s.spec.Spec().Definitions { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("definitions.%s", nm), "body", &sch)) + res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("definitions.%s", nm), "body", &sch)) //#nosec } } return res @@ -177,7 +177,7 @@ func (d *defaultValidator) validateDefaultInResponse(resp *spec.Response, respon d.resetVisited() if h.Default != nil { - red := NewHeaderValidator(nm, &h, s.KnownFormats).Validate(h.Default) + red := NewHeaderValidator(nm, &h, s.KnownFormats).Validate(h.Default) //#nosec if red.HasErrorsOrWarnings() { res.AddErrors(defaultValueHeaderDoesNotValidateMsg(operationID, nm, responseName)) res.Merge(red) @@ -186,7 +186,7 @@ func (d *defaultValidator) validateDefaultInResponse(resp *spec.Response, respon // Headers have inline definition, like params if h.Items != nil { - red := d.validateDefaultValueItemsAgainstSchema(nm, "header", &h, h.Items) + red := d.validateDefaultValueItemsAgainstSchema(nm, "header", &h, h.Items) //#nosec if red.HasErrorsOrWarnings() { res.AddErrors(defaultValueHeaderItemsDoesNotValidateMsg(operationID, nm, responseName)) res.Merge(red) @@ -233,7 +233,7 @@ func (d *defaultValidator) validateDefaultValueSchemaAgainstSchema(path, in stri // Multiple schemas in items if schema.Items.Schemas != nil { // Safeguard for i, sch := range schema.Items.Schemas { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.items[%d].default", path, i), in, &sch)) + res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.items[%d].default", path, i), in, &sch)) //#nosec } } } @@ -245,17 +245,17 @@ func (d *defaultValidator) validateDefaultValueSchemaAgainstSchema(path, in stri res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalItems", path), in, schema.AdditionalItems.Schema)) } for propName, prop := range schema.Properties { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop)) + res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec } for propName, prop := range schema.PatternProperties { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop)) + res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec } if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil { res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalProperties", path), in, schema.AdditionalProperties.Schema)) } if schema.AllOf != nil { for i, aoSch := range schema.AllOf { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.allOf[%d]", path, i), in, &aoSch)) + res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.allOf[%d]", path, i), in, &aoSch)) //#nosec } } return res diff --git a/vendor/github.com/go-openapi/validate/example_validator.go b/vendor/github.com/go-openapi/validate/example_validator.go index 130359175131c..f4b7a2dfe98bf 100644 --- a/vendor/github.com/go-openapi/validate/example_validator.go +++ b/vendor/github.com/go-openapi/validate/example_validator.go @@ -83,7 +83,7 @@ func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result { // default values provided must validate against their inline definition (no explicit schema) if param.Example != nil && param.Schema == nil { // check param default value is valid - red := NewParamValidator(¶m, s.KnownFormats).Validate(param.Example) + red := NewParamValidator(¶m, s.KnownFormats).Validate(param.Example) //#nosec if red.HasErrorsOrWarnings() { res.AddWarnings(exampleValueDoesNotValidateMsg(param.Name, param.In)) res.MergeAsWarnings(red) @@ -92,7 +92,7 @@ func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result { // Recursively follows Items and Schemas if param.Items != nil { - red := ex.validateExampleValueItemsAgainstSchema(param.Name, param.In, ¶m, param.Items) + red := ex.validateExampleValueItemsAgainstSchema(param.Name, param.In, ¶m, param.Items) //#nosec if red.HasErrorsOrWarnings() { res.AddWarnings(exampleValueItemsDoesNotValidateMsg(param.Name, param.In)) res.Merge(red) @@ -117,7 +117,7 @@ func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result { // Same constraint on regular Responses if op.Responses.StatusCodeResponses != nil { // Safeguard for code, r := range op.Responses.StatusCodeResponses { - res.Merge(ex.validateExampleInResponse(&r, "response", path, code, op.ID)) + res.Merge(ex.validateExampleInResponse(&r, "response", path, code, op.ID)) //#nosec } } } else if op.ID != "" { @@ -130,7 +130,7 @@ func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result { // reset explored schemas to get depth-first recursive-proof exploration ex.resetVisited() for nm, sch := range s.spec.Spec().Definitions { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("definitions.%s", nm), "body", &sch)) + res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("definitions.%s", nm), "body", &sch)) //#nosec } } return res @@ -153,7 +153,7 @@ func (ex *exampleValidator) validateExampleInResponse(resp *spec.Response, respo ex.resetVisited() if h.Example != nil { - red := NewHeaderValidator(nm, &h, s.KnownFormats).Validate(h.Example) + red := NewHeaderValidator(nm, &h, s.KnownFormats).Validate(h.Example) //#nosec if red.HasErrorsOrWarnings() { res.AddWarnings(exampleValueHeaderDoesNotValidateMsg(operationID, nm, responseName)) res.MergeAsWarnings(red) @@ -162,7 +162,7 @@ func (ex *exampleValidator) validateExampleInResponse(resp *spec.Response, respo // Headers have inline definition, like params if h.Items != nil { - red := ex.validateExampleValueItemsAgainstSchema(nm, "header", &h, h.Items) + red := ex.validateExampleValueItemsAgainstSchema(nm, "header", &h, h.Items) //#nosec if red.HasErrorsOrWarnings() { res.AddWarnings(exampleValueHeaderItemsDoesNotValidateMsg(operationID, nm, responseName)) res.MergeAsWarnings(red) @@ -222,7 +222,7 @@ func (ex *exampleValidator) validateExampleValueSchemaAgainstSchema(path, in str // Multiple schemas in items if schema.Items.Schemas != nil { // Safeguard for i, sch := range schema.Items.Schemas { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.items[%d].example", path, i), in, &sch)) + res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.items[%d].example", path, i), in, &sch)) //#nosec } } } @@ -234,17 +234,17 @@ func (ex *exampleValidator) validateExampleValueSchemaAgainstSchema(path, in str res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalItems", path), in, schema.AdditionalItems.Schema)) } for propName, prop := range schema.Properties { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop)) + res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec } for propName, prop := range schema.PatternProperties { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop)) + res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec } if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil { res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalProperties", path), in, schema.AdditionalProperties.Schema)) } if schema.AllOf != nil { for i, aoSch := range schema.AllOf { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.allOf[%d]", path, i), in, &aoSch)) + res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.allOf[%d]", path, i), in, &aoSch)) //#nosec } } return res diff --git a/vendor/github.com/go-openapi/validate/go.mod b/vendor/github.com/go-openapi/validate/go.mod index 76b705283e4ba..afea97254b536 100644 --- a/vendor/github.com/go-openapi/validate/go.mod +++ b/vendor/github.com/go-openapi/validate/go.mod @@ -3,19 +3,14 @@ module github.com/go-openapi/validate go 1.14 require ( - github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect - github.com/go-openapi/analysis v0.19.10 - github.com/go-openapi/errors v0.19.6 - github.com/go-openapi/jsonpointer v0.19.3 - github.com/go-openapi/loads v0.19.5 - github.com/go-openapi/runtime v0.19.15 - github.com/go-openapi/spec v0.19.8 - github.com/go-openapi/strfmt v0.19.5 - github.com/go-openapi/swag v0.19.9 - github.com/mitchellh/mapstructure v1.3.2 // indirect + github.com/go-openapi/analysis v0.19.16 + github.com/go-openapi/errors v0.19.9 + github.com/go-openapi/jsonpointer v0.19.5 + github.com/go-openapi/loads v0.20.0 + github.com/go-openapi/runtime v0.19.24 + github.com/go-openapi/spec v0.20.0 + github.com/go-openapi/strfmt v0.19.11 + github.com/go-openapi/swag v0.19.12 github.com/stretchr/testify v1.6.1 - go.mongodb.org/mongo-driver v1.3.4 // indirect - golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect - gopkg.in/yaml.v2 v2.3.0 + gopkg.in/yaml.v2 v2.4.0 ) - diff --git a/vendor/github.com/go-openapi/validate/go.sum b/vendor/github.com/go-openapi/validate/go.sum index a52271927d8f3..61fbc8f2da06e 100644 --- a/vendor/github.com/go-openapi/validate/go.sum +++ b/vendor/github.com/go-openapi/validate/go.sum @@ -4,12 +4,17 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -27,22 +32,34 @@ github.com/go-openapi/analysis v0.19.5 h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOX github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= github.com/go-openapi/analysis v0.19.10 h1:5BHISBAXOc/aJK25irLZnx2D3s6WyYaY9D4gmuz9fdE= github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= +github.com/go-openapi/analysis v0.19.16 h1:Ub9e++M8sDwtHD+S587TYi+6ANBG1NRYGZDihqk0SaY= +github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.6 h1:xZMThgv5SQ7SMbWtKFkCf9bBdvR2iEyw9k3zGZONuys= github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.7 h1:Lcq+o0mSwCLKACMxZhreVHigB9ebghJ/lrmeaqASbjo= +github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9 h1:9SnKdGhiPZHF3ttwFMiCBEb8jQ4IDdrK+5+a0oTygA4= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -50,12 +67,22 @@ github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= github.com/go-openapi/loads v0.19.5 h1:jZVYWawIQiA1NBnHla28ktg6hrcfTHsCE+3QLVRBIls= github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= +github.com/go-openapi/loads v0.19.6 h1:6IAtnx22MNSjPocZZ2sV7EjgF6wW5rDC9r6ZkNxjiN8= +github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.19.7 h1:6cALLpCAq4tYhaic7TMbEzjv8vq/wg+0AFivNy/Bma8= +github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.20.0 h1:Pymw1O8zDmWeNv4kVsHd0W3cvgdp8juRa4U/U/8D/Pk= +github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/runtime v0.19.4 h1:csnOgcgAiuGoM/Po7PEpKDoNulCcF3FGbSnbHfxgjMI= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/runtime v0.19.15 h1:2GIefxs9Rx1vCDNghRtypRq+ig8KSLrjHbAYI/gCLCM= github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/runtime v0.19.16 h1:tQMAY5s5BfmmCC31+ufDCsGrr8iO1A8UIdYfDo5ADvs= +github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= +github.com/go-openapi/runtime v0.19.24 h1:TqagMVlRAOTwllE/7hNKx6rQ10O6T8ZzeJdMjSTKaD4= +github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= @@ -64,6 +91,10 @@ github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8 github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/spec v0.19.8 h1:qAdZLh1r6QF/hI/gTq+TJTvsQUodZsM7KLqkAJdiJNg= github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.15 h1:uxh8miNJEfMm8l8ekpY7i39LcORm1xSRtoipEGl1JPk= +github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.0 h1:HGLc8AJ7ynOxwv0Lq4TsnwLsWMawHAYiJIFzbcML86I= +github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= @@ -73,6 +104,8 @@ github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6 github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/strfmt v0.19.5 h1:0utjKrw+BAh8s57XE9Xz8DUBsVvPmRUB6styvl9wWIM= github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.11 h1:0+YvbNh05rmBkgztd6zHp4OCFn7Mtu30bn46NQo2ZRw= +github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= @@ -81,9 +114,15 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4azE= github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI= +github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= +github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= +github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= +github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= @@ -114,11 +153,17 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -139,24 +184,33 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks= +github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -173,6 +227,7 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -180,6 +235,10 @@ go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE= go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.4.3 h1:moga+uhicpVshTyaqY9L23E6QqwcHRUv1sqyOsoyOO8= +go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.4 h1:bsPHfODES+/yx2PCWzUYMH8xj6PVniPI8DQrsJuSXSs= +go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -187,6 +246,7 @@ golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaE golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -194,12 +254,18 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -210,17 +276,24 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -234,6 +307,10 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/go-openapi/validate/helpers.go b/vendor/github.com/go-openapi/validate/helpers.go index 4b77a0004741c..5d901dda71775 100644 --- a/vendor/github.com/go-openapi/validate/helpers.go +++ b/vendor/github.com/go-openapi/validate/helpers.go @@ -47,7 +47,7 @@ const ( jsonProperties = "properties" jsonItems = "items" jsonType = "type" - //jsonSchema = "schema" + // jsonSchema = "schema" jsonDefault = "default" ) @@ -56,7 +56,7 @@ const ( stringFormatDateTime = "date-time" stringFormatPassword = "password" stringFormatByte = "byte" - //stringFormatBinary = "binary" + // stringFormatBinary = "binary" stringFormatCreditCard = "creditcard" stringFormatDuration = "duration" stringFormatEmail = "email" @@ -165,7 +165,7 @@ func (h *valueHelper) asInt64(val interface{}) int64 { case reflect.Float32, reflect.Float64: return int64(v.Float()) default: - //panic("Non numeric value in asInt64()") + // panic("Non numeric value in asInt64()") return 0 } } @@ -182,7 +182,7 @@ func (h *valueHelper) asUint64(val interface{}) uint64 { case reflect.Float32, reflect.Float64: return uint64(v.Float()) default: - //panic("Non numeric value in asUint64()") + // panic("Non numeric value in asUint64()") return 0 } } @@ -200,7 +200,7 @@ func (h *valueHelper) asFloat64(val interface{}) float64 { case reflect.Float32, reflect.Float64: return v.Float() default: - //panic("Non numeric value in asFloat64()") + // panic("Non numeric value in asFloat64()") return 0 } } @@ -215,7 +215,7 @@ func (h *paramHelper) safeExpandedParamsFor(path, method, operationID string, re // expand parameters first if necessary resolvedParams := []spec.Parameter{} for _, ppr := range operation.Parameters { - resolvedParam, red := h.resolveParam(path, method, operationID, &ppr, s) + resolvedParam, red := h.resolveParam(path, method, operationID, &ppr, s) //#nosec res.Merge(red) if resolvedParam != nil { resolvedParams = append(resolvedParams, *resolvedParam) diff --git a/vendor/github.com/go-openapi/validate/object_validator.go b/vendor/github.com/go-openapi/validate/object_validator.go index b413ab1fa3f1c..7bb12615d8e2c 100644 --- a/vendor/github.com/go-openapi/validate/object_validator.go +++ b/vendor/github.com/go-openapi/validate/object_validator.go @@ -271,9 +271,9 @@ func (o *objectValidator) validatePatternProperty(key string, value interface{}, // BUG(fredbi): can't get to here. Should remove dead code (commented out). - //if succeededOnce { + // if succeededOnce { // result.Inc() - //} + // } return matched, succeededOnce, patterns } diff --git a/vendor/github.com/go-openapi/validate/rexp.go b/vendor/github.com/go-openapi/validate/rexp.go index 5a0824395c791..76de03e1f4168 100644 --- a/vendor/github.com/go-openapi/validate/rexp.go +++ b/vendor/github.com/go-openapi/validate/rexp.go @@ -23,7 +23,7 @@ import ( // Cache for compiled regular expressions var ( cacheMutex = &sync.Mutex{} - reDict = atomic.Value{} //map[string]*re.Regexp + reDict = atomic.Value{} // map[string]*re.Regexp ) func compileRegexp(pattern string) (*re.Regexp, error) { diff --git a/vendor/github.com/go-openapi/validate/schema.go b/vendor/github.com/go-openapi/validate/schema.go index 55454b85227d0..b817eb0ef3051 100644 --- a/vendor/github.com/go-openapi/validate/schema.go +++ b/vendor/github.com/go-openapi/validate/schema.go @@ -28,7 +28,7 @@ var ( specSchemaType = reflect.TypeOf(&spec.Schema{}) specParameterType = reflect.TypeOf(&spec.Parameter{}) specHeaderType = reflect.TypeOf(&spec.Header{}) - //specItemsType = reflect.TypeOf(&spec.Items{}) + // specItemsType = reflect.TypeOf(&spec.Items{}) ) // SchemaValidator validates data against a JSON schema diff --git a/vendor/github.com/go-openapi/validate/schema_props.go b/vendor/github.com/go-openapi/validate/schema_props.go index 5643c783cdd1f..1f6950788e682 100644 --- a/vendor/github.com/go-openapi/validate/schema_props.go +++ b/vendor/github.com/go-openapi/validate/schema_props.go @@ -187,7 +187,7 @@ func (s *schemaPropsValidator) Validate(data interface{}) *Result { result := allOfSchema.Validate(data) // We keep inner IMPORTANT! errors no matter what MatchCount tells us keepResultAllOf.Merge(result.keepRelevantErrors()) - //keepResultAllOf.Merge(result) + // keepResultAllOf.Merge(result) if result.IsValid() { validated++ } diff --git a/vendor/github.com/go-openapi/validate/spec.go b/vendor/github.com/go-openapi/validate/spec.go index f30dd79e3832b..cdf5627a2c81a 100644 --- a/vendor/github.com/go-openapi/validate/spec.go +++ b/vendor/github.com/go-openapi/validate/spec.go @@ -141,7 +141,7 @@ func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) { errs.Merge(s.validateNonEmptyPathParamNames()) - //errs.Merge(s.validateRefNoSibling()) // warning only + // errs.Merge(s.validateRefNoSibling()) // warning only errs.Merge(s.validateReferenced()) // warning only return errs, warnings @@ -543,7 +543,7 @@ DEFINITIONS: for d, schema := range s.spec.Spec().Definitions { if schema.Required != nil { // Safeguard for _, pn := range schema.Required { - red := s.validateRequiredProperties(pn, d, &schema) + red := s.validateRequiredProperties(pn, d, &schema) //#nosec res.Merge(red) if !red.IsValid() && !s.Options.ContinueOnErrors { break DEFINITIONS // there is an error, let's stop that bleeding @@ -647,7 +647,7 @@ func (s *SpecValidator) validateParameters() *Result { if _, found := methodPaths[method]; !found { methodPaths[method] = map[string]string{} } - methodPaths[method][pathToAdd] = path //Original non stripped path + methodPaths[method][pathToAdd] = path // Original non stripped path } @@ -773,7 +773,7 @@ func (s *SpecValidator) checkUniqueParams(path, method string, op *spec.Operatio if op.Parameters != nil { // Safeguard for _, ppr := range op.Parameters { var ok bool - pr, red := paramHelp.resolveParam(path, method, op.ID, &ppr, s) + pr, red := paramHelp.resolveParam(path, method, op.ID, &ppr, s) //#nosec res.Merge(red) if pr != nil && pr.Name != "" { // params with empty name does no participate the check diff --git a/vendor/github.com/go-openapi/validate/spec_messages.go b/vendor/github.com/go-openapi/validate/spec_messages.go index 1a5892aee4dc6..b3757adddbd33 100644 --- a/vendor/github.com/go-openapi/validate/spec_messages.go +++ b/vendor/github.com/go-openapi/validate/spec_messages.go @@ -349,9 +349,9 @@ func parameterValidationTypeMismatchMsg(param, path, typ string) errors.Error { } // disabled -//func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error { +// func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error { // return errors.New(errors.CompositeErrorCode, InvalidResponseDefinitionAsSchemaError, path, method) -//} +// } func someParametersBrokenMsg(path, method, operationID string) errors.Error { return errors.New(errors.CompositeErrorCode, SomeParametersBrokenError, path, method, operationID) } diff --git a/vendor/github.com/go-openapi/validate/type.go b/vendor/github.com/go-openapi/validate/type.go index f55140d1e5b4b..dc77bff93b76b 100644 --- a/vendor/github.com/go-openapi/validate/type.go +++ b/vendor/github.com/go-openapi/validate/type.go @@ -137,7 +137,7 @@ func (t *typeValidator) Applies(source interface{}, kind reflect.Kind) bool { func (t *typeValidator) Validate(data interface{}) *Result { result := new(Result) result.Inc() - if data == nil || reflect.DeepEqual(reflect.Zero(reflect.TypeOf(data)), reflect.ValueOf(data)) { + if data == nil { // nil or zero value for the passed structure require Type: null if len(t.Type) > 0 && !t.Type.Contains(nullType) && !t.Nullable { // TODO: if a property is not required it also passes this return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), nullType)) diff --git a/vendor/github.com/go-openapi/validate/validator.go b/vendor/github.com/go-openapi/validate/validator.go index 2acb839db8ece..38cdb9bb6cc29 100644 --- a/vendor/github.com/go-openapi/validate/validator.go +++ b/vendor/github.com/go-openapi/validate/validator.go @@ -532,7 +532,6 @@ func (n *numberValidator) Validate(val interface{}) *Result { // Is the provided value within the range of the specified numeric type and format? res.AddErrors(IsValueValidAgainstRange(val, n.Type, n.Format, "Checked", n.Path)) - // nolint: dupl if n.MultipleOf != nil { // Is the constraint specifier within the range of the specific numeric type and format? resMultiple.AddErrors(IsValueValidAgainstRange(*n.MultipleOf, n.Type, n.Format, "MultipleOf", n.Path)) diff --git a/vendor/github.com/go-openapi/validate/values.go b/vendor/github.com/go-openapi/validate/values.go index 8dfe557e1a8be..321de67373156 100644 --- a/vendor/github.com/go-openapi/validate/values.go +++ b/vendor/github.com/go-openapi/validate/values.go @@ -15,6 +15,7 @@ package validate import ( + "context" "fmt" "reflect" "strings" @@ -135,6 +136,27 @@ func MaxLength(path, in, data string, maxLength int64) *errors.Validation { return nil } +// ReadOnly validates an interface for readonly +func ReadOnly(ctx context.Context, path, in string, data interface{}) *errors.Validation { + + // read only is only validated when operationType is request + if op := extractOperationType(ctx); op != request { + return nil + } + + // data must be of zero value of its type + val := reflect.ValueOf(data) + if val.IsValid() { + if reflect.DeepEqual(reflect.Zero(val.Type()).Interface(), val.Interface()) { + return nil + } + } else { + return nil + } + + return errors.ReadOnly(path, in, data) +} + // Required validates an interface for requiredness func Required(path, in string, data interface{}) *errors.Validation { val := reflect.ValueOf(data) diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go index 745d5ca4c9aad..b06d952468fd3 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go @@ -43,7 +43,7 @@ func (c *DiffCommand) Execute(_ []string) error { output io.WriteCloser err error ) - if c.Destination != "" { + if c.Destination != "stdout" { output, err = os.OpenFile(c.Destination, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) if err != nil { return fmt.Errorf("%s: %w", c.Destination, err) diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/checks.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/checks.go new file mode 100644 index 0000000000000..2ae1b8227e6a7 --- /dev/null +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/checks.go @@ -0,0 +1,266 @@ +package diff + +import ( + "fmt" + "strings" + + "github.com/go-openapi/spec" +) + +// CompareEnums returns added, deleted enum values +func CompareEnums(left, right []interface{}) []TypeDiff { + diffs := []TypeDiff{} + + leftStrs := []string{} + rightStrs := []string{} + for _, eachLeft := range left { + leftStrs = append(leftStrs, fmt.Sprintf("%v", eachLeft)) + } + for _, eachRight := range right { + rightStrs = append(rightStrs, fmt.Sprintf("%v", eachRight)) + } + added, deleted, _ := fromStringArray(leftStrs).DiffsTo(rightStrs) + if len(added) > 0 { + typeChange := strings.Join(added, ",") + diffs = append(diffs, TypeDiff{Change: AddedEnumValue, Description: typeChange}) + } + if len(deleted) > 0 { + typeChange := strings.Join(deleted, ",") + diffs = append(diffs, TypeDiff{Change: DeletedEnumValue, Description: typeChange}) + } + + return diffs +} + +// CompareProperties recursive property comparison +func CompareProperties(location DifferenceLocation, schema1 *spec.Schema, schema2 *spec.Schema, getRefFn1 SchemaFromRefFn, getRefFn2 SchemaFromRefFn, cmp CompareSchemaFn) []SpecDifference { + propDiffs := []SpecDifference{} + + if schema1.Properties == nil && schema2.Properties == nil { + return propDiffs + } + + schema1Props := propertiesFor(schema1, getRefFn1) + schema2Props := propertiesFor(schema2, getRefFn2) + // find deleted and changed properties + + for eachProp1Name, eachProp1 := range schema1Props { + eachProp1 := eachProp1 + childLoc := addChildDiffNode(location, eachProp1Name, eachProp1.Schema) + + if eachProp2, ok := schema2Props[eachProp1Name]; ok { + diffs := CheckToFromRequired(eachProp1.Required, eachProp2.Required) + if len(diffs) > 0 { + for _, diff := range diffs { + propDiffs = append(propDiffs, SpecDifference{DifferenceLocation: childLoc, Code: diff.Change}) + } + } + cmp(childLoc, eachProp1.Schema, eachProp2.Schema) + } else { + propDiffs = append(propDiffs, SpecDifference{DifferenceLocation: childLoc, Code: DeletedProperty}) + } + } + + // find added properties + for eachProp2Name, eachProp2 := range schema2.Properties { + eachProp2 := eachProp2 + if _, ok := schema1.Properties[eachProp2Name]; !ok { + childLoc := addChildDiffNode(location, eachProp2Name, &eachProp2) + propDiffs = append(propDiffs, SpecDifference{DifferenceLocation: childLoc, Code: AddedProperty}) + } + } + return propDiffs + +} + +// CompareFloatValues compares a float data item +func CompareFloatValues(fieldName string, val1 *float64, val2 *float64, ifGreaterCode SpecChangeCode, ifLessCode SpecChangeCode) []TypeDiff { + diffs := []TypeDiff{} + if val1 != nil && val2 != nil { + if *val2 > *val1 { + diffs = append(diffs, TypeDiff{Change: ifGreaterCode, Description: fmt.Sprintf("%s %f->%f", fieldName, *val1, *val2)}) + } else if *val2 < *val1 { + diffs = append(diffs, TypeDiff{Change: ifLessCode, Description: fmt.Sprintf("%s %f->%f", fieldName, *val1, *val2)}) + } + } else { + if val1 != val2 { + if val1 != nil { + diffs = append(diffs, TypeDiff{Change: DeletedConstraint, Description: fmt.Sprintf("%s(%f)", fieldName, *val1)}) + } else { + diffs = append(diffs, TypeDiff{Change: AddedConstraint, Description: fmt.Sprintf("%s(%f)", fieldName, *val2)}) + } + } + } + return diffs +} + +// CompareIntValues compares to int data items +func CompareIntValues(fieldName string, val1 *int64, val2 *int64, ifGreaterCode SpecChangeCode, ifLessCode SpecChangeCode) []TypeDiff { + diffs := []TypeDiff{} + if val1 != nil && val2 != nil { + if *val2 > *val1 { + diffs = append(diffs, TypeDiff{Change: ifGreaterCode, Description: fmt.Sprintf("%s %d->%d", fieldName, *val1, *val2)}) + } else if *val2 < *val1 { + diffs = append(diffs, TypeDiff{Change: ifLessCode, Description: fmt.Sprintf("%s %d->%d", fieldName, *val1, *val2)}) + } + } else { + if val1 != val2 { + if val1 != nil { + diffs = append(diffs, TypeDiff{Change: DeletedConstraint, Description: fmt.Sprintf("%s(%d)", fieldName, *val1)}) + } else { + diffs = append(diffs, TypeDiff{Change: AddedConstraint, Description: fmt.Sprintf("%s(%d)", fieldName, *val2)}) + } + } + } + return diffs +} + +// CheckToFromPrimitiveType check for diff to or from a primitive +func CheckToFromPrimitiveType(diffs []TypeDiff, type1, type2 interface{}) []TypeDiff { + + type1IsPrimitive := isPrimitive(type1) + type2IsPrimitive := isPrimitive(type2) + + // Primitive to Obj or Obj to Primitive + if type1IsPrimitive != type2IsPrimitive { + typeStr1, isarray1 := getSchemaType(type1) + typeStr2, isarray2 := getSchemaType(type2) + return addTypeDiff(diffs, TypeDiff{Change: ChangedType, FromType: formatTypeString(typeStr1, isarray1), ToType: formatTypeString(typeStr2, isarray2)}) + } + + return diffs +} + +// CheckRefChange has the property ref changed +func CheckRefChange(diffs []TypeDiff, type1, type2 interface{}) (diffReturn []TypeDiff) { + + diffReturn = diffs + if isRefType(type1) && isRefType(type2) { + // both refs but to different objects (TODO detect renamed object) + ref1 := definitionFromRef(getRef(type1)) + ref2 := definitionFromRef(getRef(type2)) + if ref1 != ref2 { + diffReturn = addTypeDiff(diffReturn, TypeDiff{Change: RefTargetChanged, FromType: getSchemaTypeStr(type1), ToType: getSchemaTypeStr(type2)}) + } + } else if isRefType(type1) != isRefType(type2) { + diffReturn = addTypeDiff(diffReturn, TypeDiff{Change: ChangedType, FromType: getSchemaTypeStr(type1), ToType: getSchemaTypeStr(type2)}) + } + return +} + +// checkNumericTypeChanges checks for changes to or from a numeric type +func checkNumericTypeChanges(diffs []TypeDiff, type1, type2 *spec.SchemaProps) []TypeDiff { + // Number + _, type1IsNumeric := numberWideness[type1.Type[0]] + _, type2IsNumeric := numberWideness[type2.Type[0]] + + if type1IsNumeric && type2IsNumeric { + foundDiff := false + if type1.ExclusiveMaximum && !type2.ExclusiveMaximum { + diffs = addTypeDiff(diffs, TypeDiff{Change: WidenedType, Description: fmt.Sprintf("Exclusive Maximum Removed:%v->%v", type1.ExclusiveMaximum, type2.ExclusiveMaximum)}) + foundDiff = true + } + if !type1.ExclusiveMaximum && type2.ExclusiveMaximum { + diffs = addTypeDiff(diffs, TypeDiff{Change: NarrowedType, Description: fmt.Sprintf("Exclusive Maximum Added:%v->%v", type1.ExclusiveMaximum, type2.ExclusiveMaximum)}) + foundDiff = true + } + if type1.ExclusiveMinimum && !type2.ExclusiveMinimum { + diffs = addTypeDiff(diffs, TypeDiff{Change: WidenedType, Description: fmt.Sprintf("Exclusive Minimum Removed:%v->%v", type1.ExclusiveMaximum, type2.ExclusiveMaximum)}) + foundDiff = true + } + if !type1.ExclusiveMinimum && type2.ExclusiveMinimum { + diffs = addTypeDiff(diffs, TypeDiff{Change: NarrowedType, Description: fmt.Sprintf("Exclusive Minimum Added:%v->%v", type1.ExclusiveMinimum, type2.ExclusiveMinimum)}) + foundDiff = true + } + if !foundDiff { + maxDiffs := CompareFloatValues("Maximum", type1.Maximum, type2.Maximum, WidenedType, NarrowedType) + diffs = append(diffs, maxDiffs...) + minDiffs := CompareFloatValues("Minimum", type1.Minimum, type2.Minimum, NarrowedType, WidenedType) + diffs = append(diffs, minDiffs...) + } + } + return diffs +} + +// CheckStringTypeChanges checks for changes to or from a string type +func CheckStringTypeChanges(diffs []TypeDiff, type1, type2 *spec.SchemaProps) []TypeDiff { + // string changes + if type1.Type[0] == StringType && + type2.Type[0] == StringType { + minLengthDiffs := CompareIntValues("MinLength", type1.MinLength, type2.MinLength, NarrowedType, WidenedType) + diffs = append(diffs, minLengthDiffs...) + maxLengthDiffs := CompareIntValues("MaxLength", type1.MinLength, type2.MinLength, WidenedType, NarrowedType) + diffs = append(diffs, maxLengthDiffs...) + if type1.Pattern != type2.Pattern { + diffs = addTypeDiff(diffs, TypeDiff{Change: ChangedType, Description: fmt.Sprintf("Pattern Changed:%s->%s", type1.Pattern, type2.Pattern)}) + } + if type1.Type[0] == StringType { + if len(type1.Enum) > 0 { + enumDiffs := CompareEnums(type1.Enum, type2.Enum) + diffs = append(diffs, enumDiffs...) + } + } + } + return diffs +} + +// CheckToFromRequired checks for changes to or from a required property +func CheckToFromRequired(required1, required2 bool) (diffs []TypeDiff) { + if required1 != required2 { + code := ChangedOptionalToRequired + if required1 { + code = ChangedRequiredToOptional + } + diffs = addTypeDiff(diffs, TypeDiff{Change: code}) + } + return diffs +} + +const objType = "object" + +func getTypeHierarchyChange(type1, type2 string) TypeDiff { + fromType := type1 + if fromType == "" { + fromType = objType + } + toType := type2 + if toType == "" { + toType = objType + } + diffDescription := fmt.Sprintf("%s -> %s", fromType, toType) + if isStringType(type1) && !isStringType(type2) { + return TypeDiff{Change: NarrowedType, Description: diffDescription} + } + if !isStringType(type1) && isStringType(type2) { + return TypeDiff{Change: WidenedType, Description: diffDescription} + } + type1Wideness, type1IsNumeric := numberWideness[type1] + type2Wideness, type2IsNumeric := numberWideness[type2] + if type1IsNumeric && type2IsNumeric { + if type1Wideness == type2Wideness { + return TypeDiff{Change: ChangedToCompatibleType, Description: diffDescription} + } + if type1Wideness > type2Wideness { + return TypeDiff{Change: NarrowedType, Description: diffDescription} + } + if type1Wideness < type2Wideness { + return TypeDiff{Change: WidenedType, Description: diffDescription} + } + } + return TypeDiff{Change: ChangedType, Description: diffDescription} +} + +func isRefType(item interface{}) bool { + switch s := item.(type) { + case spec.Refable: + return s.Ref.String() != "" + case *spec.Schema: + return s.Ref.String() != "" + case *spec.SchemaProps: + return s.Ref.String() != "" + case *spec.SimpleSchema: + return false + default: + return false + } +} diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/compatibility.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/compatibility.go index 94694154e0c66..5a548300f7002 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/compatibility.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/compatibility.go @@ -32,29 +32,33 @@ func init() { ChangedTag: NonBreaking, AddedTag: NonBreaking, DeletedTag: NonBreaking, + DeletedConstraint: Breaking, + AddedConstraint: NonBreaking, }, ForRequest: map[SpecChangeCode]Compatibility{ - AddedRequiredProperty: Breaking, - DeletedProperty: Breaking, - AddedProperty: Breaking, - AddedOptionalParam: NonBreaking, - AddedRequiredParam: Breaking, - DeletedOptionalParam: NonBreaking, - DeletedRequiredParam: NonBreaking, - WidenedType: NonBreaking, - NarrowedType: Breaking, - ChangedType: Breaking, - ChangedToCompatibleType: NonBreaking, - ChangedOptionalToRequiredParam: Breaking, - ChangedRequiredToOptionalParam: NonBreaking, - AddedEnumValue: NonBreaking, - DeletedEnumValue: Breaking, - ChangedDescripton: NonBreaking, - AddedDescripton: NonBreaking, - DeletedDescripton: NonBreaking, - ChangedTag: NonBreaking, - AddedTag: NonBreaking, - DeletedTag: NonBreaking, + AddedRequiredProperty: Breaking, + DeletedProperty: Breaking, + AddedProperty: Breaking, + AddedOptionalParam: NonBreaking, + AddedRequiredParam: Breaking, + DeletedOptionalParam: NonBreaking, + DeletedRequiredParam: NonBreaking, + WidenedType: NonBreaking, + NarrowedType: Breaking, + ChangedType: Breaking, + ChangedToCompatibleType: NonBreaking, + ChangedOptionalToRequired: Breaking, + ChangedRequiredToOptional: NonBreaking, + AddedEnumValue: NonBreaking, + DeletedEnumValue: Breaking, + ChangedDescripton: NonBreaking, + AddedDescripton: NonBreaking, + DeletedDescripton: NonBreaking, + ChangedTag: NonBreaking, + AddedTag: NonBreaking, + DeletedTag: NonBreaking, + DeletedConstraint: NonBreaking, + AddedConstraint: Breaking, }, ForChange: map[SpecChangeCode]Compatibility{ NoChangeDetected: NonBreaking, @@ -63,8 +67,8 @@ func init() { DeletedDeprecatedEndpoint: NonBreaking, AddedConsumesFormat: NonBreaking, DeletedConsumesFormat: Breaking, - AddedProducesFormat: Breaking, - DeletedProducesFormat: NonBreaking, + AddedProducesFormat: NonBreaking, + DeletedProducesFormat: Breaking, AddedSchemes: NonBreaking, DeletedSchemes: Breaking, ChangedHostURL: Breaking, @@ -75,6 +79,10 @@ func init() { ChangedTag: NonBreaking, AddedTag: NonBreaking, DeletedTag: NonBreaking, + RefTargetChanged: Breaking, + RefTargetRenamed: NonBreaking, + AddedDefinition: NonBreaking, + DeletedDefinition: NonBreaking, }, } } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/difftypes.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/difftypes.go index 32225075fa00a..64d75dee5c7b6 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/difftypes.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/difftypes.go @@ -43,8 +43,6 @@ const ( AddedRequiredParam // DeletedRequiredParam - A required parameter has been deleted in the new spec DeletedRequiredParam - // ChangedRequiredToOptional - A required parameter has been made optional in the new spec - ChangedRequiredToOptional // AddedEndpoint - An endpoint has been added in the new spec AddedEndpoint // WidenedType - An type has been changed to a more permissive type eg int->string @@ -61,10 +59,10 @@ const ( DeletedEnumValue // AddedOptionalParam - A new optional parameter has been added to the new spec AddedOptionalParam - // ChangedOptionalToRequiredParam - An optional parameter is now required in the new spec - ChangedOptionalToRequiredParam - // ChangedRequiredToOptionalParam - An required parameter is now optional in the new spec - ChangedRequiredToOptionalParam + // ChangedOptionalToRequired - An optional parameter is now required in the new spec + ChangedOptionalToRequired + // ChangedRequiredToOptional - An required parameter is now optional in the new spec + ChangedRequiredToOptional // AddedResponse An endpoint has new response code in the new spec AddedResponse // AddedConsumesFormat - a new consumes format (json/xml/yaml etc) has been added in the new spec @@ -89,88 +87,112 @@ const ( ChangedResponseHeader // DeletedResponseHeader Added a header Item DeletedResponseHeader + // RefTargetChanged Changed a ref to point to a different object + RefTargetChanged + // RefTargetRenamed Renamed a ref to point to the same object + RefTargetRenamed + // DeletedConstraint Deleted a schema constraint + DeletedConstraint + // AddedConstraint Added a schema constraint + AddedConstraint + // DeletedDefinition removed one of the definitions + DeletedDefinition + // AddedDefinition removed one of the definitions + AddedDefinition ) var toLongStringSpecChangeCode = map[SpecChangeCode]string{ - NoChangeDetected: "No Change detected", - AddedEndpoint: "Added endpoint", - DeletedEndpoint: "Deleted endpoint", - DeletedDeprecatedEndpoint: "Deleted a deprecated endpoint", - AddedRequiredProperty: "Added required property", - DeletedProperty: "Deleted property", - ChangedDescripton: "Changed a description", - AddedDescripton: "Added a description", - DeletedDescripton: "Deleted a description", - ChangedTag: "Changed a tag", - AddedTag: "Added a tag", - DeletedTag: "Deleted a tag", - AddedProperty: "Added property", - AddedOptionalParam: "Added optional param", - AddedRequiredParam: "Added required param", - DeletedOptionalParam: "Deleted optional param", - DeletedRequiredParam: "Deleted required param", - DeletedResponse: "Deleted response", - AddedResponse: "Added response", - WidenedType: "Widened type", - NarrowedType: "Narrowed type", - ChangedType: "Changed type", - ChangedToCompatibleType: "Changed type to equivalent type", - ChangedOptionalToRequiredParam: "Changed optional param to required", - ChangedRequiredToOptionalParam: "Changed required param to optional", - AddedEnumValue: "Added possible enumeration(s)", - DeletedEnumValue: "Deleted possible enumeration(s)", - AddedConsumesFormat: "Added a consumes format", - DeletedConsumesFormat: "Deleted a consumes format", - AddedProducesFormat: "Added produces format", - DeletedProducesFormat: "Deleted produces format", - AddedSchemes: "Added schemes", - DeletedSchemes: "Deleted schemes", - ChangedHostURL: "Changed host URL", - ChangedBasePath: "Changed base path", - AddedResponseHeader: "Added response header", - ChangedResponseHeader: "Changed response header", - DeletedResponseHeader: "Deleted response header", + NoChangeDetected: "No Change detected", + AddedEndpoint: "Added endpoint", + DeletedEndpoint: "Deleted endpoint", + DeletedDeprecatedEndpoint: "Deleted a deprecated endpoint", + AddedRequiredProperty: "Added required property", + DeletedProperty: "Deleted property", + ChangedDescripton: "Changed a description", + AddedDescripton: "Added a description", + DeletedDescripton: "Deleted a description", + ChangedTag: "Changed a tag", + AddedTag: "Added a tag", + DeletedTag: "Deleted a tag", + AddedProperty: "Added property", + AddedOptionalParam: "Added optional param", + AddedRequiredParam: "Added required param", + DeletedOptionalParam: "Deleted optional param", + DeletedRequiredParam: "Deleted required param", + DeletedResponse: "Deleted response", + AddedResponse: "Added response", + WidenedType: "Widened type", + NarrowedType: "Narrowed type", + ChangedType: "Changed type", + ChangedToCompatibleType: "Changed type to equivalent type", + ChangedOptionalToRequired: "Changed optional param to required", + ChangedRequiredToOptional: "Changed required param to optional", + AddedEnumValue: "Added possible enumeration(s)", + DeletedEnumValue: "Deleted possible enumeration(s)", + AddedConsumesFormat: "Added a consumes format", + DeletedConsumesFormat: "Deleted a consumes format", + AddedProducesFormat: "Added produces format", + DeletedProducesFormat: "Deleted produces format", + AddedSchemes: "Added schemes", + DeletedSchemes: "Deleted schemes", + ChangedHostURL: "Changed host URL", + ChangedBasePath: "Changed base path", + AddedResponseHeader: "Added response header", + ChangedResponseHeader: "Changed response header", + DeletedResponseHeader: "Deleted response header", + RefTargetChanged: "Changed ref to different object", + RefTargetRenamed: "Changed ref to renamed object", + DeletedConstraint: "Deleted a schema constraint", + AddedConstraint: "Added a schema constraint", + DeletedDefinition: "Deleted a schema definition", + AddedDefinition: "Added a schema definition", } var toStringSpecChangeCode = map[SpecChangeCode]string{ - AddedEndpoint: "AddedEndpoint", - NoChangeDetected: "NoChangeDetected", - DeletedEndpoint: "DeletedEndpoint", - DeletedDeprecatedEndpoint: "DeletedDeprecatedEndpoint", - AddedRequiredProperty: "AddedRequiredProperty", - DeletedProperty: "DeletedProperty", - AddedProperty: "AddedProperty", - ChangedDescripton: "ChangedDescription", - AddedDescripton: "AddedDescription", - DeletedDescripton: "DeletedDescription", - ChangedTag: "ChangedTag", - AddedTag: "AddedTag", - DeletedTag: "DeletedTag", - AddedOptionalParam: "AddedOptionalParam", - AddedRequiredParam: "AddedRequiredParam", - DeletedOptionalParam: "DeletedRequiredParam", - DeletedRequiredParam: "Deleted required param", - DeletedResponse: "DeletedResponse", - AddedResponse: "AddedResponse", - WidenedType: "WidenedType", - NarrowedType: "NarrowedType", - ChangedType: "ChangedType", - ChangedToCompatibleType: "ChangedToCompatibleType", - ChangedOptionalToRequiredParam: "ChangedOptionalToRequiredParam", - ChangedRequiredToOptionalParam: "ChangedRequiredToOptionalParam", - AddedEnumValue: "AddedEnumValue", - DeletedEnumValue: "DeletedEnumValue", - AddedConsumesFormat: "AddedConsumesFormat", - DeletedConsumesFormat: "DeletedConsumesFormat", - AddedProducesFormat: "AddedProducesFormat", - DeletedProducesFormat: "DeletedProducesFormat", - AddedSchemes: "AddedSchemes", - DeletedSchemes: "DeletedSchemes", - ChangedHostURL: "ChangedHostURL", - ChangedBasePath: "ChangedBasePath", - AddedResponseHeader: "AddedResponseHeader", - ChangedResponseHeader: "ChangedResponseHeader", - DeletedResponseHeader: "DeletedResponseHeader", + AddedEndpoint: "AddedEndpoint", + NoChangeDetected: "NoChangeDetected", + DeletedEndpoint: "DeletedEndpoint", + DeletedDeprecatedEndpoint: "DeletedDeprecatedEndpoint", + AddedRequiredProperty: "AddedRequiredProperty", + DeletedProperty: "DeletedProperty", + AddedProperty: "AddedProperty", + ChangedDescripton: "ChangedDescription", + AddedDescripton: "AddedDescription", + DeletedDescripton: "DeletedDescription", + ChangedTag: "ChangedTag", + AddedTag: "AddedTag", + DeletedTag: "DeletedTag", + AddedOptionalParam: "AddedOptionalParam", + AddedRequiredParam: "AddedRequiredParam", + DeletedOptionalParam: "DeletedRequiredParam", + DeletedRequiredParam: "Deleted required param", + DeletedResponse: "DeletedResponse", + AddedResponse: "AddedResponse", + WidenedType: "WidenedType", + NarrowedType: "NarrowedType", + ChangedType: "ChangedType", + ChangedToCompatibleType: "ChangedToCompatibleType", + ChangedOptionalToRequired: "ChangedOptionalToRequiredParam", + ChangedRequiredToOptional: "ChangedRequiredToOptionalParam", + AddedEnumValue: "AddedEnumValue", + DeletedEnumValue: "DeletedEnumValue", + AddedConsumesFormat: "AddedConsumesFormat", + DeletedConsumesFormat: "DeletedConsumesFormat", + AddedProducesFormat: "AddedProducesFormat", + DeletedProducesFormat: "DeletedProducesFormat", + AddedSchemes: "AddedSchemes", + DeletedSchemes: "DeletedSchemes", + ChangedHostURL: "ChangedHostURL", + ChangedBasePath: "ChangedBasePath", + AddedResponseHeader: "AddedResponseHeader", + ChangedResponseHeader: "ChangedResponseHeader", + DeletedResponseHeader: "DeletedResponseHeader", + RefTargetChanged: "RefTargetChanged", + RefTargetRenamed: "RefTargetRenamed", + DeletedConstraint: "DeletedConstraint", + AddedConstraint: "AddedConstraint", + DeletedDefinition: "DeletedDefinition", + AddedDefinition: "AddedDefinition", } var toIDSpecChangeCode = map[string]SpecChangeCode{} @@ -273,5 +295,4 @@ func init() { for key, val := range toStringCompatibility { toIDCompatibility[val] = key } - } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go index a4a9cf794ba06..e1c7c95f1b0bf 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go @@ -1,5 +1,11 @@ package diff +import ( + "fmt" + + "github.com/go-openapi/spec" +) + // Node is the position od a diff in a spec type Node struct { Field string `json:"name,omitempty"` @@ -12,14 +18,12 @@ type Node struct { func (n *Node) String() string { name := n.Field if n.IsArray { - name = "array[" + n.TypeName + "]" + name = fmt.Sprintf("%s", name, n.TypeName) + } else if len(n.TypeName) > 0 { + name = fmt.Sprintf("%s<%s>", name, n.TypeName) } - if n.ChildNode != nil { - return name + "." + n.ChildNode.String() - } - if len(n.TypeName) > 0 { - return name + " : " + n.TypeName + return fmt.Sprintf("%s.%s", name, n.ChildNode.String()) } return name } @@ -36,12 +40,43 @@ func (n *Node) AddLeafNode(toAdd *Node) *Node { return n } -//Copy deep copy of this node and children +// Copy deep copy of this node and children func (n Node) Copy() *Node { - newNode := n - - if newNode.ChildNode != nil { - n.ChildNode = newNode.ChildNode.Copy() + newChild := n.ChildNode + if newChild != nil { + newChild = newChild.Copy() + } + newNode := Node{ + Field: n.Field, + TypeName: n.TypeName, + IsArray: n.IsArray, + ChildNode: newChild, } + return &newNode } + +func getSchemaDiffNode(name string, schema interface{}) *Node { + node := Node{ + Field: name, + } + if schema != nil { + switch s := schema.(type) { + case spec.Refable: + node.TypeName, node.IsArray = getSchemaType(s) + case *spec.Schema: + node.TypeName, node.IsArray = getSchemaType(s.SchemaProps) + case spec.SimpleSchema: + node.TypeName, node.IsArray = getSchemaType(s) + case *spec.SimpleSchema: + node.TypeName, node.IsArray = getSchemaType(s) + case *spec.SchemaProps: + node.TypeName, node.IsArray = getSchemaType(s) + case spec.SchemaProps: + node.TypeName, node.IsArray = getSchemaType(&s) + default: + node.TypeName = fmt.Sprintf("Unknown type %v", schema) + } + } + return &node +} diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/reporting.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/reporting.go index 020660f70cdfd..7f7b1f26c717f 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/reporting.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/reporting.go @@ -5,8 +5,6 @@ import ( "encoding/json" "fmt" "io" - "net/url" - "strings" "github.com/go-openapi/spec" ) @@ -14,6 +12,9 @@ import ( // ArrayType const for array var ArrayType = "array" +// ObjectType const for object +var ObjectType = "object" + // Compare returns the result of analysing breaking and non breaking changes // between to Swagger specs func Compare(spec1, spec2 *spec.Swagger) (diffs SpecDifferences, err error) { @@ -72,60 +73,6 @@ func getNameOnlyDiffNode(forLocation string) *Node { return &node } -func getSimpleSchemaDiffNode(name string, schema *spec.SimpleSchema) *Node { - node := Node{ - Field: name, - } - if schema != nil { - node.TypeName, node.IsArray = getSimpleSchemaType(schema) - } - return &node -} - -func getSchemaDiffNode(name string, schema *spec.Schema) *Node { - node := Node{ - Field: name, - } - if schema != nil { - node.TypeName, node.IsArray = getSchemaType(&schema.SchemaProps) - } - return &node -} - -func definitonFromURL(url *url.URL) string { - if url == nil { - return "" - } - fragmentParts := strings.Split(url.Fragment, "/") - numParts := len(fragmentParts) - if numParts == 0 { - return "" - } - return fragmentParts[numParts-1] -} - -func getSimpleSchemaType(schema *spec.SimpleSchema) (typeName string, isArray bool) { - typeName = schema.Type - if typeName == ArrayType { - typeName, _ = getSimpleSchemaType(&schema.Items.SimpleSchema) - return typeName, true - } - return typeName, false -} - -func getSchemaType(schema *spec.SchemaProps) (typeName string, isArray bool) { - refStr := definitonFromURL(schema.Ref.GetURL()) - if len(refStr) > 0 { - return refStr, false - } - typeName = schema.Type[0] - if typeName == ArrayType { - typeName, _ = getSchemaType(&schema.Items.Schema.SchemaProps) - return typeName, true - } - return typeName, false -} - func primitiveTypeString(typeName, typeFormat string) string { if typeFormat != "" { return fmt.Sprintf("%s.%s", typeName, typeFormat) diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/schema.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/schema.go new file mode 100644 index 0000000000000..0874154bbdaf1 --- /dev/null +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/schema.go @@ -0,0 +1,126 @@ +package diff + +import ( + "fmt" + "strings" + + "github.com/go-openapi/spec" +) + +func getTypeFromSchema(schema *spec.Schema) (typeName string, isArray bool) { + refStr := definitionFromRef(schema.Ref) + if len(refStr) > 0 { + return refStr, false + } + typeName = schema.Type[0] + if typeName == ArrayType { + typeName, _ = getSchemaType(&schema.Items.Schema.SchemaProps) + return typeName, true + } + return typeName, false + +} + +func getTypeFromSimpleSchema(schema *spec.SimpleSchema) (typeName string, isArray bool) { + typeName = schema.Type + format := schema.Format + if len(format) > 0 { + typeName = fmt.Sprintf("%s.%s", typeName, format) + } + if typeName == ArrayType { + typeName, _ = getSchemaType(&schema.Items.SimpleSchema) + return typeName, true + } + return typeName, false + +} + +func getTypeFromSchemaProps(schema *spec.SchemaProps) (typeName string, isArray bool) { + refStr := definitionFromRef(schema.Ref) + if len(refStr) > 0 { + return refStr, false + } + if len(schema.Type) > 0 { + typeName = schema.Type[0] + format := schema.Format + if len(format) > 0 { + typeName = fmt.Sprintf("%s.%s", typeName, format) + } + if typeName == ArrayType { + typeName, _ = getSchemaType(&schema.Items.Schema.SchemaProps) + return typeName, true + } + } + return typeName, false + +} + +func getSchemaTypeStr(item interface{}) string { + typeStr, isArray := getSchemaType(item) + return formatTypeString(typeStr, isArray) +} + +func getSchemaType(item interface{}) (typeName string, isArray bool) { + + switch s := item.(type) { + case *spec.Schema: + typeName, isArray = getTypeFromSchema(s) + case *spec.SchemaProps: + typeName, isArray = getTypeFromSchemaProps(s) + case spec.SchemaProps: + typeName, isArray = getTypeFromSchemaProps(&s) + case spec.SimpleSchema: + typeName, isArray = getTypeFromSimpleSchema(&s) + case *spec.SimpleSchema: + typeName, isArray = getTypeFromSimpleSchema(s) + default: + typeName = "unknown" + } + + return + +} + +func formatTypeString(typ string, isarray bool) string { + if isarray { + return fmt.Sprintf("", typ) + } + return fmt.Sprintf("<%s>", typ) +} + +func definitionFromRef(ref spec.Ref) string { + url := ref.GetURL() + if url == nil { + return "" + } + fragmentParts := strings.Split(url.Fragment, "/") + numParts := len(fragmentParts) + + return fragmentParts[numParts-1] +} + +func isArray(item interface{}) bool { + switch s := item.(type) { + case *spec.Schema: + return isArrayType(s.Type) + case *spec.SchemaProps: + return isArrayType(s.Type) + case *spec.SimpleSchema: + return isArrayType(spec.StringOrArray{s.Type}) + default: + return false + } +} + +func isPrimitive(item interface{}) bool { + switch s := item.(type) { + case *spec.Schema: + return isPrimitiveType(s.Type) + case *spec.SchemaProps: + return isPrimitiveType(s.Type) + case spec.StringOrArray: + return isPrimitiveType(s) + default: + return false + } +} diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go index eb516f3c00c61..e6408749b2860 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go @@ -7,6 +7,7 @@ import ( "github.com/go-openapi/spec" ) +// StringType For identifying string types const StringType = "string" // URLMethodResponse encapsulates these three elements to act as a map key @@ -26,18 +27,19 @@ type URLMethods map[URLMethod]*PathItemOp // SpecAnalyser contains all the differences for a Spec type SpecAnalyser struct { - Diffs SpecDifferences - urlMethods1 URLMethods - urlMethods2 URLMethods - Definitions1 spec.Definitions - Definitions2 spec.Definitions - AlreadyComparedDefinitions map[string]bool + Diffs SpecDifferences + urlMethods1 URLMethods + urlMethods2 URLMethods + Definitions1 spec.Definitions + Definitions2 spec.Definitions + ReferencedDefinitions map[string]bool } // NewSpecAnalyser returns an empty SpecDiffs func NewSpecAnalyser() *SpecAnalyser { return &SpecAnalyser{ - Diffs: SpecDifferences{}, + Diffs: SpecDifferences{}, + ReferencedDefinitions: map[string]bool{}, } } @@ -50,9 +52,10 @@ func (sd *SpecAnalyser) Analyse(spec1, spec2 *spec.Swagger) error { sd.analyseSpecMetadata(spec1, spec2) sd.analyseEndpoints() - sd.analyseParams() + sd.analyseRequestParams() sd.analyseEndpointData() sd.analyseResponseParams() + sd.AnalyseDefinitions() return nil } @@ -94,7 +97,7 @@ func (sd *SpecAnalyser) analyseSpecMetadata(spec1, spec2 *spec.Swagger) { sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: schemesLocation, Code: DeletedSchemes, Compatibility: Breaking, DiffInfo: eachDeleted}) } - // // host should be able to change without any issues? + // host should be able to change without any issues? sd.analyseMetaDataProperty(spec1.Info.Description, spec2.Info.Description, ChangedDescripton, NonBreaking) // // host should be able to change without any issues? @@ -116,6 +119,32 @@ func (sd *SpecAnalyser) analyseEndpoints() { sd.findAddedEndpoints() } +// AnalyseDefinitions check for changes to defintion objects not referenced in any endpoint +func (sd *SpecAnalyser) AnalyseDefinitions() { + alreadyReferenced := map[string]bool{} + for k := range sd.ReferencedDefinitions { + alreadyReferenced[k] = true + } + location := DifferenceLocation{Node: &Node{Field: "Spec Definitions"}} + for name1, sch := range sd.Definitions1 { + schema1 := sch + if _, ok := alreadyReferenced[name1]; !ok { + childLocation := location.AddNode(&Node{Field: name1}) + if schema2, ok := sd.Definitions2[name1]; ok { + sd.compareSchema(childLocation, &schema1, &schema2) + } else { + sd.addDiffs(childLocation, []TypeDiff{{Change: DeletedDefinition}}) + } + } + } + for name2 := range sd.Definitions2 { + if _, ok := sd.Definitions1[name2]; !ok { + childLocation := location.AddNode(&Node{Field: name2}) + sd.addDiffs(childLocation, []TypeDiff{{Change: AddedDefinition}}) + } + } +} + func (sd *SpecAnalyser) analyseEndpointData() { for URLMethod, op2 := range sd.urlMethods2 { @@ -124,20 +153,19 @@ func (sd *SpecAnalyser) analyseEndpointData() { location := DifferenceLocation{URL: URLMethod.Path, Method: URLMethod.Method} for _, eachAddedTag := range addedTags { - sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: AddedTag, DiffInfo: eachAddedTag}) + sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: AddedTag, DiffInfo: fmt.Sprintf(`"%s"`, eachAddedTag)}) } for _, eachDeletedTag := range deletedTags { - sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: DeletedTag, DiffInfo: eachDeletedTag}) + sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: DeletedTag, DiffInfo: fmt.Sprintf(`"%s"`, eachDeletedTag)}) } sd.compareDescripton(location, op1.Operation.Description, op2.Operation.Description) } } - } -func (sd *SpecAnalyser) analyseParams() { +func (sd *SpecAnalyser) analyseRequestParams() { locations := []string{"query", "path", "body", "header"} for _, paramLocation := range locations { @@ -153,7 +181,7 @@ func (sd *SpecAnalyser) analyseParams() { // detect deleted params for paramName1, param1 := range params1 { if _, ok := params2[paramName1]; !ok { - childLocation := location.AddNode(getSchemaDiffNode(paramName1, param1.Schema)) + childLocation := location.AddNode(getSchemaDiffNode(paramName1, ¶m1.SimpleSchema)) code := DeletedOptionalParam if param1.Required { code = DeletedRequiredParam @@ -163,12 +191,12 @@ func (sd *SpecAnalyser) analyseParams() { } // detect added changed params for paramName2, param2 := range params2 { - //changed? + // changed? if param1, ok := params1[paramName2]; ok { sd.compareParams(URLMethod, paramLocation, paramName2, param1, param2) } else { // Added - childLocation := location.AddNode(getSchemaDiffNode(paramName2, param2.Schema)) + childLocation := location.AddNode(getSchemaDiffNode(paramName2, ¶m2.SimpleSchema)) code := AddedOptionalParam if param2.Required { code = AddedRequiredParam @@ -183,8 +211,10 @@ func (sd *SpecAnalyser) analyseParams() { func (sd *SpecAnalyser) analyseResponseParams() { // Loop through url+methods in spec 2 - check deleted and changed - for URLMethod2, op2 := range sd.urlMethods2 { - if op1, ok := sd.urlMethods1[URLMethod2]; ok { + for eachURLMethodFrom2, op2 := range sd.urlMethods2 { + + // present in both specs? Use key from spec 2 to lookup in spec 1 + if op1, ok := sd.urlMethods1[eachURLMethodFrom2]; ok { // compare responses for url and method op1Responses := op1.Operation.Responses.StatusCodeResponses op2Responses := op2.Operation.Responses.StatusCodeResponses @@ -192,7 +222,7 @@ func (sd *SpecAnalyser) analyseResponseParams() { // deleted responses for code1 := range op1Responses { if _, ok := op2Responses[code1]; !ok { - location := DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code1} + location := DifferenceLocation{URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code1, Node: getSchemaDiffNode("Body", op1Responses[code1].Schema)} sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: DeletedResponse}) } } @@ -202,39 +232,48 @@ func (sd *SpecAnalyser) analyseResponseParams() { if op1Response, ok := op1Responses[code2]; ok { op1Headers := op1Response.ResponseProps.Headers headerRootNode := getNameOnlyDiffNode("Headers") - location := DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code2, Node: headerRootNode} // Iterate Spec2 Headers looking for added and updated + location := DifferenceLocation{URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code2, Node: headerRootNode} for op2HeaderName, op2Header := range op2Response.ResponseProps.Headers { if op1Header, ok := op1Headers[op2HeaderName]; ok { - sd.compareSimpleSchema(location.AddNode(getNameOnlyDiffNode(op2HeaderName)), - &op1Header.SimpleSchema, - &op2Header.SimpleSchema, false, false) + diffs := sd.CompareProps(forHeader(op1Header), forHeader(op2Header)) + sd.addDiffs(location, diffs) } else { sd.Diffs = sd.Diffs.addDiff(SpecDifference{ - DifferenceLocation: location.AddNode(getNameOnlyDiffNode(op2HeaderName)), + DifferenceLocation: location.AddNode(getSchemaDiffNode(op2HeaderName, &op2Header.SimpleSchema)), Code: AddedResponseHeader}) } } for op1HeaderName := range op1Response.ResponseProps.Headers { if _, ok := op2Response.ResponseProps.Headers[op1HeaderName]; !ok { + op1Header := op1Response.ResponseProps.Headers[op1HeaderName] sd.Diffs = sd.Diffs.addDiff(SpecDifference{ - DifferenceLocation: location.AddNode(getNameOnlyDiffNode(op1HeaderName)), + DifferenceLocation: location.AddNode(getSchemaDiffNode(op1HeaderName, &op1Header.SimpleSchema)), Code: DeletedResponseHeader}) } } - responseLocation := DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code2} + schem := op1Response.Schema + node := getNameOnlyDiffNode("NoContent") + if schem != nil { + node = getSchemaDiffNode("Body", &schem.SchemaProps) + } + responseLocation := DifferenceLocation{URL: eachURLMethodFrom2.Path, + Method: eachURLMethodFrom2.Method, + Response: code2, + Node: node} sd.compareDescripton(responseLocation, op1Response.Description, op2Response.Description) if op1Response.Schema != nil { sd.compareSchema( - DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code2}, + DifferenceLocation{URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code2, Node: getSchemaDiffNode("Body", op1Response.Schema)}, op1Response.Schema, - op2Response.Schema, true, true) + op2Response.Schema) } } else { + // op2Response sd.Diffs = sd.Diffs.addDiff(SpecDifference{ - DifferenceLocation: DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code2}, + DifferenceLocation: DifferenceLocation{URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code2, Node: getSchemaDiffNode("Body", op2Response.Schema)}, Code: AddedResponse}) } } @@ -249,126 +288,51 @@ func addTypeDiff(diffs []TypeDiff, diff TypeDiff) []TypeDiff { return diffs } -// CheckToFromPrimitiveType check for diff to or from a primitive -func (sd *SpecAnalyser) CheckToFromPrimitiveType(diffs []TypeDiff, type1, type2 spec.SchemaProps) []TypeDiff { - - type1IsPrimitive := len(type1.Type) > 0 - type2IsPrimitive := len(type2.Type) > 0 - - // Primitive to Obj or Obj to Primitive - if type1IsPrimitive && !type2IsPrimitive { - return addTypeDiff(diffs, TypeDiff{Change: ChangedType, FromType: type1.Type[0], ToType: "obj"}) - } +// CompareProps computes type specific property diffs +func (sd *SpecAnalyser) CompareProps(type1, type2 *spec.SchemaProps) []TypeDiff { - if !type1IsPrimitive && type2IsPrimitive { - return addTypeDiff(diffs, TypeDiff{Change: ChangedType, FromType: type2.Type[0], ToType: "obj"}) - } - - return diffs -} - -// CheckToFromArrayType check for changes to or from an Array type -func (sd *SpecAnalyser) CheckToFromArrayType(diffs []TypeDiff, type1, type2 spec.SchemaProps) []TypeDiff { - // Single to Array or Array to Single - type1Array := type1.Type[0] == ArrayType - type2Array := type2.Type[0] == ArrayType + diffs := []TypeDiff{} - if type1Array && !type2Array { - return addTypeDiff(diffs, TypeDiff{Change: ChangedType, FromType: "obj", ToType: type2.Type[0]}) - } + diffs = CheckToFromPrimitiveType(diffs, type1, type2) - if !type1Array && type2Array { - return addTypeDiff(diffs, TypeDiff{Change: ChangedType, FromType: type1.Type[0], ToType: ArrayType}) + if len(diffs) > 0 { + return diffs } - if type1Array && type2Array { - // array - // TODO: Items?? - diffs = addTypeDiff(diffs, compareIntValues("MaxItems", type1.MaxItems, type2.MaxItems, WidenedType, NarrowedType)) - diffs = addTypeDiff(diffs, compareIntValues("MinItems", type1.MinItems, type2.MinItems, NarrowedType, WidenedType)) - + if isArray(type1) { + maxItemDiffs := CompareIntValues("MaxItems", type1.MaxItems, type2.MaxItems, WidenedType, NarrowedType) + diffs = append(diffs, maxItemDiffs...) + minItemsDiff := CompareIntValues("MinItems", type1.MinItems, type2.MinItems, NarrowedType, WidenedType) + diffs = append(diffs, minItemsDiff...) } - return diffs -} -// CheckStringTypeChanges checks for changes to or from a string type -func (sd *SpecAnalyser) CheckStringTypeChanges(diffs []TypeDiff, type1, type2 spec.SchemaProps) []TypeDiff { - // string changes - if type1.Type[0] == StringType && - type2.Type[0] == StringType { - diffs = addTypeDiff(diffs, compareIntValues("MinLength", type1.MinLength, type2.MinLength, NarrowedType, WidenedType)) - diffs = addTypeDiff(diffs, compareIntValues("MaxLength", type1.MinLength, type2.MinLength, WidenedType, NarrowedType)) - if type1.Pattern != type2.Pattern { - diffs = addTypeDiff(diffs, TypeDiff{Change: ChangedType, Description: fmt.Sprintf("Pattern Changed:%s->%s", type1.Pattern, type2.Pattern)}) - } - if type1.Type[0] == StringType { - if len(type1.Enum) > 0 { - enumDiffs := sd.compareEnums(type1.Enum, type2.Enum) - diffs = append(diffs, enumDiffs...) - } - } - } - return diffs -} - -// CheckNumericTypeChanges checks for changes to or from a numeric type -func (sd *SpecAnalyser) CheckNumericTypeChanges(diffs []TypeDiff, type1, type2 spec.SchemaProps) []TypeDiff { - // Number - _, type1IsNumeric := numberWideness[type1.Type[0]] - _, type2IsNumeric := numberWideness[type2.Type[0]] - - if type1IsNumeric && type2IsNumeric { - diffs = addTypeDiff(diffs, compareFloatValues("Maximum", type1.Maximum, type2.Maximum, WidenedType, NarrowedType)) - diffs = addTypeDiff(diffs, compareFloatValues("Minimum", type1.Minimum, type2.Minimum, NarrowedType, WidenedType)) - if type1.ExclusiveMaximum && !type2.ExclusiveMaximum { - diffs = addTypeDiff(diffs, TypeDiff{Change: WidenedType, Description: fmt.Sprintf("Exclusive Maximum Removed:%v->%v", type1.ExclusiveMaximum, type2.ExclusiveMaximum)}) - } - if !type1.ExclusiveMaximum && type2.ExclusiveMaximum { - diffs = addTypeDiff(diffs, TypeDiff{Change: NarrowedType, Description: fmt.Sprintf("Exclusive Maximum Added:%v->%v", type1.ExclusiveMaximum, type2.ExclusiveMaximum)}) - } - if type1.ExclusiveMinimum && !type2.ExclusiveMinimum { - diffs = addTypeDiff(diffs, TypeDiff{Change: WidenedType, Description: fmt.Sprintf("Exclusive Minimum Removed:%v->%v", type1.ExclusiveMaximum, type2.ExclusiveMaximum)}) - } - if !type1.ExclusiveMinimum && type2.ExclusiveMinimum { - diffs = addTypeDiff(diffs, TypeDiff{Change: NarrowedType, Description: fmt.Sprintf("Exclusive Minimum Added:%v->%v", type1.ExclusiveMinimum, type2.ExclusiveMinimum)}) - } + if len(diffs) > 0 { + return diffs } - return diffs -} - -// CompareTypes computes type specific property diffs -func (sd *SpecAnalyser) CompareTypes(type1, type2 spec.SchemaProps) []TypeDiff { - - diffs := []TypeDiff{} - - diffs = sd.CheckToFromPrimitiveType(diffs, type1, type2) + diffs = CheckRefChange(diffs, type1, type2) if len(diffs) > 0 { return diffs } - diffs = sd.CheckToFromArrayType(diffs, type1, type2) - - if len(diffs) > 0 { + if !(isPrimitiveType(type1.Type) && isPrimitiveType(type2.Type)) { return diffs } - // check type hierarchy change eg string -> integer = NarrowedChange - //Type - //Format + // check primitive type hierarchy change eg string -> integer = NarrowedChange if type1.Type[0] != type2.Type[0] || type1.Format != type2.Format { diff := getTypeHierarchyChange(primitiveTypeString(type1.Type[0], type1.Format), primitiveTypeString(type2.Type[0], type2.Format)) diffs = addTypeDiff(diffs, diff) } - diffs = sd.CheckStringTypeChanges(diffs, type1, type2) + diffs = CheckStringTypeChanges(diffs, type1, type2) if len(diffs) > 0 { return diffs } - diffs = sd.CheckNumericTypeChanges(diffs, type1, type2) + diffs = checkNumericTypeChanges(diffs, type1, type2) if len(diffs) > 0 { return diffs @@ -385,49 +349,37 @@ func (sd *SpecAnalyser) compareParams(urlMethod URLMethod, location string, name sd.compareDescripton(paramLocation, param1.Description, param2.Description) if param1.Schema != nil && param2.Schema != nil { - childLocation = childLocation.AddNode(getSchemaDiffNode(name, param2.Schema)) - sd.compareSchema(childLocation, param1.Schema, param2.Schema, param1.Required, param2.Required) - } - diffs := sd.CompareTypes(forParam(param1), forParam(param2)) - - childLocation = childLocation.AddNode(getSchemaDiffNode(name, param2.Schema)) - for _, eachDiff := range diffs { - sd.Diffs = sd.Diffs.addDiff(SpecDifference{ - DifferenceLocation: childLocation, - Code: eachDiff.Change, - DiffInfo: eachDiff.Description}) - } - if param1.Required != param2.Required { - code := ChangedRequiredToOptionalParam - if param2.Required { - code = ChangedOptionalToRequiredParam + if len(name) > 0 { + childLocation = childLocation.AddNode(getSchemaDiffNode(name, param2.Schema)) } - sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: childLocation, Code: code}) - } -} -func (sd *SpecAnalyser) compareSimpleSchema(location DifferenceLocation, schema1, schema2 *spec.SimpleSchema, required1, required2 bool) { - if schema1 == nil || schema2 == nil { - return + sd.compareSchema(childLocation, param1.Schema, param2.Schema) } + diffs := sd.CompareProps(forParam(param1), forParam(param2)) - if schema1.Type == ArrayType { - refSchema1 := schema1.Items.SimpleSchema - refSchema2 := schema2.Items.SimpleSchema + childLocation = childLocation.AddNode(getSchemaDiffNode(name, ¶m2.SimpleSchema)) + if len(diffs) > 0 { + sd.addDiffs(childLocation, diffs) + } - childLocation := location.AddNode(getSimpleSchemaDiffNode("", schema1)) - sd.compareSimpleSchema(childLocation, &refSchema1, &refSchema2, required1, required2) - return + diffs = CheckToFromRequired(param1.Required, param2.Required) + if len(diffs) > 0 { + sd.addDiffs(childLocation, diffs) } - if required1 != required2 { - code := AddedRequiredProperty - if required1 { - code = ChangedRequiredToOptional +} +func (sd *SpecAnalyser) addTypeDiff(location DifferenceLocation, diff *TypeDiff) { + diffCopy := diff + desc := diffCopy.Description + if len(desc) == 0 { + if diffCopy.FromType != diffCopy.ToType { + desc = fmt.Sprintf("%s -> %s", diffCopy.FromType, diffCopy.ToType) } - sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: code}) } - + sd.Diffs = sd.Diffs.addDiff(SpecDifference{ + DifferenceLocation: location, + Code: diffCopy.Change, + DiffInfo: desc}) } func (sd *SpecAnalyser) compareDescripton(location DifferenceLocation, desc1, desc2 string) { @@ -440,145 +392,96 @@ func (sd *SpecAnalyser) compareDescripton(location DifferenceLocation, desc1, de } sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: code}) } - } -func (sd *SpecAnalyser) compareSchema(location DifferenceLocation, schema1, schema2 *spec.Schema, required1, required2 bool) { +func isPrimitiveType(item spec.StringOrArray) bool { + return len(item) > 0 && item[0] != ArrayType && item[0] != ObjectType +} - if schema1 == nil || schema2 == nil { - return - } +func isArrayType(item spec.StringOrArray) bool { + return len(item) > 0 && item[0] == ArrayType +} +func (sd *SpecAnalyser) getRefSchemaFromSpec1(ref spec.Ref) (*spec.Schema, string) { + return sd.schemaFromRef(ref, &sd.Definitions1) +} - sd.compareDescripton(location, schema1.Description, schema2.Description) +func (sd *SpecAnalyser) getRefSchemaFromSpec2(ref spec.Ref) (*spec.Schema, string) { + return sd.schemaFromRef(ref, &sd.Definitions2) +} - if len(schema1.Type) == 0 { - refSchema1, definition1 := sd.schemaFromRef(schema1, &sd.Definitions1) - refSchema2, definition2 := sd.schemaFromRef(schema2, &sd.Definitions2) +// CompareSchemaFn Fn spec for comparing schemas +type CompareSchemaFn func(location DifferenceLocation, schema1, schema2 *spec.Schema) - if len(definition1) > 0 { - info := fmt.Sprintf("[%s -> %s]", definition1, definition2) +func (sd *SpecAnalyser) compareSchema(location DifferenceLocation, schema1, schema2 *spec.Schema) { - if definition1 != definition2 { - sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, - Code: ChangedType, - DiffInfo: info, - }) - } - sd.compareSchema(location, refSchema1, refSchema2, required1, required2) - return + refDiffs := []TypeDiff{} + refDiffs = CheckRefChange(refDiffs, schema1, schema2) + if len(refDiffs) > 0 { + for _, d := range refDiffs { + diff := d + sd.addTypeDiff(location, &diff) } - } else { - if schema1.Type[0] == ArrayType { - refSchema1, definition1 := sd.schemaFromRef(schema1.Items.Schema, &sd.Definitions1) - refSchema2, _ := sd.schemaFromRef(schema2.Items.Schema, &sd.Definitions2) - - if len(definition1) > 0 { - childLocation := location.AddNode(getSchemaDiffNode("", schema1)) - sd.compareSchema(childLocation, refSchema1, refSchema2, required1, required2) - return - } - - } - diffs := sd.CompareTypes(schema1.SchemaProps, schema2.SchemaProps) + return + } - for _, eachTypeDiff := range diffs { - if eachTypeDiff.Change != NoChangeDetected { - sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: eachTypeDiff.Change, DiffInfo: eachTypeDiff.Description}) - } - } + if isRefType(schema1) { + schema1, _ = sd.schemaFromRef(getRef(schema1), &sd.Definitions1) + } + if isRefType(schema2) { + schema2, _ = sd.schemaFromRef(getRef(schema2), &sd.Definitions2) } - if required1 != required2 { - code := AddedRequiredProperty - if required1 { - code = ChangedRequiredToOptional + sd.compareDescripton(location, schema1.Description, schema2.Description) - } - sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: code}) + typeDiffs := sd.CompareProps(&schema1.SchemaProps, &schema2.SchemaProps) + if len(typeDiffs) > 0 { + sd.addDiffs(location, typeDiffs) + return } - requiredProps2 := sliceToStrMap(schema2.Required) - requiredProps1 := sliceToStrMap(schema1.Required) - schema1Props := sd.propertiesFor(schema1, &sd.Definitions1) - schema2Props := sd.propertiesFor(schema2, &sd.Definitions2) - // find deleted and changed properties - for eachProp1Name, eachProp1 := range schema1Props { - eachProp1 := eachProp1 - _, required1 := requiredProps1[eachProp1Name] - _, required2 := requiredProps2[eachProp1Name] - childLoc := sd.addChildDiffNode(location, eachProp1Name, &eachProp1) - - if eachProp2, ok := schema2Props[eachProp1Name]; ok { - sd.compareSchema(childLoc, &eachProp1, &eachProp2, required1, required2) - sd.compareDescripton(childLoc, eachProp1.Description, eachProp2.Description) - } else { - sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: childLoc, Code: DeletedProperty}) - } + + if isArray(schema1) { + sd.compareSchema(location, schema1.Items.Schema, schema2.Items.Schema) } - // find added properties - for eachProp2Name, eachProp2 := range schema2.Properties { - eachProp2 := eachProp2 - if _, ok := schema1.Properties[eachProp2Name]; !ok { - childLoc := sd.addChildDiffNode(location, eachProp2Name, &eachProp2) - _, required2 := requiredProps2[eachProp2Name] - code := AddedProperty - if required2 { - code = AddedRequiredProperty - } - sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: childLoc, Code: code}) - } + diffs := CompareProperties(location, schema1, schema2, sd.getRefSchemaFromSpec1, sd.getRefSchemaFromSpec2, sd.compareSchema) + for _, diff := range diffs { + sd.Diffs = sd.Diffs.addDiff(diff) } } -func (sd *SpecAnalyser) addChildDiffNode(location DifferenceLocation, propName string, propSchema *spec.Schema) DifferenceLocation { - newLoc := location - if newLoc.Node != nil { - newLoc.Node = newLoc.Node.Copy() +func (sd *SpecAnalyser) addDiffs(location DifferenceLocation, diffs []TypeDiff) { + for _, e := range diffs { + eachTypeDiff := e + if eachTypeDiff.Change != NoChangeDetected { + sd.addTypeDiff(location, &eachTypeDiff) + } } +} - childNode := sd.fromSchemaProps(propName, &propSchema.SchemaProps) - if newLoc.Node != nil { - newLoc.Node.AddLeafNode(&childNode) +func addChildDiffNode(location DifferenceLocation, propName string, propSchema *spec.Schema) DifferenceLocation { + newNode := location.Node + childNode := fromSchemaProps(propName, &propSchema.SchemaProps) + if newNode != nil { + newNode = newNode.Copy() + newNode.AddLeafNode(&childNode) } else { - newLoc.Node = &childNode + newNode = &childNode + } + return DifferenceLocation{ + URL: location.URL, + Method: location.Method, + Response: location.Response, + Node: newNode, } - return newLoc } -func (sd *SpecAnalyser) fromSchemaProps(fieldName string, props *spec.SchemaProps) Node { +func fromSchemaProps(fieldName string, props *spec.SchemaProps) Node { node := Node{} - node.IsArray = props.Type[0] == ArrayType - if !node.IsArray { - node.TypeName = props.Type[0] - } + node.TypeName, node.IsArray = getSchemaType(props) node.Field = fieldName return node } -func (sd *SpecAnalyser) compareEnums(left, right []interface{}) []TypeDiff { - diffs := []TypeDiff{} - - leftStrs := []string{} - rightStrs := []string{} - for _, eachLeft := range left { - leftStrs = append(leftStrs, fmt.Sprintf("%v", eachLeft)) - } - for _, eachRight := range right { - rightStrs = append(rightStrs, fmt.Sprintf("%v", eachRight)) - } - added, deleted, _ := fromStringArray(leftStrs).DiffsTo(rightStrs) - if len(added) > 0 { - typeChange := strings.Join(added, ",") - diffs = append(diffs, TypeDiff{Change: AddedEnumValue, Description: typeChange}) - } - if len(deleted) > 0 { - typeChange := strings.Join(deleted, ",") - diffs = append(diffs, TypeDiff{Change: DeletedEnumValue, Description: typeChange}) - } - - return diffs -} - func (sd *SpecAnalyser) findAddedEndpoints() { for URLMethod := range sd.urlMethods2 { if _, ok := sd.urlMethods1[URLMethod]; !ok { @@ -607,48 +510,23 @@ func (sd *SpecAnalyser) analyseMetaDataProperty(item1, item2 string, codeIfDiff } } -func (sd *SpecAnalyser) schemaFromRef(schema *spec.Schema, defns *spec.Definitions) (actualSchema *spec.Schema, definitionName string) { - ref := schema.Ref - url := ref.GetURL() - if url == nil { - return schema, "" - } - fragmentParts := strings.Split(url.Fragment, "/") - numParts := len(fragmentParts) - if numParts == 0 { - return schema, "" - } - - definitionName = fragmentParts[numParts-1] +func (sd *SpecAnalyser) schemaFromRef(ref spec.Ref, defns *spec.Definitions) (actualSchema *spec.Schema, definitionName string) { + definitionName = definitionFromRef(ref) foundSchema, ok := (*defns)[definitionName] if !ok { return nil, definitionName } + sd.ReferencedDefinitions[definitionName] = true actualSchema = &foundSchema return } -func (sd *SpecAnalyser) propertiesFor(schema *spec.Schema, defns *spec.Definitions) map[string]spec.Schema { - schemaFromRef, _ := sd.schemaFromRef(schema, defns) - schema = schemaFromRef - props := map[string]spec.Schema{} - - if schema.Properties != nil { - for name, prop := range schema.Properties { - prop := prop - eachProp, _ := sd.schemaFromRef(&prop, defns) - props[name] = *eachProp - } - } - for _, eachAllOf := range schema.AllOf { - eachAllOf := eachAllOf - eachAllOfActual, _ := sd.schemaFromRef(&eachAllOf, defns) - for name, prop := range eachAllOfActual.Properties { - prop := prop - eachProp, _ := sd.schemaFromRef(&prop, defns) - props[name] = *eachProp - } - } - return props +// PropertyDefn combines a property with its required-ness +type PropertyDefn struct { + Schema *spec.Schema + Required bool } + +// PropertyMap a unified map including all AllOf fields +type PropertyMap map[string]PropertyDefn diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go index 222ea89b0180f..122db9f4ad6a7 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "sort" + "strings" ) // SpecDifference encapsulates the details of an individual diff in part of a spec @@ -89,37 +90,37 @@ func (sd SpecDifference) String() string { prefix := "" direction := "" - if isResponse { - direction = " Response" + if hasMethod { if hasURL { - if hasMethod { - prefix = fmt.Sprintf("%s:%s -> %d", sd.DifferenceLocation.URL, sd.DifferenceLocation.Method, sd.DifferenceLocation.Response) - } else { - prefix = fmt.Sprintf("%s ", sd.DifferenceLocation.URL) - } + prefix = fmt.Sprintf("%s:%s", sd.DifferenceLocation.URL, sd.DifferenceLocation.Method) } - } else { - if hasURL { - if hasMethod { - direction = " Request" - prefix = fmt.Sprintf("%s:%s", sd.DifferenceLocation.URL, sd.DifferenceLocation.Method) - } else { - prefix = fmt.Sprintf("%s ", sd.DifferenceLocation.URL) - } + if isResponse { + prefix += fmt.Sprintf(" -> %d", sd.DifferenceLocation.Response) + direction = "Response" } else { - prefix = " Metadata" + direction = "Request" } + } else { + prefix = sd.DifferenceLocation.URL } paramOrPropertyLocation := "" if sd.DifferenceLocation.Node != nil { - paramOrPropertyLocation = " - " + sd.DifferenceLocation.Node.String() + " " + paramOrPropertyLocation = sd.DifferenceLocation.Node.String() } optionalInfo := "" if sd.DiffInfo != "" { - optionalInfo = fmt.Sprintf(" <%s>", sd.DiffInfo) + optionalInfo = sd.DiffInfo + } + + items := []string{} + for _, item := range []string{prefix, direction, paramOrPropertyLocation, sd.Code.Description(), optionalInfo} { + if item != "" { + items = append(items, item) + } } - return fmt.Sprintf("%s%s%s- %s%s", prefix, direction, paramOrPropertyLocation, sd.Code.Description(), optionalInfo) + return strings.Join(items, " - ") + // return fmt.Sprintf("%s%s%s - %s%s", prefix, direction, paramOrPropertyLocation, sd.Code.Description(), optionalInfo) } func (sd SpecDifferences) addDiff(diff SpecDifference) SpecDifferences { diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go index 5e271b21b2f84..0edde5301960a 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go @@ -1,8 +1,6 @@ package diff import ( - "fmt" - "github.com/go-openapi/spec" ) @@ -32,8 +30,28 @@ func forItems(items *spec.Items) *spec.Schema { return &schema } -func forParam(param spec.Parameter) spec.SchemaProps { - return spec.SchemaProps{ +func forHeader(header spec.Header) *spec.SchemaProps { + return &spec.SchemaProps{ + Type: []string{header.Type}, + Format: header.Format, + Items: &spec.SchemaOrArray{Schema: forItems(header.Items)}, + Maximum: header.Maximum, + ExclusiveMaximum: header.ExclusiveMaximum, + Minimum: header.Minimum, + ExclusiveMinimum: header.ExclusiveMinimum, + MaxLength: header.MaxLength, + MinLength: header.MinLength, + Pattern: header.Pattern, + MaxItems: header.MaxItems, + MinItems: header.MinItems, + UniqueItems: header.UniqueItems, + MultipleOf: header.MultipleOf, + Enum: header.Enum, + } +} + +func forParam(param spec.Parameter) *spec.SchemaProps { + return &spec.SchemaProps{ Type: []string{param.Type}, Format: param.Format, Items: &spec.SchemaOrArray{Schema: forItems(param.Items)}, @@ -95,76 +113,51 @@ func getURLMethodsFor(spec *spec.Swagger) URLMethods { return returnURLMethods } -func sliceToStrMap(elements []string) map[string]bool { - elementMap := make(map[string]bool) - for _, s := range elements { - elementMap[s] = true - } - return elementMap -} - func isStringType(typeName string) bool { return typeName == "string" || typeName == "password" } -const objType = "obj" +// SchemaFromRefFn define this to get a schema for a ref +type SchemaFromRefFn func(spec.Ref) (*spec.Schema, string) -func getTypeHierarchyChange(type1, type2 string) TypeDiff { - if type1 == type2 { - return TypeDiff{Change: NoChangeDetected, Description: ""} - } - fromType := type1 - if fromType == "" { - fromType = objType - } - toType := type2 - if toType == "" { - toType = objType - } - diffDescription := fmt.Sprintf("%s -> %s", fromType, toType) - if isStringType(type1) && !isStringType(type2) { - return TypeDiff{Change: NarrowedType, Description: diffDescription} - } - if !isStringType(type1) && isStringType(type2) { - return TypeDiff{Change: WidenedType, Description: diffDescription} - } - type1Wideness, type1IsNumeric := numberWideness[type1] - type2Wideness, type2IsNumeric := numberWideness[type2] - if type1IsNumeric && type2IsNumeric { - if type1Wideness == type2Wideness { - return TypeDiff{Change: ChangedToCompatibleType, Description: diffDescription} - } - if type1Wideness > type2Wideness { - return TypeDiff{Change: NarrowedType, Description: diffDescription} - } - if type1Wideness < type2Wideness { - return TypeDiff{Change: WidenedType, Description: diffDescription} - } +func propertiesFor(schema *spec.Schema, getRefFn SchemaFromRefFn) PropertyMap { + if isRefType(schema) { + schema, _ = getRefFn(schema.Ref) } - return TypeDiff{Change: ChangedType, Description: diffDescription} -} + props := PropertyMap{} -func compareFloatValues(fieldName string, val1 *float64, val2 *float64, ifGreaterCode SpecChangeCode, ifLessCode SpecChangeCode) TypeDiff { - if val1 != nil && val2 != nil { - if *val2 > *val1 { - return TypeDiff{Change: ifGreaterCode, Description: fmt.Sprintf("%s %f->%f", fieldName, *val1, *val2)} - } - if *val2 < *val1 { - return TypeDiff{Change: ifLessCode, Description: fmt.Sprintf("%s %f->%f", fieldName, *val1, *val2)} - } + requiredProps := schema.Required + requiredMap := map[string]bool{} + for _, prop := range requiredProps { + requiredMap[prop] = true } - return TypeDiff{Change: NoChangeDetected, Description: ""} -} -func compareIntValues(fieldName string, val1 *int64, val2 *int64, ifGreaterCode SpecChangeCode, ifLessCode SpecChangeCode) TypeDiff { - if val1 != nil && val2 != nil { - if *val2 > *val1 { - return TypeDiff{Change: ifGreaterCode, Description: fmt.Sprintf("%s %d->%d", fieldName, *val1, *val2)} + if schema.Properties != nil { + for name, prop := range schema.Properties { + prop := prop + required := requiredMap[name] + props[name] = PropertyDefn{Schema: &prop, Required: required} } - if *val2 < *val1 { - return TypeDiff{Change: ifLessCode, Description: fmt.Sprintf("%s %d->%d", fieldName, *val1, *val2)} + } + for _, e := range schema.AllOf { + eachAllOf := e + allOfMap := propertiesFor(&eachAllOf, getRefFn) + for name, prop := range allOfMap { + props[name] = prop } + } + return props +} +func getRef(item interface{}) spec.Ref { + switch s := item.(type) { + case *spec.Refable: + return s.Ref + case *spec.Schema: + return s.Ref + case *spec.SchemaProps: + return s.Ref + default: + return spec.Ref{} } - return TypeDiff{Change: NoChangeDetected, Description: ""} } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go index 202d83f5a1eae..9604918d9ebf7 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go @@ -47,11 +47,12 @@ func writeToFile(swspec *spec.Swagger, pretty bool, format string, output string var err error asJSON := format == "json" - if pretty && asJSON { + switch { + case pretty && asJSON: b, err = json.MarshalIndent(swspec, "", " ") - } else if asJSON { + case asJSON: b, err = json.Marshal(swspec) - } else { + default: // marshals as YAML b, err = json.Marshal(swspec) if err == nil { @@ -62,12 +63,15 @@ func writeToFile(swspec *spec.Swagger, pretty bool, format string, output string b, err = yaml.Marshal(d) } } + if err != nil { return err } + if output == "" { fmt.Println(string(b)) return nil } + return ioutil.WriteFile(output, b, 0644) // #nosec } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate.go index 13794f1937ab0..1d2a3e9fbcba1 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate.go @@ -24,4 +24,5 @@ type Generate struct { Server *generate.Server `command:"server"` Spec *generate.SpecFile `command:"spec"` Client *generate.Client `command:"client"` + Markdown *generate.Markdown `command:"markdown"` } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/markdown.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/markdown.go new file mode 100644 index 0000000000000..ba9df38122cac --- /dev/null +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/markdown.go @@ -0,0 +1,33 @@ +package generate + +import ( + "github.com/go-swagger/go-swagger/generator" + "github.com/jessevdk/go-flags" +) + +// Markdown generates a markdown representation of the spec +type Markdown struct { + WithShared + WithModels + WithOperations + + Output flags.Filename `long:"output" short:"" description:"the file to write the generated markdown." default:"markdown.md"` +} + +func (m Markdown) apply(opts *generator.GenOpts) { + m.Shared.apply(opts) + m.Models.apply(opts) + m.Operations.apply(opts) +} + +func (m *Markdown) generate(opts *generator.GenOpts) error { + return generator.GenerateMarkdown(string(m.Output), m.Models.Models, m.Operations.Operations, opts) +} + +func (m Markdown) log(rp string) { +} + +// Execute runs this command +func (m *Markdown) Execute(args []string) error { + return createSwagger(m) +} diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go index e506a013c2882..d88f348c15c76 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go @@ -52,7 +52,7 @@ type Server struct { Name string `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"` // TODO(fredbi): CmdName string `long:"cmd-name" short:"A" description:"the name of the server command, when main is generated (defaults to {name}-server)"` - //deprecated flags + // deprecated flags WithContext bool `long:"with-context" description:"handlers get a context as first arg (deprecated)"` } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go index 6e233e928fc0f..24c3b345a18e5 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go @@ -80,10 +80,13 @@ type sharedCommand interface { type schemeOptions struct { Principal string `short:"P" long:"principal" description:"the model to use for the security principal"` DefaultScheme string `long:"default-scheme" description:"the default scheme for this API" default:"http"` + + PrincipalIface bool `long:"principal-is-interface" description:"the security principal provided is an interface, not a struct"` } func (so schemeOptions) apply(opts *generator.GenOpts) { opts.Principal = so.Principal + opts.PrincipalCustomIface = so.PrincipalIface opts.DefaultScheme = so.DefaultScheme } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go index 83aa682907ccf..79e26c440f336 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go @@ -16,7 +16,8 @@ import ( const ( // Output messages - nothingToDo = "nothing to do. Need some swagger files to merge.\nUSAGE: swagger mixin [-c ] " + nothingToDo = "nothing to do. Need some swagger files to merge.\nUSAGE: swagger mixin [-c ] " + ignoreConflictsAndCollisionsSpecified = "both the flags ignore conflicts and collisions were specified. These have conflicting meaning so please only specify one" ) // MixinSpec holds command line flag definitions specific to the mixin @@ -28,6 +29,7 @@ type MixinSpec struct { Output flags.Filename `long:"output" short:"o" description:"the file to write to"` KeepSpecOrder bool `long:"keep-spec-order" description:"Keep schema properties order identical to spec file"` Format string `long:"format" description:"the format for the spec document" default:"json" choice:"yaml" choice:"json"` + IgnoreConflicts bool `long:"ignore-conflicts" description:"Ignore conflict"` } // Execute runs the mixin command which merges Swagger 2.0 specs into @@ -52,6 +54,9 @@ func (c *MixinSpec) Execute(args []string) error { if len(args) < 2 { return errors.New(nothingToDo) } + if c.IgnoreConflicts && c.ExpectedCollisionCount != 0 { + return errors.New(ignoreConflictsAndCollisionsSpecified) + } log.Printf("args[0] = %v\n", args[0]) log.Printf("args[1:] = %v\n", args[1:]) @@ -65,6 +70,9 @@ func (c *MixinSpec) Execute(args []string) error { return err } + if c.IgnoreConflicts { + return nil + } if len(collisions) != int(c.ExpectedCollisionCount) { if len(collisions) != 0 { // use bash $? to get actual # collisions diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go index 3f13c76a17091..0a22668e4b5f4 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go @@ -27,7 +27,7 @@ type ServeCmd struct { NoUI bool `long:"no-ui" description:"when present, only the swagger spec will be served"` Flatten bool `long:"flatten" description:"when present, flatten the swagger spec before serving it"` Port int `long:"port" short:"p" description:"the port to serve this site" env:"PORT"` - Host string `long:"host" description:"the interface to serve this site, defaults to 0.0.0.0" env:"HOST"` + Host string `long:"host" description:"the interface to serve this site, defaults to 0.0.0.0" default:"0.0.0.0" env:"HOST"` } // Execute the serve command diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go index 25331c6627442..9a860653b506e 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go @@ -1,6 +1,9 @@ package commands -import "fmt" +import ( + "fmt" + "runtime/debug" +) var ( // Version for the swagger command @@ -16,9 +19,17 @@ type PrintVersion struct { // Execute this command func (p *PrintVersion) Execute(args []string) error { if Version == "" { + if info, available := debug.ReadBuildInfo(); available && info.Main.Version != "(devel)" { + // built from source, with module (e.g. go get) + fmt.Println("version:", info.Main.Version) + fmt.Println("commit:", fmt.Sprintf("(unknown, mod sum: %q)", info.Main.Sum)) + return nil + } + // built from source, local repo fmt.Println("dev") return nil } + // released version fmt.Println("version:", Version) fmt.Println("commit:", Commit) diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go index 6c4a0ecc3e03b..10cc2de2d82f1 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go @@ -41,7 +41,7 @@ func main() { // Recovering from internal panics // Stack may be printed in Debug mode // Need import "runtime/debug". - //defer func() { + // defer func() { // r := recover() // if r != nil { // log.Printf("Fatal error:", r) @@ -50,7 +50,7 @@ func main() { // } // os.Exit(1) // } - //}() + // }() parser := flags.NewParser(&opts, flags.Default) parser.ShortDescription = "helps you keep your API well described" @@ -123,6 +123,9 @@ It aims to represent the contract of your API with a language agnostic descripti case "operation": cmd.ShortDescription = "generate one or more server operations from the swagger spec" cmd.LongDescription = cmd.ShortDescription + case "markdown": + cmd.ShortDescription = "generate a markdown representation from the swagger spec" + cmd.LongDescription = cmd.ShortDescription } } diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/README.md b/vendor/github.com/go-swagger/go-swagger/codescan/README.md new file mode 100644 index 0000000000000..7468cda5bee6d --- /dev/null +++ b/vendor/github.com/go-swagger/go-swagger/codescan/README.md @@ -0,0 +1,3 @@ +# codescan + +Version of the go source parser with support for go modules, from go1.11 onwards. diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/application.go b/vendor/github.com/go-swagger/go-swagger/codescan/application.go index d6d3f1c51ae08..117d758541f25 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/application.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/application.go @@ -595,7 +595,7 @@ func (a *typeIndex) detectNodes(file *ast.File) (node, error) { if seenStruct == "" || seenStruct == matches[1] { seenStruct = matches[1] } else { - return 0, fmt.Errorf("classifier: already annotated as %s, can't also be %q", seenStruct, matches[1]) + return 0, fmt.Errorf("classifier: already annotated as %s, can't also be %q - %s", seenStruct, matches[1], cline.Text) } case "meta": n |= metaNode @@ -604,14 +604,14 @@ func (a *typeIndex) detectNodes(file *ast.File) (node, error) { if seenStruct == "" || seenStruct == matches[1] { seenStruct = matches[1] } else { - return 0, fmt.Errorf("classifier: already annotated as %s, can't also be %q", seenStruct, matches[1]) + return 0, fmt.Errorf("classifier: already annotated as %s, can't also be %q - %s", seenStruct, matches[1], cline.Text) } case "response": n |= responseNode if seenStruct == "" || seenStruct == matches[1] { seenStruct = matches[1] } else { - return 0, fmt.Errorf("classifier: already annotated as %s, can't also be %q", seenStruct, matches[1]) + return 0, fmt.Errorf("classifier: already annotated as %s, can't also be %q - %s", seenStruct, matches[1], cline.Text) } case "strfmt", "name", "discriminated", "file", "enum", "default", "alias", "type": // TODO: perhaps collect these and pass along to avoid lookups later on diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/doc.go b/vendor/github.com/go-swagger/go-swagger/codescan/doc.go new file mode 100644 index 0000000000000..e789b71d10831 --- /dev/null +++ b/vendor/github.com/go-swagger/go-swagger/codescan/doc.go @@ -0,0 +1,5 @@ +/*Package codescan provides a scanner for go files that produces a swagger spec document. + +This package is intendnd for go1.11 onwards, and does support go modules. +*/ +package codescan diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/meta.go b/vendor/github.com/go-swagger/go-swagger/codescan/meta.go index 1115d0203c6a7..20dbb7cb8319f 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/meta.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/meta.go @@ -204,7 +204,8 @@ func parseContactInfo(line string) (*spec.ContactInfo, error) { ContactInfoProps: spec.ContactInfoProps{ URL: url, Name: name, - Email: email,}, + Email: email, + }, }, nil } diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/parameters.go b/vendor/github.com/go-swagger/go-swagger/codescan/parameters.go index b5f0a9364d580..decc20712eee7 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/parameters.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/parameters.go @@ -260,9 +260,6 @@ func (p *parameterBuilder) buildFromField(fld *types.Var, tpe types.Type, typabl typable.Typed("string", sfnm) return nil } - //if err := r.makeRef(decl, typable); err != nil { - // return err - //} sb := &schemaBuilder{ctx: p.ctx, decl: decl} sb.inferNames() if err := sb.buildFromType(decl.Type, typable); err != nil { diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/parser.go b/vendor/github.com/go-swagger/go-swagger/codescan/parser.go index 8c45aedf41a42..8ef4d0bb2294b 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/parser.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/parser.go @@ -626,7 +626,8 @@ COMMENTS: } var matched bool - for _, tagger := range st.taggers { + for _, tg := range st.taggers { + tagger := tg if tagger.Matches(line) { st.seenTag = true st.currentTagger = &tagger @@ -1311,13 +1312,13 @@ func (ss *setOpResponses) Matches(line string) bool { return ss.rx.MatchString(line) } -//ResponseTag used when specifying a response to point to a defined swagger:response +// ResponseTag used when specifying a response to point to a defined swagger:response const ResponseTag = "response" -//BodyTag used when specifying a response to point to a model/schema +// BodyTag used when specifying a response to point to a model/schema const BodyTag = "body" -//DescriptionTag used when specifying a response that gives a description of the response +// DescriptionTag used when specifying a response that gives a description of the response const DescriptionTag = "description" func parseTags(line string) (modelOrResponse string, arrays int, isDefinitionRef bool, description string, err error) { @@ -1331,8 +1332,8 @@ func parseTags(line string) (modelOrResponse string, arrays int, isDefinitionRef tag = tagValList[0] value = tagValList[1] } else { - //TODO: Print a warning, and in the long term, do not support not tagged values - //Add a default tag if none is supplied + // TODO: Print a warning, and in the long term, do not support not tagged values + // Add a default tag if none is supplied if i == 0 { tag = ResponseTag } else { @@ -1353,15 +1354,15 @@ func parseTags(line string) (modelOrResponse string, arrays int, isDefinitionRef } } if foundModelOrResponse { - //Read the model or response tag + // Read the model or response tag parsedModelOrResponse = true - //Check for nested arrays + // Check for nested arrays arrays = 0 for strings.HasPrefix(value, "[]") { arrays++ value = value[2:] } - //What's left over is the model name + // What's left over is the model name modelOrResponse = value } else { foundDescription := false @@ -1369,7 +1370,7 @@ func parseTags(line string) (modelOrResponse string, arrays int, isDefinitionRef foundDescription = true } if foundDescription { - //Descriptions are special, they make they read the rest of the line + // Descriptions are special, they make they read the rest of the line descriptionWords := []string{value} if i < len(tags)-1 { descriptionWords = append(descriptionWords, tags[i+1:]...) @@ -1382,13 +1383,13 @@ func parseTags(line string) (modelOrResponse string, arrays int, isDefinitionRef } else { err = fmt.Errorf("invalid tag: %s", tag) } - //return error + // return error return } } } - //TODO: Maybe do, if !parsedModelOrResponse {return some error} + // TODO: Maybe do, if !parsedModelOrResponse {return some error} return } @@ -1431,7 +1432,7 @@ func (ss *setOpResponses) Parse(lines []string) error { if err != nil { return err } - //A possible exception for having a definition + // A possible exception for having a definition if _, ok := ss.responses[refTarget]; !ok { if _, ok := ss.definitions[refTarget]; ok { isDefinitionRef = true diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/responses.go b/vendor/github.com/go-swagger/go-swagger/codescan/responses.go index 7c92c4884afe4..84d258320b196 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/responses.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/responses.go @@ -402,6 +402,12 @@ func (r *responseBuilder) buildFromStruct(decl *entityDecl, tpe *types.Struct, r return nil, err } return append(taggers, otherTaggers...), nil + case *ast.SelectorExpr: + otherTaggers, err := parseArrayTypes(iftpe.Sel, items.Items, level+1) + if err != nil { + return nil, err + } + return otherTaggers, nil case *ast.StarExpr: otherTaggers, err := parseArrayTypes(iftpe.X, items, level) if err != nil { diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/schema.go b/vendor/github.com/go-swagger/go-swagger/codescan/schema.go index 81349a7c40ab7..3488522acf8f1 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/schema.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/schema.go @@ -238,7 +238,7 @@ func (s *schemaBuilder) buildFromType(tpe types.Type, tgt swaggerTypable) error case *types.Array: return s.buildFromType(titpe.Elem(), tgt.Items()) case *types.Map: - //debugLog("map: %v -> [%v]%v", fld.Name(), ftpe.Key().String(), ftpe.Elem().String()) + // debugLog("map: %v -> [%v]%v", fld.Name(), ftpe.Key().String(), ftpe.Elem().String()) // check if key is a string type, if not print a message // and skip the map property. Only maps with string keys can go into additional properties sch := tgt.Schema() @@ -387,7 +387,6 @@ func (s *schemaBuilder) buildFromType(tpe types.Type, tgt swaggerTypable) error return nil } default: - //log.Printf("WARNING: can't determine refined type %s (%T)", titpe.String(), titpe) panic(fmt.Sprintf("WARNING: can't determine refined type %s (%T)", titpe.String(), titpe)) } @@ -429,7 +428,7 @@ func (s *schemaBuilder) buildFromInterface(decl *entityDecl, it *types.Interface continue } - //decl. + // decl. debugLog("maybe interface field %s: %s(%T)", o.Name(), o.Type().String(), o.Type()) afld = an break @@ -514,7 +513,7 @@ func (s *schemaBuilder) buildFromInterface(decl *entityDecl, it *types.Interface var afld *ast.Field ans, _ := astutil.PathEnclosingInterval(decl.File, fld.Pos(), fld.Pos()) - //debugLog("got %d nodes (exact: %t)", len(ans), isExact) + // debugLog("got %d nodes (exact: %t)", len(ans), isExact) for _, an := range ans { at, valid := an.(*ast.Field) if !valid { @@ -600,7 +599,7 @@ func (s *schemaBuilder) buildFromStruct(decl *entityDecl, st *types.Struct, sche debugLog("maybe allof field(%t) %s: %s (%T) [%q](anon: %t, embedded: %t)", fld.IsField(), fld.Name(), fld.Type().String(), fld.Type(), tg, fld.Anonymous(), fld.Embedded()) var afld *ast.Field ans, _ := astutil.PathEnclosingInterval(decl.File, fld.Pos(), fld.Pos()) - //debugLog("got %d nodes (exact: %t)", len(ans), isExact) + // debugLog("got %d nodes (exact: %t)", len(ans), isExact) for _, an := range ans { at, valid := an.(*ast.Field) if !valid { @@ -696,7 +695,7 @@ func (s *schemaBuilder) buildFromStruct(decl *entityDecl, st *types.Struct, sche var afld *ast.Field ans, _ := astutil.PathEnclosingInterval(decl.File, fld.Pos(), fld.Pos()) - //debugLog("got %d nodes (exact: %t)", len(ans), isExact) + // debugLog("got %d nodes (exact: %t)", len(ans), isExact) for _, an := range ans { at, valid := an.(*ast.Field) if !valid { diff --git a/vendor/github.com/go-swagger/go-swagger/generator/.gitignore b/vendor/github.com/go-swagger/go-swagger/generator/.gitignore new file mode 100644 index 0000000000000..9ab870da897d6 --- /dev/null +++ b/vendor/github.com/go-swagger/go-swagger/generator/.gitignore @@ -0,0 +1 @@ +generated/ diff --git a/vendor/github.com/go-swagger/go-swagger/generator/bindata.go b/vendor/github.com/go-swagger/go-swagger/generator/bindata.go index d9ded7df9fb1d..19a3497975609 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/bindata.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/bindata.go @@ -2,22 +2,23 @@ // sources: // templates/client/client.gotmpl (5.125kB) // templates/client/facade.gotmpl (3.83kB) -// templates/client/parameter.gotmpl (12.261kB) -// templates/client/response.gotmpl (6.363kB) +// templates/client/parameter.gotmpl (15.048kB) +// templates/client/response.gotmpl (10.424kB) // templates/contrib/stratoscale/client/client.gotmpl (3.591kB) // templates/contrib/stratoscale/client/facade.gotmpl (2.078kB) -// templates/contrib/stratoscale/server/configureapi.gotmpl (6.644kB) +// templates/contrib/stratoscale/server/configureapi.gotmpl (7.309kB) // templates/contrib/stratoscale/server/server.gotmpl (236B) -// templates/docstring.gotmpl (270B) +// templates/docstring.gotmpl (566B) // templates/header.gotmpl (432B) +// templates/markdown/docs.gotmpl (14.106kB) // templates/model.gotmpl (700B) -// templates/schema.gotmpl (5.504kB) +// templates/schema.gotmpl (6.259kB) // templates/schemabody.gotmpl (14.007kB) -// templates/schemaembedded.gotmpl (551B) -// templates/schemapolymorphic.gotmpl (2.061kB) +// templates/schemaembedded.gotmpl (1.006kB) +// templates/schemapolymorphic.gotmpl (2.125kB) // templates/schematype.gotmpl (965B) -// templates/schemavalidator.gotmpl (31.954kB) -// templates/serializers/additionalpropertiesserializer.gotmpl (2.824kB) +// templates/schemavalidator.gotmpl (51.727kB) +// templates/serializers/additionalpropertiesserializer.gotmpl (2.862kB) // templates/serializers/aliasedserializer.gotmpl (480B) // templates/serializers/allofserializer.gotmpl (7.467kB) // templates/serializers/basetypeserializer.gotmpl (2.894kB) @@ -25,20 +26,25 @@ // templates/serializers/schemaserializer.gotmpl (679B) // templates/serializers/subtypeserializer.gotmpl (6.461kB) // templates/serializers/tupleserializer.gotmpl (2.34kB) -// templates/server/builder.gotmpl (18.967kB) -// templates/server/configureapi.gotmpl (6.786kB) +// templates/server/builder.gotmpl (18.855kB) +// templates/server/configureapi.gotmpl (7.308kB) // templates/server/doc.gotmpl (1.52kB) -// templates/server/main.gotmpl (5.965kB) -// templates/server/operation.gotmpl (3.868kB) -// templates/server/parameter.gotmpl (28.728kB) -// templates/server/responses.gotmpl (12.037kB) -// templates/server/server.gotmpl (23.049kB) +// templates/server/main.gotmpl (6.138kB) +// templates/server/operation.gotmpl (3.752kB) +// templates/server/parameter.gotmpl (29.44kB) +// templates/server/responses.gotmpl (12.038kB) +// templates/server/server.gotmpl (23.073kB) // templates/server/urlbuilder.gotmpl (7.641kB) -// templates/structfield.gotmpl (1.91kB) +// templates/simpleschema/defaultsinit.gotmpl (1.412kB) +// templates/simpleschema/defaultsvar.gotmpl (1.353kB) +// templates/structfield.gotmpl (1.291kB) // templates/swagger_json_embed.gotmpl (759B) -// templates/validation/customformat.gotmpl (473B) -// templates/validation/primitive.gotmpl (2.225kB) -// templates/validation/structfield.gotmpl (909B) +// templates/validation/customformat.gotmpl (194B) +// templates/validation/maximum.gotmpl (1.751kB) +// templates/validation/minimum.gotmpl (1.746kB) +// templates/validation/multipleOf.gotmpl (1.816kB) +// templates/validation/primitive.gotmpl (1.16kB) +// templates/validation/structfield.gotmpl (1.063kB) package generator @@ -147,7 +153,7 @@ func templatesClientFacadeGotmpl() (*asset, error) { return a, nil } -var _templatesClientParameterGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x5f\x73\xdb\xb8\x11\x7f\xe7\xa7\xd8\xaa\xe9\x55\xf4\x38\xd4\x3d\xfb\x46\x9d\xc9\xd9\xb9\xc6\x9d\x69\x2e\x4d\x3c\xd7\x87\x4c\xa6\x03\x93\x2b\x09\x77\x24\x40\x03\xa0\x14\x95\xc3\xef\xde\xc1\x1f\x92\x20\x45\x4a\x54\x12\xc7\x77\xd3\x3c\x59\x04\x81\xc5\xee\x6f\x7f\xfb\x07\xa0\x17\x0b\xb8\xe6\x09\xc2\x1a\x19\x0a\xa2\x30\x81\xfb\x3d\xac\xf9\x73\xb9\x23\xeb\x35\x8a\x1f\xe0\xe6\x67\x78\xfd\xf3\x1d\xbc\xbc\xb9\xbd\x8b\x82\x20\x28\x4b\xa0\x2b\x88\xae\x79\xbe\x17\x74\xbd\x51\xf0\xbc\xaa\x16\x0b\x28\x4b\x88\x79\x96\x21\x53\xbd\x77\x65\x09\xc8\x12\xa8\xaa\x20\x08\x72\x12\xff\x46\xd6\xa8\x27\x47\x6f\xdc\x6f\xfd\x62\xb1\x80\xbb\x0d\x95\xb0\xa2\x29\xc2\x8e\xc8\xae\x32\x6a\x83\xe0\xb4\x01\xc5\x79\x1a\xe9\xf9\x2f\x13\xaa\x28\x5b\x83\x6a\xd6\x65\x66\xc7\x5c\xf0\x2d\xc2\xaa\x50\x46\xd4\x06\x19\xec\x79\x01\x02\x9f\x8b\x82\x75\x24\xd5\x5b\x18\xb5\x09\x4b\x82\x80\x66\x39\x17\x0a\xe6\x01\xc0\x2c\xe6\x4c\xe1\x47\x35\xd3\xbf\x19\xaa\xc5\x46\xa9\xdc\x3c\x28\x9a\xe1\x2c\xd0\xbf\xd6\x54\x6d\x8a\xfb\x28\xe6\xd9\x62\xcd\x9f\xf3\x1c\x19\xc9\xe9\x02\x85\xe0\x42\xce\xc6\x27\x88\x82\x59\x19\x00\xb1\x38\x31\x69\x11\xa7\x14\x99\x3a\x22\x4d\x2a\xb1\xca\x8e\x4e\xd8\x91\xf5\x91\xd7\x5b\x92\xd2\x84\x28\x6b\x92\x76\xad\xc1\x40\x42\x74\x83\x2b\x52\xa4\xea\xd6\x3d\x57\x55\xef\xbd\xf7\x22\x34\x0e\x7c\x8d\xbb\xb2\x84\x9c\xc8\x98\xa4\xf4\xbf\x08\xd1\x6b\x92\x69\xef\xbe\x21\x82\x64\x12\x62\x81\x44\xa1\x04\x02\x0c\x77\x70\x6c\x26\xbf\xff\x15\x63\xa5\x45\xee\xa8\xda\x18\x9f\x25\x56\x19\xd8\x92\xb4\x40\x09\x94\x51\x45\xcd\xda\x24\x0a\x56\x05\x8b\x4f\x6c\x3e\x0f\xe1\xe2\xd8\x8e\xa5\xb3\x6d\xa5\x59\x69\x46\xaa\x6a\x4b\x84\x61\x42\x59\x82\x20\x6c\x8d\xde\x2b\x37\xf5\x15\x91\x0e\xa4\x66\x8c\x71\x05\xd1\xad\xfc\x89\xa6\x68\x66\xdb\x17\x5b\x22\x98\xde\x2f\xba\xbd\xa9\xaa\x7a\xc9\xb2\xde\xf1\x56\xbe\x11\x34\xa3\x8a\x6e\x51\xcf\x8e\xfe\xce\xef\xf6\x39\x56\xd5\xdc\x06\x8e\x91\x90\x0b\xca\xd4\x0a\x66\x7f\xf9\xf3\x76\xd6\xb8\xa6\xd5\xc4\x13\x01\x55\x15\xb6\x11\x67\xd4\xb7\xbf\xbd\x1f\x46\x6a\x00\xd0\x99\x28\x50\x15\x82\xc1\x77\x87\x38\xd5\x30\x95\x67\xa1\x71\x20\xe4\xca\x19\x4c\x58\x02\x73\x07\xd4\x0b\x21\xc8\x3e\x6c\x1e\xff\x49\xf2\xfa\x41\x8b\xa3\x32\xd6\x66\x31\xa2\xb8\x08\x61\xce\x85\x9e\xf3\xba\x48\x53\x72\x9f\x22\x40\x08\x55\xf5\x9d\x6f\x9f\x87\x33\x34\x40\x5f\x0e\x82\x10\x00\x98\xe1\x98\x64\x68\x95\xbc\xa3\x19\xf2\x42\x39\x62\x5c\x41\x2c\x6a\x9c\xdd\x1b\x2d\xa8\x0a\xaa\x09\x5c\xff\x37\x55\x1b\xb7\xe8\xb1\x68\x7f\x69\x60\xd4\x73\xc8\x3d\x4d\xa9\xda\x83\xe2\x20\x51\x01\x01\xe5\x76\xe6\x0c\x08\x08\x7c\x28\x50\xaa\x29\x41\xe2\x69\x3d\xaf\x65\xe8\xbf\xd1\x4d\x21\x88\xa2\x9c\x7d\x0b\xa2\xa7\x0c\x22\x6d\xf6\x1f\x2c\x84\xd4\xa7\x04\xce\xb5\x2d\xbc\x4f\x10\x38\xae\xe4\xc3\x8a\x8b\xf3\x23\xc7\xa9\x3d\x8f\xd5\xc7\x5a\x50\xe4\xc6\x9e\x36\x6e\x5a\xf7\x58\x1a\xfe\x1f\x86\xce\xd7\xaa\x3f\x5d\xa8\x27\xc5\x8f\xa3\xc8\x15\xc4\xea\xe3\x79\x71\xf2\xea\xee\xee\xcd\xb5\xe9\x0e\x9f\x22\x54\x0a\xa9\x78\x06\x9e\x0e\x9f\x14\x34\xed\xfa\xb9\x6d\x74\xe1\x42\xf7\xd9\x91\x1d\xfb\x16\x37\xdf\xe2\x66\x00\x87\x96\x34\x57\x60\x59\xd3\x06\xce\x51\xc2\xe8\xb4\x4c\x28\x93\x40\xd2\xd4\xd0\x3a\xd7\xe3\xa8\x50\x48\xcb\x6c\xcd\x76\x6e\xde\xbc\x78\x73\xab\x77\xcb\x39\x65\x2a\xd0\xd4\xd6\x83\x65\x09\x9b\x22\x23\xcc\x17\x0d\x3c\x47\xdb\x1d\x81\xda\xe7\x34\x26\x69\x6a\xce\xab\x12\x81\x08\x84\x9d\xa0\x4a\x21\xd3\x62\x09\x18\x6a\xbf\x75\x11\x72\xb1\x08\xd4\x3e\xc7\xa3\xd1\x2a\x95\x28\x62\x05\x65\x30\xec\xc0\x11\x6b\xcb\x52\xbb\xf5\x06\xb5\x13\x72\xa3\x59\x4d\xa8\xfb\x94\xc7\xbf\x35\x87\xf4\xde\x0c\x1f\xeb\x8b\x85\x7d\xea\xb4\x1f\xda\xda\xcf\x64\x82\x9b\x74\xcb\x14\x8a\x15\x89\xb1\x1d\x7a\xa7\x04\x92\x6c\x84\x2c\x17\x3e\x09\x46\x03\xd6\x05\xa0\xa3\x4a\x2a\xf5\x2f\x77\x8c\x36\xd0\x24\x6f\x91\x24\xd7\x29\x97\x28\xda\x50\xf2\x2e\x27\x8e\x36\x33\xdd\x4e\x38\x68\x12\x77\xbf\xd6\x07\xe0\x27\x45\x3f\x9b\xb9\xc4\xae\xd3\x5e\x17\xd9\xde\x46\x24\x49\xa4\xa1\x5b\xd3\x83\xf3\x71\xf6\x19\x06\x4b\x9b\x6e\x75\xde\x89\xde\x62\x8c\x74\x8b\xa2\x9e\x70\x2c\x20\xc2\x93\xca\x7c\xce\x39\xa0\xaf\x4a\xf4\x0e\xd5\x94\xbd\xc2\x36\xa7\x0d\x48\x71\x28\x9e\x90\xf5\x55\x41\x9c\x68\x57\x1f\xc3\x31\x98\x8e\x91\x70\x59\xdb\xe3\x91\xa9\x26\x62\x63\x72\xdd\xc6\x3e\x32\x6f\x3e\xbb\xe1\x1d\x22\x88\x27\x74\x2a\x0f\x9e\xc2\xfe\xae\xa6\x87\xe6\x8f\x59\x58\xeb\xba\xd4\xed\x9e\xe7\x43\x2f\x65\x34\x66\x78\x63\x8f\xec\xc9\x2f\xd1\x85\x0d\x39\xf3\x40\xee\x54\x97\x3e\x1d\x1c\x43\x5a\xf7\xd0\x18\x33\xd8\x53\x70\xe9\xfa\x12\x6d\xd1\x40\xdd\x1e\x2e\x03\xb6\xc0\x36\xf6\xfa\x67\x71\xb3\x85\x29\x42\x87\x96\x3f\x1b\x35\xfd\xd9\x09\xdb\x9f\x9d\xae\x06\x46\xa7\xf9\xa0\x2a\x5f\xa6\x13\xf8\xda\x65\xdf\xc9\xeb\x73\xfa\xd9\x30\xa9\x0f\x10\x3c\xac\x61\xe3\x08\x7d\x5a\x1d\x3b\x64\x41\xaf\x39\x7e\x7c\x1a\x9c\x61\xe3\x1f\x9d\x05\xa3\x7e\x1e\x72\xca\x72\x30\x26\x5d\x8c\xbb\x26\x52\x47\xb6\xa0\x0a\xef\xb8\xeb\xf3\xcd\x09\x00\xa5\x3b\x12\x58\xdf\xd8\xd3\x40\xfd\x19\xaa\x73\x64\xfe\x94\x0c\xde\xd9\x6f\x2e\xa0\x36\xdb\x26\x23\x37\x7e\x09\x02\xd7\x60\x3f\x16\x45\x6f\x71\x4d\xa5\x12\xfb\x10\xcc\xc7\x2a\x7b\xc0\xa0\x2b\xfd\x04\x57\x4b\x10\x9a\xe6\xf5\x4d\xf0\x99\x2d\x4a\xf8\x83\x91\xf2\xa7\x25\x30\x9a\x1a\x7c\x9b\x28\x40\x21\xcc\x39\x0d\x34\x88\x20\x50\xc2\xfb\x0f\x66\x7f\xe3\x84\x4e\x92\xac\xdb\x71\xe7\x6e\xc7\x0b\x43\x2d\x47\x2a\xfd\xe7\x47\x9e\xec\xcd\xfc\xb0\xfd\x3a\x65\xc9\xe8\x93\xc8\x92\xec\x45\x9a\xf2\xdd\xcb\x2c\x57\xfb\x5f\x48\x5a\xa0\x5e\x41\x57\x26\x30\xcd\xf3\xcb\x8f\xb9\x40\x29\xed\x51\xa8\xd1\x1e\xea\x93\x7c\x7b\xd3\x70\x2b\xff\x55\xa0\xd8\xd7\xcc\x0b\x00\x16\x0b\x78\xd0\x43\xd6\xb9\x46\x64\x1d\xe3\xde\xaa\x46\x1d\x7b\x47\xf1\x20\x06\x7d\x0a\x1d\x26\x5b\xa7\x9c\xd0\xd1\x20\x3c\x26\x6e\x69\xb8\x33\xb0\x5c\x3b\xa2\x0d\x94\xb1\xe5\x57\xcb\x91\xdd\x3d\x5c\x1e\x86\xae\x0c\xdc\x4a\x6d\xfa\x4f\x5c\x64\x44\x29\x14\x2e\x4e\xfd\xe7\xf9\xc8\xc6\xe1\x49\xd5\x1a\x5c\xaf\xcd\x45\x94\x2f\x34\x7a\xa7\x04\x65\xeb\x79\xe8\x0e\x79\xcd\x9f\x26\x79\xf4\xb8\xd0\x20\x3d\x60\x8a\x43\x7a\x36\x6b\xc8\xd0\xcc\xf6\x83\xa5\xe5\xc4\xdc\xbf\xf4\x79\x98\x35\x52\x2e\x47\xa4\x4f\x8a\x97\xa3\xba\x57\xfd\x5b\x23\x0d\x9c\xbb\x5c\x22\x6a\xd3\x65\x6a\x4e\xd4\x66\x90\xa8\x3d\x83\x9a\x95\xe3\xf6\x4c\xf1\xef\x10\xfd\x2f\x5a\x87\x0c\x30\xcb\x73\xfd\x61\x6d\xe9\x39\x3b\x3c\x4b\xf2\xf9\x94\x99\xea\x1b\x0f\xf1\x57\x48\x12\x14\x5d\xcc\x37\x66\x6c\x0a\xea\xde\xea\x6f\xb8\x9f\x85\xbb\x96\xea\xa1\xde\xec\xe9\x77\x09\x43\xe9\x78\x7a\x92\x6d\xaf\x8c\x8c\x53\x57\x5c\x64\xf6\xbf\x4e\x86\xfc\x7a\xe0\xd9\x46\x8f\xa3\x7e\x1d\xf2\xcb\x00\x16\x3d\x34\xfc\x1c\xd1\x37\xad\x7b\xc5\xd5\xa2\x56\x73\xd3\x98\x71\x4e\xe1\x5a\x7d\xd9\xc2\x35\x26\x6e\x62\xe1\x1a\x5b\x3e\xa5\x70\xad\x3e\xa7\x70\x8d\x6c\x1c\x9e\x54\xed\x51\x0a\xd7\x80\x29\x13\x0b\x57\x13\x37\xe3\xbc\x1c\x16\xfe\x08\x75\x6b\xe4\xf7\x39\x2d\x5d\xe5\x5f\xec\x7a\xe9\xc1\x76\x8e\x55\x4f\x27\xaf\x83\x6c\x3d\x73\xbd\xa1\x69\x7b\xd8\xd0\x8d\xa7\x19\xf1\xdc\xef\x06\x86\x5c\xa8\x23\xc4\x7e\x47\x1b\xf6\xc8\xfb\x0f\xd2\xf8\x58\xd3\x8f\x0b\xf8\xcf\x25\x6c\x8d\x2b\x4c\xef\x7b\xce\x59\xca\x3b\x33\x79\xc0\x84\x27\x93\xb1\xf3\xd4\x31\x1d\x97\x40\xf2\x1c\x59\x32\x3f\x32\xc9\x66\xab\x3e\x30\x5d\x0c\x0f\x2a\x92\x75\xea\xb6\x33\xe7\x44\x1c\x74\x0e\x7e\x03\x62\xdb\x29\x61\xaf\x2c\x68\x5f\x8c\xdb\xd8\x44\xf9\x11\xb4\x1b\x80\x3b\xe8\x9f\x85\xf6\x70\xe6\xfd\x9d\x29\xf6\x2b\xa7\x0c\x93\xb1\x64\xa8\x4f\xa9\xd1\x3f\x38\x65\x3f\xee\x2d\xf0\xc7\x69\x31\x2b\xcb\xe8\x9a\xa7\x29\xc6\x8a\x72\x66\x57\x54\xd5\x2c\x1c\x3d\x40\x35\xa7\x27\x62\x42\x74\x42\x93\x34\xa5\xd7\x1e\xb3\x49\xb3\x2b\x8a\xce\xed\x2f\x5c\xfa\xf1\x7b\x8c\xba\x74\x4e\xd6\x7a\x42\xa2\x7d\x14\xa5\xfd\x23\x40\xdd\xff\x8f\x2b\x6d\x6f\xa4\xda\x35\x09\x47\x69\x72\xa5\x2c\x72\xf3\xaf\xb1\x5b\x22\x28\x49\x04\x8d\x81\x88\x75\x91\x21\x53\xf2\x12\x24\x65\x31\xc2\x0e\xa1\x90\x98\x80\x4f\x16\x2b\x72\x87\x10\x13\xe6\xbe\xaf\x6e\x10\x56\x54\x48\x05\x54\x61\x06\xd4\xfe\x4b\xae\xd5\x88\x48\xa0\xea\xaf\xed\xe7\x59\x3d\x43\x02\x5f\xd9\x6f\xb5\x02\xb7\x94\x17\xd2\x8a\xb4\x0b\x2c\x62\xa0\xf8\x1a\xd5\x06\x85\x45\x3d\x45\x36\x3f\x02\x65\x08\x7f\x83\xef\xeb\x46\xea\xfc\x53\xcf\x11\xc9\xef\xbf\xff\x30\xb9\x5b\x1b\xfe\xc2\x1f\x1c\x7e\x90\xb4\x21\xd3\xd4\x29\xaf\x84\xe9\xd2\xf4\x2e\xde\x60\x46\xfc\x2f\xaa\xde\x98\xcd\x13\x30\x37\x4c\x68\x46\xdd\x25\x8a\xc9\xa5\x61\xff\xa5\xb9\x58\x19\x7e\xd5\x2b\xbe\x07\x97\x79\x3a\xe9\x4c\xe8\xfa\x3a\x7d\x74\x0f\xfe\xc6\xca\xf9\x17\xe9\x85\x7f\x8f\x00\x55\xd0\xe9\x50\xcc\xaf\xce\xe1\xc2\x11\x58\xa0\xf4\x89\xda\xda\xc8\x85\x8c\xae\x79\x96\x73\x49\x15\xfe\x62\xff\x77\x9b\x72\xf6\x52\xbf\xd1\xab\x74\xa6\x70\xfc\x72\x8b\x18\x4d\x83\x2a\xf8\x5f\x00\x00\x00\xff\xff\x42\x0a\x05\x41\xe5\x2f\x00\x00") +var _templatesClientParameterGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x5b\x6f\xe3\x36\xf6\x7f\xd7\xa7\x38\x7f\x63\xda\xbf\x15\x64\xe4\x3e\xa7\xc8\x02\xd3\x24\xdd\x66\x81\x9d\xce\x4e\x82\xd9\x87\xc1\x60\xc1\x48\xc7\x36\x5b\x89\x54\x48\x2a\x89\x6b\xf8\xbb\x2f\x78\xd1\x8d\xa6\x64\x39\x49\x3b\xdd\xc5\x3e\xc5\x92\xc8\x43\x9e\xdf\xb9\x1f\x32\x8b\x05\x5c\xf0\x0c\x61\x85\x0c\x05\x51\x98\xc1\xdd\x06\x56\xfc\xad\x7c\x24\xab\x15\x8a\xef\xe1\xf2\x67\x78\xff\xf3\x2d\x5c\x5d\x5e\xdf\x26\x51\x14\x6d\xb7\x40\x97\x90\x5c\xf0\x72\x23\xe8\x6a\xad\xe0\xed\x6e\xb7\x58\xc0\x76\x0b\x29\x2f\x0a\x64\xca\xfb\xb6\xdd\x02\xb2\x0c\x76\xbb\x28\x8a\x4a\x92\xfe\x4a\x56\xa8\x07\x27\x1f\xdc\x6f\xfd\x61\xb1\x80\xdb\x35\x95\xb0\xa4\x39\xc2\x23\x91\xfd\xcd\xa8\x35\x82\xdb\x0d\x28\xce\xf3\x44\x8f\xbf\xca\xa8\xa2\x6c\x05\xaa\x99\x57\x98\x15\x4b\xc1\x1f\x10\x96\x95\x32\xa4\xd6\xc8\x60\xc3\x2b\x10\xf8\x56\x54\xac\x47\xa9\x5e\xc2\x6c\x9b\xb0\x2c\x8a\x68\x51\x72\xa1\x60\x1e\x01\xcc\x52\xce\x14\x3e\xa9\x99\xfe\xbd\x2c\xec\x5f\x86\x6a\xb1\x56\xaa\x34\x0f\x8a\x16\x38\x8b\xf4\xaf\x15\x55\xeb\xea\x2e\x49\x79\xb1\x58\xf1\xb7\xbc\x44\x46\x4a\xba\x40\x21\xb8\x90\xb3\xe1\x01\xa2\x62\x96\x06\x40\x2a\x0e\x0c\x5a\xa4\x39\x45\xa6\x46\xa8\x49\x25\xea\x6d\x0e\x0c\x78\x24\xab\x91\xcf\x0f\x24\xa7\x19\x51\x96\x25\x2d\x62\x83\x85\x84\xe4\x12\x97\xa4\xca\xd5\xb5\x7b\xde\xed\xbc\xef\x9d\x0f\xb1\x11\xe4\x7b\x7c\xdc\x6e\xa1\x24\x32\x25\x39\xfd\x0d\x21\x79\x4f\x0a\x2d\xe5\x0f\x44\x90\x42\x42\x2a\x90\x28\x94\x40\x80\xe1\x23\x8c\x8d\xe4\x77\xbf\x60\xaa\x4e\x35\xcd\x47\xaa\xd6\x46\x78\x99\xdd\x0d\x68\x50\x78\xa5\x60\xc9\x85\xd5\x00\x0b\x90\xd6\x0c\x3d\xde\x6d\x1a\x1e\x48\x5e\xe9\xb5\x04\x02\xe3\x0a\xd6\x9b\xcc\x28\xd5\x29\x48\xca\xd2\x86\x5a\x3d\x40\x14\x24\xcf\x37\x40\xca\x32\xa7\xad\xe6\xbd\xfb\x70\x0d\x12\xc5\x03\x0a\x90\x34\xc3\x7a\x89\x5b\x0e\xc8\x96\x5c\xb4\x64\xea\xd5\x28\x83\x52\x73\x80\x0a\xc5\x29\x54\x12\xe1\x06\xd5\x65\xbd\x14\x17\xf0\x4f\xaa\xd6\xf5\x73\x12\x2d\x2b\x96\x1e\x00\x6d\x1e\xc3\xc9\x18\x52\xdb\x08\x40\xa0\xaa\x04\x83\x6f\xf7\xc7\xd5\xc3\xf4\x28\x23\xbb\x94\x14\x68\x3f\xdf\x5a\x18\x1d\xb5\x33\x48\x45\x2d\x6f\xf7\xe5\x34\x02\xd8\x45\xbb\x09\x82\xd5\x4c\xb9\x49\x47\xcb\xb8\x27\x62\x72\x47\x73\xaa\x36\xa0\x38\x48\x54\x40\x1a\x59\x73\x06\x04\x04\xde\x57\x28\xd5\x24\xd8\x3a\x5b\x9a\xd7\x44\xf4\xdf\xe4\xb2\x12\x44\x51\xce\xfe\x28\x58\xd5\x73\xc0\xbc\xb0\x1e\xe8\x95\xc1\x74\x7e\xcd\x18\xce\xf1\x68\xba\x3d\xcd\x53\xf5\x54\x53\x4a\xdc\xbb\x57\xc4\xd2\x51\x3c\x83\x54\x3d\x1d\x87\xd9\x4f\xb7\xb7\x1f\x2e\x8c\x27\x78\x6d\xd8\x2a\xa9\x78\x01\x1d\xfa\xcf\x03\xb0\x25\x30\xb7\x1e\x0b\x4e\x74\x44\x49\xec\xbb\x57\xc4\xb0\x5d\xe8\xcc\xf9\xc6\x16\xc9\x93\x51\x38\xb4\x5c\x09\x65\x12\x48\x9e\x1b\x30\x1a\x67\x26\x2d\x1e\x2c\xd3\x7f\x6b\xd7\x88\x2c\x2b\x39\x65\x4a\xaf\x6a\xbd\xb1\x09\xef\xeb\xaa\x20\xac\x4b\x1d\x78\x89\xd6\xea\x12\x1d\x62\xe0\x76\x53\xd2\xd4\xf8\x5b\xb5\x46\x89\xc6\x05\x3f\x0a\xaa\x14\x32\x4d\x9e\x80\xc1\xe5\x63\x8d\xef\xc9\x22\x52\x9b\x12\x47\x77\x2e\x95\xa8\x52\x65\x60\xda\x6e\xdf\x82\x20\x6c\x85\x3a\xcf\x30\x1f\x4d\xe0\xb2\x1f\x74\xfa\x72\x89\x32\x15\xb4\xd4\xfb\x31\x19\x08\xc0\x10\x2c\x76\xbb\xc6\xc2\xef\x72\x9e\xfe\xda\x64\x39\x1e\x09\x80\x0e\x7d\x2e\x20\xb9\xb1\x89\xc6\x8f\x3a\xae\xa8\x26\x90\xb6\x43\x0d\xc9\x52\x50\xa6\x60\x36\xeb\xbf\xb6\x7b\xec\x13\xa8\x07\xd8\xc7\x33\x93\x43\x85\x47\x38\x12\x2e\xeb\xf2\xa9\xfa\xfb\x70\xcf\x86\xe0\x2f\x92\xb3\x81\x9d\x7a\xf4\x7a\x2f\x4e\x16\x0d\xb6\x98\x4b\xac\x01\x5d\x0c\x01\x7a\x14\x54\x8b\xc5\x14\x60\x16\x8b\xd7\x05\xa6\x4d\x22\x5e\x02\x4c\xe0\xb1\x0b\xc8\xf5\xa5\x36\x0c\x9b\x50\x13\x96\xc1\x5c\x27\x29\xc9\xb5\x7c\x27\x04\xd9\xc4\xcd\xe3\xdf\x49\x59\x3f\xfc\x44\xe4\x25\xd5\x6a\x57\x50\x46\x14\x17\xed\xa0\x6b\xa6\x50\x2c\x49\x8a\xed\xab\x1b\x25\x90\x14\x31\xcc\x35\xc4\xd7\xf2\x7d\x95\xe7\xe4\x2e\x47\x80\x18\x76\xbb\x93\x26\x2f\xb7\xeb\xbb\x39\x3f\xd2\x1c\x8d\xc5\xd8\x0f\xc9\x5f\xf9\xad\x36\x3b\x9b\xc6\x5b\xd9\xba\x9c\xd4\x88\x33\xfb\x88\x24\xbb\xc8\xb9\x44\xd1\xe6\xf9\x3d\xae\xa3\xd1\xd8\xd8\x8f\xc7\x51\xe3\xfb\xfd\xe8\x12\x75\x3d\x5a\xcf\x67\xba\xd8\xd0\xcd\xa9\xea\x3c\x4f\x06\x32\xb3\x41\xf7\x54\x5a\x37\x61\xb0\xd3\x83\xee\x2b\x14\x1b\xb8\xe3\xd9\x26\xae\x53\xbe\x77\x79\x5e\x53\x32\x91\x82\xf1\x66\x01\xed\xbd\x04\xea\x58\x61\x5d\x23\x15\xf0\x1b\x0a\x6e\x87\xbb\xe8\x30\xd7\x78\x7e\xc4\x14\xe9\x03\x8a\x7a\xd9\x31\x87\x1f\xf7\xb8\x9a\x92\x04\x1a\xac\xfd\x35\x92\x4e\xfa\x39\x8f\xcd\x28\x17\x45\x02\x83\x1d\x9c\xdd\x8c\xf5\xbf\x06\xcd\x1e\x0e\xb0\x8d\x6a\xc3\xb7\xdf\xb5\x6d\xdd\xf0\x02\x1b\xbe\x8d\x26\x3f\x10\x61\x0a\xc2\x83\x01\x45\x5b\xa6\xef\x1e\xea\x6f\x7d\xb3\x32\x1f\x75\x3a\xf3\xf3\xed\xd5\x59\x97\x6d\x59\x95\xba\x96\xc2\xcc\x04\x52\x53\xd3\x36\xb1\xd7\xc8\xca\xf8\x8b\xae\x9f\xd1\x06\x69\x17\xb0\xb6\x3e\x9d\xba\xb4\xe3\xa7\xd1\x77\xbe\xe1\x07\x9e\x6d\x7a\x4c\x38\x85\x53\x58\x94\xb9\xae\xa4\x67\x92\x16\x65\x8e\x32\x5d\x63\x41\x6a\x1c\x1f\x88\x98\x41\x32\xcd\x41\xf6\x1e\xe2\x09\xb0\x6b\xaf\xd9\x85\x7e\xee\xbb\xb1\x80\x37\xf4\xb9\x89\xbb\x7b\x3b\xc0\x0c\x65\x54\x75\xb8\x19\xda\xbc\x51\x9c\x1c\xce\xce\xc7\xf2\x95\x29\x79\xca\xab\xf2\x17\xca\x19\xcf\x5e\x1a\x7e\x42\xb1\xe5\xdb\x6e\x6c\x79\x20\x82\x69\xb6\xad\x76\x39\x46\x4e\x0f\xc8\xbe\x86\x30\x19\x8b\x1d\xe7\x41\x6f\x37\x32\xc3\xd1\xac\x63\x4c\x78\x7e\x1b\x71\xf4\xd8\x4e\xd4\x09\x0f\x6f\x07\xe8\x44\x28\xe4\x94\xce\x35\xa1\xa8\x9b\x1c\x19\x03\xed\x98\xa6\x73\x83\x19\x2e\x29\x73\xf6\x69\x9a\x1a\x8d\x75\x46\x1d\x70\xda\x78\xd7\x97\xa7\x07\x0e\xc9\x32\x69\x5c\x6f\x53\xf9\xf2\x43\xee\xfa\x45\x61\x6a\x6c\x33\xcf\xae\xbe\x07\xa2\xd9\x94\xb5\xe2\x68\x5a\x98\xfb\xd3\x80\x38\x91\x2f\x1f\xc3\x21\x98\xc6\x0d\xc7\x11\xeb\x28\x53\x6d\x14\x0d\xcb\x75\xa7\xe0\x77\xd6\x9b\x97\xb5\x14\x06\x14\xa4\x43\x74\xaa\x1e\x7c\x0d\xfe\xfb\x3b\xdd\x67\x7f\x88\xc3\xd6\x81\xa5\xea\xa9\x23\xc3\x8e\xb3\x6a\xd8\xe8\xbc\xfb\x9d\x25\xf9\xe2\xde\xc6\x80\x30\xf7\xe8\x4e\x15\xe9\xd7\x83\x23\xb4\x6b\x0f\x8d\x21\x86\x7b\x01\x27\x6d\x4a\x9c\x60\xa2\x10\x0e\x04\xb6\xaa\x6c\x38\xee\x86\x60\xb3\x88\x29\xbb\xf6\x79\x7f\x33\xc8\xfc\x9b\x03\xdc\xbf\x39\x1c\x0f\xcc\x9e\xe6\xc1\xad\xbc\x4e\xf9\xfb\x95\x6a\x5d\x5f\xab\xdf\x84\xd5\x7a\x0f\xc1\xfd\x28\x36\x8c\xd0\xf3\x22\xd9\xbe\x16\xb4\xe1\xe0\x0f\x52\x83\x23\x78\xfc\x4f\xd7\x82\x41\x39\x87\x84\x72\x1e\xb4\xc9\x68\xd7\xcd\xf2\x8c\x69\x0b\xaa\xf0\x96\xbb\x1e\xa8\xe9\x8e\xa2\x74\xed\x52\x57\x60\x9b\x4e\x69\x7d\xa2\xe9\x9a\xd1\xcf\x77\xe2\xbd\xf5\xe6\x02\x6a\xbe\xad\x3f\x72\xef\x4f\x41\xe0\x0a\xec\x79\x63\xf2\x11\x57\x54\x2a\xb1\x89\xc1\x9c\x77\xc2\x56\xe7\xed\x74\xa9\x9f\x74\xf5\x23\xb4\x9e\xd7\x47\x30\x47\x66\x29\xf1\xf7\x86\xca\xff\x9d\x03\xa3\xb9\xeb\x6e\x38\x33\x40\x21\x4c\x8d\x60\xcb\x73\x81\x12\x3e\x7f\x31\xeb\x4f\xa8\xa8\xb4\xd4\x9d\x7a\x18\x0d\x73\xba\x35\x5c\x11\xb6\x75\x58\x47\xa1\xac\xc2\xbd\xcb\x73\xfe\x78\x55\x94\x6a\xf3\x49\x67\xf0\xb1\x2b\xfd\xe8\xd2\x18\xaa\x79\x77\xf5\x54\x0a\x94\xd2\xf6\x88\xfb\xcc\x34\x25\x8f\x9d\xd5\x6f\x18\xfc\xa3\x42\xd1\x16\xdb\xb6\x62\xb0\x4d\x14\x23\x79\xb3\x40\x5b\xd5\xf8\xb3\x9b\x7d\x36\x3d\x8c\x7b\x11\x14\x3d\xf4\x34\xfe\x88\xcd\x0f\xd1\x3b\xb7\x35\xd0\xfe\x74\x27\x30\xaf\xb9\x60\xde\x0f\xd1\xb2\xe5\x73\x98\x96\x0f\x20\xc0\x7d\xa8\xbc\x75\x34\x34\x2a\xb6\x17\xac\x50\x38\x3b\xef\x3e\xcf\x07\xb6\x10\xb7\x3e\x60\x60\x84\x23\x7e\x2d\x2f\xcc\x09\x51\x97\x68\x72\xa3\x04\x65\xab\x79\xbc\xdd\x9a\x3d\xba\x3f\xbe\xb8\x42\x9a\x64\x79\xa4\xcb\x10\x53\x4e\x14\xb3\x59\xa3\x46\x7e\xeb\xc1\xb3\xbf\x56\x95\xe6\xf5\x81\xc3\x12\x66\xdf\xdc\xcf\x1a\x7a\xa7\x03\xeb\x4c\x32\xc1\x89\xcc\x04\x5b\xe6\xe1\x5e\xd6\x07\xa2\xd6\x9e\xea\x97\x44\xad\x83\x9a\xef\xf1\xda\x4c\x1d\x66\x75\x8a\x3a\x34\x52\xed\x18\xd2\x49\x23\xc6\x90\x4a\x76\x34\x65\x3f\x94\x79\xba\x11\x1f\x45\xf9\x78\x0d\x9b\x20\xb6\x30\xf0\x3f\x21\xc9\x50\x78\xd0\xaf\xcd\xcb\x29\xe0\x77\xa6\xff\x0f\xfe\x09\x56\xe3\xa1\xaf\x49\x07\xda\xab\x83\x2d\xe4\x31\xa7\x7f\x4c\x14\x0a\x34\x65\x17\x0b\x58\x72\x51\x74\x7a\xd0\x7b\x01\xc7\x93\x7d\xb3\xbb\x51\xc9\x87\x24\x17\x40\xcb\xc3\xab\xeb\x3c\x42\x0c\x7b\xfe\x65\xf0\x90\xaf\x7f\x36\x69\x18\x1c\x0e\xa6\xe3\xe1\x74\x39\x29\x9c\x4e\x16\xc2\x10\xb9\x69\xd1\xd4\x8f\xa7\x43\xd4\x0e\xc7\xd3\x7e\x44\x5d\xbe\x24\xa2\x0e\x6c\xa2\x63\xa8\x03\x23\x5e\x10\x51\xa7\xc5\xd4\x00\x5b\xa1\x98\xea\xa9\x91\xaf\xef\xb5\xb1\x0e\xeb\x7b\x78\x9d\x23\x62\xea\x51\x51\x75\x58\xeb\x47\x4e\xa7\x9f\x91\xdf\x7a\xee\xcb\x3b\xc8\x69\xbd\x99\x4d\xae\xf7\x52\xdb\xd0\x51\xd2\x34\x3b\xd9\x73\x89\x17\x6b\x9a\xdb\x6a\x6e\x71\x02\x77\x94\x65\x90\xf2\xa2\xcc\xf1\xa9\x7b\x63\x65\x4e\xf4\x3e\xa4\x61\x90\xa1\x54\x98\xb9\x6b\x22\x95\x40\x19\xc3\xc9\xa2\xf1\x07\x9a\x02\x65\x2b\xa0\x0a\x0b\x69\x7a\xf0\x7d\xb7\xf0\x0b\xa7\x0c\xb3\x51\xcb\xf2\xab\x1b\x4d\xd2\x70\x19\x9c\x35\x17\xb8\x8a\x07\x52\x62\x7b\x22\x30\xb6\xd8\x78\xb5\xec\x1f\x06\xd9\xea\xb9\x23\xe1\xf8\x60\xe0\x1b\x61\xd9\x6e\x42\x97\x9d\xc9\xdf\x38\x65\x3f\x6c\xac\x91\xce\x47\x76\x7d\x0a\xb3\xed\x36\xb9\xe0\x79\x8e\xa9\xa2\x9c\xd9\x19\xbb\xdd\x2c\x1e\xc9\x0b\xa7\x15\x44\x46\xc2\x53\xf2\x93\x29\x89\xf0\x88\x94\x93\x24\x99\x9e\x59\xf5\xed\xc1\x99\x57\x2f\xc2\x77\xa2\xd0\x64\x0e\x26\x78\x9d\xdf\x95\x81\xa1\xcc\x7c\x98\x01\xdb\x9a\x6a\xe7\x65\x1c\xa5\x71\x02\xee\x38\x5a\x47\x53\x4a\x32\x9a\x02\x11\xab\xaa\x40\xa6\x64\x7d\x3b\xf7\x11\xa1\x92\x98\x41\x57\xc5\x2c\xc5\x47\x84\x94\x30\x77\x15\x6d\x8d\xb0\xa4\x42\x2a\x63\xb8\xf5\xa5\x04\xbb\x21\x22\x81\xaa\xff\x6f\x6f\xb2\x59\xd3\xe6\x4b\x7b\xad\x4d\xe0\x03\xe5\x95\xb4\x24\xed\x04\x0b\x1e\x28\xbe\x42\xb5\x46\x61\x05\x90\x23\x9b\x8f\xa0\x1a\xc3\x5f\xe0\xbb\x3a\x6e\x1c\x5f\x8e\x8c\x50\xfe\xfc\xdd\x97\xc9\xd9\xd1\x80\xdc\x0e\x24\xf5\xa3\x8a\xf7\x02\xbe\x27\x55\x02\xaf\xc6\x79\x30\xda\x1d\xbe\x6e\x10\xf5\x1d\x4c\xe0\x76\x43\xf7\x86\x9a\xb9\x06\xd0\xbd\x67\xd5\x79\xe7\x2e\x5f\xcc\x8d\x95\x34\x6f\x5d\x7b\xc9\x84\xa9\xd8\xff\x68\x5a\x4e\xe1\x4f\x5e\x10\xde\xeb\x76\xc6\x47\xa5\x96\x7b\x08\x78\xa2\x6a\xd8\x9e\xbf\x42\x7e\xfe\xa7\x06\x6c\x92\x46\xec\x75\x52\xb4\x15\x98\x54\xa1\xd5\xf6\x96\x79\x2e\x64\x72\xc1\x8b\x92\x4b\xaa\xf0\x93\xfd\x17\x0a\xca\xd9\x95\xfe\xa2\x67\x69\x8f\xeb\x56\x76\x93\x18\xcd\x07\x8f\x73\x7a\xd9\x58\xe0\x1a\x47\xe0\xf2\x47\x37\xd1\x72\x39\xcc\x7e\xc2\xd1\xb6\xf4\xf5\x77\xd9\xbf\xd4\xdb\xb3\xfb\xa9\x9d\xe3\xbd\x56\xff\x81\x4c\x67\x69\x9c\xb7\xdc\xef\x1a\x7f\xfe\x22\x4d\x4a\x5f\x37\xd0\x9b\xae\xb8\x91\x74\x40\x1d\x3f\xfe\x61\xe9\x4f\xe4\x5f\x07\xca\x69\x8a\xf6\x40\xce\x80\xa7\x59\xc6\xfa\x6a\x53\xef\x88\xe6\x20\x13\x37\x91\x77\xe1\xc5\xfb\x69\x2f\x82\x0c\x2f\xa9\x75\xa5\x75\x5c\x8d\x02\x98\xca\x74\xca\xfa\x17\x0d\xee\x91\x49\x74\xff\x75\x3a\x69\xda\xb5\x01\xdf\xaa\xed\x34\x59\x6d\x75\xac\xc1\xa7\x32\xe7\x19\xee\xd5\xc6\x13\xe1\xad\xd3\x7c\x37\x63\x02\x73\xe7\x40\xca\x12\x59\x36\x9f\x34\x7c\x22\xef\x9f\xe2\xc8\x04\x59\x7b\xab\xd9\x8d\xbb\xd6\x09\xc5\x25\x96\x6a\xad\x29\x79\xc9\xed\x19\xf8\xa1\xcf\x1f\xe1\x04\x39\x41\x61\xc2\xf9\xf6\x74\xfe\x0e\x6d\x23\x8e\xfc\xc2\x4a\xfb\x25\x64\xaa\xae\xaf\xec\x75\x42\x9b\x78\x69\xa3\xc2\xa7\x12\x53\x05\x04\x66\x45\x95\x2b\x3a\x83\x3d\xa2\x8f\x54\xad\x29\x03\xc2\x80\x32\xd6\xe4\x1a\xa6\xe0\x9a\xc4\xf3\x27\x67\xe9\x87\xc1\xf9\xfc\xdd\x97\xc8\x77\xe4\xfd\x72\xaa\x47\x27\x24\x5c\x38\x3b\x8f\x7a\xd9\xc0\x7e\xf3\x21\xea\x64\x19\xee\xd6\x3e\xcc\xbc\x2b\x6e\x21\x9b\x69\x9a\x16\x91\x97\x9b\xe1\x7d\x63\x0f\x33\x6b\x8d\xb3\x17\x2c\xe3\x53\x4f\x0e\xee\x3d\xdc\x78\x1d\x5d\xa4\xcf\xc3\xf0\x66\xb5\x93\xbf\xb1\x3a\x37\x9f\x7d\xf3\x30\x3b\x3d\x24\x80\x0e\x65\x23\xc1\xda\xcc\x1a\x7f\xa1\x73\xf9\xda\x65\x85\x1d\xe7\xbf\x03\x00\x00\xff\xff\x1a\x90\x6c\x6c\xc8\x3a\x00\x00") func templatesClientParameterGotmplBytes() ([]byte, error) { return bindataRead( @@ -162,12 +168,12 @@ func templatesClientParameterGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/client/parameter.gotmpl", size: 12261, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x90, 0xd8, 0x41, 0xd2, 0x6, 0xe3, 0x24, 0x53, 0x68, 0xa4, 0xc6, 0xcc, 0x6d, 0xa3, 0x61, 0xd3, 0x49, 0x4e, 0xe2, 0x3d, 0xf3, 0x9b, 0x1e, 0x12, 0x19, 0xf, 0xd3, 0xd4, 0x4c, 0x37, 0x6f, 0x72}} + info := bindataFileInfo{name: "templates/client/parameter.gotmpl", size: 15048, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4e, 0x97, 0x6b, 0x6, 0x1d, 0x36, 0x14, 0xf0, 0x17, 0xd2, 0x61, 0xf4, 0x38, 0x7a, 0xcb, 0x25, 0x36, 0x59, 0xf, 0x34, 0xa6, 0x71, 0x81, 0x69, 0xb2, 0x5e, 0xc0, 0x52, 0xb8, 0x2f, 0xb4, 0x7c}} return a, nil } -var _templatesClientResponseGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x58\xcd\x72\xe4\xb6\x11\x3e\x07\x4f\xd1\x61\xbc\x5b\x43\x65\xc4\xb1\x73\x94\x4b\x07\x5b\x2b\xaf\x75\xf0\xae\x4a\xda\x54\x0e\x2e\x57\x0a\x22\x7b\x66\x90\x25\x01\x1a\x00\x35\x9e\xb0\xf8\xee\x29\xfc\x90\x04\x87\xe0\x48\x9b\x9c\xb2\xba\x68\x08\x34\xba\xd1\xdd\x5f\x7f\x68\xa0\x6d\xa1\xc0\x2d\xe3\x08\x49\x5e\x32\xe4\x5a\xa2\xaa\x05\x57\x98\x40\xd7\x6d\x36\xf0\x01\x0f\x6d\x0b\x35\x55\x39\x2d\xd9\xbf\x11\xb2\x0f\xb4\x42\xe8\x3a\xc8\x25\x52\x8d\x0a\x28\xc4\xe7\x0f\x4c\xef\x8d\x6a\xda\x94\x1a\xf6\x48\x0b\x94\x0a\x9e\x69\xd9\xa0\x22\xdb\x86\xe7\x8b\x9a\x57\x6d\x0b\x6c\x0b\xf8\x3b\x64\x37\xa2\x40\xb8\xfc\x0e\xba\x2e\x37\xbf\x18\xd7\x6d\x0b\xc8\x0b\xe8\x3a\x27\x94\x3d\xe6\x7b\xac\xe8\xf0\x4d\x79\x01\xab\x60\x65\xda\x4b\x64\x77\xea\x51\x4b\xa4\x15\x74\xdd\x1a\xda\x16\x79\x71\xa2\x23\x94\x38\x48\xa6\x51\x02\x13\xd9\x3f\xec\xaf\xd0\xaa\xfb\x91\xc2\x45\xdc\xed\x96\x00\x48\xd4\x8d\xe4\xf0\x36\x2a\x61\x04\x00\x62\x3e\xfe\x53\x69\xaa\x1b\x65\x06\xae\xc0\x38\xbc\xee\x45\x07\xe3\x92\xf2\x1d\x42\xf6\xb3\x0f\xe7\xe0\xc2\xcf\x54\xbd\xf3\xa1\xb6\x63\x73\xb3\x57\x36\x4d\x92\x71\xbd\x85\xe4\xcd\x5f\x9e\x13\xc8\xc6\x15\x73\x43\xe7\x82\x1c\x09\xd8\x3d\x3d\x96\x82\x16\x57\xe0\x22\xb7\xa4\xaf\x23\x1d\x21\x9b\x48\xe4\xba\x0e\xf6\x94\x17\x25\x2a\xd0\x7b\xa6\x20\xa7\x0a\x63\x08\xf2\x00\xca\x08\xf1\x5b\x79\x87\x2a\x97\xac\xd6\x4c\x70\x67\xe8\xa9\x14\xf9\xe7\x5c\x54\x15\x72\x3d\x9f\xc6\x52\xe1\x42\x80\xcc\x76\xf7\x4d\x45\xf9\x24\x59\x0e\x28\xe4\x62\x43\xf4\xb1\xc6\x05\xa8\x2b\x2d\x9b\x5c\xdb\xd4\xc7\xf2\x4a\x00\x82\xd4\x1a\x14\x13\xf2\xba\xb4\x4e\xb7\x6f\x03\x77\xce\x3f\x02\x70\xb1\x19\xf4\x3a\x1b\x71\x47\xb3\xf7\xe2\x93\xf1\xa7\x97\x0a\x57\x4c\x32\x4e\x00\x7c\x6e\x21\xa8\x30\x2e\x74\x80\x82\x1f\xa9\x42\xa3\x2d\x3d\x9d\xb8\xe3\x1a\xe5\x96\xe6\x18\x96\xe1\x8d\xa8\xea\x12\xff\xf8\xf8\xf4\x2f\xcc\xf5\xe9\x0a\x07\xa8\x14\xba\xee\xe2\x04\x84\x8b\x82\xc6\x1b\x3f\x3c\x38\x65\xd6\x96\xca\xfc\x0a\x4a\xd8\x65\x32\x74\xb7\x8b\x66\x8b\x6c\x36\x60\x3f\x77\xa8\x0d\x1c\x11\x5c\xf2\x6c\x49\xc2\x56\x48\x3b\x16\x43\x0b\xf4\xdc\xe9\x08\xce\x10\x59\xf6\x80\x39\xb2\x67\x94\xbd\x48\x9c\x36\x52\x6b\x71\x95\x1a\x70\x84\x14\x12\xd1\x90\x05\x58\x22\x1d\x19\xbd\x21\xff\x85\xd5\x5b\x29\x85\x5c\xa5\x06\xc1\x8c\xef\xa0\x25\x7f\xf2\x86\xb7\x95\xce\x1e\x1d\x5d\xac\x92\x5f\xdb\x16\x9a\xba\x46\x09\xd9\x2f\xa8\xf7\xa2\xe8\x51\x74\x4f\xf5\x1e\xba\xee\xb7\x5f\xdf\x14\xbf\xf5\xd0\x19\x2a\x67\x02\x38\x9f\x8e\x86\x7f\xe6\xe2\xc0\x01\x8d\x5d\x58\xe4\x19\x78\xf3\xd7\xe7\x61\x32\x59\x47\xab\xea\x85\xd0\x8c\x36\x8d\xa0\x5d\x76\x86\xd8\xd6\x20\x32\x8f\xf3\x91\xe2\x0d\x59\xcd\xea\xe1\xcb\x63\xfc\x1e\xb5\x57\xbd\x4a\xbf\x8e\x22\x0a\x70\x32\x84\x6d\x0a\xc5\x2f\x8f\x92\x44\x5a\x3c\xf8\xf2\x59\xf5\x75\x04\xb2\xe1\x9a\x55\x98\xdd\xd8\xd6\xa4\x9f\x5f\x43\x2e\xb8\x6a\x2a\x94\xa3\x80\x1f\x58\x9b\x02\xad\xa8\x56\x06\xd2\x06\xc4\x0f\xb8\x63\x4a\xcb\x63\xda\x63\xce\x31\xc0\x8c\x71\x09\xc0\x66\x33\x14\x70\x7f\xdc\xb4\xad\x3f\x9e\xec\x2a\x83\x84\x1b\xc1\x9f\x51\x9a\xee\xc0\x46\x28\xa7\x15\x4e\x3c\x59\x1b\x3b\x70\x75\x0d\x0e\x76\xa3\xf0\xe0\x54\xf6\x1e\xb5\xb3\xbb\x4a\x82\x2a\x49\xd2\x94\x80\x85\xb9\x94\xf0\xe7\x6b\xe0\xac\x04\xd7\x2b\xf8\x50\xdb\xfd\xab\xec\x8e\x3f\xd3\x92\x15\x26\x49\xab\xa0\x06\xd7\x90\xb8\x3d\x27\x6b\x48\x26\x0c\x9f\xac\xe1\x55\xa6\x3d\x37\xce\x8a\x2a\x7e\x88\x58\x07\x67\xde\x7b\x7a\x35\xb0\x31\xc1\xba\x53\x37\x8d\xd2\xa2\xfa\xc9\xe6\xc4\xc5\xc1\x89\x2c\xc7\xcd\xe7\x2f\xbb\xa7\x52\x59\x0f\x87\xa6\xe5\xf7\x04\xb2\xc7\x03\xdd\xed\x50\x3a\x85\x76\xd9\xd7\x16\xd6\x8b\x55\x2c\x3c\xd9\xea\x62\x62\xdd\xaa\xf6\xa1\x8e\x73\xe1\x92\xfe\x17\x37\x6d\x15\xcf\x0f\xcb\x68\x6f\x70\xda\x10\xf6\x2c\x36\x2f\xa8\xda\x77\x11\x54\x99\x33\xce\x31\x1a\x98\x9e\x8a\x40\x3f\x17\x96\x8e\x16\xf7\x34\xff\x4c\x77\x68\xb7\x95\xfd\x22\x0a\x2c\x95\x1f\x32\xde\xfd\x9d\x57\x54\xaa\x3d\x2d\xcd\xfd\x45\x8a\xba\x9f\x8a\xb1\xd8\x64\x87\x3f\x48\x49\x8f\x5d\xf7\x58\xb2\x1c\x07\xe7\xc6\xda\xfc\x51\x14\xc7\x55\x3a\x12\xcc\xcb\xe0\x39\x93\xe2\xbe\x73\xba\xee\x3d\x3c\x29\x8f\x05\x3a\xef\x5e\xd6\xc7\xf1\xb0\x8a\x71\x76\x7a\xd2\x58\xb2\x2d\xc4\x8f\x99\xc5\x04\x8d\xfe\x5e\x5d\x0f\x51\xe8\xe9\x75\x1e\xa7\xd1\xc6\x4a\xc8\x45\x8f\x62\x47\xce\x5b\xb7\xcf\x38\x78\xbd\xa7\xe9\xf7\x61\xe4\xdf\xbe\xed\xbf\x98\xc8\x6e\x3f\xfe\x74\x26\x15\x27\xf7\x8e\xb1\xa1\xe2\xac\x0c\x4f\xaa\xb1\xd5\xe3\x28\xa9\xc6\x02\x9e\x8e\xb0\x13\x97\xca\xd1\xcc\xf7\xf0\xee\x23\x7c\xf8\xf8\x09\x6e\xdf\xdd\x7d\xca\xc8\xd0\x0e\xdc\x88\xfa\x28\xd9\x6e\xaf\xe1\xd2\xea\x30\x15\xdb\xb7\xe4\x93\xb9\xb0\x3b\xab\x3d\x44\x1d\xbb\xf4\x48\xb6\xed\xe6\x27\x73\xe7\xd9\xb2\x12\xe1\x40\xd5\x74\x33\xb6\xff\x74\xbb\x01\x2d\x44\x99\x19\xf9\xdb\x82\x69\xd3\xaf\xe9\x61\x5d\x65\x2d\xd6\x52\x3c\x23\x6c\x1b\x6d\x55\xed\x91\xc3\x51\x34\x20\xf1\x52\x36\x7c\xa2\xa9\x37\x61\xb7\x4d\x79\x41\x08\x61\x55\x2d\xa4\x86\x15\x01\x48\x98\x48\xcc\x3f\x8e\x7a\xb3\xd7\xba\x4e\xcc\x7d\x25\xd9\x31\xbd\x6f\x9e\xb2\x5c\x54\x9b\x9d\xb8\x14\x35\x72\x5a\xb3\x8d\xa3\xcf\x64\x59\xc0\x9f\xd0\x67\x24\xdc\x49\x7d\x4e\xe0\x40\x77\x67\xa6\x2d\x71\x53\x8d\x89\xbf\x56\x39\x4f\xd4\x70\xc1\xbd\xf3\xdf\x03\x63\xf5\xf3\xc1\x44\x6a\xf3\x10\xe5\xcc\x07\xd7\x0a\x30\x05\x14\xfc\xef\xe0\x12\xb0\x78\x1d\x6c\x24\x66\x67\x2e\x8d\x5e\x53\x70\x75\x5c\x68\x5c\xc6\x1b\xbe\xab\x1d\xc6\x77\x7d\x1f\xe4\x3c\xf2\x8f\x15\x91\xd7\x0a\xe2\xd0\xf5\x10\xb4\x56\xb6\xcf\x32\x9e\x28\x94\xcf\xa6\x7f\xea\xc7\x19\xd7\xc2\xfa\x24\x5d\x29\x16\x51\x06\xfa\xe2\xc6\xce\xb9\x99\x4e\xf6\xf0\x3f\xb4\x77\x29\xac\x86\xd3\xa3\x75\x3d\x83\x90\xa9\x6f\xea\x2e\x6d\xa0\x7a\x2d\xca\x06\x47\x1d\x98\xce\xf7\xe3\xa1\xe7\xaf\x59\xfd\x82\xe0\x6c\xbb\xec\x7b\xc2\x41\x81\x9b\x01\xf7\x18\x11\xdc\x22\xae\xec\xa8\xa1\x14\xd5\x94\xda\xf0\xe4\x0b\x4f\x59\xaf\x78\x40\x69\x5b\xf8\x66\x16\xed\xc3\xd2\xe3\x93\xdf\xc0\x48\xd4\x6e\x2b\x59\xb4\x89\x1e\xc3\x69\xe9\x7a\x6e\xc6\x03\x6f\x4a\xb6\xad\xb7\x11\x32\xe7\xda\x93\xac\xf9\xeb\xc8\x64\xd6\x3b\x76\xa7\x1e\x9b\x3c\x47\x65\x62\xe7\xf6\xb4\x36\x0b\xfb\x87\x17\xab\xc3\x8d\x87\x2d\xc6\x49\x1e\xdc\xcb\x87\x2d\xdd\x29\xd2\xdd\xb4\x7d\x16\x5a\x12\x18\x34\x7c\x73\x02\x04\xe8\x5f\x92\xae\x02\xb9\xc1\xec\x2b\xd3\x79\x02\xa3\x57\x67\x77\x21\xf0\xff\x0f\xf9\x65\xdb\x59\xf1\x6c\xe0\xbb\x6f\xbf\x85\xeb\x6b\xf8\xdb\x5c\x4b\x90\xf4\x38\x50\x02\x08\x90\x59\x1a\xec\x47\x19\xa6\xfb\x15\xa9\x8c\x24\x32\xb0\xe4\x09\xe4\x03\x1e\x7e\xb8\xbf\x73\xcf\x1d\xc9\xc0\x3f\xe1\xc3\x4e\x21\x50\xd9\x46\xa6\xa2\x86\x31\x28\x3f\xc2\x89\x1c\x2a\xff\x54\x5e\xf8\x03\x80\x29\x63\xb8\x16\x8c\x6b\x60\xd3\x03\x56\xd5\x98\x07\x37\x84\xf5\x69\x10\xd3\x25\xe0\x4f\x5d\x3d\xa9\x0f\xf7\x20\x11\xe3\x29\xd3\x32\x63\x55\x97\xe6\x4c\x9f\x3d\xe4\x67\x5e\xc2\x6b\x19\x1e\x17\x67\x15\x74\x5e\x4b\x7c\x41\xdf\xdf\x8c\x1b\xbb\xfd\x43\x4b\xea\x8a\xc0\xee\x2d\xf6\xe0\xeb\x9f\x85\x46\x6b\x85\xc8\xdd\x23\x94\xdf\xae\x0f\xe4\x55\x65\x3a\x7f\x08\x2e\x28\xe4\x62\x43\x4c\x48\xc6\xa5\xca\x9a\x1a\xdc\x1c\xa2\xf5\x9f\x00\x00\x00\xff\xff\x4c\xb6\xa9\x92\xdb\x18\x00\x00") +var _templatesClientResponseGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x3a\x4b\x73\xdc\xb6\xfd\xe7\x3f\x3e\xc5\x2f\x1c\x5b\xb3\xd4\x7f\xc5\x4d\x7a\x54\x46\x87\x58\x52\x9c\x3d\xc4\xf6\x48\xae\x7b\xc8\x64\x32\x10\x09\xed\x22\x26\x01\x06\x00\x57\xde\x72\xf8\xdd\x3b\x78\x90\x04\xf8\x58\x51\x4e\x3b\x9d\xb6\xa7\x25\x09\xe0\xf7\x7e\x63\xeb\xfa\x02\x32\xf2\x48\x19\x81\x28\xcd\x29\x61\x4a\x10\x59\x72\x26\x49\x04\x4d\x83\x36\x1b\x78\x47\x9e\xea\x1a\x4a\x2c\x53\x9c\xd3\xbf\x13\x48\xde\xe1\x82\x40\xd3\x40\x2a\x08\x56\x44\x02\x86\xe9\xf5\x27\xaa\xf6\x1a\x36\xae\x72\x05\x7b\x82\x33\x22\x24\x1c\x70\x5e\x11\x89\x1e\x2b\x96\xce\x42\x5e\xd5\x35\xd0\x47\x20\x7f\x40\x72\xcd\x33\x02\x17\xdf\x41\xd3\xa4\xfa\x89\x32\x55\xd7\x40\x58\x06\x4d\x63\x37\x25\xf7\xe9\x9e\x14\xb8\x7b\xc7\x2c\x83\x95\x77\x32\x6e\x77\x24\x5b\x79\xaf\x04\xc1\x05\x34\xcd\x1a\xea\x9a\xb0\x6c\x00\xc3\xdf\xf1\x24\xa8\x22\x02\x28\x4f\xfe\x66\x9e\x7c\xac\xf6\x21\x86\xf3\x69\xb6\x6b\x04\xa0\xa5\xaa\x01\xff\x64\xb9\x4e\x7e\xc2\xf2\x9e\x17\xe4\xc6\x0a\x43\x6a\xc9\x02\x1c\xb0\x80\x15\x02\xd8\x6c\x80\x32\xaa\xa8\x85\xd3\x0a\x2a\x90\x9e\x93\x1a\x80\x05\x2d\x30\xdb\x91\x0e\xba\x85\xd6\xae\x19\xb4\x58\x3a\x54\xfd\x9a\x5e\x05\x45\x8a\x32\xc7\x8a\x40\x24\x69\x51\xe6\x44\x1a\xc6\x5b\xb2\x0e\x58\x44\x90\x78\x47\x34\x3c\xcb\x2d\x1a\xbd\xc6\xff\x6a\x6a\xb4\x4c\x02\x72\x4e\x51\x13\xbc\x08\xa2\x2a\xc1\xe0\x6c\x52\x3f\x35\xf2\x68\x0b\x4d\xcc\xac\xfc\x26\x15\x56\x95\xd4\x5f\x2f\x41\x1b\xdd\x7a\x8c\xcd\x50\xff\x72\xb6\xc7\xf4\x34\xcd\x25\x78\x76\xcb\xb8\x82\x64\x2b\x7f\x10\x02\x1f\x63\xf7\xaa\xc1\x50\x99\x0a\x5a\x50\x86\x15\x17\x71\xb7\x6d\xcb\x14\x11\x8f\x38\x25\xfd\x27\x6b\xbf\xb1\x7e\x7c\x57\xe5\x39\x7e\xc8\x35\xcb\x67\xbe\xf5\x1e\xb0\x60\x5a\x12\xc9\xf6\x06\x9a\xc6\x51\xb8\x5e\x20\xe2\x9e\xb3\xce\xe5\x06\x1c\x8f\xdd\xc8\x6c\xf8\x80\x8f\x39\xc7\xd9\x25\x58\xa7\x5a\x86\xab\x41\x0d\x42\x9b\xf3\x49\x99\x41\x46\xb4\x40\x1e\x4c\xec\x69\xc3\x95\x75\x18\xab\x3c\xa3\x37\x7d\xd4\x2a\x57\x3b\xfc\x44\x30\x72\x5e\x95\x20\xe4\x74\x90\xdc\x18\xb8\xa5\xa2\x9c\x59\x61\x3d\xe4\x3c\xfd\x9c\xf2\xa2\x20\x4c\x8d\x97\x49\x2e\x89\xd9\x36\x15\x05\x6a\xd8\x57\x05\x66\x81\xe9\xd9\xa0\x83\xe0\x7c\x83\xd4\xb1\x24\x33\x71\x53\x2a\x51\xa5\xca\x8f\x23\x23\x33\xf5\x8c\x54\xc7\xc4\xa1\x03\xcc\x7b\x65\xab\xaa\x90\x15\xa4\xa3\x90\x91\xf5\x29\x86\x91\xaf\x6c\x2e\x20\xb9\x7f\xc2\xbb\x1d\x11\x3f\x72\x51\x60\xb3\x7b\xe8\xe4\x9a\x3f\x41\x99\x82\x28\x1a\x44\x15\x63\x2e\xc1\xf1\x76\xdd\xbe\x1a\xb7\x98\xd9\x31\xb2\x95\x80\xaf\x90\x06\xf7\x6e\xc0\xfd\x2e\x39\x9b\xa6\x32\x84\x16\xbc\x9f\x6f\xa6\x82\xcd\x8c\xc6\x93\xb7\xfc\xa3\xd6\xeb\x38\x24\x8d\x5d\x07\x75\x8e\x31\x8a\x00\x9d\x1f\xbd\xc1\x92\x68\x80\xf1\x70\xc1\x73\xfd\xfe\xe3\x35\xd7\x41\xf4\xcb\xfb\x87\xdf\x49\xaa\x86\x27\xda\xc8\xd0\x34\xe7\x83\x0c\x3a\xbb\xd1\x68\xc0\x7e\xee\xf8\xd2\x67\x73\xa9\x9f\xbc\xd4\xe8\xac\xda\xe7\xb8\x99\x35\x5e\x5d\x52\x98\xd7\x1d\x51\x12\xd4\x9e\x04\x3e\xfb\xc8\x85\xf9\x36\xe5\x3e\x9d\xab\xdb\xea\x41\x57\x09\xc9\x1d\x49\x09\x3d\x10\xd1\x6e\x99\xce\xc9\xb1\xc1\xb8\x8a\xb5\xaf\x18\xbf\x72\x19\x62\x02\x42\xe2\xb9\x16\x1a\x30\x85\xbe\x02\xf1\xad\x10\x5c\xac\x62\xed\xd4\x94\xed\xa0\x46\xff\xe7\x70\x3f\x16\x2a\xb9\x37\xde\xf1\xb8\x8a\x7e\xa9\x6b\xa8\xca\x92\x08\x48\x7e\x26\x6a\xcf\xb3\xd6\xa0\x3e\x60\xb5\x87\xa6\xf9\xf5\x97\xd7\xd9\xaf\x6d\x94\xea\xa2\x49\x60\x7b\x4e\x2d\x15\xfb\xcc\xf8\x13\x03\xa2\xf1\xc2\x6c\xb1\x04\xaf\xff\xff\xd0\x2d\x46\x6b\x98\xaa\xb8\x9e\x91\x4e\x8f\xd3\x0b\xb4\xb3\x08\xd7\xc0\x13\x67\xef\x7d\x09\x85\x8c\x1b\x8c\x7d\xe3\xe5\x62\x7e\x4b\x94\x83\xbe\x8a\xff\x3b\xfc\xc9\x33\x95\x4e\x72\x23\x83\x7c\xb9\xa0\x04\xc1\xd9\x9d\xf3\xa3\x55\x97\x3b\x45\xc5\x14\x2d\x48\x72\x6d\x3a\x80\x76\x7d\x0d\x29\x67\xb2\x2a\x88\xe8\x37\xb8\x0f\x6b\xed\xa9\x05\x56\x52\x1b\xb6\x36\xe5\x3b\xb2\xa3\x52\x89\x63\xdc\x5a\xde\x6c\x1a\xb2\x15\xef\xfe\x98\x09\xd3\x3d\x74\x34\xb8\xa4\x5c\xd7\x2e\xcb\x23\x80\x7d\x26\xa6\x63\xed\xe5\x55\x77\x2e\x79\x4b\x94\x85\xbe\x8a\x3c\x97\x88\x62\x8d\x88\x3e\xce\xc3\xf8\xe6\x4a\xa7\xa5\xa0\x1c\xd4\xec\x1d\x88\xd0\x95\xbf\xab\xd0\xf3\xba\x86\x14\x17\x24\x38\xba\xd6\x3c\x6a\x1a\xac\xe1\xf7\x47\x56\x73\xc8\x62\x4b\x8b\x3e\xf6\xcd\x15\x30\x9a\x3b\xbc\x4e\xc1\x46\x64\x32\xd9\xb2\x03\xce\x69\xa6\x4d\x63\xe5\x39\xff\x1a\x22\x2b\x9b\x68\x0d\x51\x90\x65\xa2\xf5\x2c\x7b\x1a\xa3\xcb\x55\x23\x27\x9e\x96\xc7\xd5\x1c\xbb\x7d\x02\xd4\x96\x6a\xc4\xb4\xa7\x79\xd6\xeb\xf2\x81\xb2\x4c\x07\x37\xa7\x41\xaa\x48\x21\x4d\x24\xf7\xf4\xd1\x49\x73\x8c\x39\x10\xe7\x90\x56\x0d\xdb\xaa\x77\xba\x55\x9c\xe3\xbf\x33\xd0\xe7\x45\x6f\x24\xf5\x55\xa2\x1a\x2f\x8d\x65\xb5\x95\xd7\x95\x54\xbc\xb0\x45\xcc\x62\xd3\x72\xd4\x27\x1f\xb0\x90\xc6\x1a\x6c\xaa\x80\xe8\xf5\x1f\xd1\xb8\x30\x3a\x6d\x07\xff\x1e\xcb\xf3\xfd\x2a\x68\x47\x34\xf7\x9a\xc5\xd5\x8c\x0c\x92\x55\x80\x2a\x8e\x5f\xa8\x9b\xb3\x83\xdf\x61\xd8\xe8\xfa\xcf\xf1\x84\x21\x65\x27\x3a\x99\x0e\xed\xa0\xdb\x74\x87\x23\x5b\x0f\x44\x2f\x27\x6d\x4e\xec\x7f\x9a\xe7\x80\xb5\x93\x91\xec\xb9\xee\xad\xcd\x52\x5d\x9a\x9a\x6b\x1d\x47\x8d\x63\x9b\xa0\xfb\xd8\xd2\xa5\x87\xd2\x15\xcb\x58\xea\x2a\xce\x66\x6b\xd0\x5d\x14\x82\x76\xcd\x0f\x24\x8a\x7f\xc0\xe9\x67\xbc\x23\x86\xee\xe4\x67\x9e\x91\x5c\xba\x4f\x5a\x0a\x7f\x65\x05\x16\x72\x6f\xf4\x9c\x09\x5e\xb6\x4b\x53\x19\x3a\x20\xd1\x34\xe7\x4d\x73\x9f\xd3\x94\x74\x99\xbf\xcb\xa4\xc9\x1b\x9e\x1d\x57\x71\x9f\x39\x17\x86\x9f\x69\x55\xb5\x0d\xc2\x55\xcb\xe1\x38\xbc\xcc\x54\x2b\xcd\x6c\x44\xeb\x61\x32\xf2\xb4\x9a\xaa\x49\xe2\x13\xbd\xff\x74\x3d\x35\xaf\xae\x9e\xfb\xcb\xab\x4e\x26\x6d\x15\x31\x96\x9a\x15\xb6\x46\xb2\x32\x0d\xe6\x34\x73\x53\xc5\x95\x9b\x71\x4c\x57\xad\x8e\xe7\xf8\x7b\x5f\x0f\x67\x67\xed\x1b\xe5\xc9\xed\xfb\x1f\xe7\x14\x33\x3f\x69\xea\x1b\x09\x46\x73\xb4\xac\xf1\xee\x53\xa7\x4b\x9c\x13\xc9\xed\x55\xe7\x95\x7a\x83\x6d\x92\xc6\x65\x52\xef\xf9\x4b\xab\xc0\x57\x7d\x19\xb8\x20\xad\xba\x96\xe5\x44\xa5\x17\x46\xc3\xb5\x4d\x26\xb1\x2b\xfd\xfa\x41\x93\x61\x39\xf9\x84\xf3\x8a\xdc\x7e\x29\x05\x91\xd2\xce\x13\x3e\x69\x9b\xd8\x67\xc2\x59\xaa\x37\x0d\xd4\xbe\x65\x87\xd1\x96\x5b\x4d\x2d\x69\x67\x93\x41\xfb\xf6\x2c\x92\xeb\x75\xa7\x9c\x79\x45\x7a\x8f\x7d\x77\xca\x88\x2e\x50\x33\x78\x38\xc2\x8e\x5f\x48\x9b\x71\xbf\x87\x9b\xf7\xf0\xee\xfd\x47\xb8\xbd\xd9\x7e\x4c\x10\x42\x2e\x3c\x5c\xf3\xf2\x28\xe8\x6e\xaf\xe0\xa2\x69\x36\x1b\x4d\x5a\x37\x45\x09\xd6\xba\x90\x81\x10\x2a\x5d\xcc\xb1\x19\xb7\x0d\x4d\xc6\x32\x3e\xee\xa9\x84\x47\x9a\x13\x78\xc2\x32\x24\xc6\xb4\xcc\x96\x1a\x50\x9c\xe7\x89\xde\x7f\x9b\x51\xa5\x4b\x30\xd5\x9d\x2b\x0c\xc6\x52\xf0\x03\x81\xc7\x4a\x19\x50\x7b\xc2\xe0\xc8\x2b\x10\xe4\x42\x54\x2c\x80\xd4\xa2\x30\x64\x63\x96\x21\x84\x68\x51\x72\xa1\xcc\x88\x3a\xa2\x3c\xd2\x3f\x8c\xa8\xcd\x5e\xa9\x32\xd2\x5a\x88\x76\x54\xed\xab\x87\x24\xe5\xc5\x66\xc7\x2f\x78\x49\x18\x2e\xe9\xc6\x96\x14\xd1\xfc\x06\xd7\x4b\x9c\xd8\x61\x2d\xed\xd4\x86\x27\xbc\x3b\xb1\x6c\x8a\x19\xac\x48\xe4\x4c\xcb\x72\x22\xbb\xe1\xcf\xd6\xbd\xb7\x39\xb2\x5b\xf7\x16\x62\xa3\x87\x49\xef\xb8\x73\x75\xae\x04\x0c\xee\xd9\x9b\x5b\xcc\x4e\xf4\x2a\x41\x92\x13\x73\x3f\x07\xc9\x9b\xfe\xcd\x38\x1e\xf2\x26\xcc\x36\x00\x52\xb6\x6b\x7b\x36\xcb\x93\xbb\xbe\xe8\xef\x2f\x50\x30\x9b\xd1\x9c\xdd\x79\x8d\xa0\xe9\x0a\x35\x37\x92\x88\x83\xee\xf6\xda\xef\x94\x29\xee\xc2\x8f\x09\x2c\xd9\x64\x4a\x79\x71\x1b\x6a\x59\x8d\x03\x1a\xfe\x44\x33\x1a\xc3\xaa\x2b\x09\xea\x61\x1c\xb2\xa2\x6a\xa1\x48\x23\x1e\xf9\x44\x55\xba\xef\x5b\x48\x37\x1d\xaa\x4f\xcc\x51\x3b\x00\x6d\x40\x4f\xb1\x0c\x46\xcc\x97\xae\x30\x12\x44\x56\xb9\xd2\xa1\xed\x99\xeb\xad\xe1\xcd\xd5\xc4\xf8\xbc\xae\xe1\xd5\x48\xda\x4f\x73\x17\x52\x8e\x80\x3e\xdf\x5a\x52\x92\xc9\x96\xbf\x17\xa7\xc9\xba\x63\x34\x6d\xfb\xf4\xfd\xb8\x76\xf1\xd2\x24\xa3\xf9\xda\xe5\x4a\x3b\xb5\x0f\x56\x1d\x63\x5b\x79\x5f\xa5\x29\x91\x5a\x76\x96\x26\x13\x94\xdb\x01\xba\x81\x61\xbf\xf7\xd1\x71\x66\x7e\xea\x1c\x38\xb4\x76\xbb\x6c\x26\xfc\x73\x1b\x3a\x08\xaf\x06\xa6\x00\xed\xa5\xc0\xe5\x74\x61\xbb\x48\xa1\x03\x43\x5a\xac\xdf\x19\xd1\xff\x27\x68\x98\x3e\x8e\xdc\x67\x03\xdf\x7d\xfb\x2d\x5c\x5d\xc1\x5f\xc6\x50\x3c\xb5\x4f\x9b\x8a\x67\x04\x33\xa9\x3a\x0f\xd5\xfd\xbc\x2e\x27\x34\xe9\xa1\x72\x31\xe4\x1d\x79\xfa\xe1\xc3\xd6\x4e\x69\xa3\x2e\x04\xf9\x23\xe9\x8c\x13\x69\x4a\xd2\x02\xeb\xa0\x81\xd9\x11\x06\xfb\x88\x74\x57\xe8\x99\xcb\x03\x54\x6a\xc4\x25\xa7\x4c\x01\x0d\xf3\xac\x2c\x49\x1a\xad\xa1\x57\xd2\x40\x8a\xf1\x9c\xe5\x87\xac\x8e\xc6\xed\xa8\xbf\x91\x1c\x84\xaa\xa0\xb4\x1a\x5e\xf1\x27\xb6\xfc\xe9\x0b\xa1\x79\x2f\x3b\x0d\x67\xe2\x88\x57\xea\xf4\xc4\xdd\x7e\x51\x02\x5b\x4f\x30\xf4\x6d\xe6\x6e\xd1\x7d\x6c\x19\x4f\xdb\x7e\xd9\x10\xec\x84\x79\x59\xe8\xae\x2e\x28\x85\xcd\x75\x8d\x16\x8c\x57\x4d\x1a\x64\x1d\xab\x17\x1e\x51\xfd\x5f\x1f\x66\x4b\x4e\xcd\x7a\x3f\xc5\x30\xcd\x9f\xf9\xd6\x5e\xde\x2f\x2b\x42\x87\x97\x43\x31\x02\x5b\x5c\xb8\x23\x5b\x45\x0a\x79\x43\x4a\x33\x75\xb9\xe6\x79\x4e\x52\x45\x39\xf3\xee\xc2\x82\xf1\xcf\x70\x87\xa3\xf2\x79\x42\xee\x74\xd0\xd0\xd2\x4b\xee\xcb\x9c\xaa\x37\x47\x7b\x7e\xb5\xa8\x5c\x5f\x2f\xa1\x23\x46\xa8\x1d\xfd\xb9\x5b\x42\xc7\xe1\x68\x0c\xe6\x16\xfc\xf9\xa9\x16\xc8\x96\x65\xe4\xcb\x27\x2c\x82\xe1\xf8\x6f\x9d\x2d\xad\x17\xf1\xb9\x35\xbd\x85\x35\xb9\x65\x72\xa9\xd1\xe8\x3f\x09\xb3\x5d\x48\xd7\xc3\x2d\x56\xff\x15\xe0\xb2\x24\x2c\x5b\x24\xe8\xeb\x85\x3c\x5e\xc7\xa6\xe3\xe6\x79\x7e\x51\x95\x9e\x31\x75\x76\x66\xcb\xb7\x81\xe9\x35\x08\x0d\xe3\xe9\x66\xa3\x53\x85\xd6\x02\x48\x6d\x16\xed\x65\xd5\xf8\xb0\x3f\xd1\x9b\x1a\x6b\x1e\x70\xfe\xd5\x13\x4c\x9f\xe7\x29\x8d\xc6\x68\x6a\x90\x32\xc8\x52\x4b\x86\x99\xc6\xca\x7c\x87\x9b\x9a\x6e\x2e\xa0\x26\xbc\x10\x1f\xce\x38\x9f\x01\x70\x6d\x26\xa0\x67\x07\x9c\xc7\xc9\xea\x7c\x6a\xac\x18\x28\x69\x09\xb4\x03\xce\xa7\x07\x94\x61\x22\x0c\x27\xf9\xc1\x85\x87\xaf\x3e\xbd\xcd\x5d\xde\x43\xd4\xde\xf1\x79\x57\x1d\xff\x83\xea\xd2\xda\xfa\x7a\xdd\x9c\xd4\xc5\x38\x98\xcc\x40\x42\x8b\x06\xca\xdd\xa6\x4e\x83\x83\x3f\xff\x4c\xc9\x68\x82\xb5\x69\x40\xc1\xd5\xf5\xeb\xc3\x32\xf1\x87\xcc\xeb\x98\xe3\xa2\x0c\x96\xd3\x51\xa6\x95\xd2\xf4\x9c\xe6\x1f\x01\x00\x00\xff\xff\xcf\x38\x76\x3e\xb8\x28\x00\x00") func templatesClientResponseGotmplBytes() ([]byte, error) { return bindataRead( @@ -182,8 +188,8 @@ func templatesClientResponseGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/client/response.gotmpl", size: 6363, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x40, 0x2e, 0x8b, 0x3b, 0xc7, 0xb, 0xf9, 0x2c, 0x74, 0x50, 0xe2, 0xd0, 0xb6, 0xa3, 0x6a, 0x54, 0xe0, 0x84, 0x11, 0xaa, 0xa1, 0x6c, 0xe4, 0x98, 0xd1, 0x66, 0x16, 0x20, 0x23, 0x3d, 0x60, 0x14}} + info := bindataFileInfo{name: "templates/client/response.gotmpl", size: 10424, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb, 0x12, 0xba, 0xe0, 0x4e, 0x37, 0xb2, 0xf0, 0x5b, 0x83, 0xc4, 0x4c, 0x3c, 0x98, 0x58, 0x1a, 0x3c, 0xfb, 0x9a, 0x3b, 0x3c, 0x96, 0xf5, 0xbd, 0x93, 0x7d, 0xb4, 0xbc, 0xb5, 0xf4, 0xe, 0x57}} return a, nil } @@ -227,7 +233,7 @@ func templatesContribStratoscaleClientFacadeGotmpl() (*asset, error) { return a, nil } -var _templatesContribStratoscaleServerConfigureapiGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\xdf\x6f\xe3\xb8\xf1\x7f\xb6\xfe\x8a\xf9\x0a\xdf\x02\x52\xe0\xc8\x40\x1f\xb7\xf0\x83\x6f\x73\xd7\x73\xaf\x97\x18\x9b\xb4\xf7\x50\x14\x05\x43\x8d\x65\x36\x32\xa9\x25\xa9\x24\x5e\x43\xff\x7b\x31\xfc\x61\xcb\xb6\xbc\x71\x90\x2b\xd0\x7d\xd8\x58\xe2\xcc\xf0\x33\x9f\x19\x0e\x47\x33\x99\xc0\x67\x55\x22\x54\x28\x51\x33\x8b\x25\x3c\x6e\xa0\x52\xd7\xe6\x85\x55\x15\xea\x3f\xc1\xcd\x1d\xdc\xde\x3d\xc0\x8f\x37\xf3\x87\x22\x49\x92\xed\x16\xc4\x12\x8a\xcf\xaa\xd9\x68\x51\xad\x2c\x5c\x77\xdd\x64\x02\xdb\x2d\x70\xb5\x5e\xa3\xb4\x47\x6b\xdb\x2d\xa0\x2c\xa1\xeb\x92\x24\x69\x18\x7f\x62\x15\x92\x70\x31\x5b\xcc\x17\xe1\x91\xd6\xc4\xba\x51\xda\x42\x96\x8c\x52\xae\xa4\xc5\x57\x9b\xd2\x4f\xbd\x69\xac\x9a\xd8\xda\xd0\x93\x44\x3b\x59\x59\xdb\xd0\xef\x5a\x55\xf4\x67\xb9\xb6\x69\x92\x8c\xd2\x4a\xd8\x55\xfb\x58\x70\xb5\x9e\x54\xea\x5a\x35\x28\x59\x23\x26\xa8\xb5\xd2\x4e\x75\x78\xbd\x56\xac\xfc\xce\xb2\x6e\xa5\x15\x6b\x7c\x53\x60\xb2\x16\x65\x59\xe3\x0b\xd3\x17\xc8\x1a\xe4\xad\x16\x76\x93\x26\x09\x10\x11\xde\x71\x03\xc5\x0d\x2e\x59\x5b\xdb\x79\x78\xee\xba\xa3\xf5\xde\x42\x4e\x51\xf8\xff\xc8\xe6\xa7\x29\x14\x7d\x2a\xed\xa6\x41\x08\x24\xfe\x82\x1b\x30\x56\x0b\x59\x25\x09\x57\xd2\x58\x98\xb5\x76\x45\x6f\x7b\x02\x53\x48\xe9\x6d\xea\x82\xab\x99\xac\x10\x8a\xbb\x86\xb2\x41\x28\xf9\x67\xad\xda\xc6\x50\x24\x93\xc9\xa4\x52\x9f\x62\x9e\xc0\x5a\xf1\x27\xd4\x1b\xb8\x96\x6c\xed\x42\xda\x30\xc3\x59\x2d\xbe\x21\x14\xb7\x6c\x8d\x5d\x37\x5b\xcc\xe1\x5a\xc8\xe6\xa9\x4a\x92\xc9\xd5\x80\x08\x78\x19\x4a\x87\x1b\x34\x5c\x8b\x86\x76\x84\xae\x83\xab\x89\x77\xe3\xac\x8e\x90\x16\xf5\x92\x71\x84\xed\x10\x6a\x0f\x78\x14\x92\xf5\xbe\x5d\xaf\x19\x41\xa5\x77\xe7\x90\x38\x18\x51\xd2\x43\x20\x7d\xac\x0d\x3a\x23\x7d\x84\x6f\x1b\x3a\xf5\x67\x14\x4e\x42\x04\x76\xaa\x98\x71\xfb\x1a\xe3\x52\x7c\xf6\x7f\xc7\xd0\x30\xcd\xd6\x06\xb6\xdb\x18\xe4\xae\x2b\x06\xd5\x17\x4e\x30\x87\x7d\x36\x16\x5f\xd0\x34\x4a\x96\xa8\x5d\x68\xe3\xee\x5d\xd2\x3b\x94\xee\xfc\xcb\xa5\xa8\x40\x18\xda\x7c\x29\xaa\xd6\x73\x08\x4b\xa5\xe1\x67\x26\xcb\x1a\xb5\x8f\x46\x10\x34\x56\xb7\xdc\xc2\xd6\xb9\xf1\x9d\x7c\x19\xf6\x72\xb6\x98\x1f\x72\xf1\x57\x45\x85\x06\x96\xad\xe4\x99\xcf\xd5\x31\x14\x45\xb1\x8b\xf0\xb6\xcb\x93\xd1\x64\x02\x73\x29\x51\xff\xba\x73\x8e\xf0\x12\x42\xbb\x42\x58\x79\x94\x80\xaf\xc8\x5b\xab\xb4\x29\xe0\x61\x85\x06\xa1\x54\x20\x95\x05\xd6\x34\xf5\x06\xac\x72\xc2\xa1\xb2\x15\xff\x36\x4a\x42\xa9\x78\x4b\x55\xab\x70\x5b\x3c\xac\xb0\x47\x5f\x30\x87\x06\xd8\xd2\xa2\x06\xad\x5a\x2b\x64\x05\x8f\xad\x85\x47\x5c\x2a\x8d\xc0\x5a\xbb\x42\x69\x05\x77\xbe\x8f\xe1\x51\xc8\x92\x44\x98\x2c\xe1\x99\xd5\xa2\x74\xef\x93\xd1\x31\x76\xe7\x2c\xd5\xb2\x22\x10\x9c\x43\xff\x29\x71\x68\xe8\x50\x2a\x2d\xbe\xa1\x26\x5f\x5b\x83\x25\xb9\xc0\xe2\x5b\x60\xa0\xf1\x6b\x8b\xc6\x06\x7c\xe4\x1c\xe9\x38\xeb\x2e\x82\x2f\xcc\x00\x67\x75\x8d\x25\xb4\x86\x70\x91\x88\x3b\xec\x57\xe9\x4e\xca\xb8\xcd\x08\x31\xad\x36\x5a\x48\x2e\x1a\x56\x3b\x65\x63\x95\xc6\x12\x84\x74\x6b\x21\x37\xe3\x63\x1a\x6a\x49\xba\x5b\x78\x66\x75\x8b\x45\x32\xea\x21\x77\x9e\x5e\x39\xe7\xbe\x78\xb4\x39\xb8\xba\x9c\xf4\xd3\xe7\x3e\x54\xc5\x1b\x5c\x0a\x29\x4e\x4f\xf0\xdc\xfc\xc0\x8c\xe0\xce\x3b\x7f\xf8\x3c\x3d\x87\x19\x36\xbf\xa1\xb3\x46\x49\xf1\x48\xd2\x47\xd1\xf1\xb0\x06\x35\x08\x63\x6b\x50\x43\xcc\xbf\x86\x19\x13\x1e\x72\xc8\x7a\xa9\x38\xf6\xe0\xf3\x93\xe3\xec\x51\xce\x16\xf3\x5f\x70\x73\x11\xcc\x59\xd3\xd4\x02\x0d\xbc\xac\x30\xd0\x49\x75\x23\x1c\x92\xd4\x57\x23\xd5\x6a\xee\x4a\x8a\x30\x60\xd0\xbe\xe1\x81\x55\x4f\x28\x2f\x43\x7d\x00\xfa\x8e\xac\xfe\xf1\x4d\xc0\x3f\x29\x0d\x41\xf4\x5d\xc4\xf6\x61\x8d\xc1\x70\xd5\xa0\x81\x7f\xfc\xf3\x5d\xec\xc6\xdf\x3b\x80\x61\x77\x3a\xff\x8a\x8e\x86\x8b\x3a\xab\x6b\xf0\x11\x38\x45\xb8\x0b\xcc\x5e\xf3\xa0\xe2\xec\xfe\x86\x4c\x2c\x1e\x08\xf6\xec\xc0\x4c\x0e\xe1\x16\x2f\x0e\x0c\xbd\x0d\xea\x07\x64\x1a\xf5\x09\xa8\x5d\x4e\x1f\x63\x8a\x18\xfe\x66\x50\x2f\x98\x31\xbf\x17\x8c\xc1\x53\xe1\xc1\x7d\x8f\x9a\x08\xe7\x9e\x62\x57\xbe\x83\x18\x7f\xbf\x84\xa2\x06\x1a\x6d\xab\xa5\x01\x26\x0f\x8a\x1d\x54\xe2\x39\x1c\x81\x58\xc7\x0f\xee\x21\x32\x31\xb7\xb0\x56\xad\xb4\xc6\xf9\x41\xa2\x8f\x54\xd0\xd0\x18\xa8\x55\x25\x38\xb5\x49\x35\x52\x21\x47\x6d\x62\x7d\xf2\x3d\x68\xa8\xda\x45\x42\x3e\x45\x2c\x19\x0f\x97\x59\x0e\x07\x65\x38\x26\x20\x5d\x6e\xab\x31\xfc\xcb\x3d\x53\x87\x15\xd6\x67\x8b\x79\xc6\xf3\x64\xe4\x5d\x81\x95\x5b\x3f\x74\x93\xba\x93\x0f\x78\x1a\xeb\x30\x57\x5a\xfb\xdb\x9b\xea\xf6\xd5\x70\xa7\x21\xa4\xb1\x4c\x72\x2c\xfe\x1b\x1c\x39\x5f\xcf\xd1\x74\xf5\x76\x3f\x32\x5b\xcc\xfb\x74\x9a\x06\xf9\x8e\x4e\xd7\x79\x17\x33\xc9\xea\xcd\x37\x2c\xb3\x70\x25\xd3\x87\x43\x76\xef\x7f\xff\xe5\xfe\xee\x36\x1f\x43\x9a\xe6\xc9\x48\x2c\x9d\xde\xff\x4d\x41\x8a\x9a\x6c\x45\xfe\xa5\xa8\xc7\xfe\xbf\xe5\xda\x16\x3f\xd2\x5e\xcb\x2c\x65\xde\x6c\xbc\xe8\x3f\xc1\x1f\x9e\x53\xb7\x73\x9e\x8c\xba\x64\xc4\x1a\x41\x10\x0e\x1c\xb8\xc5\x97\x73\x3e\x64\x04\x3c\x77\x6a\xc5\x3d\xea\x67\x74\xdb\xc0\xd4\xbb\x66\x7a\xef\xbc\x4c\x68\x67\xa6\xc0\xc3\xcf\xc4\x39\xc0\x8b\xa1\x12\xd4\x73\x89\x74\x87\x44\xa6\xc3\xaa\xce\x15\x67\x77\xa0\x8a\x1c\xdb\x1d\x12\x99\x0e\xaa\xf6\xcc\x0e\x94\x85\x13\xbb\x43\x32\xd3\x61\x65\xb2\xdc\xbf\xf2\x3f\x2b\x69\xda\x35\x1e\xdd\xf3\x31\x45\xd9\xbe\xcf\xa6\x8d\x06\x83\x13\x2c\x10\x45\x74\x5b\x1e\xe9\xc6\x9b\x83\xfa\xf7\x4b\xcd\xc4\x2a\x16\x5f\xfd\x44\x65\xd0\xd5\x42\x0d\x42\x15\x5f\x90\x95\x94\xfc\x96\xe9\x0a\x2d\xf4\x3b\x54\x9f\x0d\xfd\xdc\x0c\xe9\x71\xab\xec\x0e\x18\x96\x59\xba\xdd\x86\xaf\x23\x3a\xfa\x7e\xdf\x15\x33\xae\x4b\xdd\x20\xf5\x95\x28\x7b\x07\xb5\xa4\xf4\xef\xce\xdf\x87\x3d\x3e\x17\x5a\x95\x2d\xff\x08\x9f\xc1\xc2\x05\x7c\x5e\x6c\x27\x12\x1a\x5f\xed\x09\x7d\x21\x42\x7f\xd3\xc2\x12\xa1\x25\xb3\xec\xa3\x74\x36\x71\xd7\x0f\xd0\xf9\xa1\x96\xf4\x94\x0f\xd7\x04\x39\x81\xe9\x9b\x3d\xe6\x76\x2b\x96\x0e\x76\x06\xf8\x95\xa2\x19\xdb\xf0\xb4\xc7\x4b\x0a\x79\xd7\x5d\xed\x7a\x38\x2a\x61\x51\xae\xeb\x7a\xc5\x16\xc2\x3f\x5f\x77\xce\x34\x67\xd3\x78\x96\xa1\xf7\x2f\xb0\x9d\xa6\xae\xae\xee\x96\xba\x7d\x20\xce\x1a\x74\xde\x79\xb7\x7c\xa1\xbd\xa8\x43\xbe\x80\xb5\xa3\xbe\xf6\x77\x65\x6a\x74\x39\x4d\xa3\x23\x8e\x1c\x2c\x4f\xd3\xe8\x62\x8e\x9c\xd2\x01\x3d\x67\x5b\xf1\x77\x32\x33\xd4\x5a\xff\x6f\x25\x55\x8f\xb0\x77\xe5\x55\xd0\xf3\xee\x0d\xa6\xd6\xc1\xf9\x75\x13\x9f\x73\x87\x37\xdc\xb2\xbd\x0f\xd4\xe9\xfe\x8b\x5a\x67\x1e\x84\x7f\xc8\xcf\x96\x86\xe3\x31\x93\x8f\x14\x51\x8d\xfb\x51\x5c\x9c\xcf\x11\xa3\x3d\x97\x16\xfb\xb7\x28\x4b\x37\x1f\x3d\xad\xa0\xb1\x5f\x9c\x3a\xa2\xb6\xdb\xeb\x9d\xde\xac\x16\xcc\xc0\xb9\x96\x2b\xe8\xed\xab\xec\xc9\xf0\xc8\xe9\x7f\x7f\x82\xe4\x3c\xd9\xf3\x50\x52\x12\xec\xa7\x02\xbd\xc4\x09\x1e\x0c\x4f\x9c\x5c\xed\xe6\xf6\x95\x5a\x2d\x8f\xa2\xf8\xf9\xe1\x61\x11\x66\x00\x71\xbc\x95\xe5\xc9\x28\xc6\x6c\xbf\xa3\x67\xd5\x69\x4f\xfd\x08\x82\xd6\x32\x6e\x5f\x7b\x48\x82\xe6\x2e\x0d\xf6\x79\x34\xcc\xf7\x6c\x31\x3f\x5c\xf1\xf7\x46\xb0\xea\x67\x67\x27\x97\x43\xaf\xed\xd3\xf7\xab\xd6\x96\xea\x45\xc6\xc3\x97\xc3\xd6\x25\x70\xd8\x77\x27\x98\xf1\xe2\x68\xdc\x93\x8f\x69\xd5\x67\xbe\xff\x56\xe8\x35\xbc\xc0\x55\x23\xd0\xf4\x47\x53\xe0\x46\x53\x56\x41\xa3\xf1\x19\xa5\xf5\xf7\xa3\x66\x74\xbb\x0b\x19\x2f\x55\xdf\xac\xf7\x5b\x67\xa5\x45\xe5\x74\x8b\x2f\xec\xe5\x57\x34\x86\x55\x98\x1f\xbf\xa0\xc0\x70\x8a\xca\x9a\x3d\x61\x76\xb4\x38\x86\x1a\xa5\xb3\x93\xe7\xc9\x88\x93\x51\x3e\x06\xf7\xbc\x73\x94\x07\x1f\xd8\xc1\x78\x8a\xc1\x0a\xeb\x26\x0c\x7c\x5c\xc3\x60\xd5\xfe\xe6\xf5\xdf\x1a\xbd\x6f\xc4\xa8\x18\xb3\xa9\xf0\x13\x46\x76\xd1\xe0\xc8\x39\x9e\xb1\x9e\x74\xbe\x1f\x96\x65\x1a\xbf\xc2\x81\xde\x99\xf4\xed\x35\x19\x62\x09\xac\x57\xe8\x7b\x9f\x17\xae\xda\x84\x34\xde\x67\xa2\xc6\xaf\xfb\x0c\x3e\xcc\xc9\x98\x0d\x4e\xe6\x37\x61\x57\x51\x8e\xdb\xd7\x3c\x27\xea\x7c\xd8\xfa\x59\x3d\x30\xf4\x1d\x06\x7c\x24\x47\x58\x63\x50\xc2\x0a\xed\xf8\x77\x56\xb7\xe8\xf3\x3a\x4c\xe8\x0e\x20\x76\xc9\x7f\x02\x00\x00\xff\xff\xf4\x62\xb6\x58\xf4\x19\x00\x00") +var _templatesContribStratoscaleServerConfigureapiGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x59\x5f\x6f\xe3\xb8\x11\x7f\xb6\x3e\xc5\x54\x68\x01\x2b\x70\x64\xa0\x8f\x5b\xf8\xc1\xb7\xb9\xeb\xb9\xd7\xcb\x1a\x9b\xb4\xf7\x50\x14\x05\x43\x8d\x65\x36\x32\xa9\x25\xa9\x24\x5e\x43\xdf\xbd\x18\xfe\xb1\x64\x5b\xde\x78\x2f\xb7\xe8\xed\xc3\x5a\x12\x67\x86\xf3\x9b\x7f\x1c\x4e\xa6\x53\x78\xaf\x0a\x84\x12\x25\x6a\x66\xb1\x80\x87\x2d\x94\xea\xda\x3c\xb3\xb2\x44\xfd\x17\xb8\xf9\x00\xb7\x1f\xee\xe1\xfb\x9b\xc5\x7d\x9e\x24\xc9\x6e\x07\x62\x05\xf9\x7b\x55\x6f\xb5\x28\xd7\x16\xae\xdb\x76\x3a\x85\xdd\x0e\xb8\xda\x6c\x50\xda\xa3\xb5\xdd\x0e\x50\x16\xd0\xb6\x49\x92\xd4\x8c\x3f\xb2\x12\x89\x38\x9f\x2f\x17\xcb\xf0\x4a\x6b\x62\x53\x2b\x6d\x61\x9c\x8c\x52\xae\xa4\xc5\x17\x9b\xd2\xa3\xde\xd6\x56\x4d\x6d\x65\xe8\x4d\xa2\x9d\xae\xad\xad\xe9\xb9\x52\x25\xfd\xac\x36\x36\x4d\x92\x51\x5a\x0a\xbb\x6e\x1e\x72\xae\x36\xd3\x52\x5d\xab\x1a\x25\xab\xc5\x14\xb5\x56\xda\xb1\x0e\xaf\x57\x8a\x15\x5f\x58\xd6\x8d\xb4\x62\x83\xaf\x12\x4c\x37\xa2\x28\x2a\x7c\x66\xfa\x02\x5a\x83\xbc\xd1\xc2\x6e\xd3\x24\x01\x32\x84\x07\x6e\x20\xbf\xc1\x15\x6b\x2a\xbb\x08\xef\x6d\x7b\xb4\xde\x5b\xc8\xc8\x0b\x7f\x8c\xd6\x7c\x37\x83\xbc\x6f\x4a\xbb\xad\x11\x82\x11\x7f\xc2\x2d\x18\xab\x85\x2c\x93\x84\x2b\x69\x2c\xcc\x1b\xbb\xa6\xaf\x3d\x82\x19\xa4\xf4\x35\x75\xce\xd5\x4c\x96\x08\xf9\x87\x9a\xa2\x41\x28\xf9\x57\xad\x9a\xda\x90\x27\x93\xe9\xb4\x54\xef\x62\x9c\xc0\x46\xf1\x47\xd4\x5b\xb8\x96\x6c\xe3\x5c\x5a\x33\xc3\x59\x25\x3e\x23\xe4\xb7\x6c\x83\x6d\x3b\x5f\x2e\xe0\x5a\xc8\xfa\xb1\x4c\x92\xe9\xd5\x00\x09\x78\x1a\x0a\x87\x1b\x34\x5c\x8b\x9a\x76\x84\xb6\x85\xab\xa9\x87\x71\x96\x47\x48\x8b\x7a\xc5\x38\xc2\x6e\x48\x6b\xaf\xf0\x28\x04\xeb\x5d\xb3\xd9\x30\x52\x95\xbe\x9d\xd3\xc4\xa9\x11\x29\xbd\x0a\xc4\x8f\x95\x41\x27\xa4\xaf\xe1\xeb\x82\x4e\xf1\x8c\x42\x26\x44\xc5\x4e\x19\xc7\xdc\xbe\x44\xbf\xe4\xef\xfd\xef\x04\x6a\xa6\xd9\xc6\xc0\x6e\x17\x9d\xdc\xb6\xf9\x20\xfb\xd2\x11\x66\xd0\x45\x63\xfe\x11\x4d\xad\x64\x81\xda\xb9\x36\xee\xde\x26\xbd\xa4\x74\xf9\x2f\x57\xa2\x04\x61\x68\xf3\x95\x28\x1b\x6f\x43\x58\x29\x0d\x3f\x32\x59\x54\xa8\xbd\x37\x02\xa1\xb1\xba\xe1\x16\x76\x0e\xc6\x17\xe2\x65\x18\xe5\x7c\xb9\x38\xb4\xc5\xdf\x15\x15\x1a\x58\x35\x92\x8f\x7d\xac\x4e\x20\xcf\xf3\xbd\x87\x77\x6d\x96\x8c\xa6\x53\x58\x48\x89\xfa\xe7\x3d\x38\xd2\x97\x34\xb4\x6b\x84\xb5\xd7\x12\xf0\x05\x79\x63\x95\x36\x39\xdc\xaf\xd1\x20\x14\x0a\xa4\xb2\xc0\xea\xba\xda\x82\x55\x8e\x38\x54\xb6\xfc\xbf\x46\x49\x28\x14\x6f\xa8\x6a\xe5\x6e\x8b\xfb\x35\xf6\xcc\x17\xc4\xa1\x01\xb6\xb2\xa8\x41\xab\xc6\x0a\x59\xc2\x43\x63\xe1\x01\x57\x4a\x23\xb0\xc6\xae\x51\x5a\xc1\x1d\xf6\x09\x3c\x08\x59\x10\x09\x93\x05\x3c\xb1\x4a\x14\xee\x7b\x32\x3a\xd6\xdd\x81\xa5\x5a\x96\x07\x03\x67\xd0\x7f\x4b\x9c\x36\x94\x94\x4a\x8b\xcf\xa8\x09\x6b\x63\xb0\x20\x08\x2c\x7e\x05\x06\x1a\x3f\x35\x68\x6c\xd0\x8f\xc0\x11\x8f\x93\xee\x3c\xf8\xcc\x0c\x70\x56\x55\x58\x40\x63\x48\x2f\x22\x71\xc9\x7e\x95\xee\xa9\x8c\xdb\x8c\x34\xa6\xd5\x5a\x0b\xc9\x45\xcd\x2a\xc7\x6c\xac\xd2\x58\x80\x90\x6e\x2d\xc4\x66\x7c\x4d\x43\x2d\x49\xf7\x0b\x4f\xac\x6a\x30\x4f\x46\x3d\xcd\x1d\xd2\x2b\x07\xee\xa3\xd7\x36\x03\x57\x97\x93\x7e\xf8\xdc\x85\xaa\x78\x83\x2b\x21\xc5\x69\x06\x2f\xcc\x77\xcc\x08\xee\xd0\xf9\xe4\xf3\xe6\x39\x8c\xb0\xc5\x0d\xe5\x1a\x05\xc5\x03\x51\x1f\x79\x27\x81\xf3\x2c\xa4\x64\x63\x50\x43\x0c\xc0\x9a\x19\x13\x5e\x32\x18\x07\x2d\x96\xd1\x36\x0b\x73\xdb\x54\x15\x7b\xa8\x28\xa0\xaf\xf6\xd9\x44\x89\xbf\xa7\x81\xb6\x9d\x78\xa4\xd9\x49\xee\x7b\x48\xf3\xe5\xe2\x27\xdc\x5e\x84\x69\x5e\xd7\x95\x40\x03\xcf\x6b\x0c\xb6\xa7\xbd\x42\x46\xa5\xbe\x74\xa9\x46\x73\x57\x7f\x84\x01\x83\xf6\x35\xb8\x56\x3d\xa2\xfc\xed\x21\x1e\x20\xfc\x40\x1a\xfc\xf9\x55\x74\x3f\x28\x0d\x81\xf4\xeb\x5c\xd6\xc7\x30\x01\xc3\x55\x8d\x06\xfe\xf5\xef\x6f\xe6\xb7\xf8\xbc\x47\x13\x54\xa5\x32\xa4\x28\x43\x5d\xf0\xb1\xaa\x02\xef\xdb\x63\x38\xa3\xce\xe5\x1d\xe7\x41\xe1\xdb\xff\x86\x84\xc8\xef\x09\xe2\xfc\x40\x4c\x06\xa1\x99\xc8\x0f\x04\xbd\xae\xd4\x77\xc8\x34\xea\x13\xa5\xf6\xa9\x75\xac\x53\xd4\xe1\x1f\x06\xf5\x92\x19\xf3\x5b\xa9\x31\x94\x9c\x23\xaf\xdc\x97\x4c\x13\xd5\xb9\x23\x3f\x17\x5f\x61\x18\x7f\xcc\x85\xda\x0a\x1a\x6d\xa3\xa5\x01\x26\x0f\x6a\x2e\x94\xe2\x29\x24\x57\x3c\x4e\x0e\x8e\x43\x12\xb1\xb0\xb0\x51\x8d\xb4\xc6\xe1\x20\xd2\x07\xaa\xab\x68\x0c\x54\xaa\x14\x9c\xba\xb5\x0a\xe9\x3c\x41\x6d\x62\x99\xf4\xad\x70\x38\x3c\xf2\x84\x30\x45\x5d\xc6\x3c\x9c\xa9\x19\x1c\x9c\x06\x31\x00\xe9\x8c\x5d\x4f\xe0\x3f\xee\x9d\x1a\xbd\xb0\x3e\x5f\x2e\xc6\x3c\x4b\x46\x1e\x0a\xac\xdd\xfa\x21\x4c\x6a\x92\xde\x80\x34\x1e\x07\x5c\x69\xed\x9b\x08\x3a\x3e\xae\x86\x1b\x1e\x21\x8d\x65\x92\x63\xfe\x2d\x6c\xe4\xb0\x9e\x33\xd3\xd5\xeb\x6d\xd1\x7c\xb9\xe8\x9b\xd3\xd4\xc8\xf7\xe6\x74\x17\x80\x7c\x2e\x59\xb5\xfd\x8c\xc5\x38\x74\x06\x74\x7f\x19\xdf\xf9\xe7\xbf\xdd\x7d\xb8\xcd\x26\x90\xa6\x59\x32\x12\x2b\xc7\xf7\x87\x19\x48\x51\x91\xac\x68\x7f\x29\xaa\x89\xff\x6f\xb5\xb1\xf9\xf7\xb4\xd7\x6a\x9c\x32\x2f\x36\xf6\x1b\xef\xe0\x4f\x4f\xa9\xdb\x39\x4b\x46\x6d\x32\x62\xb5\x20\x15\x0e\x00\xdc\xe2\xf3\x39\x0c\x63\x52\x3c\x73\x6c\xf9\x1d\xea\x27\x74\xdb\xc0\xcc\x43\x33\xbd\x6f\x9e\x26\x74\x55\x33\xe0\xe1\x31\x71\x00\x78\x3e\x54\x82\x7a\x90\x88\x77\x88\x64\x36\xcc\xea\xa0\x38\xb9\x03\x55\xe4\x58\xee\x10\xc9\x6c\x90\xb5\x27\x76\xa0\x2c\x9c\xc8\x1d\xa2\x99\x0d\x33\x93\xe4\x7e\xe7\xf1\x5e\x49\xd3\x6c\xf0\xa8\xdd\x88\x21\xca\xba\x76\x9f\x36\x1a\x74\x4e\x90\x40\x26\xa2\x83\xe4\x88\x37\x9e\x1c\x74\x8d\xb8\x54\x4c\xac\x62\xf1\xd3\x0f\x54\x06\x5d\x2d\xd4\x20\x54\xfe\x11\x59\x41\xc1\x6f\x99\x2e\xd1\x42\xbf\x51\xf6\xd1\xd0\x8f\xcd\x10\x1e\xb7\xca\xee\x15\xc3\x62\x9c\xee\x76\xe1\x92\x46\xa9\xef\xf7\x5d\x33\xe3\x9a\xe5\x2d\x52\x7b\x8b\xb2\x97\xa8\x05\x85\x7f\x7b\xfe\x3c\xec\xd9\x73\xa9\x55\xd1\xf0\xb7\xd8\x33\x48\xb8\xc0\x9e\x17\xcb\x89\x06\x8d\x9f\x3a\x83\x3e\x93\x41\x7f\xd1\xc2\x92\x41\x0b\x66\xd9\x5b\xcd\x59\xc7\x5d\xdf\x60\xce\x37\x75\xc6\xa7\xf6\x70\x0d\x93\x23\x98\x5d\xd0\xe9\x5e\xd6\x30\x75\x24\x5d\xbb\x04\xbb\x04\x00\xc0\x57\x99\x33\x6d\xdb\x2c\x66\x2e\x51\xc2\x6e\x77\x4d\xe4\xf8\xa9\xdf\x7f\xa5\x3d\x0f\xa4\x7e\x0e\xe2\xff\x05\x17\xa4\xa9\x2b\xb6\x9d\x84\x98\x5b\x91\xae\x66\x52\xf0\x71\xba\x55\x0d\x50\xd1\x14\x2b\x81\x05\x30\xe0\x8d\xb1\x6a\xd3\xbb\xe0\xd0\x9d\x76\xe2\x6e\x73\x85\x28\x9c\xaf\x6a\xad\x9e\x44\x81\xee\x48\x62\xc7\x2d\x4c\xb7\x28\x4c\x9a\xf5\xb6\xf7\x5d\x2f\xbd\xb6\x5d\xa0\x9c\x35\x81\xb3\xbe\x37\xbb\x3f\x08\x2e\xba\x1b\x5c\xe0\xd5\x5f\xdb\xd0\x9f\x71\xe5\xe8\x1b\x78\x72\x74\xe0\x48\xa7\xf0\xef\xd2\x97\xa3\x0b\x5d\xe9\x10\x1c\x78\xf1\xec\xf5\xe7\x2b\x1d\xf8\xa6\xdb\xcc\xff\x31\x39\x7f\xbf\x3e\xbd\x38\x3f\x03\x04\x6f\xff\xc1\x14\x3d\xa8\xd3\x6e\xc0\x78\xae\x48\x87\x6e\xaa\x37\x0f\x99\x75\x03\x1c\x3d\xf6\x4a\xf8\x97\xec\xec\x11\x70\x3c\xd5\xf4\xa1\x24\x56\x20\xb1\x9b\xfc\xc6\x71\x30\xf9\xbf\x07\x69\xd9\x7d\x45\x59\xb8\xab\xee\xe9\x49\x19\xef\x05\xb3\xc4\x5b\x2c\x72\xcd\x2b\xc1\x0c\x9c\x6b\xac\x03\x57\x77\x96\x9e\x4c\x2a\x1d\xff\x97\xc7\x95\xfe\xbc\xd9\x5b\xa1\xa0\x80\xed\x22\xe0\x57\xde\xdf\x03\xd6\xe1\x51\xa8\x3b\xcd\xb9\x7d\xa1\xe6\xdb\x6b\x9c\xff\x78\x7f\xbf\x0c\xc3\xa9\x38\x77\x1d\x67\xc9\x28\x7a\xb7\xd3\xce\xdb\xdf\x71\xcf\xfc\x6c\x8c\xd6\xc6\xdc\xbe\xf4\xb4\x0e\x9c\xfb\x80\xe9\x22\x6e\xd8\x33\xf3\xe5\xe2\x70\xc5\x77\x12\x41\xaa\x1f\xea\x9e\xb4\x0b\xbd\x8b\x80\xbe\x5b\x37\xb6\x50\xcf\x32\xd6\x91\x0c\x76\x2e\xd4\xc3\xbe\x7b\xc2\x31\xcf\x8f\xe6\x90\xd9\x84\x56\x7d\xba\xfa\xdb\x63\xef\x0a\x04\x5c\xd5\x02\x4d\x7f\x66\x0a\x6e\x66\xea\x72\x0d\x9f\x50\x5a\xdf\x31\x69\x46\xfd\x9e\x90\xb1\xcd\xf2\xd7\xb7\xfe\x65\x4a\x69\x51\x3a\xde\xfc\x23\x7b\xfe\x19\x8d\x61\x25\x66\xc7\x1f\xc8\x31\x9c\xbc\xb2\x61\x8f\x38\x3e\x5a\x9c\x40\x85\xd2\xc9\xc9\xb2\x64\xc4\x49\x28\x9f\x80\x7b\xdf\x03\xe5\x01\x03\x3b\x98\x9b\x32\x58\x63\x55\x87\x49\xa4\x6b\x21\xad\xea\x7a\x31\x7f\xfb\xec\x4d\x0d\x22\x63\x2c\x73\xb9\x1f\x7d\xb3\x8b\x26\x9a\x0e\xf8\x98\xf5\xa8\xb3\x6e\x8a\x3b\xd6\xf8\x09\x0e\xf8\xfa\xa1\x3e\xdc\x76\x8a\x15\xb0\xae\x2c\xf7\x2f\x9c\xae\x2e\x85\x30\xee\x22\x51\xe3\xa7\x2e\x82\x0f\x63\x32\x46\x83\xa3\xf9\x45\xd8\x75\xa4\xe3\xf6\x25\xcb\xc8\x74\xde\x6d\xfd\xa8\x1e\xf8\x6b\xc4\xb0\xc2\x47\x74\xa4\x6b\x74\x4a\x58\xa1\x1d\xff\xc9\xaa\x06\x7d\x5c\x87\xd1\xf1\x81\x8a\x6d\xf2\xbf\x00\x00\x00\xff\xff\x39\x41\x01\xca\x8d\x1c\x00\x00") func templatesContribStratoscaleServerConfigureapiGotmplBytes() ([]byte, error) { return bindataRead( @@ -242,8 +248,8 @@ func templatesContribStratoscaleServerConfigureapiGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/contrib/stratoscale/server/configureapi.gotmpl", size: 6644, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x40, 0xda, 0x58, 0x57, 0x11, 0x3a, 0xc4, 0x3e, 0x12, 0x28, 0x47, 0xd7, 0x99, 0x62, 0xa, 0xad, 0x1c, 0x36, 0x53, 0xbb, 0x8a, 0xae, 0x4d, 0x9f, 0x56, 0x4f, 0x73, 0x34, 0x5a, 0xca, 0x14, 0xb2}} + info := bindataFileInfo{name: "templates/contrib/stratoscale/server/configureapi.gotmpl", size: 7309, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x21, 0xaa, 0xda, 0xe4, 0xfd, 0x5f, 0x38, 0xb4, 0x7b, 0x3a, 0xca, 0x25, 0xf8, 0x94, 0xfa, 0xb1, 0x12, 0x89, 0x82, 0x14, 0xfd, 0xe, 0x38, 0xa7, 0xdc, 0x74, 0xb2, 0xc2, 0x3e, 0x4, 0x31, 0x6f}} return a, nil } @@ -267,7 +273,7 @@ func templatesContribStratoscaleServerServerGotmpl() (*asset, error) { return a, nil } -var _templatesDocstringGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x8e\x41\xae\x83\x30\x10\x43\xf7\x9c\xc2\x62\xff\xc9\x25\xfe\xba\xab\x5e\x00\x25\xa6\x1d\x89\x4c\x2a\x92\x6e\x3a\xe2\xee\x15\x8a\x5a\x22\xca\x6e\x64\x3f\xdb\x63\x86\xc0\x49\x94\xe8\x43\xf2\xb9\x2c\xa2\xb7\x1e\xeb\xda\x01\x66\x7f\x90\x09\xc3\x55\xca\xcc\x2a\x55\xd1\xa7\x18\xa9\xe5\xc4\xd9\xf0\x7f\x66\xbf\xc8\xa3\x48\xd2\xcd\x72\xae\x73\x0e\x66\x7b\xea\x00\x7c\xb2\xd4\xb0\xef\x72\xce\x3c\xb6\x9d\x7d\xf0\xd3\xf5\x0d\x37\xf4\xfd\x19\x47\x95\x17\x31\x5c\xc6\xc8\x86\xab\x8b\xcd\xf9\x0e\x00\x00\xff\xff\x57\x05\xa1\xd1\x0e\x01\x00\x00") +var _templatesDocstringGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x91\xb1\x6e\xc4\x20\x0c\x86\xf7\x3c\x85\x95\xbd\xb0\x77\x6e\xc7\x54\x1d\xfa\x02\x28\x71\x5a\x4b\xc1\x20\xa0\x52\x74\x28\xef\x7e\xe2\xb8\xbb\x70\xc0\x16\xec\xcf\x1f\xf9\x4d\x8c\xb0\xe0\x4a\x8c\x30\x2e\x66\xf6\xc1\x11\xff\x8e\x70\x1c\x03\x40\x8c\x6f\x40\x2b\x88\x1f\x0a\x1b\xe6\x52\x2e\xce\x46\x6b\xe4\xd0\xe9\x24\xfc\x03\xfd\xec\xc8\x06\x32\x9c\x5a\x52\x0e\x52\x42\x8c\xe7\x54\x05\x3c\x66\x91\x97\xf3\x5e\xdc\x3c\xd6\xb6\xde\x1f\x34\xae\xe7\x70\x41\xff\xfd\x6b\xc5\x74\x41\x10\x5f\x4a\x63\xc1\x95\x37\xd2\x0a\xc6\x81\x98\x88\xbf\x9d\xb1\xe8\x02\xa1\xaf\x8f\x39\x4e\x19\xb6\xd3\x87\x89\x18\xce\xe2\x7b\xca\xde\x72\x4d\xea\xc2\xa9\xf6\xd6\xa9\xf6\xd6\x59\x73\xfd\x4d\x56\x21\xc5\xe7\xae\xb4\xcd\xcf\x26\x25\xdc\x4f\x37\xa3\x75\x94\x76\x5a\x00\x2f\x8a\xe2\xf3\x1a\x00\x00\xff\xff\x86\x40\x49\xf2\x36\x02\x00\x00") func templatesDocstringGotmplBytes() ([]byte, error) { return bindataRead( @@ -282,8 +288,8 @@ func templatesDocstringGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/docstring.gotmpl", size: 270, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1d, 0x3e, 0x50, 0x87, 0x7e, 0xc7, 0xce, 0xf0, 0x64, 0xaf, 0x8f, 0xab, 0x38, 0x17, 0xd1, 0xd7, 0x49, 0x9, 0xe4, 0x59, 0xa4, 0xdd, 0x14, 0x7b, 0x7b, 0xa3, 0x65, 0xb9, 0xe6, 0xf6, 0xa1, 0x23}} + info := bindataFileInfo{name: "templates/docstring.gotmpl", size: 566, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x47, 0x8, 0xf2, 0xcc, 0x14, 0x7c, 0x30, 0xa, 0x46, 0x12, 0xc8, 0xf, 0x70, 0xff, 0xf5, 0x47, 0x24, 0xbf, 0xfa, 0x98, 0x17, 0x3e, 0xa4, 0xbd, 0x1c, 0x9a, 0xc, 0x3c, 0x91, 0xa9, 0xbf, 0x5e}} return a, nil } @@ -307,6 +313,26 @@ func templatesHeaderGotmpl() (*asset, error) { return a, nil } +var _templatesMarkdownDocsGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\xdd\x6e\xdb\x38\x16\xbe\xd7\x53\x1c\x38\x5d\x20\x16\x26\x69\xb1\x97\xc1\x4c\x81\x4c\xd3\x1f\x03\xcd\x26\x9b\xb4\x7b\x93\x2d\x10\x56\xa2\x63\xb5\x92\xa8\x92\x74\x27\xae\x9d\xa7\xd8\xdb\x7d\xba\x7d\x92\x05\xff\x7f\x44\xc9\x4e\x27\x9d\x29\x06\xed\xc5\xc4\x22\x0f\x0f\xc9\x73\xbe\xf3\x2b\xcd\x7a\x7d\x00\x25\x9e\x57\x2d\x86\x09\xbe\xe5\x98\xb6\xa8\x3e\x21\xc5\x04\xee\xee\xd6\xeb\xc7\x39\x50\xdc\x96\x98\x32\x30\x73\x50\x92\x62\xd9\xe0\x96\x23\x5e\x91\x16\xf2\xc7\x77\x77\x19\x80\xe0\xf2\x5b\xc5\x17\x70\xf8\xdc\xf1\x60\x20\xe7\xd4\x6c\x35\x87\xc3\xb7\x17\xaf\xcd\x90\x1b\x3c\xc1\xac\xa0\x55\x27\xb9\xdd\xdd\x65\x4f\xe1\x6a\xbd\x06\x4e\xab\xe6\xb2\x43\x05\x8e\xe7\xdf\xed\xaf\xd7\x86\xd1\xd4\xe3\x84\x6b\x86\xf5\xf2\x0b\x8c\x4a\x68\x08\xc5\x83\xb4\x6d\xe9\x9f\xcc\x2d\x1d\xdb\x38\xeb\xad\xf6\x1e\xbc\x9f\x99\x2f\xd0\x92\x14\xe7\x88\xa2\xa6\x27\x4d\x04\x9d\x18\xc7\x1c\x53\x25\x37\x56\x35\x5d\x8d\x81\x15\x0b\xdc\x20\x25\xd5\x8d\x38\xcf\xe1\x3f\x50\x23\x4e\x07\x1b\xb8\x16\x8f\xaf\x49\x81\xf4\x89\xae\x41\x52\x48\x46\x27\xa4\x78\xb3\xea\x30\x1c\x7a\xa4\x2f\x89\x1c\xb2\x84\x42\xd8\xcf\x48\x5d\xe3\x42\x30\x78\x41\x68\x83\xb8\x98\x5d\xaf\x85\x4e\x7b\x33\x7d\xda\xc3\x67\x8b\xaa\x2e\xf5\x12\x75\x5d\xc7\xf9\x02\x7f\x5a\x56\x14\x8b\xc1\xff\xfd\xf7\x3f\x09\x82\x13\x3c\x47\xcb\xda\xec\xf8\x81\x91\x36\x1e\xf3\x57\x0c\xea\x01\x36\x63\xd2\x3e\x25\x25\xae\x2f\xa5\x10\x13\x32\xf7\xa5\xeb\x00\x38\x63\xc7\x94\xa2\x55\x0c\xd6\x19\x3b\xae\x2b\xc4\xb0\xd2\xf6\x95\xdc\x88\x92\xee\x1c\x15\x1f\xd1\x0d\xf6\xc4\xfb\x6e\x7f\x4f\x88\x10\xb1\x05\xa6\xd5\x17\x0c\xfb\x09\xb2\x29\x1c\x18\x0c\x5a\xc8\xc9\x4d\x38\x6e\x58\xcf\x26\x50\x5b\xea\xa9\xc3\x19\x3b\xa7\x55\x53\xf1\xea\x33\x86\xfd\x96\x70\x37\xae\x4f\x27\x39\x67\x72\xa5\xba\x9e\x83\xc2\x41\xc0\x57\xee\x29\x87\xae\xde\xf5\x6f\xa3\xb8\xee\x78\x27\x9f\xd8\xbb\x99\x33\x89\x83\xd8\xbc\xf4\xbe\xa8\x5d\x09\xc4\xd2\xaa\xe5\x73\x98\xc0\x24\x24\xb4\x0b\x7d\x11\x29\x59\xb0\x53\xd4\x99\xfb\xb3\xe3\xb2\xac\x04\x1a\x50\x7d\x4e\x49\x87\x29\xaf\x30\x9b\x06\xac\x42\xfd\x1d\x7c\x43\x05\x3e\xaf\x71\xa3\xd9\x24\x74\x68\x66\x13\x6a\xf4\xa6\xac\x26\x7b\x33\xb3\x96\x63\x3a\x47\x05\xb6\x5a\x76\x4a\x3e\x45\xdd\xb0\x9e\xfd\xa3\xf9\x7c\x14\x6d\x83\x3a\x20\xe2\x88\x03\xda\x88\x15\xa7\xe9\xfb\x22\xb4\x5b\xec\x28\xcb\x88\xfe\x1e\xd8\xd9\x76\xe4\xad\x00\x32\x60\x48\x59\x14\xbb\x5c\x76\x98\x4a\x0a\x25\xe8\x0d\x48\xb7\xbb\x01\x79\xab\x0d\xbc\x24\xc0\xd5\x2f\xe3\xb1\xc4\x2f\xe7\x96\x36\xf0\xfc\x16\x49\x07\xbe\xc9\x36\x07\xf2\x5f\xf8\x47\xfc\x02\xfd\x03\xdc\x58\x44\xd1\x73\xf9\xbe\xbe\xad\x7f\x57\x44\xfa\x3e\x5a\xec\xf7\x77\xb3\xdb\xbc\xac\xe1\x67\x2e\xa6\xd6\x46\x8f\xc6\x63\x67\x9e\x52\xfe\xdd\x4e\xa0\xa7\x04\x42\x61\x3f\x52\x84\x94\xfd\xfe\x90\x39\x4f\xa7\x76\xc1\x33\x22\x76\xbc\x3d\x7b\xff\x01\x17\x5c\xab\xcc\x37\x7c\x35\x72\x5c\xd7\x67\xf3\xa9\x52\xdf\x43\xd9\x7a\x02\x46\xce\x92\xac\x37\x0a\xad\x57\xba\x2a\x75\x0c\xd4\xae\xb2\x18\xc7\x1a\xaa\x14\xb5\x62\x3f\x79\xe8\x7e\x4a\x34\x63\xc7\x2d\x69\x57\x0d\x59\xca\xd8\x90\x43\xd5\xd6\x55\x8b\x4b\x68\x70\xf3\x1e\x53\xd8\xcf\x3d\x98\xe4\x53\x11\x05\x81\xe3\xa6\xab\x11\x4f\x84\xc1\x43\x48\xfa\x07\x42\xfb\xc2\x0d\x8c\x43\xee\x5c\x90\xa6\x23\x42\x5d\x12\xff\x0f\xe7\x44\xc3\xd4\x2b\x87\x7b\xdd\x20\xca\xdf\xc2\x47\x21\x40\x07\x0f\x99\x24\xe4\xb9\x06\xf3\x8c\xbd\x59\x2a\xf4\xaa\xbf\x4a\x9e\x4c\x20\x59\x9d\xc4\x2d\xb4\xe8\xce\xf3\x6c\xc4\x1f\xd8\xb4\xe7\x77\xb9\x86\x23\xf3\xeb\x68\x17\x2f\xe1\x24\xa1\x61\x14\x5e\x37\xe1\x44\x02\xd1\x2a\xa9\x5e\xca\x84\x73\xa2\x3d\xca\x60\xc2\xf8\x60\x69\xdd\xc3\xfa\x9b\x1e\x18\x52\x0e\x68\x10\x1e\xaf\x50\xd2\xe9\x68\xac\xb8\x29\x70\x73\x79\xee\xed\xa9\x2a\x9d\x21\x16\x00\xb1\x35\x3b\xa7\x21\x76\x50\x6e\x21\x11\xb0\x23\xe3\xcb\x1e\x20\xfc\xdc\x27\xee\x6c\x01\x49\xaa\xac\xf8\x0e\x30\x10\x3a\x92\x9d\x3d\x61\x0f\x1b\x3b\xba\x16\x1d\x06\x94\xfb\x08\x81\x94\xc8\xe5\x63\xa0\x58\x92\x10\x66\x72\xd8\x22\xec\x07\x72\xfe\x4a\xc8\xf1\x13\xd3\x6d\x85\x6b\xa2\x64\x95\x24\x55\xba\xd5\xd2\xeb\x9c\x88\x2b\xc7\xad\x09\x87\xa6\xb8\x33\x13\x5c\x38\x68\xfd\x1c\xf6\x1a\x1c\xa0\x05\x2c\x92\x06\x7f\xdb\x14\xd3\x74\x22\x68\xaf\x3d\x26\xe5\x71\x19\x85\xc8\xea\x57\xf7\xaa\x85\xd2\x29\x67\xbc\x4a\x94\xf9\xdf\xa2\x1e\x8c\xec\x30\xdd\x4a\xf8\x51\xe5\x6f\x29\xd2\x74\x85\x1f\xd7\xf0\x3f\xaa\xeb\xef\xbd\xba\x0e\x64\xbf\x05\xa3\x11\x4e\x1e\xd2\x00\x77\x74\xb0\xbf\x92\x72\x15\x36\x64\x6b\xb4\x22\x4b\x0e\x73\x42\xe1\x3d\x29\x57\xaa\x9b\x3a\xde\x86\x15\x74\xd7\xdb\xf3\x6a\xf5\xe8\x85\x3f\x35\x10\x66\xd9\x7f\x7c\x9e\x3d\x26\xa3\x57\x18\x09\x5f\xda\xf3\xad\x14\xb3\x8e\xb4\x0c\xc3\x42\x11\xc4\xae\x55\xaf\x83\xd1\xce\xc9\x25\x16\xb2\xe5\x84\x0e\x27\x23\xc3\x05\x52\x3a\xfb\x08\xb3\x92\xb8\xb8\x0e\x4e\xd5\x2b\x89\xd4\x55\xfe\xfc\xbe\xf9\xc3\xb5\xc5\x07\x53\x8f\x9e\x61\x3c\xce\x81\x75\xb8\x00\x4e\xba\x83\x1a\x7f\xc6\x35\x54\xed\x5c\x9e\x55\x30\x7b\x5f\x93\xe2\xa3\x52\xb1\x0d\x60\xed\x9c\x40\x94\x7d\x88\xb1\xc3\x37\x15\x97\xe9\x55\xb6\x27\x25\xdc\x8f\xf7\xbd\x15\x51\xd2\x92\x5c\x05\xb0\x25\x37\x71\xd8\x93\x5d\x0c\xc1\xf7\x5f\x98\x32\x99\x91\xc8\xa7\xd7\x55\x81\x05\x60\xd5\xd3\x33\xd2\x72\x24\xdb\x1b\xf2\xcc\x98\x36\xec\x6c\x7e\x89\xe9\xe7\x4a\x27\xd6\x7b\x7b\x30\x73\x12\x60\xdb\xee\x60\xf6\x52\x4b\xf7\x40\x3f\x67\xe9\xdb\xf4\xd7\x9b\xd3\x99\xf5\xfa\x59\xae\x17\xe2\xd6\x40\xbd\xf2\x40\x2b\xdf\x65\xe1\xb6\x14\x96\x69\xde\x69\x85\xd4\x53\x0b\x95\x6d\xdb\x1b\x71\x98\xed\xf5\xb3\x3a\xbe\x31\x12\x99\x3e\x37\xa8\xaa\xcd\x83\x7d\x79\x37\xca\x3b\x29\xdc\x3d\x90\xc3\x70\x36\x07\x3d\x31\x20\x2a\x3f\x21\xdf\x0a\x82\xd8\x91\x09\x59\xbc\x41\x37\xcc\x68\x54\xfc\xce\x02\x8f\x60\x67\x01\xc4\xa1\x7e\x66\x1d\x6a\xa1\x2a\x7f\x99\x70\x74\x73\x10\x44\x1c\x23\x86\xc9\xd3\x9f\x1f\x0b\xaa\xa7\xb6\xbe\x08\xd2\xdd\x9e\x86\x02\x82\x50\x4d\xc1\x4c\x64\xbc\x5e\xd4\xfd\xdb\xa7\xc9\x28\xad\xd5\xf2\xd4\x75\xad\xbc\x53\xf8\x20\x18\x7c\xc7\x2a\x85\xff\x3b\x5e\x6f\x6a\xbb\x93\x01\x0d\x33\xe1\xf1\x5a\xb6\x94\xbf\xce\x29\x29\x97\x05\xb6\x3a\x10\xd0\xc2\x2d\x87\x16\xdf\x10\x5e\x49\xeb\xca\x22\xc6\xe2\x7c\x86\x93\x81\xcb\xdb\x8b\x19\xe8\xb1\x50\x83\x1e\x21\x40\x9e\xf6\x39\xc1\x82\xe7\xb7\x9c\xa2\x5d\x56\xa5\xd0\x64\xef\xe5\x59\x8a\x1c\x08\xf7\xf0\xc9\xfa\x0d\xde\x4b\x4c\x2b\x54\x57\x5f\x74\x28\x32\x07\x38\xc5\x65\x85\xfc\xdc\x76\xbb\xf0\xa5\xe3\x16\x3f\xad\x18\xa4\x93\xce\xbc\xae\xa7\x2f\xfc\x3d\x30\x03\x59\xdc\x2d\xb4\x64\xdf\xf2\xb8\x21\x56\x70\xb1\xa4\x15\x5f\x9d\xd8\x7a\x96\xb9\x41\x9d\xfc\x34\xb8\xe5\x16\x39\xc7\x45\x81\x19\x83\x82\xb4\x9c\x92\x3a\x09\x9a\x04\x4b\x73\x73\x33\x37\x80\xa2\xe1\x95\x2a\x8e\xcd\x4e\x9c\xdd\x5e\x92\x25\x95\x9e\x0c\xa4\x81\xdb\xc7\xf5\x5a\xfb\x3d\x6d\x79\x47\x06\x57\xa1\x85\xba\xba\xb7\x67\x85\x61\x97\xc8\x08\x37\x7b\x0a\x79\x2e\x1e\xf2\xfc\xc8\x83\xea\x60\x33\x73\xc6\xce\x8e\x97\x7c\xf1\xf7\x44\xe3\xe9\x45\x4d\x7e\x93\x9d\x01\xc9\x53\x3c\xc5\x3c\x07\x9a\x19\xba\x6f\xb5\xe4\x0b\x42\xab\x2f\xd2\x6c\xb5\xfb\x57\xac\x82\x19\x78\x7b\xf1\xfa\x5e\x7c\xdf\x90\x8f\x38\xe4\x27\x47\x76\xe6\xa3\x5d\x06\xe9\x30\x13\x22\xb5\xaa\xdb\x03\x35\x98\x65\x3a\x07\xf5\x04\x9e\x25\x32\xc6\xa0\xa1\x63\x1d\x8c\xcf\xb6\x97\x35\xa6\xbc\xe6\x57\xb7\x84\x86\x8c\x3b\x81\xce\xd0\xd0\x47\xec\xc6\x83\xbe\x3f\x9b\xc5\x96\x3e\xc4\xc2\xd8\xbb\x0b\x27\x4e\xd8\x06\xe4\x8a\xc5\xa3\xaa\xbc\xfd\x09\x1e\x31\x31\x05\x47\xbf\x78\x44\x6a\xd1\x0d\x97\x24\xf0\x04\xee\xee\x7e\x02\x6b\x0a\xeb\xb5\x59\x93\x0a\x56\xf7\x95\x51\x70\x7c\x25\x24\xe1\x3b\xea\x5a\x90\x75\xa4\x6a\x39\x93\x8b\x44\x9c\x6f\x4b\x7c\x2b\xab\xdc\xba\x86\xe3\xf3\x99\xa3\xf0\xa4\xfb\x08\xd5\x35\x17\x59\x82\xb8\x90\x49\x17\x3c\xb1\x9d\x75\x98\x4a\xd0\xbf\xa4\x64\xd9\x39\xa1\x4b\x99\xe9\x0a\x55\x36\x1c\xdc\x2d\x1e\x75\x1f\x6f\x24\xbb\xf4\xb4\x16\xa6\xd9\x37\x34\x6e\xfc\x49\x6b\x42\x32\x31\x09\xd7\x96\xb6\xdd\xb0\x24\xb3\x0d\x9c\x62\xbe\x20\x25\xc0\x46\xc6\x58\xf1\x4f\x57\x6c\xe2\xc7\xe5\xb2\x69\x10\x5d\xb9\x42\x2c\x5d\x6e\x85\xef\xa2\x52\xd2\x71\x45\xd7\xb2\xeb\x30\x15\xe1\x43\x6e\x6b\xcc\xe8\x03\xa9\xda\x73\x24\x7c\xc1\xaf\x88\x61\xf5\x4b\xfe\x57\x12\x88\xac\x6a\xb1\x6c\x50\xeb\x67\x62\x71\x4f\xc0\xa6\xbd\xda\x30\xcd\xd9\x75\x29\x14\x57\x13\x51\x53\xd2\x17\x8a\x08\x94\x88\x2f\x34\x50\xea\x1a\x3a\xf1\x04\x9c\x00\x71\xf7\x71\x10\x49\xde\x55\x69\x9a\x74\xad\x38\x94\x50\xb6\x3e\x9d\x42\x87\x4b\x34\xc7\x93\x4c\xeb\xdb\xec\x5d\xc2\x92\x2f\x18\x77\xb9\x5f\x4f\x56\xae\x68\xec\xbd\x29\xbe\xbe\xbe\xce\x52\x6a\x19\x57\x8a\x5c\x36\xd2\x7a\xde\xa1\xf0\x89\x1b\xc5\x99\xbd\xad\x8a\x04\xe9\xcf\xf6\x60\xd2\x77\xba\x93\x2d\x95\x8e\xfe\xdc\xe0\x86\xc3\x7e\x8d\x5b\x93\x2c\x9d\x7d\xc6\x94\x56\x25\x66\x53\x80\x27\x53\x6f\xda\xcb\x10\x3d\x9a\x27\x53\x97\x11\xf8\xd9\x68\xcf\x8f\x86\x0b\xfb\x29\x66\x32\x14\xf4\x93\xd3\xdd\x39\x24\x2f\xdc\x4b\x55\xbd\x5c\x35\xde\x35\x4c\x57\xef\xbd\x53\x9c\x65\x7a\x69\x66\xbc\x53\x98\x69\xde\x7b\xa7\xb1\x30\x37\x14\xe7\xbe\xeb\x30\xb7\x5b\xbc\xf3\x65\x8d\x28\x6a\x7c\x49\x9b\x8f\x46\x99\xf7\x4d\x82\xce\x48\xb7\xb4\xdc\xb6\x7f\xa8\xd0\x7b\x01\x38\xde\x86\x03\xfd\xd1\xc2\x11\x0c\x77\xe4\x7c\x2c\x20\xbe\xb0\xd7\x89\x5b\xa7\xba\x27\x1b\x64\xcf\x59\xaf\x95\xf7\xd5\xcb\xff\xb9\xc4\x74\xf5\xd5\xab\x5f\x10\xda\x7c\xf5\x62\xa7\x41\x97\xaf\xdb\x2e\xb4\x19\xee\xbf\x11\xf3\x1a\xd5\xa3\xa5\x6a\x2a\x37\xd2\x5b\x9a\x6c\x48\xe7\x43\xa6\x87\xcb\xb2\x0d\x3c\x23\xa5\x84\x07\x47\x7c\xc9\x7a\x6f\x84\x5f\x21\x66\x1b\xbd\x1b\xd0\x6d\xec\x41\x74\x98\xa7\x23\xef\xe1\x68\x93\x84\xc0\x85\x39\x82\xca\x0e\xae\xd6\xeb\x43\x71\x92\x7e\x6c\x37\x81\xf4\xee\xee\x40\x18\xa9\x3c\xae\x8d\xf4\x0b\xce\x3b\x7d\x72\x33\xb3\xb5\x37\x6a\x42\x8d\x6b\x09\x47\x4d\xf6\x2b\xd5\xf1\xdf\xed\x20\x07\x8a\x78\x1a\x36\xd3\xfd\xe0\x28\xed\xcb\x5c\x57\xdf\xb6\x54\xa3\x23\x5b\x68\x8a\xa9\x79\x2f\xf0\x6d\x2f\xa4\x77\x4b\x5f\x46\xe1\xc6\x2a\x2c\xb3\xee\x30\x54\xa2\x2e\xbb\x06\xf2\x9b\xb4\xf4\xfc\x6c\x47\xeb\xdf\xb6\xc2\x83\x4b\x1e\x8c\xca\xc0\x59\x9b\x02\xc3\xd1\x00\x36\xf4\x19\xef\x79\x48\x2d\x15\x77\x56\x65\x06\x7e\x70\x32\xaf\x77\x32\x80\xf4\xd7\x6b\x93\x90\x28\xed\xe1\xf5\x17\x0a\xcc\x3f\xa9\x19\xd3\x51\xc2\x65\x0b\x8e\x54\x7e\xd1\x16\x34\x65\xf2\x5c\x24\x69\x1f\x98\x6c\xb0\x41\x47\x31\xe7\x2b\xf5\x36\xc1\x7d\x04\xa1\xd3\xb8\x9d\x42\x8f\xf7\xf6\xc4\x9c\xeb\x22\x7a\x0d\xd4\x7b\x99\x6f\xdf\x1f\x6d\x6f\xaf\x0d\x5a\xca\xce\x90\xd2\xf8\x75\x2a\x32\x61\xcd\x70\xcb\x46\xff\x77\x8e\xdd\x61\x11\x1a\xca\x4e\x90\xd8\x19\x0f\xba\xd7\x8d\x9b\x8e\xaf\xf4\x5b\xc7\x3f\x1a\x2a\xdf\x1f\x3e\xfc\x2b\x9b\x04\x19\x05\x3b\xcd\xcc\xf7\xb0\x42\xae\xbd\xa4\x2f\x5e\x15\x7c\x39\xd0\x9a\x32\x69\x22\x0b\xc1\x2c\xcf\xef\x53\x9d\xd9\x52\x2a\x1f\xf8\x94\x65\xe7\x8f\x55\x63\x83\x88\xa3\xf8\x59\x5c\x7b\xee\xed\xc1\xa9\xba\xae\x1f\x53\xd5\xd0\x57\x55\x9a\xae\x46\x1d\xbb\xc9\x36\x6d\xfc\xc5\x74\xe1\xfd\xfc\x7f\x00\x00\x00\xff\xff\x56\x53\xe3\x33\x1a\x37\x00\x00") + +func templatesMarkdownDocsGotmplBytes() ([]byte, error) { + return bindataRead( + _templatesMarkdownDocsGotmpl, + "templates/markdown/docs.gotmpl", + ) +} + +func templatesMarkdownDocsGotmpl() (*asset, error) { + bytes, err := templatesMarkdownDocsGotmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/markdown/docs.gotmpl", size: 14106, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5d, 0xa8, 0x4b, 0x6f, 0xe, 0x98, 0x3f, 0x90, 0x8e, 0xef, 0x51, 0x79, 0x4a, 0x94, 0xd5, 0xf5, 0x9f, 0x28, 0x15, 0xec, 0xd0, 0xbf, 0x42, 0x61, 0x58, 0x99, 0xee, 0xf2, 0xd7, 0x53, 0xec, 0xa0}} + return a, nil +} + var _templatesModelGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x90\xcd\x4e\x2b\x31\x0c\x85\xf7\x7d\x8a\xa3\x2e\x2b\xdd\x99\xfd\x5d\x22\x8a\xc4\x02\x36\xf0\x02\x56\xe2\x4e\x23\xe5\x67\x14\xa7\xa2\x60\xe5\xdd\x51\xda\xd2\x4e\x07\x54\xb1\x60\x97\xb1\xbf\xb1\xfd\x1d\x55\x14\x0e\xa3\xa7\xc2\x58\x6e\x99\x2c\xe7\x25\x3a\xd4\xba\x50\xfd\x07\xb7\x41\xf7\x18\x8d\xdf\x59\x7e\x4a\x96\x7d\xab\x03\xe7\x8e\xac\xf7\x63\xca\x85\x6d\xab\xf7\x3d\x54\x31\x92\x18\xf2\xee\x83\xd1\x3d\x53\x60\xd4\x8a\xab\x15\x36\x19\x29\xd9\xc5\xe1\xb4\x05\x38\xce\xbb\x10\x14\x63\x2a\x54\x5c\x8a\x72\x66\x1a\xc1\xd1\x5e\x3e\x2e\xb8\x98\x2d\x07\x9a\xdc\x7c\xe2\x16\xaa\xc8\x14\x07\x46\xb7\xde\x97\x4c\x2f\x07\x4e\x66\x06\xdf\xdc\xfe\xde\xee\x37\x7e\x33\xc3\x9b\x8e\x57\xec\xec\x69\x79\xe3\xe2\x7c\x47\xad\xaa\xfd\x0a\x93\x1a\x4a\xc2\xc0\x91\x73\x9b\x2e\x23\x1b\x6c\x72\x0a\x90\xb4\xcb\x86\xb1\xea\xa7\x19\xc5\x54\x5a\x16\x77\x24\xfc\xfa\x3e\xf2\x31\x8b\x16\x87\xbc\xd1\x30\x70\xfe\x1f\x0e\xe1\xa9\x9e\x23\xf9\xba\xd0\xcb\x0f\xb4\x75\x62\xb2\x0b\x2e\x52\x49\x79\xfa\xd7\xe1\x7d\x3f\xed\x3e\x38\xf6\xf6\x96\xf1\x67\x00\x00\x00\xff\xff\x75\xb1\xeb\x60\xbc\x02\x00\x00") func templatesModelGotmplBytes() ([]byte, error) { @@ -327,7 +353,7 @@ func templatesModelGotmpl() (*asset, error) { return a, nil } -var _templatesSchemaGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x58\x5f\x6f\xdb\x36\x10\x7f\xcf\xa7\xb8\x79\xd9\x20\x05\xa9\xbc\xf5\x69\xeb\x90\x87\xa4\x69\xd7\x0e\x58\x53\xd4\x5d\x0b\xac\x2b\x0a\x5a\x3c\x59\x6c\x29\x52\x25\xa9\xb4\x9e\xe0\xef\x3e\x50\xa4\x64\xca\xa6\x9c\x06\xd9\x80\x61\x58\x9e\x1c\xf1\x74\xbc\xfb\xdd\xdf\x9f\xda\xf6\x1e\xb0\x02\x88\xa0\x90\x3d\xd5\x17\x44\xe3\xcb\x75\x8d\xf6\xf7\xa3\xcf\xb5\x54\x06\x29\x24\x42\x1a\xfb\x60\xd1\xd4\xa8\xce\x39\x23\x3a\x85\xcd\xe6\x08\xc0\xbe\x6b\xb0\xaa\x39\x31\x08\x33\x9d\x97\x58\x91\xe7\x92\xaf\x2b\xa9\xea\x92\xe5\x33\xc8\xac\x9c\x95\x42\xae\xd1\x5e\x33\xd2\xe2\x94\x18\x7b\x5d\xdb\x42\x4d\x74\x4e\x38\xfb\x13\x21\x7b\x46\x2a\x84\xcd\xc6\x3e\xdd\xaa\xb7\x72\x8b\xee\x0a\x6b\xa0\xd3\xdd\xb6\xf3\x13\x78\x2c\x55\xa7\x44\x03\xc5\x9c\x13\x85\x14\x88\x86\x63\x85\x05\x48\x01\x5a\x56\x08\xd2\x94\xe8\x84\x4e\xe1\x7d\xa3\x4d\x2f\x09\xa6\x44\x67\x00\xd1\x40\x60\x25\x39\x11\x2b\x78\x47\xac\x75\x48\xdf\xf9\x37\x30\x5b\x65\x4e\xea\x1c\xce\xe0\x22\x83\x67\x12\x2a\x34\xa5\xa4\xa0\x4b\xc2\x39\x2c\x11\x14\xf6\x97\x67\x00\x27\xf3\x01\x1e\xe7\xf3\x00\x6b\xf7\x1c\xc6\x8e\x2d\xfd\xe1\x02\x15\xeb\x00\x50\x81\x73\xaf\x4b\x14\x9d\x95\x9d\x4d\xdb\x6b\xac\xb9\xf5\x16\x6a\x6f\x29\xc5\x82\x09\x84\x82\xe4\x46\xaa\xb5\x37\x52\xc3\x27\x66\x4a\x30\x25\xd3\x4e\x4b\x16\x1a\x88\x82\x46\x82\xf4\xa8\x5a\x22\xa5\x48\xa7\xe3\xdc\x4b\xec\x06\x39\xf4\x5c\x2a\xab\xeb\xa1\xac\x6a\x8e\x9f\xaf\x96\xef\x31\xef\xf2\xe8\x65\x53\xf3\x2e\xc3\xce\x29\x65\x86\x49\x41\xf8\x73\x25\x6b\x54\x86\xa1\xee\x1d\x7f\x79\x75\x79\x95\x14\x0a\x69\xfa\x00\x4a\x22\x28\x47\xc8\x89\x46\x90\x05\xe8\x66\xd9\x45\x83\x89\x12\x15\x33\x4c\xac\xa0\x50\xb2\x02\x0b\xa4\x8b\x53\xe7\x70\x4c\xfb\x29\x30\xad\x1b\x84\xaf\xef\xdf\xbf\xff\x5d\x0f\x83\x8f\x88\xf5\xdc\x67\x5e\x9f\x93\xac\x00\x9f\xfb\x43\x31\x58\xf3\x06\xb9\xb6\xed\x9d\x8e\x26\xb0\x3d\x16\x34\xfc\x31\x8e\xbc\x43\xf2\x42\xd2\xb5\x47\xd1\x59\x72\x0f\x14\x11\x2b\x84\x6c\x84\xca\x60\xe8\x54\x52\xd9\xbf\xf9\x3c\x52\x4a\x9b\x0d\xac\xd0\xe8\x2e\x8d\xda\x16\xca\xa6\x22\x62\x54\x67\xb2\x70\xd9\x31\x00\xd8\x45\xc0\x66\x76\xbd\xb5\xe0\x53\xc9\xf2\x12\x6c\xd1\xc8\x02\x48\x00\xb6\x95\x21\x2b\xeb\x10\x33\x1a\x98\x30\xa8\x0a\x92\x63\x88\x2e\x40\xd1\x88\x1c\x92\xb6\x85\xe3\xec\x05\xe6\xc8\xae\x51\x79\xd3\x4e\x46\x06\x1f\x7b\x8b\xd3\xa8\x1f\x49\x1a\x03\x30\xe8\x07\xc3\x7d\x03\x50\xf8\x11\x8e\xb3\x4b\xa6\x73\xc5\x2a\x26\x88\x91\xea\x31\x43\x4e\x07\xe7\x83\x37\x00\x14\x9a\x46\x89\xee\x6a\xc5\x84\x29\x60\xf6\xcd\xc7\xd9\xee\xfb\xaf\x08\x6f\x76\xde\x1c\x67\x7f\x4c\xdf\xd8\x6d\xd8\x6c\xb2\xb6\xcd\x49\x85\xa1\x77\x9d\x61\xbb\x5a\x05\x0d\x95\x6e\x8e\xc2\x50\x2f\xd0\x44\xa3\xad\x6f\x17\xed\x3b\x04\x69\xc2\x82\xe4\x9a\xf0\xc3\x91\x4a\x21\x12\x2b\x81\xb7\x88\xd5\x6d\x40\x85\x33\xb8\x26\xfc\x26\x68\xa3\x47\x91\x7f\x6d\xf9\x5d\x62\x41\x1a\x6e\xf6\xbb\x15\xdc\x1b\x5a\xcc\xf7\x3f\xfc\x18\x16\x41\x8f\xee\x61\x6c\x7b\x5f\x53\xf8\x4d\x54\x44\xd9\x01\xf3\xcb\xe2\xea\x59\xb2\x84\x37\x6f\x97\x6b\x83\x29\xa0\x52\x52\x05\xf0\x4d\x0f\x50\x37\x65\xa3\x47\xc3\xdb\xd7\x44\x81\x39\xf0\xfa\x20\x68\x6b\x49\x29\x78\x70\x06\xef\xb5\x14\xd9\x60\x5d\xe2\xec\x4a\xda\x36\xac\x99\xc4\x0a\x0d\x30\xa5\x9b\x4d\x7a\x0a\xdf\x9a\xf4\xa7\x4e\xc7\x57\x67\x20\x18\x1f\x65\x80\xaf\x14\x54\x6a\x2f\x20\x07\xae\x5e\xde\x41\xe9\xc9\x7e\x24\xce\xe2\x38\x24\x26\x3d\xda\x51\x29\x58\x9f\x4d\x91\x2c\xd9\xed\x06\x77\xd9\x70\x8e\x22\xba\x59\x01\x89\xdf\xd7\x9e\xdb\x4a\x31\xec\xda\x8d\x53\xb7\xb6\x74\x33\xb7\xd1\x46\x56\x8f\xa5\xaa\x88\x31\xa8\xdc\x0a\x97\x68\xa3\x98\x58\x3d\x94\xc2\x10\x26\x34\x64\xbf\xa3\x92\x30\x4b\xfe\x98\xcd\xd2\x34\x8d\xee\x26\x7e\x13\xda\x5d\x4d\x26\xac\xea\xb6\xbb\xe5\xce\xa2\xe3\x67\xd9\x39\xe7\x57\x45\x38\xc6\x0e\x0d\xb9\xa9\x31\xf7\x37\xcd\x39\xbf\x40\xec\xf5\xbd\xff\x67\xd3\xbf\x65\x36\xdd\x39\x42\xff\xc1\xc1\x14\x39\xdc\x3e\x98\xda\x99\xa3\x2b\x36\x13\xc1\xfa\x36\x4c\xa8\xbd\x49\x17\xa0\x54\x91\xfa\x4a\x2d\x38\xcb\xf1\x67\xb4\x0d\x65\xaa\x0d\xec\x01\xbb\xd7\x39\x76\x38\xc7\x40\x3d\x45\xce\x1b\x8a\xaf\x08\x67\xd4\xe2\x1b\x25\x9d\xfd\xb3\x9e\x7b\xa4\xbd\xe3\xbe\x4d\x79\x1a\xb8\xa5\x6a\x40\x65\xb7\xc0\x5b\xda\xd4\x31\xa3\x9e\x11\x8d\x19\x9a\xb5\xc0\x75\x48\xc7\x58\x9e\x0e\x3b\xac\x35\xc0\x28\x24\x55\x9a\xba\xc3\x17\xf8\xb1\x61\x96\x62\x66\x4f\x88\xf6\xd6\x32\x69\x9b\xe9\x13\x32\xb4\xaa\x78\x2f\x75\x80\x5c\xf7\x1e\x8e\x21\xf4\xd4\xeb\x06\x23\xec\x0b\xf3\x39\xf8\x7b\x11\xbc\x32\xeb\xb3\xad\x9a\x58\x49\x75\xf8\xb8\x9a\xea\xee\x07\x66\xd9\x58\x85\xc2\x97\xa1\x6a\x84\x61\x15\x66\x5e\x27\x59\x72\x0c\x76\xf8\x65\x63\xa0\x24\x1a\x84\xec\xef\xea\x9c\x35\x12\xf2\x12\xf3\x0f\x0e\xc7\xa9\xc5\xc6\x11\x28\xe7\xcd\xc0\xf9\xf6\xd8\xe0\x04\x09\x3c\x09\xc9\x93\x53\x93\xec\x70\xb1\x14\xc2\x9a\xf4\xd4\x11\xc6\x75\x76\x0b\x92\x96\x0e\xb8\x26\x45\x37\x38\x35\x68\xa3\x8a\xca\x64\x2f\x70\xc5\xb4\x51\xeb\x70\xf7\x0a\x16\x81\x9d\x99\xdf\x21\x1e\x90\x44\xa0\x12\x75\x17\xd9\x01\xfa\x9b\x91\x7f\x00\x42\xca\x7a\x8a\xa8\x8f\xea\x27\x7b\x4d\x84\xd1\xbf\xba\x95\xe8\x82\x09\xa2\xd6\x91\x72\xac\xc2\xf3\x9b\xaa\xd2\x57\x4b\xa4\xec\xbd\x7b\x9a\xad\x04\x31\x8d\x42\x28\xa4\x8a\x37\x19\x5b\x54\xdb\x83\xa7\x06\x2b\x6d\xc7\xb3\xdd\x46\x6c\xc2\xec\xd6\xa0\x8f\xed\xfe\x97\x12\xe7\xe3\x13\x32\x95\x28\x41\x2b\xec\x68\x7f\x76\x58\xce\xef\x0e\xe1\x07\x0d\x2a\x73\xb7\x19\xf5\xdf\x5d\xc2\x43\xcf\x80\xd7\xdb\x5a\xbf\x94\xf9\x22\x10\x0f\xba\x73\x6c\x77\x4c\xa1\x22\xf5\x1b\xa7\xff\xed\xc1\xc9\xf3\xc5\xfc\x63\xd7\x4d\x87\xed\xa0\xe0\x9f\xf1\x6f\xca\xbb\x37\x5f\xe0\xd4\x81\xed\x78\x3e\xff\x82\x11\xa5\x4b\xd9\x50\x58\xa2\x1f\x6a\xd4\x7d\xc3\xe3\xec\x03\x82\xc2\x55\xc3\x89\x0a\x3e\x54\xec\x4d\x42\x42\x29\x14\x0d\xe7\xa0\x9b\xda\x36\x8e\xe9\x94\x8d\xcd\x45\x6b\xa0\x71\x0d\xb4\x92\xb6\x76\x4f\xbb\xe2\x1d\x7f\xfe\xb0\x00\x02\xd3\x50\x37\xba\x44\x0a\x54\x7e\x12\xb6\x47\x5a\xc1\xed\x26\x13\x2f\xe2\xbf\x02\x00\x00\xff\xff\xde\xd7\x2a\x36\x80\x15\x00\x00") +var _templatesSchemaGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x58\xdd\x6e\xdc\xb6\x12\xbe\xf7\x53\xcc\xf1\xf1\x39\x90\x0c\x47\xdb\xe6\xaa\x4d\xe1\x0b\x3b\x4e\xea\x14\x68\x1c\xc4\x69\x02\x34\x0d\x02\xae\x38\x5a\x31\xa1\x48\x85\xa4\x1c\x6f\x85\x7d\xf7\x82\x22\xa5\xa5\xb4\xdc\xb5\x5d\xa7\x40\xd0\xd6\x57\x6b\x91\x1c\xce\x7c\xf3\xfb\xb1\x6d\x1f\x00\x2b\x80\x08\x0a\xd9\x33\x7d\x4a\x34\xbe\x5a\xd6\x68\x7f\x3f\xb9\xae\xa5\x32\x48\x21\x11\xd2\xd8\x0f\x97\x4d\x8d\xea\x84\x33\xa2\x53\x58\xad\xf6\x00\xec\x59\x83\x55\xcd\x89\x41\xd8\xd7\x79\x89\x15\x79\x21\xf9\xb2\x92\xaa\x2e\x59\xbe\x0f\x99\xdd\x67\x77\x21\xd7\x68\xaf\x19\x49\x71\x42\x8c\xbd\xae\x6d\xa1\x26\x3a\x27\x9c\xfd\x8e\x90\x3d\x27\x15\xc2\x6a\x65\xbf\xae\xc5\xdb\x7d\x97\xdd\x15\x56\x41\x27\xbb\x6d\x67\x87\xf0\x54\xaa\x4e\x88\x06\x8a\x39\x27\x0a\x29\x10\x0d\x07\x0a\x0b\x90\x02\xb4\xac\x10\xa4\x29\xd1\x6d\x3a\x82\x0f\x8d\x36\xfd\x4e\x30\x25\x3a\x05\x88\x06\x02\x0b\xc9\x89\x58\xc0\x7b\x62\xb5\x43\xfa\xde\x9f\xc0\x6c\x91\xb9\x5d\x27\x70\x0c\xa7\x19\x3c\x97\x50\xa1\x29\x25\x05\x5d\x12\xce\x61\x8e\xa0\xb0\xbf\x3c\x03\x38\x9c\x0d\xf0\x38\x9b\x07\x58\xbb\xef\x30\x36\x6c\xee\x17\x2f\x51\xb1\x0e\x00\x15\x18\xf7\xa6\x44\xd1\x69\xd9\xe9\xb4\xbe\xc6\xaa\x5b\xaf\xa1\xf6\x9a\x52\x2c\x98\x40\x28\x48\x6e\xa4\x5a\x7a\x25\x35\x7c\x66\xa6\x04\x53\x32\xed\xa4\x64\xa1\x82\x28\x68\xc4\x49\x4f\xaa\x39\x52\x8a\x74\xbb\x9f\xfb\x1d\x53\x27\x87\x96\x4b\x65\x65\x3d\x96\x55\xcd\xf1\xfa\x62\xfe\x01\xf3\x2e\x8e\x5e\x35\x35\xef\x22\xec\x84\x52\x66\x98\x14\x84\xbf\x50\xb2\x46\x65\x18\xea\xde\xf0\x57\x17\x67\x17\x49\xa1\x90\xa6\x8f\xa0\x24\x82\x72\x84\x9c\x68\x04\x59\x80\x6e\xe6\x9d\x37\x98\x28\x51\x31\xc3\xc4\x02\x0a\x25\x2b\xb0\x40\x3a\x3f\x75\x06\xc7\xa4\x1f\x01\xd3\xba\x41\xf8\xef\xc3\x87\x0f\xbf\xe9\x61\xf0\x1e\xb1\x96\xfb\xc8\xeb\x63\x92\x15\xe0\x63\x7f\x48\x06\xab\xde\xb0\xaf\x6d\x7b\xa3\xa3\x01\x6c\x97\x05\x0d\x7f\x8c\x3d\xef\x90\x3c\x95\x74\xe9\x51\x74\x9a\x3c\x00\x45\xc4\x02\x21\x1b\xa1\x32\x28\xba\x2d\xa8\xec\xdf\x6c\x16\x49\xa5\xd5\x0a\x16\x68\x74\x17\x46\x6d\x0b\x65\x53\x11\x31\xca\x33\x59\xb8\xe8\x18\x00\xec\x3c\x60\x23\xbb\x5e\x6b\xf0\xb9\x64\x79\x09\x36\x69\x64\x01\x24\x00\xdb\xee\x21\x0b\x6b\x10\x33\x1a\x98\x30\xa8\x0a\x92\x63\x88\x2e\x40\xd1\x88\x1c\x92\xb6\x85\x83\xec\x25\xe6\xc8\xae\x50\x79\xd5\x0e\x47\x0a\x1f\x78\x8d\xd3\xa8\x1d\x49\x1a\x03\x30\xa8\x07\xc3\x7d\x03\x50\xf8\x09\x0e\xb2\x33\xa6\x73\xc5\x2a\x26\x88\x91\xea\x29\x43\x4e\x07\xe3\x83\x13\x00\x0a\x4d\xa3\x44\x77\xb5\x62\xc2\x14\xb0\xff\xbf\x4f\xfb\xd3\xf3\xaf\x09\x6f\x26\x27\xc7\xd1\x1f\x93\x37\x36\x1b\x56\xab\xac\x6d\x73\x52\x61\x68\x5d\xa7\xd8\x54\xaa\xa0\xa1\xd0\xd5\x5e\xe8\xea\x4b\x34\x51\x6f\xeb\xbb\x79\xfb\x1e\x4e\xda\xa2\x41\x72\x45\xf8\x6e\x4f\xa5\x10\xf1\x95\xc0\x3b\xf8\xea\x2e\xa0\xc2\x31\x5c\x11\x7e\x13\xb4\xd1\xa5\xc8\xbf\x36\xfd\xce\xb0\x20\x0d\x37\x9b\xd5\x0a\x1e\x0c\x25\xe6\xdb\xef\xbe\x0f\x93\xa0\x47\x77\x37\xb6\xbd\xad\x29\xfc\x22\x2a\xa2\x6c\x83\xf9\xe9\xf2\xe2\x79\x32\x87\xb7\xef\xe6\x4b\x83\x29\xa0\x52\x52\x05\xf0\x6d\x6f\xa0\xae\xcb\x46\x97\x86\xd3\x57\x44\x81\xd9\x71\x7c\xd8\x68\x73\x49\x29\x78\x74\x0c\x1f\xb4\x14\xd9\xa0\x5d\xe2\xf4\x4a\xda\x36\xcc\x99\xc4\x6e\x1a\x60\x4a\x57\xab\xf4\x08\xfe\x6f\xd2\x1f\x3a\x19\xff\x39\x06\xc1\xf8\x28\x02\x7c\xa6\xa0\x52\x1b\x0e\xd9\x71\xf5\xfc\x1e\x42\x0f\x37\x3d\x71\x1c\xc7\x21\x31\xe9\xde\x44\xa4\x60\x7d\x34\x45\xa2\x64\x5a\x0d\xee\x33\xe1\xec\x45\x64\xb3\x02\x12\x3f\xaf\xbd\xb0\x99\x62\xd8\x95\x6b\xa7\x6e\x6c\xe9\x7a\x6e\xa3\x8d\xac\x9e\x4a\x55\x11\x63\x50\xb9\x11\x2e\xd1\x46\x31\xb1\x78\x2c\x85\x21\x4c\x68\xc8\x7e\x45\x25\x61\x3f\xf9\x6d\x7f\x3f\x4d\xd3\xe8\x6c\xe2\x27\xa1\xe9\x68\xb2\x45\xab\x6e\xba\x9b\x4f\x06\x1d\xdf\xcb\x4e\x38\xbf\x28\xc2\x36\xb6\xab\xc9\x6d\x6b\x73\x5f\xa8\xcf\xf9\x01\x62\xa3\xee\xfd\xdb\x9b\xbe\x96\xde\x74\x6f\x0f\xfd\x0d\x1b\x53\x64\x71\xfd\x61\xdb\xcc\x1c\x1d\xb1\x99\x08\xc6\xb7\xa1\x43\x6d\x74\xba\x00\xa5\x8a\xd4\x17\xea\x92\xb3\x1c\x7f\x44\x5b\x50\xb6\x95\x81\x0d\x60\x37\x2a\xc7\x84\x73\x0c\xd4\x53\xe4\xbc\xa1\xf8\x9a\x70\x46\x2d\xbe\x51\xd2\xd9\x7f\xeb\xb9\x47\xda\x1b\xee\xcb\x94\xa7\x81\x6b\xaa\x06\x54\x76\x03\xbc\xa5\x4d\x1d\x33\xea\x19\xd1\x98\xa1\x59\x0d\x5c\x85\x74\x8c\xe5\xd9\x30\xc3\x5a\x05\x8c\x42\x52\xa5\xa9\x5b\x7c\x89\x9f\x1a\x66\x29\x66\x76\x4e\xb4\xd7\x96\x49\x5b\x4c\xcf\xc9\x50\xaa\xe2\xb5\xd4\x01\x72\xd5\x5b\x38\x86\xd0\x53\xaf\x1b\x94\xb0\x07\x66\x33\xf0\xf7\x22\x78\x61\xd6\x66\x9b\x35\xb1\x94\xea\xf0\x71\x39\xd5\xdd\x0f\xcc\xb2\xb1\x0a\x85\x4f\x43\xd5\x08\xc3\x2a\xcc\xbc\x4c\x32\xe7\x18\xcc\xf0\xf3\xc6\x40\x49\x34\x08\xd9\xdf\xd5\x19\x6b\x24\xe4\x25\xe6\x1f\x1d\x8e\xdb\x06\x1b\x47\xa0\x9c\x35\x03\xe7\xdb\x60\x83\x5b\x48\xe0\x61\x48\x9e\x9c\x98\x64\xc2\xc5\x52\x08\x73\xd2\x53\x47\x18\xe7\xd9\x1d\x48\x5a\x3a\xe0\x9a\x14\x5d\xe3\xd4\xa0\x8d\x2a\x2a\x93\xbd\xc4\x05\xd3\x46\x2d\xc3\xd9\x2b\x18\x04\x26\x3d\xbf\x43\x3c\x20\x89\x40\x25\xea\xce\xb3\x03\xf4\x37\x23\xff\x08\x84\x94\x75\x84\xa8\xff\x99\xa0\x3d\x27\xda\x36\x7d\xbc\x36\x41\xc4\xee\x0a\xd2\xdc\xed\xfe\x12\xb1\x3a\xbe\xf8\x56\x21\xdb\x15\x27\x0a\x52\x80\xd7\x03\x98\x01\xa6\xa1\xb1\x5f\x6f\x1b\xcf\xe3\x7b\xff\xd1\x61\x3d\x71\x41\x92\x9b\xeb\x1e\xd9\x1e\xa6\x23\xf8\x8a\x43\x7e\xb3\x65\x64\x6f\x88\x30\xfa\x67\xc7\x02\x4e\x99\x20\x6a\x19\xe9\x40\x55\xb8\x7e\x53\x23\xf2\x0d\x22\xd2\xe9\xbc\x79\x9a\x2d\x04\x31\x8d\x42\x0b\x55\xbc\xaf\xda\x94\x5c\x2f\x3c\x33\x58\x69\x3b\x91\xda\x01\xdc\x06\xd3\xb4\xed\x78\xbf\x6f\x3e\x0e\x3a\x1b\xcf\xc9\xb6\x20\x0a\xba\x7f\xf7\xd2\x95\xed\xde\xe7\xc7\xe5\xf0\x0d\x8f\xca\xdc\x91\x81\xfe\xa9\x31\x5c\xf4\x8f\x3e\xcb\x75\xb1\x38\x93\xf9\x65\xb0\x3d\x18\x48\x62\x74\x29\x85\x8a\xd4\x6f\x9d\xfc\x77\x3b\x87\xad\x5b\x53\xee\xa9\x99\x0e\xdb\x41\xc0\x5f\x63\xdf\x36\xeb\xde\xde\xc2\xa8\x1d\x84\x70\x36\xbb\xc5\x54\xa6\x4b\xd9\x50\x98\xa3\x9f\xe3\xa8\x7b\xb6\xe6\xec\x23\x82\xc2\x45\xc3\x89\x0a\xde\xe6\x36\x86\x3f\x42\x29\x14\x0d\xe7\xa0\x9b\xda\x16\x95\xed\x21\x1b\x1b\x05\xad\x82\xc6\xd5\xd8\x4a\xda\xdc\x3d\xea\x92\x77\xfc\xe2\x67\x01\xb4\x45\xb9\x6e\x74\x89\x14\xa8\xfc\x2c\x6c\xfd\xb4\x1b\xd7\xc3\x7b\x3c\x89\xff\x08\x00\x00\xff\xff\x38\x2e\xed\x30\x73\x18\x00\x00") func templatesSchemaGotmplBytes() ([]byte, error) { return bindataRead( @@ -342,8 +368,8 @@ func templatesSchemaGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/schema.gotmpl", size: 5504, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4d, 0x80, 0x58, 0x1d, 0x87, 0xd8, 0xdb, 0xff, 0xc9, 0x33, 0x69, 0x35, 0x93, 0x22, 0x2, 0xe3, 0x44, 0xb, 0x31, 0x1a, 0xe7, 0x60, 0xc2, 0xe8, 0x97, 0xe8, 0xff, 0x64, 0x99, 0xaf, 0xb2, 0xc5}} + info := bindataFileInfo{name: "templates/schema.gotmpl", size: 6259, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3a, 0xd6, 0xc6, 0x56, 0x8c, 0xce, 0x4f, 0x11, 0x45, 0xba, 0xcb, 0xb6, 0xc2, 0x28, 0xd4, 0x31, 0x52, 0x91, 0xbd, 0x36, 0xa7, 0xe5, 0xc4, 0x21, 0x15, 0xa1, 0xaa, 0x46, 0x3a, 0x8, 0x9f, 0x4f}} return a, nil } @@ -367,7 +393,7 @@ func templatesSchemabodyGotmpl() (*asset, error) { return a, nil } -var _templatesSchemaembeddedGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x91\xcd\x8e\x1a\x31\x10\x84\xef\x7e\x8a\x12\x27\x26\x4a\xfc\x00\x89\x38\x25\x28\xe2\x42\x22\x84\x72\x37\x9e\x36\xf1\xe2\x9f\x51\xdb\x33\x82\xb5\xfc\xee\x2b\xc3\x20\xb1\xec\x9e\x6c\xb5\x3f\x77\x55\x75\x97\x82\x9e\x8c\x0d\x84\x45\xd2\xff\xc9\xab\xb5\x3f\x50\xdf\x53\xbf\x40\xad\x22\x5f\x06\x42\x29\x18\x54\xd2\xca\xd9\x57\x82\xdc\x2a\x4f\xa8\x15\x29\xf3\xa8\x33\x8a\x40\x03\xac\x81\x5c\x3b\xf2\xfb\xcb\x40\x72\x93\xb6\xa3\x73\xea\xe0\x1a\xf8\xa5\x14\x50\xe8\x51\x6b\x29\x0f\xcc\xef\xd8\x8e\xa6\x51\x85\x30\x63\xd0\x58\x96\x22\x77\xa4\xc9\x4e\xc4\x77\x91\x5b\xe7\xc8\x90\x9b\xb4\x1f\x07\x47\xed\xf2\x33\xfa\xc1\xd1\xf9\xcf\xe1\x85\x74\x7e\x56\x68\x46\x7e\xd9\xa4\xd9\x7a\x1b\x54\xa6\x74\x2b\x6b\xe5\xe9\x9d\xff\xf6\xc7\x25\xba\xf2\x9b\xb4\x3e\x0f\x91\x33\xcd\x3d\x3e\xa6\xbd\xd3\xb7\x10\x0f\xc5\xab\x6c\x87\x7f\xca\xd9\x5e\x65\x5a\x9a\xc8\x5e\xe5\xd4\xa6\x63\x7c\x96\x3b\x3a\xda\x94\xf9\xd2\x81\x98\x23\x5f\xa7\x35\x29\x86\x81\x0d\x99\xd8\x28\x4d\xa5\x62\xd5\x72\x3e\x67\x97\x6d\x33\x1c\x87\xbf\x4a\x9f\xd4\x91\x3e\x1d\x1d\x9a\xfd\xe9\x2b\xe2\x09\xdf\x57\x30\x72\xc9\x63\xc8\xd6\x93\x9c\xfd\xb4\x15\x74\xf8\xd1\xde\x9b\x32\xc0\x94\x47\x0e\x98\xe4\xb3\xe1\x4e\x00\xad\xdf\x0c\x04\xeb\x44\x15\xa5\x7c\x9b\x13\x8a\xb7\x00\x00\x00\xff\xff\x18\x59\xcb\x94\x27\x02\x00\x00") +var _templatesSchemaembeddedGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x51\x4b\x6e\xdb\x30\x10\xdd\xeb\x14\x0f\x59\xd9\x45\xca\x03\xb4\xc8\x2a\x35\x0a\x6f\xd2\x22\x08\xba\xa7\xa9\x61\xca\x86\x1f\x61\x38\x12\xe4\x12\xbc\x7b\x41\x4b\x09\x12\xd7\xdd\x17\x59\x49\x98\x79\x9c\xf7\x2b\x05\x3d\x59\x17\x09\x57\xd9\xfc\xa4\xa0\x77\xe1\x40\x7d\x4f\xfd\x15\x6a\xed\xe4\x38\x10\x4a\xc1\xa0\xb3\xd1\xde\xfd\x26\xa8\x3b\x1d\x08\xb5\x22\x0b\x8f\x46\x50\x3a\x34\x80\xb3\x50\x3b\x4f\xe1\xe1\x38\x90\xda\xe7\xbb\xd1\x7b\x7d\xf0\x0d\xf8\xa1\x14\x50\xec\x51\x6b\x29\xaf\x30\x5f\x53\xfb\x34\x8e\xda\x75\x76\x8c\x06\x9b\x52\xd4\x3d\x19\x72\x13\xf1\x33\xc9\x72\x39\x31\xd4\x3e\x3f\x8c\x83\xa7\xf6\x73\x9b\xc2\xe0\x69\xfe\x76\xf8\x45\x46\xce\x19\x9a\x90\x2f\x2e\x1b\x76\xc1\x45\x2d\x94\x97\xb1\xd1\x81\xde\xe8\x6f\x6f\x7c\xa6\x13\x7e\x9f\x77\xf3\x90\x58\x68\xbd\xf1\xb7\xdb\x67\xf4\x62\xe2\xd5\xf0\x44\xbb\xc5\x0f\xed\x5d\xaf\x85\x36\x36\x71\xd0\x92\x5b\x3a\x36\x88\xba\xa7\x47\x97\x85\x8f\x5b\x10\x73\xe2\x53\x5a\x93\x66\x58\xb8\x28\xc4\x56\x1b\x2a\x15\x37\xcd\xe7\xb9\x77\xd5\x9a\xe1\x34\x7c\xd7\xe6\x49\x3f\xd2\xc5\xe8\xd0\xe4\x4f\xd7\x48\x4f\xf8\x74\x03\xab\x36\x3c\x46\x71\x81\xd4\xaa\xa7\x55\xb0\xc5\xe7\xb6\x6f\xcc\x00\x93\x8c\x1c\x31\xa9\x73\xc1\xdb\x0e\x68\xf7\x56\x40\x74\xfe\x5d\xf4\x72\x9b\xa2\xd0\x2c\x2f\x6e\x8d\xcc\x30\xcb\x4c\xad\xbb\x6b\xfc\x27\x9d\xbd\xd5\xfa\xef\xea\x2e\x78\x7a\xf1\x70\xb1\xc6\x52\x3e\xae\x81\x74\x7f\x02\x00\x00\xff\xff\xc7\x64\x36\xad\xee\x03\x00\x00") func templatesSchemaembeddedGotmplBytes() ([]byte, error) { return bindataRead( @@ -382,12 +408,12 @@ func templatesSchemaembeddedGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/schemaembedded.gotmpl", size: 551, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x20, 0x86, 0x25, 0x7d, 0x64, 0xed, 0xf7, 0x80, 0x5c, 0x4d, 0x25, 0xbc, 0xfd, 0xcd, 0xbe, 0x94, 0x37, 0xa5, 0x11, 0xa9, 0xb7, 0x27, 0xff, 0xa4, 0x49, 0xe, 0xd9, 0x21, 0xff, 0xf7, 0x51, 0x4d}} + info := bindataFileInfo{name: "templates/schemaembedded.gotmpl", size: 1006, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe4, 0xa4, 0x81, 0x1e, 0x5f, 0xcc, 0xb5, 0xc5, 0x89, 0x34, 0xe8, 0x25, 0xa0, 0x6e, 0x11, 0xd1, 0x44, 0x15, 0xb9, 0x8a, 0x52, 0x89, 0x1d, 0xad, 0xc2, 0x2b, 0x2, 0x7d, 0xf7, 0x9a, 0x12, 0x2d}} return a, nil } -var _templatesSchemapolymorphicGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x95\x4f\x8f\xdb\x36\x10\xc5\xef\xfe\x14\x0f\xee\x16\xb5\x8c\xad\x0c\xa4\xb7\x00\x3d\xb8\x08\x1a\xf8\x52\x07\xf5\x36\xf7\x89\x34\x5a\xb1\xe5\x1f\x85\xa4\x9c\xba\x84\xbe\x7b\x21\x4a\x96\x68\x57\xdb\x4d\x2f\xd5\x91\x1c\xce\x3c\xfe\xde\x0c\x15\x02\x4a\xae\x84\x66\xac\x5d\x51\xb3\xa2\x0f\x46\x5e\x94\xb1\x4d\x2d\x8a\x35\xba\x6e\x05\xf8\x4b\xc3\x08\x01\x0d\xb9\x82\xa4\xf8\x8b\x91\xff\x42\x8a\xd1\x75\x10\xda\xb3\xad\xa8\x60\x84\x15\x10\xc2\xf7\x10\x15\xb4\xf1\xd8\x18\x8b\xfc\xe0\x0e\xd3\x7e\x7e\x70\x27\x6f\x99\x54\x86\xae\x0b\x61\xb7\x5d\x61\xfc\xf6\xf8\x44\x8e\x87\x2a\xc2\x81\xe4\x17\xba\x38\x7c\x24\x29\x4a\xf2\xf4\x49\x72\x3e\x85\xfe\xa6\x4b\xb6\xd0\xc6\x2a\x92\x28\x8c\x2e\x85\x17\x46\xbb\x47\x7c\x61\x14\xa4\xbf\xf3\xa8\xe9\xcc\xa0\x24\xa3\xe5\xfe\x0c\x97\xa0\x59\x02\xee\xc4\xbd\x85\xaf\x85\x43\x51\x73\xf1\x47\x2f\xe1\xf7\xd6\x79\x54\xc6\xc2\x91\x16\xfe\x32\x6c\x64\xf9\x6a\xd2\x71\xd0\xf0\x35\x0f\xe0\xa2\x04\x98\x2a\xae\x24\x37\xf1\x8e\x65\xf5\x38\x64\x56\x4c\xda\xc1\xd7\xe4\x63\x54\xab\xf9\xcf\xc6\x58\xcf\x25\x9c\xb7\x6d\xe1\x51\x1b\x59\x0a\xfd\x3c\x15\x78\x2d\x7b\x4d\x0e\x74\x65\xc4\x9b\x0c\x55\xab\x8b\x81\xd3\x76\x17\x4d\x1b\x3e\xdb\x6a\x2f\x14\xe7\x09\xcd\xd1\x27\xd6\xe5\xe0\x6e\x08\xb0\xa4\x9f\x19\xf9\x5e\xca\x63\x85\xf1\xf4\xe8\x65\x7e\x70\x7b\x6d\xf4\x45\x99\xd6\x61\x4a\x3c\x9f\xf9\x60\x4d\xc3\xd6\x0b\x4e\x76\xe3\xbe\xa8\xf0\x90\x1f\xdc\x53\xdb\x48\x8e\x8e\xc3\xb3\x6a\x24\x79\xc6\xda\xf7\x8b\x95\x60\x59\x1e\x7a\xfc\x6b\xe4\x43\x04\x4b\x37\xc4\xce\xa1\x03\x9f\xa5\xd8\xab\xfe\xab\xd8\xbb\x85\xa4\x9c\xa2\xe6\x68\x4f\x52\x14\xfc\x9e\xbd\x67\x3b\xe4\x98\x6e\x39\x56\x9d\x4f\xe6\xef\xcd\x53\x0f\x39\x8d\x99\x69\x2d\xa2\xfb\x27\x86\x91\x5f\xca\x60\x49\xdb\x22\x8a\x97\xa5\xbd\x06\xe6\x75\xc1\x5f\x81\xa5\x5b\x25\x43\x5f\x90\xe2\xdb\x99\xbf\x95\x11\xdf\x8c\x9f\x4c\x79\xb9\x3a\xb3\xdb\xa6\xfd\x2d\x54\x23\x59\xb1\xf6\x94\x36\xf2\xfc\x6c\x6c\x9e\x8e\xef\x8e\x9b\xca\x72\x99\xbd\x05\x79\x35\x0e\x8c\x70\xf1\x15\x69\x1d\x97\x8f\x10\xce\xb5\x8c\x6f\xde\xfc\xf0\x26\xbb\x76\x77\x7f\xab\x45\xf4\x11\xc0\x6e\xb7\xf0\x5c\x75\x1d\x9e\xd9\xbb\x58\x3f\x04\xd4\xad\x22\x7d\x73\xaf\xa8\x4d\x38\x34\xf3\x03\x18\x29\xc4\x94\xfd\x7c\x61\x13\x02\x1e\xf2\x5f\xb9\x60\x71\x66\x3b\x26\xdd\xa6\x90\x1e\xc6\x52\xd9\xa2\x80\x4d\xb6\x04\xaf\xef\xb5\x11\x5e\xd2\xce\xa2\x02\x7f\xc6\x43\xfe\x4e\xb8\xc2\x0a\x25\x34\x79\x63\x7f\xee\xed\x9e\x14\xcf\x53\xce\xbe\xb5\x3a\x96\xb4\x42\xfb\x0a\xeb\x6f\x3f\xaf\xef\xcf\x7e\x24\xd9\xf2\xdd\xc8\xdc\xb4\x57\x9a\xe7\xf6\x96\xe8\xba\x3c\x84\xdb\x4e\xe8\xba\x28\x66\x79\x00\x67\x1f\x4e\xec\x17\xad\x70\xff\xa3\x15\x2f\x68\xd8\x9c\x49\xfe\xbb\x1f\x19\xee\x1c\xd1\xfc\x95\x8e\xfc\x17\x84\xf8\x11\x67\x92\x2f\x81\x4c\x97\xe2\x70\xa5\x03\xb3\x2f\x87\x3f\x20\xc9\x64\x0a\xa6\x11\x49\x6e\x96\x80\x3c\xb1\x15\x91\xc3\x75\xe0\x93\x92\x7f\x07\x00\x00\xff\xff\x5c\xdd\xd1\x0d\x0d\x08\x00\x00") +var _templatesSchemapolymorphicGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x55\x4d\x6f\xdb\x46\x10\xbd\xeb\x57\x3c\xa8\x2e\x2a\x19\x2e\x05\xa4\xb7\x00\x3d\xb8\x0d\x1a\xe8\x52\x07\xb5\x9b\xfb\x84\x1c\x9a\xdb\xee\x07\xb3\x3b\x74\xa2\x2e\xf8\xdf\x0b\x2e\x29\x71\xa5\xd0\x75\x7a\x89\x8e\x9c\xd9\x99\x37\xef\xcd\x1b\xc5\x88\x8a\x6b\x65\x19\xeb\x50\x36\x6c\xe8\x9d\xd3\x07\xe3\x7c\xdb\xa8\x72\x8d\xbe\x5f\x01\x72\x68\x19\x31\xa2\xa5\x50\x92\x56\xff\x30\x8a\xdf\xc9\x30\xfa\x1e\xca\x0a\xfb\x9a\x4a\x46\x5c\x01\x31\xfe\x08\x55\xc3\x3a\xc1\xc6\x79\x14\xfb\xb0\x3f\xc5\x8b\x7d\xb8\x17\xcf\x64\xb6\xe8\xfb\x18\x77\xd7\x2b\x4c\xbf\x5b\x7c\xa0\xc0\x63\x17\x15\x40\xfa\x13\x1d\x02\xde\x93\x56\x15\x09\x7d\xd0\x5c\x9c\x52\xff\xb4\x15\x7b\x58\xe7\x0d\x69\x94\xce\x56\x4a\x94\xb3\xe1\x06\x9f\x18\x25\xd9\x1f\x04\x0d\x3d\x31\x28\xab\xe8\x79\x78\xc3\x15\x68\x86\x80\x0b\x70\xaf\x21\x8d\x0a\x28\x1b\x2e\xff\x1e\x20\xfc\xd5\x05\x41\xed\x3c\x02\x59\x25\x87\x31\xb0\x2d\x56\x27\x1c\x7b\x0b\x69\x78\x24\x2e\x41\x80\xab\xd3\x97\x6c\x12\x09\xac\xeb\x9b\xb1\xb2\x61\xb2\x01\xd2\x90\xa4\xac\xce\xf2\xe7\xd6\x79\xe1\x0a\x41\x7c\x57\x0a\x1a\xa7\x2b\x65\x1f\x4f\x0d\x5e\xaa\xde\x50\x00\x1d\x39\xe2\xcd\x16\x75\x67\x4b\x90\x1d\xc6\xfc\xd5\x59\xe1\xcf\x32\x04\x65\x0e\x8e\x24\x5e\xef\x92\xa2\xe3\xcf\x77\x56\x94\xe1\x22\xa3\xfa\x8b\x58\x56\x6c\x4e\x19\x74\x66\x5b\x8d\xdb\x11\x23\x3c\xd9\x47\x46\x71\xab\xf5\x5d\x8d\xa9\xc1\xb4\x0b\xc5\x3e\xdc\x5a\x67\x0f\xc6\x75\x01\xa7\xde\xf3\x9b\x77\xde\xb5\xec\x45\x71\x16\x4d\x71\x55\xe3\xaa\xd8\x87\x87\xae\xd5\x9c\x36\x06\xc2\xa6\xd5\x24\x8c\xb5\x0c\x1f\x6b\xc5\xba\xda\x0f\xf2\xad\x51\x8c\x19\xac\xc3\x98\x3b\xa7\x8e\xfc\x2e\xe5\x1e\xf1\x1f\xc1\x5e\x7c\xc8\xda\x19\x6a\xef\xfc\xbd\x56\x25\xbf\x65\x11\xf6\x63\x8d\xd3\x94\x53\xd7\xf9\x65\xf1\xd6\x3d\x0c\x22\xe5\x39\x33\x5b\x8b\xd4\x7d\x49\xc3\xc4\x5f\xce\xc1\x12\xb6\x45\x2a\x9e\x87\xf6\x12\x31\x2f\x03\xfe\x0a\x5a\xfa\x55\x76\x34\x4a\x32\x7c\x7e\x33\xce\x61\xa4\x9b\xf3\x8b\xab\x0e\x47\x65\x76\xd7\xb9\x3f\x94\x69\x35\x1b\xb6\x42\xb9\x11\xe6\xb3\xb3\x79\xb8\x7b\x73\xb7\xa9\x3d\x57\xdb\xd7\x20\x31\x93\xe1\x54\x48\x57\xa8\x0b\x5c\xdd\x40\x85\xd0\x31\xbe\x7b\xf5\xd3\xab\xed\xd1\x00\xc3\x54\x8b\xd4\x27\x02\x76\xbb\x85\x73\xd7\xf7\x78\x64\x09\xa9\x7f\x8c\x68\x3a\x43\xf6\x6c\xae\x84\x4d\x05\xb4\xf3\x01\x4d\x2c\xa4\x92\xc9\x9f\x9b\x18\x71\x55\xfc\xc1\x25\xab\x27\xf6\x53\xd1\xeb\x9c\xa4\xab\xa9\xd5\x76\x11\xc0\x66\xbb\x44\xde\xb0\x6b\x13\x79\xd9\x3a\xab\x1a\xfc\x11\x57\xc5\x1b\x15\x4a\xaf\x8c\xb2\x24\xce\xff\x36\xc8\x7d\x42\x3c\x9b\x9d\xa5\xf3\x36\xb5\xf4\xca\x4a\x8d\xf5\xf7\x1f\xd7\x97\x6f\xdf\x93\xee\xf8\xc2\x32\x67\xeb\x95\xd7\x39\x9f\x12\x7d\x5f\xc4\x78\xbe\x09\x7d\x9f\xc0\x2c\x1b\x70\xd6\xe1\x9e\x65\x51\x8a\xf0\x0d\xa5\x78\x06\xc3\xe6\x89\xf4\x7f\xeb\xb1\xc5\x85\x22\x96\xbf\x52\x91\xff\x43\x21\x7e\xc6\x13\xe9\xe7\x88\xcc\x3f\x25\x73\xe5\x86\xb9\xad\xc6\x7f\x50\xd2\x99\x0b\x4e\x16\xc9\x26\xcb\x88\xbc\x67\xaf\x12\x0f\x47\xc3\x67\x2d\xff\x0d\x00\x00\xff\xff\x41\xad\xdc\xe8\x4d\x08\x00\x00") func templatesSchemapolymorphicGotmplBytes() ([]byte, error) { return bindataRead( @@ -402,8 +428,8 @@ func templatesSchemapolymorphicGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/schemapolymorphic.gotmpl", size: 2061, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd8, 0x38, 0x31, 0x5b, 0x7b, 0xaf, 0x27, 0xcd, 0xb5, 0x5f, 0x2d, 0x20, 0xa9, 0x78, 0xd9, 0x99, 0xfb, 0xc6, 0xb8, 0x2a, 0x88, 0x27, 0xdd, 0xd5, 0x59, 0x3f, 0xa5, 0xee, 0xdc, 0x33, 0x74, 0x7a}} + info := bindataFileInfo{name: "templates/schemapolymorphic.gotmpl", size: 2125, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x95, 0x81, 0xb5, 0xb0, 0x9e, 0x91, 0x1d, 0xa4, 0xde, 0x61, 0x53, 0xa, 0xdc, 0x28, 0xc1, 0x77, 0x7c, 0xda, 0x72, 0xfe, 0x8d, 0xc6, 0x82, 0x2, 0xf1, 0x30, 0x41, 0x46, 0x35, 0x40, 0xde, 0x71}} return a, nil } @@ -427,7 +453,7 @@ func templatesSchematypeGotmpl() (*asset, error) { return a, nil } -var _templatesSchemavalidatorGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\x5b\x73\xdb\x36\x16\x7e\x5e\xff\x8a\xb3\x9e\xec\xae\x94\xba\x54\x1f\x3a\x7d\x50\x37\x3b\x93\xa6\x69\xeb\xd9\xa6\xc9\x34\x4d\x1f\x36\x93\xd9\xc0\xd4\x91\x84\x86\x02\x19\x80\x94\xed\xd5\xe8\xbf\xef\x00\xe0\x05\x04\x01\x8a\xd4\xc5\x96\x5d\xf9\x49\x22\x41\x5c\xce\xe5\x3b\xe7\x7c\x00\xe5\xd5\x0a\x26\x38\xa5\x0c\xe1\x3c\xe1\x74\x41\x53\xba\xc4\x29\xc5\x68\xb2\x24\x11\x9d\x90\x34\xe6\xe7\xb0\x5e\x9f\x01\xac\x56\x40\xa7\x10\xfc\x8a\x9f\x33\xca\x71\xa2\x2f\xd2\x29\x20\xe7\x30\x7e\x06\x79\x73\x2c\x1b\xe8\xf6\x84\x4d\x60\x80\x9f\x21\xf8\x31\xfe\xed\x36\x41\x38\x17\x29\xa7\x6c\x76\x3e\x84\x01\x8b\x53\x08\x2e\xc5\x2f\x59\x14\x91\xab\x08\x87\xb0\x5e\xbf\x55\x37\x57\x2b\x40\x26\x07\x18\xe4\x63\xbe\x21\xe9\x1c\xd6\xeb\xd5\xca\xfc\x88\x91\x40\x58\xaf\xcf\xcf\xcb\xe6\x17\x72\x8e\x09\xa7\x2c\x9d\xc2\xf9\xdf\x3e\x9f\x43\xf0\x73\x1c\x92\x94\xc6\xac\xb8\x49\xa7\x20\x47\x1d\xc4\x5c\x8e\xfc\x9c\xc5\xec\x76\x11\x67\xc2\x9e\x86\x1c\x28\x9f\xaf\x9e\x84\xee\x7f\xb5\x0a\x7e\x27\x51\x86\x2f\x6f\x12\x8e\x42\xe8\x7e\xbb\xf7\x3a\x2c\x3b\x1a\x7e\xab\xa4\xf6\xd7\x67\xc0\x68\x04\xab\x33\x00\x00\x8e\x69\xc6\x99\xbc\x7e\x06\x90\xcb\x5b\xb7\xae\x64\xff\x8a\xb2\x9f\x91\xcd\x94\x04\xdc\xc2\x2f\x5b\xec\x57\x74\x5a\x69\x45\x9f\xd5\xb2\x60\xbd\x7e\xda\x2e\x9e\xa1\xec\xb9\x36\xf1\xad\x17\x4f\x6e\x36\x2d\xbe\x68\x71\x64\x8b\x37\x26\xbe\xed\xe2\xdf\x90\x34\x45\xce\xbc\x4b\xcf\xef\x1f\xd1\xc2\x3f\xae\x56\xc6\xac\x3f\xee\x60\xf2\x74\x91\x2d\xda\x0c\x5e\xde\xd7\xad\x25\xce\xbc\xbd\x26\xb3\x19\x72\x0d\x36\x94\xa5\x38\x43\x85\x60\x97\x2c\x3d\x28\xae\xb4\x8d\x4d\xf5\xd8\xba\xe3\x69\x14\x93\x6a\x2a\xdf\x7c\xbd\x93\x57\xe5\xb2\x51\x5f\x5f\xde\x84\x51\x26\xe8\x12\xab\xeb\x3b\xf8\x5a\xbb\xd4\xf5\xfd\x3f\xa7\xd4\x4b\xd9\x58\x52\x2f\xaf\x6f\x2d\xf5\x2c\x4a\x69\x12\xe1\xeb\xa9\x5f\xf0\x65\x93\xfd\x4a\x53\x89\x67\x27\xa9\x98\x73\xdf\x56\x00\x2f\x59\x61\x73\xa3\x91\x5c\x73\x86\x80\x2c\x5b\xd4\x44\xb1\x5a\x05\xbf\x62\x88\x74\x89\xfc\x17\xb2\x90\xf3\x0b\x0a\xe9\xc8\x15\x12\x11\x92\x88\xfe\x0f\x21\xc8\xef\x4a\xc1\xbc\xcd\xa6\x53\x7a\x03\xeb\xb5\x1c\xe0\x10\x66\xd8\x4f\x60\xfd\xa5\xf3\x65\x91\x4a\x05\x97\xe2\x45\x26\xd2\x78\xf1\x43\xcc\x17\x0a\x5d\xcb\x3c\xea\x6d\xca\x91\x2c\xaa\xbc\xea\x3b\x22\xf0\x9b\xaf\x87\xba\x0b\xd5\x61\x8a\x8b\x24\x22\x29\xc2\x79\x2e\x31\x1a\x33\xdd\xdb\x54\xf5\x76\x0e\x41\xa9\x8e\x7c\xf0\xea\xd3\xd9\x6a\x55\xe4\x89\x22\xa2\x21\x76\x4a\x0f\x5b\x13\xc4\xbd\x2b\xa2\xa3\xac\x2d\x69\xfb\xac\x51\x66\x73\xaf\x28\xbb\x4c\x71\x21\x14\x22\xea\x4f\x95\x38\x83\x4b\x36\xc1\x9b\xdf\x09\xd7\x33\x6e\x9a\xde\x5b\xf9\x65\xfc\x0c\x28\x93\xae\x15\xa1\x0c\xcf\xae\x39\x0e\xbd\xa1\xaf\x36\xa4\x3b\xfa\xa9\x26\xfb\x17\x65\x97\xb5\x15\x41\xa8\x98\xe5\x0e\xc2\x6e\xc8\xd7\x1d\x74\xee\x7d\xb1\xd5\x2c\x77\x59\xec\x3b\x46\x3f\x67\xb8\x69\xbd\x46\xab\x7d\x2f\x79\xbf\x9e\x62\xe0\xb6\x42\xee\x69\xcc\x41\x61\x84\xb5\xb2\xbe\xd0\x7d\x08\xb4\xde\xf3\xca\x2d\x4c\x28\x71\x5a\xd7\x82\xf2\x66\x85\x88\xf9\xf7\x9f\x88\xf8\xbd\x84\x5f\x51\x5c\xd5\x78\xad\x72\x98\xf2\xca\xf3\x88\x12\x81\x93\x12\xd2\xf3\xcb\x97\x2c\x45\x3e\x25\x21\xda\x37\x8a\x08\x90\x4f\x07\x94\x22\x56\x2b\xd3\xbc\xa5\x1a\xbe\xfa\xd6\xbe\xf8\x4f\xf0\x83\x93\xdd\xf8\x8b\x2f\x4a\x11\xc9\xf5\x5e\xd3\x74\x6e\x89\xc1\x12\x85\x19\x1b\xf5\x7c\x0b\x89\x54\xb1\xea\x15\x49\x64\x9b\xd7\x4b\xe4\x9c\x4e\x70\x68\x76\xa5\x2c\x48\x5c\x93\x59\x70\x29\xfe\x83\x3c\x1e\x78\x90\x1e\x56\xd2\xf6\x64\x87\x3c\xef\xdf\xe8\x02\x20\x8c\x59\x4a\x59\x86\xc6\xc5\xfa\x74\x4b\xd5\x16\x97\x8c\x78\x99\xf0\x38\x41\x9e\xde\x1a\x41\x2f\xa8\x1a\x37\x9e\xae\xcc\xa1\x16\xc3\x73\x73\x35\x6d\x25\xa7\x0c\xb4\xa2\x61\xc0\xb0\xb9\xb4\x9a\xcf\x68\x76\x62\xf4\x14\x12\x8e\x4b\x64\xa9\x80\x19\x32\xe4\x24\xc5\x09\x84\xf1\x04\x21\x8d\x21\x24\x51\x04\x34\x15\x18\x4d\xc7\x90\xce\xa9\x00\x2a\x80\xa3\x40\xbe\xc4\x89\xb2\x09\x92\x8f\x97\xde\x26\x28\xe0\xe9\xa8\xb6\x12\xaf\xda\xfc\x6a\xa2\x53\x4f\xf8\xb5\x9d\xaa\x21\xa9\x1a\x38\x34\x9f\x0f\x72\x4f\xc1\x81\xce\x50\x84\xdb\x57\x55\x3f\x4b\xbc\x80\xf8\x93\xec\x0a\x39\x0f\x06\x4f\x91\xf3\x98\x8b\xa0\xf2\xb5\xe1\xb7\xf2\xfe\xca\x30\x80\xdc\xc7\x97\x58\x8e\x23\x65\xdc\x13\x72\x86\x67\x4d\x7b\xb2\xc0\xa3\xba\xb5\xa5\x80\x3d\x96\xd6\xb4\x30\x3b\x6b\x33\xd8\xbd\x05\x49\x6a\x39\x9b\x32\xa3\x02\x7f\x05\x90\xc9\x84\x4a\x29\x91\xe8\x8d\x36\x76\x5a\x99\x46\x2e\x90\x9f\x88\x78\xee\x6a\x55\x37\x69\x08\x5c\x8d\x6c\xd8\x33\x9e\x79\x52\x4c\x62\xa2\x0c\x40\x48\x15\xba\x89\xb6\x27\x9f\xf0\x56\xa2\x90\x6c\xe0\x1c\xe4\xdf\xfa\x7e\xde\xb9\x86\xbf\x4d\x4d\x65\x6f\x9c\xb0\x19\xfa\x6c\xb8\x32\xde\x1c\xed\xda\x84\x60\xc7\x01\x0b\xf0\xea\x85\x82\x52\x81\xf8\x44\x13\xb8\x9e\x23\x03\x96\x45\xca\x25\xa5\xbf\x92\x30\xc4\x44\x7a\xb5\xe1\x9d\x4d\x1c\x6c\x88\x6e\xbd\x7e\x6f\xc8\x69\xbd\xfe\xd0\x06\x8b\x16\x24\x5a\x70\x28\x0d\xbd\x58\x85\x03\xb2\x9f\x73\x4e\x6e\x4b\x38\x2a\x83\x9c\x8a\xfb\x72\x01\x09\x8f\x43\x14\x12\x65\xae\x30\x8a\xaf\xad\x75\xdc\x59\x4d\xd0\x41\x42\x1e\x48\xf1\xfa\xb0\x27\x5c\x7c\x99\x17\x82\x6f\x0a\x16\xbd\x1e\xc4\xaa\x06\x05\xda\xd7\x6e\x97\x0d\x0a\xf1\x96\x2c\xb2\x29\xb6\x25\x89\x0a\x90\xeb\xb4\xb6\x06\xe2\xed\x80\x41\xd5\x14\x9a\xb2\xf2\x8a\xc5\x52\x76\x67\x3c\xf7\xa8\xa0\xae\x86\x9d\x97\xe3\xea\xca\x11\xc8\x6b\xb7\xb5\x0d\x9a\xe0\x29\xad\x2d\x96\x13\x28\x34\x16\x5f\xfd\x81\x61\x5a\x0b\xac\x55\x17\x39\xd6\x04\xcf\xa3\xa8\xe0\x79\x7c\x4d\xdc\xe8\x52\x6b\xd9\x35\x45\xa9\x3d\xd4\xd0\x91\x57\x79\x7d\xe6\xb3\xc5\x6c\xdc\x73\xf1\xcc\xa4\xda\x4f\x0a\x2e\xc5\x6f\x59\x12\xa1\x89\xc4\x56\x06\x3a\x1a\xc1\x6f\xaf\xbf\x7f\x3d\x2e\x75\xc4\x66\x46\x84\x03\xaa\x5a\x8b\x79\x9c\x45\x13\x98\xc5\x30\x47\x8e\x17\xb2\xfb\xdb\x38\x03\x81\xa8\xd3\x26\x4e\xa8\x40\x20\x0c\xa8\x10\x19\x2a\x95\xcb\x4e\x07\x53\x09\x84\x63\xa0\x6c\x89\x22\xa5\x33\xb9\xe0\x74\x8e\x10\x12\xa1\xf2\x2f\x8e\x8b\x78\x29\x2f\x91\x14\xc2\x78\xb1\x40\x96\x8e\xc1\x9e\xa9\x1e\x9b\xfd\x43\x35\x41\xa0\x0c\x16\x24\x11\x01\xbc\x4b\x84\xca\xe2\x4d\xe3\xa2\x02\x18\xe2\x44\x26\x6c\x31\xcc\x32\xc2\x27\x40\x66\x84\x32\x91\xea\x79\x1a\x76\x36\x1a\x01\x49\x61\x9e\xa6\x89\x18\x8f\x46\x33\x9a\xce\xb3\xab\x20\x8c\x17\xa3\x59\xfc\xa5\xd0\x3c\xa9\xf9\x51\x2d\x4c\xd8\x62\x6e\x08\xbf\xc2\x5e\xbb\xa9\xa9\x71\xcf\xe6\x61\xd0\xec\xab\x09\x9d\x66\xb4\x71\x71\x5c\x32\x4f\xb6\x0b\xa7\x2a\x26\xe5\xfe\x18\xaa\xa7\x40\x43\x8b\x02\xd2\x90\x24\x69\x26\xc3\x12\x91\x01\xa9\xc0\x65\xcb\x2f\x0b\x64\x3e\xed\x6c\xde\xd1\xce\x66\xab\xa3\x37\x92\xa7\x36\x66\xb3\xf4\xc9\x31\x14\xcd\xd4\x93\x96\xfd\xe4\x8e\x7e\x85\xb0\xc8\xd2\x8c\x44\xd1\x2d\x60\x41\xdb\x4b\xd7\x53\x49\x17\x47\x11\x47\x4b\xe4\x4d\xd8\xee\x43\x9d\xb6\xac\xad\xd0\x6c\x9e\x05\xc8\xfc\xa9\xe1\x1a\xd5\x38\x36\xc9\x1a\xf8\xbb\x7a\x45\x92\x96\x8e\xea\x79\x7f\xd3\x1b\x6d\x02\xa7\x5e\x94\x41\x3f\xca\x46\x5b\xd1\x21\x58\xf6\x83\x24\x72\x9b\xf4\xa4\xed\xfe\x45\xbc\x48\x22\xbc\x79\xad\xc2\xba\x11\x7d\x2e\xdd\xe5\x90\x2f\xc5\xdb\x90\xe0\xed\x27\xbd\xdb\x3a\x1b\x6a\x4b\xed\xee\x23\xb1\xdb\x7a\x21\xad\xc9\x44\x43\xf5\xee\xb0\xd6\x9e\xa3\x1d\x51\x46\xd4\x61\x1e\xbd\x67\xe1\x85\x65\x57\x5e\x70\xaf\x29\xd9\x9e\x92\x1e\x57\x4a\xe2\x32\x9a\xfa\xd5\xc6\x37\x17\x13\xce\xe3\x85\x4c\xec\x1a\x44\x78\x4f\x58\x3d\x08\xa2\xee\x42\x85\x37\x37\x28\xcd\xd0\x56\x47\x3f\xd3\x93\x0d\x32\xbc\xe2\xb1\x5d\x91\xe7\xe0\xcc\x40\xe7\xd5\x7b\x03\x88\x83\x8c\xab\xbc\x41\xc6\xe4\x26\xe7\xe5\x2a\x1b\x73\x61\xc9\xf4\x1f\xae\xb2\x14\x26\x31\x0a\x15\x24\x3e\xb1\xf8\x1a\xc8\x55\x9c\xa5\xe0\x8a\x33\x63\xc0\x60\x16\x00\xd5\x15\x84\xd0\xb6\x46\xe0\x09\xc7\xa9\x83\xd2\xf5\xd3\x0a\x65\x93\x27\x65\x2a\xa1\xa6\x79\x8d\xba\x34\xc9\xfb\x5d\x90\x24\x47\x9b\x3a\x93\x53\x8f\x59\x0e\xa9\x5a\x41\xca\xcf\x9d\x6c\x53\xc1\x3b\x26\xdf\x81\xac\x70\x21\x7f\x67\x0e\xbb\x65\x11\x2d\x31\x52\x5b\x6f\x35\xcb\x25\x89\x2a\xbb\x75\x0f\x5c\xda\xf2\x7e\x83\xeb\x5e\xf8\x12\xbf\x16\x63\xde\xd0\x45\xcb\x63\xbd\x09\x6d\xe3\x18\x82\xa6\x59\x9a\xe7\x10\x46\x4f\x25\xf4\x7e\xff\xf2\xbb\x77\x3f\xea\x93\x24\x0a\x45\xc7\x4a\xbd\x39\x9e\xe6\xd7\x4b\xa8\xd2\x37\x2d\xe4\xca\x5b\x14\x1e\x53\xb6\xa9\xbb\x90\x6e\x55\x88\xb1\x68\x64\x90\xbc\x79\x9b\x02\xc7\xc6\x39\xfa\x9b\xb5\xa6\xee\xa3\xd8\x00\x2c\xfa\x28\x37\x04\xcb\x36\x96\x8d\x8c\x3d\x16\x5b\x8e\x58\x45\x98\xb1\x2b\xe6\x54\xf4\x7e\x2b\x44\x38\xf1\x3b\x2f\x09\xcb\x75\x1a\xf3\x1d\x3e\x50\x3c\xdf\x44\xdc\xd7\xf5\xd1\x8e\x19\xcf\x3c\x63\x32\x1a\x39\xc6\x6c\xc9\x2a\xee\x66\x97\x50\x51\x57\x46\x30\xda\xd7\xc6\xe0\x69\x6b\xb0\x81\x9c\xf7\xb6\x35\x58\xdb\x7c\xf6\x54\x38\x9b\x2a\x8a\x5e\x9b\xe2\xad\xc9\x72\xcb\x30\x9d\x07\x69\xa4\xa0\xee\x03\x73\xed\x85\xc9\xa1\xca\x92\x6d\x8b\x92\x4d\x51\xcf\x21\x10\x73\xcd\xae\x0d\xa8\x96\xad\xa7\x9a\xac\x1b\x01\x35\xa8\x59\x53\x2d\x61\xea\xc9\xfd\xba\xac\xf3\x5e\x28\xdf\x13\xd9\x7b\xe7\x64\xaf\xbf\x4e\xea\x78\x74\xb5\x2f\x03\xeb\xc6\x3e\x07\xed\xda\x85\x70\x75\x98\xaa\xcc\x6d\xa5\x94\xca\xad\xf0\xf2\x9c\x56\xde\xa0\x70\xb3\xda\x61\xad\xd2\x66\xf1\x26\xc4\x24\x55\xa7\x13\x68\x71\xf7\x42\xed\x20\x71\x64\x13\xe4\x94\x4d\x6b\xa7\x74\x54\x65\x48\x05\x24\xc8\xe5\x52\x71\x02\x57\xb7\x60\xf9\xaa\x69\xe0\x9b\xb8\x5f\x73\x45\x7b\x22\x38\x3b\xc1\x88\x0f\xd9\xca\x13\x2a\x16\x7a\x6c\x86\xb5\x1e\x10\x74\x42\x9c\x13\xe2\x3c\x40\xc4\xa9\x57\xd2\x1d\x7d\xbb\xed\xe8\x7e\x38\xc7\x05\xf1\x9c\xdd\x37\xc9\x4b\x7d\x69\xd0\x78\xbf\xa6\xb4\x42\x53\x52\x4f\x66\xb1\xda\x42\x1b\x3f\x33\xd4\x7f\x16\xc6\x4c\xa4\x30\x68\xa4\x96\xb5\xb7\x3c\x8c\xa7\xed\xc3\xd7\xb2\x48\xc8\x7d\x4b\xa8\xf7\x40\xf2\x57\x42\x6c\x5b\x95\x7d\xfd\x65\x43\x3f\xb5\xdb\xf0\xcc\xd9\x87\x9d\xb7\x0e\xad\x24\xf3\xac\x38\xda\xac\x64\x78\xb6\x24\xea\x74\x59\x48\x16\xd8\xe0\x6a\xe1\xfd\x87\x12\xda\x57\xeb\xb3\x69\xc6\x42\xa0\x8c\xa6\x83\xa1\x32\x5a\xf9\xa8\x5c\xd4\xfb\x0f\x35\x8d\x4e\x90\xe3\x74\x8a\x93\xb7\x6a\x00\x29\xc6\x72\x66\x15\x5c\xfc\x21\x62\x16\xbc\x63\x0b\xc2\xc5\x9c\x44\x83\xf7\x1f\xae\x6e\x53\x1c\x7c\x5c\xad\xd4\x9d\x52\xba\x1f\x87\x17\xf0\x77\x8e\xce\xaa\x28\x21\x8c\x86\x03\xe4\x7c\x98\x7b\x8c\x5c\xd5\x7f\x2f\x60\x59\x1d\x85\x93\xb3\x5b\x15\xeb\x77\x2f\xf1\x19\x90\x24\x41\xa6\x0a\x79\x67\x8b\x0b\x58\xea\x01\xd6\x67\x5a\x02\x03\x17\x07\x51\xc1\x80\x85\xf1\xe6\x5b\x34\xb9\x2b\xbc\xbc\x49\x62\x9e\xe2\xc4\x77\x4e\xbf\xce\xa8\x19\x17\x35\x78\xc0\x66\x8e\x3d\x21\xe9\xfc\x02\xa2\x02\xfd\xb4\xb5\x5f\x54\x86\x57\x86\xcc\x32\x42\x36\x62\xa7\xe7\x74\x60\x6d\x39\x9b\x75\x3e\x04\x55\xa4\x2a\x25\x38\x62\x85\x9c\xec\x0b\x22\xd0\x9a\x70\x3e\xd3\x0b\xaf\xd6\x8c\x17\x96\x54\x17\x97\xb0\x5e\x4f\x49\x24\xb0\x12\x5d\xca\x33\xec\x07\xb8\x06\xb7\xb1\x6e\x39\x26\x5f\xf8\xbd\xcf\x71\xaa\x46\x75\xef\xd9\xc9\x7d\x8c\x5a\xaf\xbb\x0f\x99\xd3\x3d\xa8\x23\x55\x03\xb5\x7a\x53\xd9\xac\x9b\x4b\x3d\xad\xc8\x66\x9f\xc7\x3c\x71\xba\x4c\xfd\x72\x17\xa7\x29\x67\x76\x24\x9e\x53\xbe\x9d\xb3\x7f\xf7\x31\x94\x70\xe7\x3e\xb4\xf9\xdc\xb1\x15\xc2\xf3\x50\x65\x10\x19\x09\x8f\x13\xe1\xf5\xbd\xf2\xdc\xc6\x3e\x7d\xef\x18\x43\x57\xb5\xd0\x56\x8f\x2b\x9b\xf5\xf2\xb8\x43\x87\xa8\xea\x74\xcd\x71\x78\xdb\x61\x1c\xcd\x90\xfd\xe1\x1d\xad\x91\xbb\x17\x9f\x47\x23\x28\x98\x5f\xe3\x2d\x09\xc5\xf6\xad\x56\x30\xcf\x16\x84\x99\x93\x2e\x8d\xc3\x93\xe0\xec\x43\x1b\x52\x14\xdf\x53\x11\xca\x24\x89\xa9\xe9\xa8\xcb\x0d\x01\xd6\x4f\x87\xed\x6a\x91\x36\xcf\x2e\x8d\x6d\xba\x48\x83\x5f\x71\x46\x45\xca\x6f\x4d\x0b\xa8\xd0\x41\x5d\x3b\x3b\xf3\x72\xcd\xe6\x9e\x93\x8b\x04\xd6\x2f\x80\x17\xfb\xe4\x0a\xcb\xf4\x31\xbd\x30\x5e\x24\xb1\x50\xb2\xd2\xb0\x58\xab\x39\x37\x95\x7f\x5a\x0d\xd5\xc9\x03\xbb\xec\xac\xf6\xb0\x54\xd3\xea\xb8\x42\x9d\x17\xf0\x15\x8a\x4e\xf2\xa1\x3b\xb7\x5e\x16\xa9\x32\x40\x1b\x9a\x8e\xf9\x0f\xb2\x63\xad\x9d\xee\x53\x83\x9d\xde\xbe\xec\xb2\xd9\x2c\x75\x5d\xe2\x28\x47\x71\x01\x39\x34\x17\x7f\xdd\xb7\x7e\xeb\xac\xbd\xef\x55\x23\x63\x37\x64\xd8\xf1\x1d\x26\xca\x80\xb0\x9c\x2f\x83\xeb\x39\x0d\xe7\xea\x40\x75\x9c\xe6\xbb\x5f\xf9\xd9\x86\xda\xa9\xcf\x6e\x07\x28\x1d\x2b\xe8\x71\x1e\x6a\x87\xe3\x40\xfa\x9d\xe0\x0d\xfa\x69\xd5\x8d\x6f\x97\xa6\x62\x1e\xba\x1a\x59\xfb\x32\x6a\xd3\x1f\x4c\x78\x9c\xbc\x21\xe1\x27\x22\xbd\x40\xfb\xec\xb0\xcf\x56\x5e\x87\x25\xf9\x4e\x10\x74\x71\xd4\x76\x1f\xdd\xbf\x7f\x1e\xce\x37\x3b\x09\xca\x15\xf5\x8e\xc6\x0b\x7b\x51\x5d\x5d\x3d\xcf\x3b\x51\xdd\x40\xce\x11\x52\xf5\x70\x39\x8f\xc3\x7a\x69\x8b\x9e\xdc\x95\xb4\x5a\xa1\x4a\x5f\x07\x36\x65\x32\xb4\xd5\x72\x56\xc5\xd1\xea\x87\x54\x76\x3f\x86\x78\x7e\x7e\x01\xe7\x57\xf1\xe4\xf6\xfc\xc2\xd5\xc3\x8e\x0b\xd5\x69\x64\x84\x4c\xb6\x1a\xc2\xbf\xe0\xab\x46\x22\x17\x73\x11\xbc\xc8\xb3\x00\xac\x3c\xeb\xa5\xbc\x23\x9f\x0a\x82\x60\xe8\x4a\xf6\x3a\xf9\x77\x9b\xeb\xda\x40\x1f\xf8\x18\x8d\xb2\x8c\x96\x08\xe7\x94\xa4\x1c\xfe\x31\x97\x5b\x3d\x24\xe0\xac\xc3\xba\x3f\x6f\x16\x68\xf5\x54\xaa\x0b\x79\x0d\x6d\x04\x76\xbd\x89\x2c\xa0\x99\x1c\x5b\x36\x2a\xb2\xfe\x3a\xc7\x0d\xad\x3c\xb7\x9b\x7d\x31\xae\x96\x23\xec\xca\x84\xef\x36\x52\x77\xae\x1c\x1c\x7c\x39\x34\x38\x73\x39\x98\x09\x42\x1d\x88\xab\xb6\x2a\xa7\x41\x5d\x6d\x45\x75\xf5\x66\xba\x1e\x6d\xd9\xdd\xc7\xd5\xee\xa2\x1e\xb7\x93\xd2\x6e\x24\xb2\xdb\xd0\x37\x51\xcb\x8f\x8f\x59\xee\x2a\x87\x76\xd4\x6d\x7f\xb8\x27\x0b\x7d\x84\xce\xdc\x9f\xb6\xce\x7f\x62\xa7\xf0\xeb\xfc\xab\xed\xdd\xc5\x0f\xf7\x1c\x25\x91\xdd\x59\xbb\xf7\xea\xe5\xde\x7a\xd9\xd7\xe2\xc8\xb2\x30\xe7\xfc\xbb\x03\x84\x67\x71\x8f\x28\x49\x7b\x98\x88\xd1\x07\x2c\x6c\x1d\xfa\x2a\xd2\x26\x80\x34\x1b\xec\x01\x4a\x9a\x16\xf9\xa8\xb3\x07\x27\xb2\xd8\xdf\xbb\xfe\x90\x8f\xbd\xa9\x66\x6d\xa8\xe5\x8f\x18\xc9\x6d\xbf\xbc\xe4\xd1\x6f\xbb\x75\x5d\xfe\x16\xe9\xc8\x76\x5b\x74\x47\x09\x2e\x8f\x7b\x5f\xaf\xb3\x1a\xef\x1f\x1f\x1a\x3c\xfe\xee\x54\xaf\x77\x5f\xf0\x98\x0d\xb2\xcb\x5e\x9f\x29\xaa\xda\xcb\x52\x25\xfe\x6c\xff\xa3\x8d\xb5\xb7\xa5\xfc\x8a\xab\xb1\xd5\x4f\x4c\xaf\x50\xaf\xdf\x9e\x4e\xdc\xde\xe9\x0f\xba\x38\xdf\x09\xdd\xfc\x26\x4f\x97\xea\xc0\xbf\x59\xe1\xd9\x5c\xde\xf0\x7e\xd1\xde\x37\x5a\x4f\x84\xf0\x51\xd6\x1a\x39\xfb\x28\xcd\xee\xc4\x3d\x1e\x73\x6a\x70\xc4\xd5\xc3\x21\xf9\xc7\x13\x01\x79\x22\x20\x4f\x04\xe4\x3d\x11\x90\x2d\xae\xde\x42\x42\x9e\x68\xc8\xc7\x91\x1a\x3c\x4c\xdc\x38\xd1\x90\x0f\x27\x91\xf0\xe0\x4b\xf3\x4a\x37\x32\xb2\x7b\x91\xd1\x8b\x6a\x7c\x74\x05\xc6\x1d\x31\x8d\x5d\xc8\xe0\x87\x89\x31\x27\x36\xf2\x88\x60\xe2\xec\x44\x20\x1e\x98\x40\x3c\x24\x43\xe5\xf9\xdf\x19\xf6\x7f\x12\xeb\x93\x4e\x1e\xb4\xa4\x7c\x40\x59\x63\xc7\x8a\xf2\x54\x3b\xfe\xb9\x12\xc1\x7b\xaa\x26\x2b\x97\x6f\x85\xeb\xa6\x32\xbb\xe8\xba\x1b\x98\xfa\xf5\x5d\x31\xd8\xf6\x1d\xd7\xf9\xe6\xe2\xbf\xe6\x58\xff\x35\xac\xed\x5f\xe4\x04\xfe\xb9\x1b\xbf\xef\xd6\x0e\xb4\x4e\xe8\x69\x62\xab\xf7\x3d\xd9\xea\xd3\xff\x03\x00\x00\xff\xff\x9c\xc8\x2c\x0b\xd2\x7c\x00\x00") +var _templatesSchemavalidatorGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\x5b\x73\xdb\x38\x96\x7e\x5e\xfd\x8a\xb3\xae\xec\xac\xe4\x71\x4b\xd9\xaa\xa9\x79\x70\x4f\xba\xaa\x3b\x49\xcf\x78\x77\xdc\x49\x75\xd2\xd9\xaa\x4d\xa5\xb6\x61\x0a\x92\xd1\xa6\x40\x06\xa0\x7c\x59\x95\xfe\xfb\x16\x2e\x24\x41\x10\x20\x41\x49\xb4\x64\x47\x7e\x92\x49\x5c\x0f\xce\xf5\x3b\x00\xb8\x5a\xc1\x14\xcf\x08\xc5\x70\x92\x32\xb2\x20\x19\xb9\xc5\x33\x82\xe3\x69\x94\xd0\x0c\xdf\x67\xb7\x28\x26\x53\x94\x25\xec\x04\xd6\xeb\x01\xc0\x6a\x05\x64\x06\xe3\x5f\x31\x9a\xbe\xa3\xf1\x83\x7a\x08\xe2\x19\x66\x0c\xce\x5f\x81\xae\x80\x8b\x22\xc3\x28\xbb\x3f\xcb\xeb\xbd\x47\xd9\x35\xac\xd7\xab\x95\xf9\x13\xc7\x1c\xc3\x7a\x7d\x72\x22\x7e\xd3\x29\xac\xd7\xb2\x7c\xca\x08\xcd\x66\x70\xf2\x6f\x5f\x4f\x60\xfc\xcf\x24\x42\x19\x49\x68\xfe\x92\xcc\x80\x26\x19\x0c\x13\x06\xe3\x0b\xfe\x23\x4d\xe8\xc3\x22\x59\x72\xf1\xcf\x2f\xcb\x38\x46\x57\x31\x1e\xe9\x8e\xfe\x9e\x7c\x7c\x48\x45\x07\xc3\xa2\xfd\xd5\x6a\xfc\x09\xc5\x4b\xfc\xf6\x3e\x65\x98\x73\xd5\x6e\x78\xab\xa3\xa2\xa1\xd1\xf7\x72\xde\xff\xfa\x0a\x28\x89\x57\x92\x14\x00\x0c\x67\x4b\x46\xc5\x0b\xf9\x40\x93\x4d\x55\x18\x54\x7e\xb9\x49\xef\xa5\xf9\xd7\x25\x61\x78\x9a\xd3\x7c\xb5\xfa\x4e\x3c\x47\x74\x0a\x43\xfc\xb5\x98\xe7\x09\xcf\x18\xa1\xf3\x93\x11\x0c\xc5\x5c\xac\xa1\x0f\x3c\x6b\xa5\x9a\xfe\x20\xab\x0e\x7b\x58\x2c\x41\xce\x98\x20\x8e\xa7\x1b\xad\x4a\xa5\xba\x87\xfc\xb0\x2a\xc8\xa2\x07\xd9\x3c\xd9\x3e\xa6\x79\x70\x3c\x69\x12\x85\x16\xac\x53\xe1\x50\xc5\x62\xc6\x7b\x4d\x97\x4b\x42\xff\x89\xe9\x5c\x52\xc4\x27\xe4\x45\x99\x9d\x13\x73\xfc\x31\x51\xdc\xa8\x1f\x54\x86\xe3\x9a\x62\xd8\x9c\xd0\xbd\x39\x27\xd7\x8c\xf2\x12\x8f\x30\x23\x63\x30\x81\x33\xaa\x4d\xe8\x3d\xca\x32\xcc\xa8\x77\x3a\xfa\x7d\xcf\x93\xf9\x5d\xd4\xe4\x11\x4a\xf1\x4f\x28\xba\xc9\x48\x74\xc3\xcd\xa1\xfd\xbe\xf9\x7a\x11\x4a\x16\xcb\x45\xa9\xf2\x20\xc3\x8b\x34\x46\x19\x86\x13\x3d\x47\x92\x50\x5d\xea\x04\xc6\x45\x65\xc7\xc2\x87\x34\xa4\x4a\x35\x36\xb4\x8c\x33\x92\xc6\xf8\xdd\xac\xad\xad\xa2\x60\x53\x73\x6f\x69\x3e\xa8\xc9\x44\xac\xda\x12\x03\xa6\xcb\x45\x65\x31\x57\xab\xf1\xaf\x38\xc2\xe4\x16\xb3\x5f\xd0\x42\x2c\xd5\x38\x5f\x5f\xb1\x4c\x88\x47\x28\x26\xff\x87\x61\xac\xdf\x8a\xe5\xf9\xb0\x9c\xcd\xc8\x3d\xac\xd7\xa2\x83\x9e\x14\x7a\xae\x7e\x60\xbd\x3e\x6d\x56\x63\x9b\xae\xbf\xb0\x6d\xe3\x0b\xfe\x7a\xc9\xb3\x64\xf1\x73\xc2\x16\x92\xa5\x0a\xc3\xf6\x21\x63\x18\x2d\x4a\x43\xf7\x13\xe2\xf8\xaf\x7f\x19\xb5\x2c\x8c\x6a\x6d\x26\x5b\x33\x96\xe6\xbb\xba\x85\x36\x4d\x34\x8f\x49\x84\x8f\x4e\x51\x3f\x4e\x51\x41\xc2\x8b\x0c\x2f\xb8\xcb\xc1\x91\x9d\x8b\x97\x25\x95\xf5\xff\xff\x40\xfc\xb5\x5a\x96\x4f\xc5\x12\xf3\x82\x27\x64\x91\x0b\x7e\x41\x33\xcc\x66\x28\xc2\xf6\x8b\x9c\x85\x74\x97\x00\xb3\x84\x09\x81\xbb\xa0\x53\x7c\xff\x09\x31\x58\xaf\xc5\x02\xbe\xfc\xde\x7e\xf8\x37\x88\xb1\x50\xab\x6e\x6e\xaf\x16\xfe\xf3\x9f\x21\x27\x83\x98\xd3\x1d\xc9\xae\xad\xa9\xd6\xd8\x35\x65\x49\x8a\x59\xf6\x50\xe7\xb8\x71\x59\xc7\xb2\xea\x8a\xaa\x35\x41\x32\xdd\xa1\x82\xa8\x7a\x31\xb5\x4f\x35\xa4\x18\x6a\x13\xa9\x28\x1d\xc5\x37\x93\x53\x48\x19\xbe\xc5\x34\xe3\x30\xc7\x14\x33\x94\xe1\x29\x44\xc9\x14\x43\x96\x40\x84\xe2\x18\x48\xc6\x71\x3c\x3b\x87\xec\x9a\x70\x20\x1c\x18\xe6\x98\xdd\xe2\xa9\x24\x2c\xd2\xfd\x65\x0f\x29\xe6\x70\x3a\xa9\xcc\xa4\x94\xf7\x42\xb1\xe4\x82\x7d\x89\x52\xf1\xec\xdd\x2d\x66\x8c\x4c\xf1\xc8\x90\x30\xc1\xcc\xf5\x25\xa8\xaa\x1a\x07\xa5\x2a\xda\xb5\x5e\x7f\x5c\x65\x29\xac\xe4\x55\xe9\x0c\xee\xd2\x66\xba\xcd\x5b\x7c\x06\xc9\x8d\x68\x16\x33\x36\x1e\x9e\x62\xc6\x12\xc6\xc7\x25\x67\x8e\xbe\x17\xef\xcb\x3a\x85\x60\xdc\xe2\xbc\x14\x16\xf4\xee\xa8\xb2\x47\x45\x83\x25\x3f\x59\x12\x57\xbe\xda\x90\xd8\x1e\xae\xab\x73\x9b\x43\x8d\x56\xb4\x68\x60\x7c\xf3\x98\xae\x7b\xa0\xcd\x0a\x54\x63\x42\xb8\x2e\x09\x55\x12\x2e\x5c\x0f\x4b\xad\x81\xa9\x1c\x9c\x26\xfc\x83\xf8\xe7\xfc\x15\x10\x9a\xfd\xf5\x2f\x43\xbf\xa6\x19\x79\x9c\x94\xbc\xf3\x46\xcf\x5d\x16\xd9\x3d\x29\x43\xe6\x96\x7b\xf4\xf9\x28\xb7\x20\x76\x8d\xbe\x6e\xa7\x7e\xef\x93\x2d\x47\xb9\xcd\x64\x7f\xa3\xe4\xeb\x12\xb7\xcd\xd7\x28\xb5\xeb\x29\xef\x56\x52\x0c\xff\x57\x7a\xc0\xc2\x48\x48\x1d\x31\xa8\x29\xe9\x4e\x2e\x70\x1f\x5e\xef\x8e\x67\x1e\xe4\xea\x68\x8d\x58\xba\x3a\x86\x8f\x53\x3a\x31\xc2\xef\x95\xee\x5c\xf1\x44\x1b\xf6\xce\x6e\x90\xf9\xf4\xc3\x0d\x49\xdf\xde\x8b\x10\x0e\xc5\x86\x01\x3b\x0c\x57\xa9\xc1\x82\xe5\x54\x1b\xb5\x5a\xb4\x4a\x63\x26\x79\xaa\x05\xfc\x5e\xc6\x2b\xbd\xf0\x82\x75\x45\x5f\x4c\x77\x6d\xb5\x6e\xfa\x5f\x45\x93\xfc\x0e\xcd\xc7\x17\xfc\x7f\x30\x4b\x86\x1e\x0b\xd4\xde\xb0\xe9\xd2\xa8\x3f\xe1\x30\x12\xba\xc4\xc6\xc3\x2a\xdd\xac\x3a\x4e\xaf\x73\xe7\xee\x66\xc9\xd8\x9d\x7c\x4e\xb5\x80\x1e\x46\xfc\xd6\x5c\xd2\xc2\x17\x3d\xba\xa1\x0e\xfa\xb5\xbb\xa1\x46\x30\xbf\x40\xa9\x37\x94\x2f\x07\xe5\x01\xdc\x15\x1b\x17\xe3\x75\xe9\x0d\xcd\x04\xb6\xc9\x72\x9a\xaa\x42\x89\xd4\xac\x87\x58\xb2\x7e\x3c\x5e\x4a\xe2\xd1\xc0\x92\x60\x43\x68\x1b\x3c\xef\x12\x97\x09\xcf\x39\x28\xa0\xb0\x18\xdb\xc1\xe1\xee\x81\x0b\xb5\x2b\x2c\xde\xe9\x20\xf8\x19\xb8\x70\x18\xfe\x81\xf8\x8f\xd3\x29\x11\x33\x47\xf1\x7b\xa5\xa9\x09\xb6\x5d\x08\x18\xbb\x0a\xb9\x51\x12\xb3\xea\x8b\x7c\xa9\xa7\x52\xf5\x70\xb1\xfa\x6e\x3c\xe8\xc5\x0d\x7e\x10\xc6\x5a\x14\x70\xf6\xf5\x5f\xea\xbd\x6e\x5c\x79\x09\x6d\x45\x45\x6b\x0c\xd1\x39\xf6\x69\xcf\x52\x6d\x6a\xa7\xa0\x89\x16\xaa\xe0\xe4\xf4\x4d\x42\xff\x3d\x03\x8a\x85\x7e\x4f\x00\x4d\xa7\xa0\xc5\xbe\x60\x6c\x98\x12\x86\xa3\x2c\x7e\x80\x6b\xcc\x30\x70\x42\x23\x0c\x77\x18\x10\xc3\xc0\x70\xb4\x64\x9c\xd0\xb9\x61\x15\x4c\x77\xe1\x7d\x9e\xb5\xf3\xf9\x13\x65\xca\xaa\x62\xa2\x75\x01\x2d\x29\x25\x17\x99\x96\xe0\x16\xc5\xb9\x0a\x17\x24\xb7\x17\x67\xbd\xfe\x6c\xac\xc4\x7a\xfd\xa5\xa6\xcf\xb7\xd0\xb0\xe5\x10\xea\xc6\xc5\x63\xbb\x6a\x5a\x63\x23\x00\xc5\x63\x30\xaa\xf6\x64\xeb\xa9\xb9\x9a\x72\xb8\x35\x95\xd7\x4a\x2b\x49\x6f\xa3\x04\x92\x21\x11\x03\xc8\x57\x2f\xb9\xfa\x03\x47\x59\xc5\x85\x28\x9b\xd0\xbc\x3d\xfe\x31\x8e\xcb\xc4\x81\xbb\x88\x9b\x9b\x2b\x25\x3b\xc2\x84\x95\xba\x0e\x97\xd1\xeb\x4b\x86\x0f\x6b\xf3\x41\xb9\x87\xe4\x19\x50\x25\x2b\xf0\x71\x99\x0a\xf3\x5b\xea\x01\x2b\x4c\x98\x4c\xe0\xe3\xbb\x37\xef\xce\x6d\x99\x27\x74\x2e\x54\x81\xae\x04\x44\xd6\xe2\xd7\xc9\x32\x9e\xc2\x3c\x91\x7a\xe0\x4c\x74\xf3\x90\x2c\x81\x63\xac\xdc\x46\x86\x08\xc7\x80\x28\x10\xce\x97\x58\x32\x82\x68\x7c\x38\x13\x81\xc6\x39\x10\x7a\x8b\x79\x46\xe6\x62\xfe\xd9\x35\x86\x08\x71\xe9\x7f\x32\xbc\x48\x6e\xc5\x23\x94\x41\x94\x2c\x16\x98\x66\xe7\x60\x8f\x58\xf5\x2d\x34\x55\x94\x2c\x30\x10\x0a\x0b\x94\xf2\x31\xfc\x96\x72\x19\x96\x99\x2c\x47\xb8\x54\x67\x4a\xa1\xcd\x97\x88\x4d\x01\xcd\x11\xa1\x3c\x53\xe3\x34\xb8\x6f\x32\x01\x94\xc1\x75\x96\xa5\xfc\x7c\x32\x99\x93\xec\x7a\x79\x35\x8e\x92\xc5\x64\x9e\x7c\x27\x82\x8f\x39\x66\xe6\x4f\x39\x31\x6e\x93\xbb\xb6\x08\xa5\x8d\xb6\x8b\x9a\x0c\xd0\xbc\x93\x64\x5c\x6f\xd2\x0e\x4a\xb4\xcc\x35\xe4\x80\x84\x0d\xb6\x03\xe2\x32\xf4\xd3\xc2\x1a\xc9\x5a\x5a\xef\x48\x8d\x1b\xa1\x34\x5b\x0a\xa7\x0e\x71\x28\xc6\x69\x0b\xad\x19\xb5\xb4\xe6\x9a\x0a\x66\x38\x87\xbc\x98\xac\x69\x8d\x58\x73\xd8\x15\x86\xc5\x32\x5b\xa2\x38\x7e\x00\x7c\x1f\xc5\x4b\x2e\xfa\x27\x54\x06\x20\x22\x34\x49\xe2\x5b\xcc\xac\x75\xf4\xf2\x71\x65\x7e\x82\x2c\x9b\x70\xf3\x0e\xf9\x65\x72\xea\xe7\x8a\x96\x0c\x5c\xf9\xe7\x58\x8c\x06\xfe\x10\x26\x94\x31\xf4\x50\xe3\xa9\xb2\x67\x4f\xee\x6e\xdc\xc2\x72\x97\x28\x2d\x96\xdb\x40\x4e\xfc\xfd\x38\xc3\x8a\x90\x5e\xfc\xd8\x83\x03\x26\xab\x46\x8a\x75\xe7\xb5\x11\x18\x53\x9e\x55\x1f\x39\xe1\x76\x1f\xc5\x67\xf6\xbd\x11\x62\xc0\xea\x2b\x4f\xfc\x75\xb2\x48\x63\x7c\xff\x4e\x9a\x60\xc3\x36\x5c\xb8\x3d\x66\x9f\x6b\xf6\x48\x8e\x59\x4f\x6e\xd9\xbe\x9d\xb2\x9d\xb9\x64\x8d\x0e\x99\x1b\x4f\x0b\xf0\xb1\x0e\xcf\x95\x09\x18\xce\xa6\x83\x71\x76\xea\x79\x78\x18\x2e\xd5\x8e\x8c\x90\xc7\x97\x28\x1f\x95\xf0\x51\x15\x3d\x72\x40\x98\xce\x20\xae\xca\xe5\x52\x79\x5b\x5e\x88\x3b\x4e\xd0\xad\x08\xcf\x0e\xae\x96\x19\x4c\x13\xcc\xa5\xa6\xb9\xa1\xc9\x1d\xa0\xab\x64\x99\x81\x4b\x59\x9d\x03\x1e\xcf\xc7\x40\x94\x73\xc8\x61\xc6\x92\x05\x20\x78\xc1\xf0\xcc\x81\x56\xfa\x55\x57\x51\xe4\x85\x1e\xb6\x1e\xe6\x1d\x56\x5e\xa7\x6e\x77\x81\x52\xcd\x97\x46\xe3\x35\xb5\xe7\x08\xd0\x2d\x3d\xe7\x51\xdb\x1b\xea\x07\xc7\xe0\x03\x54\xa2\x4b\x55\x04\xc3\xb3\x0d\x93\x68\x50\xb2\x4a\x9a\xca\x51\xde\xa2\xb8\x34\xa7\xee\x8e\x0b\xd6\xeb\x4f\x3b\xef\x44\x33\xfb\x57\x34\x61\xb5\x75\x69\xa8\xd6\x15\xb7\x95\x5e\xa5\xc3\xb3\x92\xfc\x59\xc5\x74\x2b\x60\xae\x29\x84\x98\x1b\xea\xc9\xd0\xb7\x9a\xc7\x8f\xa0\xef\x11\xf4\x7d\xda\xa0\xaf\x64\x5d\x1f\xf0\x6b\x1a\x27\xb5\x54\xce\x92\x2d\xf9\xde\x67\x0a\x12\x5b\x81\x7e\x89\x20\x54\x37\xb8\x4a\x6d\xc2\x6f\x48\x0a\x77\xd7\x98\x02\x5d\xc6\x2a\x60\x27\x1c\x50\x14\xe1\x34\xc3\x53\x0f\x88\xe0\x8e\xed\x94\xb2\x68\x0f\x1f\x36\x4b\x31\xd7\xd3\xcb\x01\xd1\x59\xd7\x6c\xb3\x95\x69\xf6\x07\xb9\x43\x47\x4a\x5e\x86\xec\x05\x7a\x52\x28\x5d\x19\xa9\x0b\xa2\xa6\x2c\x89\x30\x17\x1e\xd3\x15\x8e\x93\x3b\xcb\x1b\x79\xb4\x7d\x61\xbd\x04\xb5\xcd\xbe\x51\x35\xb3\xd0\x94\x01\x07\xef\x46\x86\x6f\x39\xf1\x10\x9a\x26\xf7\x2c\x13\x1c\x93\x0d\xd5\x92\xa1\xbb\x43\x2a\x95\x1e\x31\xcb\xb0\xf7\xf4\xc2\x31\xad\xb0\x93\xb4\x82\x17\xd6\xf1\xe5\x15\x9a\x12\x0a\x8d\x98\xe1\x1e\x33\x0a\xb5\xf0\xe2\x9b\xf3\xbb\x7b\x3c\xe4\x08\x1b\x60\xc9\x9d\x72\x3d\x8d\xdb\xd1\x1e\x21\x13\xe4\x10\x89\xc0\xa4\xca\x8e\x72\x28\x3d\x27\x4f\x1a\x53\x84\xc7\x34\x48\xbb\x4a\x3b\xe6\x92\x0e\x2d\x97\x64\xaa\x95\x42\xad\xb5\x6b\x92\x1c\x91\xd9\x67\xb6\x69\xcb\x5c\xd3\xce\xfd\xf0\x8d\x27\xd2\xe8\xfb\xed\x3f\xb7\x74\x18\x49\xa5\x7d\x66\x93\x9e\x44\x16\xc9\x9d\x44\xfa\xce\x97\x45\x72\xaa\xdb\xc9\x44\xe5\x59\x16\x28\xb5\x30\xd7\xce\xca\xb7\x17\xbd\xbb\xcd\x11\x97\xdd\x26\xd1\x82\x5c\xad\x63\x8a\xed\x98\x62\xeb\x96\x62\xdb\xa9\x51\x7a\xd2\x69\x35\xf3\x54\xae\x42\x93\xbc\x27\x22\x26\xa7\xf0\x06\x5f\x2d\xe7\xea\x92\x0a\xa9\x80\xce\xe5\x12\x6b\x55\xa4\x9f\x17\x52\xae\x5e\x5a\x42\xaf\x4b\xe4\x52\x53\x94\xa9\x8a\x91\x2a\x95\x93\x32\x2f\x64\xe0\xf0\xba\x4c\x1e\x21\x9f\x6b\xc5\x69\x06\xd5\xea\xbd\xba\x24\x20\x7f\x6f\x5e\xcc\x20\xde\xbb\xb7\xc3\x8b\xb2\x0d\x1b\xe5\xd5\xe0\xf2\xc3\x76\xf9\xe0\x8a\xc3\x77\x45\x19\x8b\x01\xcf\x3d\xe2\x50\x0c\xb5\xd4\xfa\xe7\x2e\x3b\x30\x00\x2b\x4f\xe9\xd3\x40\xab\x47\x3a\xda\x2f\x51\x28\x43\xe1\xee\xea\xe8\xd4\xf1\x3c\xff\x61\x1e\xa4\xaa\x1c\xe7\xf3\x78\xc2\x6d\x9e\xe7\x26\x97\x5b\x34\xba\x56\x0d\xbd\x75\xed\xab\xe6\xb7\x98\xff\x84\xba\xb3\x7d\x6f\x8d\xda\xd4\xa5\x6d\x3d\x0a\x47\xe8\x02\xdd\x97\x64\xac\x9f\x83\xd3\xa0\x9c\x04\x74\x34\x29\xdc\x91\xb0\x27\x57\x3d\x1a\xa9\x26\x2e\x09\x35\x4b\x5f\x9a\xbd\x8e\x1c\x9e\x61\x11\x36\xbb\xda\x74\x61\x4b\x43\xfc\x15\x86\x31\xa6\x26\x57\x8c\xe0\x65\xa1\xdf\x84\xe3\x95\x08\x33\x50\xa8\x2a\x2a\xb8\x43\x66\xb1\xd5\x09\xe5\x5a\xd7\xf9\x31\xea\x86\x3c\xbc\x43\x63\x07\xfb\x23\xa3\x52\xe2\x8c\xa4\x8f\x32\xc7\x2a\x83\x9d\xd6\x36\xab\x34\x48\xbc\x45\xe2\xba\x4b\x31\xcf\x5e\x3a\x0a\xe5\xfc\xc5\xaf\x13\x96\x41\x44\x58\xb4\x24\x19\x87\x45\xa5\xdc\x0f\xf0\x72\x00\xde\x5d\x2e\xcd\xfb\x59\x3e\x26\xc9\xcf\xf8\xae\x6c\xac\x49\x19\x0a\x42\x28\x55\x88\xe9\x34\x28\x66\xb1\xe7\x33\x1a\x84\xbb\x4a\xf2\x49\xc1\x04\x0b\x74\x83\x87\x0b\x94\x7e\x56\x08\xfb\x97\x3f\x78\x42\xc7\xbf\xa2\xbb\x4b\xcc\x39\x9a\xcb\x7b\x1c\xc0\xe2\xaf\xf2\x86\x42\x3f\x87\xfc\x19\xfe\xe3\xa5\xb5\xe4\x7f\x9c\xe5\xe6\x4a\xe6\xe9\xff\x9b\x91\x0c\xff\xe7\x87\x77\xbf\x0c\x1d\xb4\x1d\x99\xa1\x62\x5b\x1c\x66\x96\xd5\x8d\x0b\xef\x47\xb6\xfd\xc7\x19\xfc\x49\xce\x75\x04\x61\x41\x9d\x43\x46\x54\xfd\xba\xa1\x28\xc2\x5d\x27\x0b\x4e\x26\x55\x6e\x3a\x77\x2e\x5c\x3e\x76\xdd\xe3\xdf\x9c\x85\x0e\x8e\xc5\x3c\x64\x30\xb5\x9b\x49\x06\xf3\xb9\x26\x83\xab\x68\x49\x86\x1f\x9c\x85\xfc\x64\xb8\x44\xf4\xa1\x37\x3a\x58\xa3\xf0\xd2\xa1\x62\x75\x8c\x9f\xd5\x88\xa3\xbe\x5f\x6f\x32\x81\x37\x6f\x7f\xfa\xed\xef\xcf\x2b\xd4\x70\xc4\x18\xce\xe0\xe2\x89\x45\x25\x9a\xce\x4e\x44\x45\x93\xdc\xbb\xfd\x4a\xd5\x2d\x8c\x77\x5e\xc1\xca\x5c\xa8\x52\x97\x28\xcd\xdf\x17\xc1\xb0\xee\x9b\x31\xf4\x50\x74\x56\x66\xb0\x8a\x7a\xa6\xe3\x6b\xb4\x61\x3e\xde\x20\xc2\xaa\x6e\x14\x1d\xd6\xf7\x86\x1a\x17\xb2\x88\xee\x46\x41\xd9\xde\xbd\xdd\x57\x13\x16\x5a\x38\xf6\xc7\x55\x99\x0c\x82\xae\x4a\xb1\xfb\xa4\x24\x76\xf4\xd9\xe0\xf9\x6f\x71\x9f\x48\x60\x06\x77\xd7\x71\x70\xc2\x94\xe3\x6c\x31\x8a\xff\x7e\x9a\x91\x91\xcb\xb3\xf2\xb2\xc7\xeb\x45\x00\x3a\x45\xc5\xbb\x23\xfe\x86\xf1\xb2\x91\xe1\xae\x85\x5a\xe3\x5e\xc2\xea\x47\x89\xa7\xfb\x0f\xa4\x0f\x39\x80\x36\x5c\x19\x2f\xc0\x60\xce\xdc\x75\x5b\x44\xc3\x76\xcd\x0a\xc5\x7d\xe8\xec\xb8\xc2\x81\x15\x10\x7e\xb3\xd3\xd8\x2e\xc6\xde\xcb\x96\xa9\x26\x2c\xa5\x2c\x2e\xe3\xe3\xda\x01\xe8\x47\xe4\x0c\x73\x57\x57\xe9\xf5\xf9\x2e\x9d\x57\x25\x8e\x5b\xba\x3a\x6d\xe9\xaa\x5d\x12\xed\xe4\xd2\xe0\xa3\xfa\x83\x36\xde\x2a\x94\xdf\x8e\x98\x6b\x1b\xd6\x9a\x9c\x06\xef\xf4\x2a\x24\xc7\x6d\x8c\x1c\x3b\xbc\x3a\x9c\x8f\xf7\x6d\xee\x4a\x58\x1d\x27\x2b\x00\x42\xad\xd1\x2a\x00\x5d\xa1\x10\xf0\x7d\x84\xd3\x4c\x1e\xfa\x20\xf9\xdb\x33\xb9\xc1\x95\x61\x3a\xc5\x8c\xd0\x59\xe5\x6e\x36\x99\xd1\x25\x1c\x52\xcc\xc4\xac\xf1\x14\xae\x1e\xc0\x0a\x21\xc1\xa0\x41\xe0\x91\xfc\x1e\xf6\xfe\x74\x51\xdc\x26\x0c\xa5\x43\x70\x97\x5d\xf1\xdc\x50\xd6\xd9\xa2\xb8\x22\x97\xfa\xc6\x24\x59\xe1\xb8\x25\xb5\x47\xfd\xe5\x04\x24\x6b\x5c\xb3\xb5\x9d\x6f\x35\xf0\xfb\x33\xef\xee\xbd\xd0\x47\xa6\x3b\x5c\xa3\x59\xe3\xb5\xd6\x6d\xc7\xd5\x0e\xbb\x59\xa2\x9e\x4d\x50\x50\x60\xe6\x2e\xe7\xda\xa2\xdc\x8b\x15\x31\xc3\x25\x77\xa5\xba\x12\xcf\x09\xe0\x80\x1f\xda\x8e\x2e\x6f\x02\xdc\xf4\x7a\x56\xd9\xb3\x17\xcd\x85\x14\xd9\x07\x1f\x8f\x4a\xa4\xff\xc3\x14\x4d\x10\x48\xa0\x39\x73\x88\x74\x0e\xc9\x6d\x73\x08\xff\x49\x72\xf2\x91\x8f\xf7\xc2\xc7\x9d\xf6\xc8\x35\x7f\x14\xb1\xc1\x25\xef\x8e\xc4\xec\xdd\x33\xeb\xe4\x17\x3c\x6e\x40\xbd\x1d\x5e\x03\xe6\x15\x75\x5d\xcf\x51\x3d\x5a\x90\x5d\xdd\xf4\xd9\x2d\x9c\x2d\xf8\xd6\xfc\x59\xe1\xe1\x2e\x00\x65\x87\xe8\x62\xef\x4c\x7b\x0c\x27\xbe\x95\x70\x62\x97\xd1\x44\xb3\xac\x35\x0a\x99\xfb\x03\x47\xd1\x35\x5e\x20\xa7\x9d\x98\x4c\xc0\xda\x85\x5a\xde\x42\x2d\x95\xdd\x6a\x05\xd7\xcb\x05\xa2\x95\x8b\x82\xae\x64\x60\x90\x50\x75\xfe\x5b\xab\x58\x92\x01\xe1\xb0\xe4\x78\x3a\x98\x2d\x69\x04\xc3\xfa\xf7\x51\xa0\xfc\x14\x91\x11\x80\xd4\x42\x13\x4f\x86\xde\xfc\x9e\x9f\x24\xd3\x1b\xc2\x23\x21\x7a\x54\x5e\xa6\x24\x1f\x47\x68\x81\xed\xbb\x72\x0c\xb2\xbe\xbd\x4f\x13\x96\xe5\xdf\x7b\x75\xde\xac\x63\x6c\x92\x33\x1e\x2a\x46\xb4\x69\x35\x8c\xb2\xfb\x7c\xfe\xf9\x6e\xde\x62\x07\x2f\xf0\x8c\xcd\x16\xd9\xf8\x57\x3c\x27\x3c\x63\x0f\x23\xe5\xd3\x49\x06\xbe\x45\x0c\x18\xe6\xf0\xf9\x8b\x7c\x36\xf0\x66\xdb\xcc\xdc\xbf\x2b\x0d\xa6\x3e\xd0\x98\x1f\x38\x91\xf8\xa4\x3a\xaa\x1b\x25\x8b\x34\xe1\x92\x8c\xca\xcc\x55\xa4\xb4\x4d\x60\xd4\x0a\x95\x8e\xac\x2d\xa8\x79\x92\x7d\x54\xe8\x4f\xd7\xe7\xee\xdc\x72\xd5\x7e\xff\x6e\x40\x82\xb1\x90\x6c\x0c\x2f\x4c\x3e\x48\xd8\xcf\xa2\x79\xb5\x76\x81\xa3\x83\xb6\xaf\xfa\x44\xd5\x55\x77\x72\x4e\xf0\xc5\x68\x62\xd9\x5f\x01\x4a\x53\x4c\xa7\x43\x86\xb9\xdc\x74\x37\x32\x8a\x98\xf3\x6c\x3e\x4f\x51\x0d\xca\x7d\x7b\xfd\x8c\x9c\xb2\x7d\x48\xc9\x77\x05\x19\xa1\xc2\xbd\xc9\xb7\x7c\x5e\x93\xe8\x5a\x5e\xc6\x90\x64\x7a\x9b\x81\x3e\x30\x64\x5d\x41\xdf\xe1\xd2\x59\x17\xda\xf8\x5c\x6e\x7c\x34\xbc\xb9\x2d\x8e\xd2\xa9\xef\x64\xb5\xf0\x53\x23\x2f\xd5\x5c\x44\xd7\xb6\x95\x5c\x37\x06\x09\x4a\xf3\x74\x2a\xd3\x18\x4e\x59\x92\xbe\x47\xd1\x0d\x12\x62\xac\xf4\xce\x68\xd3\x33\x0f\x01\xd3\xf4\x84\x4d\x72\x31\xc4\x4f\xa9\x54\x8b\xfd\x54\xc1\xda\xa8\x49\x13\x95\x5b\x6c\x9d\xbb\xe0\xd4\x19\xa5\x48\xd9\x36\x21\x4b\x80\xe2\x3b\xf4\xc0\xe1\x1a\x71\x88\x6e\x9d\x77\x47\xf5\xa9\x7b\x82\x88\x68\xd2\xd0\xbd\x53\x62\x8f\x5a\x66\x93\xa0\x43\x52\x37\xc6\x54\xcc\x78\x04\x3f\xc0\xcb\x9a\xff\x98\x30\x3e\x7e\xad\x8d\x25\x2e\x97\xf0\xad\x78\x23\x6a\x8d\xc7\xe3\x91\xf6\x31\x8d\xdd\x61\xeb\xc1\x60\x3b\xf6\xf0\xfb\x48\xa7\xf9\x61\xc2\x26\xf7\xe6\x85\xc3\xbf\x79\xd1\xe0\xe0\xd4\xca\xab\x0b\xf1\x1c\x2e\x4e\x28\xc3\x6d\xe4\xf7\x68\x2d\xd4\xe1\x24\x4c\x85\xe6\x5e\x26\x95\xc2\x56\xae\x41\x29\xe8\x6e\x9f\xaa\x65\x63\xd1\x71\xdd\x7a\x58\xb7\xa6\xcd\x5e\xd5\x75\x2c\x75\xb5\xce\x40\xcb\xa7\xee\x20\x46\x16\xab\x85\x3a\x9e\x8f\xb9\x9a\xa7\xde\xd5\x23\x19\x6b\x7f\x50\x56\xdc\x0a\xb8\x4d\x86\x78\x31\x4f\xa4\x53\x7d\xfe\xca\xf4\xa1\xa3\x84\xf2\x0c\x86\x35\xa7\xb5\x7a\x97\xc9\x4a\x5d\x51\xc9\x08\xa2\x99\x68\x40\x46\xdc\x45\x8b\x43\xc3\x64\x46\x31\x46\x74\x99\x8a\xea\x9f\x74\xf9\xf1\xa8\xdc\x21\xa2\xee\xda\x50\xcf\xd7\xeb\x1c\x80\xe0\xf2\xd3\xec\xfa\x2b\xed\x76\x40\x2f\xea\xfe\x8b\x55\xcf\x98\xce\x7a\x0d\xaf\x9c\x75\xec\xf5\x1a\x59\x2b\x36\xc8\xbf\x8a\x29\xa9\x3d\x10\xd1\x8c\x2b\xf6\x92\x84\xf8\xfc\xa5\xd8\x4e\xb1\xd2\xd2\x43\x28\xc9\x86\x23\x2b\x10\xaa\x68\xf7\x29\x66\x78\x36\xc3\xd3\x0f\xb2\x03\x41\xf0\x62\x64\xa5\xb5\x94\x27\x61\x7e\xa3\x0b\xc4\xf8\x35\x8a\x87\x9f\xbf\x5c\x3d\x64\x78\xf8\xfb\x6a\x25\xdf\x14\xeb\xf0\xfb\xe8\x0c\xfe\x24\xd4\xbf\xc3\x30\xa6\x88\x92\x68\xa8\x0d\xa1\x68\x5d\xcc\xea\x7f\xcf\xe0\xb6\xbc\xd5\x53\x8c\x6e\x95\xcf\xdf\x3d\xc5\xc2\xac\xfa\x4a\x9c\xc1\xad\xea\x60\x3d\x28\xf4\x47\xfd\xb8\x52\x89\x8d\x58\xc0\x57\x2d\xf0\xdd\x3e\x90\x6d\xbf\xc6\x21\x45\xd9\xf5\x19\xc4\x39\x24\xa4\xe4\xe2\xac\x64\xb4\x1d\xc5\xf1\xed\x6b\x6e\xea\x21\x07\x80\x26\x06\xfb\x1a\x71\x6c\x0d\x58\x8f\xf4\xcc\xbb\x6a\xc5\x97\xee\x2f\xb8\x6c\xe2\x02\xd6\xeb\x19\x8a\x39\x2e\x49\x97\xb1\x25\xee\x86\x42\x59\x5a\x6f\xe5\xf9\xc2\x6a\xae\x21\x7c\x82\x53\x16\xaa\x4a\xcf\x56\xe2\x63\x04\x51\xe1\x32\x64\x0e\xb7\x57\x41\x2a\x3b\x6a\x94\xa6\xa2\x58\x98\x48\x9d\x96\x17\x33\x74\xb3\xb0\x4e\x13\xdb\x1e\xb0\x1d\x90\xe4\x14\x1f\x76\xde\xbd\xf8\x18\x8b\xf0\xe8\x32\xd4\x7e\x85\xb2\x65\xec\xb5\xa9\x32\x70\x01\x79\x84\xcd\x2b\x7b\xc5\x05\x62\xbb\x94\xbd\x43\x34\x5d\xe5\x44\x1b\x25\xae\x28\xd6\x49\xe2\xfa\x36\x51\xe5\x35\x6f\x87\x21\x6d\xfd\x08\x9a\x41\xfb\xfe\x05\xad\x06\xa2\xe4\xbf\x27\x13\xa8\x25\x07\xb8\x3f\x3b\xf0\x7c\xd1\x7f\xfb\x34\x52\x67\x84\xbf\xfd\xd8\xcd\x93\x4e\x03\x94\x9f\x86\xaf\x26\x54\x1b\x33\x01\x76\xe8\xd8\x4f\x0e\x20\x60\x68\xad\x50\x5c\xa3\x42\x0a\xb9\xbc\xe9\x5b\x81\xfe\xfb\xc0\xfc\x0f\x02\x4a\x6f\xc1\xcf\x03\x98\x6c\x17\x10\x7a\xe8\xa1\xc8\xcd\x61\x73\x27\x48\xbe\x09\x3a\xbe\x4b\xf9\xec\x4f\x36\x9f\x1f\x34\xde\x82\x89\x87\x49\x9e\x77\xa0\xaa\x80\x18\x23\x64\xb2\x72\x31\x8e\x7e\xa5\xb4\x61\x9d\xdc\xd1\xb6\x9c\xa1\x74\x71\x87\x36\xac\x32\xb2\x97\x65\x50\xda\xd1\x25\x96\xa0\xda\xb6\x33\x92\xee\xe9\xc9\xc9\x19\x9c\x5c\x25\xd3\x87\x93\x33\x57\x0b\x5b\x4e\xb4\xcf\xfc\x46\x88\x7c\x37\x89\x6e\x0d\x52\xf7\xa1\x1e\x45\xa8\x2d\x34\x9c\x93\x92\xa2\xfb\xe7\x1c\x92\x75\xa0\x80\x33\x56\x0b\xaf\x6f\x06\x71\x55\x57\x2a\x04\x0a\x87\x26\x38\xbc\x5a\x44\x04\xd9\x54\xf4\x2d\x0a\xe5\x91\x41\x15\x31\x87\x06\xd4\x1c\xbc\xc8\xf9\xd0\x86\x6e\x46\x95\x47\x79\xbf\xa3\x83\x86\xd6\xc1\x01\xaf\x43\x0d\x62\x17\x73\x31\xf5\x51\x00\xce\xb5\x9f\xdc\xd3\xb7\x89\x26\x77\x91\xba\xc7\x08\xdf\x6d\xff\x34\x0c\x73\x36\xd7\xb3\x01\xd5\xdc\x61\x1e\xe7\x30\x81\xe8\x50\x3a\x34\x2b\xe0\xe6\xca\x1d\x41\xeb\x03\x14\xe6\xee\x28\xb7\xa8\x60\xc8\xb5\xfe\xd7\x96\x6e\xfd\xf8\x30\x71\xef\xe0\xd5\xdd\xab\x94\x7b\x43\x67\x5f\x89\x03\x73\xc8\x9c\xe3\x0f\x57\x10\x9e\xc9\x3d\x23\x7f\xed\x69\x6a\x8c\x2e\xca\xc2\x5e\x43\x5f\x70\x5a\x57\x20\xf5\x02\x3b\x50\x25\x75\x8e\x7c\xd6\xde\x83\x53\xb3\xd8\xff\x87\x7e\xc2\xd4\xce\xc1\x59\xf9\x37\x5d\xc5\x70\x6e\xbb\xf9\x25\xcf\x3e\x4b\x17\x3a\xfd\x0d\xdc\x91\xcd\x32\x7a\x07\xa9\x5c\x9e\x77\x1a\x30\x78\x19\xf7\xaf\x1f\x6a\x90\xfe\xf6\xa8\xef\xa1\x6e\xb4\x0c\x82\x9a\x5b\x37\x53\x56\x52\x7a\xf5\x0f\x30\x42\xe5\xe6\x1c\xeb\x44\xb9\x78\x68\x1f\xad\xeb\xfc\x49\xe6\xfa\xe7\x98\x5d\x47\xc2\xbb\x7c\x7f\xb9\x72\x79\x66\x43\x2a\xab\x82\x9a\xbf\x30\x45\x52\xde\x70\xd8\x9d\x18\x21\x47\xeb\xf7\x7b\xac\xde\x9e\x49\x65\x19\xfa\x3c\x12\x5a\xc9\x3f\xe6\x34\xdc\xc9\x6c\x5d\x2d\xb7\x8c\xb5\xf1\xc8\x67\xc3\x49\xd2\x5a\x57\xee\x2b\x82\x77\x3e\x9c\x0d\xae\x51\x6a\x60\xf8\xda\xa3\xf6\xfb\x2b\x37\xde\x47\xbd\xdd\xe6\xf7\xdd\x66\xd5\x8f\xe8\xff\x41\x46\x93\x1a\x5f\x16\x6c\x77\x44\x97\x0f\xd9\xf9\x3b\xe0\xf8\xb0\x4f\x84\xf9\x08\x31\x1f\x21\xe6\x23\xc4\xbc\x27\x88\xb9\x41\xd4\x1b\x60\xe6\x23\xd0\xfc\x3c\x5c\x83\xa7\xa9\x37\x8e\x40\xf3\xd3\x71\x24\x3c\xfa\xa5\xfe\x24\x0c\x6e\x0e\x0f\x32\x3a\x81\xc9\xcf\x2e\xc0\x78\x24\x2c\x39\x04\xee\x7f\x9a\x3a\xe6\x88\x37\x1f\x90\x9a\x18\x3c\x7f\x88\x78\x0b\x84\xb8\x05\x14\x3d\x44\x9c\xf8\x71\x21\xb2\x81\x79\xd7\x83\xc7\xab\xed\xe8\xcf\xf6\x1a\xd3\x3e\x21\xb7\x35\x30\xa4\x3d\x06\xaf\xdf\x96\x27\xba\xa7\x70\xb6\x14\xf9\x46\x7b\x51\x5f\xcc\x90\xb5\x0e\xd3\xe6\x06\xae\xee\x5a\xf4\x12\x47\xb7\xdf\xd8\xb8\xba\xca\xf9\xd8\xa5\xfc\xdf\x8e\xd3\x42\x2b\x3f\x32\x48\xa7\xf8\xfe\x13\x62\x62\xbe\x85\xfc\xba\xd5\xf9\xd8\x3f\x5f\xe3\x5b\x6e\xcd\xca\xd9\xa9\xae\xea\xfa\xd8\x7b\xda\xbb\xfc\xf5\xff\x01\x00\x00\xff\xff\xbd\x25\x3f\x98\x0f\xca\x00\x00") func templatesSchemavalidatorGotmplBytes() ([]byte, error) { return bindataRead( @@ -442,12 +468,12 @@ func templatesSchemavalidatorGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/schemavalidator.gotmpl", size: 31954, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf4, 0x45, 0xe4, 0x3d, 0x35, 0x81, 0x2f, 0xdb, 0x7b, 0xba, 0x7e, 0x80, 0x2d, 0x28, 0x7b, 0x73, 0x23, 0x69, 0x4e, 0xfc, 0x8d, 0xdc, 0xa2, 0x16, 0x87, 0x17, 0xff, 0xf7, 0xee, 0x89, 0x9, 0x71}} + info := bindataFileInfo{name: "templates/schemavalidator.gotmpl", size: 51727, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd0, 0xc2, 0x39, 0xa0, 0x71, 0x8a, 0xa0, 0xcf, 0x3c, 0xd5, 0x93, 0xe0, 0xed, 0x21, 0x1b, 0x9c, 0xa, 0x25, 0xbd, 0x5b, 0xfb, 0x2a, 0xd3, 0x57, 0xf8, 0x5a, 0xa7, 0x38, 0x29, 0x59, 0x2b, 0x68}} return a, nil } -var _templatesSerializersAdditionalpropertiesserializerGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x56\x4d\x6f\xe3\x36\x10\xbd\xeb\x57\xbc\x1a\x6d\x56\x2a\x14\xb9\xc9\xde\xd2\xba\xc0\x16\xdb\x02\x2d\xb0\x69\x91\xed\xf6\x62\xe4\xc0\x48\x63\x9b\x1b\x9a\x54\x49\xda\x6e\x2a\xe8\xbf\x17\xfc\x58\x4b\x6a\x24\xc3\x9b\xcb\xea\x46\x6a\x38\xf3\xe6\xcd\xcc\x23\x9b\x06\x15\xad\xb8\x24\xcc\x58\x55\x71\xcb\x95\x64\xe2\x0f\xad\x6a\xd2\x96\x93\x79\x4f\x9a\x33\xc1\xff\x25\x3d\x43\xdb\x26\xf3\x39\x3e\xc8\x2d\xd3\x66\xc3\xc4\x6f\xef\x7f\xbf\xc5\xee\xd3\xca\xc0\x6e\xb8\x81\x7a\xf8\x48\xa5\xc5\x81\xdb\x0d\x3a\x7f\xa8\x8f\x0e\xb1\xd2\x6a\x0b\x77\x36\x59\xed\x64\x89\xb4\x69\x8a\x3b\x2a\x89\xef\x49\xdf\xb2\x2d\xb5\x2d\xbe\x6d\x1a\xd4\xcc\x94\x3e\x2e\x0a\xb7\x8b\xb6\xcd\x86\x91\xd3\x8a\x59\x86\xe5\xfd\xc3\x93\xa5\x0c\xa4\xb5\xd2\x68\x12\x60\x3e\x87\xb1\x6c\x4d\xb8\xca\xf1\xc0\x65\x05\xbb\xa1\x5e\xf8\x04\xd8\x33\x1d\x4c\xae\xd0\x34\xb0\xb4\xad\x05\xb3\x84\x99\xc3\xac\x76\xf6\xcd\x11\xf5\x4f\xaa\x7a\x9a\xa1\x70\x79\x03\x7c\xe5\x82\xe0\x66\x81\x8f\x46\xc9\xe2\x88\xc5\xe3\xc8\x71\x11\x3c\x66\xdf\x7b\xab\xaf\x16\x90\x5c\x78\x3c\x80\x26\xbb\xd3\xd2\xed\x27\x40\x1b\x01\xe8\x72\x8f\xd1\x34\x13\xb8\x7d\xcd\xe4\x9a\x50\x74\x75\x08\x7f\x74\xb9\x2f\x46\x4f\x61\x11\x53\x1a\xff\xed\x9d\x5e\x82\x64\x15\x16\x8e\xe1\x01\xeb\xc1\x85\x2e\xf7\x49\x9f\xc2\xeb\x1c\x9a\xb6\x6a\xdf\x27\x10\x4c\x56\xae\xb2\xb0\x0a\x5b\x56\x27\x08\xb6\xd7\x8e\x99\x2d\x7b\xa4\x74\xcb\xea\xa5\xb1\x9a\xcb\xf5\x7d\xd3\x38\xda\x8a\x37\x23\x7d\x85\xb6\xf5\x3c\xde\xb1\xc3\x3b\x32\x86\xad\xa9\x69\x40\xc2\x38\x24\x5c\x5a\xd2\x2b\x56\x52\xd3\xba\x4d\x0f\x3a\x3b\xb7\x04\xd7\x67\x94\xe0\x24\xc7\x15\x09\xb2\x94\x06\x67\xb9\x2f\x92\xe6\xd2\xae\x30\xfb\xe6\xef\x59\xd7\x8d\x43\x4a\xe3\xea\x44\xb6\x7d\x5e\x5f\xe7\x9e\xc1\xf1\xf9\xd8\x33\xb1\xf3\x7d\xca\x57\x10\x24\x23\x90\x0c\x3f\xe2\xbb\x63\x36\x66\x27\xec\x04\xe1\x5d\x3f\x9b\x72\x43\x5b\xf6\xe7\x53\x4d\xb3\x49\x54\x99\x77\xb8\x52\x1a\x8f\x39\xf6\xce\x65\x60\x25\xd6\x34\xc4\x0b\x1d\x6b\x95\xc3\xfc\xd9\x11\xa2\x87\xc9\xda\xed\x1d\xc5\x7c\x05\xa9\xec\xb8\x8f\xe2\x57\x73\xbb\x13\x82\x3d\x08\xc7\xfb\xc5\xb1\x23\x3c\x9e\xb1\x62\x3f\x2b\xb8\xfb\x3e\xe1\x08\xdc\x2d\x1f\xef\xb1\x08\x19\x25\xdd\x5f\x37\x14\x7f\x39\xf6\x7f\xfe\xa7\xd6\x64\x0c\x57\x32\xce\x85\x3f\x14\xa7\xd7\x57\x3d\x34\x6a\x72\xe2\x4c\x60\xf0\x59\x97\x44\x60\x92\x8b\xa4\x4d\x9c\x9c\xbe\xeb\x89\xe9\xe7\x4a\x29\x97\x56\x81\x79\x31\x8d\xd6\x93\x9a\x3a\x21\xa9\xbd\xe8\x69\x86\x34\xc8\x69\x1e\xe4\x34\xf3\x7c\xbe\x4c\x2d\xa7\xc7\xeb\x94\x4c\x61\x31\xc1\xe7\x33\x1a\xe7\x73\xdf\xfb\xfd\xd4\x43\x17\x4b\x75\x90\x43\xb9\x77\x0b\x93\x0f\xba\x2f\x66\x9d\x46\xcd\xee\xa4\x65\x4c\x34\x24\x17\x79\x5f\x39\xe2\x58\x8e\x03\xcd\xb0\x58\xf4\xe6\xd4\x3b\x88\x00\x5c\xc9\xa3\x8b\x29\xf4\xee\xaa\x1a\xad\x74\x82\xde\xfe\x78\x2e\x13\x78\x5e\x94\x9b\x47\x9c\xe1\x07\xbc\x1e\x9a\xf7\x31\x0c\xd3\x29\x95\x2c\x99\x25\xe9\x5a\xc3\x65\x71\x1d\xd3\x3a\x16\x60\xd9\xf9\xbd\xbc\x72\xc3\xf7\x2a\x7f\xd5\x8d\x03\xab\x6b\x92\x55\x1a\x99\xea\xc2\x2c\xaf\x6e\xee\x8b\xa2\xc8\xf2\x38\x30\xfd\x26\xe8\x3d\x5c\xa4\x1a\x13\x8e\x97\x3e\x5d\x36\x5c\x10\x2a\x6e\x98\x10\xea\xc0\xe5\xfa\xcb\xbc\x63\xdc\xdc\x79\x3e\xce\x1f\x3b\x7f\x79\x95\xc7\xce\xb8\xa5\xc3\x5b\x2a\x55\x45\x3a\x75\xce\x8d\xdb\xb8\x23\xe6\xd6\x2e\x66\x96\x05\xfb\xe2\x6d\x4c\xf5\x83\xf4\xd3\xf3\x0b\x27\x51\x99\x74\x78\xe1\x7a\x3b\xef\x2c\xbd\x08\x55\x3c\xf3\x96\xbd\xc4\xd7\xee\xa9\x73\xb3\xc0\xb3\x07\xc7\x49\x99\x08\xca\xfa\xbf\x13\x93\xaa\xe1\x21\x9d\xf7\xf4\x19\x08\x70\xef\xcf\x7f\x01\x00\x00\xff\xff\xe9\x8a\xbc\x88\x08\x0b\x00\x00") +var _templatesSerializersAdditionalpropertiesserializerGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x56\x5d\x8f\xdc\x34\x14\x7d\xcf\xaf\x38\x8c\x60\x95\xa0\x34\x43\xb7\x6f\x0b\x83\x54\x28\x48\x20\x75\x41\x5b\xca\xcb\x6a\x1f\xbc\xc9\xcd\x8c\xbb\x8e\x3d\xd8\x9e\x0c\x4b\x94\xff\x8e\xfc\xd1\x49\x86\x4d\x86\xe9\xbe\x34\x6f\x76\xec\xeb\x73\xcf\x3d\xf7\xd8\x5d\x87\x8a\x6a\x2e\x09\x0b\x56\x55\xdc\x72\x25\x99\xf8\x5d\xab\x2d\x69\xcb\xc9\xbc\x23\xcd\x99\xe0\xff\x90\x5e\xa0\xef\x93\xe5\x12\xef\x65\xc3\xb4\xd9\x30\xf1\xeb\xbb\xdf\xae\xb1\xfb\x38\x32\xb0\x1b\x6e\xa0\xee\x3f\x50\x69\xb1\xe7\x76\x83\x21\x1e\xb6\x87\x80\xa8\xb5\x6a\xe0\xf6\x26\xf5\x4e\x96\x48\xbb\xae\xb8\xa1\x92\x78\x4b\xfa\x9a\x35\xd4\xf7\xf8\xba\xeb\xb0\x65\xa6\xf4\xe7\xa2\x70\xb3\xe8\xfb\xec\xf8\xe4\xb4\x62\x96\xe1\xf6\xee\xfe\xd1\x52\x06\xd2\x5a\x69\x74\x09\xb0\x5c\xc2\x58\xb6\x26\xbc\xcc\x71\xcf\x65\x05\xbb\xa1\xd1\xf1\x09\xd0\x32\x1d\x96\xbc\x44\xd7\xc1\x52\xb3\x15\xcc\x12\x16\x0e\xb3\xda\xd9\xd7\x07\xd4\x3f\xa8\xea\x71\x81\xc2\xe5\x0d\xf0\xda\x1d\x82\xab\x15\x3e\x18\x25\x8b\x03\x16\x8f\x23\xc7\x45\x88\x98\x7d\xeb\x57\x7d\xb1\x82\xe4\xc2\xe3\x01\x34\xd9\x9d\x96\x6e\x3e\x01\xfa\x08\x40\x97\x2d\x26\xd3\x4c\xe0\xe6\x35\x93\x6b\x42\x31\xd4\x21\xfc\xd1\x65\x5b\x4c\xee\xc2\x2a\xa6\x34\xfd\xdb\x07\x7d\x01\x92\x55\x18\x38\x86\x8f\x58\x0f\x21\x74\xd9\x26\x63\x0a\x2f\x73\x68\x6a\x54\x3b\x26\x10\x4c\x56\xae\xb2\xb0\x0a\x0d\xdb\x26\x08\x6b\x2f\x1d\x33\x0d\x7b\xa0\xb4\x61\xdb\x5b\x63\x35\x97\xeb\xbb\xae\x73\xb4\x15\xaf\x27\x74\x85\xbe\xf7\x3c\xde\xb0\xfd\x5b\x32\x86\xad\xa9\xeb\x40\xc2\x38\x24\x5c\x5a\xd2\x35\x2b\xa9\xeb\xdd\xa4\x07\x9d\x9d\x5b\x82\xcb\x33\x4a\x70\x92\xe3\x8a\x04\x59\x4a\x43\xb0\xdc\x17\x49\x73\x69\x6b\x2c\xbe\xfa\x6b\x31\xa8\xf1\x98\xd2\x38\x3a\x91\xed\x98\xd7\x57\xb9\x67\x70\xba\x3f\x5a\x26\x76\x5e\xa7\xbc\x86\x20\x19\x81\x64\xf8\x1e\xdf\x1c\xb2\x31\x3b\x61\x67\x08\x1f\xf4\x6c\xca\x0d\x35\xec\x8f\xc7\x2d\x2d\x66\x51\x65\x3e\x60\xad\x34\x1e\x72\xb4\x2e\x64\x60\x25\xd6\x34\x9c\x17\x14\x6b\x95\xc3\xfc\xc9\x27\xc4\x08\xb3\xb5\x6b\x1d\xc5\xbc\x86\x54\x76\x3a\x46\xf1\x8b\xb9\xde\x09\xc1\xee\x85\xe3\xfd\xe2\xa0\x08\x8f\x67\xaa\xd8\x4f\x0a\xee\xbe\x8f\x38\x02\x77\xb7\x0f\x77\x58\x85\x8c\x92\xe1\xaf\x6b\x8a\x3f\x1d\xfb\x3f\xfd\xbd\xd5\x64\x0c\x57\x32\xf6\x85\xdf\x14\xbb\xd7\x57\x3d\x08\x35\x39\xb1\x27\x30\xf8\x44\x25\x11\x98\xe4\x22\xe9\x13\x67\xa7\x6f\x47\x66\xfa\xa9\x56\xca\xa5\x55\x60\xde\x4c\xe3\xea\x59\x4f\x9d\xb1\xd4\xd1\xe9\x69\x86\x34\xd8\x69\x1e\xec\x34\xf3\x7c\x3e\xcf\x2d\xe7\xdb\xeb\x94\x4d\x61\x35\xc3\xe7\x13\x1a\x97\x4b\xaf\xfd\x71\xea\x41\xc5\x52\xed\xe5\xb1\xdd\xbb\x81\xc9\x8f\xd4\x17\xb3\x4e\xa3\x67\x0f\xd6\x32\x65\x1a\x92\x8b\x7c\xec\x1c\xb1\x2d\xa7\x81\x66\x58\xad\x5c\x9f\x3a\x80\x52\x4d\x97\x6d\x1c\x3c\x82\x73\x72\x88\xe1\xe7\x32\x73\xd7\xd8\x5c\xb8\x61\x7e\x3a\xcf\x19\xac\xcf\xca\xdb\x23\xce\xf0\x1d\x5e\x85\x2c\x17\x5d\xbf\xb8\x82\x92\xe2\xf1\xff\xb3\x1d\xe3\x3c\x4e\xb9\x54\xb2\x64\x96\xa4\x93\x96\xcb\xf4\x32\xa6\x6e\x86\x96\x31\x7b\xb6\x2e\x7e\xf4\xeb\xbc\x5c\x23\x75\x43\xcc\x2c\x8f\x6d\x35\x96\xca\xe8\x79\x23\xd5\x94\xbd\x3c\xf7\x81\xb3\xe1\x82\x50\x71\xc3\x84\x50\x7b\x2e\xd7\x9f\xe7\xb5\xe3\xba\xd3\x13\x71\x7e\x73\xfa\x2b\xae\x3c\x68\xe4\x9a\xf6\x6f\xa8\x54\x15\xe9\xd4\x05\x37\x6e\xe2\x86\x98\x1b\xbb\x33\xb3\x2c\xac\x2f\xde\xc4\x54\xdf\x4b\xdf\x63\x3f\x73\x12\x95\x49\x8f\xaf\x65\xbf\xce\x07\x4b\x2f\x82\x4e\xce\xbc\x8b\x5f\xe0\x4b\xf7\x20\xba\x5a\xe1\xc9\xb3\xe4\xa4\x99\x04\xff\xfd\xcf\x8e\x59\x6f\xf1\x90\xce\x7b\x20\x1d\xd9\xf4\xe8\xcf\xbf\x01\x00\x00\xff\xff\xe1\x74\x4b\x47\x2e\x0b\x00\x00") func templatesSerializersAdditionalpropertiesserializerGotmplBytes() ([]byte, error) { return bindataRead( @@ -462,8 +488,8 @@ func templatesSerializersAdditionalpropertiesserializerGotmpl() (*asset, error) return nil, err } - info := bindataFileInfo{name: "templates/serializers/additionalpropertiesserializer.gotmpl", size: 2824, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2f, 0x47, 0x3f, 0xb1, 0x62, 0x4b, 0x2b, 0x29, 0x88, 0x51, 0xf, 0x95, 0x6d, 0xcd, 0x3, 0x0, 0x3d, 0xd6, 0x57, 0x55, 0x3f, 0xb3, 0x58, 0x2c, 0xb4, 0x2c, 0x2d, 0x41, 0x26, 0xbc, 0xf, 0x47}} + info := bindataFileInfo{name: "templates/serializers/additionalpropertiesserializer.gotmpl", size: 2862, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe5, 0xaa, 0x7f, 0x2c, 0x81, 0x11, 0x85, 0x37, 0x2f, 0x55, 0xab, 0xb3, 0xd4, 0x6c, 0xaf, 0xef, 0x65, 0x95, 0x4e, 0x49, 0xa, 0x29, 0x76, 0xa0, 0xcc, 0x51, 0x22, 0x54, 0x54, 0x8d, 0x84, 0xf7}} return a, nil } @@ -607,7 +633,7 @@ func templatesSerializersTupleserializerGotmpl() (*asset, error) { return a, nil } -var _templatesServerBuilderGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3c\x5d\x6f\xe3\x38\x92\xcf\xa7\x5f\x51\x6b\xec\xde\x59\x0d\xb7\xdd\xb8\xa7\x43\x06\x39\x20\x93\xcc\xec\xe6\x6e\x66\x3a\xe8\xf4\xdc\x3d\x04\x8d\x05\x23\x95\x6d\x5e\xcb\xa4\x86\xa4\xe2\xc9\x0a\xfa\xef\x07\x7e\x8a\xfa\xb2\x1d\x77\x7a\xa7\xf3\x92\x48\x24\xeb\x9b\xc5\xaa\x62\x29\xab\x15\x5c\xf3\x1c\x61\x83\x0c\x05\x51\x98\xc3\xe3\x33\x6c\xf8\x5b\xb9\x27\x9b\x0d\x8a\xef\xe0\xe6\x3d\xfc\xf2\xfe\x23\xfc\x70\x73\xfb\x71\x99\x24\x49\x5d\x03\x5d\xc3\xf2\x9a\x97\xcf\x82\x6e\xb6\x0a\xde\x36\xcd\x6a\x05\x75\x0d\x19\xdf\xed\x90\xa9\xde\x58\x5d\x03\xb2\x1c\x9a\x26\x49\x92\x92\x64\x9f\xc9\x06\xa1\xae\x97\x77\xf6\xcf\xa6\xd1\x00\xff\xec\x07\x2e\x2e\xc1\x8f\x98\x15\xab\x15\x7c\xdc\x52\x09\x6b\x5a\x20\xec\x89\xec\x52\xa9\xb6\x08\x8e\x4c\x50\x9c\x17\x4b\x3d\xff\x87\x9c\x2a\xca\x36\xa0\xc2\xba\x9d\x21\xa5\x14\xfc\x09\x61\x5d\x29\x03\x6a\x8b\x0c\x9e\x79\x05\x02\xdf\x8a\x8a\x75\x20\x79\x14\x86\x1f\xc2\xf2\x24\xa1\xbb\x92\x0b\x05\xf3\x04\x60\x96\x71\xa6\xf0\x77\x35\xd3\x7f\xaf\x77\xf6\x37\xe5\xe6\x17\x43\xb5\xda\x2a\x55\x9a\x07\xa9\x04\x65\x1b\x39\x4b\xf4\xc3\x86\xaa\x6d\xf5\xb8\xcc\xf8\x6e\xb5\xe1\x6f\x79\x89\x8c\x94\x74\x85\x42\x70\x21\x67\xd3\x13\x0a\x4e\xf2\x43\xe3\xa2\x62\x8a\xee\xf0\xf8\x8c\xd5\x8e\xe6\x79\x81\x7b\x22\x4e\x99\x2c\x31\xab\x04\x55\xcf\x07\xa6\xca\x12\xb3\x43\xc3\x4a\x78\xd9\x4c\x4c\xd8\x93\x8d\x11\x8d\xb6\x26\x23\x5d\x09\xcb\x1b\x5c\x93\xaa\x50\xb7\xee\xb9\x69\x7a\xe3\xd1\x40\x6a\x4c\xe3\x17\xdc\xd7\x35\x94\x44\x66\xa4\xa0\xff\x40\x58\xfe\x42\x76\xda\x6e\xae\xee\x6e\x21\x13\x48\x14\x4a\x20\xc0\x70\x0f\xa3\xd3\x80\x32\xa9\x08\xcb\x30\x59\x57\x2c\x3b\x04\x6d\xae\xf9\x85\x37\x46\x1f\xcb\x1b\x9e\x55\xda\xce\x53\x78\x33\x89\xbd\x4e\x00\x04\xaa\x4a\x30\xf8\xd7\xa9\x49\x7a\x0e\xc0\x96\xb0\xbc\x40\x21\x2f\xa0\xfb\xb3\x23\x9f\x71\xbe\x23\xe5\x83\x35\xa4\x4f\xd1\x9f\xda\xc6\x96\x7f\xb3\xeb\xd2\x85\x81\xb2\xe6\x62\x47\xd4\x00\x08\x58\x45\x78\xc9\xda\xb9\xb9\x7d\xb8\xe6\x4c\x56\x3b\x6c\xd7\xcc\xea\x3a\xe8\xc0\x0f\x42\xd3\xcc\x3a\xab\xee\x04\xcf\xab\x6c\x62\x95\x1f\x6c\x57\x65\x95\x54\x7c\xe7\xa0\x45\x4c\xf6\xb9\x73\xa6\xb7\xf4\x33\xd3\x78\xb9\x03\x7b\xc2\x72\x3f\xd3\x2d\xbf\x13\x78\x8f\xe2\x09\xc5\xfd\xb6\x52\x39\xdf\x33\x07\x40\xab\x7b\x9e\x42\x0d\xd0\xd8\x89\xa3\xb3\xc6\x26\x6a\x3b\x18\x08\xd9\xbd\xb7\x33\x2a\x89\xf7\xd6\x91\xfc\x7a\x1b\xcf\x5c\x93\x42\x62\x84\xed\x07\xbd\xf9\xbb\xa0\xac\x3f\x58\xb6\xc3\x76\xfa\xf7\x44\xd2\xec\xaa\x52\x5b\x64\x8a\x66\x44\xf9\x65\x7e\x9b\x2e\xc3\x04\x3b\xff\xea\xee\xf6\xbf\xf1\x79\xb8\x20\xcc\x6f\x27\x38\x04\x48\x04\x8a\x03\x0b\xda\x09\x76\x41\x5d\x83\x20\x6c\x83\xb0\x8c\xec\x24\xb1\x4c\xd4\xf5\x5b\x73\x3e\xdc\xee\xca\x02\xf5\x36\x21\x8a\x72\xd6\x8e\xc3\xf8\x5e\xf4\x8a\xbf\xd0\xc3\xc3\xc5\x8b\x08\x3a\x16\x12\x5f\x00\xaf\x6f\x5a\x3f\x6a\x9d\x1a\xc5\x0a\xa0\x7c\xf9\x01\x49\x8e\x62\x01\x8a\x88\x0d\x2a\xa0\x4c\xa1\x58\x93\x0c\xeb\x26\xb5\x0a\x81\x3a\x69\x55\xe4\xf6\xb4\xd3\xd4\x2f\x5c\x05\x4a\x31\x9f\xcf\xea\xda\xa0\x6f\x1a\xc8\x1c\x32\xd8\x12\x09\x8c\x2b\x78\x46\x05\x8f\x88\x4c\x7b\x33\xbf\x60\x96\x06\xc8\x4d\xda\xe1\xd0\x9e\x97\xa3\x8f\x5e\xf2\xd1\x5e\xfb\x32\xc9\xfb\x3d\xf3\x5a\x92\x6f\xe1\xf5\x77\x65\x2b\xf9\xbd\x96\xfc\xff\x0a\xaa\xb4\xe4\x73\xa2\xc8\x6b\xc9\xbd\x74\xa8\xbe\x9e\xdc\xdf\x97\x3a\x38\xa0\x9c\x75\x24\xaf\x05\xcf\xb0\x8d\x5d\x42\x40\x63\xe2\x9f\x48\x48\x77\xf1\x7b\x8b\x60\x54\x8a\xce\xbd\x5f\x44\xb2\x7e\x7b\x18\x89\x7f\x7d\x55\x50\xa2\x69\x5b\x9e\x84\xa0\xd5\x49\x49\x04\xd9\xc9\xa3\xbc\x8c\xa0\xe9\x89\x8d\xae\xe1\xcf\xcb\xbf\x22\x7b\x5f\x2a\xb9\xbc\x57\x82\x66\xea\x03\xca\x92\xb3\x1c\x85\xec\x58\xcf\xdb\x31\xf3\x31\x64\xd4\xb5\xb6\x64\xed\x71\xb8\xa0\xff\xc0\xbc\x69\x16\x50\x0a\xca\x32\x5a\x92\x02\xcc\xa8\xd6\xee\x1c\xf0\x37\xbd\x15\xfc\xc0\x2c\x32\xa3\x19\xa4\x4d\xf3\x26\x12\x42\x3b\x4f\x3f\x21\xcb\x9b\x26\x75\xa0\x8e\x72\x7b\x5c\x9e\x81\xc5\x60\xb7\xce\x66\x5f\x0d\x43\xcf\xea\x53\x27\x70\xbd\x29\xbf\x35\xa9\xb6\xe1\xe6\x72\x52\x2e\xd1\x9c\xfe\x7e\xe6\x7e\x8f\x9d\x6c\x8d\x3d\xe9\xf5\x04\xd0\x34\xa7\xf8\x03\xb7\xfe\xad\x13\xa6\x77\x0d\x93\x9e\xe0\xde\x1d\x8f\x37\xb8\xa6\x8c\x0e\x5c\x82\x73\xc6\x32\x9c\xce\xed\xe0\x6a\x05\x57\x65\x59\x50\x94\x36\x11\xd1\xd9\x87\xd7\x8a\xe5\x7b\x6b\x4e\x25\xa0\x12\x24\x2a\xd8\x53\xb5\x35\x93\x0c\x2c\x90\xd9\x16\x77\x98\x0c\x3d\xf0\xed\x8d\x8e\x2c\x2b\xb5\xbd\xb0\x91\x4b\x25\x51\x80\x0d\x91\x16\x7a\x9e\x74\x0f\x29\xcc\xbf\x5c\xd9\x0b\xeb\x8d\xd3\xbe\x5e\x19\x2d\x16\x53\x8e\xfa\xd1\xd0\x4f\xb4\x30\x34\x09\x8e\xe2\xf4\x14\xed\x34\x13\x8e\x3a\x16\x75\x1b\xd8\x1c\x96\xb5\x89\x59\xdd\xce\x98\x99\x63\xef\x9e\x57\x22\xb3\x39\x81\x11\xf9\x09\xc2\x55\xfc\x33\xb2\x3f\x5a\xa0\xa4\xa4\xf0\x19\x9f\xad\x48\x63\x89\xb6\x47\xe2\x5a\xf0\x9d\x7e\xb4\x2c\xea\x33\x52\xfb\x02\x78\x88\x64\xf0\xe9\xb5\x14\xf0\x5e\xcb\xe7\xdf\xa3\xad\x72\xa2\xfc\x16\x20\x33\x5e\xa2\x84\x87\x4f\x7f\xb0\x40\x39\x31\x1c\x3c\x9a\x88\x77\x28\xd6\x2f\x90\xd3\xc8\xa3\x16\xda\x01\x2f\xb2\x5a\xf9\xac\xcb\x10\x62\x7c\xb6\xf1\x09\xe1\x29\x87\x1d\x12\x46\xd9\x06\x18\x07\x81\xbf\x55\x28\x95\x04\x22\x10\x1e\x0b\x9e\x7d\xc6\xdc\x27\x04\xc1\xe7\xf7\x53\x81\x00\x69\x3e\xe6\xee\x9a\xa4\x49\x92\xd5\x81\x34\xd7\xd6\x82\x6e\xd9\x9a\x5b\x7f\xec\x9f\x96\x37\x28\x33\x41\x4b\x17\x44\xd6\xf5\xe0\xad\x0d\x80\x6c\x40\xa9\xf7\x64\x5d\xc3\xb6\xda\x11\xd6\x49\xd0\x75\x96\x1c\x9d\x89\xf6\x0f\x78\xb3\x4a\xd4\x73\x89\xe3\xe1\xa7\x26\x4b\x2a\x51\x65\xca\xa8\xdd\x24\xee\xd1\x4f\x2f\x87\x4f\x00\x5c\x41\xa7\x9d\x11\x1d\x4c\xd7\x76\x2c\x69\xd3\x74\x3f\xeb\x78\x66\x9e\x84\xac\x3c\x80\x76\xd9\xf8\x07\xdc\x50\xa9\xc4\x73\x32\xc8\x8f\xe1\x40\x4a\x9c\x0c\xd2\xe1\xb1\xd9\x7e\x30\x19\xe4\xf9\x6e\xab\x25\x83\x54\xbe\x1d\xf8\x39\x70\x6e\xe9\x35\xfb\x34\x12\xc7\xf7\x15\x2d\x72\x14\x29\xf4\xf8\x8c\x73\x5e\xbd\xee\x91\xf3\x22\x49\x8c\x01\x0f\x93\xd7\x50\x5f\x93\x40\x42\x8a\xd0\x9d\x61\x5c\x96\x29\xc9\x55\xc6\x75\xe7\x10\x1d\x1c\x9a\x28\x6d\x40\x4b\x8b\xe0\x56\x99\x4d\x49\xc2\x56\xa1\xdd\x0c\x86\xba\xe2\x9e\xb3\x78\x70\xe1\xc3\x02\xb6\x7c\x8f\x4f\x28\x4c\x15\x30\x23\x0c\x04\x96\x05\xc9\x10\xa8\xd2\x7a\xd3\xaf\x85\x76\x95\x8a\x66\x55\x41\x04\x54\x92\x6c\x50\xe3\x1c\xe1\xc8\xc8\x29\xec\xa9\x5f\x25\x8a\x3b\x22\x65\x34\x87\x72\x96\x8e\xf3\x6a\x99\x18\x49\xd9\xcf\x12\x93\xf5\xa9\xdf\x84\x98\xc6\x58\xb2\x72\xf2\x1e\xdf\xff\xf6\x72\xfb\xa8\x89\x7f\x81\xd0\x46\xca\x16\xe7\xd9\x96\xf5\xf5\xdf\x90\xec\xc6\x38\xeb\xca\xce\xcb\xec\x5e\x1f\x9b\xf9\x8b\x24\x37\x55\xbc\xb1\x35\xfc\xe9\x4a\x0a\x08\xe3\xb6\xb4\xdf\x21\x6d\x7d\x43\xf3\xa1\x99\x5f\xf3\xa2\xe0\x7b\x7d\x12\xed\xe8\x0e\x41\xfb\x67\x79\x11\x0e\x14\x87\xf0\xaa\x28\xee\x51\x50\x03\x5f\xb4\x68\x01\xde\x9a\x20\xec\x67\xcc\x29\xf9\xa8\x3d\xfb\x64\x12\x7e\x88\xbc\xa1\xbf\xec\xac\x1f\x96\x4e\x0e\xb2\xed\x1d\x69\x87\xed\x50\x5e\xf8\xc3\xd9\x6e\xc9\x1b\x3a\xfe\x09\xb6\x47\x22\x8d\x5e\x2c\x12\x25\x2b\x4d\x93\x8c\x09\x27\x04\x71\x1d\xb1\xf8\xfd\x02\x6a\x4b\x14\x28\xf2\x19\xa5\x3e\x13\x04\xd3\xb4\x12\x96\x9b\xdc\x63\xcf\x45\x6e\x1e\x6c\x14\x66\xc5\xe9\x62\x35\x8b\x8a\x2a\x28\x51\xe8\x43\xd3\x86\x38\xad\x35\xdb\x0c\xa8\x3d\x04\x92\xc9\xe0\x72\xcc\xc7\x98\x60\x12\x4e\x8b\x26\xa1\x1b\x4e\xc6\x33\xdb\x80\xf2\x50\x3c\x17\x67\x21\x5f\x2c\x44\xe2\xbd\xd2\x99\x62\x7b\x24\x12\x73\xe0\x1a\x00\xf8\x54\x21\x8a\xfb\xcd\x9d\x18\xcd\x31\xf7\x2e\x2c\x4a\x13\x4e\x13\xf1\x3f\x59\xb4\x6d\x7e\xf1\x85\x72\x65\x40\xb2\x0c\xa5\x8c\xe4\xab\x9d\x5a\x51\xa0\x9d\xcb\xd7\x26\x9c\xa6\x02\x73\x9f\x9a\xbc\x86\x0e\xba\xd9\x85\xc5\xdd\xd7\x81\x0b\xe3\x4f\x35\xf1\x4e\xc6\xf4\x75\x35\x31\x78\x38\x90\xbf\x84\xb8\xa6\xcd\x3c\x3c\xa7\xd2\xcb\x5e\x47\xde\x82\x17\x30\xbf\xba\xfe\x69\xf5\xe1\xfb\xab\xeb\xd5\xd5\xf7\x57\xd7\x29\x3c\x3e\xbb\xa9\xda\xaf\x06\x3d\xc5\xc2\xb1\x0a\x6b\xe5\x8c\x79\x47\x21\x5d\xb4\xf1\x41\x68\x5f\x8d\xf1\x32\x75\x05\x7d\xb8\xf6\x6b\x6d\xf0\x2b\x15\x7f\x41\xa2\x92\x86\xed\xb6\x20\xe6\xf2\x90\x70\x00\x8d\xa6\x4d\x61\x7a\xd2\xa9\x4e\x7f\x05\x0a\xcf\xa8\x16\x9f\x00\xb6\xaf\x9f\xd5\x2a\xba\x33\xd3\x09\x70\x46\x8a\x02\x73\x5b\xd0\x21\xee\x5a\x40\xbf\x17\x98\x21\x7d\xc2\x7c\xa1\x65\x23\xd0\xe4\xca\x21\x6a\xdb\x06\xe0\xab\x15\x3c\x56\x2a\x84\x65\x12\x95\x8d\xc5\xf8\x9e\xf9\x5a\x1b\x95\x49\x7c\x51\xd7\xa6\x43\x26\xf5\xb1\x45\x4d\x89\xfe\x0a\xe3\x8d\x7b\x6b\x8c\x33\x6c\x20\x8b\x69\x70\x09\x19\x31\xf0\x88\x6b\x2e\xd0\x28\xf2\x6f\x1f\x3f\xde\xcd\xef\x53\x90\x66\xae\x29\x43\xb9\xf9\x16\x8c\x69\x83\x20\x3a\xda\x90\x46\xf9\x36\x17\x0c\xde\xcd\xec\x90\x0d\x2a\xc0\xdf\x31\xab\xd4\x41\xd8\x52\xf1\xd2\x6e\xc2\xd2\x76\x4a\x08\xb2\x5e\xd3\x2c\x19\xb9\x30\x75\x37\xa0\x49\xa4\x84\x31\x3e\x42\x65\x6d\x9c\x0b\x30\xd3\xf5\x9e\xcd\x39\x43\x0b\xcb\x68\xc3\x6c\xf0\xa2\x00\x92\x29\xfa\x84\xda\x21\x30\x74\xec\xd8\xd9\x68\xcb\x2d\x96\xd6\xde\xf8\x33\xec\xb8\xc0\xa4\x7f\x7b\xdb\x25\xf9\xda\x8a\xc9\xb5\x72\x40\x41\x19\x02\x11\x1b\x93\xfc\xc3\x46\xf0\xaa\x94\xa1\xbc\x4a\x05\xe4\x6d\x81\x42\x1b\xc0\xb5\x5d\xf6\x13\x65\xf8\xde\xbe\xfc\xab\x5d\xf2\xf0\x49\xee\xc9\x66\x39\x31\xee\x70\xeb\x44\x50\x5b\x1f\x65\x98\x43\xc1\x4d\x73\x49\x9c\x5a\xfc\x64\x5f\x85\x9f\x8e\x5f\x5f\x2e\x97\xf1\x9d\x58\x62\x9b\x61\x7e\x95\xf8\x01\x73\x9e\x19\x13\xc8\x5d\x11\xc3\x7a\x06\xa2\x60\x95\xf3\x4c\xda\x66\x86\x79\x5d\x2f\x3f\xd8\xdd\x20\x5c\x21\x70\xb2\x8c\x93\x06\xb0\xf3\x14\xea\xe4\x5f\x06\x4b\x97\x9d\x04\xff\xd2\xde\x65\xb7\x14\xb5\x43\xaf\x4e\x55\x00\x7d\x22\x65\x4a\x54\x9e\xb0\x7b\x54\xfd\xb6\x84\xe0\x4f\xbd\x4b\x28\xfd\xc8\x4e\xc7\xe0\x26\x7c\x3f\x87\xd0\x21\xaa\xf9\x2e\x04\xf5\xfe\x78\x1e\x25\xbf\x5f\x8a\xb9\x84\xb0\x70\xc0\x46\x48\xd7\x7c\x14\x12\x73\x92\xf9\xc1\xd7\xe2\xc4\x63\x7b\x21\x27\x81\xc8\x51\x4e\xee\x4b\xcc\xac\x16\x88\xad\xcc\x99\x98\x6c\x4f\x8b\x02\x1e\xd1\x3a\x8d\x3c\x1c\x6d\x59\x41\x91\x29\xb9\x3c\x93\x0f\x8d\x6b\xa2\x6f\x67\x94\x01\x33\xf5\xd2\x90\xe5\x08\xee\x9b\xcf\x98\xdc\x5f\xc9\x82\xfa\xe6\x93\x3a\x61\x6b\x52\xc3\x3d\xe2\x11\xe3\xe9\x52\xfd\xcf\xb0\x96\xbe\xa9\xbc\x84\x6a\xbf\xc8\x51\xfd\xa3\x2b\x95\xc6\xd4\xfa\x28\x5e\xc7\xe0\x16\xae\x2b\xa8\x9e\x43\xab\x43\x60\x69\x8c\xab\xb0\x07\x89\xf5\x08\x2d\x91\x1f\x1c\x41\x16\x56\xb7\x20\xe2\x8e\x63\x3b\xf2\x44\x0a\x9a\x9b\x7a\xcb\x19\x94\x76\xb1\xcc\x4d\x12\xed\x4f\x05\x07\xdf\xb1\x60\x67\x2c\x5a\x74\x7e\xe0\x7f\xfc\x0b\x7b\xf7\x31\xc9\xd7\xf2\x2a\xcf\x0d\x02\x0f\x39\x82\xe5\x8f\x1c\x07\x0b\xfd\x08\xc6\xca\xf1\xe1\x70\xc8\x1f\xc7\x99\x3a\x47\x0c\x1e\xef\x3c\xee\x07\x79\x22\x02\x2a\x16\x19\x86\x4f\x7f\x0e\x14\xb6\xe8\x7a\x44\x00\x87\x6b\x49\x97\x97\xc0\x68\xe1\xee\x8d\x3a\xf8\x2e\x81\x94\x25\xb2\x7c\x1e\xbf\x5d\x98\x1b\xc5\x69\x78\xe6\x66\x68\x24\x83\x1a\xef\xe5\x39\x9d\xde\x50\x04\x7a\x25\x7a\x3d\xbc\x63\xf4\x4e\xde\x59\x9d\x40\x7a\x9b\xc6\x9e\x43\xf4\xc8\x3d\xef\x28\x27\xed\xdd\xd2\x08\xf6\x90\x83\x68\x08\xc7\x78\xed\xe7\x7c\x53\x2c\x7e\xad\x1c\xf0\x2c\xd5\xbe\x52\xc7\x89\xa3\x61\x4c\x44\x56\x12\x05\xb2\x0e\xf6\x14\xfe\x13\xde\x39\x5a\x9d\x4f\xd5\xee\xc8\xa4\x50\xeb\xf9\x6c\x47\xa5\xd4\x6e\x3c\xf6\x1d\x17\xf0\x17\x39\xf3\x95\x3a\xb9\xfc\x2f\x4e\x59\x9f\xa1\x05\xcc\x52\x4b\x42\x12\xdf\xe1\x26\x4d\xd2\x49\x0c\x7f\x34\xf5\x7f\x13\x5b\x58\x87\x11\xe7\xca\x04\x36\xf4\x09\x59\x94\x49\xd3\xfc\xbc\xc0\x22\x42\x37\x0f\xd0\x6e\x6f\x42\x74\xf4\xc2\x2c\x31\x6e\x15\x1e\x1a\x56\x8b\xce\x72\xdb\x29\xe6\xcb\xc0\xb1\xf6\xbd\xa4\x33\x14\xa2\x28\x1d\xcf\xd0\x35\xd5\x67\xa8\xbf\x9f\xb0\xfd\x23\x67\x9d\xa2\x03\xfc\x73\x07\x2c\xbe\x8b\xd4\x28\x83\x8f\xb8\x37\xe3\xe9\xd8\x5d\x65\xf7\x82\xa3\x3e\x5e\x54\xd2\x82\x92\x3a\x7e\xb9\xb8\x9c\x6c\x01\xee\x00\x4d\xed\x25\x2c\x98\x33\xf4\xe2\xd2\xed\x69\x4f\xb2\xb5\x53\xb9\xa7\x2a\xdb\xda\x29\x75\x74\x75\x7f\x4a\x97\x4f\x46\xa4\xe9\x26\x59\xde\xde\x34\xcd\x6c\xd0\xac\x37\xde\xfd\xe3\xb9\x78\xd0\x28\x3f\xc1\xe5\x88\xda\x87\x77\x8c\x2f\x2a\xee\x85\xe6\x1f\x7b\xb4\x87\xea\x7b\xa8\x14\x46\x2b\x06\x4d\x12\x10\xb7\xae\xb5\x7d\x15\xa7\x39\xf5\x97\x50\x39\x42\x61\xd4\x98\x19\x70\xa7\x1d\xa9\x76\x1a\x4f\x8e\xf5\xfe\x80\x53\xb5\x56\xbd\x53\xba\x15\x7a\x87\xd5\x23\xba\x18\xb9\xc8\x74\x46\x6f\x76\xc6\xc2\x41\x5e\xde\xb2\x05\xbc\x58\x49\xbd\x26\xa2\x6f\x43\x2f\x86\xa8\x2f\x50\x45\xb7\x0b\xe8\x34\x83\x1f\xde\x78\xba\xb8\xf4\x8b\x44\x3a\xd6\x57\xf4\x0d\xc9\xd8\x93\xf7\x42\x59\xbb\x36\x4b\xdb\x6d\xe4\x8e\x66\x47\xb5\x15\x74\xd2\x6f\xd7\x8e\x0e\xcd\x0e\x3c\x1b\xe1\xc7\xb5\xf2\xf1\xf4\xab\x6d\x3f\x3a\xf7\xd0\xb0\xab\xe7\xe9\x48\x35\xfe\x54\xcf\x3f\x71\x44\x76\x8a\xfd\x2f\xe4\x3c\x34\xde\x74\x4e\xd2\x2c\xb4\xe3\x0c\x0f\xd1\x36\x61\x96\xe6\x6b\xb3\x9f\x6f\x7f\xfe\xc1\x3c\xda\xb6\x3a\xb4\xe9\xa0\x40\xa0\x1b\xc6\xb5\xe8\xb6\x28\xf0\xac\x12\x46\x4c\x5b\x5b\x84\x89\x4d\xf9\x40\xb3\x50\x47\xa6\xdd\x74\xe8\xf8\x11\xea\x81\x2c\x4c\x7c\xd7\xa2\x4e\xfd\x71\xfa\xf7\x05\xec\x54\x7b\x9e\x46\xc4\x75\x8e\xd4\x9d\x72\xcf\xd1\x71\x3a\xfe\xc1\xc8\x81\x8b\xf2\xf8\x98\xed\xde\x95\x47\xe7\xad\xf3\x2f\xc3\x29\xe3\xde\xe6\x60\xb2\x76\x52\xf7\x9e\x09\x45\x4d\x08\x9c\x2d\x80\x7f\xd6\xb2\x18\xa2\xe9\x35\x77\x3d\xec\xd4\xa7\xef\xf4\xe4\xb6\x1d\xd1\x50\xbd\x53\x9a\xca\xec\xd5\xb6\x73\xe8\x0f\xeb\x18\x75\x19\xba\xc6\xfe\x48\xa3\x8e\x69\x3b\xd9\xa8\x43\x9a\x1b\x1b\x75\x37\x67\x3e\x6e\xd4\x1e\xc8\xab\x19\x75\xc7\x72\x87\x5f\xe3\x7c\x3b\x86\x1d\x75\x86\x4c\x1e\x28\x13\xc6\x5d\x1e\x33\xee\xa0\xcf\xc3\xc6\x5d\xbe\x9a\x71\xfb\xcf\x56\xda\x5c\x2f\xee\x45\x0c\xb6\x1d\x2e\xd5\xdb\x7c\x6f\x87\x6a\xcb\x73\xd7\x8e\xa2\xb6\xe7\x58\x6f\x8b\x7c\x6e\xa1\x2d\x0c\xa8\x36\x7e\x8b\x69\x59\x98\x36\x48\x1b\x5b\x8c\x16\x0d\x42\x4b\x69\x27\xc5\x8f\x7b\x94\xed\x3d\x8b\x15\x5a\xb5\x33\x51\xac\x4b\x93\x3f\xf2\x5f\xcb\x12\x3d\x19\xa9\x45\xf1\xf7\x69\x6d\x79\x5c\x0f\xd5\xee\xd3\x77\xf0\xa7\xa0\xa7\x29\x6c\x5a\xf7\xc4\xd6\x68\x66\xab\x99\x9b\x6c\xdf\xc0\x6c\xe6\x26\x6d\x4f\xc3\xf7\xa0\xd7\x7d\x6a\x35\x6b\x96\xb5\x07\xb0\x69\xbe\x8d\xe3\x8e\xb6\xe1\x34\xf4\xe6\x1e\xbc\xed\x3e\xb3\xbe\xe8\x50\xcf\xd3\xb1\x8e\xdf\x69\xad\x79\x92\x3a\x4a\x3b\x30\xad\xf3\x9d\x0b\xee\x3f\xf0\x4a\x91\xc7\x02\x3d\xf6\xf1\x7b\x88\xc5\x10\xe2\x42\xa3\xeb\x57\x41\xb4\x5b\x88\xa7\x41\x8b\x59\x0b\xf8\x0c\xa9\xe8\xa0\xcb\x19\xf0\x35\xc9\xb6\x38\x9f\xaa\x20\xb7\xe2\x5b\xad\x20\xe7\xec\xdf\x14\x64\x5a\x65\xe4\x91\x57\xca\xc5\x8f\x7a\x7f\x2f\xe0\xff\x2a\xa9\x5c\xf3\xcd\x16\x0d\x02\xe3\x08\x7d\x3f\x43\x59\x22\x33\x8d\xea\xde\xb3\x8f\x56\xdc\x86\x7c\x8e\x6f\x9f\x43\xdb\xec\xe4\x6f\xaa\x9d\x7d\x1f\x2d\x03\x4e\x13\xf5\xa0\x25\x2c\x28\x53\x6b\x98\xfd\xe5\xb7\x19\xcc\x2b\xbd\x5d\xb5\x0f\x37\xfb\xd5\x7c\x73\xd1\xa3\xfb\x0b\x81\x0d\x98\x1b\xe3\xe8\xc0\x46\x3d\x8e\xe3\xc1\x26\x38\x26\xb5\xd1\x9e\x40\x3b\x86\xa6\x99\xcd\xba\xb5\xd6\x18\x46\x56\x20\x61\x66\xae\x59\x91\xc6\x45\x4f\x7b\x80\x9d\xdb\x3d\x32\xf5\xad\xfe\xc8\x7e\x72\xfb\x61\x64\x4b\x2d\x27\x3f\xcd\x3b\x54\xb4\x35\xb9\xd7\xa1\x72\xe9\xe1\xce\x29\x7f\x17\x2a\x9e\x30\xfa\x1f\x05\x5a\x59\xa1\x5e\xa9\xb8\xbd\x0a\xb5\xdf\x85\xdd\xdd\x02\x7f\x42\x61\x5a\x2b\xf4\xd2\x8c\x30\x78\x44\xa8\x24\xe6\x90\x53\x81\x99\x2a\x9e\x81\x32\x7b\x0e\xfe\xa4\x33\x36\x76\xc5\x72\x83\x60\x3e\xbb\xf8\x8f\x77\xef\xde\xcd\x16\x40\x4a\x6a\x6b\x89\x73\xed\x45\xd2\xb3\x2b\x9f\xf3\x47\xfb\x09\x00\x1c\xfb\x2a\xc0\x79\x8d\xa1\x51\xdf\x32\xaa\x6c\x77\xc6\xc8\x16\x6a\x9a\x65\xf4\x0d\xc2\x9f\x46\xce\xc5\x31\x90\xed\x12\x4f\x5e\xda\x1e\x63\x47\x5a\x06\x7a\xc0\x27\x8c\x47\x27\x99\x8e\xb1\xb6\x23\xa1\x87\xeb\x05\x30\xda\xa5\xd6\x1a\xb4\x4c\x7c\x6f\xcf\x33\xaf\xb4\x01\x18\xa7\x19\x7c\xa5\x35\x05\x6f\x1f\x99\x76\xcc\x8b\xd0\xbe\xa4\xb6\xa8\x83\xa9\x8c\xef\x4a\x2e\xb1\x7f\x84\x12\x0b\x52\x22\xc2\x9a\xaa\x73\x14\x6f\x35\xe6\x4f\x44\x1d\x3d\x4f\xbb\x91\x54\x7b\xb5\x77\x93\xbe\x78\x78\xba\x84\x8f\x8c\xda\xdb\xd5\x90\xc3\x76\x25\x42\xf2\x1c\xe6\x5c\x98\xcd\x20\x68\x8e\x69\xbf\x0d\x9d\x44\x79\xcc\x59\xc9\x49\x9f\x80\x41\xeb\xc3\xa2\x45\x38\xf8\x87\x15\x13\xc7\xe4\x20\x07\xf4\x20\x4d\xce\xe7\x53\xce\xae\x00\x42\xbe\x73\x5c\x00\x9d\x86\xf4\x57\x13\x80\x27\x60\x44\x00\xe5\x54\xdf\xf9\x61\x01\x44\x79\x42\x2c\x00\x0f\xcd\x17\xa2\xf2\xbc\xdd\xcb\x3a\xc4\x27\x79\x1e\xbc\x63\x64\xd3\x8a\x03\xfe\x4e\xa5\x69\x5e\xf3\x5d\x7d\xe7\xd4\xa5\x7a\xe8\xc6\x82\xfa\x05\x1c\xf2\x78\xf5\x69\x81\xf9\xf1\x50\x7a\x28\x37\xe7\x27\xcd\xfa\x17\x05\xda\x51\x16\x76\x60\xba\xa5\xcf\x2d\x81\x4b\xcf\xe5\x7c\xeb\x77\xe4\xff\x07\x00\x00\xff\xff\x05\x90\xb7\x4c\x17\x4a\x00\x00") +var _templatesServerBuilderGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3c\x5d\x6f\xdb\xb8\x96\xcf\xab\x5f\x71\xae\x71\xef\xae\x55\x38\x76\xb1\x4f\x8b\x0c\xb2\x40\x26\x99\xb9\x37\xbb\x33\x6d\xd0\x74\x76\x1f\x82\xe2\x82\x91\x8e\x6d\x6e\x65\x52\x43\x52\xc9\x64\x04\xfd\xf7\x05\x3f\x45\x7d\xd9\x8e\x9b\xce\xb4\x2f\xad\xa4\xc3\xf3\xc5\xc3\xf3\xc5\xe3\xae\x56\x70\xc5\x73\x84\x0d\x32\x14\x44\x61\x0e\x0f\xcf\xb0\xe1\x67\xf2\x89\x6c\x36\x28\xbe\x83\xeb\xf7\xf0\xee\xfd\x47\xf8\xe1\xfa\xe6\xe3\x32\x49\x92\xba\x06\xba\x86\xe5\x15\x2f\x9f\x05\xdd\x6c\x15\x9c\x35\xcd\x6a\x05\x75\x0d\x19\xdf\xed\x90\xa9\xde\xb7\xba\x06\x64\x39\x34\x4d\x92\x24\x25\xc9\x3e\x93\x0d\x42\x5d\x2f\x6f\xed\x3f\x9b\x46\x23\xfc\xab\xff\x70\x7e\x01\xfe\x8b\x59\xb1\x5a\xc1\xc7\x2d\x95\xb0\xa6\x05\xc2\x13\x91\x5d\x2e\xd5\x16\xc1\xb1\x09\x8a\xf3\x62\xa9\xe1\x7f\xc8\xa9\xa2\x6c\x03\x2a\xac\xdb\x19\x56\x4a\xc1\x1f\x11\xd6\x95\x32\xa8\xb6\xc8\xe0\x99\x57\x20\xf0\x4c\x54\xac\x83\xc9\x93\x30\xf2\x10\x96\x27\x09\xdd\x95\x5c\x28\x98\x27\x00\xb3\x8c\x33\x85\xbf\xa9\x99\xfe\xf7\x7a\x67\xff\xa6\xdc\xfc\xc5\x50\xad\xb6\x4a\x95\xe6\x41\x2a\x41\xd9\x46\xce\x12\xfd\xb0\xa1\x6a\x5b\x3d\x2c\x33\xbe\x5b\x6d\xf8\x19\x2f\x91\x91\x92\xae\x50\x08\x2e\xe4\x6c\x1a\xa0\xe0\x24\xdf\xf7\x5d\x54\x4c\xd1\x1d\x1e\x86\x58\xed\x68\x9e\x17\xf8\x44\xc4\x31\xc0\x12\xb3\x4a\x50\xf5\xbc\x07\x54\x96\x98\xed\xfb\xac\x84\xd7\xcd\x04\xc0\x13\xd9\x18\xd5\x68\x6b\x32\xda\x95\xb0\xbc\xc6\x35\xa9\x0a\x75\xe3\x9e\x9b\xa6\xf7\x3d\xfa\x90\x1a\xd3\x78\x87\x4f\x75\x0d\x25\x91\x19\x29\xe8\xef\x08\xcb\x77\x64\xa7\xed\xe6\xf2\xf6\x06\x32\x81\x44\xa1\x04\x02\x0c\x9f\x60\x14\x0c\x28\x93\x8a\xb0\x0c\x93\x75\xc5\xb2\x7d\xd8\xe6\x5a\x5e\x78\x63\xf6\x63\x79\xcd\xb3\x4a\xdb\x79\x0a\x6f\x26\xa9\xd7\x09\x80\x40\x55\x09\x06\xff\x3a\x05\xa4\x61\x00\xb6\x84\xe5\x05\x0a\x79\x0e\xdd\x3f\x3b\xf2\x19\xe7\x3b\x52\xde\x5b\x43\xfa\x14\xfd\x53\xdb\xd8\xf2\x1f\x76\x5d\xba\x30\x58\xd6\x5c\xec\x88\x1a\x20\x01\xbb\x11\x5e\xb3\x16\x36\xb7\x0f\x57\x9c\xc9\x6a\x87\xed\x9a\x59\x5d\x87\x3d\xf0\x1f\xa1\x69\x66\x9d\x55\xb7\x82\xe7\x55\x36\xb1\xca\x7f\x6c\x57\x65\x95\x54\x7c\xe7\xb0\x45\x42\xf6\xa5\x73\xa6\xb7\xf4\x90\x69\xbc\xdc\xa1\x3d\x62\xb9\x87\x74\xcb\x6f\x05\xde\xa1\x78\x44\x71\xb7\xad\x54\xce\x9f\x98\x43\xa0\xb7\x7b\x9e\x42\x0d\xd0\x58\xc0\x51\xa8\x31\x40\x6d\x07\x03\x25\xbb\xf7\x16\xa2\x92\x78\x67\x1d\xc9\x2f\x37\x31\xe4\x9a\x14\x12\x23\x6a\x3f\xe8\xc3\xdf\x45\x65\xfd\xc1\xb2\xfd\x6c\xc1\xbf\x27\x92\x66\x97\x95\xda\x22\x53\x34\x23\xca\x2f\xf3\xc7\x74\x19\x00\x2c\xfc\xe5\xed\xcd\x7f\xe3\xf3\x70\x41\x80\x6f\x01\x1c\x01\x24\x02\xc5\x9e\x05\x2d\x80\x5d\x50\xd7\x20\x08\xdb\x20\x2c\x23\x3b\x49\xac\x10\x75\x7d\x66\xe2\xc3\xcd\xae\x2c\x50\x1f\x13\xa2\x28\x67\xed\x77\x18\x3f\x8b\x7e\xe3\xcf\xf5\xe7\xe1\xe2\x45\x84\x1d\x0b\x89\x2f\xc0\xd7\x37\xad\x1f\xf5\x9e\x9a\x8d\x15\x40\xf9\xf2\x03\x92\x1c\xc5\x02\x14\x11\x1b\x54\x40\x99\x42\xb1\x26\x19\xd6\x4d\x6a\x37\x04\xea\xa4\xdd\x22\x77\xa6\xdd\x4e\xbd\xe3\x2a\x70\x8a\xf9\x7c\x56\xd7\x86\x7c\xd3\x40\xe6\x88\xc1\x96\x48\x60\x5c\xc1\x33\x2a\x78\x40\x64\xda\x9b\xf9\x05\xb3\x34\x60\x6e\xd2\x8e\x84\x36\x5e\x8e\x3e\x7a\xcd\x47\x67\xed\xcb\x34\xef\xcf\xcc\x6b\x69\xbe\xc5\xd7\x3f\x95\xad\xe6\x9f\xb4\xe6\xff\x57\x50\xa5\x35\x9f\x13\x45\x5e\x4b\xef\xa5\x23\xf5\xf5\xf4\xfe\xbe\xd4\xc9\x01\xe5\xac\xa3\x79\xad\x78\x86\x6d\xee\x12\x12\x1a\x93\xff\x44\x4a\xba\x8d\xdf\x5b\x02\xa3\x5a\x74\xee\xfd\x3c\xd2\xf5\xd9\x7e\x22\xfe\xf5\x65\x41\x89\xe6\x6d\x79\x14\x81\x76\x4f\x4a\x22\xc8\x4e\x1e\x94\x65\x84\x4c\x4f\x6d\x74\x0d\x7f\x5d\xfe\x1d\xd9\xfb\x52\xc9\xe5\x9d\x12\x34\x53\x1f\x50\x96\x9c\xe5\x28\x64\xc7\x7a\xce\xc6\xcc\xc7\xb0\x51\xd7\xda\x92\xb5\xc7\xe1\x82\xfe\x8e\x79\xd3\x2c\xa0\x14\x94\x65\xb4\x24\x05\xd8\xaf\xb7\xfe\xf9\x46\xbe\xab\x8a\x82\x3c\x14\x7a\xfd\x9b\x48\xec\x16\x44\x3f\x21\xcb\x9b\x26\xb5\x8b\x0f\xcb\x77\x58\x83\x41\xa8\x60\xa9\xce\x4a\x5f\x8d\x42\xcf\xce\x53\xa7\x62\x7d\x0c\xff\x7c\x3d\xb6\x29\xe5\x72\x52\x13\x11\x4c\xff\xcc\x72\x7f\x8e\x8e\xb6\xb8\x9e\xbe\x7a\x22\x37\xcd\x31\x67\xde\xad\x3f\x73\xea\xf3\xc7\x7f\xf2\xb4\xdf\xb9\x10\x78\x8d\x6b\xca\xe8\xe0\xd8\x3b\x87\x2b\x43\x04\x6e\x3f\xae\x56\x70\x59\x96\x05\x45\x69\x8b\x0d\x5d\x61\xf8\x7d\xb0\x72\x6f\x4d\xe4\x01\x2a\x41\xa2\x82\x27\xaa\xb6\x06\xc8\xe0\x02\x99\x6d\x71\x87\xc9\xd0\xcb\xde\x5c\xeb\xec\xb1\x52\xdb\x73\x9b\x9d\x54\x12\x05\xd8\x34\x68\xa1\xe1\xa4\x7b\x48\x61\x7e\xca\xf6\x2e\xac\x8f\x4d\xfb\x3b\xc9\x68\xb1\x98\x72\xbf\x0f\x86\x63\xa2\xc5\xd7\x44\x1d\x8f\xe9\x31\xfb\xd1\x4c\xb8\xdf\x58\xb9\x6d\xba\xb2\x5f\xbb\x26\x13\x75\xd6\x3f\x33\xc1\xec\x8e\x57\x22\xb3\x99\xbe\x51\xf2\x11\xea\x54\xfc\x33\xb2\x3f\x5e\x85\xa4\xa4\xf0\x19\x9f\xad\x12\x63\x1d\xb6\xa1\x6d\x2d\xf8\x4e\x3f\x5a\xa1\x74\xac\xd3\x27\x1c\xee\x23\xa9\x3f\xbd\x96\xca\xdf\x6b\x8d\xfc\x7b\x74\x1c\x8e\xd4\xd8\x02\x64\xc6\x4b\x94\x70\xff\xe9\x0f\x57\x21\x27\x86\xe7\x07\x93\xab\x0e\x15\xf9\x05\x9a\x19\x79\xd4\x22\xed\xf1\x0d\xab\x95\xaf\x97\x0c\x23\xc6\xf7\x9a\x93\x1e\x9e\x72\xd8\x21\x61\x94\x6d\x80\x71\x10\xf8\x6b\x85\x52\x49\x20\x02\xe1\xa1\xe0\xd9\x67\xcc\x7d\x2a\x1f\x7c\x77\x3f\x89\x0f\x98\xe6\x63\x4e\xac\x49\x9a\x24\x59\xed\x29\x50\x6d\x17\xe7\x86\xad\xb9\xf5\xb2\xfe\x69\x79\x8d\x32\x13\xb4\x74\xe9\x5f\x5d\x0f\xde\xda\xd4\xc5\xa6\x82\xfa\xdc\xd5\x35\x6c\xab\x1d\x61\x9d\xd2\x5a\xd7\xb7\x51\x6c\xb3\xff\x80\x37\xab\x44\x3d\x97\x38\x9e\x38\x6a\xb6\xa4\x12\x55\xa6\xcc\xb6\x9b\x92\x3b\xfa\xd3\xab\xbe\x13\x00\xd7\x8a\x69\x21\xa2\x70\x73\x65\xbf\x25\x6d\x81\xed\xa1\x0e\xd7\xd4\x49\xa8\xa7\x03\x6a\x57\x47\x7f\xc0\x0d\x95\x4a\x3c\x27\x83\xca\x16\xf6\x14\xb3\xc9\xa0\x90\x1d\x83\xf6\x1f\x93\x41\x85\xee\x0e\x57\x32\x28\xc2\xdb\x0f\x3f\x07\xc9\x2d\xbf\xe6\x64\x46\xea\xf8\xbe\xa2\x45\x8e\x22\x85\x9e\x9c\x71\xb5\xaa\xd7\x3d\x70\x5e\x24\x89\x31\xe0\x61\xd9\x19\x3a\x63\x12\x48\x48\xee\xbb\x10\xc6\x49\x99\x66\x5a\x65\xdc\x73\x0e\x51\x70\xd0\x4c\x69\x03\x5a\x5a\x02\x37\xca\x1c\x4a\x12\x8e\x0a\xed\xd6\x1e\xd4\xb5\xe5\x9c\xc5\x83\x4b\x0a\x16\xb0\xe5\x4f\xf8\x88\xc2\xf4\xef\x32\xc2\x40\x60\x59\x90\x0c\x81\x2a\xbd\x6f\xfa\xb5\xd0\xce\x51\xd1\xac\x2a\x88\x80\x4a\x92\x0d\x6a\x9a\x23\x12\x19\x3d\x85\x33\xf5\x8b\x44\x71\x4b\xa4\x8c\x60\x28\x67\xe9\xb8\xac\x4e\x4d\x23\xd5\xf6\x49\x7a\xb2\x6e\xf4\x9b\xd0\xd3\x98\x48\x56\x51\xde\xc9\xfb\xbf\xbd\xe2\x3e\x6a\xe6\x5f\xa2\xb5\x91\x96\xc3\x69\xd6\x65\xbd\xfd\x37\xa4\xbc\x31\xc9\xba\xca\xf3\x4a\xbb\xd3\xa1\x32\x7f\x81\xea\xa6\x1b\x2f\xb6\xff\x3e\xdd\x05\x01\x61\x1c\x97\xf6\x3c\xa4\xed\x4d\x68\x39\xb4\xf0\x6b\x5e\x14\xfc\x49\xc7\xa2\x1d\xdd\x21\x68\x0f\x2d\xcf\x43\x48\x71\x04\x2f\x8b\xe2\x0e\x05\x35\xf8\x45\x4b\x16\xe0\xcc\xa4\x5a\x3f\x63\x4e\xc9\x47\xed\xdb\x27\x0b\xe8\x7d\xec\x0d\x3d\x66\x67\xfd\xb0\xed\xb1\x57\x6c\xef\x4a\x3b\x62\x87\xd6\xc0\x9f\x2e\x76\xcb\xde\xd0\xf5\x4f\x88\x3d\x92\x6b\xf4\xb2\x91\xa8\x08\x69\x9a\x64\x4c\x39\x21\x71\xeb\xa8\xc5\x9f\x17\x50\x5b\xa2\x40\x91\xcf\x28\x75\x54\x10\x4c\xf3\x4a\x58\x6e\x6a\x8a\x27\x2e\x72\xf3\x60\xf3\x30\xab\x4e\x97\xad\x59\x52\x54\x41\x89\x42\x87\x4d\x9b\xe4\xb4\xd6\x6c\x2b\x9b\x36\x0c\x24\x93\x09\xe5\x98\x93\x31\x09\x24\x1c\x97\x41\x46\x30\xd0\xe6\x90\xfb\x52\xb8\xb8\xb8\xf8\x62\xad\x11\xef\x86\x4e\xd4\xd3\x03\x91\x98\x03\xd7\x08\xc0\xd7\x03\x51\x72\x6f\x2e\xb0\x68\x8e\xb9\xf7\x59\x51\x2d\x70\x9c\x4e\xbf\xb6\x2e\xdb\xaa\xe1\x0b\x15\xc9\x80\x64\x19\x4a\x19\x29\x54\xbb\xad\xa2\x40\x0b\xcb\xd7\x26\x65\xa6\x02\x73\x5f\x70\xbc\x86\xd2\xbb\x15\x84\xa5\xdd\x57\xba\x4b\xd5\x8f\x35\xe2\x4e\x1d\xf4\xca\xaa\x1f\x3c\xec\x29\x4a\x42\xae\xd2\x96\x13\x5e\x34\xe9\x95\xad\xd3\x69\xc1\x0b\x98\x5f\x5e\xfd\xb4\xfa\xf0\xfd\xe5\xd5\xea\xf2\xfb\xcb\xab\x14\x1e\x9e\x1d\xa8\x76\x95\x61\x63\x62\x6d\xd8\x1d\x6a\x15\x8b\x79\x67\x07\xba\x64\xe3\xd8\x66\x5f\x8d\xc9\x32\x75\x23\xbc\xbf\x15\x6b\x8d\xee\x2b\xf5\x62\x41\xa2\x92\x46\xec\xb6\x77\xe5\x8a\x8b\x10\x53\x46\x6b\xa1\x00\x9e\x74\x9a\xc5\x5f\x81\xc3\x13\x9a\xb7\x47\xa0\xed\xee\x8f\x35\xa5\xf6\x92\x4a\x97\xb5\x19\x29\x0a\xcc\x6d\x2b\x86\xb8\x36\xbd\x7e\x2f\x30\x43\xfa\x88\xf9\x42\x2b\x47\xa0\xa9\x80\x43\x26\xb6\x0d\xd8\x57\x2b\x78\xa8\x54\x48\xb5\x24\x2a\x9b\x5f\xf1\x27\xe6\xfb\x62\x54\x26\xf1\xc5\x59\x5b\xe4\x98\x82\xc6\x36\x20\x25\xfa\x2b\x85\x37\xee\xad\xb1\xce\x70\x82\x2c\xa5\xc1\xa5\x60\x24\xc0\x03\xae\xb9\x40\xb3\x93\xff\xf8\xf8\xf1\x76\x7e\x97\x82\x34\xb0\xa6\x81\xe4\xe0\x2d\x1a\x33\x96\x40\x74\x06\x21\xcd\xee\xdb\x0a\x2f\xf8\x33\x73\x44\x36\xa8\x00\x7f\xc3\xac\x52\x7b\x71\x4b\xc5\x4b\x7b\x0a\x4b\x3b\xb9\x20\xc8\x7a\x4d\xb3\x64\xe4\x02\xd3\xdd\x48\xc6\x9b\x30\x26\x47\xe8\x89\x8d\x4b\x01\x06\x5c\x1f\xda\x9c\x33\xb4\xb8\xcc\x6e\x98\x13\x5e\x14\x40\x32\x45\x1f\x51\x7b\x04\x86\x4e\x1c\x0b\x8d\xb6\x89\x62\x79\xed\x7d\x7f\x86\x1d\x17\x98\xf4\x6f\x53\xbb\x2c\x5f\x59\x35\xb9\xd1\x0a\x28\x28\x43\x20\x62\x63\x4a\x7a\xd8\x08\x5e\x95\x32\xb4\x42\xa9\x80\xbc\x6d\x3b\x68\x03\xb8\xb2\xcb\x7e\xa2\x0c\xdf\xdb\x97\x7f\xb7\x4b\xee\x3f\xc9\x27\xb2\x59\x4e\x7c\x77\xb4\x75\x79\xa7\xad\x8f\x32\xcc\xa1\xe0\x66\xd8\x23\x2e\x17\x7e\xb2\xaf\xc2\x9f\x8e\x27\x5f\x2e\x97\xf1\x1d\x55\x62\x87\x53\x7e\x91\xf8\x01\x73\x9e\x19\x13\xc8\x5d\x6b\xc2\xba\x06\xa2\x60\x95\xf3\x4c\xda\xe1\x82\x79\x5d\x2f\x3f\xd8\xd3\x20\x5c\x43\x6f\xb2\x39\x93\x06\xb4\xf3\x14\xea\xe4\x5f\x06\x4b\x97\x9d\xb2\xfd\xc2\xde\x2d\xb7\x1c\xb5\x9f\x5e\x9d\xab\x80\xfa\x48\xce\x94\xa8\x3c\x63\x77\xa8\xfa\x63\x02\xc1\xa1\x7a\x97\x50\xfa\x2f\x3b\x9d\x57\x9b\x94\xfc\x14\x46\x87\xa4\xe6\xbb\x90\xa8\xfb\x80\x3c\xca\x7e\xbf\xc1\x72\x01\x61\xe1\x40\x8c\x50\x82\xf9\xbc\x23\x96\x24\xf3\x1f\x5f\x4b\x12\x4f\xed\x85\x92\x04\x26\x47\x25\xb9\x2b\x31\xb3\xbb\x40\x6c\xbf\xcd\x64\x61\x4f\xb4\x28\xe0\x01\xad\xd3\xc8\x43\x6c\xcb\x0a\x8a\x4c\xc9\xe5\x89\x72\x68\x5a\x13\x73\x34\xa3\x02\x18\xd0\x0b\xc3\x96\x63\xb8\x6f\x3e\x63\x7a\x7f\x25\x0b\xea\x9b\x4f\xea\x94\xad\x59\x0d\xb7\x7c\x07\x8c\xa7\xcb\xf5\x1f\x61\x2d\x7d\x53\x79\x09\xd7\x7e\x91\xe3\xfa\x47\xd7\x00\x8d\xb9\xf5\x79\xbb\xce\xba\x2d\x5e\xd7\x26\x3d\x85\x57\x47\xc0\xf2\x18\xf7\x56\xf7\x32\xeb\x09\x5a\x26\x3f\x38\x86\x2c\xae\x6e\x93\xc3\x85\x63\xfb\xe5\x91\x14\x34\x37\x3d\x94\x13\x38\xed\x52\x99\x9b\xc2\xd8\x47\x05\x87\xdf\x89\x60\x21\x16\x2d\x39\xff\xe1\x7f\xfc\x0b\x7b\xa3\x31\x29\xd7\xf2\x32\xcf\x0d\x01\x8f\x39\xc2\xe5\x43\x8e\xc3\x85\xfe\x0b\xc6\x9b\xe3\xf3\xe1\x50\x22\x8e\x0b\x75\x8a\x1a\x3c\xdd\x79\x3c\x9f\xf1\x48\x04\x54\x2c\x32\x0c\x5f\xf0\xec\x69\x56\xd1\xf5\x88\x02\xf6\xf7\x87\x2e\x2e\x80\xd1\xc2\xdd\x06\x75\xe8\x5d\x00\x29\x4b\x64\xf9\x3c\x7e\xbb\x30\x77\x81\xd3\xf8\xcc\x7d\xcf\x48\x09\x35\x3e\x5b\x73\x3c\xbf\xa1\xb1\xf3\x4a\xfc\x7a\x7c\x87\xf8\x9d\xbc\x89\x3a\x82\xf5\xb6\x70\x3d\x85\xe9\x91\x1b\xda\x51\x49\xda\x1b\xa3\x11\xea\xa1\x08\xd1\x18\x0e\xc9\xda\x2f\xfa\xa6\x44\xfc\x5a\x45\xe0\x49\x5b\xfb\x4a\xf3\x20\x8e\x87\x31\x15\x59\x4d\x14\xc8\x3a\xd4\x53\xf8\x4f\x78\xeb\x78\x75\x3e\x55\xbb\x23\x53\x42\xad\xe7\xb3\x1d\x95\x52\xbb\xf1\xd8\x77\x9c\xc3\xdf\xe4\xcc\x77\xdf\xe4\xf2\xbf\x38\x65\x7d\x81\x16\x30\x4b\x2d\x0b\x49\x7c\x33\x9b\x34\x49\xa7\x30\xfc\xd1\xf4\xf4\x4d\x6e\x61\x1d\x46\x5c\x2c\x13\xd8\xd0\x47\x64\x51\x29\x4d\xf3\xd3\x12\x8b\x88\xdc\x3c\x60\xbb\xb9\x0e\xd9\xd1\x0b\xab\xc4\x78\x74\x77\x68\x58\x2d\x39\x2b\x6d\xa7\x41\x2f\x83\xc4\xda\xf7\x92\xce\xa7\x90\x45\xe9\x7c\x86\xae\xa9\x8e\xa1\xfe\xce\xc1\xce\x7a\x9c\x14\x45\x07\xf4\xe7\x0e\x59\x7c\xc3\xa8\x49\x06\x1f\x71\x67\xbe\xa7\x63\x37\x90\xdd\x4b\x8b\xfa\x70\x57\x49\x2b\x4a\xea\xfc\xe5\xfc\x62\x72\x24\xb7\x83\x34\xb5\x57\xab\x60\x62\xe8\xf9\x85\x3b\xd3\x9e\x65\x6b\xa7\xf2\x89\xaa\x6c\x6b\x41\xea\xe8\x42\xfe\x98\x89\x9c\x8c\x48\x33\x07\xb2\xbc\xb9\x6e\x9a\xd9\x60\x78\x6e\x7c\x52\xc7\x4b\x71\xaf\x49\x7e\x82\x8b\x91\x6d\x1f\xde\x1c\xba\x76\x9e\x2e\x86\xe7\x80\xbf\xc6\x3d\xbb\x59\x54\x27\xce\x20\x85\xa6\x09\x83\x3a\x36\xb4\x87\x8e\x7a\xe8\x0d\x46\x2b\x06\xa3\x0f\x10\x0f\x96\xb5\xd3\x12\xc7\x39\xf5\x97\x70\x39\xc2\x61\x34\x28\x19\x68\xa7\x1d\xad\x76\x06\x48\x0e\x4d\xed\x80\xdb\x6a\xbd\xf5\x6e\xd3\xad\xd2\x3b\xa2\x1e\xd8\x8b\x91\xdb\x49\x67\xf4\xe6\x64\x2c\x1c\xe6\xe5\x0d\x5b\xc0\x8b\x37\xa9\x37\xfe\xf3\x6d\xec\x8b\x61\xea\x0b\xb6\xa2\x3b\xcd\x73\x9c\xc1\x0f\x6f\x31\x5d\x5e\xfa\x45\x2a\x1d\x9b\x0f\xfa\x86\x74\xec\xd9\x7b\xa1\xae\xdd\x48\xa4\x9d\x21\x72\xa1\xd9\x71\x6d\x15\x9d\xf4\xc7\xa7\xa3\xa0\xd9\xc1\x67\x33\xfc\xb8\x59\x3e\x5e\x7e\xb5\x43\x45\xa7\x06\x0d\xbb\x7a\x9e\x8e\xb4\xe3\x8f\xf5\xfc\x13\x21\xb2\xd3\xed\x7f\xa1\xe4\x61\x9c\xa6\x13\x49\xb3\x30\x64\x33\x0c\xa2\x6d\xc1\x2c\xcd\xaf\xbf\x7e\xbe\xf9\xf9\x07\xf3\x68\xc7\xe3\xd0\x96\x83\x02\x81\x6e\x18\xd7\xaa\xdb\xa2\xc0\x93\x5a\x18\x31\x6f\x6d\x13\x26\x36\xe5\x3d\x23\x40\x1d\x9d\x76\xcb\xa1\xc3\x21\xd4\x23\x59\x98\xfc\xae\x25\x9d\xfa\x70\xfa\xcf\x05\xec\x54\x1b\x4f\x23\xe6\x3a\x21\x75\xa7\xdc\x73\x14\x4e\xc7\x7f\xc0\xb1\xe7\xf2\x3b\x0e\xb3\xdd\xfb\xef\x28\xde\x3a\xff\x32\x04\x19\xf7\x36\x7b\x8b\xb5\xa3\x66\xf2\x4c\x2a\x6a\x52\xe0\x6c\x01\xfc\xb3\xd6\xc5\x90\x4c\x6f\x64\xeb\x7e\xa7\x3e\x7d\xa7\x81\xdb\x21\x43\xc3\xf5\x4e\x69\x2e\xb3\x57\x3b\xce\x61\xea\xab\x63\xd4\x65\x98\x05\xfb\x33\x8d\x3a\xe6\xed\x68\xa3\x0e\x65\x6e\x6c\xd4\xdd\x9a\xf9\xb0\x51\x7b\x24\xaf\x66\xd4\x1d\xcb\x1d\xfe\x3a\xe6\xdb\x31\xec\x68\xda\x63\x32\xa0\x4c\x18\x77\x79\xc8\xb8\xc3\x7e\xee\x37\xee\xf2\xd5\x8c\xdb\xff\x8c\xa4\xad\xf5\xe2\x09\xc3\x60\xdb\xe1\x1a\xbd\xad\xf7\x76\xa8\xb6\x3c\x77\x23\x26\x6a\x7b\x8a\xf5\xb6\xc4\xe7\x16\xdb\xc2\xa0\x6a\xf3\xb7\x98\x97\x85\x19\x6e\xb4\xb9\xc5\x68\xd3\x20\x0c\x8a\x76\x4a\xfc\x78\xf2\xd8\xde\xb3\x58\xa5\x55\x3b\x93\xc5\xba\x32\xf9\x23\xff\xa5\x2c\xd1\xb3\x91\x5a\x12\xff\x9c\xde\x2d\x4f\xeb\xbe\xda\x7d\xfa\x0e\xfe\x12\xf6\x69\x8a\x9a\xde\x7b\x62\x7b\x34\xb3\xd5\xcc\x01\xdb\x37\x30\x9b\x39\xa0\xed\x71\xf4\xee\xf5\xba\x4f\xed\xce\x9a\x65\x6d\x00\x36\x23\xb5\x71\xde\xd1\x8e\x91\x86\x89\xdb\xbd\xd7\xdd\x27\xf6\x17\x1d\xe9\x79\x3a\x36\xc7\x3b\xbd\x6b\x9e\xa5\xce\xa6\xed\x01\xeb\xfc\x26\x05\x9f\x3e\xf0\x4a\x91\x87\x02\x3d\xf5\xf1\x7b\x88\xc5\x10\xe3\x42\x93\xeb\x77\x41\xb4\x5b\x88\xc1\xa0\xa5\xac\x15\x7c\x82\x56\x74\xd2\xe5\x0c\xf8\x8a\x64\x5b\x9c\x4f\x75\x90\x5b\xf5\xad\x56\x90\x73\xf6\x6f\x0a\x32\xbd\x65\xe4\x81\x57\xca\xe5\x8f\xfa\x7c\x2f\xe0\xff\x2a\xa9\xdc\xb8\xcd\x16\x0d\x01\xe3\x08\xfd\x40\x43\x59\x22\x33\xe3\xe7\xde\xb3\x8f\x76\xdc\x86\x72\x8e\x1f\x9f\x7d\xc7\xec\xe8\xdf\x38\x3b\xfb\x3e\xd8\x06\x9c\x66\xea\x5e\x6b\x58\x50\xa6\xd6\x30\xfb\xdb\xaf\x33\x98\x57\xfa\xb8\x6a\x1f\x6e\xce\xab\xf9\xed\x44\x8f\xef\x2f\x44\x36\x10\x6e\x4c\xa2\x3d\x07\xf5\x30\x8d\x7b\x5b\xe0\x98\xd2\x46\x7b\x02\xed\x18\x9a\x66\x36\xeb\xf6\x5a\x63\x1c\x59\x81\x84\x19\x58\xb3\x22\x8d\x9b\x9e\x36\x80\x9d\x3a\x3e\x32\xf5\xdb\xf9\x91\xf3\xe4\xce\xc3\xc8\x91\x5a\x4e\xfe\x70\x6e\x5f\xd3\xd6\xd4\x5e\xfb\xda\xa5\xfb\x47\xa7\xfc\x5d\xa8\x78\xc4\xe8\xff\x0c\xd0\x9b\x15\xfa\x95\x8a\xdb\xab\x50\xfb\x1b\xae\xdb\x1b\xe0\x8f\x28\xcc\x68\x85\x5e\x9a\x11\x06\x0f\x08\x95\xc4\x1c\x72\x2a\x30\x53\xc5\x33\x50\x66\xe3\xe0\x4f\xba\x62\x63\x97\x2c\x37\x04\xe6\xb3\xf3\xff\x78\xfb\xf6\xed\x6c\x01\xa4\xa4\xb6\x97\x38\xd7\x5e\x24\x3d\xb9\xf3\x39\x7f\xb0\x83\xfd\x70\x68\xd6\xdf\x79\x8d\xa1\x51\xdf\x30\xaa\xec\x74\xc6\xc8\x11\x6a\x9a\x65\xf4\xcb\x82\xbf\x8c\xc4\xc5\x31\x94\xed\x12\xcf\x5e\xda\x86\xb1\x03\x23\x03\x3d\xe4\x13\xc6\xa3\x8b\x4c\x27\x58\x3b\x91\xd0\xa3\xf5\x02\x1c\xed\x52\x6b\x0d\x5a\x27\x7e\xb6\xe7\x99\x57\xda\x00\x8c\xd3\x0c\xbe\xd2\x9a\x82\xb7\x8f\x4c\x3b\xe6\x45\x18\x5f\x52\x5b\xd4\xc9\x54\xc6\x77\x25\x97\xd8\x0f\xa1\xc4\xa2\x94\x88\xb0\xa6\xea\x94\x8d\xb7\x3b\xe6\x23\xa2\xce\x9e\xa7\xdd\x48\xaa\xbd\xda\xdb\x49\x5f\x3c\x8c\x2e\xe1\xa7\x43\xed\xed\x6a\xa8\x61\xbb\x1a\x21\x79\x0e\x73\x2e\xcc\x61\x10\x34\xc7\xb4\x3f\x5a\x4e\xa2\x3a\xe6\xa4\xe2\xa4\xcf\xc0\x60\xf4\x61\xd1\x12\x1c\xfc\x07\x12\x13\x61\x72\x50\x03\x7a\x94\xa6\xe6\xf3\x25\x67\x57\x01\xa1\xde\x39\xac\x80\xce\x90\xf9\xab\x29\xc0\x33\x30\xa2\x80\x72\x6a\x96\x7c\xbf\x02\xa2\x3a\x21\x56\x80\xc7\xe6\x1b\x51\x79\xde\x9e\x65\x9d\xe2\x93\x3c\x0f\xde\x31\xb2\x69\xc5\x01\x7f\xa3\xd2\x0c\xaf\xf9\xa9\xbe\x53\xfa\x52\x3d\x72\x63\x49\xfd\x02\xf6\x79\xbc\xfa\xb8\xc4\xfc\x70\x2a\x3d\xd4\x9b\xf3\x93\x66\xfd\x8b\x12\xed\xa8\x0a\xdb\x03\x6e\xf9\x73\x4b\xe0\xc2\x4b\x39\xdf\xfa\x13\xf9\xff\x01\x00\x00\xff\xff\xe7\x4d\x86\x07\xa7\x49\x00\x00") func templatesServerBuilderGotmplBytes() ([]byte, error) { return bindataRead( @@ -622,12 +648,12 @@ func templatesServerBuilderGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/server/builder.gotmpl", size: 18967, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xcd, 0x9, 0x7f, 0x2a, 0x86, 0xd5, 0x9a, 0x75, 0x25, 0x2d, 0x98, 0xc0, 0xc2, 0xb3, 0x1, 0xf3, 0x73, 0xa6, 0xe1, 0x1b, 0x6f, 0x95, 0x62, 0xb, 0xb6, 0x3f, 0xe3, 0x6d, 0x3c, 0x4d, 0x3a, 0x5b}} + info := bindataFileInfo{name: "templates/server/builder.gotmpl", size: 18855, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x58, 0x21, 0x57, 0xdd, 0x44, 0xf7, 0xbf, 0xcd, 0x95, 0xdc, 0x7d, 0x5f, 0xc3, 0xd0, 0x35, 0xea, 0x13, 0x62, 0x19, 0xb2, 0xf5, 0xab, 0xba, 0xf4, 0xe7, 0x6f, 0xa4, 0xde, 0xa4, 0x17, 0x2f, 0xa7}} return a, nil } -var _templatesServerConfigureapiGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x58\x4b\x93\xdb\xb8\x11\x3e\x47\xbf\xa2\x4b\xb5\x07\xc9\x25\x51\x55\x39\xba\x6a\x0e\x13\xdb\xeb\x55\xc5\x5e\xab\xac\x71\x72\xd8\xda\x03\x44\xb6\x24\x64\x40\x00\x01\x40\xcf\x68\x59\xfc\xef\xa9\x6e\x80\x14\x25\x51\x33\xb3\x99\x4d\xf6\x44\xe2\xd5\x8f\xaf\x1f\xe8\xc6\x62\x01\x77\x7b\xe9\x61\x2b\x15\x82\xf4\xe0\xc5\x16\x21\x18\xc0\x42\x86\x0c\xbe\xe8\x1c\x41\x06\xc0\x47\xe9\x83\xa7\xbf\x07\xa9\x14\x68\x13\x60\x83\x60\xbe\xa3\x7b\x70\x32\x04\xd4\xa3\x51\x5d\x83\xdc\x42\xf6\xce\xd8\x83\x93\xbb\x7d\x80\x79\xd3\x2c\x16\x50\xd7\x90\x9b\xb2\x44\x1d\xce\xd6\xea\x1a\x50\x17\xd0\x34\xa3\xd1\xc8\x8a\xfc\x5e\xec\x90\x36\x67\xb7\xab\xe5\x2a\x0d\x69\x4d\x96\xd6\xb8\x00\x93\x11\xc0\x38\x37\x3a\xe0\x63\x18\xf3\xbf\x3b\xd8\x60\x16\x41\x79\x1e\x4a\xc3\x1f\x65\x76\xfc\xd5\x18\x16\xfb\x10\xec\x78\x44\xa3\x9d\x0c\xfb\x6a\x93\xe5\xa6\x5c\xec\xcc\xdc\x58\xd4\xc2\xca\x05\x3a\x67\x5c\x3c\x3d\xbc\xc1\x55\x3a\xc8\x12\x9f\xdf\xb1\x28\x65\x51\x28\x7c\x10\xee\x25\x9b\x3d\xe6\x95\x93\xe1\xc0\xb2\x11\x6a\xac\xa1\x87\xec\x3d\x6e\x45\xa5\xc2\x32\x8d\x9b\xe6\x6c\xbd\xb7\x30\x65\xbc\x1f\x64\xd8\x43\xf6\x11\xf5\x17\x1b\xa7\x17\x8b\x9d\x79\xbb\x43\x8d\x4e\x04\x04\xff\x20\x76\x3b\x74\x70\x9c\x40\xf7\x1d\x1d\xcc\xe7\x41\xb8\x1d\x06\x86\xfb\x8e\x7f\x57\x22\xec\xa1\x69\x60\x3e\xd7\xa2\x8c\x76\xf8\x99\x7e\x78\xca\x5b\xcc\x79\x6a\x6d\x31\x4f\x3b\x47\x75\x3d\x67\x7b\x9f\x98\x2b\xfa\x80\xc6\x93\xe9\xb1\xb1\xc4\x5e\x1a\xed\xc7\x91\xa0\xb0\x72\x7e\xd5\xe4\x9d\x5f\x1c\x1d\xa4\xe5\xf5\xd9\x14\xa8\x86\xb8\x9d\x2c\x8c\x4b\x1a\xb5\xbc\x78\x70\xc2\xed\x92\xca\x35\x7e\x6b\xc6\x6b\x88\xe1\xe9\xca\xd8\xa1\x0f\xc2\xca\x71\x84\x8b\xd7\x4e\x58\x0e\x10\xba\xc6\xf3\x9d\x92\xa8\xc3\x10\xcf\xd3\x95\x71\xce\xc3\xa4\x65\x1c\x9c\xf0\x1c\x20\x74\x8d\xe7\x1d\x96\x56\x89\x80\xef\xa5\x8b\xe4\x42\x9a\x98\x17\xd2\x45\x2f\x39\xd9\x71\x4a\xc1\x09\xbd\x43\xc8\xbe\x74\x56\x8e\x34\x3a\xab\x33\x81\x6b\xa7\xee\xc4\x2e\xed\x0f\xf4\x37\xb8\x95\x44\x5c\x39\xa9\x73\x69\x85\x8a\x9b\x6d\x37\xa4\x13\xfd\xc5\xcb\xa3\x29\xac\xd6\xf9\x1e\xcb\x53\x44\x4f\x57\xc6\x9c\x30\x22\xfd\x22\xae\xcc\x7d\x5c\x22\x26\x03\x64\x86\xf0\x4c\x7a\xb1\x93\xf9\x9e\x0b\x5e\x55\xcd\x38\x98\x50\x3e\xcd\x96\x3a\x57\x55\x81\x7c\x72\x7a\x3a\xf7\x0f\xa1\x64\x21\x82\x71\xd3\x14\x91\xf7\xd2\x46\xb2\xfe\x59\x7a\x3f\x09\x5d\x28\x74\x67\x14\x57\xc2\x89\x12\x03\x3a\x0f\x67\x2b\x5f\xd1\x5b\xa3\x3d\xfa\x3e\xaf\x63\x08\x5f\xf0\xeb\x9f\x5d\x57\x96\xb3\xf5\xf1\xa0\x8f\x33\x4f\x9e\xfa\x2c\xa4\x8e\x47\xf0\x91\x27\xe6\xa5\x90\xfa\xd2\x90\x1f\xe2\x2a\x65\xa1\xd3\xed\x94\xa0\x06\xec\x5e\x95\xf6\xbd\x08\x22\x59\xb4\x2a\xed\xbc\x10\x41\x0c\x84\x79\x70\x32\x0f\x51\xef\x82\x10\x89\xe2\xf3\xec\xdc\x75\xd3\xfd\x83\xed\xdf\xb6\xd2\x39\xe4\x46\x6f\xe5\xae\x72\xf8\xa3\x12\x3b\x3f\x11\x56\xc2\x9b\xba\xce\x52\xe8\x35\x4d\x56\xd7\x60\x85\xcf\x85\x92\xbf\x61\x97\x58\x6f\x57\xcb\x29\xd4\x23\x80\xc5\x02\x84\x95\xd9\x3b\x53\x96\x42\x17\x9f\xa4\xc6\x2f\x96\xa1\xfe\xe8\x4c\x65\x3d\xdc\xc0\x2f\xbf\x52\x2a\xbf\xb6\xa3\x86\x2c\xcb\xa0\x19\x35\xa3\x33\x71\x6e\x57\xcb\xdf\x25\x0c\xf9\x7f\x96\xdc\xa5\x95\xac\x23\x06\x61\x8f\x24\x27\xec\xd1\xe1\x08\x58\x64\x4e\x6b\x1f\xe8\x1a\x85\x1b\x88\xd7\x69\x6f\x6e\x14\x29\xac\x31\xc0\xc1\x54\x0e\xf2\xca\x07\x53\x82\x32\x7c\x29\x71\x08\x62\x81\x45\x06\x29\xb2\xc0\x68\xae\x40\x94\xd9\x71\x44\x87\x6d\x24\xf0\xe1\xd1\x62\x1e\xb0\x00\xa9\x03\xba\xad\xc8\x11\x48\xcf\x09\x19\x48\xef\x66\xa4\x7d\xb7\x52\x37\x53\x3e\xd4\x9e\x14\xa5\x55\xf8\xf6\x08\xf2\xa7\xc8\xfc\xa6\xcf\x24\x29\xf3\xcd\xe3\x3a\x5e\x98\xdf\x96\x93\x48\x05\xee\x0c\x01\x10\xa4\xae\x10\x2a\x2f\xf5\x0e\x1c\x16\x26\x07\xe1\xa3\x4a\xdf\x96\x33\xa8\x74\x5b\xdf\x10\x42\x5b\xa3\x94\x79\xa0\x9d\x4a\x6a\x3c\x32\xfe\xe6\xf1\x2b\x1d\x9d\x4c\xd3\xad\x9f\xf2\xc4\x3b\xa3\x7d\x55\x62\xba\xed\x69\x25\xfa\xe4\x92\x04\x27\xaa\x31\x85\xf2\x2a\xd1\x19\xb4\x5e\x22\x42\x7a\x51\x96\x19\x3a\x1b\x29\xa3\xf2\xf8\x72\x5a\xa9\x60\x69\x65\x74\x3f\x12\xea\x0c\xbd\x03\x69\xb2\xaf\x28\x0a\x74\x33\x48\xc5\x44\xdf\x06\xd1\x19\xd8\x87\x00\x1c\x86\xca\xe9\xd6\x3f\x7e\x36\xa1\x93\x0f\x8b\xc9\xb8\xae\x99\x73\xd3\x10\xd2\x91\xf3\x5e\x78\xce\x0f\x07\xa4\x2a\x13\x35\x55\x40\xed\x81\x31\x59\x86\x8d\x9c\x34\x8a\x71\x78\x31\x68\xf1\x5d\x39\x53\x54\xf9\x2b\xf1\x4d\x44\xfe\x10\x7c\x7b\xb4\x5a\x7c\xdb\xa9\x23\xbe\x0f\x84\xef\x3f\x9d\x0c\x84\x2f\x25\xad\xd7\xa3\x6b\x5b\xbe\xaf\x41\xf7\x0c\xdc\x75\xaa\x64\xdf\xe3\x56\x6a\xd9\xde\xfd\xa7\x38\xfb\xbf\x09\x2f\xf3\xdb\x2a\x56\x8d\x1c\x0f\xb7\xd6\x2a\x89\x1e\x1e\xf6\xa8\x39\x68\x68\xd5\x38\xf9\x5b\xc4\x73\xcf\x7e\xc5\xbd\x08\x86\x58\xe3\xd2\x26\xa6\x03\xf1\x42\x1e\x01\x11\xbf\xc4\x78\xf9\x9e\x72\x19\xf1\xba\xb9\x01\x2d\x55\xc2\xe8\xc9\x8d\x31\x99\x54\x1e\x1d\xb4\x19\xc5\x0a\xef\xd3\x60\x0a\x93\xba\x4e\xf7\xd5\x04\xf0\xdf\xfd\x62\x63\xdc\x33\xca\x18\xa6\x4d\xf3\xa6\x57\x13\x1c\xf7\x35\xcd\x2c\x9a\x67\x9a\xc4\xe9\x8c\xa6\xa5\x9a\x5d\xb3\xdc\x86\xd5\x15\x24\x22\x89\x90\x44\x9e\x3e\x6f\x3e\x00\x82\xf9\xcc\x27\xa3\x29\x6e\x57\xcb\xbf\xe3\xe1\x69\x5b\x8c\x7b\xb5\xff\x38\x16\xaf\xa6\x72\x39\xb7\x02\xd1\x24\x7f\x3c\xf8\xc1\xdc\xa3\xfe\xb3\x01\xa7\xbb\xed\x1e\x0f\x11\xf2\x3e\xe2\xc7\x18\xda\x3a\x53\xd2\x30\x22\x42\x41\x45\x55\x14\xfc\xd2\x83\xec\xd7\x57\x19\xe8\x0b\xa1\xf2\xd7\x68\x9c\xff\x21\xc6\x33\xf0\xb9\xb1\xe8\xa9\xb0\xf8\x73\x41\x37\x82\x15\xde\xa0\x70\xe8\x2e\xa1\xff\xfd\x58\x5e\xb9\x0e\xda\x7e\x6e\x30\x5f\x0d\xd7\x29\x22\x25\xa5\x27\x6b\x95\xb6\x97\xcf\xda\x14\x86\x45\x5b\x3b\x0c\x94\x2d\x6d\xc2\xef\x36\xbb\x27\x8b\x95\xdb\xd5\xf2\xb8\x13\x6e\xae\x32\xbb\xd0\xf5\x87\xb6\x0f\x7c\x7b\x03\x59\xef\x31\x25\xae\x0e\xf5\x6b\x27\xfe\x96\xba\xa3\xf6\x60\x47\x8d\x9b\x97\x9e\x8f\x0d\xf7\x96\x97\x57\x5e\x5b\x52\x0e\xb9\xec\x53\xbc\x2e\x59\xbd\x98\x53\xe7\x10\xed\xc9\x5b\x25\x05\x29\x9a\xd1\xe4\xd5\x83\xc7\x1b\x98\x23\x3b\xf6\xa3\x2f\xa3\xc0\x0d\x95\x3f\x3a\xdb\x0f\xed\xbb\xcc\x50\x7b\x71\x72\x45\x1e\xad\x49\x31\xd4\xef\x6c\x5f\x1b\x91\x75\xcd\x77\x36\xa7\xb0\x67\x1a\x80\x4e\xbc\x36\x7a\x53\xf0\x3e\x7f\xf2\x2c\xa4\xa3\x43\xf6\x2a\xa1\xff\xab\xa2\xc7\x87\xb8\xec\x42\xa3\x56\xa5\xde\x9e\x8b\x74\x74\xf2\x66\xd1\x57\xfc\x4c\xef\xa6\x79\x3e\x37\x25\x59\xe7\x09\x05\x2e\xab\xce\x52\x53\x2a\x14\x57\x0e\xe3\x0b\xd1\x7a\x5f\x85\xc2\x3c\xe8\x36\x69\x4f\xa1\xa6\x33\xfd\x76\xeb\x89\x3d\x49\x3f\x8f\xa1\xb2\x1f\x95\xd9\x08\xf5\xb9\x53\x75\xd2\x11\x98\xf0\xfa\x71\xc5\x4f\xa7\xd4\x3a\xf2\x3b\x30\xc2\xdd\xa7\x75\xd7\xf3\x45\x24\x36\xb8\x35\x0e\xe1\xa7\xbb\xbb\xd5\xba\x7d\x41\xf4\x41\xb8\xe0\xb3\xb3\x7e\xf3\xee\xd3\x7a\x12\x94\x7f\xc7\x63\x78\x13\x94\xcf\xe2\x7f\xd7\xe7\x7e\x16\xf7\x08\x42\x29\xd0\x98\xa3\xf7\xc2\x1d\x20\xdf\x53\x3a\xf2\x10\x0c\x97\x1f\x97\xfc\xa9\xdf\xcc\x92\x84\xb7\x1e\xbc\x31\x9a\xfa\xaf\x24\x89\xf4\xc0\xa9\x9c\x6d\x53\xc0\xa6\x0a\x6c\x14\x57\x69\x32\xcc\x0c\x02\xbf\x6d\x57\x3a\x67\x5a\xfc\x78\xbd\x41\xc8\x85\x52\x58\x64\x44\x72\xb9\xa5\xac\xcf\xf9\x9d\x64\x28\x4d\x21\xb7\x07\x10\x49\x88\x19\xf8\x40\xda\xb7\xdc\xb4\x0f\x42\xe7\xfc\x40\xee\x83\xb1\x20\xa9\xef\x29\xe4\x77\x59\x54\x42\xa9\x03\x28\xc1\x25\x3b\x73\x95\x9e\x35\xb2\x4a\xe4\x98\x8d\xba\x77\xf6\x56\x96\x5c\xe8\xa3\x28\x50\x56\x2a\x48\xab\x10\xe8\x82\xf0\x33\x28\xd0\xa2\x2e\xa8\x8f\x34\xb1\x2e\xd3\x55\xb9\x41\x07\x66\xcb\xb2\xd0\x42\x2c\x85\x3d\x93\x4e\xef\x54\xdf\x85\xaa\xb0\xd3\x92\xca\x67\x91\xe7\xc6\x11\x1d\x75\x78\x9b\x5e\xb8\x66\xf1\xeb\xc7\x60\x1c\x8c\x2b\x2d\x1f\xc7\x67\x86\x8c\x8e\x36\xf1\xf0\x86\x9f\x04\xe2\x70\x96\x98\xcc\x40\x14\x85\xeb\xaa\xb5\xba\xe7\x3c\xc7\xc8\x3a\xb3\x21\xe9\x6d\x1c\xeb\xb1\x4f\x29\x1a\x1f\x31\xaf\x02\xd5\x04\x74\xd4\x23\x14\x86\x2d\x27\xac\x55\x87\xd6\x1b\xd2\x0b\x76\xf6\x2f\x6f\x34\x14\x26\xaf\x28\xbc\xb2\x01\x76\x91\x1a\x7a\x10\xdb\x80\x0e\x9c\xa9\x02\x41\x44\xee\x90\xfc\x97\xae\x73\xd4\x41\xe6\x2c\xd1\x0c\x36\x32\xc2\x2b\x74\x41\xb0\xc9\x82\xe7\x23\x10\xe7\x11\x32\x69\x85\xee\xbf\x90\x5c\xbc\x97\xfc\x25\xc5\x5f\xda\xfc\x12\x5c\xf6\xc2\x5a\xd4\xbe\x93\x51\x1f\xc2\x9e\xeb\x33\x76\xa0\xde\x31\xa1\xbc\x61\x68\x64\x0c\x95\xd6\x07\x9e\x06\x69\x6d\x3a\x4f\x14\xb0\x33\xa6\x88\xce\x48\x04\xac\xaa\x76\x20\x35\x08\xb0\x42\xcb\x3c\x0a\x4d\x14\x8f\x4c\x67\xfc\x54\xd3\x62\x54\x22\x5d\x63\xbe\x07\xd0\x45\x8a\xf9\x2f\x51\xfa\x4f\x00\x00\x00\xff\xff\x11\xfc\x88\xee\x82\x1a\x00\x00") +var _templatesServerConfigureapiGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x59\x4b\x8f\x1b\xb9\x11\x3e\x47\xbf\xa2\x20\xec\x41\x32\xa4\x56\xe0\xbd\x19\x3b\x87\x59\x3f\x85\x78\x6c\xc1\x1a\x27\x08\x16\x7b\xa0\xba\x4b\x12\x63\x36\x49\x90\x6c\xcf\x68\x1b\xfd\xdf\x83\x22\xd9\x4f\xb5\x66\xc6\x3b\x8b\xe4\xa4\x26\x59\xac\xc7\x57\xc5\xaa\x22\xb5\x5a\xc1\xed\x91\x5b\xd8\x73\x81\xc0\x2d\x58\xb6\x47\x70\x0a\x30\xe3\x2e\x81\xcf\x32\x45\xe0\x0e\xf0\x9e\x5b\x67\xe9\xeb\x8e\x0b\x01\x52\x39\xd8\x21\xa8\xef\x68\xee\x0c\x77\x0e\xe5\x64\x52\x96\xc0\xf7\x90\xbc\x56\xfa\x64\xf8\xe1\xe8\x60\x59\x55\xab\x15\x94\x25\xa4\x2a\xcf\x51\xba\xc1\x5a\x59\x02\xca\x0c\xaa\x6a\x32\x99\x68\x96\x7e\x63\x07\x24\xe2\xe4\x7a\xb3\xde\xc4\x21\xad\xf1\x5c\x2b\xe3\x60\x36\x01\x98\xa6\x4a\x3a\xbc\x77\x53\xff\x6d\x4e\xda\xa9\x95\x13\xd6\x0f\xb9\xf2\x3f\x42\x1d\xfc\xaf\x44\xb7\x3a\x3a\xa7\xa7\x13\x1a\x1d\xb8\x3b\x16\xbb\x24\x55\xf9\xea\xa0\x96\x4a\xa3\x64\x9a\xaf\xd0\x18\x65\xc2\xee\x71\x02\x53\x48\xc7\x73\x7c\x9c\x62\x95\xf3\x2c\x13\x78\xc7\xcc\x53\x88\x2d\xa6\x85\xe1\xee\xe4\x75\x23\xd4\xbc\x85\x16\x92\x37\xb8\x67\x85\x70\xeb\x38\xae\xaa\xc1\x7a\x67\x61\xee\xf1\xbe\xe3\xee\x08\xc9\x7b\x94\x9f\x75\x98\x5e\xad\x0e\xea\xd5\x01\x25\x1a\xe6\x10\xec\x1d\x3b\x1c\xd0\x40\x3b\x81\xe6\x3b\x1a\x58\x2e\x1d\x33\x07\x74\x1e\xee\x5b\xff\xb9\x61\xee\x08\x55\x05\xcb\xa5\x64\x79\xf0\xc3\x27\xfa\xf0\x53\x56\x63\xea\xa7\xb6\x1a\xd3\x48\x39\x29\xcb\xa5\xf7\x77\xcf\x5d\x21\x06\x24\xf6\xa6\xa7\x4a\x93\x78\xae\xa4\x9d\x06\x86\x4c\xf3\xe5\x45\x97\x37\x71\xd1\x06\x48\x2d\xeb\x46\x65\x28\xc6\xa4\xf5\x16\xa6\x39\x8d\x6a\x59\x7e\xd0\x93\x76\xce\xe5\x92\xbc\xad\xc7\x6b\x4c\x60\x7f\x65\x6a\xd0\x3a\xa6\xf9\x34\xc0\xe5\xd7\x7a\x22\x47\x18\x5d\x92\xf9\x5a\x70\x94\x6e\x4c\x66\x7f\x65\x9a\xfa\x61\xb4\x32\x0c\x7a\x32\x47\x18\x5d\x92\x79\x8b\xb9\x16\xcc\xe1\x1b\x6e\x02\x3b\x17\x27\x96\x19\x37\x21\x4a\x7a\x14\x7d\x0e\x86\xc9\x03\x42\xf2\xb9\xf1\x72\xe0\xd1\x78\xdd\x33\xb8\xb4\xeb\x96\x1d\x22\xbd\xa3\xaf\x51\x52\x52\x71\x63\xb8\x4c\xb9\x66\x22\x10\xeb\x66\x48\x3b\xba\x8b\xe7\x5b\xe3\xb1\xda\xa6\x47\xcc\xfb\x88\xf6\x57\xa6\x3e\x61\x04\xfe\x59\x58\x59\xda\xb0\x44\x42\x46\xd8\x8c\xe1\x19\xed\xf2\x41\x66\x3b\x21\x78\xd1\x34\x65\x60\x46\xf9\x34\x59\xcb\x54\x14\x19\xfa\x9d\xf3\xfe\xdc\x3f\x99\xe0\x19\x73\xca\xcc\xe3\x89\xfc\xc6\x75\x60\x6b\x1f\xe5\xf7\x81\xc9\x4c\xa0\x19\x70\xdc\x30\xc3\x72\x74\x68\x2c\x0c\x56\xbe\xa0\xd5\x4a\x5a\xb4\x5d\x59\xed\x11\x3e\x93\xd7\xdd\xbb\x2d\xb4\xcf\xd6\xed\x46\x1b\x66\x1e\xdc\x75\xc3\xb8\x0c\x5b\xf0\xde\x4f\x2c\x73\xc6\xe5\xb9\x23\xdf\x86\x55\xca\x42\x7d\x72\x4a\x50\x23\x7e\x2f\x72\xfd\x86\x39\x16\x3d\x5a\xe4\x7a\x99\x31\xc7\x46\x8e\xb9\x33\x3c\x75\xc1\xee\x8c\x10\x09\xea\xfb\xd9\xa5\x69\xa6\xbb\x1b\xeb\xaf\x7d\x21\x53\x48\x95\xdc\xf3\x43\x61\xf0\x9d\x60\x07\x3b\x63\x9a\xc3\x8b\xb2\xec\x64\xb5\x6b\xc1\x99\xad\xaa\xa4\x2c\x41\x33\x9b\x32\xc1\xff\xc0\x26\xc1\x5e\x6f\xd6\x73\x28\x27\x00\xab\x15\x30\xcd\x93\xd7\x2a\xcf\x99\xcc\x3e\x72\x89\x9f\xb5\x87\xfc\xbd\x51\x85\xb6\x70\x05\xbf\xfd\x4e\x29\xfd\x12\x45\x09\x49\x92\x40\x35\xa9\x26\x03\xb5\xae\x37\xeb\x3f\xa5\x14\x9d\x87\x24\x86\x4f\xad\x61\xc3\x14\xdc\x11\x49\x5f\x38\xa2\xc1\x09\x78\xd5\x7d\x9a\x7b\x4b\x65\x15\xae\x20\x94\xd7\xce\xdc\x24\x70\xd8\xa2\x83\x93\x2a\x0c\xa4\x85\x75\x2a\x07\xa1\x7c\x91\xf2\x47\x12\x33\xcc\x12\x88\x27\x0d\x94\xf4\x1d\x89\x50\x07\x7f\xc2\xdd\x3e\x30\x78\x7b\xaf\x31\x75\x98\x01\x97\x0e\xcd\x9e\xa5\x08\x64\xef\x8c\x1c\x26\x0f\x0b\x42\xa1\x59\x29\xab\xb9\xdf\x54\xef\x64\xb9\x16\xf8\xaa\x05\xfb\x63\x10\x7e\xd5\x15\x12\x8d\xf9\x6a\x71\x1b\x0a\xe8\xd7\xf5\x2c\x70\x81\x5b\x45\x00\x38\x2e\x0b\x84\xc2\x72\x79\x00\x83\x99\x4a\x81\xd9\x60\xd2\xd7\xf5\x02\x0a\x59\xf7\x3b\x84\xd0\x5e\x09\xa1\xee\x88\x52\x70\x89\xad\xe0\xaf\x16\xbf\xd0\xd6\xd9\x3c\x76\x01\x31\x6f\xbc\x56\xd2\x16\x39\xc6\xea\x4f\x2b\x21\x46\xd7\xa4\x38\x71\x0d\x29\xd5\xaf\x12\x9f\x51\xef\x45\x26\x64\x17\x65\x9d\xb1\xbd\x81\x33\x0a\x8b\x4f\xe7\x15\x1b\x98\x5a\x47\xf3\x8e\x50\xf7\xd0\x1b\xe0\x2a\xf9\x82\x2c\x43\xb3\x80\xd8\x5c\x74\x7d\x10\x82\xc1\xc7\x10\x80\x41\x57\x18\x59\xc7\xc7\x27\xe5\x1a\xfd\x30\x9b\x4d\xcb\xd2\x4b\xae\x2a\x42\x3a\x48\x3e\x32\xeb\xf3\xc5\x09\xa9\xeb\x44\x49\x1d\x51\xbd\x61\x4a\x9e\xf1\x4e\x8e\x16\x85\x73\x79\x36\xa8\xf1\xdd\x18\x95\x15\xe9\x33\xf1\x8d\x4c\xfe\x12\x7c\x3b\xbc\x6a\x7c\xeb\xa9\x16\xdf\x3b\xc2\xf7\x5f\x86\x3b\xc2\x97\x92\xd8\xf3\xd1\xd5\xb5\xdc\xe7\xa0\x3b\x00\x77\x1b\x3b\xdb\x37\xb8\xe7\x92\xd7\xbd\x40\x1f\x67\xfb\x2b\xb3\x3c\xbd\x2e\x42\x17\xe9\xcf\xc3\xb5\xd6\x82\xa3\x85\xbb\x23\x4a\x7f\x68\x68\x55\x19\xfe\x47\xc0\xf3\xe8\xe3\xca\xdf\x4d\xd0\x85\x9e\x97\x88\x3c\x1f\x08\x05\x7a\x02\xc4\xfc\x1c\xe3\xf5\x1b\xca\x65\x24\xeb\xea\x0a\x24\x17\x1e\xa3\x07\xc9\x42\x2a\x29\x2c\x1a\xa8\xf3\x89\x66\xd6\xc6\xc1\x1c\x66\xf1\x9a\xd3\xb4\x1c\x6b\xfb\xa9\x10\x82\xed\x04\x39\xf3\x45\xa7\x29\x68\x49\xaa\x6a\x11\xfc\x31\x8f\x3e\x6a\xbc\x24\xb9\x58\x5c\x72\xd5\xce\xdb\xc7\x48\x2b\x2f\x35\x68\x39\x7f\xdc\x5f\x00\x84\xeb\x20\x08\x03\xf6\xd7\x9b\xf5\x3f\xf0\xf4\x30\xf8\xd3\x4e\xf3\x3f\x0d\xdd\xab\x2a\x4c\xea\xef\x02\xc1\x07\x7f\x35\xda\x4e\x7d\x43\xf9\x7f\x40\x98\xaa\xd7\x37\x3c\x05\x8c\xbb\x10\xb7\xa7\x64\x6f\x54\x4e\xc3\x00\x01\x1d\x1b\xea\x9b\xe0\xb7\x0e\x46\xbf\x3f\xcb\x23\x9f\x09\x88\x97\xf5\x29\x79\x3a\xac\x3f\x0c\xec\x02\x6c\xaa\x34\x5a\x6a\x22\xfe\xe7\x48\x2b\xe6\xad\xdc\x21\x33\x68\xce\xf1\xfe\x71\x00\x2f\x64\xf9\xfa\xda\x36\x9a\x86\xc6\xdb\x0f\x16\x73\xcd\x83\x2d\x48\x7d\x65\x4f\xea\xcc\x84\x59\xdd\x12\x8c\x74\x23\x75\x1e\x6f\x88\xcd\x83\x3d\xc8\xf5\x66\xdd\x52\xc2\xd5\x45\x61\x67\xb6\xfe\x54\x5f\xf7\x5e\x5d\x41\xd2\x79\x33\x89\xab\x4c\xf3\x48\xc0\xa8\xd5\xf3\x54\x83\xf6\xaf\xa5\x1e\xbb\xc4\xf5\x12\xf7\x07\x66\xdf\x29\x93\xfb\x7b\x83\x6d\xb2\xc7\xbf\x55\x01\x39\x3b\x41\x7a\xf4\xfb\xa9\x17\xf4\x49\x24\xc7\x5c\x99\x13\x08\x9e\x73\x07\x7b\x65\xc0\x1d\xb9\x85\xbc\x10\x8e\x6b\x66\xfc\x54\x4e\x67\xc9\xa2\x49\xe0\x57\x14\xea\x8e\x60\xa6\x9d\xf1\xe6\x05\xb3\x9f\x5f\xc2\xcd\xaf\xf3\x24\xc8\x69\xef\x6c\xb5\x9d\x8d\xf1\xfe\x4a\x95\x0c\xac\xa2\xd8\x0d\xb5\xb7\x2c\xcf\x91\xe8\xdc\xc2\xc6\x8b\xf2\x0d\xbb\xdf\x90\x72\x37\xc1\x8c\x2b\xf8\xf9\x25\xfc\xf2\x0b\xbc\xfc\xfb\x93\xfb\x8c\x21\x90\xed\xc9\x7e\xd0\x8e\x8e\x2a\xe3\x37\xf7\x73\x5d\xeb\x06\x7d\x2c\x39\x3c\x24\xeb\x5c\xd4\x93\x25\x75\x03\xe3\x02\xff\x98\x1b\x88\x68\xe8\x9b\x84\x26\x2f\x72\x6f\x9b\x1e\x1d\x42\x6d\xc4\xbb\x17\x38\x84\xd8\x1c\x69\xbe\xea\x99\x91\x40\xf8\x71\x65\x9e\xce\x64\xa8\xcf\x20\x4f\xfd\x54\xbf\xdc\x8d\x5d\x40\x7b\x67\xaf\x4d\x04\x94\x7e\x7b\x6f\x1f\x3f\x9e\xbf\xcb\xd2\x37\x6e\xbe\xca\x35\x8e\x1f\x3f\x06\x8d\x46\x75\xae\x8f\xa9\xfe\xf1\x9d\x83\x02\x10\xd2\x57\xcf\x23\x8f\xdb\xf6\x0c\xd3\xda\xf7\xd8\xe4\xcc\x86\xda\x88\x0e\xcd\x59\xb9\xea\x3d\x5d\x75\x4d\x1d\x58\x5a\x55\x8f\xd7\xae\xa8\xeb\x32\xda\xed\xbb\xe9\x41\xe2\x88\x6d\xd2\xc6\x60\x78\x28\xdc\x1e\x0b\x97\xa9\x3b\x59\xd7\xf1\x39\x94\xb4\xa7\x7b\xcb\x7e\x80\x26\xda\x67\xd1\x15\xfa\xbd\x50\x3b\x26\x6e\x1a\x53\x67\x0d\x83\x99\x5f\x6f\x57\xec\x7c\x3e\xa9\x26\x13\xff\x77\x00\xc2\xed\xc7\x6d\x73\xd5\x0f\x48\xec\x70\xaf\x0c\xc2\x87\xdb\xdb\xcd\xb6\x7e\x48\xb6\x8e\x19\x67\x93\xc1\x73\xc3\xed\xc7\xed\xcc\x09\xfb\xda\x8f\xe1\x85\x13\x36\x09\xdf\xcd\x33\xc7\x0d\xfb\x86\xc0\x84\x00\x89\x29\x5a\xcb\x4c\x5d\x40\x2c\x38\xe5\xab\xc0\xb9\x7c\x2a\x2d\x49\xd4\xf0\xda\x82\x55\x4a\xd2\xb5\x3b\x6a\xc2\x2d\xf8\x52\xef\x7d\x93\xc1\xae\x70\xde\x29\xa6\x90\xe4\x98\x45\x28\x3f\xa4\xa6\xe7\xe5\xff\xc3\xd8\x21\xa4\x4c\x08\xcc\x12\x62\xb9\xde\x53\x57\xe0\xeb\x3f\xe9\x90\xab\x8c\xef\x4f\xc0\xa2\x12\x0b\xb0\x8e\xac\xaf\xa5\x49\xeb\x98\x4c\xfd\xff\x24\xd6\x29\x0d\x9c\xae\xbb\x19\xff\xce\xb3\x82\x09\x71\x02\xc1\xfc\x4d\xcd\x4b\x8d\x75\x4d\x0b\x96\x62\x32\x69\xfe\x6e\xa9\x75\x49\x99\x6c\x55\x89\x15\x52\x20\x50\x03\x61\x17\x90\xa1\x46\x99\x71\x79\x00\x15\xba\x73\x59\xe4\x3b\x34\xa0\xf6\x5e\x17\x5a\x08\x37\x20\xeb\x59\xc7\xe7\xca\xef\x4c\x14\xd8\x58\x49\xb7\x26\x96\xa6\xca\x10\x1f\x71\x7a\x15\x1f\x3a\x17\xe1\xd7\x4e\x41\x19\x98\x16\x92\xdf\x4f\x87\x9e\x0c\x91\x36\xb3\xf0\xc2\x3f\x05\x85\xe1\x22\x4a\x59\x00\xcb\x32\xd3\xb4\xed\x65\x27\x7a\xda\xa3\x35\x70\x22\x19\xee\x9b\x01\x84\x63\x2c\x26\x78\x8f\x69\xe1\xa8\x69\xa4\xad\x16\x21\x53\xde\x75\x4c\x6b\x71\xaa\xc3\x21\xfe\x93\x91\xfc\xc7\x2a\x09\x99\x4a\x0b\x3a\x5f\xc9\x88\xb8\xc0\x0d\x2d\xb0\xbd\x43\x03\x46\x15\x8e\x30\xa2\x78\x88\x01\x4c\xfd\x1e\x4a\xc7\x53\xaf\xd1\x02\x76\x3c\xe0\xcb\x64\x46\xb8\xf1\xcc\xcf\x47\x24\x86\x67\x64\x56\x6b\xdd\x7d\x1a\x3b\x7b\x28\xfb\x5b\x3c\x81\x91\xf8\x29\xc0\x1c\x99\xd6\x28\x6d\xa3\xa4\x3c\xb9\xa3\x6f\xda\x43\xdf\xd4\x6e\x63\xc2\x2a\x8f\x0d\x0f\x87\xa5\x8e\x82\x87\x51\xda\xaa\x26\x16\x19\x1c\x94\xca\x42\x38\x12\x03\x2d\x8a\x03\x70\x09\x0c\x34\x93\x3c\x0d\x4a\x13\xc7\x56\xe8\xc2\xbf\xd1\xd5\x20\xe5\x48\xd5\xca\x76\x11\x3a\xcb\x32\x7f\x12\xa6\xff\x06\x00\x00\xff\xff\x07\xb6\xfb\x62\x8c\x1c\x00\x00") func templatesServerConfigureapiGotmplBytes() ([]byte, error) { return bindataRead( @@ -642,8 +668,8 @@ func templatesServerConfigureapiGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/server/configureapi.gotmpl", size: 6786, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x80, 0x9, 0x27, 0xe2, 0x95, 0x78, 0x35, 0xb1, 0x73, 0x83, 0xa2, 0xd, 0x6e, 0x5, 0x7d, 0x1e, 0xbf, 0xbd, 0x6b, 0xa5, 0x4b, 0xd5, 0xf2, 0x6a, 0x86, 0x1b, 0xa3, 0xa5, 0x56, 0x85, 0x2e, 0x5d}} + info := bindataFileInfo{name: "templates/server/configureapi.gotmpl", size: 7308, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x33, 0xee, 0x9c, 0x38, 0x1d, 0x9b, 0xe0, 0x8b, 0xc3, 0xb3, 0xdf, 0xa9, 0x1f, 0x24, 0xf0, 0x42, 0xcf, 0x83, 0xa6, 0x3e, 0x6f, 0xf1, 0xff, 0x32, 0x30, 0x44, 0x1, 0xce, 0x78, 0x9c, 0xaf, 0x70}} return a, nil } @@ -667,7 +693,7 @@ func templatesServerDocGotmpl() (*asset, error) { return a, nil } -var _templatesServerMainGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x57\x4d\x6f\xe3\x36\x13\x3e\x8b\xbf\x62\x56\xc0\x0b\x48\xfb\x3a\x52\x17\xbd\x65\xe1\x43\x90\x8f\xad\x8b\x6c\x1c\xc0\xd9\x43\xd1\x2d\x16\x8c\x38\x92\xd9\xd0\xa4\x4a\x52\xf1\xa6\x86\xfe\x7b\x41\x8a\xb6\xe5\x8f\xa4\x2e\x82\xa0\x8b\x6e\x2e\x71\xc4\x19\x0e\x87\xcf\x7c\x3c\x9c\x3c\x87\x53\xc5\x10\x2a\x94\xa8\xa9\x45\x06\xb7\x0f\x50\xa9\x23\x33\xa7\x55\x85\xfa\x3d\x9c\x8d\xe1\x6a\x7c\x03\xe7\x67\xa3\x9b\x8c\x10\x02\x8b\x05\xf0\x12\xb2\x53\x55\x3f\x68\x5e\x4d\x2d\x1c\xb5\x6d\x9e\xbb\xe5\x42\xcd\x66\x28\xed\x96\x6c\xb1\x00\x94\x0c\xda\x96\x10\x52\xd3\xe2\x8e\x56\x08\x33\xca\x25\x21\x7c\x56\x2b\x6d\x21\x21\x00\x71\x39\xb3\xb1\xfb\x15\xaa\xf2\xbf\x12\x6d\x3e\xb5\xb6\xf6\x1f\xca\xc4\xc4\xfd\x56\xdc\x4e\x9b\xdb\xac\x50\xb3\xbc\x52\x47\xaa\x46\x49\x6b\x9e\x0b\x45\x99\x89\x49\x14\x1c\xfb\x64\xf0\x83\x9a\x58\xdd\x14\xf6\x42\xd0\xca\x40\xdb\x96\xfe\xb7\xbf\xfd\x77\x34\x06\xef\xd9\x9d\xb3\xe3\xa5\xee\x9c\xe0\xe9\x51\xdb\x76\x1f\xc1\xda\x75\xdf\xcc\x86\x15\x53\x97\xef\x7e\xcc\x6b\xb7\xfe\xc4\xfe\xe5\xf6\x78\x8f\x5e\x50\xf4\x40\x18\xc8\xce\xb0\xa4\x8d\xb0\xa3\xf0\xbd\x32\xb4\x94\xf7\x04\x29\x21\x79\x0e\x37\x53\x6e\xa0\xe4\x02\x61\x4e\xcd\x66\x0c\xed\x14\x21\x04\x11\xac\x52\x22\x73\xfa\x1f\xe9\x1d\x82\x69\x34\x82\x54\x16\xac\x02\x75\x8f\x7a\xae\xb9\x45\xb0\x2b\x53\xb4\xb4\xa8\xe1\x41\x35\x3d\x83\xdc\xc2\x2d\x16\xb4\x31\x08\x54\x08\x27\xd4\x80\x8c\x5b\x03\x73\xd5\x08\x06\xb7\x08\x42\x19\xfb\x86\x84\x7b\x9f\x7f\x2d\x44\xc3\x70\x52\x63\xe1\xbc\x2d\x1b\x59\x00\x97\xdc\x26\x29\x2c\x08\x80\x8f\x59\x76\xc2\xd8\xa5\xa2\x0c\x75\x52\xce\xac\xc9\x7e\x39\xf9\x78\xf9\x91\xda\x62\x8a\x7a\x00\xab\x95\x33\x55\xa4\xa4\x25\xbd\x34\xf2\xc6\x5c\x0a\x05\x63\x7b\x42\x45\x00\xdc\xfa\x91\x13\xb8\x9b\x6e\xfb\x03\x4b\x68\xdc\xc2\x00\x50\x6b\x38\x1e\x06\xaf\xce\x67\xb7\xc8\x18\xb2\x64\xb1\x80\xec\xe4\x7a\x74\x1d\x92\xb6\x6d\xb3\x49\xb7\xe9\xe7\xc9\xf8\x6a\x00\xbb\xe2\x0b\x41\x6d\x4f\x25\x25\xe0\xce\x77\xc6\xdf\x0c\x41\x72\xe1\xbd\x75\x97\xaf\xb2\x0b\x6a\xa9\x10\x32\x41\xad\x9d\xda\xda\xe1\xe5\x25\x01\xee\xa9\x06\x83\xfa\x1e\x35\xbc\xdd\xe3\x4a\x27\xc9\x73\x98\xad\x62\xea\x00\x06\x6e\xa0\xa0\x42\x20\x23\x24\x72\x19\x97\x7d\x32\x6e\xcb\x10\x1c\x6c\x01\x31\x70\xf0\x66\x17\xb5\xe6\xd2\x26\xca\x64\x13\xcb\x50\xeb\x01\xc4\x5e\xf7\xf8\xb3\x8c\x53\x12\x45\x8f\xe8\x78\xc0\x19\x35\x53\xd4\xfc\x4f\x84\xec\x8a\xce\x9c\x47\x47\xc1\xd7\x5f\xc7\xd7\x37\xa3\xf1\xd5\xe4\xb7\xcf\xd2\xdb\xf1\xc7\x59\x6e\x05\x3a\x88\x43\xac\x46\xb2\x54\xe0\x7b\xc3\xf2\x2b\xbb\xf1\x2a\x7e\xcd\x9f\x59\x42\xfc\xbf\x3f\xe2\x5d\x21\x0a\x83\xeb\xad\x9b\x71\x8d\xe3\xb5\x42\x2f\xc0\x99\xfb\x93\xa4\x3d\x53\xab\x6c\xda\xf8\xe7\x05\x2c\xb7\xed\xa3\x40\x7a\x4c\xfe\x1f\x07\x98\xa2\x88\xa1\x29\x9e\x86\xe8\x0c\x4d\xa1\x79\x6d\xb9\x92\x8f\x01\xb5\xa3\xf2\xdc\x4b\xf5\x0c\xbe\x08\x68\x8f\xdb\x0f\x55\xcc\x4b\xf0\xc8\xbc\x19\x42\x1c\xc3\x82\x44\x7d\x3c\xcb\x3e\xa0\x4e\xad\x87\xe7\x26\xf2\x42\xf6\x55\x7d\x61\x9c\xaa\xd9\x8c\x4a\x76\xc9\x25\xba\xd2\xad\x7c\xf2\x9b\x24\x4d\x89\xdb\x9b\xe7\x50\x53\x6d\xd0\x37\xd2\xd3\xcb\x91\xdf\x63\x42\x4d\x5d\x3b\x49\x92\xf6\xdb\xcc\x76\x8b\x71\x3d\xa6\xab\x88\xe1\x9e\x56\x71\x85\xf3\xae\x82\x13\xc9\x45\xfa\x64\x3f\xf2\x68\x19\xab\xb9\xac\x92\xce\xa2\x5f\x4a\xff\x61\x7b\xa1\x35\xef\xb2\x2b\x0b\x6e\x74\x5e\xb8\x2c\xa2\xa6\xa0\xa2\x5f\xcb\x27\xd7\xa3\xa4\xe7\x50\xba\xba\x4b\x36\x41\xeb\x84\xb4\xe6\xeb\xcb\x87\x08\x13\x02\xd1\xb3\x0e\x71\x90\x57\x68\x97\xb0\xcd\xb9\x9d\x7a\xd0\xe1\x9e\x8a\x06\x3d\x39\x09\x64\xa0\x1a\x4b\xa2\x83\xa0\xdd\xf4\xb2\x6b\xac\x11\xc3\x12\xf5\xea\x3a\xd3\xc6\x32\x35\x97\x49\x4a\x96\x36\xb3\x53\x25\x4b\x5e\x35\x1a\x9d\x83\x29\x89\x02\xc6\xc7\xc3\x35\x06\xfa\x1e\x93\xf4\xfd\x26\xf4\x51\xb4\x03\xbc\x4b\xa3\x35\x6f\xf5\x89\x6a\xe3\x85\xb2\x49\x57\x7b\xa8\xaa\xbb\xeb\xf1\x41\x79\xb4\x19\x92\x6f\x8f\xe7\x9e\x9b\x89\xd1\x61\x68\x84\xd0\x3f\x16\xec\x5d\xb6\xf5\xb5\xee\xcd\xfa\x3a\x77\xa6\x7c\x91\xeb\x50\x73\x83\xb0\x1e\x9e\x68\xe9\x6a\x4b\x36\x99\x2a\x6d\xfb\x7d\xf7\xbb\x64\xb9\x15\x1c\x97\x4a\x56\x87\xa2\xf1\xdd\x11\xda\x01\xef\xd2\xad\x26\xe4\x3b\x84\xcf\xd8\x52\x69\xf8\x32\x00\x55\x5b\xf3\x41\xab\xa6\x76\xb9\xaa\xa9\xac\xd0\x15\x54\x9f\xcc\xc6\xfe\xf0\x4e\xc9\x84\x5a\xfc\xb2\x2a\xfe\x10\xa6\x13\xc6\xbc\x42\xb2\xb2\xb7\x93\xc8\xbd\xb3\xb6\xa3\xda\x17\x85\xe3\xd2\x25\x5b\xef\xf4\x81\xbd\x9d\xa0\x23\xa5\xdd\x77\xaf\x6b\xb7\x3b\xce\x06\xba\xdd\xe9\xb8\x85\x9b\x5c\x8f\x87\xf0\x8e\x44\x6e\x5f\x89\x03\x50\x77\x6e\x01\xb5\xce\x92\xb7\x5d\xc5\x9e\x6b\xad\x74\xfa\xde\x49\xfc\xeb\xc1\x2b\x66\x37\x0f\x35\xc2\x70\x59\xed\xe7\x5a\xff\x84\xa2\xee\x14\x3a\xb3\x43\xf8\xc1\x7d\xb4\xe1\x25\xa1\x4c\x76\xfe\x95\xdb\xc4\xc9\x7c\x67\x7f\xba\x65\xbf\x2c\x9b\xbf\x10\x9d\x1f\xde\x2d\xf7\x53\xe5\xfa\x0a\x7f\x47\x96\x4f\xbc\x53\xf6\x13\xe6\x1e\xa2\xdc\x57\x3f\xdf\x20\xe1\x6d\x81\xf7\x3a\xd7\xfd\x57\x18\xef\x75\xae\xfb\x17\xe7\xba\xed\xf9\x6d\x82\x76\xdc\xd8\xba\xe9\x45\xa2\xeb\x5b\xdd\xb8\xe6\x6c\x86\x97\x9b\x23\xd3\x83\xe7\xbb\xd7\x01\x6f\x63\x9a\x78\x9d\xef\xb6\xe7\xbb\x3e\x5f\xb5\xe4\xaf\x00\x00\x00\xff\xff\x88\xa0\xc7\x7a\x4d\x17\x00\x00") +var _templatesServerMainGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x57\x5b\x6f\xdb\x36\x14\x7e\x36\x7f\xc5\xa9\x80\x01\x52\xe7\x48\x2b\xf6\x96\xc2\x0f\x41\x2e\x9d\x87\x34\x0e\xe0\xf4\x61\x58\x87\x82\x91\x8e\x64\x2e\x14\xa9\x91\x54\xdc\xcc\xf0\x7f\x1f\x48\xd1\x36\x7d\x6d\x82\x35\xd8\xa5\x79\xb1\x2c\xf2\xe8\xe3\xe1\x77\x2e\x1f\x99\x65\x70\x2a\x0b\x84\x0a\x05\x2a\x6a\xb0\x80\xdb\x07\xa8\xe4\x91\x9e\xd2\xaa\x42\xf5\x16\xce\x46\x70\x35\xba\x81\xf3\xb3\xe1\x4d\x4a\x08\x81\xd9\x0c\x58\x09\xe9\xa9\x6c\x1e\x14\xab\x26\x06\x8e\xe6\xf3\x2c\xb3\xc3\xb9\xac\x6b\x14\x66\x63\x6e\x36\x03\x14\x05\xcc\xe7\x84\x90\x86\xe6\x77\xb4\x42\xa8\x29\x13\x84\xb0\xba\x91\xca\x40\x4c\x00\xa2\xb2\x36\x91\x7d\x72\x59\xb9\xa7\x40\x93\x4d\x8c\x69\xdc\x8b\xd4\x11\xb1\xcf\x8a\x99\x49\x7b\x9b\xe6\xb2\xce\x2a\x79\x24\x1b\x14\xb4\x61\x19\x97\xb4\xd0\xd6\x6e\x36\x3b\x72\xae\x7d\xd0\xf8\x4e\x8e\x8d\x6a\x73\x73\xc1\x69\xa5\xed\xda\x00\xa5\xfb\x1b\x62\xfc\x8e\x5a\xe3\x7d\x71\x67\xc1\xdc\xec\x02\xc4\xfb\xbb\x86\x78\xbd\x01\xb5\x86\xa4\x9b\xf2\xcd\x8f\x59\x63\xc7\x0f\x61\x04\x10\xd1\x0e\x5b\xf7\x06\x1d\x2b\x1a\xd2\x33\x2c\x69\xcb\xcd\xd0\xbf\x7b\xb0\xd5\x7c\x30\x91\x10\x92\x65\x70\x33\x61\x1a\x4a\xc6\x11\xa6\x54\xaf\x07\xd4\x4c\x10\x7c\x44\xc1\x48\xc9\x53\x6b\xff\x9e\xde\x21\xe8\x56\x21\x08\x69\xc0\x48\x90\xf7\xa8\xa6\x8a\x19\x04\xb3\x84\xa2\xa5\x41\x05\x0f\xb2\x0d\x00\x99\x81\x5b\xcc\x69\xab\x11\x28\xe7\x76\x52\x01\x16\xcc\x68\x98\xca\x96\x17\x70\x8b\xc0\xa5\x36\xaf\x88\xcf\x95\xf3\xcf\x39\x6f\x0b\x1c\x37\x98\x5b\x6f\xcb\x56\xe4\xc0\x04\x33\x71\x02\x33\x02\xe0\x02\x98\x9e\x14\xc5\xa5\xa4\x05\xaa\xb8\xac\x8d\x4e\x7f\x39\x79\x7f\xf9\x9e\x9a\x7c\x82\xaa\x0f\xcb\x91\x33\x99\x27\x64\x4e\x82\x9c\x72\x60\x36\x9f\x3c\x98\x5f\x72\x23\x62\xcb\x30\xd8\x9d\x6e\xfa\x03\x0b\x6a\xec\x40\x1f\x50\x29\x38\x1e\x78\xaf\xce\xeb\x5b\x2c\x0a\x2c\xe2\xd9\x0c\xd2\x31\xaa\x7b\x54\xd7\x5d\x12\x9f\x70\x46\x2d\x7a\x3a\xee\x3e\xfe\x79\x3c\xba\xea\xc3\x7e\xb3\x0b\x4e\x4d\x60\x9a\x10\xb0\xfe\xd8\xc5\x5e\x0d\x40\x30\xee\xbc\xb7\x64\x54\xe9\x05\x35\x94\x73\x11\xa3\x52\xd6\x6c\xb5\x81\x55\xa2\xdc\x53\x05\xda\xad\x03\xaf\x0f\xb8\xd6\x59\x64\x19\xd4\xcb\x58\x5b\xe2\x81\x69\xc8\x29\xe7\x58\x10\xd2\xb3\x99\x98\x7e\xd0\xb6\x2e\x07\x60\xe9\xf4\x4c\x82\xa5\x3d\xbd\x68\x14\x13\x26\x96\x3a\x1d\x9b\x02\x95\xea\x43\xe4\x6c\x8f\x3f\x8a\x28\x21\xbd\xde\x1e\x1b\x17\x88\x82\xea\x09\x2a\xf6\x27\x42\x7a\x45\x6b\x84\xf9\xfc\xc8\xfb\xfc\xeb\xe8\xfa\x66\x38\xba\x1a\xff\xf6\x51\x38\x1c\xb7\x9c\x61\x86\xa3\xa5\xde\xc7\x70\x28\x4a\x09\xae\x81\x2c\xde\xd2\x1b\x67\xe2\xc6\xdc\x9a\x25\x44\xdf\xfd\x11\x6d\x4f\x22\xd7\xb8\xfa\x74\x3d\xde\x51\xb4\x32\x08\x02\x9f\xda\x9f\x38\x09\xa0\x96\x59\xb6\xf6\xe7\x19\x90\xe7\xf3\xbd\x44\x3a\x4e\xbe\x8f\x3c\x4d\xbd\x5e\x81\x3a\x3f\x4c\xd1\x19\xea\x5c\xb1\xc6\x30\x29\xf6\x11\xb5\x65\xf2\x77\x37\x15\x00\x3e\x0b\x69\xfb\xf1\x7d\x75\xb3\x12\x1c\x33\xaf\x06\x10\x45\x30\x23\xbd\x90\xcf\x32\x24\xd4\x9a\x05\x7c\xae\x33\xcf\x45\x68\xea\x0a\xe3\x54\xd6\x35\x15\xc5\x25\x13\x68\x4b\xb8\x72\xc9\xaf\xe3\x24\x21\xf6\xdb\x2c\x83\x86\x2a\x8d\xae\xc1\x9e\x5e\x0e\x3b\x95\xf1\x35\x75\x6d\x67\xe2\x24\x6c\x3f\x9b\xad\xc7\xf6\x9e\xae\x22\x06\x07\x5a\xc7\x15\x4e\xbb\x89\x58\x30\x9e\x1c\xec\x57\x8e\x35\x6d\x14\x13\x55\xdc\x21\xbb\xa1\xe4\x89\xed\x86\x36\xac\xcb\xb2\xf4\xe4\x7a\x18\xba\xd3\x79\x63\xb3\x8a\xea\x9c\xf2\xb0\xb6\x4f\xae\x87\x71\xe0\x58\xb2\xdc\x5b\x3a\x46\x63\x27\x69\xc3\x56\x64\xf8\x88\x93\xaf\xb5\x98\x0d\x45\x85\x66\x41\xe7\x94\x99\x49\xa7\xd3\xf7\x94\xb7\xe8\xc4\x8c\x63\x01\xb2\x35\xa4\xf7\x24\xca\xd7\xbd\xee\x1a\x70\xaf\xc0\x12\xd5\x72\x7b\x93\xd6\x14\x72\x2a\xe2\x84\x2c\xb0\xd3\x53\x29\x4a\x56\xb5\x0a\xad\xa3\x09\xe9\x79\xee\x8f\x07\x2b\x4e\xd4\x3d\xc6\xc9\xdb\xf5\x90\xf4\x7a\x5b\x01\xb1\x69\xb6\xd2\xbb\x50\xe0\xd6\x0e\x39\xeb\x32\xb7\x43\xe2\xba\x3d\x1f\x3f\x29\xcf\xd6\x43\xf5\xef\xd7\xc9\xaf\x96\x4c\x4f\x63\xcb\xa7\xc8\xbe\xa4\xd8\x56\x6f\xd7\x33\x1c\xbc\xeb\x17\x16\xca\x35\x0b\xe5\x6b\xb6\xef\xc7\xfd\x11\x30\x59\x7e\x92\x8e\x27\x52\x99\xb0\x7f\x7f\x93\x6a\xb9\xa4\xe3\x52\x8a\xea\xb1\x6c\x7c\x73\xc2\xf8\x88\x73\xef\x46\xb3\x72\x9d\xc4\x65\x6c\x29\x15\x7c\xea\x83\x6c\x8c\x7e\xa7\x64\xdb\xd8\x5c\x55\x54\x54\x68\x0b\x2c\x14\xc5\x91\x5b\xbc\x33\xd2\xbe\x36\x3f\x2d\x9b\x83\x0f\xd3\x49\x51\x38\x83\x78\x89\xb7\x95\xc8\xc1\x5a\x9b\x51\x0d\xa7\xfc\x72\xc9\x42\xf5\xb7\xfa\xc2\xce\xce\xd0\x89\xda\xf6\x39\xda\xb6\xe5\x2d\x67\xbd\x6c\x6f\x75\xe6\xdc\x5e\x93\x8f\x07\xf0\x86\xf4\xec\x77\x25\xf6\x41\xde\xd9\x01\x54\x2a\x8d\x5f\x77\x15\x7b\xae\x94\x54\xc9\x5b\x3b\xe3\x4e\x21\xce\x30\xbd\x79\x68\x10\x06\x8b\x6a\x3f\x57\xea\x27\xe4\x4d\x67\xd0\xc1\x0e\xe0\x07\xfb\x32\xf7\x27\x12\xa9\xd3\xf3\xcf\xcc\xc4\x76\xce\x29\xc0\xe1\xd6\xfe\xbc\xa7\x81\x67\x3e\x0e\x3c\xbe\x6b\xee\x96\xd6\xd5\x56\xbe\x24\xae\x07\xce\x3b\xbb\x05\x76\x87\xb0\xee\xaa\xa3\xff\x80\x30\x6e\x90\xf9\x72\x7f\xfc\xbf\x29\xe2\xcb\xfd\xf1\x1f\xbc\x3f\x6e\xde\x13\xc7\x68\x46\xad\x69\xda\x20\x12\x5d\x3f\xeb\xae\x85\x16\xd3\x9f\xec\xac\xd8\x3e\xfa\x1e\xf9\x72\x91\x3c\x74\x91\x7c\xb9\x47\x7e\xf1\x1e\x19\xea\xdc\x9c\xfc\x15\x00\x00\xff\xff\x82\x07\x48\x11\xfa\x17\x00\x00") func templatesServerMainGotmplBytes() ([]byte, error) { return bindataRead( @@ -682,12 +708,12 @@ func templatesServerMainGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/server/main.gotmpl", size: 5965, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x18, 0x3a, 0x5f, 0x4, 0xcb, 0x2, 0x79, 0xa2, 0x38, 0x87, 0x61, 0x77, 0x5c, 0xac, 0x21, 0x9c, 0xa5, 0x9d, 0x1c, 0xa0, 0xc9, 0x41, 0xba, 0x52, 0xc2, 0x20, 0x9f, 0x9b, 0x64, 0x2c, 0xab, 0x8f}} + info := bindataFileInfo{name: "templates/server/main.gotmpl", size: 6138, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x26, 0x57, 0xb3, 0x4, 0x1f, 0x3e, 0x53, 0xdb, 0xd7, 0xe3, 0x4a, 0x9b, 0x13, 0x7c, 0x4d, 0xab, 0x85, 0x9c, 0xd, 0xf9, 0x3c, 0x67, 0x32, 0x9a, 0x90, 0xf7, 0x4d, 0x4e, 0xcf, 0x87, 0xad, 0xa4}} return a, nil } -var _templatesServerOperationGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x57\x4d\x6f\xdb\x46\x13\xbe\xf3\x57\xcc\x2b\xbc\x08\x28\x43\x26\xef\x0e\x7c\x48\xed\x14\xf1\xa1\x89\x60\x1b\xed\xb1\x58\x93\x43\x72\x11\x72\x97\x99\x1d\x5a\x56\x08\xfe\xf7\x62\x3f\x48\x53\x2e\x25\x05\x2d\x7a\x28\x7a\x92\xc8\x9d\x9d\x8f\xe7\x99\x2f\xa6\x29\xdc\xe8\x1c\xa1\x44\x85\x24\x18\x73\x78\xda\x43\xa9\x2f\xcd\x4e\x94\x25\xd2\x7b\xb8\xfd\x02\x9f\xbf\x3c\xc2\xc7\xdb\xbb\xc7\x24\x8a\xa2\xbe\x07\x59\x40\x72\xa3\xdb\x3d\xc9\xb2\x62\xb8\x1c\x86\x34\x85\xbe\x87\x4c\x37\x0d\x2a\x7e\x73\xd6\xf7\x80\x2a\x87\x61\x88\xa2\xa8\x15\xd9\x57\x51\xa2\x15\x4e\xb6\xe1\xbf\x3d\x48\x53\x78\xac\xa4\x81\x42\xd6\x08\x3b\x61\x0e\x9d\xe1\x0a\x21\x78\x03\xac\x75\x9d\x58\xf9\x8f\xb9\x64\xa9\x4a\xe0\xe9\x5e\xe3\x2c\xb6\xa4\x9f\x11\x8a\x8e\x9d\xaa\x0a\x15\xec\x75\x07\x84\x97\xd4\x29\xa7\x69\x54\xed\xdc\x15\x2a\x8f\x22\xd9\xb4\x9a\x18\xe2\x08\x60\xa5\x90\xd3\x8a\xb9\x5d\x45\xf6\xa9\x94\x5c\x75\x4f\x49\xa6\x9b\xb4\xd4\x97\xba\x45\x25\x5a\x99\x22\x91\x26\xb3\x3a\x2e\x40\x9d\x62\xd9\x60\xda\xc8\x3c\xaf\x71\x27\x08\x7f\x40\xd8\x60\xd6\x91\xe4\xfd\x09\x51\xc3\x54\x34\x7c\x4a\x60\x27\xca\x13\xc7\xcf\xa2\x96\xb9\x60\x74\xc1\x59\x1e\x5d\xe0\x06\x92\x5b\x2c\x44\x57\xf3\x5d\x78\x1e\x86\x37\xe7\xb3\x83\xb5\x63\xab\xef\xa1\x15\x26\x13\xb5\xfc\x8e\x90\x7c\x16\x8d\xe5\xf1\x93\x50\x79\x8d\xf4\x73\xa7\x32\xe0\x8e\x94\x01\x01\x45\xa7\x32\x96\x5a\xc1\x4e\x72\xe5\xf0\xf7\x89\x61\x64\xa9\x04\x77\x84\x20\x15\x6b\x10\x56\x63\xd5\x35\x42\xcd\x15\x42\xe5\x35\x46\xbc\x6f\xf1\xbc\x4d\x6b\x2b\x5e\x94\xda\x0a\x12\x8d\x09\x99\xfb\xa1\xe3\x4a\x93\xfc\x8e\x36\x29\x37\xe0\xdf\x2a\xcd\x10\x03\x7e\x83\x64\x4b\x52\x65\xb2\x15\x35\xac\xa4\x62\xa4\x42\x64\xd8\x0f\x2b\x58\xc3\x30\x5c\x4c\xc9\xec\x32\x78\x92\x9c\x65\xf9\x3a\x28\xfc\x7f\xf2\xc0\x24\x33\xbe\x47\xd3\x6a\x95\x23\x59\xf4\x96\x63\x98\x44\xa0\xef\xb1\x36\x38\x0c\xf0\x9a\x39\xc9\xc1\xa9\xca\x43\xb9\xf8\xb8\x01\x5f\x30\xeb\x42\x1d\x20\x10\x7e\xeb\xd0\x30\x08\x95\x03\xa1\xa5\xc0\x9e\x08\x20\xa7\xc2\x60\x64\x11\x82\xb8\x50\x67\xb1\x5c\x07\x03\x71\xeb\x90\x5b\x96\x3f\x85\x6a\x3b\x61\xf3\xaf\xc3\x17\xfa\x08\x02\x7c\x50\xa8\x80\xc0\x99\x28\x5f\xdd\x8b\x86\xb3\x05\x02\x53\xdc\x50\x68\x02\xae\x04\x43\x26\x54\xc8\x76\x70\x55\xba\x5c\x0f\xde\x97\xf3\xe5\x30\xb3\x60\x83\x09\x5c\xfe\x07\x4a\xc3\x83\xff\x19\x77\x8b\xda\x20\x23\x14\x8c\xb6\x2f\x29\xdc\x81\xed\xf3\xc9\x88\x98\x67\x02\x97\x71\xd7\xad\x1d\x19\x52\x2b\x5f\x41\xc7\xf4\xc7\x19\xbf\xc0\xc5\xcc\xc1\x1b\xad\x18\x5f\x78\x33\x36\xb2\x93\xa4\xad\xe1\x62\xd9\xeb\x59\x3e\xbe\x5b\x94\xe8\x83\x9d\x2b\xc8\xf8\x65\x13\xe8\xa6\xab\xd1\xaa\x87\xe5\x88\xf2\x30\x58\xaf\x48\x77\xec\x07\xf3\x2f\xc8\x95\xce\x03\x25\xc9\x56\x70\xe5\x49\x24\xa1\x4a\x84\xe4\x51\x94\x23\x5f\xc9\x9c\x5d\xb7\x01\x88\x06\x0f\xd4\x4f\xeb\xc2\x43\xd7\x34\x82\xf6\x21\x3d\x0e\x9e\xec\xf1\x2d\x9a\x8c\x64\xeb\x26\x45\xb8\xf5\x54\xeb\xec\xeb\xb4\x52\x1c\x0a\xcc\x73\xcd\xa6\xc5\x5b\x1d\xee\xe0\x9c\x02\x7b\xcf\xfd\x5b\x82\x7c\x29\x0b\x3e\x6c\xef\x66\xcb\xcc\x45\x7a\xa2\x0e\xc1\x30\x75\x19\x3b\xea\x02\x39\x4b\x89\x31\xd5\xe6\xe9\xcc\xb0\xfc\xf9\xd6\x6d\xc1\xbb\xc7\x0c\xe5\x33\xd2\x68\x6a\x99\xd8\x35\x3c\x20\x3d\xe3\xa7\xc7\xc7\x6d\x4c\x21\xd7\xef\xc3\x1c\xf8\x8d\x24\x23\x6d\x80\xe0\x22\xbc\x77\x73\x63\xed\x33\xcd\x26\xc2\x06\xe8\xc6\xa6\xd2\xef\x70\x75\x0d\x0b\x46\xc7\x00\x92\x7b\x2b\x7d\xa7\x0a\x1d\xd3\x3a\x02\xcb\x83\xbd\x08\xff\xbb\x06\x25\x6b\xa7\x0f\x80\xe0\xda\xbd\x8d\x00\xec\x62\xf1\x2c\x08\x7c\xd7\x81\xeb\xa3\xa5\xe4\x05\xe2\xf5\xb8\xa9\xbc\x6d\x4e\x9d\x6b\xbd\x1b\x10\xce\x4d\x24\x3a\xe7\xe8\x74\x3b\xb6\x81\x5b\xaf\x83\xbf\xf6\xee\x81\xbb\x27\xc3\xf5\x1d\x27\xa6\xdd\x06\x46\x3d\xc9\x96\x74\xde\x65\x68\x36\x23\x76\x48\x0e\x8c\xb1\x6a\x43\xdc\xb2\x70\xde\xfe\x19\x1b\x71\x88\xcd\xe2\xe8\x3c\xd1\x7e\x4f\x77\x5f\x6f\xd8\xc3\x75\x68\xfa\xd5\xce\x75\xb0\x74\xaa\xc7\x8f\x90\xbf\x56\x8e\x7f\x4e\xe2\x8b\xb7\x26\xd7\x90\xa6\x7e\x2f\x97\x06\x08\x45\x5d\xef\xfd\x82\x77\x20\xb5\x81\x3b\xbb\xac\x37\xd2\xe0\x6b\x55\x59\x14\x3c\xe3\xd3\x8b\x40\xd1\x19\x7a\x7f\x92\x2a\xff\xd5\x0e\xce\x90\xcb\x13\xcb\x1b\x78\xe7\x73\x69\xfd\xfe\x80\x6a\xeb\xe3\x93\x54\xf9\x38\x53\xff\x39\xe6\x8f\x64\xb0\x6b\xea\xe6\x58\x5c\xa1\xf2\xc3\x6f\xec\x43\x98\x2d\x1c\x0e\x63\x91\x71\xe7\xd0\x0d\x9b\xc3\x6c\x07\x74\x46\xfd\xc4\xfc\x0b\x86\x7e\x48\xfb\x2b\x45\x7f\x1f\x37\x42\xb3\x8e\x22\xdf\xf8\xc3\x9c\xf9\xf8\xc2\x24\x1e\xb2\x0a\x1b\xe1\x3e\x3c\xfc\x52\x35\xef\xd0\x8c\x4d\x5b\xdb\x2f\xb9\x55\xae\x33\xc3\x24\x55\xb9\x72\x33\x29\x4a\x53\x2b\x3e\x8e\xb6\x46\xe7\x58\xcf\x2f\x3b\x97\x2f\x67\xf7\x8d\x33\x13\x2e\xdb\xa3\x10\xda\x1f\x01\x00\x00\xff\xff\x64\x70\xfa\x14\x1c\x0f\x00\x00") +var _templatesServerOperationGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x57\x4b\x6f\xdb\xc6\x13\xbf\xf3\x53\xcc\x5f\xf8\x23\xa0\x0c\x99\xbc\x3b\xf0\x21\xb5\x53\xc4\x87\x3a\x82\x2d\xb4\xc7\x62\x4d\x0e\xc9\x45\xc8\x5d\x66\x76\x68\x59\x21\xf8\xdd\x8b\x7d\x50\xa2\x1c\x5a\x0a\xfa\x00\x8a\x9e\xec\xe5\xce\xce\xe3\x37\xbf\x79\x28\x4d\xe1\x46\xe7\x08\x25\x2a\x24\xc1\x98\xc3\xd3\x0e\x4a\x7d\x69\xb6\xa2\x2c\x91\xde\xc3\xed\x67\xb8\xff\xbc\x81\x8f\xb7\x77\x9b\x24\x8a\xa2\xbe\x07\x59\x40\x72\xa3\xdb\x1d\xc9\xb2\x62\xb8\x1c\x86\x34\x85\xbe\x87\x4c\x37\x0d\x2a\x7e\x75\xd7\xf7\x80\x2a\x87\x61\x88\xa2\xa8\x15\xd9\x17\x51\xa2\x15\x4e\xd6\xe1\x7f\x7b\x91\xa6\xb0\xa9\xa4\x81\x42\xd6\x08\x5b\x61\x8e\x9d\xe1\x0a\x21\x78\x03\xac\x75\x9d\x58\xf9\x8f\xb9\x64\xa9\x4a\xe0\xfd\xbb\xc6\x59\x6c\x49\x3f\x23\x14\x1d\x3b\x55\x15\x2a\xd8\xe9\x0e\x08\x2f\xa9\x53\x4e\xd3\xa8\xda\xb9\x2b\x54\x1e\x45\xb2\x69\x35\x31\xc4\x11\xc0\x42\x21\xa7\x15\x73\xbb\x88\xec\xa9\x94\x5c\x75\x4f\x49\xa6\x9b\xb4\xd4\x97\xba\x45\x25\x5a\x99\x22\x91\x26\xb3\x78\x5b\x80\x3a\xc5\xb2\xc1\xb4\x91\x79\x5e\xe3\x56\x10\xfe\x80\xb0\xc1\xac\x23\xc9\xbb\x13\xa2\x86\xa9\x68\xf8\x94\xc0\x56\x94\x27\xae\x9f\x45\x2d\x73\xc1\xe8\x82\xb3\x79\x74\x81\x1b\x48\x6e\xb1\x10\x5d\xcd\x77\xe1\x3c\x0c\xaf\xee\x27\x17\x4b\x97\xad\xbe\x87\x56\x98\x4c\xd4\xf2\x1b\x42\x72\x2f\x1a\x9b\xc7\x4f\x42\xe5\x35\xd2\xcf\x9d\xca\x80\x3b\x52\x06\x04\x14\x9d\xca\x58\x6a\x05\x5b\xc9\x95\xc3\xdf\x13\xc3\xc8\x52\x09\xee\x08\x41\x2a\xd6\x20\xac\xc6\xaa\x6b\x84\x9a\x2a\x84\xca\x6b\x8c\x78\xd7\xe2\x79\x9b\xd6\x56\x3c\x2b\xb5\x16\x24\x1a\x13\x98\xfb\xa1\xe3\x4a\x93\xfc\x86\x96\x94\x2b\x08\x5f\xd7\x24\x55\x26\x5b\x51\xdf\x99\xfb\xae\xae\xc5\x53\x6d\x1f\x5e\xec\xd9\xeb\x28\x3b\xca\xc0\x84\xd6\xcb\xa0\xe1\xff\xc9\x23\x93\xcc\xf8\x01\x4d\xab\x55\x8e\x64\xe1\x9a\x77\x7a\x2f\x02\x7d\x8f\xb5\xc1\x61\x80\x03\x55\x92\xa3\x5b\x95\x87\xfa\xf0\x81\x02\xbe\x60\xd6\x05\xe2\x23\x10\x7e\xed\xd0\x30\x08\x95\x03\xa1\xc5\xdc\xde\x08\x20\xa7\xc2\x60\x64\x21\x81\xb8\x50\x67\xc1\x5b\x06\x03\x71\xeb\xa0\x9a\x97\x3f\x05\x63\xbb\xc7\xe6\xdf\x0f\x28\xf4\x11\x04\xbc\xa0\x50\x21\xe4\x33\x61\x1d\xdc\x8b\x86\xb3\x25\x60\x49\x8d\x54\x88\x0c\xa1\xd0\x04\x5c\x09\x86\x4c\xa8\xc0\x67\x70\x75\x38\xcf\x78\xef\xcb\x79\xc2\x4f\x2c\xd8\x60\x42\xf2\xfe\x8b\xe4\xf7\x68\xdf\xe3\x76\x56\x1b\x64\x84\x82\xd1\xb6\x1a\x85\x5b\xb0\xad\x3b\x19\x21\xf2\xd0\xe3\x3c\xd0\xba\xb5\x53\x40\x6a\xe5\x6b\xe4\x2d\xfd\x71\xc6\x2f\x70\x31\x71\xf0\x46\x2b\xc6\x17\x5e\x8d\xbd\xe9\x64\x96\x96\x70\x31\xef\xf5\x84\x80\xef\x66\x25\xfa\x60\xe7\x0a\x32\x7e\x59\x85\xfc\xd2\xd5\x68\xd5\xc3\x72\x31\x6f\x7c\x1c\x96\x57\xa4\x3b\xf6\xc3\xf6\x17\xe4\x4a\xe7\x21\x27\xc9\x5a\x70\xe5\xb3\x48\x42\x95\x08\xc9\x46\x94\x63\xc2\x92\x69\x7a\xdd\x54\x17\x0d\x1e\xa9\xdf\xaf\x00\x8f\x5d\xd3\x08\xda\x05\x7e\x1c\x9d\xec\xf5\x2d\x9a\x8c\x64\xeb\xba\x7f\x78\xf5\x54\xeb\xec\xcb\x7e\x4d\x38\x16\x98\x92\xcd\xf2\xe2\xb5\x0e\x77\x71\x4e\x81\x7d\xe7\xfe\x9b\xc3\x7c\x8e\x06\x1f\xd6\x77\x93\x05\xe5\x22\x3d\x51\x79\x60\x98\xba\x8c\x5d\xee\x42\x76\xe6\x98\xb1\xaf\xc6\xd3\xd4\xb0\x09\xf4\xdd\xd9\x82\xf7\x80\x19\xca\x67\xa4\xd1\xd4\x3c\x6d\x96\xf0\x88\xf4\x8c\x9f\x36\x9b\x75\x4c\x81\xec\x0f\xa1\xd5\xff\x46\x92\x91\x56\x40\x70\x11\xbe\xbb\xd1\xb0\xf4\x54\xb3\x44\x58\x01\xdd\x58\x2e\xfd\x0e\x57\xd7\x30\x63\x74\x0c\x20\x79\xb0\xd2\x77\xaa\xd0\x31\x2d\x23\xb0\x79\xb0\x0f\xe1\x7f\xd7\xa0\x64\xed\xf4\x01\x10\x5c\xbb\xaf\x11\x80\x5d\x16\x9e\x05\x81\xef\x33\x70\xfd\x66\x2d\x79\x81\x78\xe9\xb7\x8f\xcb\xef\xfb\x51\x04\xd0\xb9\x86\xbb\x02\xe1\x5c\x45\xa2\x73\xce\xee\x15\xc4\x36\x78\xeb\x79\xf0\xd9\xbe\x3d\x72\xf9\x64\xc8\xbe\xed\xc4\xb4\x5d\xc1\xa8\x27\x59\x93\xce\xbb\x0c\xcd\x6a\xc4\x0f\xc9\x01\x32\x96\x6e\x88\x5d\x16\xce\xdb\xef\xf1\x11\xc7\xf8\xfc\xe5\x09\xe9\x6d\x79\x84\x8e\xad\x1d\x54\x5f\x07\xe5\xf8\x75\xfa\x76\x21\x55\xe1\xa7\x45\x3f\x2c\x60\x18\xbc\x8e\x43\xc1\xf8\x73\x12\xff\x49\xc7\x96\x90\xa6\x7e\x11\x97\x06\x08\x45\x5d\xef\xfc\x46\x77\x24\xb5\x82\x3b\xbb\x9d\x37\xd2\xe0\xa1\xe4\x3c\x3c\xd3\x73\x48\xdd\x99\xb4\xff\x24\x55\xfe\xab\x1d\xa3\x81\xe7\xfb\xec\xaf\xe0\x9d\xe7\xd9\xf2\xfd\x11\x05\xac\x8b\x4f\x52\xe5\xe3\x84\xfd\xe7\x18\xe1\x5a\xbb\x79\x2b\x80\x50\xfe\xe1\x6f\xfc\x43\x2b\xd5\x64\xdc\xa6\x29\x88\x8c\x3b\x07\x71\xd8\x26\x26\x8b\x60\xf4\x77\xc4\x44\x68\x96\x51\xe4\x1b\x76\x98\x0f\x1f\x5f\x98\xc4\x63\x56\x61\x23\xdc\x8f\x00\xbf\xfe\x4c\x3b\x2b\x63\xd3\xd6\xf6\x57\xd5\x22\xd7\x99\x61\x92\xaa\x5c\xb8\x59\x12\xa5\xa9\x15\x1f\x47\x52\xa3\x73\xac\xa7\x8f\x43\x2f\x38\xbc\x37\xce\x4c\x78\x6c\xaf\x02\x33\xfe\x08\x00\x00\xff\xff\x9c\x28\xa4\x7b\xa8\x0e\x00\x00") func templatesServerOperationGotmplBytes() ([]byte, error) { return bindataRead( @@ -702,12 +728,12 @@ func templatesServerOperationGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/server/operation.gotmpl", size: 3868, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x93, 0x85, 0xb, 0x19, 0xe8, 0x7d, 0xb, 0xc0, 0x51, 0x86, 0x7d, 0x2d, 0x8b, 0x11, 0xfe, 0x39, 0x17, 0x4f, 0xa3, 0xba, 0xc1, 0x9, 0x51, 0xff, 0x12, 0xcf, 0x4c, 0xde, 0xf5, 0x7d, 0xfb, 0x67}} + info := bindataFileInfo{name: "templates/server/operation.gotmpl", size: 3752, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x12, 0x9e, 0xc1, 0x15, 0xfc, 0x9c, 0x4f, 0x16, 0xa3, 0xd7, 0x49, 0xc2, 0xf, 0x43, 0x7d, 0x78, 0xd6, 0x19, 0x4f, 0xd5, 0xb1, 0x2a, 0xd7, 0xee, 0x51, 0xb6, 0xa9, 0xc6, 0x7d, 0xe0, 0x46, 0x5c}} return a, nil } -var _templatesServerParameterGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3d\x5b\x73\xdb\x36\xba\xcf\xab\x5f\xf1\xad\xce\xd9\x0c\xe9\x91\xc9\x9e\x3d\x9d\x7d\x70\xeb\xce\x24\xb6\xdb\x78\xda\x5c\x4e\x92\xf6\xe1\x64\x33\x5b\x58\x84\x24\x6c\x48\x82\x01\x20\x3b\x3a\x1a\xfe\xf7\x33\xb8\x91\x00\x09\x52\x54\xec\xa6\xed\xb4\xfb\xb0\xb5\x88\xdb\x77\x01\xbe\x3b\x90\xfd\x1e\x32\xbc\x22\x25\x86\xf9\x0d\x29\xb3\x8a\x91\x82\x08\x72\x8b\x2b\xc4\x50\x31\x87\xba\xde\xef\xd3\x13\x40\x25\xe0\xa2\x12\x3b\x10\x98\x0b\x3d\x80\x08\x42\x4b\x10\x54\x7f\x12\xb8\xa8\x72\x24\x30\x30\x5c\x51\xc8\x70\x85\xcb\x0c\x97\x4b\x82\x39\x30\xcc\x69\xbe\x55\xbd\x4f\xe1\xf2\x05\x3c\x7f\xf1\x06\x2e\x9e\x3e\x7e\xfe\xdd\x15\xbc\x79\x7a\xfd\x1a\x4e\xd2\xba\x9e\xed\xf7\x80\xcb\x0c\xea\x7a\x36\x73\x21\xa2\xd9\xee\x16\xe5\x24\x43\x82\x32\x09\xcc\x0c\x60\xbf\x3f\x05\xb2\x82\xe4\x29\xe2\xcf\x68\x86\xf3\x27\x34\xdb\xbd\x94\xc0\x72\xdd\x9e\xa6\x60\x86\x60\x90\xe3\x81\xde\xfc\x1b\x2f\x85\x42\x23\xc3\x39\x5e\xcb\x06\xd3\xc3\x60\x50\xc8\x79\x4c\x3f\x0d\x0e\xc8\x25\x30\x63\x70\x76\xae\x26\x49\x7e\x32\x53\x46\x8c\x6e\x05\x4e\xbe\xa5\xac\x40\x82\xc7\x5f\xa9\x4e\x7f\x3d\x87\x92\xe4\xb0\x9f\x01\x80\x44\x17\xce\x01\x55\x92\x02\x11\xc3\x7c\x21\xbb\xc4\x33\x80\x7a\xa6\xa7\xcd\x71\x29\xbf\xc7\x70\x7e\x0e\x5f\x98\x41\xfb\x3d\x24\xaf\xf0\x12\x93\x5b\xcc\x9e\xa3\x02\x43\x5d\x27\xfb\x3d\x54\x88\x2f\x51\x4e\xfe\x0f\x43\x62\xbe\xc2\xb9\xec\x4b\x56\x80\xca\x0c\xa2\x92\x0a\x48\x5e\x2f\x37\xb8\x40\xc9\x35\x7f\x82\x38\x7e\xb3\xab\x70\x0c\xc9\x35\x7f\xbe\xcd\x73\x74\x93\xcb\x31\x8f\x1a\xe2\x4a\x54\x14\x24\x9a\x8c\x38\xe7\xd8\xce\x25\xe9\xf9\x9a\x14\x55\x8e\x1d\x82\x7a\x44\xbe\x16\x58\xd3\xd8\x40\xac\xd8\x40\x59\x03\x80\x9c\x20\x27\x4b\xfc\x53\x43\x5b\xde\x02\x27\xc7\xca\x1e\x6e\x63\x8f\x5d\x88\x31\xb4\x03\xba\x72\xf9\xc6\x9b\xd5\xcc\xfe\x70\x16\x1f\x5b\xd9\xf4\xfc\xdc\xa4\x35\x2b\x36\xc7\x61\xce\x25\x60\xea\x30\x39\x1b\x39\x71\x11\xb1\xfb\xde\x41\x4c\x31\x64\x8c\x74\x0a\xbc\xc8\x21\xbe\xee\x75\xcd\xaf\x4b\x81\xd9\x0a\x2d\x71\xaf\xe5\xb5\x60\x18\x15\x71\xac\x97\x5e\x51\xa6\x28\x73\x5d\x66\xf8\xe3\x4f\x88\x49\xfc\xcf\xce\x81\xa1\x72\x6d\x8e\xcd\xbe\xc1\xc6\xa3\xb5\x9d\xce\x21\x82\xea\x48\x34\xd7\xde\x76\x26\x7d\x27\x77\x79\x7b\x38\x06\x27\x7c\x85\x3f\x6c\x09\xc3\x59\xcb\xb7\x81\x93\x44\x59\xdb\x39\x92\x8b\x5d\x6c\x48\x9e\x25\x2f\x91\xd8\x40\x5d\x2f\x24\x52\x15\x23\xa5\x58\xc1\xfc\x6f\x1f\xe6\xb6\xf9\x07\xba\xd4\xa7\x5d\x76\x09\xc2\x19\xc7\xcd\xba\x37\x0c\xa3\xf7\x1e\xb8\xea\xa0\x34\x90\x2d\x69\x29\x48\xb9\xc5\x7e\x97\x76\x77\xd6\xb3\xe0\x67\x5f\xa2\xf4\x00\x38\x42\xc4\x8c\x08\x19\x1f\xfe\xda\x8a\x1d\x87\xee\xee\xc6\x1e\x3c\x38\xbf\x19\x31\x35\x70\xf8\x5b\x86\xa4\x29\x94\xd4\x95\xe7\x72\x67\x13\x25\xaa\x48\x09\x62\x43\x38\xa8\x23\x38\xfb\xfc\x92\xc0\x3f\xdc\xc7\x0b\xdc\x67\xa8\x1a\x13\x0c\x87\x44\xc2\xe3\x2c\x53\x3a\x1a\xe5\x2f\x19\xad\x30\x13\x04\x87\x25\xc4\x40\x47\x5f\x60\xb8\x72\xba\x40\x55\x40\x4a\x5b\x91\xf2\x3d\xde\x1d\x23\x50\x82\xab\x77\xc5\x41\x7b\x76\x2c\x10\x9e\x10\x90\xd3\x79\x72\xa0\x27\x18\x24\x77\xf4\x9e\x99\xcf\x1b\x4e\x4d\x92\x16\x7a\x7a\xb5\x09\xae\xf9\xe3\x92\x96\xbb\x82\x6e\xb9\x59\xc3\xe0\xf0\x1d\x95\x5b\x02\xea\x3a\xf2\x76\xc1\x5b\x8f\x1c\xef\x06\x67\x8a\x9b\x51\x43\xa7\x5d\x6c\x59\x29\x5b\xc6\xe4\x4b\x70\x93\x0c\xf0\xb6\xd9\xb8\x91\x01\xe7\x19\xaa\xe4\xb7\x17\xb7\x98\x31\x92\xe1\x38\x24\xd6\x5b\x4c\x0e\x0a\xf5\x49\x4c\x9d\x2e\xe3\x07\xa5\x7b\x58\xae\xb7\x80\x1e\x21\xd5\xef\x23\xd7\x6f\x51\x0e\x0b\xa0\xef\xe1\xec\x3c\x00\xc4\x57\xb2\xa5\x47\x2a\xc5\xa5\x23\x38\xe1\x2c\xf5\xd7\x10\xf5\xbd\x9d\xd0\x39\x31\x47\xe9\x96\x09\x1a\x26\x44\xd1\xfa\x21\x10\xac\xc7\x68\xff\xdb\x32\xa0\x27\x29\x22\xa5\x7f\x0a\x54\xfd\xba\xda\xc7\x57\x3e\x41\xc5\xe3\x1b\xd6\xed\xca\xd7\xfc\xb1\x34\xca\x63\x97\x7b\xf1\x90\x0a\xea\x29\x0a\x52\xe6\xd2\x8f\x33\x30\x7d\x5e\x0a\xb4\x07\x20\xb4\xae\x05\xd1\x5f\xff\xfa\x12\xea\x5a\x52\xe5\x5e\x6e\x9e\xb7\x37\x2c\x16\x52\x31\x1b\x62\xde\x87\x8c\x86\x30\xcd\x54\x75\xad\x9c\xa6\x56\xbd\x15\xa8\x6a\x7d\xe9\x3f\x28\xcd\x07\x0e\x24\xb3\xfa\x87\x96\xbf\xea\xce\x6c\xce\xa6\x7f\x34\xbb\x6a\xdc\xb3\xd5\xc2\x18\xd1\x12\xd6\xb8\xc4\x8c\x2c\x81\xd8\xae\xbf\x02\x3a\x01\x59\xa3\x7f\xb8\x16\xb0\x13\xd6\x09\xf9\xc4\x3a\x06\x64\x22\x0a\xcf\x48\xa9\xa3\x0d\xc9\x33\xf4\xb1\x89\x3b\x18\x39\xbf\x44\x05\xf6\xb0\x78\x2d\x7f\x9c\x9d\x4b\x12\xfc\xe3\xcb\x48\x6a\x87\x2e\x52\x1d\x29\xf6\x14\xf1\x4b\xc2\x97\x8c\x14\xa4\x94\x8b\xb7\xd2\xad\x21\x78\xfb\xc9\x98\xc1\x1d\x2a\x9c\x34\x54\x68\xd7\xd2\xd6\xa3\x31\xc4\x37\x88\xbf\x64\x78\x45\x3e\x82\x54\xbe\x5b\x7c\xf5\xb1\x62\x98\x73\xc9\xb5\x39\x4d\xe6\xca\xac\x6e\xad\xd4\x6e\x97\xba\xbe\x68\x8f\xb4\xec\xd6\xef\xd0\xda\x8c\xb1\x13\x3d\x33\xe2\xa1\x21\x60\x5d\xcf\xd2\x54\x7b\xfa\xf2\xf7\x25\xae\x94\x25\x55\x98\xf6\x33\xd5\xe4\xf6\x0e\x58\xda\xb6\xf9\x08\x53\x6c\x88\x4d\x8b\xee\x7a\xfd\x63\xee\x18\xbb\x75\x00\x31\x67\x3f\x04\x11\x33\xed\x06\x31\xa7\x77\x08\x31\xd3\xfc\x40\x88\x35\xf3\x1d\x8f\xd6\x8f\x25\xf9\xb0\xc5\xa3\x98\x6d\xdb\x2e\x67\x20\xd8\x16\x87\x30\x72\xe6\x39\x0e\xa9\x5f\xfb\xb8\xc0\x81\xf3\x02\x0f\x79\x60\x8e\x64\xce\x55\xb9\x2d\x86\xb8\x22\xdb\xf4\x5e\xb3\xbd\x02\x5c\x91\x4d\x17\x88\xe3\xc8\x48\xc7\x69\x6c\x99\x1d\x36\xc7\x1e\x90\x33\xa7\x5e\x70\x5d\xb3\xe6\xd4\xb7\x0a\x27\x32\xca\x1b\x36\xc6\x2e\xab\xe5\x2e\xb6\x5c\xd0\x42\xeb\x7d\x81\xa5\xcb\x94\xbc\x16\x8c\x94\xeb\x28\xf6\x80\x73\x74\xe5\xa9\xa7\x2c\x7b\xd3\x9f\x4a\x6e\x3b\x98\x1c\xbf\x88\x47\x11\xf3\xcb\x72\xa4\xe1\xd8\x7f\xdc\xce\x0d\xdf\x4f\xdb\x63\x94\x5c\x73\xc5\xef\x6b\xa8\xeb\x15\xca\x39\x6e\xf7\xa5\x3c\xb5\xd3\x76\xa1\x34\x69\xbc\x7d\xd8\x6a\xd1\xd3\x46\x8d\x2e\x25\x6a\x43\xe9\x91\x0b\x5a\xde\x62\xa6\x31\xf5\x98\x88\x21\x79\x7d\x87\xd6\x6b\xcc\x34\x31\x60\x3e\x6f\xac\x8b\xde\xf6\xd6\x5d\xce\x7a\xfb\xd4\x9f\xa1\x1f\xcc\x56\x8a\xfa\x16\xb1\x52\x4a\xc8\x00\xf7\x17\xae\x9d\xe8\x82\x1a\x8d\x8f\xfb\x29\x6e\xad\xcc\x8e\x69\x68\x69\x47\x19\x4f\xae\x4b\x45\x16\x69\xbe\x1c\x21\x06\xe7\xb2\x6b\x13\xca\x99\x2f\x0e\xe0\x10\x0f\x65\x52\xfa\x9b\xcd\x98\x56\xef\x49\xf5\x12\x31\x8e\x63\x9b\x56\xab\x10\xe3\xa4\x5c\x03\xe1\xc0\xdf\x93\xaa\xc2\x99\xf2\x1a\xb9\xf2\xce\xb4\xbd\xaf\x43\x99\x26\x29\x75\x4f\x16\xdd\x4a\x1c\x1a\xd2\xaf\xb4\xa1\x9d\x28\x90\xa2\x43\xc3\x17\xbf\x25\xc6\x28\x44\x5c\xc3\x7f\x0c\x34\x89\xeb\x49\xa4\x86\x24\xd1\xc9\x7e\x6f\x66\x52\x86\x53\x98\x7b\x54\x92\xff\xe3\x0b\x9d\x0f\xec\x7b\x67\x26\x95\x98\x91\x25\x12\x38\x03\x41\xa1\xc4\x5c\xfe\xa5\x18\x56\x69\x87\xda\x70\xec\x30\x68\x07\xe8\xda\xf3\xaa\xfa\x7d\xda\xe8\x8e\x61\x69\x0c\x01\xe7\x89\xac\xe0\x16\x9b\x20\x95\x6c\x4d\xa2\x13\xc3\x94\x16\xbb\xd8\x0b\x55\x19\xd6\xdd\xe2\x66\x01\x69\xf0\xb8\x7c\x8b\x9d\xb8\x58\x47\x7a\xf5\x1d\x9b\x87\x20\x45\x57\xc4\xb4\x79\xb6\x4a\xc7\x19\x77\xc1\x54\x9b\xef\x87\xb4\x12\xb4\x40\x55\xb7\xbf\x2b\x44\x5b\x2b\x65\x38\xd8\x6e\xf5\x8b\x13\x56\xb7\x9f\xdc\x00\xba\xe7\xd1\xab\x29\xe4\x41\xb7\x91\xa1\x96\x50\xba\x5f\x81\x2a\xa9\x67\x7d\x6f\x8f\x9f\xc1\x92\x56\x3b\x29\x2f\x50\x9e\x03\xce\x71\x81\x4b\x15\x79\x1f\x14\xbc\x43\xca\xf7\x95\xa4\x76\x81\xde\x6b\x66\x36\x27\x6b\x61\x7c\xa7\x61\xa5\xad\x8e\x4c\x2f\xd0\xaf\xad\xfa\xa1\x41\x3f\xb5\x79\x80\xc1\x6e\x75\x7d\xd1\x04\xf2\x7c\xbd\x6d\xc3\x1c\x4e\x36\x57\x37\x0d\xc2\xd8\xdd\x49\x83\x70\x75\xdc\xed\x86\xd1\xc3\xb9\x64\xdd\xf9\x50\x72\x57\x1b\x4f\xf5\x68\x98\x3e\x34\xc7\x0d\x29\x33\xdc\x9b\xc0\x0b\xdd\x59\xaa\x98\xd4\xd0\x2f\x48\x13\x07\xc2\xc0\x29\x19\x00\x31\x98\x89\xb0\x30\x07\x32\xc6\x93\x40\xea\x25\x1b\x7c\x86\x05\xb2\x0a\xbe\xce\xb9\x67\xb6\x78\x12\x8c\xb1\x0b\xdb\xa1\xbc\xc2\xb4\xb4\x42\x77\x9f\x74\xad\xbd\x00\x0b\xdc\x1c\xe9\x04\x21\xf0\x76\xbf\x37\x67\x58\xa5\x74\x26\x0d\x6a\x63\x34\xfe\x01\x75\x77\x66\x5d\x5f\xbf\xda\xef\x6d\x7c\x6b\x58\xfa\x0e\x89\x6c\xcf\x8e\xbd\xe6\x2f\x6d\x49\x92\x83\x5c\x4b\x96\x56\x3e\x36\xfd\x9a\xfa\x8a\x5e\x58\xea\x90\x85\xd6\x3a\x49\xf6\xf7\x13\xc4\xf1\x3f\xbe\x8c\x07\x1c\x3b\x3d\xfe\xc5\x2a\xda\xef\xd5\x9e\x32\xc6\x4a\xb3\x81\x94\xb1\x22\x3f\x78\xd6\x94\xb5\x2d\xfb\x42\xb0\x71\x49\x16\xd6\x3a\x3b\xe0\xab\x86\x71\x74\xc4\xa6\xb2\x55\x94\x88\xf1\x94\x8f\xb1\x4e\x8e\xa8\x55\xf1\xc4\x90\x27\x80\x46\x15\xc6\x71\x82\xe7\xa0\xd8\x39\x3e\xc2\x68\x85\x6a\x5d\xcf\x6e\x11\x9b\xa8\x1d\x3d\xad\x38\x33\xfa\xae\x15\x39\xcf\x31\xce\xb8\xaa\xdd\x30\xc1\x06\xa7\x8e\xa3\xf5\xf6\xfe\xe5\xe7\x99\x27\x08\x3a\x57\x4f\x1e\xec\xae\x15\xe6\x90\xba\x54\x7c\x67\x78\xb9\x65\x5c\x9e\x1c\xa7\x06\x8f\xae\x74\x9d\x95\xaa\x8f\xf0\x8d\x55\xbf\x46\x44\x4f\xd9\x38\x2d\x96\xdd\xc6\x07\x31\x0b\xba\x9e\xc8\x05\xcd\x73\xbc\x94\x8b\x38\x3e\x89\xd5\x4c\x9d\xb6\x61\xb9\x35\x51\x95\xb5\x48\xbb\x10\x4e\xa2\x73\xcb\x22\x7e\x87\xd6\xc9\xeb\x2a\x27\xe2\xc9\x4e\xc3\x15\x4d\x9a\x61\x48\x71\x04\xb0\x8c\xdd\x6c\xcc\x51\xc6\xc6\xd1\xa6\x86\x47\x4b\x93\x27\xed\xa3\x33\x6c\xdb\xc1\x37\x6e\x3a\xf5\x18\x0b\x65\xca\x99\x6a\x12\x37\x93\xba\x4f\x3b\x32\x53\xb4\x11\x38\xea\x28\xe4\xb2\x77\xfa\x6a\x81\xa9\x1d\x70\x69\x86\x93\xd2\xb8\xe0\x51\x45\x39\x27\xd2\x7e\xb9\x23\x62\xe3\xfa\x7a\xb1\x2b\x4d\x1f\xd6\x12\xf3\xf7\xc0\x04\x43\xec\xf7\xc4\x09\xc7\x56\x52\x54\x2f\x69\x79\xaa\x4b\x40\x1f\x3d\x52\x3f\x24\xfd\x85\x14\xc2\x0d\x13\xba\x82\x2a\x6c\x60\x4e\x28\x6a\xf9\xd3\xf2\x04\x2f\x6d\xea\x4b\xa8\xe9\x56\xe7\xef\x6e\xbf\x69\x44\xdd\x98\x6a\x9a\xc2\x05\xcd\xb0\xce\xa4\xaa\x88\xce\xcd\x0e\xd6\xf4\x94\x6b\x9b\xed\x2b\x5b\xb3\x7e\x75\x79\xfd\x26\x99\xcd\x6c\x56\xe0\x82\x56\x3b\x46\xd6\x1b\x01\xa7\x75\xad\x95\xe2\x92\x16\xd2\x25\xef\xb4\x39\xd1\xdb\x59\x85\x96\xef\x91\x71\x84\x5f\x9a\xbf\x65\x43\x9a\xc2\x9b\x0d\xe1\xb0\x22\x52\xbe\x20\xee\x03\x23\x36\x18\x0c\x34\x20\x28\xcd\x13\xd9\xff\x2a\x23\x82\x94\x6b\x5d\x62\xa2\xc6\x15\x6a\xc5\x8a\xd1\x5b\x0c\xab\xad\x50\x53\x6d\x70\x09\x3b\xba\x05\x86\x4f\xd9\xb6\xf4\x66\xb2\x4b\x28\xb0\x51\x99\xcd\x66\xa4\xa8\x28\x13\x10\xcd\x00\xe6\xab\x42\xcc\xe5\x7f\x09\x55\xff\x29\xb1\x48\x37\x42\x54\xf3\x99\xfc\xb5\x26\x62\xb3\xbd\x49\x96\xb4\x48\xd7\xf4\x94\x56\xb8\x44\x15\x49\xf5\xae\x9f\x0f\x77\x60\xdb\x52\x90\x02\x1f\xee\x91\x72\x69\xb9\x10\xb1\x9b\xd0\xb5\x20\x59\x96\xe3\x3b\xc4\xc6\xe6\xe5\x82\x59\x84\x06\x3a\xdc\xa1\xf5\x48\xb3\xb5\xf8\xe7\xba\x92\x13\x34\xa5\x38\x24\x97\x78\x85\xb6\xb9\xb8\x36\xbf\x6d\x04\xa6\x69\x77\x1a\x62\xc5\xe6\xe7\xf8\x2e\x98\x8a\x37\x75\x38\x4b\x86\x91\xc0\x1c\x10\x94\xf8\x0e\xc6\x7a\xea\xc2\x4b\xbb\x1b\xf5\x47\x65\x50\xd0\x02\x1b\xa8\xb8\xca\x61\xa4\xa9\xd6\x58\x92\xf7\x99\x6e\xd0\x01\x54\x69\x01\x12\x41\xd4\xec\x59\x62\xad\x22\x33\xa4\xa4\xdd\xce\xda\xb6\xce\xa4\x30\xe6\x15\x5e\x26\xae\xed\xbd\xda\x96\xcb\x03\xa8\x45\xf1\x28\x3a\xfb\x03\x98\x98\x00\x36\x53\xbb\x33\x4d\x1d\xd0\xb5\x16\xc6\x02\x33\xae\x11\xf5\xe1\xd6\x0c\xd1\x76\x75\xe2\x57\x3b\x81\x35\x24\x9f\x22\x6e\x16\x72\x32\x4b\x6d\xbb\x51\x27\xdf\x92\x1c\xab\x09\x3a\x86\xe6\xf5\x65\x5d\xdb\xe1\xe7\x5e\x85\x5c\xd7\xeb\x6c\x5d\xd9\x21\x17\x34\xe2\xca\x03\xbc\xa0\xa5\x40\xa4\xe4\x90\xfc\x2f\x66\x14\xe6\xd1\x3f\xe7\x4e\x0a\x54\x7d\xb3\xa6\x8a\xda\xd9\x56\x4d\x5a\x9a\x30\x5b\xec\xc2\xe1\xc7\xb2\x40\x8c\x6f\x50\xfe\x06\x7f\x14\xd2\xb3\xc4\xc9\x3a\x81\x4b\x24\xf0\x42\xfd\xbf\x3c\x44\x0b\xb8\xdc\x32\xad\x78\x1a\x0d\xeb\xe3\xd0\x09\x91\x8f\x23\x32\x86\x83\x82\xbb\x09\xc1\x47\xfd\x7c\x9a\xa5\xa4\x32\x9d\x47\x10\x14\xe8\x3d\xe6\xa0\x97\x3a\x1a\x6a\x6b\x21\x74\x40\x8f\xb5\xbc\x3e\x06\x3c\x86\xd7\xdb\x1c\x31\x58\x53\x68\xee\x4e\xf5\x81\x3d\x00\x5f\xa3\xbe\x4c\xe2\x32\x3d\x81\x4b\xaa\xb6\x9d\xb3\xcd\x57\x8c\x16\xd0\x18\xa1\x99\x3d\x18\xa4\xb4\xe9\x07\xe3\xd6\x9d\xa4\x9d\x4d\x1c\xda\x8b\x56\x4d\x3a\x8c\x1c\xce\x94\x76\xf7\x5c\x03\x94\xde\x32\x5c\x48\x35\xb2\xde\xe9\xd3\xd7\xd9\x6f\x21\xd4\x7b\xe8\xfb\x3a\xfc\xf4\xc8\x15\xff\xcd\x69\x99\x34\xcb\x4e\x5b\x72\x80\x08\x91\xe3\xf9\x1e\xdc\x1d\x72\x3e\x45\xf3\x6b\x87\xd3\xce\x06\x99\xbe\x3f\xce\xac\xc7\xa1\x23\x35\x07\x76\x4e\xc7\xda\x73\x2d\xc9\xce\x16\xd5\x77\xf7\xf2\x1c\xa8\xd8\x60\x06\x4b\xc4\x31\x87\x48\x09\x00\xae\xea\xbc\x62\x78\xcb\x37\x74\x9b\x67\x6a\xb3\xd1\xe5\x72\xcb\xde\x8d\x2e\xe9\x17\x19\x1f\x0d\x8b\x84\xc0\xd6\x98\x0d\x1e\x8a\xee\x1a\xc1\xc0\x68\xa8\xdc\x0c\x20\x56\xe6\x59\x57\xd8\x07\xa5\xbc\x39\x67\x4b\xc4\xd8\x0e\x68\xe9\xef\xdb\xc1\x0d\xe7\x1d\x2e\xa7\x96\xe5\x9e\xb2\xdd\x8a\xf6\x90\x4e\x49\xfc\x13\xf5\xf6\xdd\xcd\x4e\xf4\xf3\xb5\x8e\x5c\x8a\x5b\xf0\x42\x02\xa6\xa7\xde\x28\x83\xe8\x68\xa9\x10\x07\x4e\xad\x33\x73\x1b\x2c\xed\x9c\x4e\x03\xfe\xcf\xfb\x7d\x03\x3e\x9f\x43\x24\x7b\x35\x48\xc4\x75\xfd\x73\xbc\x80\x47\x3e\x41\xa0\xa1\xc8\x58\xdd\x7a\x9a\x42\x85\x4a\xb2\xe4\x12\x04\x69\xa7\x90\x15\x31\x3e\x15\x91\xc2\x52\x59\x72\xde\x88\x82\xaf\x55\x3a\xbc\x10\xc9\x6b\x0d\x53\x34\x37\xfd\x7c\x53\x42\x25\xbe\x1a\x63\x03\x7a\xd0\x9d\xc1\xdf\x6e\xe7\x8b\x5e\x99\xbc\x02\x27\x2a\xf8\xda\xfd\xdc\xe1\x82\x5b\x7f\xd2\xcf\xe7\xd9\x56\x2f\xee\xd9\xf6\x30\x4e\xe7\x88\x75\xb5\x0f\x99\x40\xfd\x53\xd1\x7a\x75\x5e\x7d\xae\xc4\xec\x97\x2f\x11\x7b\xe4\x96\x88\x05\xd9\xbe\x68\xa9\xe1\x78\x55\x20\xbd\x39\x53\x9b\x35\x6c\x56\xdb\x33\x27\x85\xa1\x34\x84\x6f\xe8\xb6\xcc\x6c\xf8\x53\x57\xea\x2b\xaf\x6c\xb3\x2d\x50\xe9\x95\xc8\xd2\x0a\x6b\xd3\x48\xae\x21\x76\x15\x59\xa2\x3c\x57\x3e\x19\xc7\x80\x18\x06\x7a\x23\xa7\xc6\x99\x56\xd0\x08\xa4\x9b\xa4\x5c\x7f\xcc\xc5\x2c\x4d\xe5\x30\xe3\x72\x9d\x39\x96\xaa\xd4\x70\x66\x89\x99\x52\x07\x63\xe0\x73\xc1\xb6\x4b\x01\x7b\x93\x1e\x7e\xfa\xe6\xcd\x4b\x30\x2b\x80\x2e\x53\x98\x81\xfa\x6a\x3f\x9e\xb8\x40\xc0\xcf\xf2\x74\x9d\xcd\x4f\xe7\x3f\xcf\xc2\xd6\x70\x7a\x62\x36\xc3\x25\x96\x4c\xac\x44\xe3\x64\xdf\xe4\x74\xf9\xbe\xf1\x6b\x7b\xcd\x6e\x4d\x5f\x27\x1e\x62\x7f\xe9\x62\xc5\x6e\xdf\x67\xe8\x23\x29\x74\xc1\x1c\x80\xf9\x61\x77\x59\x72\xf5\x71\x99\x6f\x39\xb9\xc5\x6d\xaf\xaf\x3d\xce\x3b\xc3\x7b\x13\x93\xd2\x99\x58\xff\x08\x4c\xdc\xf4\xfa\xa6\x33\x71\xd3\xd0\x9b\x78\x9b\x0b\x52\xe5\xf8\xc5\xca\xcc\x6d\x7e\xc3\x8b\x95\x29\x36\x75\x3b\x04\xf0\xfd\x01\x97\x6b\x15\xfc\xd1\x18\x83\xfe\xdd\x14\xaa\x36\xcd\x01\x8c\xbc\xa1\xa4\xf4\x87\x3a\xcd\xdd\xa1\x2f\x95\xac\x2e\xf5\x40\xf3\xe3\xcc\x04\x1f\x6c\x4b\x00\x52\xa7\xe2\x5a\x02\x1a\x2e\xa8\x0d\x80\xe9\x8e\x23\x25\x84\x2b\x8c\xbb\xe3\x3a\xa5\xaf\x00\xfa\x43\x78\xdb\x38\xf1\xb1\x19\xc0\xb5\x41\xc6\xf9\xda\x1d\x10\xce\x3b\xb4\x5f\xc1\x4b\x55\xf4\x3b\x77\xe7\xeb\x4a\x4b\xf3\xc3\x2f\xbf\xea\x59\x3e\xad\xac\x3e\x49\x67\x9e\x57\x69\x4c\x21\x6d\x39\x75\x2e\x45\x7c\xe6\xba\x5c\xc7\xae\x75\xcd\xb9\xfe\xa5\x81\x23\xaf\x0c\x74\x3a\x59\x40\x46\x16\xf7\x55\x5f\x6d\x05\xfc\x13\x52\x66\x56\xa4\xdd\x50\xb1\x81\x1b\x52\x66\x5c\x01\x62\xe3\x33\x1c\x90\xf2\x7c\x31\x17\x0b\x20\x02\x10\xe7\xdb\x02\x73\x10\x1b\x24\x60\xa9\xeb\xba\x40\x6c\x48\xb9\xe6\xa0\x2c\x6e\x25\xd7\x10\x98\x04\x8c\x84\x37\xd2\x0e\x67\xf2\x0a\xaf\x09\x17\x6c\x17\xeb\x68\xae\x73\xc1\x22\x4d\xdd\x2a\x3d\x1b\x4a\x11\x70\x47\xf2\x1c\xb6\x1c\x2b\x6b\x51\xc5\xe2\x0a\x2c\x36\x34\x03\xa9\x31\x78\x62\x74\xc1\x1b\x0a\xb8\xe4\x5b\xd6\x0d\xc6\x2c\x74\x70\x4e\x4b\xfa\x62\xcb\x05\x6c\xd0\x2d\x86\x1b\x8c\x4b\x37\x4e\xa3\x5d\x9e\x83\xa1\x96\x1b\xbc\xa2\x0c\x6f\x50\x99\x25\x3a\x38\x13\x05\x2e\x85\xc0\xc9\xc8\x24\xb1\x4b\xef\x88\xf9\x2a\x65\x01\xea\xb2\x0e\x9c\xb4\xd1\xb7\xe4\x19\x12\xcb\x0d\xce\x5e\xc9\x06\x4b\xb4\xbd\x09\xda\x30\xcc\xe1\xed\x3b\xf5\x6d\x36\x70\x41\xc5\x55\x5f\xe7\x60\xbb\x99\x33\xf7\x3f\x5b\xcc\xda\xab\x6a\x1f\xb8\x4a\x95\xea\x00\xa0\x0e\x0e\xf3\x88\x25\x3f\xbe\xfa\x21\x51\x1d\xa3\xd8\xc9\xba\x79\xf3\xc8\x73\xdd\x4c\xd3\xda\xa8\x4c\x17\x41\x6a\x09\x8e\x98\x90\xdd\xa2\xff\xfe\x3b\x7c\xfd\x35\xfc\xfd\x8b\xae\xb5\xf9\x97\xbf\xb4\x75\x8e\x8a\x26\x57\x8c\x3d\xa7\xa2\x19\xdc\xbb\x48\xe9\xa6\x04\x9e\xe3\xbb\xe8\xcb\x2f\xbe\x58\xcc\x7b\xa6\x62\xdd\x18\xeb\x3e\x50\x0a\x96\xf1\x9b\x9a\x13\x17\x98\xfd\xa5\xf6\x29\xa1\x28\xe7\x86\xc4\x56\x59\x98\xb2\xb2\x73\x1c\xb4\xbe\x06\x0c\x8a\x59\x27\x74\xe6\xba\x08\x4d\x99\x74\xcb\x54\xc9\xd3\xe0\x56\x5c\xc0\x87\xcd\xfb\x81\x96\x7f\x49\x50\x3f\xf0\xe4\x3b\x2c\x5e\x7c\xdf\xad\x4a\x1c\xbf\x89\x26\x05\x47\x40\xe0\x46\xc7\x03\x71\xbf\x3b\x6b\xbe\x87\x26\xc1\xb7\xe4\x60\x43\xeb\x8d\x93\x43\x83\x63\x42\xa8\x0f\x48\x98\xe3\xc1\x79\x48\xc2\x3c\xc5\x28\xc3\xcc\x92\xe6\x13\x31\x48\xf4\x2c\x6f\xd5\x91\xbd\x40\x25\x2d\xa5\x25\xaf\x3f\x7e\x8f\x77\x1e\x9d\xde\x2d\x94\xf5\xf1\xb0\x58\x34\xb2\xc7\xb9\x69\x60\x5a\xfc\xc0\x72\xef\x82\x51\xf8\xda\x91\x06\x7d\xd1\x8a\x0b\xb9\x80\x9c\x6a\x80\xe5\x16\x6e\x7b\xfc\x5c\xdf\xeb\x51\x57\xa0\x3d\x23\x9c\x93\x72\x2d\xa7\x6b\x0f\xfd\x30\xc6\xae\xe4\x81\x39\xc3\x28\x23\xe5\x5a\x67\xa5\xfe\xf6\x01\x56\x88\xe4\xd2\x11\x90\x22\xa9\x9b\xf8\x8c\x7c\xbc\x62\x7b\x39\xc0\xb9\xb9\x1f\x82\xd8\x97\x96\xe7\x41\xc0\x0d\x8b\x54\x32\xe3\x94\x56\xba\xe2\x56\x37\xc3\xcd\x56\x00\xad\xf4\x13\x05\x1a\xce\xc6\x37\x9b\x75\xfc\xf2\xee\x62\x47\x6e\xbc\x63\x19\x1a\xda\x65\x7d\x07\x2b\x4d\xfb\x0e\x96\x25\xeb\x3f\x4b\xfd\x6e\x97\x06\x7e\x78\x87\x6a\xac\x8e\xbf\x3f\xff\xc8\xea\x07\xb5\x3b\x2e\x91\x40\x67\x41\x7c\x16\xa0\x31\x0a\xb7\xea\xb6\xda\x2d\xe2\x37\x56\xe7\x2a\x1b\x90\x29\xab\x6c\x5c\xfa\xad\xb2\x07\x15\x7a\x9f\x02\xc7\xfd\xef\x30\x37\x1a\x36\x3d\x51\x7f\x26\xad\x74\x68\xef\x14\x74\xfa\x28\x2d\xab\x75\xac\xd3\x67\x28\xf6\xf7\xa7\x02\xfe\x53\x01\xff\xe1\x14\xb0\x89\xd2\xb7\x4a\xf8\x8f\x2c\x67\x02\x76\x7c\x27\x9b\xd1\x3c\x0d\xd2\x84\x28\x4e\x6d\x59\xa1\x95\xfe\x4f\x11\xd7\xcf\x36\xc4\x9d\xab\x1b\x1d\x57\xdf\xad\xed\x9c\xaa\x62\x58\xf2\xc4\x7b\x2b\xc1\xa9\x6b\xca\xf0\x0a\x33\xd3\x21\xb9\xc8\x29\xc7\x51\x1c\xb8\x75\xd0\x0b\x4a\x38\x9f\xae\x3e\x56\x94\x89\xb6\x70\xeb\x86\x66\x3b\xf7\x46\xa2\xa0\xa6\x36\x47\x01\x94\xa8\x07\xb9\x78\x5b\xae\xd3\x66\x33\xf6\x7b\xc8\x18\xad\x6c\x53\x5b\x33\xdc\x7b\xa5\x43\x95\x79\x36\xd4\x8e\x34\xf8\x96\x8d\x17\xb4\xe4\xdb\x02\x1b\x5f\x2d\x74\x8b\xce\x25\x6f\xbf\xec\xac\xb5\x82\x08\x4d\xae\x5e\x7c\xeb\x0c\x52\xdf\xef\xf1\xa6\xd2\x7c\x6e\x89\xeb\xdf\x81\x71\xf2\x71\x23\x2f\x05\x75\x79\x77\x8b\x58\xf3\x8a\x89\x53\x60\x0d\x5e\xc2\xc8\xa7\x89\xfd\xa3\x21\xd9\x23\x39\xc1\x90\x3f\xfc\x49\x34\x9a\xf4\x06\xd5\x41\x9b\xf5\x10\x19\x1b\x3a\xba\x66\x57\x80\x9c\xe3\x16\xb6\x0a\x09\x5c\xc9\x9f\x0f\x01\x54\xdf\xd2\x1e\x22\x5f\x9f\xfb\x03\xe9\xaa\x1e\x82\x7e\x3d\x61\xe7\x45\xd7\x64\xa4\x14\xd1\x2f\x98\x76\x40\x72\xe7\xff\x7c\xbc\x0b\x40\x38\xfc\xc3\x7d\xa5\xaa\xad\xaa\xf6\x23\x35\x17\xb4\xa8\x28\x27\xc2\xa9\xfe\xd6\x8c\x65\x98\x27\x49\x62\xd7\x34\x83\x4a\x92\xcf\xcc\xfd\x99\xff\x5c\xe6\x88\x73\x25\x9b\xce\xce\x21\xea\x08\xd0\xd8\xa4\x07\x83\x21\x19\x7b\x3d\xc4\xf5\x38\x67\x69\x0a\x03\xaa\xc9\x44\x58\x7d\xff\x48\x1d\x5e\xd5\xdc\x84\x34\x37\x18\x68\x99\xef\x80\x6f\x2b\x23\x59\xdd\xcb\x26\xb4\x54\x33\x70\x95\x2d\x6b\xd3\x15\x52\x4c\x37\x79\x8f\x03\x41\x4a\x07\xe5\x36\x3e\x39\xa8\x4f\x55\x31\xa4\x0d\xc7\x29\xfb\x79\x01\x1b\x65\x67\xc0\x89\xff\xdd\xb8\x5c\x4e\xb4\x12\xdc\x97\x6d\x5b\x60\xbb\x09\x1c\x00\xae\x5e\xfd\xd0\xf6\x00\xc9\x71\xf2\x1a\xe3\xf7\xd1\x17\x0b\x29\x5e\xe4\x9f\x57\x65\xa6\xcf\x55\xa8\xf1\xb5\x40\x4c\xc4\x43\xd5\xb7\x5e\xd2\xa7\x15\x8f\x72\x41\xf8\x5a\xbd\x33\xd2\x36\x7a\x62\xcc\xdd\x5d\x57\x1f\x97\x18\x67\xdc\xe4\xb3\x8e\x7b\x0c\xc4\xcb\x29\x2d\x40\xbd\x62\xb0\x50\xeb\xc7\xe3\x75\xc3\x5e\xa6\xab\x03\xf9\x37\xe6\x85\x94\xc9\x90\xeb\x14\xdf\xb1\x90\x3b\x6c\x9a\x0a\xb9\x77\xc2\xfc\x32\x21\x7b\x0b\xac\xb1\x86\x7c\x64\xf5\xa3\x5e\xa3\x95\x1f\x53\xce\x97\x9f\xc1\x08\x1c\x34\x9d\x5a\xee\xa4\xba\x0e\x05\xf6\x8f\x3a\x33\x0c\xdd\x49\x47\x1e\xde\xbe\xd3\x45\x2a\x0b\xd8\x20\xfe\x3d\xde\xc1\x0d\xa5\x79\x73\x1b\x0d\x06\x72\x23\xfb\xbe\x01\x66\xf3\x4e\x8d\x4f\x15\xf7\xd5\x0a\x59\xc1\x5f\xcd\x32\x43\x9b\xe1\x13\x4c\x16\x83\x8a\xcb\xf0\x1e\xcb\x55\x4e\x02\xdd\x99\xf2\x41\x0b\x8c\x12\xd9\x66\xb4\x23\xb6\x15\x54\xe8\x4e\x9a\xa5\xba\xf1\xad\xdb\xf1\xf4\xbf\xde\x99\x95\x74\x72\xbe\x0d\xcb\x68\xc6\x74\x35\x69\xd8\xfb\x4e\x53\x78\x9c\xe7\xf4\xee\xaa\xa8\xc4\x4e\xc5\xdd\xf5\xf8\xce\xc7\x40\x46\xd2\x77\x5b\xd3\x14\x5e\x36\xfb\x87\x70\x55\x0d\x4e\x32\x5d\x46\xbe\xa4\xa5\x4e\x2f\xa9\xd7\x09\xe5\x8e\x12\x1b\xac\xcd\x2d\xff\x92\x12\x04\x32\x8f\x41\x3e\xea\xc6\x0e\x8c\x71\xeb\x2a\x0c\xbd\xd9\x6a\xae\x39\x1e\xc5\xd3\xb0\x93\xd3\x79\x73\x00\xa0\xe7\xf4\x45\xd0\xc5\x00\x62\x75\x75\x5f\x03\x6f\x41\x8a\xc7\xf0\x50\xdc\x3f\x87\xf9\x1c\xf6\x92\xc5\xfa\x29\x7c\x93\xf8\xab\x10\xe7\x4e\x8d\x9d\xa3\xf8\x06\x0b\x6c\xd2\xd4\xe6\x8d\xed\x24\x6d\xaa\xaf\x62\xf8\x96\xd0\x2d\xcf\x77\x5e\xd6\xef\x66\x67\x72\x7e\x81\x53\x1d\x75\xee\x98\x39\xf2\xcc\xa7\x4a\x9f\xc3\xde\xdb\x2b\xfe\xf3\x20\xbd\x97\x59\x24\x0f\x7e\xc1\x47\x3e\xba\x8d\xed\xab\x04\x60\x56\x36\x4e\x6a\xe8\xf1\x88\xf3\x70\x58\xbb\x41\x5a\xa1\x16\x2c\x8b\xeb\xcb\xeb\x34\xf5\x8a\x02\x1e\xfa\x1d\x15\xf8\x3d\xd0\xd1\x7b\xad\xb2\x5b\x67\xe0\x1b\x90\xad\x9f\x6f\x45\x85\xe5\x80\x9f\xe3\x77\x5e\x60\x71\x80\x72\x8a\x15\x25\x53\x86\xde\xee\x3a\xc8\x60\x86\xee\x06\x37\xba\x39\x84\xfe\x25\xcb\x4f\x7e\xaa\x32\x1a\xbc\x99\x3d\x22\x8f\x3a\xa5\x7a\xd6\xd4\x18\xa8\x02\x3f\xde\x66\xd0\xd7\xe6\xa6\x5b\x0e\xda\x6e\x7f\xac\x0b\xc6\xa5\x59\x5e\xc9\xcd\x9b\x01\x5a\x2e\x29\x53\xb9\x1b\x41\xa1\x7f\x9f\x77\x3e\x50\x25\x33\x87\xa8\xa9\x47\x17\x14\xe6\x4b\x7e\x3b\xd7\x77\x8f\x94\xa8\x8c\x7f\x93\xa6\x4a\xc7\xab\xec\x19\x23\x0f\x69\x88\x8c\x4b\x61\xfc\x21\x40\xd5\xb9\xf2\x54\xe6\x46\x09\xa9\x4b\x6a\xc1\xeb\xd5\xc1\x02\xa7\x69\x17\xc8\xcf\x1a\x8b\xa6\x23\x1a\x4f\x9b\xdb\x36\x1f\x6e\xc3\x21\xba\xc6\x70\x1a\x36\x9b\x86\x86\x86\xcd\x28\x38\x05\x65\x48\x59\x33\xea\x17\xc1\x36\x70\xdf\x7b\x00\xca\xc0\x05\xcd\x83\x77\xbb\xcd\xa6\x52\xe1\xc7\x43\x26\xd2\xf8\x1d\xed\xe0\xed\x6c\xe7\xb5\xeb\x7b\x6f\xcd\x69\x4b\x06\x8c\x2a\x75\x4e\x8e\x06\x3a\x70\xcf\xea\xd7\x30\x85\xc2\x77\x09\xc6\x6f\xba\x37\x3b\x6c\x50\x2b\x1d\xbe\xd2\xea\x7b\x47\xa3\xff\xea\xc6\x67\xd3\x49\xee\x3f\x4d\x11\xd0\x4a\x9d\x47\x19\xcc\x2d\x81\x40\x29\x62\x47\xb3\xc6\xba\x93\x67\x3c\x74\x91\x8d\x8d\x82\x1b\x41\x48\x5d\xcb\x20\x58\xc5\x8e\xba\x8f\x66\x05\xb4\xdc\xa7\xa8\x97\x09\xe4\x1c\xd3\x21\xd3\x1f\x1f\x3b\x40\xdf\x8e\x05\xe0\x86\x1a\x54\x7e\xd7\x79\xee\xd9\x94\x13\xaa\x7f\xe1\xc4\x79\x12\xbc\x7b\xff\x71\xe0\xa1\x97\x36\x37\x12\x7a\x00\xbe\x29\x29\xf5\xff\xbd\xa7\x38\xd0\xa0\xde\x2e\xf7\xa2\xbf\xfe\xbf\xc5\xd4\xd9\xd7\xe3\x9c\x96\x13\xba\x86\x4c\x19\x46\xed\x81\x39\xac\x12\x57\x13\x2d\x05\x08\x3c\xab\xe3\xdd\xde\x38\x70\xaa\xdd\xff\x4d\x79\xd3\xe3\xc0\xe5\x27\x08\xbd\x22\x32\xb2\xe8\x64\xe5\x18\x96\x71\xdd\xb9\x26\x08\x4b\xaf\xff\xfd\xc5\xe6\x00\x15\x86\x1f\x24\xfa\xc5\x31\x1f\x7e\x99\xe8\xc1\x51\x0f\xbd\xea\x70\x9c\xf0\x09\x10\xb0\x27\x8f\x82\xc1\xdc\xf0\x83\xee\xf6\xaf\xff\x0f\x00\x00\xff\xff\xf1\xc0\x2a\x5b\x38\x70\x00\x00") +var _templatesServerParameterGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3d\x6d\x73\xdb\x36\x9a\x9f\x4f\xbf\xe2\xa9\xee\x9a\x21\x7d\x32\x95\xdd\xeb\xec\x07\xb7\xee\x4c\x62\xbb\x8d\xa7\x75\x92\x4b\xd2\xde\xcc\xe5\x32\x5b\x58\x84\x24\xac\x49\x82\x01\x40\xdb\x3a\x8d\xfe\xfb\x0e\xde\x48\x80\x04\x29\x2a\x76\xdb\x74\xb6\xfb\x61\x1b\x91\x20\xf0\xbc\xe1\x79\x07\xbc\xdd\x42\x8a\x97\xa4\xc0\x30\xbd\x26\x45\x5a\x32\x92\x13\x41\x6e\x71\x89\x18\xca\xa7\xb0\xdb\x6d\xb7\xf3\x23\x40\x05\xe0\xbc\x14\x1b\x10\x98\x0b\xfd\x01\x11\x84\x16\x20\xa8\x7e\x24\x70\x5e\x66\x48\x60\x60\xb8\xa4\x90\xe2\x12\x17\x29\x2e\x16\x04\x73\x60\x98\xd3\xac\x52\xa3\x8f\xe1\xfc\x15\xbc\x7c\xf5\x0e\xce\x5e\x3c\x7b\xf9\xfd\x05\xbc\x7b\x71\xf9\x16\x8e\xe6\xbb\xdd\x64\xbb\x05\x5c\xa4\xa0\xff\x55\x03\x44\xd3\xcd\x2d\xca\x48\x8a\x04\x65\x12\x96\x09\xc0\x76\x7b\x0c\x64\x09\xc9\x0b\xc4\xaf\x68\x8a\xb3\xe7\x34\xdd\xbc\x96\xb0\x72\xfd\x7e\x3e\x07\xf3\x09\x06\xf9\x3d\xd0\xeb\x7f\xe0\x85\x50\x58\xa4\x38\xc3\x2b\xf9\xc2\x8c\x30\x08\xe4\x72\x1e\x33\x4e\x43\x03\x72\x09\xcc\x18\x9c\x9c\xaa\x49\x92\x9f\xcd\x94\x11\xa3\x95\xc0\xc9\x77\x94\xe5\x48\xf0\xf8\x6b\x35\xe8\x8b\x53\x28\x48\x06\xdb\x09\x00\x48\x6c\xe1\x14\x50\x29\x09\x10\x31\xcc\x67\x72\x48\x3c\x01\xd8\x4d\x26\x00\x0b\x71\x2f\xe7\xb4\x10\x26\xff\x43\xc4\xfa\x55\x89\x99\x82\xe5\x0d\xfe\x58\x61\x2e\xa2\x05\x2d\x04\xbe\x17\xc9\x73\xb4\xb8\x59\x31\x5a\x15\x69\x14\xc7\x5d\x98\xce\xf4\xb0\x1a\xb4\x85\xb8\x9f\xc1\x03\xe1\x23\x4b\xc8\x70\x21\x9f\xc7\x70\x7a\x0a\x4f\xcd\x47\xdb\x2d\x24\x6f\xf0\x02\x93\x5b\xcc\x5e\xa2\x1c\xc3\x6e\x97\x6c\xb7\x50\x22\xbe\x40\x19\xf9\x7f\x0c\x89\x79\x0a\xa7\x72\x2c\x59\x02\x2a\x52\x88\x0a\x2a\x20\x79\xbb\x58\xe3\x1c\x25\x97\xfc\x39\xe2\xf8\xdd\xa6\xc4\x31\x24\x97\xfc\x65\x95\x65\xe8\x3a\x93\xdf\x3c\xa9\x79\x2f\xd1\x52\x90\x68\x36\xe3\x8c\x63\x3b\x97\xe4\xf7\x5b\x92\x97\x19\x76\x18\xee\x09\xc1\xa5\xc0\x5a\x06\x0c\xc4\x4a\x4c\x28\xab\x01\x90\x13\x64\x64\x81\x7f\xae\x79\xcf\x1b\xe0\xe4\xb7\x72\x84\xfb\x52\x4f\xe5\xca\x13\x62\x0c\x6d\x80\x2e\x5d\xc1\xe2\xf5\x72\x46\x7e\xdd\xe5\x87\xd6\x56\x62\xf6\xdb\x13\xd7\xac\x58\xef\xd7\x29\x97\x80\xa9\xdd\xee\x6c\xb5\xc4\x82\xd7\x83\x98\x62\xc9\x10\xf1\x14\x78\x91\x43\x7e\x3d\xea\x92\x5f\x16\x02\xb3\x25\x5a\xe0\xce\x9b\xb7\x82\x61\x94\xc7\xb1\x5e\x7a\x49\x99\xa2\xcc\x65\x91\xe2\xfb\x9f\x11\x93\xf8\x9f\x9c\x02\x43\xc5\xca\x6c\xec\x6d\x8d\x8d\x47\x6b\x3b\x9d\x43\x04\x35\x90\x68\xb6\xbd\x6f\x4d\xfa\x41\xca\x79\xb3\x3d\x7a\x27\x94\x9b\x93\x30\x9c\x36\x7c\xeb\xd9\x4b\x94\x35\x83\x23\xb9\xd8\xd9\x9a\x64\x69\xf2\x1a\x89\x35\xec\x76\x33\x89\x54\xc9\x48\x21\x96\x30\xfd\xf2\xe3\xd4\xbe\xfe\x91\x2e\xb4\x3e\x92\x43\x82\x70\x2a\x15\xa0\xff\x77\xcd\x30\xba\xf1\xc0\x55\x5b\xa5\x86\x4c\x2a\x10\x52\x54\xd8\x1f\x52\xd4\xb0\xef\x26\xc1\xc7\xbe\x7e\xe9\x00\x70\x80\x12\x1c\x50\x33\x3e\xfc\x3b\xab\x78\x1c\xba\xbb\x82\xdd\xb3\x71\x3e\x27\x4d\x15\x20\xa4\xcf\x91\xf9\x1c\x0a\xea\x9a\x1c\x29\xda\x44\x69\x2b\x52\x80\x58\x13\x0e\x6a\x0f\x4e\x7e\x7b\x55\xe0\xef\xee\xc3\x75\xee\x15\x2a\x87\x34\xc3\x3e\x9d\xf0\x2c\x4d\x95\x17\x81\xb2\xd7\x8c\x96\x98\x09\x82\xc3\x2a\xa2\x67\xa0\xaf\x31\x5c\x4d\x9d\xa3\x32\xa0\xa7\xad\x4e\xf9\x01\x6f\x0e\xd1\x28\xc1\xd5\xdb\xfa\xa0\xd9\x3c\xb5\x71\x77\xb5\x80\x9c\xce\x53\x04\x1d\xcd\x20\xb9\xa3\x65\x66\x3a\xad\x39\x35\x4a\x5d\xe8\xe9\x95\x10\x5c\xf2\x67\x05\x2d\x36\x39\xad\xb8\x59\xc3\xe0\xf0\x3d\x95\x22\x01\xbb\x5d\xe4\x49\xc1\x7b\x8f\x1c\x1f\x7a\x67\x8a\xeb\xaf\xfa\xb6\xbb\xa8\x58\x21\xdf\x0c\x29\x98\xa0\x90\xf4\xf0\xb6\x16\xdc\xc8\x80\x73\x85\x4a\xf9\xec\xd5\x2d\x66\x8c\xa4\x38\x0e\xe9\xf5\x06\x93\xbd\x5a\x7d\x14\x53\xc7\x2b\xf9\x5e\xf5\x1e\x56\xec\x0d\xa0\x07\xa8\xf5\x87\x28\xf6\x5b\x94\xc1\x0c\xe8\x0d\x9c\x9c\x06\x80\xf8\x5a\xbe\xe9\x90\x4a\x71\xe9\x00\x4e\x38\x4b\x7d\x11\xa2\xbe\x27\x09\xad\x1d\x73\x90\x71\x19\x61\x62\x42\x14\xdd\x3d\x06\x82\xbb\x21\xda\x7f\x6e\x96\x69\x84\x21\x52\xf6\x27\x47\xe5\xef\x6b\x7d\x7c\xe3\x13\x34\x3c\x8e\x6d\xf5\x56\xbe\xe4\xcf\xa4\x5b\x1e\xbb\xdc\x8b\xfb\x4c\x50\xc7\x50\x90\x22\x93\xa1\xa6\x81\xe9\xb7\xa5\x40\xb3\x01\x42\xeb\x5a\x10\xfd\xf5\x2f\xcf\x61\xb7\x93\x54\x79\x50\x24\xea\xc9\x86\xc5\x42\x1a\x66\x43\xcc\x87\x90\xd1\x10\xa6\x9e\x6a\xb7\x53\x61\x53\x63\xde\x72\x54\x36\xd1\xfe\xbf\x28\xcd\x7b\x36\x24\xb3\xf6\x87\x16\xbf\xab\x64\xd6\x7b\xd3\xdf\x9a\xfe\x16\xf4\x3c\xb5\x30\x3e\xb4\x80\x15\x2e\x30\x23\x0b\x20\x76\xe8\x67\xa1\x68\x6c\xaa\xa9\x71\x7f\x9d\xb4\x53\x28\x22\x76\x73\x4f\x72\xa3\x5c\x91\x42\x27\x1c\x92\x2b\x74\xdf\x4e\x3d\xc0\x02\xe5\xd8\x43\xe4\xad\xfc\x71\x72\x2a\xa9\xf0\xb7\xaf\x22\x69\x1e\xda\x78\xb5\xd4\xd8\x0b\xc4\xcf\x09\x5f\x30\x92\x93\x42\x02\xd0\xa8\xb7\x9a\xe6\xcd\x23\xe3\x07\xb7\x08\x71\x54\x13\xa2\x59\x4b\xbb\x8f\xc6\x13\x5f\x23\xfe\x9a\xe1\x25\xb9\x07\x69\x7d\x2b\x7c\x71\x5f\x32\xcc\xb9\x64\xdc\x94\x26\x53\xe5\x57\x37\x6e\x6a\x7b\xc8\x6e\x77\xd6\xec\x69\x39\xac\x3b\xa0\x71\x1a\xe3\x49\x80\x0b\x52\x86\x6a\x3a\x4a\xea\xcd\xe7\x3a\xe4\x97\x0f\xce\x71\xa9\x3c\xaa\xdc\x0c\x38\x51\xaf\xdc\xe1\x01\x8f\xdb\xbe\x3e\xc0\x25\xeb\xe3\xd6\xac\xbd\x5e\x77\xbb\x3b\x4e\xef\xae\x17\x3f\x57\x3a\x82\xf8\x99\x01\x06\x3f\x67\x78\x08\x3f\xf3\xfa\x91\xf0\xab\xe7\xfb\x54\xec\x7e\x2a\xc8\xc7\x0a\x0f\x23\x58\x35\x63\x4e\x40\xb0\x0a\x87\x10\x73\x26\x3a\x0c\xb7\xdf\x7b\x0f\xc1\x9e\x4d\x04\x8f\xb9\x8b\xf6\xf0\xc8\x65\x91\xe5\xd0\x45\x51\xe5\xbd\xac\x91\x2f\xb5\xdc\xd9\x61\x01\xd6\xc8\x57\x67\x88\xe3\xc8\xf0\x7d\x1c\x6f\x26\xfb\x3d\xb5\x47\x64\xcf\xb1\x27\x95\x9a\x3f\xc7\xbe\xb5\x1a\xc9\x2d\xef\xb3\x21\x9e\x59\x13\x78\x56\x71\x41\x73\xed\x12\x08\x2c\xa3\xa9\xe4\xad\x60\xa4\x58\x45\xb1\x07\x9c\x63\x46\x8f\xbd\x70\xb8\x33\xfd\xb1\x64\xb9\x83\xc9\xe1\x8b\x78\x14\x31\xbf\x2c\x47\x6a\x8e\xfd\xfb\xed\xd4\xf0\xfd\xb8\xd9\x4b\xc9\x25\x57\xfc\xbe\x84\xdd\x6e\x89\x32\x8e\x1b\xe1\x94\x5b\x77\x9c\x28\x3a\x19\xfc\x90\x9d\x3d\xae\x0d\xed\x42\xa2\xd7\x57\xe0\x39\xa3\xc5\x2d\x66\x1a\x5b\x8f\x91\x18\x92\xb7\x77\x68\xb5\xc2\x4c\x13\x04\xa6\xd3\xda\xfd\xe8\x88\xb8\x1e\x72\xd2\x91\x55\x7f\x86\x6e\xb2\x5b\x99\xf1\x5b\xc4\x0a\xa9\x31\x03\x12\x30\x73\xdd\x48\x17\xd4\x68\xf8\xbb\x9f\x9d\x42\x4e\xcb\x73\xb4\xf4\xa3\x8c\x27\x97\x85\x22\x8b\xf4\x6f\x0e\xd0\x87\x53\x39\xb4\xce\xf4\x4c\x67\x7b\x70\x88\xfb\x6a\x2d\x5d\x81\x33\xbe\xd7\x0d\x29\x5f\x23\xc6\x71\x6c\xeb\x82\x25\x62\x9c\x14\x2b\x20\x1c\xf8\x0d\x29\x4b\x9c\xaa\xa0\x92\xab\xe0\x4d\x87\x03\x3a\xd3\x69\xca\x6a\x0f\x64\xd1\xad\xc4\xa1\x26\xfd\x52\xfb\xe1\x89\x02\x29\xda\xf7\xf9\xec\x73\x62\x8c\x42\xc4\x8d\x0b\x86\x40\x93\xb8\x1e\x45\xea\x93\x24\x3a\xda\x6e\xcd\x4c\xae\x5b\xd5\xe2\x1e\x95\xe4\xbf\x7f\xa5\x2b\x9a\xdd\xe0\xcd\x14\x43\x53\xb2\x40\x02\xa7\x20\x28\x14\x98\xcb\x7f\x29\x86\x95\x3a\xde\x36\x1c\xdb\x0f\xda\x1e\xba\x76\x82\xae\xee\x98\x26\xf9\x63\x58\x1a\x43\x20\xb6\x22\x4b\xb8\xc5\x26\x87\x25\xdf\x26\xd1\x91\x61\x4a\x83\x5d\xec\x65\xb2\x0c\xeb\x6e\x71\xbd\x80\x74\x80\x5c\xbe\xc5\x4e\xda\x2c\xac\xc1\xbc\xb8\xe7\xe1\xa4\x68\xab\x98\xa6\x0e\x57\xea\x34\xe4\x26\x58\x8a\xeb\xd3\xa0\x39\x2a\xdb\xe3\x5d\x25\xda\xb8\x2b\xfd\xb9\x78\x6b\x63\x9c\xac\xbb\x7d\xe4\xe6\xd7\xbd\x80\x5f\x4d\x21\x37\xba\x4d\x1c\x35\x84\xd2\xe3\x72\x54\x4a\x5b\xeb\x87\x83\xfc\x04\x16\xb4\xdc\x48\x7d\x81\xb2\x0c\x70\x86\x73\x5c\xa8\xc4\x7c\xaf\xe2\xed\x33\xc0\x6f\x24\xb5\x73\x74\xa3\x99\x59\xef\xac\x99\x89\xac\xfa\x0d\xb7\xda\x32\x9d\x3a\x80\x76\xf6\xfb\x3e\xfa\xb9\x29\x13\xf4\x0e\xdb\xed\xce\x94\xd8\xb5\x2d\xb7\xcd\x81\x38\xb5\x5e\xfd\xaa\x17\xc2\xb6\x1c\xf5\x42\xe5\xc5\xe2\x35\x93\xfb\xeb\xcc\x7a\xf0\xbe\xc2\xaf\x76\x9e\x42\x06\x71\x68\x86\x6b\x52\xa4\xb8\xf5\xb9\x97\xd1\xb3\xf4\x30\x15\xa3\x5f\x89\x1a\xad\x2d\x15\xd8\x1d\x41\x00\xbb\xa9\xc5\x1a\xde\x40\x15\x79\x14\x38\xed\xfa\x83\xcf\xa7\x40\x9d\xc1\x37\x33\x0f\x2c\x20\x8f\x02\x31\x76\x8b\x05\xc3\x85\x86\x60\x99\x61\x8f\x70\xb4\x9d\xbb\x0e\xe5\xdd\x7a\xe9\x88\x1d\xff\x7e\xbb\x35\x1b\x56\x95\x77\x46\x7d\xa4\x9d\x5a\x57\xcb\x99\xf4\xa6\x23\x8e\xbb\xdd\xe5\x9b\xed\xd6\xe6\xba\xfa\x55\x6d\x9f\x7e\xf6\x9c\xd6\x4b\xfe\xda\x36\x50\x39\xc8\x35\x44\x69\x94\x61\x3d\xae\x6e\xb6\x08\x45\xd8\x83\xee\x58\x13\x15\xd9\xdf\xcf\x11\xc7\x7f\xfb\x4a\xeb\xeb\x40\x28\xa7\x27\x78\xb5\x8c\xb6\x5b\x25\x4e\xc6\x35\xa9\x65\x47\xb9\x26\xf2\x81\xe7\x3b\x59\x4f\xb2\xab\xf2\xea\x20\x64\x66\x7d\xb1\x4f\x4b\x23\x34\x6a\x52\x79\x26\x4a\xad\x78\xa6\xc6\xf8\x22\x07\x74\xae\x78\xca\xc7\x53\x3b\x83\xe6\xe1\x50\xe5\xbb\x47\xd9\x1c\x9e\x71\xb4\x8a\x74\xb7\x9b\xdc\x22\x36\xd2\x16\x7a\x36\x70\x62\xac\x5b\xa3\x6d\x5e\x62\x9c\x72\xd5\xc9\x61\x72\x0c\x4e\x57\x47\x13\xdf\xfd\xdd\x2f\x3a\x8f\x50\x71\xae\x55\xdc\x3b\x7c\xd8\x3c\x2a\xbe\x33\xbc\xa8\x18\x97\x5b\xc7\x69\x19\xa4\x4b\xdd\x76\xa5\x9a\x25\x7c\xd7\xd4\xef\x18\xd1\x53\xd6\x21\x8a\x65\xb7\x89\x38\xcc\x82\x6e\xdc\x71\x46\xb3\x0c\x2f\xe4\x22\x4e\x04\x62\xed\x51\xeb\x5d\x8f\x41\x1c\x6f\xc0\x1a\xa4\x5d\x08\x47\xd1\xb9\x61\x11\xbf\x43\xab\xe4\x6d\x99\x11\xf1\x7c\xa3\xe1\x8a\x46\xcd\xd0\x67\x33\x02\x58\xc6\x6e\x69\xe6\x20\xf7\xe2\x61\xce\x85\x29\x9a\x76\xd1\xe9\xf7\xe4\xe0\x5b\xb7\xb6\x3a\xd6\x2b\x19\xeb\x5f\xd6\x55\x9c\x51\xc3\xc7\x6d\x99\x31\xe6\x08\x1c\x7b\x14\x0a\xd0\x5b\x63\xb5\xc2\xd4\xe1\xb6\x74\xba\x49\x61\x02\xee\xa8\xa4\x9c\x13\xe9\xb9\xdc\x11\xb1\x76\x23\xbb\xd8\xd5\xa6\x8f\xef\x8d\x8e\x76\xbf\xfe\x68\x9c\x70\xfc\x24\x45\xf5\x82\x16\xc7\xba\x23\xf4\xc9\x13\xf5\x43\xd2\x5f\x48\x25\x5c\x33\xa1\xad\xa8\xc2\xae\xe5\x88\x0e\x97\x4f\xf2\x39\x3f\x67\xa7\x73\x54\x7b\xcb\x18\xb7\x73\xbc\xd3\xf9\x87\x94\x37\x8d\xa8\xdb\x1f\x3f\x9f\xc3\x19\x4d\xb1\x2e\xac\xaa\xfc\xcd\xf5\x06\x56\xf4\x98\x6b\x9f\xed\x6b\xdb\x62\x7f\x71\x7e\xf9\x2e\x99\x28\x37\x43\xa7\x53\xcb\x0d\x23\xab\xb5\x80\xe3\xdd\x4e\x1b\xc5\x05\xcd\x65\x00\xde\x7a\xd7\xac\x34\x99\x94\x68\x71\x83\x4c\xd8\xfb\xda\xfc\xdb\x14\x13\xde\xad\x09\x87\x25\x91\xfa\x05\x71\x1f\x18\xb1\xc6\x60\xa0\x01\x41\x69\x96\xc8\xf1\x17\x29\x11\x32\xf2\x17\xf5\x77\xb9\x5a\xb1\x64\xf4\x16\xc3\xb2\x12\x6a\xaa\x35\x2e\x60\x43\x2b\x60\xf8\x98\x55\x85\x37\x93\x5d\x42\x81\x8d\x8a\x74\x32\x21\x79\x49\x99\x80\x68\x02\x30\x5d\xe6\x62\x2a\xff\x4b\xa8\xfa\x4f\x81\xc5\x7c\x2d\x44\x39\x9d\xc8\x5f\x2b\x22\xd6\xd5\x75\xb2\xa0\xf9\x7c\x45\x8f\x69\x89\x0b\x54\x92\xb9\x96\xfa\x69\xff\x00\x56\x15\x82\xe4\x78\xff\x88\x39\x97\x9e\x0b\x11\x9b\x11\x43\x73\x92\xa6\x19\xbe\x43\x6c\x68\x5e\x2e\x98\x45\xa8\x67\xc0\x1d\x5a\x0d\xbc\xb6\x1e\xff\x54\xb7\x75\x82\xa6\x14\x87\xe4\x1c\x2f\x51\x95\x89\x4b\xf3\xdb\xe6\x5b\xea\xf7\xce\x8b\x58\x87\x3f\xa6\x1d\x47\x3a\x08\x4d\x23\x8e\xa9\x26\x75\x0b\xf6\x57\xe8\x5e\xf9\x36\x57\x38\xa7\x6c\x03\x1c\x0b\xae\x98\x98\xa3\x7b\x92\x57\x39\x70\x39\x98\x14\x70\xbd\x11\x58\x65\x90\xe4\x4c\x6a\x40\x95\x09\x52\x22\x26\x54\x24\xa1\xf2\xca\x98\x35\x0d\x4a\xd4\x9e\x91\x90\xb2\xa4\xc5\x0f\x4b\xef\x59\x22\xa3\x93\xa9\x40\x38\xfc\xd7\x5f\xe1\xea\x79\x62\x5f\x37\x53\x9a\xd9\xb8\xa0\x0c\x73\xa8\x4a\x75\x6a\x45\x4e\xfb\x9f\xf0\x97\xa7\xf2\x0b\xe3\x6a\xef\xc5\x47\x95\xef\xe1\x54\x2e\xf4\xcd\x37\xf0\xd7\xa7\x9e\x3f\x3f\x9f\xc3\x4b\x7c\x17\x9c\xc6\x50\x6e\xc1\x30\x92\x78\x23\x28\xf0\x5d\x78\x41\x33\x52\xf7\xac\xd6\x0c\xd0\x4f\x95\xff\x45\x73\x6c\x98\xc8\x8d\x36\x50\xf6\x5d\xb4\xe9\x21\xfd\x65\x22\x88\x9a\x3d\x4d\x26\xae\xba\xad\x29\xc8\x30\x20\x86\xa1\xa0\xed\x4f\x75\x5c\x92\xea\xfe\x64\x0c\xbc\xc4\x8b\xc4\xc5\x75\x59\x15\x8b\x3d\xc8\x46\xf1\x20\x82\x5b\xab\x97\xfa\x51\x03\xa9\x56\xd5\xee\x9e\xcf\x1d\x64\xb4\x17\x83\x05\x66\x5c\xa3\xee\xc3\xae\x05\x5a\xc7\x25\x89\xdf\x3a\x06\xd6\x11\x7f\x81\xb8\x59\xc8\xa9\xc5\x35\xef\x8d\x39\xfe\x8e\x64\x58\x4d\xd0\x72\xd4\x2f\xcf\x77\x3b\xfb\xf9\xa9\xd7\x6e\xd8\x0e\xdb\x9b\x5c\x40\x5f\x0c\x1f\x71\x15\x41\x9f\xd1\x42\x20\x52\x70\x48\xfe\x17\x33\x0a\xd3\xe8\xff\xa6\x4e\xe5\x58\x3d\xb3\xae\x9e\xd2\x0c\xd6\xcd\xb0\x34\x61\xb6\x73\x88\xc3\x4f\x45\x8e\x18\x5f\xa3\xec\x1d\xbe\x17\x32\x32\xc7\xc9\x2a\x81\x73\x24\xf0\x4c\xfd\xbf\x54\x42\x33\x38\xaf\xf4\x76\x6a\x3c\x14\x1f\x87\x56\x41\x61\x18\x91\x21\x1c\x14\xdc\x75\xc1\x22\xea\x56\x20\x2d\x25\x55\xe8\x31\x80\xa0\x40\x37\x98\x83\x5e\xea\x60\xa8\xad\x87\xd5\x02\x3d\xd6\xf6\xee\x10\xf0\x18\x5e\x55\x19\x62\xb0\xa2\x50\x1f\x95\xeb\x02\xbb\x07\xbe\xda\xfc\x9b\x52\xef\xfc\x08\xce\xa9\x12\x3b\x47\xcc\x97\x8c\xe6\x50\x3b\xf1\xa9\xdd\x18\xa4\xb0\xc5\x1a\x13\x16\x1f\xcd\x5b\x42\x1c\x92\x45\xeb\x66\x38\x8c\xec\xaf\x2d\xb7\x65\xae\x06\x4a\x8b\x0c\x17\xd2\x0c\xaf\x36\x7a\xf7\xb5\xe4\x2d\x84\x7a\x07\x7d\xdf\x07\x3a\x3e\x70\xc5\x7f\x70\x5a\x24\xf5\xb2\xe3\x96\xec\x21\x42\xe4\x64\x0e\xf6\x4a\x87\x9c\x4f\xd1\xfc\xd2\xe1\xb4\x23\x20\xe3\xe5\xe3\xc4\x46\x6c\x3a\xd3\xb5\x47\x72\x5a\xde\xb2\xeb\x89\xb7\x44\x54\x1f\xd5\xcc\x32\xa0\x62\x8d\x19\x2c\x10\xc7\x1c\x22\xa5\x00\xb8\x6a\x9b\x8b\xe1\x3d\x5f\xd3\x2a\x4b\x95\xb0\xd1\xc5\xa2\x62\x1f\x06\x97\xf4\x3b\xb6\x0f\x86\x45\x42\x60\x5b\xf6\x7a\x37\x45\x7b\x8d\x60\x5e\x39\xd4\xbe\x07\xa0\x7c\x94\x8e\xb2\x0f\x6a\x79\xb3\xcf\x16\x88\xb1\x0d\xd0\x4a\xf8\x82\xdb\x2b\x71\xde\xee\x72\x7a\x80\x1e\xa8\xdc\xad\x6e\x0f\x19\x95\xc4\xdf\x52\xef\x3f\x48\x67\xa9\x53\xde\x76\x14\x53\x93\xc8\x0f\x6a\x98\x8e\x7d\xa3\x0c\xa2\x83\xd5\x42\x1c\xd8\xb6\xce\xcc\x4d\xb6\xb9\xb5\x3d\x0d\xf8\xbf\x6c\xb7\x35\xf8\x7c\x0a\x91\x1c\x55\x23\x11\xef\x76\xbf\xc4\x33\x78\xe2\x13\x04\x6a\x8a\x0c\x9d\x02\x98\xcf\xa1\x44\x05\x59\x70\x09\x82\x74\x54\xc8\x92\x98\xa0\x94\x48\x6d\xa9\x5c\x61\xef\x8b\x9c\xaf\x54\xf7\x40\x2e\x92\xb7\x1a\xa6\x68\x6a\xc6\xb5\x5c\x4a\xe9\x7e\xd6\xde\x06\x74\xa0\x3b\x81\x2f\x6f\xa7\xb3\xce\xa1\x03\x05\x4e\x94\xf3\x95\xfb\xb8\xc5\x05\xb7\x65\xa7\x5b\xfe\xb4\x6f\xbd\xc4\x71\x33\xc2\x44\xed\x03\xee\xd5\x36\xe4\x03\x75\xb7\x45\x13\x16\x7b\xdd\xce\x12\xb3\x5f\xbf\xb5\xee\x89\xdb\x5a\x17\x64\xfb\xac\xa1\x86\x13\x96\x82\x0c\x87\x7b\x03\x10\xeb\x69\xdb\x3d\x27\xb5\xa1\x74\x61\xaf\x69\x55\xa4\x36\x7f\xac\xc3\x0a\x15\xd6\xae\xab\x1c\x15\x5e\xcb\x71\x1d\x6a\xa8\xd0\x64\x53\x92\x05\xca\x32\x15\xd4\x72\xed\x2e\xd3\x6b\x39\x35\x4e\xb5\x85\x46\x20\xe3\xcc\xc4\x9c\xdd\x36\xbe\xb5\x89\x59\x4f\x1c\x57\x55\x9a\x38\xb3\xc4\x44\xd9\x83\x21\xf0\xb9\x60\xd5\x42\xc0\xd6\x54\xd3\x5f\xbc\x7b\xf7\x1a\xcc\x0a\xa0\xbb\x3a\x26\xa0\x9e\xda\x87\x47\x2e\x10\xf0\x8b\xdc\x5d\x27\xd3\xe3\xe9\x2f\x93\xb0\x3b\x3c\x3f\x32\xc2\x70\x8e\x25\x13\x4b\x51\x67\x29\xae\x33\xba\xb8\xa9\x13\x03\x9d\xd7\x6e\x2f\x64\x2b\xa1\x64\x7f\xe9\x26\xcf\xf6\xd8\x2b\x13\x00\xaa\xa1\xe6\x87\x95\xb2\xe4\xe2\x7e\x91\x55\x9c\xdc\xe2\x66\xd4\x37\x1e\xe7\x9d\xcf\x3b\x13\x93\xc2\x99\x58\xff\x08\x4c\x5c\x8f\xfa\xb6\x35\x71\xfd\xa2\x33\xb1\x0a\x1f\x33\xfc\x6a\x69\xe6\x36\xbf\xe1\xd5\xd2\xf4\xea\xba\x03\x02\xf8\xfe\x88\x8b\x95\xca\x9e\x69\x8c\x41\xff\xae\xfb\x7c\xeb\xd7\x01\x8c\xbc\x4f\x49\xe1\x7f\xea\xbc\x6e\x7f\xfa\x5a\xe9\xea\x42\x7f\x68\x7e\x9c\x98\xec\x8d\x7d\x13\x80\xb4\x6e\xe0\xd5\x80\x86\xfb\x91\x03\x60\xba\xdf\x91\x02\xc2\x7d\xda\xed\xef\x5a\x3d\xc3\x00\xfa\x41\x58\x6c\x9c\x04\xe3\x04\xe0\xd2\x20\xe3\x3c\x6d\x7f\x10\x2e\xdc\x34\x4f\xc1\xab\xf5\x74\x07\xb7\xe7\x6b\x6b\x4b\xf3\xc3\xef\x56\xeb\xb8\x3e\x8d\xae\x3e\x9a\x4f\xbc\xb0\xd2\xf8\x42\xda\x75\x6a\x1d\x31\xf9\x8d\xfb\x99\x1d\xc7\xd6\xf5\xe7\xba\x87\x30\x0e\x3c\x82\xd1\x1a\x64\x01\x19\x58\xdc\x37\x7d\x3b\xab\xe0\x9f\x93\x22\xb5\x2a\xed\x9a\x8a\x35\x5c\x93\x22\xe5\x0a\x10\x9b\xe0\xe2\x80\x54\xe8\x8b\xb9\x98\x01\x11\x80\x38\xaf\x72\xcc\x41\xac\x91\x80\x85\x6e\x83\x03\xb1\x26\xc5\x8a\x83\x72\xb9\x95\x5e\x43\x60\x2a\x58\x12\xde\x48\x47\x9c\xc9\x1b\xbc\x22\x5c\xb0\x4d\xac\xd3\xe1\xce\x81\x95\xf9\xdc\x6d\x6a\xb4\xd9\x15\x01\x77\x24\xcb\xa0\xe2\x58\x79\x8b\x2a\x99\x99\x63\xb1\xa6\x29\x48\x8b\xc1\xeb\x4c\x15\x05\x5c\xf0\x8a\xb5\xf3\x33\x33\x9d\x5a\xd1\x9a\x3e\xaf\xb8\x80\x35\xba\xc5\x70\x8d\x71\xe1\xa6\x6e\x74\xcc\xb3\x37\xd7\x72\x8d\x97\x94\xe1\x35\x2a\xd2\x44\x67\x67\xa2\xc0\x21\x1b\x38\x1a\x98\x24\x76\xe9\x1d\x31\xdf\xa4\x98\x8b\x45\xe0\xa8\x49\x5f\x26\x57\x48\x2c\xd6\x38\x7d\x23\x5f\x58\xa2\x6d\x4d\xd6\x86\x61\x0e\xef\x3f\xa8\x67\x93\x9e\x03\x3f\xae\xf9\x3a\x05\xe6\x65\x1b\xff\xbb\xc2\xcc\x39\xf7\x37\x01\xf8\xc8\x55\xb9\x59\x27\x51\x75\x82\x9d\x47\x2c\xf9\xe9\xcd\x8f\x89\x1a\x1c\xc5\x71\xa7\x73\x23\x9c\xba\x74\x7d\x55\xa6\x7b\x47\xaf\x6c\xa6\x50\x0e\x8d\x46\x24\x02\x43\x0e\x69\xd3\x3b\xaa\x08\x77\xc1\xd8\x4b\x2a\xea\x99\x3b\x67\x57\xdd\xc2\xcb\x4b\x7c\x17\x7d\xf5\xf4\xe9\x6c\xda\xf1\x27\x77\xb5\x47\xef\x43\xac\x00\x1d\x3e\x1c\x3b\x72\x81\xc9\xbf\xed\xfc\x5b\x75\xe4\xd4\x8a\xbe\x6e\xf2\x6c\x99\x86\xe9\x2f\x07\xc7\xbd\x2d\x0e\xe1\x44\x9c\x5b\xb4\x6f\x35\xc8\x35\x0d\x21\x8d\x04\x58\x01\x08\xb2\x65\x06\x1f\xd7\x37\x3d\x6f\xfe\x2e\x21\xfe\xc8\x93\xef\xb1\x78\xf5\x43\xbb\xe9\x73\xf8\x1c\xa0\x54\x34\x01\x05\x1d\x1d\x0e\xc4\x63\x9e\xd2\x94\x81\x1a\x12\x6b\x97\x2a\xac\x6f\xd9\x61\xaa\x68\xa8\x4c\xea\xf5\x11\xe9\x73\x38\x38\x8f\x4c\x9f\x17\x18\xa5\x98\xb9\x14\xfa\x44\x44\x12\x3d\xd3\x7b\xb5\x97\xcf\x50\x41\x0b\x19\x07\xe8\x87\x3f\xe0\x8d\x47\xae\x0f\x33\xe5\xbb\x3c\x3a\x32\xb5\xe2\xf2\x53\x21\xe6\xa5\x93\x9d\x36\x2a\xb6\x73\xce\x2b\x7c\xfa\x4b\x23\x31\x6b\x34\x8a\x5c\x47\x4e\xd7\x23\x03\x16\x03\x7b\x40\xc4\x8d\xe1\x9e\xb4\x75\xde\x15\xe1\x9c\x14\x2b\x39\x5d\x63\xed\xfb\x71\x77\x95\x13\x4c\x19\x46\x29\x29\x56\xba\x3c\xf8\xe5\x47\x58\x22\x92\xc9\x80\x42\x6a\xad\x76\x05\x3a\xf2\xf1\x8a\xed\x99\x0c\xe7\x3e\x85\x86\x58\x7e\x17\xa7\xaf\x54\x4f\x83\xc0\x1b\x86\xa9\x13\xad\xc7\xb4\xd4\xcd\xce\xfa\x35\x5c\x57\x02\x68\xa9\x2f\x8f\xd0\xb0\xd6\x71\x5e\xf8\x72\x80\x8e\x16\x3f\x44\x14\x0f\x65\x6c\x9f\x55\xb0\xd4\x68\xb7\x01\xcc\xe7\xad\xd0\xad\xef\x82\x83\x7e\xe1\xd5\xe8\x1d\x7e\xcd\xc1\x13\x6b\x4f\x94\xb8\x9c\x23\x81\x4e\x7a\xe4\x58\xa3\x16\x7e\xab\xdf\xed\xda\xd7\xf1\x34\xfd\xe8\xcb\xb4\x47\xf9\x2c\xd3\x61\x35\xb9\x4c\x1f\x55\x3b\x7e\x0a\x1c\x0f\x55\x29\xc1\x7e\x89\xf0\xa5\x0b\x7f\xda\xe2\x3f\x6d\xf1\x9f\xb6\xb8\xef\x7a\x8c\xb6\x3d\xfe\x17\xd7\x2b\x7d\x35\x99\x4e\xeb\x7a\x7d\x83\x8b\x93\xfb\x30\xb2\x60\xb5\xff\x0b\xc4\xf5\xed\x1a\x71\x6d\x43\xfc\x0b\xf8\x4c\x0e\xc1\xed\xba\x1d\x6b\x62\x58\xf2\xdc\xbb\x05\xc2\xe9\x38\x4b\xf1\x12\x33\x33\x20\x39\xcb\x28\xc7\x51\xec\xbb\x59\xde\x2d\x87\x75\xb6\xc3\x79\x74\x71\x5f\x52\x26\x1a\x5b\x7a\x4d\xd3\x8d\x7b\x32\x54\x50\xd3\x35\xa5\x00\x4a\xd4\xbd\x69\xbc\x69\xa4\x6a\xca\x24\xdb\x2d\xa4\x8c\x96\xf6\x55\xd3\xcd\xdd\xb9\x4c\x45\x35\xe0\xd6\xae\x55\xa4\xc1\xb7\xfc\x3c\xa3\x05\xaf\x72\x6c\xe2\xbb\xd0\x69\xc6\x21\x4f\x00\x1c\x97\x88\xd0\xe4\xe2\xd5\x77\xce\x47\xea\xf9\x03\xae\xbe\x9a\x4e\x2d\x71\x77\x07\x3b\x18\x5d\xde\xdd\x22\x56\x5f\x36\xe3\xb4\xbe\x83\x57\x89\xf2\x69\x62\xff\x51\x93\xec\x89\x9c\xe0\x50\x6f\x69\x90\x46\xa3\xae\x0a\xdb\xeb\xc4\xee\x23\x63\x4d\x47\xd7\xed\x0a\x90\x73\xd8\xe5\x56\x69\x84\x0b\xf9\xf3\x31\x80\xea\x73\xbd\xbb\xe4\xeb\xe5\x7e\xb7\xdd\xd3\xc7\xcf\x6f\xf4\x6c\x5d\x0d\x9c\x0c\xf4\x88\xfa\xee\x8c\x03\x91\x3b\xff\x6f\xc7\xba\x61\xfd\x19\x6a\x8a\x57\x37\x89\x35\xcd\xee\x7e\x6a\xe7\x8c\xe6\x25\xe5\x44\x38\x4d\xf9\x9a\xab\x0c\xf3\x24\x49\xec\x8a\xe6\xa3\x82\x64\x13\x93\x1d\xfb\x8f\x45\x86\x38\x57\x8a\xe9\xe4\x14\xa2\x96\xf6\x8c\xf7\xe6\x6f\xda\x31\xe8\x7c\x0e\x3d\x06\xca\xe4\x6d\xfd\x48\x49\x9f\x03\x97\xaf\xdd\x96\x3e\x5a\x64\x1b\xe0\x55\x69\xd4\xaa\x7b\x06\x88\x16\x6a\x06\xae\x6a\x70\x4d\x11\x44\xea\xe8\xba\x9a\xb2\x27\xf5\xe9\xa0\xdc\x64\x3d\x7b\xad\xaa\xea\x51\xb5\xf9\x3b\x15\xa2\xcc\x60\xad\x9c\x0e\x38\xf2\x9f\x9b\xc0\xcb\xc9\x81\x42\xeb\xae\x20\x03\x6c\xbb\x2c\x04\xaa\x21\xd2\x7a\x05\x24\xc3\xc9\x5b\x8c\x6f\xa2\xa7\x33\xa9\x5b\xe4\x3f\x2f\x8a\x54\x6f\xaa\xd0\xcb\xb7\x02\x31\x11\xf7\x35\x45\x7b\xa5\xa4\x46\x37\xaa\x0e\xcc\x6f\xd4\xe5\x2f\xcd\x4b\x4f\x87\xb9\xd2\x75\x71\xbf\xc0\x38\xe5\xa6\x4a\x76\xd8\xd5\x2c\x5e\xa5\x6a\x06\xea\x3a\x89\x99\x5a\x3f\x1e\x6e\xe7\xf6\xea\x67\x2d\xc8\xbf\x35\xd7\xd6\x8c\x86\x5c\x17\x0e\x0f\x85\xdc\x61\xd3\x58\xc8\xbd\x1d\xe6\xfb\x8f\xf6\x74\x5e\xed\x0a\xf9\xc8\xea\x8b\xd7\x06\xfb\x49\x4c\x7f\xe9\xf0\x06\xf3\x0b\x23\x81\x9d\xa6\x2b\xd6\xad\x0a\xda\xbe\x7a\xc1\x41\x9b\x86\xa1\x3b\x19\xc6\xc3\xfb\x0f\xba\xf7\x65\x06\x6b\xc4\x7f\xc0\x1b\xb8\xa6\x34\xab\x4f\x09\x42\x4f\xc9\x65\xdb\x75\xbf\x6c\x39\xab\x0e\xb6\xe2\xae\x51\x21\x4b\xf8\xc2\x2c\xd3\x27\x0d\x9f\xe0\xb0\x18\x54\x5c\x8e\x77\x78\xae\x4a\x1d\xe8\xce\xb4\x25\x5a\x60\x94\xce\x36\x5f\x3b\x7a\x5b\x41\x85\xee\xa4\x53\xaa\x5f\xbe\x77\x07\x1e\xff\xe5\x83\x59\x69\xd2\xca\xc9\x68\xc6\xb4\xed\x68\x5f\x78\xae\x3e\x7e\x96\x65\xf4\xee\x22\x2f\xc5\x46\x65\xea\xf5\x1c\xad\x87\xbd\x76\xd7\x3b\xcd\xea\xc6\xb8\x6a\xea\xd7\xb5\x58\x11\xae\x9a\xf7\x49\xaa\xbb\xfe\x17\xb4\xd0\xc5\x2c\x75\xb3\xa4\x14\x34\xb1\xc6\xda\x07\xeb\xae\x73\x20\xa3\xf5\xcb\x16\x02\x71\x27\xaa\xec\xdc\xbc\x6b\xce\xa7\x1e\xc4\xf4\x70\x30\xd4\xba\x1a\x02\x42\x17\x28\x42\x1b\x05\x88\xd5\x15\x0b\x1a\x7a\x0b\x53\x3c\x84\x88\x92\x8f\x53\x98\x4e\x61\x2b\x89\xad\xff\xe6\x82\xa9\x38\x96\x88\x73\xa7\xbb\xcf\xb1\x8d\x1d\xb7\xab\xdb\xe3\x33\x9f\xdb\xd2\xb5\x9d\xae\xa9\x36\x96\x0c\xdf\x12\x5a\xf1\x6c\xe3\x15\x1e\xaf\x37\xa6\xec\x18\xd0\x00\x51\xdc\xef\xc4\xd7\x6a\x30\xb8\x6d\x5a\x22\xe6\xdd\xf2\xd3\xb9\xe1\xa5\x73\xb9\x8e\xe4\xcf\xaf\x78\x4f\x4b\xfb\x65\x73\xb1\x04\x98\x95\x4d\x99\x3a\x74\xff\xc7\x69\x38\x45\x5e\xc7\x6a\x0a\xb5\x80\xec\xf4\xa8\x7b\xc5\x33\xb7\x5b\xe1\xb1\xef\xc3\x81\x3f\x02\x31\xbd\x4b\x49\xdb\x0d\x10\xbe\x0f\xda\xe4\x09\xac\x2e\xb1\x6c\xf0\x9b\x0f\x9c\x9b\x74\x1c\xa0\xe2\xf6\x75\x08\xbb\x07\xb0\x9a\xa1\xbb\xbd\x92\x1f\xfc\x6b\x13\x9f\x7c\x3d\x69\xd4\x7b\x00\x7f\x48\x7b\xd5\x80\xb5\x9c\x97\xfe\xcc\xf0\xa1\x5e\x88\x3e\x20\x39\xde\x17\xd1\xa1\xc0\x33\xdd\xda\x2e\x3d\x7d\x75\x76\x27\x05\xb4\x58\x50\xa6\x8a\x43\x82\x42\xf7\xe4\xf6\xb4\xa7\x9d\x67\x0a\x51\xdd\x39\x2f\x28\x4c\x17\xfc\x76\xaa\x4f\x99\x29\xd5\x1a\x7f\xbe\xce\x4f\xcb\xe4\x77\x7c\x9c\xc7\xf4\x6f\xf6\x39\x02\xf8\x63\x80\xb8\x53\x15\x03\x35\x57\xaf\xf5\x1c\xa7\x0f\xf6\x63\x8d\xbb\x30\xe0\xa4\xf6\x94\x02\x75\x1d\xed\x7c\x7d\xbc\x0d\x27\xfe\x6a\x87\xac\xdf\x1d\xeb\xfb\x34\xec\x9e\xc1\x31\x28\x07\xcd\x2a\xe6\x5f\x05\xdb\xc0\xf9\xfe\x1e\x28\x03\x07\x72\x03\x67\xf9\xf7\xb0\x55\xa5\x37\x47\xf8\x58\x03\xa7\xf3\x83\xe7\xf2\x9d\x4b\xcf\x1f\x2c\xa5\xe3\x96\xec\xa9\xfd\x3d\x00\xf0\xcf\xd2\x9b\x0a\xf3\x72\xf8\xea\x03\xd8\x6b\xc7\xf6\x9f\x71\xee\x5a\xae\xf0\x35\x10\x9f\x97\xf5\xea\xfe\xd5\x22\xe9\x8b\x07\xba\x2b\x5b\xa6\x38\xd6\x83\x3c\xb7\xa3\x8d\x6f\x6c\x6d\xe1\x00\x52\xea\xac\x09\xc1\x2a\x73\xd5\xbe\x37\x2d\x60\x10\x3f\xc5\x12\x8d\x20\xe9\x90\xb9\x19\x7f\xff\xdc\x5e\x1a\xb7\xfc\x05\x37\xd5\xa1\x4e\x02\x39\x97\x82\x9b\x26\x49\xf5\x57\x70\x9c\x6b\xe3\xdb\xc7\x3a\x7b\xee\xff\x69\x34\x57\xe8\x8f\x04\xd4\x8d\xb2\xfe\x9f\x05\x8b\x03\x2f\xd4\xfd\xf6\x9d\x90\xb7\xf7\xbe\xfb\x3d\xcc\x96\x33\xba\x6e\x4f\x11\xc6\xed\x91\x99\xac\xca\x66\x23\xfd\x0a\x08\x5c\xb7\x54\xbf\x1a\xb1\xb9\xdd\xff\x6d\x47\xdc\xf5\xb2\xe7\x50\x17\x84\x6e\x97\x19\x58\x74\xb4\x11\x0d\xab\xba\xf6\x5c\x23\x74\xa6\x37\xfe\xe1\xda\xb3\x87\x0a\xdb\xde\x8b\xaa\x7e\x75\xcc\xfb\x6f\xac\x7a\x74\xd4\x43\xb7\x7d\x1c\xa6\x7f\x02\x04\xec\xa8\xa4\x11\xcd\x2e\x9d\x2a\xcb\x3f\x03\x00\x00\xff\xff\xe0\xe5\x11\xf5\x00\x73\x00\x00") func templatesServerParameterGotmplBytes() ([]byte, error) { return bindataRead( @@ -722,12 +748,12 @@ func templatesServerParameterGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/server/parameter.gotmpl", size: 28728, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4b, 0x53, 0xb9, 0xa3, 0xe8, 0xc6, 0x71, 0x82, 0x7a, 0xd6, 0x71, 0xb9, 0x4e, 0x13, 0x9f, 0xe, 0x59, 0x1c, 0x98, 0xc, 0x37, 0x19, 0xbf, 0xc4, 0x84, 0x11, 0x3c, 0x3e, 0x24, 0x20, 0x65, 0x31}} + info := bindataFileInfo{name: "templates/server/parameter.gotmpl", size: 29440, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xed, 0x43, 0xd4, 0x63, 0x5e, 0xa4, 0x12, 0x99, 0x24, 0x71, 0xa6, 0xc0, 0xf, 0x42, 0xd, 0x2c, 0x8f, 0xfb, 0x25, 0x2e, 0x46, 0x82, 0xc1, 0x74, 0xee, 0xc7, 0x6, 0xfc, 0x74, 0x77, 0x90, 0xcc}} return a, nil } -var _templatesServerResponsesGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\xdf\x73\xdb\x36\xf2\x7f\xd7\x5f\xb1\xd5\x37\xed\x88\x1e\x89\xcc\xf7\xe1\x5e\xdc\xba\x33\xd7\x38\x77\x75\xe7\x1a\x7b\x62\xf7\x6e\xe6\x72\x99\x06\x26\x57\x12\x5a\x12\x64\x00\x50\x8e\x4e\xc3\xff\xfd\x06\xbf\x48\x80\x3f\x64\xd9\x6d\xf3\xd4\x3c\xc4\x22\x80\x5d\xec\x2e\x3e\xfb\x03\x4b\x1e\x0e\x90\xe1\x9a\x32\x84\xb9\x40\xbe\x43\xbe\x45\x92\x21\xbf\xaf\x69\x9e\x21\x9f\x43\xd3\xcc\x0e\x07\xa0\x6b\x60\xa5\x84\xf8\x4a\xfc\x95\x73\xb2\x87\xa6\x39\x1c\x40\x62\x51\xe5\x44\x2a\x4a\x5a\x54\x39\x8e\xd2\xc7\x66\x2d\xe6\x02\x07\x54\x39\x4d\x8f\x13\xb1\xcc\xec\xbf\xea\x7e\x76\xd2\x4e\xef\xd9\xca\x1c\x5f\x89\x37\x75\x9e\x93\xfb\x1c\x61\xd5\x34\xb3\x1d\xe1\x70\x38\xc0\x8e\x70\x46\x0a\x84\xf8\xea\x12\x9a\x06\x84\xe4\x94\x6d\x66\x74\xad\xe6\xe2\xb7\x98\x22\xdd\x21\x7f\xa3\x56\x34\x4d\x7c\x38\x40\x45\x44\x4a\x72\xfa\xdf\x96\xe2\x8b\x0b\x60\x34\x87\xc3\x0c\x46\xd8\x5d\x80\xdd\xfc\x6f\x25\x2f\x88\x94\xc8\x8d\x36\xc1\xf3\xe2\xec\xc4\xbd\xa2\xc0\x78\xdd\x39\xbc\xaa\x85\x2c\x0b\x9f\xe5\x59\x6b\xb1\x13\x59\xb7\x36\x1a\xf2\x8a\x6f\xb5\x4d\x16\xd1\xe1\x80\x2c\x53\x4b\xf5\x9f\x99\x36\x6c\x27\x4e\x4f\xf3\xf3\xd3\x54\x7f\x96\xe6\x7f\x90\x42\xd6\x66\x0a\x1c\xe6\xfc\x7b\x2a\x7d\x71\x01\xf3\xb9\x3e\x68\xfe\x10\x7f\xaf\x61\xb6\x88\xe2\x5b\x94\x4a\x8b\x8a\x53\x26\xd7\x30\xff\xf2\xe3\x1c\x62\x2b\xd7\x72\xc8\x24\x9a\xb5\xfb\xf4\x20\xac\x1c\x80\x4a\x2c\x9e\x85\xe2\xf8\x9f\x24\xaf\xf1\xf5\xa7\x8a\xa3\x10\xb4\x64\xd0\x34\xb7\x3d\x2c\x0f\x57\xf4\xa0\x3b\xca\xe3\x09\x00\x1e\x92\x7b\xa7\x36\xb1\xe2\x37\xc1\x6e\x65\xac\x32\x2a\xf7\x13\xe0\x77\x54\xee\xdf\x4d\xec\x01\xb8\x46\xc5\xee\x20\x36\xbe\xe2\x2d\x5c\x00\xa9\x2a\x64\xd9\x84\xe8\x6f\x97\x53\xbc\xfb\xc8\x0b\x80\x37\x05\xba\x7e\x90\x7c\xb5\xa5\x79\x36\x2a\xd7\xbb\xf7\x16\x6e\xeb\x92\xc3\xcf\xcb\x93\xa8\xd4\x29\x71\xc2\x36\x38\x05\x50\x63\x88\x55\x1b\xea\x0c\xa3\xa9\xc4\x73\xd4\x83\x0c\xed\xb3\x12\x90\x4f\x69\x8f\x30\x48\x84\x46\xaa\x1b\xc2\x91\x49\x07\xca\x61\x34\x14\x0f\x64\x13\xff\x50\x52\xf6\xdd\xde\xe0\x65\x71\x92\x61\xb5\x25\x83\xe0\xf2\xaa\xcc\x73\x4c\x25\x2d\x99\xe1\xa3\xa3\x0a\x5d\x43\x8e\x6c\x31\x8c\x37\xf0\x2d\xbc\xd4\x76\xdc\xee\xac\x53\x84\x0b\xde\xbd\x7c\x3f\x03\xa5\xca\x76\xe7\xa1\xef\x09\x21\x6e\xbb\x8b\x66\x00\x4f\xf0\xcb\xcf\x65\x88\x51\x27\x68\xcd\x31\xb1\x40\x58\x23\x8d\xcd\xb5\xa6\x9a\xa4\xf5\x0d\xf8\xbb\x3b\xb0\xf0\xed\x6c\x71\x18\xfe\x0c\x8b\x37\x8e\xa2\x2a\x99\x40\xbf\x6e\x53\x06\x2e\x33\x84\xd5\xff\x43\xd3\x24\x09\x1c\x0e\x5e\xde\x54\x47\xda\x34\x7a\x9e\x0a\x90\x5b\x84\xef\xef\xee\x6e\x20\x55\x03\x1c\x65\xcd\x19\x66\xa0\xdc\x5b\xee\x2b\xed\xb2\x03\xda\x59\x5a\x32\x21\x47\xa7\x0c\x5b\x26\x4d\x46\x31\x52\xf8\x85\xdd\x2c\x39\xb3\x51\xf5\x12\x45\xca\x69\x25\xdb\x50\xdb\xe3\xa5\x03\xc3\x01\xee\xf3\x32\xfd\x35\x2d\x8b\x42\x79\xdd\x80\x48\x01\xf1\x08\xf1\xb6\x2e\x08\xf3\x07\x5d\x98\x9e\x29\x74\x6e\x90\x9f\x3b\xeb\xa9\xd5\x29\x29\x30\x60\x31\x3b\x4b\x66\x13\x46\xb0\x45\x64\x9d\x4a\x07\x33\xba\x06\xfc\xe8\xdb\x7d\x06\xf0\xb3\x90\x44\xd6\xc2\x19\xc5\x2c\x6c\x0b\x36\x13\x13\xad\xff\x09\x75\x52\x67\x87\xc3\xa8\x69\x8e\x1b\xc1\xd9\xd6\x89\x11\xff\x48\x3e\xd1\xa2\x2e\xcc\x98\x7d\x38\x77\x93\xaf\x3f\xa5\x79\x2d\xe8\x0e\xbb\x55\xdf\x04\x62\x79\xe4\xfe\xb0\x66\x4c\x99\xc7\xd8\x3c\x8c\x30\x6e\x57\x7d\xdb\x63\xdc\x4e\x0c\x18\xd7\xb9\xa4\x55\x8e\xd7\x6b\xcb\xdb\x3e\xc3\xf5\x5a\xf3\x0f\x17\x0c\xa8\xc9\xa7\x7f\x20\xdb\xc8\x6d\xab\x31\x98\x67\x4b\xeb\x4d\x8f\x68\x14\x90\x52\x16\x92\x7a\xd3\x7d\xd2\x1b\x5d\x0b\x30\x43\x68\x1f\x0c\x55\x37\x33\x22\xe9\x95\x4a\x5d\x9d\xa0\xfa\xb1\x95\xd3\x4d\x8e\x88\xe9\xd3\x51\x16\xd0\x75\x93\x7d\xba\x9f\x18\xfd\x58\xa3\x47\x6a\x06\xce\x41\xf2\x1a\xfb\x8b\xbf\x27\xe2\x12\xd7\xa4\xce\xa5\x59\x6b\x1f\xce\x83\x88\xfc\x7f\xbb\xb9\x42\xa0\x5b\xe6\xa3\xef\x2c\x31\x10\x1c\xf7\xc5\xf8\xef\xe5\x9d\xf2\xa5\xa6\x81\x0f\xbf\x88\x92\x9d\xcf\x0f\x07\x1b\x34\xbc\x24\xfb\x16\x3f\xd6\x94\xa3\xe2\xb8\x2c\x0b\x95\xe6\x2b\xb9\xef\x0b\x7a\x25\x7e\xb8\xbd\x7e\x63\x2a\x30\xb5\xd0\x94\x24\xed\xaa\xf9\x07\xdf\xd1\x3a\xb7\xb8\x4d\xb7\x58\x10\xc3\xe6\x81\xca\xad\x37\x32\x03\xf8\x6d\xce\xf7\xa7\xe7\xfd\xe9\x79\xcf\xf0\xbc\x19\xc0\x15\x3b\x87\xef\xca\x6c\xaf\x1d\xc8\x9f\xb8\x21\xfb\xbc\x24\x99\x3d\x64\xc2\x32\x58\x68\x17\x31\xa0\x8d\xaf\xc4\x77\x44\xa0\x72\xa9\xc8\x1b\x7b\x55\x16\x55\x8e\x9f\xae\xef\x7f\xc1\x54\x0e\x3a\x04\x76\xd9\xc0\x13\xef\xcb\x6c\xdf\xb9\x5b\xcf\x7f\x54\xd2\x4e\xe0\x0d\x3e\x8c\xbb\x76\xca\x91\x48\x14\x13\x8e\xaf\xfd\x2c\xb3\xe1\x62\x6b\x33\xdd\x4e\x55\x3d\x62\xb6\xae\x59\x3a\xc9\x77\x31\x96\x52\x53\x9b\x48\x5b\xe1\x22\x38\x9b\x08\x38\xe3\x29\x99\xae\x4d\x9d\xf3\xcd\x85\xad\x0f\xc1\x3c\x5f\xc0\x5f\x5e\xbe\xd4\x75\x57\x70\x6b\xd7\x51\xd1\x08\xad\xa2\xe3\x6d\x59\xa0\x0d\x7d\xf6\x50\xd5\xc5\x69\xa1\x82\x47\x02\x94\x51\x49\x8d\x14\x4e\xcf\x40\x79\xab\xb4\xb6\xec\x20\xf3\x6b\x49\xda\x40\xe5\x05\xe2\x55\x3b\x67\xe7\xbd\xb2\xbe\x69\xdc\xaa\x0b\x6f\x8d\x59\xb7\x72\x98\x89\xaf\xc4\x0d\xa7\x05\x95\x74\x87\x63\x57\x59\x8d\xa9\x85\x89\xa0\xaf\x4a\x26\x09\x65\x02\xe2\x7f\x23\x2f\x61\xbe\xf8\xcf\x7c\x0e\x51\x64\xc1\xa3\xc7\xd4\xcf\xe4\x4c\x95\x3e\xeb\x42\x9a\x0a\xb1\x53\x9c\x03\x37\xe1\x5b\xc0\x4f\xac\x20\x5c\x6c\x49\x7e\x87\x9f\xe4\x22\x5a\x02\xc6\x9b\x18\x2e\x89\xc4\xa5\xfe\x5f\xd2\x42\xfd\xaa\x39\xd1\x91\xf4\x2c\x09\xf4\x74\x3a\xe8\x7b\xc6\xa9\x8a\x1c\xd3\x41\xcb\x6d\x71\xaf\xb1\xb5\x9a\xcc\x68\xd1\x51\x05\x25\xf9\x15\x85\x6d\xb9\x3c\x59\xea\xc5\x78\x23\x2f\x52\xa7\xfc\x34\xf1\x38\x6e\xea\x9c\x70\xd8\x94\x6a\xa1\x65\x3f\x10\xf6\x11\xf9\xda\x1b\xb6\xde\x7e\x05\xc9\x19\x5c\x96\x3a\x0d\x7b\x58\x5e\xf3\xb2\x80\xaa\x14\x82\xde\xe7\xe8\xc0\x2c\x80\x32\x60\x28\x24\x66\x40\x14\x0b\x01\x67\x49\x0f\xab\x63\x58\x74\x17\x7b\xef\x20\xdd\xd0\xb0\xc5\xd2\xc7\x5c\x2b\x94\x81\x8c\x90\x9c\x48\xdc\xec\x8d\x97\xf5\xf0\x36\xa6\xfa\x40\xfd\xb0\xcd\xb0\x7a\xe2\x8e\x2a\x72\xc6\xed\xb6\xa7\x6d\x39\x61\x84\x45\xd0\xf5\x78\x04\x1d\x8a\x9f\xb6\xf9\x95\x77\xd2\x41\x45\x76\x2a\x3e\xce\xc1\x34\xd4\x41\x37\x45\x1e\x43\x4e\xa0\x8b\xb9\x73\x4d\xd6\x84\xc9\x19\x90\x3c\x87\x52\x6e\x91\x43\x4a\x04\x0a\x58\xe8\x00\x20\x74\x02\x8a\xe0\x9d\xd8\x96\x75\x9e\x69\xb0\x95\x69\x5a\xf3\xf7\x47\xb7\x74\x29\xf1\x99\xb2\x28\x09\xda\x62\x6f\xca\x29\xfc\x3d\x82\x81\xe0\x21\x9a\xcd\xc6\xe2\xf7\x68\xe0\xb6\x3e\x95\x12\xce\xf7\x50\xb2\x10\xa3\x93\xe0\x0a\x1c\xa9\xcb\xfd\xbf\x35\x8e\xbb\x30\x3e\x96\x3f\xe2\xd0\x7b\xde\xbd\xbf\xdf\x4b\x1c\xb4\x82\xbc\x18\x14\x75\xe2\x8d\x05\x93\x30\x63\xd1\x35\x94\x1c\x16\x4f\x8e\x00\xd1\x88\x87\x7a\x9c\x55\x72\xe7\x1c\xce\x2f\xfa\x9e\x68\xc5\xff\x70\x38\xb4\xe2\x8b\x39\x2c\xd4\xaa\x56\x89\xa8\x69\x3e\x44\x4b\xf8\x6a\xd0\x27\x73\xf3\x5f\x6b\xe6\x5e\xe7\xbc\xfb\x97\x24\x50\x11\x46\x53\xa1\x44\x10\x15\xa6\x74\x4d\x53\x73\x88\x54\x05\xc6\x1d\xc9\x69\x16\x50\x14\x62\xa3\xe4\x5c\x17\x32\xbe\x35\x32\x2d\xe6\x76\x5d\x58\x1e\xe8\xb6\x8b\xa9\x1e\x86\x2d\xbc\x73\xf8\x72\x37\x5f\x22\xe7\x51\xc0\x5c\xcb\xb2\x28\xc4\xc6\x1f\xee\x1d\x81\x6b\x1e\x1d\x47\x77\xf8\xd2\xad\x5d\x61\x7a\x42\xda\x56\xc3\x42\xab\x6d\x82\x0d\x6a\x2d\xaf\xf7\x71\xae\x8b\xac\xa5\xcf\x74\xbc\x0c\x9a\xb8\x88\x8e\xdd\x2a\x95\x3d\xfa\x95\xb1\x05\x4a\x64\x1f\x15\x1b\xaa\x6e\x6b\x05\x65\x44\x96\x3c\x6a\x97\x5d\x31\x89\x7c\x4d\x52\xec\x86\x6e\x25\x47\x52\x44\xc1\x9b\x97\xa6\xf9\xca\x2f\x9f\x47\x91\xb2\x9c\x79\x36\x76\xb7\xcd\xce\xde\xba\x7c\x1e\x2d\x45\x93\x04\xfe\x45\xe5\xf6\xb6\xeb\x10\x91\x2c\x33\xfd\x38\x63\x39\x90\xa5\x7e\x1a\xeb\x63\x81\xeb\x5b\x99\x22\x7a\xec\xfd\xda\x44\x65\x1c\xf5\x76\x5d\xb8\x9a\x7a\xba\x94\xb6\x6d\xd4\xfe\xdb\x38\xbf\xb9\x75\xa1\x4f\xb8\x03\xcb\xc8\x7a\x7b\x8f\xb8\x45\xe9\xa9\x2c\x50\x7e\x0e\x95\x83\x4d\x3d\x8d\x9f\xa0\x9a\xe7\x13\xa3\x05\xbc\x3d\xce\x71\x13\xb6\x27\x3b\xec\x32\xaa\xe9\x11\xad\x5f\x1c\x51\xfb\xc5\x23\x7a\xbf\x08\xcf\x7a\xf2\x7a\xd5\xe2\xb9\x15\xa4\x6b\xd3\x0c\xaf\x56\x2f\xfa\x80\x18\x88\x11\x8f\x2b\x1f\xbe\x8d\x70\x7b\x9d\x88\x95\x89\xce\xab\x83\xcd\xe7\xb6\xe7\x94\x44\xa7\x98\xf3\xf7\x31\x5b\x88\xc3\xa0\xad\xe5\x30\xe8\x1a\x07\x2d\xea\x2a\x3b\xf0\x07\x06\x14\xbb\xe7\xa2\x1a\x34\x2d\xa6\x7a\x13\x93\xcd\x8c\xc7\x9a\x16\x4f\x0e\x54\xce\x1e\x17\xce\x10\x27\x62\xcf\xd1\xb5\x68\xfb\x83\xed\xd8\x6d\xf9\x79\xcc\x78\xba\xbd\xfc\x82\x40\xa3\x8c\x53\x89\x6f\xdd\xab\x13\x6b\x8e\x34\xa7\xc8\xe4\x73\xf0\xe3\x73\x5b\xf0\x07\xd8\x4a\x59\xc5\x6e\x40\xcf\xf2\x25\x54\xbc\xcc\xea\x14\x39\xf0\x9a\x49\x5a\x60\x7c\x63\x07\x5a\x45\xc6\xba\x2a\x49\xd2\x9e\x48\x57\x58\xb9\xd7\x58\x36\x73\x7b\x6f\x87\xc7\xbf\x4c\x5a\xf9\x79\xdd\xeb\x28\x7b\xa6\xb7\x11\xcd\x7b\x9b\x7a\x89\xf9\xc2\x89\x6a\x06\x55\x59\x8e\x4c\x9a\xe3\x49\x92\xb7\x58\x94\x3b\x04\x3b\xba\xd2\xc7\x52\x32\xd0\x2d\xb8\x56\x68\xd1\xdb\x98\x3f\xc4\xda\x20\x76\x9b\xb1\xca\xe2\x91\x84\x16\x7e\xf4\xd0\x7f\x41\x17\x75\xaf\xe2\x03\xcd\xfa\xa3\x23\xad\xc6\xee\xa5\xe9\x14\xa0\x82\x72\xba\x77\xe9\x72\x88\xb7\xef\x65\x27\x58\xf8\x92\x8c\x74\x44\xfd\xba\xae\xe4\xde\x84\xb9\x40\x74\xcf\x3f\x92\x2a\x72\x3b\xd3\x75\xbb\xf9\x45\x58\xef\x6b\xf0\xe8\x38\x61\x0e\x25\x08\xb8\xde\xf7\x09\xfa\x3a\xee\xdf\x85\xfc\x7d\xa0\x69\x0a\x52\x85\xb5\x6f\xa7\xee\x85\x57\x93\x9b\x8b\x92\xc7\x3e\xa7\x44\xe0\xb4\xeb\x7b\xd7\xa1\x69\x93\x9c\xd2\x24\x76\x55\xee\x68\xa4\x58\xa9\xc8\x1a\x5c\x1d\x0c\x7a\x82\xbd\x1d\x8d\xed\x9e\x8c\x5d\x34\xdc\xa5\x24\xb4\x44\x77\x8b\x73\xfe\xed\xfc\x7a\xc1\x1f\x96\xce\x4c\xe3\xd7\x31\x73\xf3\x51\x17\x22\x75\x52\x39\x4a\x1d\x86\x38\xa6\xe5\x0e\xf9\x1e\x0a\x9a\x65\x39\x3e\x10\x8e\x90\x21\xc9\x4d\xd7\x46\x6e\xa9\x08\x84\x79\x1c\xd4\xcd\x10\xae\xde\x43\x5b\xde\xbf\xd0\x9f\x04\xa5\xd2\xc4\x2d\x17\x81\x9e\x1e\x0d\xc3\xe1\xeb\x0a\x4d\x8b\xd4\xce\xb7\xdc\x17\x91\x3a\x95\xb1\x2b\x5b\x92\x80\xf6\xea\x0d\x32\x45\x8b\x19\xdc\xef\x61\x53\xae\xec\x2b\xef\xaf\xe1\xf2\x1a\xde\x5c\xdf\xc1\xeb\xcb\xab\xbb\x78\xe6\xc4\x8f\x5f\x95\xd5\x9e\xd3\xcd\x56\xb7\x2e\xf4\x37\x03\xd0\xbe\xf4\x0a\xe6\xbc\x54\x30\xab\x48\xfa\x2b\xb1\x1f\xf6\xdc\xd8\xdf\x36\x47\xdc\x6d\xa9\x80\x35\xcd\x11\x1e\x88\x08\x85\xd1\x05\xbf\x91\x06\x64\x59\xe6\xb1\x5a\xff\x3a\xa3\x92\xb2\x8d\x3e\x21\x43\x57\xe8\x1d\x2b\xae\xa2\xe4\xba\x96\x9a\xd5\x16\x19\xec\xcb\x1a\x38\xae\x78\xcd\x02\x4e\x6e\x0b\x2d\x36\x61\xd9\x6c\x36\xa3\x45\x55\x72\xa9\x3b\xf4\xf3\x75\x21\xe7\xea\x2f\x43\x99\xa8\x04\x33\x9f\xa9\xa7\x0d\x95\xdb\xfa\x3e\x4e\xcb\x22\xd9\x94\xab\xb2\x42\x46\x2a\x9a\x20\xe7\x25\x17\xf3\xe9\x05\x36\xb0\x3f\xbe\x22\x11\x98\xd6\x9c\xca\xfd\x91\xa5\x4a\x81\x23\xd3\xba\x4f\x40\xe4\x29\x9b\x75\x90\xd7\xda\xa9\x93\xd5\x16\x10\x6d\xe3\xe3\xca\x3e\xb7\x59\xcc\xcd\x7b\x13\x41\x8f\xcb\xa5\x61\x61\x31\xd6\x4f\x96\xdd\xe7\x27\x71\xd8\x38\x68\x3f\xf3\xd0\xfb\xb6\xc5\xc2\xa3\x5c\xc6\x09\x1c\xe2\x8e\xf9\xda\xf4\xa7\x1a\x6f\x4a\xa5\x78\x8e\x0a\xcd\x98\xb5\x54\xfe\x17\x1c\x9d\xe9\xe2\x76\x5e\x39\xb7\x71\xe0\x71\x67\x9d\x60\xdb\xf7\xe1\x71\xd7\x35\x9c\x4f\xe0\xbb\x78\x8c\x9f\xf9\x56\xf5\x58\x97\x66\x42\x50\x13\x48\x3d\xcd\x7b\x1b\xdb\x38\x3b\x2f\x5d\x10\x02\x52\xcb\x2d\x32\x69\xfb\x5d\x13\x37\x97\x2d\x11\xba\x34\xda\xa3\x84\x7b\x44\x06\xb4\xe3\x39\x5f\x5a\xa6\xd1\xd2\x75\x47\xa6\x8f\xad\xd3\x90\xba\xc4\x3e\x7d\x56\x13\x9f\x1e\x78\x56\x0f\xca\xd8\xff\x05\x00\x00\xff\xff\xb9\x14\xb8\x74\x05\x2f\x00\x00") +var _templatesServerResponsesGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\xdf\x73\xdb\x36\xf2\x7f\xd7\x5f\xb1\xd5\x37\xed\x88\x1e\x89\xcc\xf7\xe1\x5e\xdc\xba\x33\xd7\x38\x77\x75\xe7\x1a\x7b\x62\xf7\x6e\xe6\x72\x99\x06\x26\x57\x12\x5a\x12\x64\x00\x50\x8e\x4e\xc3\xff\xfd\x06\xbf\x48\x80\x3f\x64\xd9\x6d\xf3\xd4\x3c\xc4\x22\x80\x5d\xec\x2e\x3e\xfb\x03\x4b\x1e\x0e\x90\xe1\x9a\x32\x84\xb9\x40\xbe\x43\xbe\x45\x92\x21\xbf\xaf\x69\x9e\x21\x9f\x43\xd3\xcc\x0e\x07\xa0\x6b\x60\xa5\x84\xf8\x4a\xfc\x95\x73\xb2\x87\xa6\x39\x1c\x40\x62\x51\xe5\x44\x2a\x4a\x5a\x54\x39\x8e\xd2\xc7\x66\x2d\xe6\x02\x07\x54\x39\x4d\x8f\x13\xb1\xcc\xec\xbf\xea\x7e\x76\xd2\x4e\xef\xd9\xca\x1c\x5f\x89\x37\x75\x9e\x93\xfb\x1c\x61\xd5\x34\xb3\x1d\xe1\x70\x38\xc0\x8e\x70\x46\x0a\x84\xf8\xea\x12\x9a\x06\x84\xe4\x94\x6d\x66\x74\xad\xe6\xe2\xb7\x98\x22\xdd\x21\x7f\xa3\x56\x34\x4d\x7c\x38\x40\x45\x44\x4a\x72\xfa\xdf\x96\xe2\x8b\x0b\x60\x34\x87\xc3\x0c\x46\xd8\x5d\x80\xdd\xfc\x6f\x25\x2f\x88\x94\xc8\x8d\x36\xc1\xf3\xe2\xec\xc4\xbd\xa2\xc0\x78\xdd\x39\xbc\xaa\x85\x2c\x0b\x9f\xe5\x59\x6b\xb1\x13\x59\xb7\x36\x1a\xf2\x8a\x6f\xb5\x4d\x16\xd1\xe1\x80\x2c\x53\x4b\xf5\x9f\x99\x36\x6c\x27\x4e\x4f\xf3\xf3\xd3\x54\x7f\x96\xe6\x7f\x90\x42\xd6\x66\x0a\x1c\xe6\xfc\x7b\x2a\x7d\x71\x01\xf3\xb9\x3e\x68\xfe\x10\x7f\xaf\x61\xb6\x88\xe2\x5b\x94\x4a\x8b\x8a\x53\x26\xd7\x30\xff\xf2\xe3\x1c\x62\x2b\xd7\x72\xc8\x24\x9a\xb5\xfb\xf4\x20\xac\x1c\x80\x4a\x2c\x9e\x85\xe2\xf8\x9f\x24\xaf\xf1\xf5\xa7\x8a\xa3\x10\xb4\x64\xd0\x34\xb7\x3d\x2c\x0f\x57\xf4\xa0\x3b\xca\xe3\x09\x00\x1e\x92\x7b\xa7\x36\xb1\xe2\x37\xc1\x6e\x65\xac\x32\x2a\xf7\x13\xe0\x77\x54\xee\xdf\x4d\xec\x01\xb8\x46\xc5\xee\x20\x36\xbe\xe2\x2d\x5c\x00\xa9\x2a\x64\xd9\x84\xe8\x6f\x97\x53\xbc\xfb\xc8\x0b\x80\x37\x05\xba\x7e\x90\x7c\xb5\xa5\x79\x36\x2a\xd7\xbb\xf7\x16\x6e\xeb\x92\xc3\xcf\xcb\x93\xa8\xd4\x29\x71\xc2\x36\x38\x05\x50\x63\x88\x55\x1b\xea\x0c\xa3\xa9\xc4\x73\xd4\x83\x0c\xed\xb3\x12\x90\x4f\x69\x8f\x30\x48\x84\x46\xaa\x1b\xc2\x91\x49\x07\xca\x61\x34\x14\x0f\x64\x13\xff\x50\x52\xf6\xdd\xde\xe0\x65\x71\x92\x61\xb5\x25\x83\xe0\xf2\xaa\xcc\x73\x4c\x25\x2d\x99\xe1\xa3\xa3\x0a\x5d\x43\x8e\x6c\x31\x8c\x37\xf0\x2d\xbc\xd4\x76\xdc\xee\xac\x53\x84\x0b\xde\xbd\x7c\x3f\x03\xa5\xca\x76\xe7\xa1\xef\x09\x21\x6e\xbb\x8b\x66\x00\x4f\xf0\xcb\xcf\x65\x88\x51\x27\x68\xcd\x31\xb1\x40\x58\x23\x8d\xcd\xb5\xa6\x9a\xa4\xf5\x0d\xf8\xbb\x3b\xb0\xf0\xed\x6c\x71\x18\xfe\x0c\x8b\x37\x8e\xa2\x2a\x99\x40\xbf\x6e\x53\x06\x2e\x33\x84\xd5\xff\x43\xd3\x24\x09\x1c\x0e\x5e\xde\x54\x47\xda\x34\x7a\x9e\x0a\x90\x5b\x84\xef\xef\xee\x6e\x20\x55\x03\x1c\x65\xcd\x19\x66\xa0\xdc\x5b\xee\x2b\xed\xb2\x03\xda\x59\x5a\x32\x21\x47\xa7\x0c\x5b\x26\x4d\x46\x31\x52\xf8\x85\xdd\x2c\x39\xb3\x51\xf5\x12\x45\xca\x69\x25\xdb\x50\xdb\xe3\xa5\x03\xc3\x01\xee\xf3\x32\xfd\x35\x2d\x8b\x42\x79\xdd\x80\x48\x01\xf1\x08\xf1\xb6\x2e\x08\xf3\x07\x5d\x98\x9e\x29\x74\x6e\x90\x9f\x3b\xeb\xa9\xd5\x29\x29\x30\x60\x31\x3b\x4b\x66\x13\x46\xb0\x45\x64\x9d\x4a\x07\x33\xba\x06\xfc\xe8\xdb\x7d\x06\xf0\xb3\x90\x44\xd6\xc2\x19\xc5\x2c\x6c\x0b\x36\x13\x13\xad\xff\x09\x75\x52\x67\x87\xc3\xa8\x69\x8e\x1b\xc1\xd9\xd6\x89\x11\xff\x48\x3e\xd1\xa2\x2e\xcc\x98\x7d\x38\x77\x93\xaf\x3f\xa5\x79\x2d\xe8\x0e\xbb\x55\xdf\x04\x62\x79\xe4\xfe\xb0\x66\x4c\x99\xc7\xd8\x3c\x8c\x30\x6e\x57\x7d\xdb\x63\xdc\x4e\x0c\x18\xd7\xb9\xa4\x55\x8e\xd7\x6b\xcb\xdb\x3e\xc3\xf5\x5a\xf3\x0f\x17\x0c\xa8\xc9\xa7\x7f\x20\xdb\xc8\x6d\xab\x31\x98\x67\x4b\xeb\x4d\x8f\x68\x14\x90\x52\x16\x92\x7a\xd3\x7d\xd2\x1b\x5d\x0b\x30\x43\x68\x1f\x0c\x55\x37\x33\x22\xe9\x95\x4a\x5d\x9d\xa0\xfa\xb1\x95\xd3\x4d\x8e\x88\xe9\xd3\x51\x16\xd0\x75\x93\x7d\xba\x9f\x18\xfd\x58\xa3\x47\x6a\x06\xce\x41\xf2\x1a\xfb\x8b\xbf\x27\xe2\x12\xd7\xa4\xce\xa5\x59\x6b\x1f\xce\x83\x88\xfc\x7f\xbb\xb9\x42\xa0\x5b\xe6\xa3\xef\x2c\x31\x10\x1c\xf7\xc5\xf8\xef\xe5\x9d\xf2\xa5\xa6\x81\x0f\xbf\x88\x92\x9d\xcf\x0f\x07\x1b\x34\xbc\x24\xfb\x16\x3f\xd6\x94\xa3\xe2\xb8\x2c\x0b\x95\xe6\x2b\xb9\xef\x0b\x7a\x25\x7e\xb8\xbd\x7e\x63\x2a\x30\xb5\xd0\x94\x24\xed\xaa\xf9\x07\xdf\xd1\x3a\xb7\xb8\x4d\xb7\x58\x10\xc3\xe6\x81\xca\xad\x37\x32\x03\xf8\x6d\xce\xf7\xa7\xe7\xfd\xe9\x79\xcf\xf0\xbc\x19\xc0\x15\x3b\x87\xef\xca\x6c\xaf\x1d\xc8\x9f\xb8\x21\xfb\xbc\x24\x99\x3d\x64\xc2\x32\x58\x68\x17\x31\xa0\x8d\xaf\xc4\x77\x44\xa0\x72\xa9\xc8\x1b\x7b\x55\x16\x55\x8e\x9f\xae\xef\x7f\xc1\x54\x0e\x3a\x04\x76\xd9\xc0\x13\xef\xcb\x6c\xdf\xb9\x5b\xcf\x7f\x54\xd2\x4e\xe0\x0d\x3e\x8c\xbb\x76\xca\x91\x48\x14\x13\x8e\xaf\xfd\x2c\xb3\xe1\x62\x6b\x33\xdd\x4e\x55\x3d\x62\xb6\xae\x59\x3a\xc9\x77\x31\x96\x52\x53\x9b\x48\x5b\xe1\x22\x38\x9b\x08\x38\xe3\x29\x99\xae\x4d\x9d\xf3\xcd\x85\xad\x0f\xc1\x3c\x5f\xc0\x5f\x5e\xbe\xd4\x75\x57\x70\x6b\xd7\x51\xd1\x08\xad\xa2\xe3\x6d\x59\xa0\x0d\x7d\xf6\x50\xd5\xc5\x69\xa1\x82\x47\x02\x94\x51\x49\x8d\x14\x4e\xcf\x40\x79\xab\xb4\xb6\xec\x20\xf3\x6b\x49\xda\x40\xe5\x05\xe2\x55\x3b\x67\xe7\xbd\xb2\xbe\x69\xdc\xaa\x0b\x6f\x8d\x59\xb7\x72\x98\x89\xaf\xc4\x0d\xa7\x05\x95\x74\x87\x63\x57\x59\x8d\xa9\x85\x89\xa0\xaf\x4a\x26\x09\x65\x02\xe2\x7f\x23\x2f\x61\xbe\xf8\xcf\x7c\x0e\x51\x64\xc1\xa3\xc7\xd4\xcf\xe4\x4c\x95\x3e\xeb\x42\x9a\x0a\xb1\x53\x9c\x03\x37\xe1\x5b\xc0\x4f\xac\x20\x5c\x6c\x49\x7e\x87\x9f\xe4\x22\x5a\x02\xc6\x9b\x18\x2e\x89\xc4\xa5\xfe\x5f\xd2\x42\xfd\xaa\x39\xd1\x91\xf4\x2c\x09\xf4\x74\x3a\xe8\x7b\xc6\xa9\x8a\x1c\xd3\x41\xcb\x6d\x71\xaf\xb1\xb5\x9a\xcc\x68\xd1\x51\x05\x25\xf9\x15\x85\x6d\xb9\x3c\x59\xea\xc5\x78\x23\x2f\x52\xa7\xfc\x34\xf1\x38\x6e\xea\x9c\x70\xd8\x94\x6a\xa1\x65\x3f\x10\xf6\x11\xf9\xda\x1b\xb6\xde\x7e\x05\xc9\x19\x5c\x96\x3a\x0d\x7b\x58\x5e\xf3\xb2\x80\xaa\x14\x82\xde\xe7\xe8\xc0\x2c\x80\x32\x60\x28\x24\x66\x40\x14\x0b\x01\x67\x49\x0f\xab\x63\x58\x74\x17\x7b\xef\x20\xdd\xd0\xb0\xc5\xd2\xc7\x5c\x2b\x94\x81\x8c\x90\x9c\x48\xdc\xec\x8d\x97\xf5\xf0\x36\xa6\xfa\x40\xfd\xb0\xcd\xb0\x7a\xe2\x8e\x2a\x72\xc6\xed\xb6\xa7\x6d\x39\x61\x84\x45\xd0\xf5\x78\x04\x1d\x8a\x9f\xb6\xf9\x95\x77\xd2\x41\x45\x76\x2a\x3e\xce\xc1\x34\xd4\x41\x37\x45\x1e\x43\x4e\xa0\x8b\xb9\x73\x4d\xd6\x84\xc9\x19\x90\x3c\x87\x52\x6e\x91\x43\x4a\x04\x0a\x58\xe8\x00\x20\x74\x02\x8a\xe0\x9d\xd8\x96\x75\x9e\x69\xb0\x95\x69\x5a\xf3\xf7\x47\xb7\x74\x29\xf1\x99\xb2\x28\x09\xda\x62\x6f\xca\x29\xfc\x3d\x82\x81\xe0\x21\x9a\xcd\xc6\xe2\xf7\x68\xe0\xb6\x3e\x95\x12\xce\xf7\x50\xd6\x32\x04\xe9\x24\xba\x02\x4f\xea\x92\xff\x6f\x0d\xe4\x2e\x8e\x8f\x25\x90\x38\x74\x9f\x77\xef\xef\xf7\x12\x07\xbd\x20\x2f\x08\x45\x9d\x78\x63\xd1\x24\x4c\x59\x74\x0d\x25\x87\xc5\x93\x43\x40\x34\xe2\xa2\x1e\x67\x95\xdd\x39\x87\xf3\x8b\xbe\x2b\x5a\xf1\x3f\x1c\x0e\xad\xf8\x62\x0e\x0b\xb5\xaa\x55\x22\x6a\x9a\x0f\xd1\x12\xbe\x1a\x34\xca\xdc\xfc\xd7\x9a\xb9\xd7\x3a\xef\xfe\x25\x09\x54\x84\xd1\x54\x28\x11\x44\x85\x29\x5d\xd3\xd4\x1c\x22\x55\x91\x71\x47\x72\x9a\x05\x14\x85\xd8\x28\x39\xd7\x85\x8c\x6f\x8d\x4c\x8b\xb9\x5d\x17\xd6\x07\xba\xef\x62\xca\x87\x61\x0f\xef\x1c\xbe\xdc\xcd\x97\xc8\x79\x14\x30\xd7\xb2\x2c\x0a\xb1\xf1\x87\x7b\x47\xe0\xba\x47\xc7\xe1\x1d\xbe\x75\x6b\x57\x98\xa6\x90\xb6\xd5\xb0\xd2\x6a\xbb\x60\x83\x62\xcb\x6b\x7e\x9c\xeb\x2a\x6b\xe9\x33\x1d\xaf\x83\x26\x6e\xa2\x63\xd7\x4a\x65\x8f\x7e\x69\x6c\x81\x12\xd9\x47\xc5\x86\xaa\xeb\x5a\x41\x19\x91\x25\x8f\xda\x65\x57\x4c\x22\x5f\x93\x14\xbb\xa1\x5b\xc9\x91\x14\x51\xf0\xea\xa5\x69\xbe\xf2\xeb\xe7\x51\xa4\x2c\x67\x9e\x8d\xdd\x75\xb3\xb3\xb7\xae\x9f\x47\x6b\xd1\x24\x81\x7f\x51\xb9\xbd\xed\x5a\x44\x24\xcb\x4c\x43\xce\x58\x0e\x64\xa9\x9f\xc6\x1a\x59\xe0\x1a\x57\xa6\x8a\x1e\x7b\xc1\x36\x51\x1a\x47\xbd\x5d\x17\xae\xa8\x9e\xae\xa5\x6d\x1f\xb5\xff\x3a\xce\xef\x6e\x5d\xe8\x13\xee\xc0\x32\xb2\xde\x5e\x24\x6e\x51\x7a\x2a\x0b\x94\x9f\x43\xe5\x60\x53\x4f\xe3\x27\xa8\xe6\xf9\xc4\x68\x05\x6f\x8f\x73\xdc\x84\xed\xc9\x0e\xdb\x8c\x6a\x7a\x44\xeb\x17\x47\xd4\x7e\xf1\x88\xde\x2f\xc2\xb3\x9e\xbc\x5f\xb5\x78\x6e\x05\xe9\xfa\x34\xc3\xbb\xd5\x8b\x3e\x20\x06\x62\xc4\xe3\xca\x87\xaf\x23\xdc\x5e\x27\x62\x65\xa2\xf5\xea\x60\xf3\xb9\xed\x39\x25\xd1\x29\xe6\xfc\x7d\xcc\x16\xe2\x30\xe8\x6b\x39\x0c\xba\xce\x41\x8b\xba\xca\x0e\xfc\x81\x01\xc5\xee\xb9\xa8\x06\x5d\x8b\xa9\xe6\xc4\x64\x37\xe3\xb1\xae\xc5\x93\x03\x95\xb3\xc7\x85\x33\xc4\x89\xd8\x73\x74\x2d\xda\xfe\x60\x3b\x76\x5b\x7e\x1e\x33\x9e\x6e\x2f\xbf\x20\xd0\x28\xe3\x54\xe2\x5b\xf7\xee\xc4\x9a\x23\xcd\x29\x32\xf9\x1c\xfc\xf8\xdc\x16\xfc\x01\xb6\x52\x56\xb1\x1b\xd0\xb3\x7c\x09\x15\x2f\xb3\x3a\x45\x0e\xbc\x66\x92\x16\x18\xdf\xd8\x81\x56\x91\xb1\xb6\x4a\x92\xb4\x27\xd2\x15\x56\xee\x3d\x96\xcd\xdc\xde\xeb\xe1\xf1\x4f\x93\x56\x7e\x5e\xf7\x5a\xca\x9e\xe9\x6d\x44\xf3\x5e\xa7\x5e\x62\xbe\x70\xa2\x9a\x41\x55\x96\x23\x93\xe6\x78\x92\xe4\x2d\x16\xe5\x0e\xc1\x8e\xae\xf4\xb1\x94\x0c\x74\x0f\xae\x15\x5a\xf4\x36\xe6\x0f\xb1\x36\x88\xdd\x66\xac\xb2\x78\x24\xa1\x85\x5f\x3d\xf4\xdf\xd0\x45\xdd\xbb\xf8\x40\xb3\xfe\xe8\x48\xaf\xb1\x7b\x6b\x3a\x05\xa8\xa0\x9c\xee\xdd\xba\x1c\xe2\xed\x8b\xd9\x09\x16\xbe\x24\x23\x2d\x51\xbf\xae\x2b\xb9\x37\x61\x2e\x10\xdd\xf3\x8f\xa4\x8a\xdc\xce\x74\xdd\x6e\x7e\x11\xd6\xfb\x1a\x3c\x3a\x4e\x98\x43\x09\x02\xae\xf7\x81\x82\xbe\x8f\xfb\x77\x21\x7f\x1f\x68\x9a\x82\x54\x61\xed\xdb\xa9\x7b\xe1\xd5\xe4\xe6\xa2\xe4\xb1\xcf\x29\x11\x38\xed\xfa\xde\x75\x68\xda\x24\xa7\x74\x89\x5d\x95\x3b\x1a\x29\x56\x2a\xb2\x06\x57\x07\x83\x9e\x60\x6f\x47\x63\xdb\x27\x63\x17\x0d\x77\x29\x09\x2d\xd1\xdd\xe2\x9c\x7f\x3b\xbf\x5e\xf0\x87\xa5\x33\xd3\xf8\x75\xcc\xdc\x7c\xd4\x85\x48\x9d\x54\x8e\x52\x87\x21\x8e\x69\xb9\x43\xbe\x87\x82\x66\x59\x8e\x0f\x84\x23\x64\x48\x72\xd3\xb6\x91\x5b\x2a\x02\x61\x1e\x07\x75\x33\x84\xab\xf7\xd0\x96\xf7\x2f\xf4\x37\x41\xa9\x34\x71\xcb\x45\xa0\xa7\x47\xc3\x70\xf8\xba\x42\xd3\x23\xb5\xf3\x2d\xf7\x45\xa4\x4e\x65\xec\xca\x96\x24\xa0\xbd\x7a\x83\x4c\xd1\x62\x06\xf7\x7b\xd8\x94\x2b\xfb\xce\xfb\x6b\xb8\xbc\x86\x37\xd7\x77\xf0\xfa\xf2\xea\x2e\x9e\x39\xf1\xe3\x57\x65\xb5\xe7\x74\xb3\xd5\xbd\x0b\xfd\xd1\x00\xb4\x6f\xbd\x82\x39\x2f\x15\xcc\x2a\x92\xfe\x4a\xec\x97\x3d\x37\xf6\xb7\xcd\x11\x77\x5b\x2a\x60\x4d\x73\x84\x07\x22\x42\x61\x74\xc1\x6f\xa4\x01\x59\x96\x79\xac\xd6\xbf\xce\xa8\xa4\x6c\xa3\x4f\xc8\xd0\x15\x7a\xc7\x8a\xab\x28\xb9\xae\xa5\x66\xb5\x45\x06\xfb\xb2\x06\x8e\x2b\x5e\xb3\x80\x93\xdb\x42\x8b\x4d\x58\x36\x9b\xcd\x68\x51\x95\x5c\xea\x16\xfd\x7c\x5d\xc8\xb9\xfa\xcb\x50\x26\x2a\xc1\xcc\x67\xea\x69\x43\xe5\xb6\xbe\x8f\xd3\xb2\x48\x36\xe5\xaa\xac\x90\x91\x8a\x26\xc8\x79\xc9\xc5\x7c\x7a\x81\x0d\xec\x8f\xaf\x48\x04\xa6\x35\xa7\x72\x7f\x64\xa9\x52\xe0\xc8\xb4\xee\x13\x10\x79\xca\x66\x1d\xe4\xb5\x76\xea\x64\xb5\x05\x44\xdb\xf8\xb8\xb2\xcf\x6d\x16\x73\xf3\xde\x44\xd0\xe4\x72\x69\x58\x58\x8c\xf5\x93\x65\xf7\xfd\x49\x1c\x36\x0e\xda\xef\x3c\xf4\xbe\x6d\xb1\xf0\x28\x97\x71\x02\x87\xb8\x63\xbe\x36\xfd\xad\xc6\x9b\x52\x29\x9e\xa3\x42\x33\x66\x2d\x95\xff\x09\x47\x67\xba\xb8\x9d\x57\xce\x6d\x1c\x78\xdc\x59\x27\xd8\xf6\x7d\x78\xdc\x75\x0d\xe7\x13\xf8\x2e\x1e\xe3\x67\x3e\x56\x3d\xd6\xa5\x99\x10\xd4\x04\x52\x4f\xf3\xde\xc6\x36\xce\xce\x4b\x17\x84\x80\xd4\x72\x8b\x4c\xda\x7e\xd7\xc4\xcd\x65\x4b\x84\x2e\x8d\xf6\x28\xe1\x1e\x91\x01\xed\x78\xce\x97\x96\x69\xb4\x74\xdd\x91\xe9\x63\xeb\x34\xa4\x2e\xb1\x4f\x9f\xd5\xc4\xb7\x07\x9e\xd5\x83\x32\xf6\x7f\x01\x00\x00\xff\xff\xd1\x5c\x66\x10\x06\x2f\x00\x00") func templatesServerResponsesGotmplBytes() ([]byte, error) { return bindataRead( @@ -742,12 +768,12 @@ func templatesServerResponsesGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/server/responses.gotmpl", size: 12037, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb5, 0x1d, 0x82, 0x1f, 0x70, 0xed, 0x78, 0x0, 0x19, 0xe2, 0xd, 0xe5, 0x9b, 0xa9, 0x6, 0x88, 0xd9, 0x2, 0x7a, 0xca, 0x1, 0x6c, 0x8c, 0xb3, 0x34, 0xf1, 0xd3, 0x69, 0xd6, 0x1a, 0x43, 0x81}} + info := bindataFileInfo{name: "templates/server/responses.gotmpl", size: 12038, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4f, 0x3e, 0xa6, 0x40, 0x1a, 0x63, 0xc, 0xe8, 0x7f, 0xd9, 0x98, 0xaf, 0x4f, 0x4f, 0xd3, 0x5f, 0xde, 0xe, 0xa, 0x75, 0x5f, 0x6a, 0x13, 0xd9, 0xfc, 0xd9, 0x64, 0xd4, 0xd4, 0x15, 0x17, 0xd7}} return a, nil } -var _templatesServerServerGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x5c\x7d\x6f\xdb\x38\xd2\xff\xdb\xfe\x14\xb3\x3e\x5c\x56\x2e\x6c\xa9\x2f\xd7\xc5\x5d\x6e\xf3\x00\xd9\x34\x6d\x73\x4d\x5b\xa3\xf6\xee\x3e\x87\xc5\x22\x65\x24\xda\xe6\x13\x99\xd4\x91\x54\x1c\x6f\xe0\xef\xfe\x60\xf8\x22\x51\xb2\x9c\xa4\xb9\xee\xbd\x04\x68\x6d\x51\x43\xf2\x37\x43\xce\x70\x38\x1c\x3a\x49\xe0\x44\x64\x14\x16\x94\x53\x49\x34\xcd\xe0\x72\x03\x0b\x31\x56\x6b\xb2\x58\x50\xf9\x57\x78\xf5\x11\x3e\x7c\x9c\xc1\xe9\xab\xb3\x59\xdc\xef\xf7\x6f\x6f\x81\xcd\x21\x3e\x11\xc5\x46\xb2\xc5\x52\xc3\x78\xbb\x4d\x12\xb8\xbd\x85\x54\xac\x56\x94\xeb\xd6\xbb\xdb\x5b\xa0\x3c\x83\xed\xb6\xdf\xef\x17\x24\xbd\x22\x0b\x8a\xc4\xf1\xf1\xe4\x6c\xe2\x1e\xf1\x1d\x5b\x15\x42\x6a\x88\xfa\xbd\x41\x2a\xb8\xa6\x37\x7a\x80\x5f\xe5\xa6\xd0\x22\xd1\xb9\xc2\x27\x2a\xa5\x90\xe6\x5b\x2e\x16\xf8\xc1\xa9\x76\x1f\xc9\x52\xeb\x02\xbf\x0b\x65\xff\x4f\x14\x5b\x70\x92\xe3\x83\xd2\x32\x15\xfc\xda\x7c\xdd\xf0\xd4\x7f\x26\x44\x8b\x15\x73\x8f\x2a\x25\xb9\x21\xd6\x6c\x45\x07\xfd\x3e\xc0\x60\xc1\xf4\xb2\xbc\x8c\x53\xb1\x4a\x16\x62\x2c\x0a\xca\x49\xc1\x12\x14\xcb\xa0\x0f\xe0\xc4\xf0\xa3\xa2\x6f\xc4\x54\xcb\x32\xd5\xaf\x73\xb2\x50\xb0\xdd\xce\xcd\x67\x58\xfd\xff\xa8\x52\xf4\x3a\xbb\xc2\x76\xcc\x5b\xd7\x00\xca\x65\xbc\xdd\xee\xef\x4c\x96\x1c\xf1\x24\x58\xc9\x48\x24\xec\x77\x12\x76\xd8\x68\x41\x15\xf3\x67\x2f\x92\x02\xcb\x77\x7a\xaa\xeb\xfb\xea\x03\x4f\x87\x82\x62\xbc\x13\x9d\xc8\x09\x5f\xc4\x42\x2e\x92\x9b\x04\xa5\xcd\xa9\x2e\x35\xcb\x8d\xa0\xb0\x45\x33\x78\x0a\xe2\x57\x74\x4e\xca\x5c\x9f\xb9\xe7\xaa\x47\xff\x3e\x78\x31\xec\xf7\x53\xc1\x95\x19\x72\x95\x2e\xe9\x8a\xbe\x9d\xcd\x26\x00\x47\x30\x70\x63\x59\x97\x4e\x7d\xa9\xaa\x8a\x7f\xe4\xec\xc6\x10\x97\x9c\xdd\x0c\xb0\xb5\x6b\x22\x21\xb3\xfd\x4f\x0d\x89\x82\x5f\x7e\xb5\x2c\xf5\xfb\xf3\x92\xa7\xc0\x38\xd3\xd1\x10\x6e\xfb\xbd\x16\xdd\x51\x45\x79\xeb\x04\x14\x2d\x89\x3a\xe3\x8a\xa6\xa5\xa4\x10\x3b\xba\x21\xe2\xee\x05\xb8\x46\x56\x4c\x66\x92\xbb\x4a\xd3\x7b\xaa\x4c\x47\x95\x42\xb8\x4a\x38\xdd\x09\xe3\x0a\xe2\xd3\x1b\x2d\x89\xc7\x64\x19\x6b\xd4\x47\x9e\xeb\xea\xfd\xde\xb6\xbf\xf5\xfa\xc8\x85\xde\x9d\x8c\xdb\xad\x11\x4a\xe4\xc6\xfc\xf4\x26\xcd\xcb\x8c\x4e\x0b\x9a\xda\x91\x51\x05\x4d\x5f\xb3\x9c\x82\xff\x73\xd2\xaa\x86\x7f\xbb\xa5\x9c\x5c\xe6\x34\x3b\x67\x4a\xa3\x7d\x08\x44\x0a\x90\xe6\x94\xf0\xb2\x98\xb1\x15\x15\xa5\x06\x00\x9c\xab\xf1\xab\x52\x12\xcd\x04\xef\x03\x2c\x24\x49\xe9\xbc\xcc\x2b\x8a\x36\xc1\x8a\xdc\xbc\xa5\x24\xa3\x72\xca\x7e\x33\x28\xdc\x44\x8f\x7f\xd8\x68\x8a\x65\x38\xbf\x94\x48\xaf\xa8\x9e\x10\xbd\xf4\xf8\xfa\x00\x4b\xa1\xf4\x2e\x6c\x63\x42\xfc\x1f\xe3\xba\x0f\x90\x1b\xe4\xe7\x6c\xc5\xb4\x2f\xba\xa2\xb4\x38\xce\xd9\xb5\xe9\xb1\x0d\x49\x52\x92\xed\xc5\xbb\x96\x4c\x53\xff\xb6\xf9\xb2\x0f\xa0\x73\xf5\x36\x84\x15\x00\xd3\xb9\x9a\x84\xd8\x3c\x14\x9d\xab\xf3\x10\x60\x50\xfe\x2e\x44\xb9\x0b\x45\xe7\xea\x53\x08\xb5\x93\xe2\xe7\x10\x6f\x27\xc5\x09\x95\x9a\xcd\x59\x4a\x34\x6d\x03\x0e\x5e\xbd\xa3\x9b\xe6\xab\xe3\x46\x3d\xf7\x6a\x58\x2d\x0e\xde\xba\x6c\xb7\xfd\x24\x81\xa9\x79\x3d\xcd\x59\x4a\x7f\x22\x12\x54\x59\x98\x71\x9a\x0b\x69\xc6\xbb\xaf\x37\x05\x05\x65\x5f\xe7\x25\x6d\x6b\x2d\xa7\xeb\x69\xf5\x32\xba\x26\x79\x3d\x09\x47\x50\xc0\x13\xff\x30\x84\x27\x41\x23\xb7\xfd\xde\x93\x02\x8e\x00\xe9\xfb\x3d\x49\x75\x29\x39\x44\x01\xc5\x30\x2a\x86\xa8\x3f\xa6\x8f\x48\x85\x95\x87\x30\xa5\x1a\x7b\x02\xdf\xb2\x59\x79\x4c\x9b\x68\x2c\x6a\xca\xc8\x99\xcc\x78\x5a\xe4\xcc\x54\x19\xc1\x60\x34\x18\x0e\xab\x2e\x39\xcb\xf7\xf6\xf2\x86\xa2\x39\x62\x5c\x53\x39\x27\x29\xbd\xdd\xc2\x2d\xb8\x6a\x9e\xa9\xe8\x09\x9a\x90\x7d\x28\x2d\xc9\xd0\xc1\xac\x6b\x7b\x54\x7f\x13\x8c\x47\x61\x53\x16\x1d\x98\x61\x41\x05\xbf\x6f\x68\x82\xc5\xbb\x69\x41\xdb\xba\x7b\xb4\xa3\xba\xd1\xb3\xa7\xe6\x6f\xb8\xcf\xfa\x60\x85\xd8\x02\xf8\x89\xc8\x49\x74\xe0\xcd\xd1\x08\x06\xf8\x75\x30\x82\x81\xff\xa7\x97\x14\x9c\x43\x62\xac\x96\x9d\x7a\x4c\x70\xd0\x02\x14\x95\xd7\x74\x30\x0c\xcd\x56\xe7\x42\xd7\xef\x99\x2e\x7f\x22\x32\x6a\xce\xa9\xe6\x6a\x30\x82\x83\xb6\xd5\x43\xb9\x19\x13\x4c\x3c\x98\xbc\x32\x88\x5a\x80\x25\x1f\x81\x5e\x32\x05\x29\xe1\x70\x49\x41\xd2\x82\x1a\x6f\x8a\xf0\xcc\x2f\x4b\x86\xd8\xb0\xe2\x6c\x3c\xe3\xd0\xe6\x6c\x30\xec\xf7\x02\x13\xdf\xb1\xdc\x3b\x36\x9a\x43\x17\xed\x60\xf6\x90\xe9\x60\x04\x6d\x06\xff\xa5\x2c\x18\xb4\xde\xea\x18\xa8\xcd\x85\x63\x04\x03\x57\x30\xd6\xb6\x64\x30\x82\x67\x4f\x9f\x18\x6b\x35\xa5\xa9\xe0\xd9\x08\x06\x66\x2d\x81\x82\x4a\x26\x32\x33\x3f\xd7\x4b\x96\x2e\x11\xcd\x9a\x30\x0d\x97\x74\x2e\x24\x85\x2b\x96\xe7\xa8\x09\x2c\xcb\x29\xa4\x82\x73\x9a\x62\xaf\x0a\x21\xed\xe2\x68\xad\x4f\xbe\x97\x79\x99\x87\x48\x5e\x3e\x0a\x89\x5a\x96\x5a\x23\x94\x4c\xac\x9d\x88\x70\x9a\xca\x0a\x89\x41\xd0\x50\xa2\x11\x0c\x56\xe4\x66\xbc\x34\x05\x63\xc5\x7e\xc3\xa1\x33\xde\xb0\x14\xb9\x32\x6d\xac\xc8\x0d\x5b\x95\x2b\xe0\xe5\xea\x92\x4a\x10\x73\xb8\xdc\x68\xaa\x82\xf6\x61\xcd\xf2\xdc\xac\x62\x50\x10\xa9\x10\x01\xbe\x94\xf4\x1f\x25\x55\x1a\x6c\xe3\xdf\x2a\xb8\xa2\x1b\x65\x06\xf6\x1a\x55\x40\x8d\x80\x71\xd4\xcf\x36\x7d\xce\x38\x8d\xe1\x4c\x43\x26\xa8\x32\x5e\x46\x6e\x56\x2a\xd3\x21\x2a\xbe\x98\x37\xe8\x2f\x45\xb6\x19\x0c\xfb\x8d\x39\x6a\x38\xad\x57\x71\x9c\x98\xe6\x61\x5c\x10\xbd\x44\x16\x93\x6b\x22\xd1\xd7\x4d\xb4\xc8\xc4\x18\xe7\x65\x8c\x14\x5e\xd7\xd0\x11\x72\x5e\x00\x4a\xd9\xce\x5b\x10\xbc\xb3\x1f\x74\x0c\x46\x30\xc0\x0f\xac\x9f\x8b\x94\xe4\xfe\x01\x1b\x3b\x9b\xb4\xdb\xb0\x4d\x9c\x71\x6d\xea\xa3\xfd\x1b\xc1\x00\x3f\x06\x23\x78\xea\x6a\x19\xab\x18\xd6\x33\x03\xcf\xbc\x83\x18\xcc\xb4\x51\x43\x53\x08\x48\xc2\x33\xb1\xb2\x52\xde\xe9\x2c\x70\x4e\x10\xab\x79\x1a\x1b\x01\xbb\xbe\x6b\x61\xd7\x23\x2e\x4a\xad\x34\xe1\x66\xa8\x9c\xd8\xf7\xcc\xef\xca\xd1\x19\xc1\x00\xbf\x8f\x09\x3e\x0c\x46\xf0\xc2\x4e\xe9\xf7\x8c\x97\xda\x98\x5b\xaa\xed\x1c\x9a\x9d\x4c\xa0\xa6\x04\xa7\x05\x0a\x19\x26\x69\x4a\x0b\xb4\x06\x01\xb3\x66\x66\x14\xb2\xe4\x54\x41\x86\x53\x0e\xeb\x07\xef\x21\x02\x1a\x2f\x62\x48\x73\x61\x66\x62\x4e\x0a\x2d\x0a\x58\xb1\x6c\x8c\x6a\x91\x0b\x92\x0d\xbb\xa1\x07\x6e\xd8\x08\x06\xf8\x14\xa8\xe4\x8b\xb6\x71\xf0\x6a\x91\xb9\x26\xbc\x12\x6a\xb6\xc2\x6e\xd1\xfb\x31\x1a\xd1\x9c\xac\xdd\x3d\x87\x3e\xde\x08\x06\xe6\xf1\x9f\xec\xdb\xb4\x51\x77\xae\x0a\xc1\x15\xed\x9c\xbd\xce\x85\xc4\x59\x97\xab\xf1\xa3\x27\xb1\x73\x37\x5d\x33\x0f\x9a\xcb\x8f\x9c\xc9\x4d\xec\x81\x57\xe8\xfa\x4e\xeb\x92\x70\x2d\x0f\x8a\x61\x8e\x3b\x10\x2d\xa0\x54\x74\x0f\x92\xfb\x7b\x7b\x47\x37\xae\xc3\x2b\xba\x09\x3b\x2a\x24\xbb\xc6\x4e\xae\xe8\xe6\x01\x1d\x41\xb4\x66\x7a\x89\x43\x56\x10\xa5\x8a\xa5\x24\x8a\x0e\xf7\xf5\x7e\xdc\xc1\x2d\xd9\xc7\x24\x29\xf5\x52\x48\xa6\x37\x9d\xac\x5f\x52\x04\x95\x01\xf6\x0e\xab\x52\x97\x24\x47\x37\xdb\xd4\xea\x1a\xdc\xf3\x86\xdd\xc0\x9e\xbf\xba\xed\x08\x77\x20\x95\x68\xff\xab\x4c\x48\x73\x87\xe4\x78\xf8\x57\x5a\x92\xd6\x06\xcc\x21\xf8\x3d\x0d\x8a\x77\xd3\xad\xc3\x7f\xca\xaf\x3f\x5e\x53\x29\x59\x46\x23\x21\xd9\x02\xfc\xa6\x29\xa3\xf3\xea\xbb\xf1\x03\xe2\x38\xf6\x3b\x1d\xbf\x95\xe8\xf7\x50\x45\x2e\x46\x70\x05\x87\x47\xa8\xfb\x0b\x6a\x69\x6f\xfb\xbd\x1e\x9b\x83\x50\xf1\x1b\xaa\x29\xbf\x8e\xae\x86\xf0\xcd\x11\x0c\x06\xe6\x8d\xdf\xf6\x84\xaf\xfb\xbd\x9e\x09\x56\x60\x35\xec\xda\x52\x1f\x1c\x80\x01\x75\x54\xd5\x75\x55\x33\x3a\x37\xd4\xbe\x25\xc9\x16\xfd\x7a\xff\xa1\x77\xb8\x62\x5c\x5b\x96\xcc\x97\x36\x3f\x8c\xeb\xc7\x33\x73\x3d\xc2\x9d\x1f\xd6\x71\x31\xc4\xf8\x58\x0b\x16\x85\xe4\xc8\x1d\x36\x81\x74\xdf\x1c\xe1\x76\xcf\x56\xed\xcd\x57\x3a\x7e\x5d\x48\xc6\x75\xce\xb1\xc6\x54\x67\x54\xca\x11\x5c\x8d\x60\xc0\xac\x2b\x45\xd0\x98\xb2\xcc\xe9\xe7\xc0\x34\xd5\x13\x2a\x3e\xbd\x61\x3a\x7a\x66\x1e\xb7\x81\x4c\xaf\x3b\x04\xf9\x34\x94\xe3\xd3\xfb\xc5\x18\x6c\xe8\x92\x04\x3e\xd0\xf5\xd4\x7a\x8d\xa9\x44\x57\x5f\x01\xc1\xed\x36\x90\x82\xe1\xfe\x69\x59\xae\x08\x47\x27\x2f\xfe\x40\x56\x14\xb6\x5b\xef\x63\x5e\x96\x81\x43\x98\x0a\x3e\x67\x0b\xb4\xa4\x4c\xdb\x51\xaa\x9a\x8d\xb0\xa1\x27\xb7\xb7\x10\xd7\xa1\xde\xf8\xf6\x16\xad\x6b\x4a\xf2\xb0\xe5\xe3\xc9\xd9\x10\x9e\x38\x30\xb7\xfd\x9e\x42\xa1\x73\xba\x8e\x6c\xd1\xb0\xda\xd0\x75\x06\xba\xcc\x3e\x43\xc5\xa7\xed\x60\xd5\x11\xb4\x77\x45\x48\x76\xd2\x8c\x5b\x1d\xb5\x02\x59\x48\xf2\xa6\x15\xb9\x3a\x6a\xc7\xb2\x90\xe8\x7d\x6b\x07\xdc\x70\xe6\x91\x60\x5a\x47\xae\x8e\x82\x30\x16\xbe\x32\x81\xa2\xa3\x0e\x45\x75\xfe\x2b\xae\x21\x6f\x3f\x4e\x67\x38\x29\x54\x6c\x62\x47\x47\xed\xd9\x6f\x5d\x55\x34\xf5\x93\x8f\x9f\x1c\x65\x18\x4d\x3a\x0a\x83\x5f\xf8\xb2\x0e\x29\x1d\xd5\x41\x30\x7c\x11\x46\x92\x8e\xc2\x10\x18\xbe\x6c\x04\x91\x8e\x1a\x31\x30\x7c\x3d\x3b\x9f\xee\x65\xa6\x72\x67\x2c\xc3\x23\x18\xcc\xce\xa7\x17\x86\xaf\x06\x7f\xb3\xf3\x69\x37\x8b\x95\x23\xf3\xd4\xd5\xad\x39\x9d\x9d\x4f\xc3\x20\xd4\x9e\xee\x9b\x6b\xf4\xc0\xb5\x72\x72\xfa\x69\x76\xf6\xfa\xec\xe4\x78\x76\xda\xd5\xd8\x3b\xba\x79\x40\x7b\xd6\xe7\xf0\x4d\x4e\x3e\x9d\xfd\x74\x3c\x3b\xbd\x78\x77\xfa\xf7\xba\xc9\xe3\x87\x20\x3c\xde\x83\xf1\xb8\x13\x66\x73\x80\x9b\xbe\x80\x23\x09\x87\x39\x5c\xc6\xdd\xeb\xe6\x60\x37\x57\x49\x47\xd2\x1a\xf2\xd6\x42\xd6\x07\x40\x6d\x1c\x77\x87\x75\x00\x54\x6c\x9e\x8e\xaa\xf8\x72\x55\x21\x08\xce\x54\x0f\x3d\x15\xe3\x5e\xd9\x6c\x93\x51\x87\xae\x68\x94\x2e\x89\x89\x61\x95\xa9\xbe\xdd\x1a\xc6\xd1\x8e\x1c\xa1\x59\xc2\x07\x13\x30\x93\x65\xa1\x1b\xf4\x68\x62\xcd\x91\xcf\x08\x9e\xd5\xe1\x37\xd5\xb7\x96\xee\xc4\x1b\xa9\xe3\xc9\x59\x6d\xb1\xac\xc7\x82\x45\xb8\x13\x5e\x12\x9e\xe5\x54\xaa\xb8\x8e\xb6\x39\xeb\xd3\xa8\xee\xe2\x5f\x80\xec\x5b\x64\x95\xdd\xaf\xe2\xbe\xb1\x6b\x0b\x8d\x4b\x58\xd5\xd0\x0f\x0d\xdd\xb6\x8d\xcc\x5a\xb2\x16\x36\x92\x65\x0c\x9d\x00\x92\x83\x3d\x57\xca\xe8\x9c\x71\x7b\x48\x87\xef\x2b\xcc\xf0\x81\xd2\x4c\x39\x67\x32\x25\x79\x8e\x34\xce\x71\x40\x3f\x98\x48\x45\x65\x3c\xc1\x8f\x3b\xd8\x33\x18\xee\x67\x30\x6d\xd2\x77\x70\xe5\x2c\x39\x2e\xbb\xd8\x7d\xe7\x62\x72\x3c\x39\xb3\xb1\x5f\x47\x6c\x47\x1c\xad\xff\x8e\x21\xaf\x8e\x67\xf6\x9e\xba\xc1\xe7\x5c\xf0\xc5\xa1\x8f\x79\x41\x46\x55\x2a\x59\x81\xb2\x3b\xfc\x9d\xc3\x5d\x9f\x83\x60\xd7\xc9\x9d\x67\x22\x77\xc0\x07\xf0\x1c\xb4\x83\x61\x4d\x56\xfe\xc9\x38\x98\x67\xec\x70\xf0\xec\xa9\x6a\x20\x6f\x2f\x79\x8f\x40\xbe\x13\x3d\x7b\x0c\xf4\xbd\x81\xb3\x00\xfa\xcb\x26\xf4\xf7\xf7\x1d\x23\xdd\x3f\x6d\xda\x81\xb7\x26\xf2\xff\xbe\x18\x5c\x1c\x8a\xeb\x3d\xfb\x21\x94\x57\xbf\x17\x38\x26\x77\x7b\x55\x95\xd6\xd1\x5c\x51\x7f\xb6\x1d\xa3\x4d\xe7\xa8\xc4\x5e\xe7\x82\x70\xde\xae\xe2\xed\x0d\xdf\xd5\x08\xab\x00\xe0\xed\x2d\x64\x44\x2d\xa9\x0c\x0d\x85\x0d\x06\x86\x03\x9e\x89\x15\x61\xdc\x72\x71\x0e\x9c\xea\xd8\x9b\x8a\x7e\xbf\x67\xbc\x91\x87\x9a\x0b\x13\x55\xd9\xc5\xdc\x0e\xb0\xd4\x50\xeb\x58\x0c\x50\x7e\x7d\x68\x9d\x98\x10\x9b\x71\x64\x18\xd7\x0f\xd2\x18\x13\x9a\xd9\xed\xfe\x2b\x85\x1b\x2d\x42\xe3\x32\x85\x08\xcf\x5b\x47\xa2\x77\x23\x75\x7f\x0e\x70\x23\xce\xd0\x04\xfe\xe0\x78\x43\x88\xe5\xdd\xde\xb3\xd8\xfb\xc7\x2e\x88\x47\x34\x91\xfc\x5b\x63\x11\xf5\x54\x79\xb1\x6a\xb0\xfa\x69\xef\xc9\xf2\xfd\xac\x36\xc2\x16\x4d\x66\x1f\x19\xb1\x08\x60\xb6\x16\x82\x9f\xf7\x1e\x72\xdf\x8f\xb3\x19\xdc\xf8\x62\xa0\xdd\x71\x8d\x1a\xea\x77\x2d\xa8\x4b\xad\x0b\xeb\x3c\x9c\x03\xb4\xed\x80\xdf\x98\xb4\x8f\xe3\x1f\x30\xdd\x1d\x37\x55\x0c\xf6\x5e\x03\x61\x1d\x9d\x5c\x8d\x60\xbd\xa4\xdc\x98\x53\x77\x4c\x49\x33\x60\xfa\x5b\xb7\x3a\xa0\x3d\x23\x0a\xc6\xe3\xc0\x80\x54\x3b\xa2\x90\x31\xbf\x21\x6a\xe4\x0b\x3c\x48\x4f\x43\xec\x5f\x64\x5d\x1e\x65\x5b\xaa\x2d\x59\x0b\x7c\x2b\xad\xe0\x6b\x2c\x32\xed\x68\xf2\x2e\x5f\x61\x64\xf5\xee\x78\x72\x0d\x3e\xdc\x62\xed\xe7\x01\x37\x84\x5f\x8b\x87\x2b\xba\xe9\x1a\x93\x20\x4e\xfd\x50\xec\xe1\x96\xb3\x8d\xbd\x99\xa0\xf1\xd5\xe4\x4f\xee\x11\x7b\x1d\xe6\x7e\x50\x68\x3b\x18\x87\xe3\xbb\x86\x62\x37\x47\xe6\x8b\x75\xe1\x6b\x2f\x5c\x8d\x7d\xf6\x6e\x86\xce\x5d\xf8\x1a\x93\xe1\x3f\x71\x09\x6b\xf1\x79\x57\x9e\xd1\x03\xf9\xfc\xfa\xeb\x57\x0b\xe3\x5d\x99\x4e\x0f\xc4\xf8\xbb\xac\x5d\xed\xd5\x4a\x55\xcb\x55\x6b\xb5\xea\xcc\x92\x31\x1f\x5f\xc5\x43\xc7\x7d\xea\xae\xea\xde\x93\x52\xf3\x39\x4c\x55\xf4\x5c\x90\x82\x41\xf3\xef\xa1\x01\xde\x7e\xcf\x47\x45\xea\x3f\x94\x49\xfc\xd6\x16\xe3\x7b\x55\xef\xf9\xcd\xdf\xa5\x10\x79\xbf\x57\x05\x88\xaa\xbf\x46\x88\xc8\x12\xe0\xa6\xf1\x55\x45\xc4\xb8\x7e\xf1\xbc\xdf\xab\x62\x45\x34\x83\xb0\xc5\x3a\x86\xd4\x68\xb1\x0a\x22\xb9\x30\xc6\xb9\x58\xcc\x21\x17\x0b\x05\x2b\xaa\x14\xf2\x47\x99\x5e\x52\x09\xd7\x8c\x54\xa1\x98\x52\x51\x89\x44\x28\x49\x61\x5f\xa9\x8d\xd2\x74\x05\x82\x53\x3b\x76\x0d\x1a\x56\x45\x71\x3a\x22\x4d\xd8\x63\x54\x1f\xcf\x10\xb9\x30\xc7\x19\x41\x92\x98\x49\x60\x6d\x87\x66\x0e\x0e\xec\x73\x7c\x6e\xfb\x08\x8e\x22\xc2\xf2\x68\x6e\x9b\x8c\xe3\x78\xd8\xef\x6d\xed\xa4\x41\xa2\x5c\x2c\xe2\x89\x64\x5c\xcf\x5b\x24\x4e\x10\xaf\x89\x26\xf9\xef\x2b\x8a\x24\x81\xd3\x1b\xa6\x95\x5d\x2a\xb8\xe0\xe3\xdf\xa8\x14\xa0\x34\xd1\xa5\x02\x32\xd7\x54\x82\x39\x4f\x61\x7c\xb1\x2b\x37\x0b\xf0\x5f\x25\xb9\xc6\x29\x4d\x4b\x8c\x1e\x49\x97\x18\xa7\x54\x77\x04\x20\xab\xa8\x81\x5e\xda\xe7\xca\x75\x3c\x9e\x9c\xdd\x15\xd9\x33\xcc\xef\xca\xc2\xf6\xf2\x85\x87\x2f\x56\x34\x26\xd0\xda\x92\x00\x98\x67\xf3\x54\x87\x35\x6d\x89\x8d\xb2\x22\x7f\x3b\x51\xda\x3d\x11\x50\x13\x29\x0c\x13\x1a\x3d\xe8\x25\x51\x36\x3f\x2d\xb2\xb1\xb6\x2a\xf7\x12\x15\xd6\x1c\x09\xb9\x10\xdc\xe1\x11\xec\x1e\xf5\x18\xf0\x39\xe5\xae\xb2\x1a\xd6\xe7\x61\xaa\x4a\xf2\x6e\xa6\xc1\x59\xd4\xee\x60\xf0\xba\x3e\x18\xf4\xf4\xee\x6c\xf0\x1a\x5b\x72\x90\xc2\x13\x4e\x2d\x4b\x5a\x1d\xc8\xb9\xb2\x39\xc9\x15\x0d\x23\xa0\x36\x86\x5b\xb0\xae\x31\x92\xd7\x34\x1a\x42\x44\xa5\xb4\xe9\xa5\x7e\x08\xbe\x41\xd9\x05\x76\xd0\xe1\x40\x3a\xe4\xdc\xbe\x88\x86\x7f\x6d\x1f\x39\x82\xcf\xfe\xa4\x52\x7a\x60\xfd\x5e\x92\x80\xa2\xda\xb3\xee\xe3\xc5\x23\xab\x8b\xa8\x93\x0a\xdf\x3b\xb5\xa8\xc6\xac\x6e\xb5\x52\x97\xa0\xac\x57\x77\x24\xa4\x8a\x3f\xd0\x75\x34\x48\x09\xff\x56\xbb\x63\x44\xc3\xf5\x4e\x8f\x44\xa1\xf6\x63\x53\xb6\xcf\x81\x3d\x18\x36\xf3\x6a\x4a\xb5\x5b\x04\x6c\x30\x39\xb6\xe2\xe1\x2c\x1f\x0e\x2d\x1f\xeb\x85\x3f\x11\x54\x1b\x9e\xc6\x3f\x13\xa6\xdf\x48\x51\x16\xc3\x7e\x4f\xf0\x94\x36\x5e\x7e\xe4\x29\x1d\xf6\x7b\xf6\x06\xc8\x07\xa1\xd9\x7c\x13\x05\xc7\x06\xc3\x7e\x6f\x21\x1c\xae\x33\x5f\x18\x61\x2b\x23\x50\x43\x9c\xc9\x66\x8c\xcc\x4c\xfb\xe5\xd7\x27\x66\x89\xb2\xc3\x76\x8b\x48\x9c\xa4\x9a\xb3\xf5\x47\xce\x6e\xcc\x00\x36\x62\x53\x1e\x55\xd0\xc4\xb0\x45\x52\x9f\x22\xfe\x60\xa2\x88\xe6\x08\x2c\x6a\x1d\x2e\xee\x54\x7a\x5b\x29\x57\x35\x68\x76\xac\x18\xd7\xdf\xfd\x29\x6a\x9f\x71\x0e\xe1\x7f\x9c\x32\x34\x9b\x39\xcb\xf2\xe0\x98\xa7\x5d\xcb\x0f\x4f\xa5\xbf\xee\x50\x37\x6c\x62\xe4\xee\x29\x8c\x9c\xba\x46\xe1\xa9\xe7\x70\x68\x46\xd7\x49\x13\x2d\x43\x41\x79\x16\xb9\x82\x11\x84\x0d\x21\x8b\xeb\x45\x7c\x9c\x65\xf6\xe4\x5b\xc5\x66\x25\x1c\x60\x9f\x26\x21\xa1\xeb\x04\x81\x68\x13\x5d\x3c\x4c\x92\x3f\x2a\x84\x10\xf6\xdd\xef\xe1\x28\xa3\xde\x45\x79\xc3\xd9\x1a\x5a\x65\xc9\xe8\x1c\x6d\xee\x22\x7e\x25\x38\x8d\x86\xa6\xcc\xa9\xd9\xe1\x51\x03\x9a\x9b\x8c\x79\x53\xe5\x0e\x0e\xfc\x93\x19\xdd\x53\x29\xad\x78\x4e\x72\x81\xfb\x1d\x23\x6c\xe5\x17\x83\xc1\x1f\xaf\x07\x26\x97\xc0\xf6\xb3\x35\xff\x57\x2c\x6a\x51\x14\x34\x33\xcb\xc0\x63\x59\xdd\x46\x2a\x6e\x44\x45\x9d\xda\x74\x4e\xd6\xb7\xb3\xd9\xc4\x4e\xd6\x3a\x80\xb2\x67\xaa\xd6\x04\x0f\x9e\xa8\x41\x95\xe6\x51\x63\xe3\x9c\xb9\x49\xd8\x3a\x70\x6c\x1e\x3a\x37\x49\xa7\x54\x57\x1b\x2f\xe5\x96\x81\xc8\x4f\xfb\xea\x8d\x99\xf1\x43\x6f\xbf\xc2\xfd\x63\xa5\x09\x2a\x0e\xc3\x47\xc8\xbd\xb9\xd3\x14\x1b\x32\x3f\x59\xa2\x06\xd5\xa8\xd9\x56\x65\xc0\x1e\xa2\x78\x01\x0b\x0f\x53\xbb\xa0\x42\x97\xba\x77\x28\x66\x5d\x63\xe4\x2e\x51\x21\xe0\x00\x3f\xaa\x97\x8c\x86\xb1\xbf\x38\x70\x8f\x7e\xd6\x35\x1f\xab\x9d\xd8\x42\x3d\x65\x77\x91\xdc\xa1\xa5\xce\x5c\xed\x68\x69\xaf\x56\xd2\xc6\xac\x78\xa4\x8a\xee\xd1\x51\x9b\x78\xf3\xa5\x1a\x1a\xb2\x9b\x07\x2c\x6e\x9b\xd3\xe8\x3e\xdd\x9c\xd6\xca\xa9\xee\xd5\x4e\xf5\x08\xf5\x54\x7b\xf4\xb3\xb9\xd9\x6f\x11\xef\xe8\x68\x6b\xdb\xdd\x22\xbf\x53\x4f\xc3\xe8\x49\x53\x55\x5b\xd1\x9e\x96\xb6\xaa\x87\xa9\xab\x0a\xf4\xb5\xd9\xa0\x4b\x46\x7b\xb0\xc6\xaa\x87\xab\x6c\xb3\xc2\x1e\x95\x4d\x12\x38\xe3\xaa\x60\xd2\x1e\xe1\x9b\x1a\x87\x49\x72\x89\x1b\x87\x4b\x49\x52\x7a\xc9\xb8\xb9\xc3\x49\xd2\x25\xa3\x38\xd9\xc6\x05\x95\x73\x9a\xea\xb1\x52\xf9\x38\x27\x97\x6a\xac\x52\x21\xe9\x18\x77\x0b\xe3\x85\x68\x75\x3b\x3b\x9f\xda\xc3\x7c\x38\x82\x03\x9d\xab\xd8\x3e\x19\x7e\x92\x04\x4e\x48\xa9\xa8\x02\xaf\xf2\x2e\xd2\xf8\x46\x7c\xab\x2a\x7f\x2d\x65\xc5\x92\x4a\x55\x32\x4d\xa1\x90\xa8\x7e\x94\xa7\x54\x8d\x5c\x0b\xf6\xcc\x96\x48\x0a\xba\xc4\x1d\x9f\x16\x40\xae\x05\xcb\x80\x68\x4d\xd2\x2b\x15\xc3\x2b\x77\x4a\xb9\x34\x91\x11\x0e\x69\xce\x28\xd7\x2a\xc6\x06\x26\xa6\x41\xa7\x85\xa6\xa3\x29\x76\xa4\x0e\x8d\x3b\xed\xfb\xf8\xc8\xf3\x8d\x01\x96\x96\xf2\x9a\x2a\xd7\xe7\x92\x5c\x53\x20\x4a\xd1\xd5\x65\xbe\x01\xb6\x2a\x72\xba\xa2\x5c\x9b\x98\x85\x72\x35\xbd\x3c\x1b\xd7\x69\x73\xc2\x17\xc9\x42\x24\x5a\x52\x9a\xac\x88\xd2\x54\x26\x4a\xa6\x89\xbb\x5c\x4c\xf3\x9c\x15\x9a\xa5\xd8\xc4\x09\x76\x38\xa9\xb9\x3e\x84\x5f\x7e\x35\x52\xc4\xf2\xb3\x57\xb7\xd5\xf7\xc9\xf3\x97\xdf\x6d\x11\xaf\xcf\x83\xf9\x51\xd1\xf7\x22\xa3\x92\xe3\xff\xf6\xd2\x26\x02\xfa\x51\x51\x58\x99\x72\x13\xf5\xc4\xaf\x15\xc8\x35\xbb\x62\xf1\x4a\xfc\xc6\xf2\x9c\x98\xbb\xb5\xe6\xee\x28\xd3\x9b\xc4\x0a\xe8\x62\xca\x32\x7a\x31\x3b\x9f\xfe\xc1\xb6\x7c\x91\x8a\x55\x41\x34\xbb\x64\x39\xd3\x1b\xec\xe0\x03\xbd\xd1\x13\x29\xb4\x30\x40\x5d\x28\x68\xb0\x7c\x3e\x70\xf6\x3f\x79\x16\x3f\x1b\x6c\x47\x2d\xe1\xac\xd7\xeb\x58\xac\x89\x2a\x4c\xa7\x8c\x67\xf4\x26\x2e\x96\x45\x32\x93\x84\xab\x42\x48\x7d\x71\x4e\x36\x54\x5e\x60\xcb\x36\x6c\x78\x71\xb2\xa4\x44\x5f\x4c\x97\x94\xea\x3f\x7c\x2a\x73\x7a\x31\xbe\xc0\x41\xba\x98\xda\x0b\x63\x17\x53\x2d\x05\x5f\x98\x1a\x22\x15\xb9\x19\x8e\xf7\x8c\xff\x44\xa5\x62\x82\x1f\x22\xef\xb1\x7b\x98\x9d\x4f\x9f\x3d\xf7\x90\x66\x4b\x8a\xc3\x5c\x4f\x39\x55\xdd\x41\x7b\x2d\xe4\x9a\xc8\x0c\xa6\x34\x95\x34\xdd\x1c\x56\xf0\x29\x8f\x51\x72\x05\xcd\x98\x15\x1b\x3e\x25\x8e\xfc\x42\x59\x72\x33\x98\x8d\x09\xf6\xcb\xaf\x25\xe3\xfa\xd9\x77\xd6\xea\x23\xa0\xd9\xf9\xf4\xe2\xf4\xe4\xd5\xdb\x53\xfc\x7f\x7a\x7c\xf1\xf3\xd9\xec\xed\xc5\xf1\xe9\xf4\xe2\xf9\xcb\xef\x2e\xde\x9c\xbc\xbf\x98\xbe\x3d\x7e\xf1\xe7\x3f\x8d\x3a\x2a\x7c\xfa\x32\xf2\x56\xfb\xcf\x9e\xff\xd9\x57\x78\xfe\xf2\xbb\x7b\xdb\xbf\x9f\x3c\x68\xff\xe4\xed\xf1\xc9\xdb\xe3\xe7\x4f\x2f\x26\x1f\xcf\xff\xfe\xec\xc5\xd3\x97\x77\x36\xdf\x4d\x5d\x4d\x6c\x1f\xf3\xb3\x0e\x49\x92\xc0\x65\xc9\xf2\x0c\x4c\x64\x1c\xc7\xc6\x3a\x20\x30\x97\x62\xe5\x83\x18\xa2\xf0\xfa\xe8\xcd\x79\x78\x12\x51\xa5\xfe\x76\xa5\xdc\x05\x89\xb7\x9d\x26\x2d\x0e\xe8\x95\xcf\xfd\x72\xfa\x19\xa6\xd0\xd9\xcc\xd9\xfb\x9b\xf8\xe5\xe9\xaf\x23\xb7\xad\xc6\x36\xce\x05\xc9\xfe\xf7\xe5\xd3\xbf\xbc\xa3\x9b\x09\x61\x32\xda\x1f\x36\x76\x5b\x9d\x2a\x28\xda\x66\x66\x7f\xcd\x61\x55\x67\x74\xc7\x2f\x08\xdc\xd7\xfe\x3b\xba\x79\x48\x17\x7b\x53\x93\x1b\x71\x82\xde\x36\xf0\x62\x3b\xd2\x16\x83\x51\x49\x12\x97\xa1\x12\x86\xa8\x4e\x8e\xc3\x13\x20\x24\x4b\x09\xd6\x1f\x81\xfd\x3c\xb5\xbe\x1a\x13\x66\xb5\x46\xf7\xe2\x35\xcb\xe9\x17\x4b\xf7\xf8\x0b\xe5\xeb\x99\xaf\x41\x74\x89\xa0\x7a\x5b\xb9\x7c\xb6\x64\x22\x44\x8e\xa8\x6f\x5e\x3e\xfd\x4b\xfc\x81\xae\x7d\x99\xf5\x40\x85\x49\x23\xaf\x29\xe3\x63\xe3\x38\xe3\xa3\x7a\x2d\xc5\x6a\x72\xfa\x3e\xb2\x6f\x3d\x8a\x6f\xc4\x55\xb3\xe3\xf9\x4a\xa3\x3f\x2a\xe4\xdc\x84\x4e\xb8\xd0\x36\x45\xaf\x25\xce\x41\xed\x8b\xee\x99\xcf\x66\x71\x3d\x39\x46\x7d\xa8\x01\xdd\x47\x7f\x5c\x9a\x94\x64\x9c\xf5\x9f\xe8\x3f\x4a\x26\xe9\x31\xcf\x7e\xa2\x92\xcd\x37\xae\x41\x2a\x75\xa0\xf6\x29\xc9\x73\x48\x4b\xa5\xc5\x0a\x66\xe7\xd3\x2a\xa2\x47\xb4\x90\xe1\x3e\x64\x76\x3e\x8d\x3a\xfb\x1d\xba\xf9\x95\x53\xde\x4d\xd0\x50\x4c\x17\xbc\x3b\x38\x80\x6e\xda\x37\x54\x37\x12\x6b\x83\x81\x4d\x12\x17\x29\xae\x6c\x14\xe1\x99\x87\xee\xcc\x15\x3a\x2f\x05\x3a\x12\x99\x4b\x00\xa4\x3c\x53\x50\x16\x3e\xf0\xdc\x9e\xcf\x5d\x86\xac\xbe\xb5\xd0\xf9\xde\x64\x10\x07\x24\xc1\x2e\xc3\x1f\x62\x19\x17\xd0\xe6\x74\x7e\x1e\x8f\x5b\xa7\xdb\x9f\x0d\x6c\x57\x7e\x45\x37\x9f\x61\x4d\x25\x6d\xe6\x15\xb8\xfb\x02\xdb\xfe\x3d\xed\x77\x36\xbf\x26\xaa\xab\xb5\xed\x1e\x7e\xdb\xfc\x3c\xa0\x3b\x8b\xfa\x8e\x6e\x92\xc4\x4a\x7f\x69\xb6\x9d\x2e\xec\x4f\x60\x8d\x9e\xc4\x1d\x93\x2d\xe8\xbb\x39\x54\xa6\xb3\x6a\x2a\xda\x0c\xc3\xd9\xf9\xb4\x0e\x33\x26\x09\xac\x4a\xa5\x9d\x23\xa9\x21\xa7\x44\x69\x73\x30\x11\xb6\x22\x24\x14\x84\xb3\x54\xed\xf3\xac\xe3\x1f\x70\x11\xc4\x5d\xdf\x4c\x04\x22\x8a\x86\xfb\xb6\xe4\xaa\xb1\x27\xaf\xb7\xc2\xea\xf1\xbb\x72\xf5\xcf\x6f\xcb\x55\x73\x5f\xae\xbe\xf6\xc6\x5c\xfd\xc7\xed\xcc\x55\xf7\xd6\x1c\xad\xe0\x07\xba\xde\xbb\x85\xec\x36\x68\x55\x58\xba\x92\xfe\x42\x54\x5b\xbd\xa9\x3b\xaf\x8c\xd6\x8b\x11\x1c\xb8\x91\x1b\x5a\xf2\x9f\x09\xd3\xd1\xce\xef\x43\x24\x09\x58\x00\xd5\x4d\x9c\x66\xce\xb2\x4f\xa4\xb6\x6d\x75\x1c\x1b\xba\x53\x81\xea\x97\x2a\x5c\xf6\x76\xf3\x24\x01\xd0\x3c\xe6\x92\x92\x6c\x03\x19\x4e\x7c\x54\x40\x93\xb7\x1d\xa0\x01\xd8\xf6\x83\xea\xdd\xd1\x09\xac\xe3\xb6\x37\x28\x1f\xfb\x7b\x2c\x6c\x6e\x85\x65\x9f\xd6\x44\xf1\x6f\xb5\x3f\xdf\xab\x13\xca\xab\x0b\x23\xce\x9e\xf8\x94\xf9\xe0\x22\x89\xb9\x2d\xe2\xf2\xc9\xab\x6d\x94\xe9\xc7\xe5\x2c\xd9\x94\x8d\xaa\xbf\x46\x69\xab\xdf\xee\xb8\x42\x75\x3a\xd4\x75\xab\xa2\x11\xe4\x73\x7b\xfb\x10\x84\x4e\x0b\x93\x93\x01\x36\x27\xa3\x82\xd1\x2a\xef\x02\xd2\x1d\x00\x69\xa1\x09\x2f\x70\x04\x31\xcd\x0e\x24\x26\x33\xc2\xa5\x2c\xd4\x38\x1a\xa5\xf7\xa0\x08\xe2\x3d\x3b\x38\xee\x0e\xdf\xb6\xb1\xd8\x04\x88\x1d\x30\xcd\xe2\x7b\xd0\x84\xf1\xa4\x1d\x38\xf7\x05\x89\xb7\x77\x4e\x5d\x7f\x42\x83\xb3\x2a\x13\xab\xa9\x48\xaf\xbc\x66\x54\xb7\xfc\x6a\x3b\x17\xdd\x7d\xac\xe1\x26\x73\xc3\xb3\xb6\xf3\x38\xf0\xad\xed\xfc\xb5\x93\xbb\x99\xb1\x7c\xd4\x46\x70\xaf\xd2\x79\xe4\xf9\x5d\x90\x75\x5a\x0c\x46\xa6\xe4\x6f\x82\x71\xd4\xa1\x89\x90\x3a\xf2\x97\xaf\xfc\x1d\xc6\x33\x2d\x48\x64\x2f\x95\x0d\xbf\x8c\x17\xf3\xb1\x1c\x41\x51\xdf\x8b\x5c\x93\x85\xfd\xf1\x9b\xaa\x3b\x0f\x71\x77\x59\xfb\x62\xa9\x39\x7b\xb0\x74\x8f\xee\x8e\x58\xe1\x1e\x9b\xe1\xfb\xfc\xa1\xa2\xac\xec\x57\x75\x79\xea\x4b\xc5\xe9\x2c\xd5\x8e\x44\x5d\xd6\xe6\x63\x84\xaa\x96\x23\x50\x77\x8a\x35\x40\xfb\x15\x24\x1b\x18\xdb\x65\x5d\xe4\x04\xac\x42\x09\x07\x21\xd7\x00\x82\x97\x72\x6b\x85\x39\x72\xc7\xe2\x3b\x8b\x9b\x5f\x11\x7d\x98\xc0\x78\xe5\x39\x25\x1c\xfd\x6e\x49\x95\x28\x65\x4a\x55\xc7\x31\xb9\x5f\x49\x83\xdf\x60\x62\x73\xb0\x3f\xdd\x17\x9f\x88\x55\x41\xcc\xe6\x65\xba\x26\xc5\x19\xd7\x2f\x9e\x47\x07\xf6\x3e\x99\xcf\x06\x32\x57\x07\x9f\x59\xa7\x25\x45\xef\x22\xaa\xef\x9b\x0d\xc3\xb3\xfb\xf6\x0f\x35\xd5\x79\x09\xad\x15\x1d\x9e\x34\x4f\xa0\x47\x3e\x9c\x3a\xd1\x12\x9e\x34\x0f\x8c\x4d\xbf\x49\xe2\xfd\x24\xeb\x7f\x8a\x34\x2d\x25\xe4\x04\x67\x90\xdb\xac\xd4\x67\xde\xb2\xe6\xd8\xd4\x8c\xb4\x80\x42\x52\xd3\x05\x88\x3c\x83\x4b\xba\x24\xd7\x4c\x94\xe8\x0c\xb5\x9d\xb0\x7e\xef\xfb\x71\xcd\x5e\xf3\x24\xfb\x49\x8d\xb2\xdf\xef\xa5\xfa\x06\x37\xe8\x3c\xa5\x66\x9f\xeb\x7e\x72\x31\xfe\x99\xe9\xa5\x33\xa8\x91\x2f\x9b\x7d\x7c\xf5\x31\x1a\xa2\x9f\xd8\xba\x22\x54\x01\xb0\xed\x60\xff\xc6\x29\x98\x33\xa9\x34\xd0\x1b\x9a\x96\x2e\x17\xa0\x90\x74\x5c\xe5\x70\x2d\x85\xb8\x72\xd9\x22\xf1\xc4\x3b\xca\x01\xd7\x75\xba\xd7\xc9\x92\x70\x44\x57\x5f\xf2\xbb\x14\x22\x1f\xda\xa4\x0d\x16\x64\x6c\x38\x2e\x6f\x2b\xbf\xd9\xe8\x90\x2d\xfd\x85\xfd\x1a\xf8\xb2\xce\x7b\xbd\x36\x3f\x76\x95\xa6\x54\x29\x97\x10\xe6\x3d\xda\x90\xaa\x09\xe4\xfb\xb1\xaf\x62\xbc\xd0\xb6\xcf\xab\x9c\xbb\xeb\x19\x49\xf5\xcd\x6e\x8e\x86\x59\x31\xcd\xbe\xdf\x06\xcd\xaa\x34\xcc\xfa\x57\x9b\x84\xf4\xa3\xe1\x17\xcd\x43\xe7\x0d\x5b\x8f\xd7\xfc\x4a\xa2\xe3\xd2\x77\x76\x08\x4d\x0f\xb9\x4e\x48\xea\xf5\x3c\x9b\x5e\x35\x5d\xc0\x27\x1a\x56\xf9\x21\x38\x93\xa1\xe4\x9a\xe5\x80\xfb\xfc\xda\xe9\x34\x1b\x25\x57\x7f\x5e\xe6\xf9\xc6\x5c\xce\xb2\x17\xb3\x5c\x06\x52\x4a\xec\x45\xb3\xe6\x28\xf6\xab\x5e\x0f\x7d\xb7\x38\x64\x1d\xa3\x55\x81\xf3\xdf\x0e\x0e\xe0\xfb\x71\x28\x77\x7f\xe1\xdd\x13\xd4\x89\x59\xbb\xfa\xe2\xd3\xac\xde\x54\xe9\x24\xce\xfe\x29\x20\x3e\x11\x05\x4a\x85\x73\xd8\x7a\xd4\x54\x75\x67\x93\xd5\x0d\x44\xc3\x46\x8e\x22\x76\xef\xaf\x96\x56\xe7\x3a\x55\x6e\x97\x27\x22\x79\x2e\xd6\xca\x65\x70\xdb\xdb\x6c\xc4\xf9\xc9\x8e\x42\x70\xbb\xf9\xdd\xe7\xcf\x07\x09\x31\xbe\x4a\x08\xc3\x4c\xd0\x30\xc7\xaa\x09\x05\x7d\x1d\x6f\x94\x2b\x09\x98\xa4\x1c\xe3\x86\xf8\xdb\x58\xd5\x92\xb9\xd3\x7d\xd8\x40\x34\x84\x28\xdc\x00\x8e\x1e\x9c\xae\x74\x78\x67\xbe\x52\x60\x78\x47\x61\xce\x52\x2d\xdf\x86\xd3\x34\x0a\x56\x13\xd4\x81\x4e\xfe\x82\x3d\x42\x17\x5b\x61\xbd\x7f\x1f\x5b\x8d\x84\x82\x9a\xa9\x6a\x1b\xd2\xc1\x93\xba\x83\xa9\xa0\xde\xbf\x97\x27\xd5\x66\xca\x40\xed\xca\xb3\x72\x4b\xe8\x47\x9b\x72\x55\xb3\x72\x6b\x93\xb9\xe2\x57\x22\xb2\x76\xf8\xb6\x61\x38\x82\x9b\xdf\x55\x6a\x5a\x98\xe0\x7b\xdb\x88\x0c\x38\x47\xc3\x6d\x77\x1b\xd7\x4a\x6d\x14\x0a\xcd\x2c\xe3\x3e\x8b\xaf\xd7\x6c\xab\x32\x97\x55\x7b\x61\x03\x71\x1c\xc3\x60\xd8\x12\x5f\x6d\x89\x76\x05\xf8\x70\xeb\x6d\x05\xbb\x0d\x7e\xcc\x25\x4c\x63\xab\x25\x80\xeb\xe1\xf7\xe3\x3a\x63\xd9\x9a\x04\xf3\x35\x6e\x13\x8f\xc0\xfd\xc2\x71\x3c\x3d\x7b\x73\xf6\x61\xd6\x78\x9e\x9d\x7e\x7a\x8f\xbd\xfd\x7f\x00\x00\x00\xff\xff\x4b\x3c\xa5\x19\x09\x5a\x00\x00") +var _templatesServerServerGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x5c\x7d\x6f\xdb\x38\xd2\xff\xdb\xfe\x14\xb3\x3e\x5c\x56\x2e\x6c\xa9\x2f\xd7\xc5\x5d\x6e\xf3\x00\xd9\x34\x6d\x73\x4d\x5b\xa3\xf6\xee\x3e\x87\xc5\x22\x65\x24\xda\xe6\x13\x99\xd4\x91\x54\x1c\x6f\xe0\xef\xfe\x60\xf8\x22\x51\xb2\x9c\xa4\xb9\xee\xbd\x04\x68\x6d\x51\x43\xf2\x37\x43\xce\x70\x38\x1c\x3a\x49\xe0\x44\x64\x14\x16\x94\x53\x49\x34\xcd\xe0\x72\x03\x0b\x31\x56\x6b\xb2\x58\x50\xf9\x57\x78\xf5\x11\x3e\x7c\x9c\xc1\xe9\xab\xb3\x59\xdc\xef\xf7\x6f\x6f\x81\xcd\x21\x3e\x11\xc5\x46\xb2\xc5\x52\xc3\x78\xbb\x4d\x12\xb8\xbd\x85\x54\xac\x56\x94\xeb\xd6\xbb\xdb\x5b\xa0\x3c\x83\xed\xb6\xdf\xef\x17\x24\xbd\x22\x0b\x8a\xc4\xf1\xf1\xe4\x6c\xe2\x1e\xf1\x1d\x5b\x15\x42\x6a\x88\xfa\xbd\x41\x2a\xb8\xa6\x37\x7a\x80\x5f\xe5\xa6\xd0\x22\xd1\xb9\xc2\x27\x2a\xa5\x90\xe6\x5b\x2e\x16\xf8\xc1\xa9\x76\x1f\xc9\x52\xeb\x02\xbf\x0b\x65\xff\x4f\x14\x5b\x70\x92\xe3\x83\xd2\x32\x15\xfc\xda\x7c\xdd\xf0\xd4\x7f\x26\x44\x8b\x15\x73\x8f\x2a\x25\xb9\x21\xd6\x6c\x45\x07\xfd\x3e\xc0\x60\xc1\xf4\xb2\xbc\x8c\x53\xb1\x4a\x16\x62\x2c\x0a\xca\x49\xc1\x12\x14\xcb\xa0\x0f\xe0\xc4\xf0\xa3\xa2\x6f\xc4\x54\xcb\x32\xd5\xaf\x73\xb2\x50\xb0\xdd\xce\xcd\x67\x58\xfd\xff\xa8\x52\xf4\x3a\xbb\xc2\x76\xcc\x5b\xd7\x00\xca\x65\xbc\xdd\xee\xef\x4c\x96\x1c\xf1\x24\x58\xc9\x48\x24\xec\x77\x12\x76\xd8\x68\x41\x15\xf3\x67\x2f\x92\x02\xcb\x77\x7a\xaa\xeb\xfb\xea\x03\x4f\x87\x82\x62\xbc\x13\x9d\xc8\x09\x5f\xc4\x42\x2e\x92\x9b\x04\xa5\xcd\xa9\x2e\x35\xcb\x8d\xa0\xb0\x45\x33\x78\x0a\xe2\x57\x74\x4e\xca\x5c\x9f\xb9\xe7\xaa\x47\xff\x3e\x78\x31\xec\xf7\x53\xc1\x95\x19\x72\x95\x2e\xe9\x8a\xbe\x9d\xcd\x26\x00\x47\x30\x70\x63\x59\x97\x4e\x7d\xa9\xaa\x8a\x7f\xe4\xec\xc6\x10\x97\x9c\xdd\x0c\xb0\xb5\x6b\x22\x21\xb3\xfd\x4f\x0d\x89\x82\x5f\x7e\xb5\x2c\xf5\xfb\xf3\x92\xa7\xc0\x38\xd3\xd1\x10\x6e\xfb\xbd\x16\xdd\x51\x45\x79\xeb\x04\x14\x2d\x89\x3a\xe3\x8a\xa6\xa5\xa4\x10\x3b\xba\x21\xe2\xee\x05\xb8\x46\x56\x4c\x66\x92\xbb\x4a\xd3\x7b\xaa\x4c\x47\x95\x42\xb8\x4a\x38\xdd\x09\xe3\x0a\xe2\xd3\x1b\x2d\x89\xc7\x64\x19\x6b\xd4\x47\x9e\xeb\xea\xfd\xde\xb6\xbf\xf5\xfa\xc8\x85\xde\x9d\x8c\xdb\xad\x11\x4a\xe4\xc6\xfc\xf4\x26\xcd\xcb\x8c\x4e\x0b\x9a\xda\x91\x51\x05\x4d\x5f\xb3\x9c\x82\xff\x73\xd2\xaa\x86\x7f\xbb\xa5\x9c\x5c\xe6\x34\x3b\x67\x4a\xa3\x7d\x08\x44\x0a\x90\xe6\x94\xf0\xb2\x98\xb1\x15\x15\xa5\x06\x00\x9c\xab\xf1\xab\x52\x12\xcd\x04\xef\x03\x2c\x24\x49\xe9\xbc\xcc\x2b\x8a\x36\xc1\x8a\xdc\xbc\xa5\x24\xa3\x72\xca\x7e\x33\x28\xdc\x44\x8f\x7f\xd8\x68\x8a\x65\x38\xbf\x94\x48\xaf\xa8\x9e\x10\xbd\xf4\xf8\xfa\x00\x4b\xa1\xf4\x2e\x6c\x63\x42\xfc\x1f\xe3\xba\x0f\x90\x1b\xe4\xe7\x6c\xc5\xb4\x2f\xba\xa2\xb4\x38\xce\xd9\xb5\xe9\xb1\x0d\x49\x52\x92\xed\xc5\xbb\x96\x4c\x53\xff\xb6\xf9\xb2\x0f\xa0\x73\xf5\x36\x84\x15\x00\xd3\xb9\x9a\x84\xd8\x3c\x14\x9d\xab\xf3\x10\x60\x50\xfe\x2e\x44\xb9\x0b\x45\xe7\xea\x53\x08\xb5\x93\xe2\xe7\x10\x6f\x27\xc5\x09\x95\x9a\xcd\x59\x4a\x34\x6d\x03\x0e\x5e\xbd\xa3\x9b\xe6\xab\xe3\x46\x3d\xf7\x6a\x58\x2d\x0e\xde\xba\x6c\xb7\xfd\x24\x81\xa9\x79\x3d\xcd\x59\x4a\x7f\x22\x12\x54\x59\x98\x71\x9a\x0b\x69\xc6\xbb\xaf\x37\x05\x05\x65\x5f\xe7\x25\x6d\x6b\x2d\xa7\xeb\x69\xf5\x32\xba\x26\x79\x3d\x09\x47\x50\xc0\x13\xff\x30\x84\x27\x41\x23\xb7\xfd\xde\x93\x02\x8e\x00\xe9\xfb\x3d\x49\x75\x29\x39\x44\x01\xc5\x30\x2a\x86\xa8\x3f\xa6\x8f\x48\x85\x95\x87\x30\xa5\x1a\x7b\x02\xdf\xb2\x59\x79\x4c\x9b\x68\x2c\x6a\xca\xc8\x99\xcc\x78\x5a\xe4\xcc\x54\x19\xc1\x60\x34\x18\x0e\xab\x2e\x39\xcb\xf7\xf6\xf2\x86\xa2\x39\x62\x5c\x53\x39\x27\x29\xbd\xdd\xc2\x2d\xb8\x6a\x9e\xa9\xe8\x09\x9a\x90\x7d\x28\x2d\xc9\xd0\xc1\xac\x6b\x7b\x54\x7f\x13\x8c\x47\x61\x53\x16\x1d\x98\x61\x41\x05\xbf\x6f\x68\x82\xc5\xbb\x69\x41\xdb\xba\x7b\xb4\xa3\xba\xd1\xb3\xa7\xe6\x6f\xb8\xcf\xfa\x60\x85\xd8\x02\xf8\x89\xc8\x49\x74\xe0\xcd\xd1\x08\x06\xf8\x75\x30\x82\x81\xff\xa7\x97\x14\x9c\x43\x62\xac\x96\x9d\x7a\x4c\x70\xd0\x02\x14\x95\xd7\x74\x30\x0c\xcd\x56\xe7\x42\xd7\xef\x99\x2e\x7f\x22\x32\x6a\xce\xa9\xe6\x6a\x30\x82\x83\xb6\xd5\x43\xb9\x19\x13\x4c\x3c\x98\xbc\x32\x88\x5a\x80\x25\x1f\x81\x5e\x32\x05\x29\xe1\x70\x49\x41\xd2\x82\x1a\x6f\x8a\xf0\xcc\x2f\x4b\x86\xd8\xb0\xe2\x6c\x3c\xe3\xd0\xe6\x6c\x30\xec\xf7\x02\x13\xdf\xb1\xdc\x3b\x36\x9a\x43\x17\xed\x60\xf6\x90\xe9\x60\x04\x6d\x06\xff\xa5\x2c\x18\xb4\xde\xea\x18\xa8\xcd\x85\x63\x04\x03\x57\x30\xd6\xb6\x64\x30\x82\x67\x4f\x9f\x18\x6b\x35\xa5\xa9\xe0\xd9\x08\x06\x66\x2d\x81\x82\x4a\x26\x32\x33\x3f\xd7\x4b\x96\x2e\x11\xcd\x9a\x30\x0d\x97\x74\x2e\x24\x85\x2b\x96\xe7\xa8\x09\x2c\xcb\x29\xa4\x82\x73\x9a\x62\xaf\x0a\x21\xed\xe2\x68\xad\x4f\xbe\x97\x79\x99\x87\x48\x5e\x3e\x0a\x89\x5a\x96\x5a\x23\x94\x4c\xac\x9d\x88\x70\x9a\xca\x0a\x89\x41\xd0\x50\xa2\x11\x0c\x56\xe4\x66\xbc\x34\x05\x63\xc5\x7e\xc3\xa1\x33\xde\xb0\x14\xb9\x32\x6d\xac\xc8\x0d\x5b\x95\x2b\xe0\xe5\xea\x92\x4a\x10\x73\xb8\xdc\x68\xaa\x82\xf6\x61\xcd\xf2\xdc\xac\x62\x50\x10\xa9\x10\x01\xbe\x94\xf4\x1f\x25\x55\x1a\x6c\xe3\xdf\x2a\xb8\xa2\x1b\x65\x06\xf6\x1a\x55\x40\x8d\x80\x71\xd4\xcf\x36\x7d\xce\x38\x8d\xe1\x4c\x43\x26\xa8\x32\x5e\x46\x6e\x56\x2a\xd3\x21\x2a\xbe\x98\x37\xe8\x2f\x45\xb6\x19\x0c\xfb\x8d\x39\x6a\x38\xad\x57\x71\x9c\x98\xe6\x61\x5c\x10\xbd\x44\x16\x93\x6b\x22\xd1\xd7\x4d\xb4\xc8\xc4\x18\xe7\x65\x8c\x14\x5e\xd7\xd0\x11\x72\x5e\x00\x4a\xd9\xce\x5b\x10\xbc\xb3\x1f\x74\x0c\x46\x30\xc0\x0f\xac\x9f\x8b\x94\xe4\xfe\x01\x1b\x3b\x9b\xb4\xdb\xb0\x4d\x9c\x71\x6d\xea\xa3\xfd\x1b\xc1\x00\x3f\x06\x23\x78\xea\x6a\x19\xab\x18\xd6\x33\x03\xcf\xbc\x83\x18\xcc\xb4\x51\x43\x53\x08\x48\xc2\x33\xb1\xb2\x52\xde\xe9\x2c\x70\x4e\x10\xab\x79\x1a\x1b\x01\xbb\xbe\x6b\x61\xd7\x23\x2e\x4a\xad\x34\xe1\x66\xa8\x9c\xd8\xf7\xcc\xef\xca\xd1\x19\xc1\x00\xbf\x8f\x09\x3e\x0c\x46\xf0\xc2\x4e\xe9\xf7\x8c\x97\xda\x98\x5b\xaa\xed\x1c\x9a\x9d\x4c\xa0\xa6\x04\xa7\x05\x0a\x19\x26\x69\x4a\x0b\xb4\x06\x01\xb3\x66\x66\x14\xb2\xe4\x54\x41\x86\x53\x0e\xeb\x07\xef\x21\x02\x1a\x2f\x62\x48\x73\x61\x66\x62\x4e\x0a\x2d\x0a\x58\xb1\x6c\x8c\x6a\x91\x0b\x92\x0d\xbb\xa1\x07\x6e\xd8\x08\x06\xf8\x14\xa8\xe4\x8b\xb6\x71\xf0\x6a\x91\xb9\x26\xbc\x12\x6a\xb6\xc2\x6e\xd1\xfb\x31\x1a\xd1\x9c\xac\xdd\x3d\x87\x3e\xde\x08\x06\xe6\xf1\x9f\xec\xdb\xb4\x51\x77\xae\x0a\xc1\x15\xed\x9c\xbd\xce\x85\xc4\x59\x97\xab\xf1\xa3\x27\xb1\x73\x37\x5d\x33\x0f\x9a\xcb\x8f\x9c\xc9\x4d\xec\x81\x57\xe8\xfa\x4e\xeb\x92\x70\x2d\x0f\x8a\x61\x8e\x3b\x10\x2d\xa0\x54\x74\x0f\x92\xfb\x7b\x7b\x47\x37\xae\xc3\x2b\xba\x09\x3b\x2a\x24\xbb\xc6\x4e\xae\xe8\xe6\x01\x1d\x41\xb4\x66\x7a\x89\x43\x56\x10\xa5\x8a\xa5\x24\x8a\x0e\xf7\xf5\x7e\xdc\xc1\x2d\xd9\xc7\x24\x29\xf5\x52\x48\xa6\x37\x9d\xac\x5f\x52\x04\x95\x01\xf6\x0e\xab\x52\x97\x24\x47\x37\xdb\xd4\xea\x1a\xdc\xf3\x86\xdd\xc0\x9e\xbf\xba\xed\x08\x77\x20\x95\x68\xff\xab\x4c\x48\x73\x87\xe4\x78\xf8\x57\x5a\x92\xd6\x06\xcc\x21\xf8\x3d\x0d\x8a\x77\xd3\xad\xc3\x7f\xca\xaf\x3f\x5e\x53\x29\x59\x46\x23\x21\xd9\x02\xfc\xa6\x29\xa3\xf3\xea\xbb\xf1\x03\xe2\x38\xf6\x3b\x1d\xbf\x95\xe8\xf7\x50\x45\x2e\x46\x70\x05\x87\x47\xa8\xfb\x0b\x6a\x69\x6f\xfb\xbd\x1e\x9b\x83\x50\xf1\x1b\xaa\x29\xbf\x8e\xae\x86\xf0\xcd\x11\x0c\x06\xe6\x8d\xdf\xf6\x84\xaf\xfb\xbd\x9e\x09\x56\x60\x35\xec\xda\x52\x1f\x1c\x80\x01\x75\x54\xd5\x75\x55\x33\x3a\x37\xd4\xbe\x25\xc9\x16\xfd\x7a\xff\xa1\x77\xb8\x62\x5c\x5b\x96\xcc\x97\x36\x3f\x8c\xeb\xc7\x33\x73\x3d\xc2\x9d\x1f\xd6\x71\x31\xc4\xf8\x58\x0b\x16\x85\xe4\xc8\x1d\x36\x81\x74\xdf\x1c\xe1\x76\xcf\x56\xed\xcd\x57\x3a\x7e\x5d\x48\xc6\x75\xce\xb1\xc6\x54\x67\x54\xca\x11\x5c\x8d\x60\xc0\xac\x2b\x45\xd0\x98\xb2\xcc\xe9\xe7\xc0\x34\xd5\x13\x2a\x3e\xbd\x61\x3a\x7a\x66\x1e\xb7\x81\x4c\xaf\x3b\x04\xf9\x34\x94\xe3\xd3\xfb\xc5\x18\x6c\xe8\x92\x04\x3e\xd0\xf5\xd4\x7a\x8d\xa9\x44\x57\x5f\x01\xc1\xed\x36\x90\x82\xe1\xfe\x69\x59\xae\x08\x47\x27\x2f\xfe\x40\x56\x14\xb6\x5b\xef\x63\x5e\x96\x81\x43\x98\x0a\x3e\x67\x0b\xb4\xa4\x4c\xdb\x51\xaa\x9a\x8d\xb0\xa1\x27\xcd\x68\xef\x71\xce\x08\x6e\x63\xe2\xdb\x5b\xb4\xb2\x29\xc9\xc3\x1e\x8e\x27\x67\x43\x78\xe2\x40\xdd\xf6\x7b\x0a\x85\xcf\xe9\x3a\xb2\x45\xc3\x6a\x63\xd7\x19\xf0\x32\xfb\x0d\x15\x9f\xb6\x83\x56\x47\xd0\xde\x1d\x21\xd9\x49\x33\x7e\x75\xd4\x0a\x68\x21\xc9\x9b\x56\x04\xeb\xa8\x1d\xd3\x42\xa2\xf7\xad\x9d\x70\xc3\xa9\x47\x82\x69\x1d\xc1\x3a\x0a\xc2\x59\xf8\xca\x04\x8c\x8e\x3a\x14\xd6\xf9\xb1\xb8\x96\xbc\xfd\x38\x9d\xe1\xe4\x50\xb1\x89\x21\x1d\xb5\xb5\xc0\xba\xac\x68\xf2\x27\x1f\x3f\x39\xca\x30\xaa\x74\x14\x06\xc1\xf0\x65\x1d\x5a\x3a\xaa\x83\x61\xf8\x22\x8c\x28\x1d\x85\xa1\x30\x7c\xd9\x08\x26\x1d\x35\x62\x61\xf8\x7a\x76\x3e\xdd\xcb\x4c\xe5\xd6\x58\x86\x47\x30\x98\x9d\x4f\x2f\x0c\x5f\x0d\xfe\x66\xe7\xd3\x6e\x16\x2b\x87\xe6\xa9\xab\x5b\x73\x3a\x3b\x9f\x86\xc1\xa8\x3d\xdd\x37\xd7\xea\x81\x6b\xe5\xe4\xf4\xd3\xec\xec\xf5\xd9\xc9\xf1\xec\xb4\xab\xb1\x77\x74\xf3\x80\xf6\xac\xef\xe1\x9b\x9c\x7c\x3a\xfb\xe9\x78\x76\x7a\xf1\xee\xf4\xef\x75\x93\xc7\x0f\x41\x78\xbc\x07\xe3\x71\x27\xcc\xe6\x00\x37\x7d\x02\x47\x12\x0e\x73\xb8\x9c\xbb\xd7\xcd\xc1\x6e\xae\x96\x8e\xa4\x35\xe4\xad\x05\xad\x0f\x80\xda\x38\xee\x0e\xef\x00\xa8\xd8\x3c\x1d\x55\x71\xe6\xaa\x42\x10\xa4\xa9\x1e\x7a\x2a\xc6\x3d\xb3\xd9\x2e\xa3\x0e\x5d\xd1\x28\x5d\x12\x13\xcb\x2a\x53\x7d\xbb\x35\x8c\xa3\x3d\x39\x42\xf3\x84\x0f\x26\x70\x26\xcb\x42\x37\xe8\xd1\xd4\x9a\xa3\x9f\x11\x3c\xab\xc3\x70\xaa\x6f\x2d\xde\x89\x37\x56\xc7\x93\xb3\xda\x72\x59\xcf\x05\x8b\x70\x47\xbc\x24\x3c\xcb\xa9\x54\x71\x1d\x75\x73\xd6\xa7\x51\xdd\xc5\xc1\x00\xd9\xb7\xc8\x2a\xfb\x5f\xc5\x7f\x63\xd7\x16\x1a\x97\xb0\xaa\xa1\x1f\x1a\xba\x6d\x1b\x99\xb5\x64\x2d\x6c\x24\xcb\x18\x3a\x03\x24\x07\x7b\xbe\x94\xd1\x39\xe3\xf6\xb0\x0e\xdf\x57\x98\xe1\x03\xa5\x99\x72\x4e\x65\x4a\xf2\x1c\x69\x9c\x03\x81\xfe\x30\x91\x8a\xca\x78\x82\x1f\x77\xb0\x67\x30\xdc\xcf\x60\xda\xa4\xef\xe0\xca\x59\x72\x5c\x7e\xb1\xfb\xce\x45\xe5\x78\x72\x66\x63\xc0\x8e\xd8\x8e\x38\x5a\xff\x1d\x43\x5e\x1d\xd3\xec\x3d\x7d\x83\xcf\xb9\xe0\x8b\x43\x1f\xfb\x82\x8c\xaa\x54\xb2\x02\x65\x77\xf8\x3b\x87\xbd\x3e\x07\x41\xaf\x93\x3b\xcf\x46\xee\x80\x0f\xe0\x39\x68\x07\xc5\x9a\xac\xfc\x93\xf1\x30\xcf\xd8\xe1\xe0\xd9\x53\xd5\x40\xde\x5e\xf2\x1e\x81\x7c\x27\x8a\xf6\x18\xe8\x7b\x03\x68\x01\xf4\x97\x4d\xe8\xef\xef\x3b\x4e\xba\x7f\xda\xb4\x03\x70\x4d\xe4\xff\x7d\xb1\xb8\x38\x14\xd7\x7b\xf6\x43\x28\xaf\x7e\x2f\x70\x4c\xee\xf6\xaa\x2a\xad\xa3\xb9\xa2\xfe\x8c\x3b\x46\x9b\xce\x51\x89\xbd\xce\x05\x61\xbd\x5d\xc5\xdb\x1b\xc6\xab\x11\x56\x81\xc0\xdb\x5b\xc8\x88\x5a\x52\x19\x1a\x0a\x1b\x14\x0c\x07\x3c\x13\x2b\xc2\xb8\xe5\xe2\x1c\x38\xd5\xb1\x37\x15\xfd\x7e\xcf\x78\x23\x0f\x35\x17\x26\xba\xb2\x8b\xb9\x1d\x68\xa9\xa1\xd6\x31\x19\xa0\xfc\xfa\xd0\x3a\x31\x21\x36\xe3\xc8\x30\xae\x1f\xa4\x31\x26\x44\xb3\xdb\xfd\x57\x0a\x3b\x5a\x84\xc6\x65\x0a\x11\x9e\xb7\x8e\x46\xef\x46\xea\xfe\x1c\xe0\x46\xbc\xa1\x09\xfc\xc1\x71\x87\x10\xcb\xbb\xbd\x67\xb2\xf7\x8f\x5d\x10\x97\x68\x22\xf9\xb7\xc6\x24\xea\xa9\xf2\x62\xd5\x60\xf5\xd3\xde\x13\xe6\xfb\x59\x6d\x84\x2f\x9a\xcc\x3e\x32\x72\x11\xc0\x6c\x2d\x04\x3f\xef\x3d\xec\xbe\x1f\x67\x33\xc8\xf1\xc5\x40\xbb\xe3\x1b\x35\xd4\xef\x5a\x50\x97\x5a\x17\xd6\x79\x38\x07\x68\xdb\x01\xbf\x31\x69\x1f\xcb\x3f\x60\xba\x3b\x6e\xaa\x58\xec\xbd\x06\xc2\x3a\x3a\xb9\x1a\xc1\x7a\x49\xb9\x31\xa7\xee\xb8\x92\x66\xc0\xf4\xb7\x6e\x75\x40\x7b\x46\x14\x8c\xc7\x81\x01\xa9\x76\x44\x21\x63\x7e\x43\xd4\xc8\x1b\x78\x90\x9e\x86\xd8\xbf\xc8\xba\x3c\xca\xb6\x54\x5b\xb2\x16\xf8\x56\x7a\xc1\xd7\x58\x64\xda\x51\xe5\x5d\xbe\xc2\x08\xeb\xdd\x71\xe5\x1a\x7c\xb8\xc5\xda\xcf\x03\x6e\x08\xbf\x16\x0f\x57\x74\xd3\x35\x26\x41\xbc\xfa\xa1\xd8\xc3\x2d\x67\x1b\x7b\x33\x51\xe3\xab\xc9\x9f\xdc\x23\xf6\x3a\xdc\xfd\xa0\x10\x77\x30\x0e\xc7\x77\x0d\xc5\x6e\xae\xcc\x17\xeb\xc2\xd7\x5e\xb8\x1a\xfb\xec\xdd\x4c\x9d\xbb\xf0\x35\x26\xc3\x7f\xe2\x12\xd6\xe2\xf3\xae\x7c\xa3\x07\xf2\xf9\xf5\xd7\xaf\x16\xc6\xbb\x32\x9e\x1e\x88\xf1\x77\x59\xbb\xda\xab\x95\xaa\x96\xab\xd6\x6a\xd5\x99\x2d\x63\x3e\xbe\x8a\x87\x8e\xfb\xd4\x5d\xd5\xbd\x27\xb5\xe6\x73\x98\xb2\xe8\xb9\x20\x05\x83\xe6\xdf\x97\x06\x7a\xfb\x3d\x1f\x1d\xa9\xff\x50\x36\xf1\x5b\x5b\x8c\xef\x55\xbd\xf7\x37\x7f\x97\x42\xe4\xfd\x5e\x15\x28\xaa\xfe\x1a\xa1\x22\x4b\x80\x9b\xc7\x57\x15\x11\xe3\xfa\xc5\xf3\x7e\xaf\x8a\x19\xd1\x0c\xc2\x16\xeb\x58\x52\xa3\xc5\x2a\x98\xe4\xc2\x19\xe7\x62\x31\x87\x5c\x2c\x14\xac\xa8\x52\x64\x41\x81\x32\xbd\xa4\x12\xae\x19\xa9\x42\x32\xa5\xa2\x12\x89\x50\xa2\xc2\xbe\x52\x1b\xa5\xe9\x0a\x04\xa7\x76\x0c\x1b\x34\xac\x8a\xe6\x74\x44\x9c\xb0\xc7\xa8\x3e\xae\x21\x72\x61\x8e\x37\x82\xa4\x31\x93\xd0\xda\x0e\xd1\x1c\x1c\xd8\xe7\xf8\xdc\xf6\x11\x1c\x4d\x84\xe5\xd1\xdc\x36\x19\xc7\xf1\xb0\xdf\xdb\xda\xc9\x83\x44\xb9\x58\xc4\x13\xc9\xb8\x9e\xb7\x48\x9c\x20\x5e\x13\x4d\xf2\xdf\x57\x14\x49\x02\xa7\x37\x4c\x2b\xbb\x64\x70\xc1\xc7\xbf\x51\x29\x40\x69\xa2\x4b\x05\x64\xae\xa9\x04\x73\xbe\xc2\xf8\x62\x57\x6e\x16\xe0\xbf\x4a\x72\x8d\x53\x9b\x96\x18\x3d\x92\x2e\x31\x4e\xa9\xee\x08\x44\x56\xd1\x03\xbd\xb4\xcf\x95\x0b\x79\x3c\x39\xbb\x2b\xc2\x67\x98\xdf\x95\x85\xed\xe5\x91\x87\x31\x56\x44\x26\xf0\xda\x92\x04\x98\x67\xf3\x54\x87\x39\x6d\x89\x8d\xba\x22\x9f\x3b\x51\xdb\x3d\x11\x51\x13\x39\x0c\x13\x1d\x3d\xf8\x25\x51\x36\x6f\x2d\xb2\xb1\xb7\x2a\x27\x13\x15\xd7\x1c\x11\xb9\x90\xdc\xe1\x11\xec\x1e\xfd\x18\xf0\x39\xe5\xae\xb2\x1a\xd6\xe7\x64\xaa\x4a\xfe\x6e\xa6\xc7\x59\xd4\xee\xc0\xf0\xba\x3e\x30\xf4\xf4\xee\xcc\xf0\x1a\x5b\x72\x90\xc2\x93\x4f\x2d\x4b\x5a\x1d\xd4\xb9\xb2\x39\xc9\x15\x0d\x23\xa2\x36\xa6\x5b\xb0\xae\xb1\x92\xd7\x34\x1a\x42\x44\xa5\xb4\x69\xa7\x7e\x08\xbe\x41\xd9\x05\xf6\xd0\xe1\x40\x3a\xe4\xdc\xbe\x88\x86\x7f\x6d\x1f\x45\x82\xcf\x0a\xa5\x52\x7a\x60\xfd\x5e\x92\x80\xa2\xda\xb3\xee\xe3\xc7\x23\xab\x93\xa8\x9b\x0a\xdf\x3b\xf5\xa8\xc6\xac\x6e\xb5\x52\x9b\xa0\xac\x57\x77\x24\xa4\x8a\x3f\xd0\x75\x34\x48\x09\xff\x56\xbb\xe3\x45\xc3\xf5\x4e\x8f\x44\xa1\x15\xc0\xa6\x6c\x9f\x03\x7b\x60\x6c\xe6\xd5\x94\x6a\xb7\x18\xd8\xe0\x72\x6c\xc5\xc3\x59\x3e\x1c\x5a\x3e\xd6\x0b\x7f\x42\xa8\x36\x3c\x8d\x7f\x26\x4c\xbf\x91\xa2\x2c\x86\xfd\x9e\xe0\x29\x6d\xbc\xfc\xc8\x53\x3a\xec\xf7\xec\xcd\x90\x0f\x42\xb3\xf9\x26\x0a\x8e\x11\x86\xfd\xde\x42\x38\x5c\x67\xbe\x30\xc2\x56\x46\xa0\x86\x38\x93\xcd\x18\x99\x99\xf6\xcb\xaf\x4f\xcc\x52\x65\x87\xed\x16\x91\x38\x49\x35\x67\xeb\x8f\x9c\xdd\x98\x01\x6c\xc4\xaa\x3c\xaa\xa0\x89\x61\x8b\xa4\x3e\x55\xfc\xc1\x44\x15\xcd\x91\x58\xd4\x3a\x6c\xdc\xa9\xf4\xb6\x52\xae\x6a\xd0\xec\x58\x31\xae\xbf\xfb\x53\xd4\x3e\xf3\x1c\xc2\xff\x38\x65\x68\x36\x73\x96\xe5\xc1\xb1\x4f\xbb\x96\x1f\x9e\x4a\x7f\xdd\x61\x6f\xd8\xc4\xc8\xdd\x5f\x18\x39\x75\x8d\xc2\x53\xd0\xe1\xd0\x8c\xae\x93\x26\x5a\x86\x82\xf2\x2c\x72\x05\x23\x08\x1b\x42\x16\xd7\x8b\xf8\x38\xcb\xec\x89\xb8\x8a\xcd\x8a\x38\xc0\x3e\x4d\xa2\x42\xd7\x89\x02\xd1\x26\xda\x78\x98\x24\x7f\x54\x08\x21\xec\xbb\xdf\xc3\x51\x46\xbd\x8b\xf2\x86\xf3\x35\xb4\xca\x92\xd1\x39\xda\xde\x45\xfc\x4a\x70\x1a\x0d\x4d\x99\x53\xb3\xc3\xa3\x06\x34\x37\x19\xf3\xa6\xca\x1d\x1c\xf8\x27\x33\xba\xa7\x52\x5a\xf1\x9c\xe4\x02\xf7\x3f\x46\xd8\xca\x2f\x0a\x83\x3f\x5e\x0f\x4c\x8e\x81\xed\x67\x6b\xfe\xaf\x58\xd4\xa2\x28\x68\x66\x96\x83\xc7\xb2\xba\x8d\x54\xdc\x88\x92\x3a\xb5\xe9\x9c\xac\x6f\x67\xb3\x89\x9d\xac\x75\x40\x65\xcf\x54\xad\x09\x1e\x3c\x51\x83\x2a\xcd\xa3\xc7\xc6\xb9\x73\x93\xb0\x75\x00\xd9\x3c\x84\x6e\x92\x4e\xa9\xae\x36\x62\xca\x2d\x03\x91\x9f\xf6\xd5\x1b\x33\xe3\x87\xde\x7e\x85\xfb\xc9\x4a\x13\x54\x1c\x86\x93\x90\x7b\x73\xd7\x29\x36\x64\x7e\xb2\x44\x0d\xaa\x51\xb3\xad\xca\x80\x3d\x44\xf1\x02\x16\x1e\xa6\x76\x41\x85\x2e\x75\xef\x50\xcc\xba\xc6\xc8\x5d\xae\x42\xc0\x01\x7e\x54\x2f\x19\x0d\x63\x7f\xa1\xe0\x1e\xfd\xac\x6b\x3e\x56\x3b\xb1\x85\x7a\xca\xee\x22\xb9\x43\x4b\x9d\xb9\xda\xd1\xd2\x5e\xad\xa4\x8d\x59\xf1\x48\x15\xdd\xa3\xa3\x36\x21\xe7\x4b\x35\x34\x64\x37\x0f\x58\xdc\x36\xa7\xd1\x7d\xba\x39\xad\x95\x53\xdd\xab\x9d\xea\x11\xea\xa9\xf6\xe8\x67\x73\xf3\xdf\x22\xde\xd1\xd1\xd6\x36\xbc\x45\x7e\xa7\x9e\x86\xd1\x94\xa6\xaa\xb6\xa2\x3f\x2d\x6d\x55\x0f\x53\x57\x15\xe8\x6b\xb3\x41\x97\xa4\xf6\x60\x8d\x55\x0f\x57\xd9\x66\x85\x3d\x2a\x9b\x24\x70\xc6\x55\xc1\xa4\x3d\xd2\x37\x35\x0e\x93\xe4\x12\x37\x10\x97\x92\xa4\xf4\x92\x71\x73\xb7\x93\xa4\x4b\x46\x71\xb2\x8d\x0b\x2a\xe7\x34\xd5\x63\xa5\xf2\x71\x4e\x2e\xd5\x58\xa5\x42\xd2\x31\xee\x1a\xc6\x0b\xd1\xea\x76\x76\x3e\xb5\x87\xfb\x70\x04\x07\x3a\x57\xb1\x7d\x32\xfc\x24\x09\x9c\x90\x52\x51\x05\x5e\xe5\x5d\xe4\xf1\x8d\xf8\x56\x55\xfe\x5a\xca\x8a\x25\x95\xaa\x64\x9a\x42\x21\x51\xfd\x28\x4f\xa9\x1a\xb9\x16\xec\x19\x2e\x91\x14\x74\x89\x3b\x3f\x2d\x80\x5c\x0b\x96\x01\xd1\x9a\xa4\x57\x2a\x86\x57\xee\xd4\x72\x69\x22\x25\x1c\xd2\x9c\x51\xae\x55\x8c\x0d\x4c\x4c\x83\x4e\x0b\x4d\x47\x53\xec\x48\x1d\x1a\x77\xda\xf7\xf1\x91\xe7\x1b\x03\x2c\x2d\xe5\x35\x55\xae\xcf\x25\xb9\xa6\x40\x94\xa2\xab\xcb\x7c\x03\x6c\x55\xe4\x74\x45\xb9\x36\x31\x0c\xe5\x6a\x7a\x79\x36\xae\xd9\xe6\x84\x2f\x92\x85\x48\xb4\xa4\x34\x59\x11\xa5\xa9\x4c\x94\x4c\x13\x77\xe9\x98\xe6\x39\x2b\x34\x4b\xb1\x89\x13\xec\x70\x52\x73\x7d\x08\xbf\xfc\x6a\xa4\x88\xe5\x67\xaf\x6e\xab\xef\x93\xe7\x2f\xbf\xdb\x22\x5e\x9f\x17\xf3\xa3\xa2\xef\x45\x46\x25\xc7\xff\xed\x65\x4e\x04\xf4\xa3\xa2\xb0\x32\xe5\x26\x0a\x8a\x5f\x2b\x90\x6b\x76\xc5\xe2\x95\xf8\x8d\xe5\x39\x31\x77\x6e\xcd\x9d\x52\xa6\x37\x89\x15\xd0\xc5\x94\x65\xf4\x62\x76\x3e\xfd\x83\x6d\xf9\x22\x15\xab\x82\x68\x76\xc9\x72\xa6\x37\xd8\xc1\x07\x7a\xa3\x27\x52\x68\x61\x80\xba\xd0\xd0\x60\xf9\x7c\xe0\xec\x7f\xf2\x2c\x7e\x36\xd8\x8e\x5a\xc2\x59\xaf\xd7\xb1\x58\x13\x55\x98\x4e\x19\xcf\xe8\x4d\x5c\x2c\x8b\x64\x26\x09\x57\x85\x90\xfa\xe2\x9c\x6c\xa8\xbc\xc0\x96\x6d\x18\xf1\xe2\x64\x49\x89\xbe\x98\x2e\x29\xd5\x7f\xf8\x54\xe6\xf4\x62\x7c\x81\x83\x74\x31\xb5\x17\xc9\x2e\xa6\x5a\x0a\xbe\x30\x35\x44\x2a\x72\x33\x1c\xef\x19\xff\x89\x4a\xc5\x04\x3f\x44\xde\x63\xf7\x30\x3b\x9f\x3e\x7b\xee\x21\xcd\x96\x14\x87\xb9\x9e\x72\xaa\xba\x9b\xf6\x5a\xc8\x35\x91\x19\x4c\x69\x2a\x69\xba\x39\xac\xe0\x53\x1e\xa3\xe4\x0a\x9a\x31\x2b\x36\x7c\x4a\x1c\xf9\x85\xb2\xe4\x66\x30\x1b\x13\xec\x97\x5f\x4b\xc6\xf5\xb3\xef\xac\xd5\x47\x40\xb3\xf3\xe9\xc5\xe9\xc9\xab\xb7\xa7\xf8\xff\xf4\xf8\xe2\xe7\xb3\xd9\xdb\x8b\xe3\xd3\xe9\xc5\xf3\x97\xdf\x5d\xbc\x39\x79\x7f\x31\x7d\x7b\xfc\xe2\xcf\x7f\x1a\x75\x54\xf8\xf4\x65\xe4\xad\xf6\x9f\x3d\xff\xb3\xaf\xf0\xfc\xe5\x77\xf7\xb6\x7f\x3f\x79\xd0\xfe\xc9\xdb\xe3\x93\xb7\xc7\xcf\x9f\x5e\x4c\x3e\x9e\xff\xfd\xd9\x8b\xa7\x2f\xef\x6c\xbe\x9b\xba\x9a\xd8\x3e\x06\x68\x1d\x92\x24\x81\xcb\x92\xe5\x19\x98\x48\x39\x8e\x8d\x75\x40\x60\x2e\xc5\xca\x07\x33\x44\xe1\xf5\xd1\x9b\xf3\xf0\x64\xa2\x4a\x09\xee\x4a\xc1\x0b\x12\x72\x3b\x4d\x5a\x1c\xd0\x2b\x9f\x0b\xe6\xf4\x33\x4c\xa9\xb3\x19\xb5\xf7\x37\xf1\xcb\xd3\x5f\x47\x6e\x5b\x8d\x6d\x9c\x0b\x92\xfd\xef\xcb\xa7\x7f\x79\x47\x37\x13\xc2\x64\xb4\x3f\x8c\xec\xb6\x3a\x55\x90\xb4\xcd\xcc\xfe\x9a\xc3\xaa\xce\xe8\x8e\x5f\x16\xb8\xaf\xfd\x77\x74\xf3\x90\x2e\xf6\xa6\x2c\x37\xe2\x04\xbd\x6d\xe0\xc5\x76\xa4\x31\x06\xa3\x92\x24\x2e\x63\x25\x0c\x55\x9d\x1c\x87\x27\x42\x48\x96\x12\xac\x3f\x02\xfb\x79\x6a\x7d\x35\x26\xcc\x6a\x8d\xee\xc5\x6b\x96\xd3\x2f\x96\xee\xf1\x17\xca\xd7\x33\x5f\x83\xe8\x12\x41\xf5\xb6\x72\xf9\x6c\xc9\x44\x88\x1c\x51\xdf\xbc\x7c\xfa\x97\xf8\x03\x5d\xfb\x32\xeb\x81\x0a\x93\x5e\x5e\x53\xc6\xc7\xc6\x71\xc6\x47\xf5\x5a\x8a\xd5\xe4\xf4\x7d\x64\xdf\x7a\x14\xdf\x88\xab\x66\xc7\xf3\x95\x46\x7f\x54\xc8\xb9\x09\x9d\x70\xa1\x6d\xca\x5e\x4b\x9c\x83\xda\x17\xdd\x33\x9f\xcd\xe2\x7a\x72\x8c\xfa\x50\x03\xba\x8f\xfe\xb8\x34\x29\xca\x38\xeb\x3f\xd1\x7f\x94\x4c\xd2\x63\x9e\xfd\x44\x25\x9b\x6f\x5c\x83\x54\xea\x40\xed\x53\x92\xe7\x90\x96\x4a\x8b\x15\xcc\xce\xa7\x55\x44\x8f\x68\x21\xc3\x7d\xc8\xec\x7c\x1a\x75\xf6\x3b\x74\xf3\x2b\xa7\xbc\x9b\xa0\xa1\x98\x2e\x78\x77\x70\x00\xdd\xb4\x6f\xa8\x6e\x24\xda\x06\x03\x9b\x24\x2e\x62\x5c\xd9\x28\xc2\x33\x0f\xdd\x99\x2b\x74\x5e\x0a\x74\x24\x32\x97\x10\x48\x79\xa6\xa0\x2c\x7c\x00\xba\x3d\x9f\xbb\x0c\x59\x7d\x9b\xa1\xf3\xbd\xc9\x28\x0e\x48\x82\x5d\x86\x3f\xd4\x32\x2e\xa0\xcd\xf1\xfc\x3c\x1e\xb7\x4e\xbb\x3f\x1b\xd8\xae\xfc\x8a\x6e\x3e\xc3\x9a\x4a\xda\xcc\x33\x70\xf7\x08\xb6\xfd\x7b\xda\xef\x6c\x7e\x4d\x54\x57\x6b\xdb\x3d\xfc\xb6\xf9\x79\x40\x77\x16\xf5\x1d\xdd\x24\x89\x95\xfe\xd2\x6c\x3b\x5d\xf8\x9f\xc0\x1a\x3d\x89\x3b\x26\x5b\xd0\x77\x73\xa8\x4c\x67\xd5\x54\xb4\x19\x87\xb3\xf3\x69\x1d\x66\x4c\x12\x58\x95\x4a\x3b\x47\x52\x43\x4e\x89\xd2\xe6\x80\x22\x6c\x45\x48\x28\x08\x67\xa9\xda\xe7\x59\xc7\x3f\xe0\x22\x88\xbb\xbe\x99\x08\x44\x14\x0d\xf7\x6d\xc9\x55\x63\x4f\x5e\x6f\x85\xd5\xe3\x77\xe5\xea\x9f\xdf\x96\xab\xe6\xbe\x5c\x7d\xed\x8d\xb9\xfa\x8f\xdb\x99\xab\xee\xad\x39\x5a\xc1\x0f\x74\xbd\x77\x0b\xd9\x6d\xd0\xaa\xb0\x74\x25\xfd\x85\xa8\xb6\x7a\x53\x77\x6e\x19\xad\x17\x23\x38\x70\x23\x37\xb4\xe4\x3f\x13\xa6\xa3\x9d\xdf\x8d\x48\x12\xb0\x00\xaa\x1b\x3a\xcd\x1c\x66\x9f\x58\x6d\xdb\xea\x38\x3e\x74\xa7\x02\xd5\x2f\x58\xb8\x6c\xee\xe6\x49\x02\xa0\x79\xcc\x25\x25\xd9\x06\x32\x9c\xf8\xa8\x80\x26\x8f\x3b\x40\x03\xb0\xed\x07\xd5\xbb\xa3\x13\x58\xc7\x6d\x6f\x50\x3e\xf6\x77\x5a\xd8\xdc\x0a\xcb\x3e\xad\x89\xe2\xdf\x6a\x7f\xce\x57\x27\x98\x57\x17\x48\x9c\x3d\xf1\x29\xf4\xc1\xc5\x12\x73\x7b\xc4\xe5\x97\x57\xdb\x28\xd3\x8f\xcb\x61\xb2\x29\x1c\x55\x7f\x8d\xd2\x56\xbf\xdd\x71\x85\xea\x74\xa8\xeb\x96\x45\x23\xc8\xe7\xf6\xf6\x21\x08\x9d\x16\x26\x47\x03\x6c\x8e\x46\x05\xa3\x55\xde\x05\xa4\x3b\x00\xd2\x42\x13\x5e\xe8\x08\x62\x9a\x1d\x48\x4c\xa6\x84\x4b\x61\xa8\x71\x34\x4a\xef\x41\x11\xc4\x7b\x76\x70\xdc\x1d\xbe\x6d\x63\xb1\x09\x11\x3b\x60\x9a\xc5\xf7\xa0\x09\xe3\x49\x3b\x70\xee\x0b\x12\x6f\xef\x9c\xba\xfe\x84\x06\x67\x55\x26\x56\x53\x91\x5e\x79\xcd\xa8\x6e\xff\xd5\x76\x2e\xba\xfb\x58\xc3\x4d\xe6\x86\x67\x6d\xe7\x71\xe0\x5b\xdb\xf9\x6b\x27\x77\x33\x83\xf9\xa8\x8d\xe0\x5e\xa5\xf3\xc8\xf3\xbb\x20\xeb\xb4\x18\x8c\x4c\xc9\xdf\x04\xe3\xa8\x43\x13\x21\x75\xe4\x2f\x63\xf9\xbb\x8d\x67\x5a\x90\xc8\x5e\x32\x1b\x7e\x19\x2f\xe6\x63\x39\x82\xa2\xbe\x2f\xb9\x26\x0b\xfb\xa3\x38\x55\x77\x1e\xe2\xee\xb2\xf6\xc5\x52\x73\xf6\x60\xe9\x1e\xdd\x9d\xb1\xc2\x3d\x36\xc3\xf7\xf9\x43\x45\x59\xd9\xaf\xea\x32\xd5\x97\x8a\xd3\x59\xaa\x1d\x89\xba\x2c\xce\xc7\x08\x55\x2d\x47\xa0\xee\x14\x6b\x80\xf6\x2b\x48\x36\x30\xb6\xcb\xba\xc8\x09\x58\x85\x12\x0e\x42\xae\x01\x04\x2f\xe5\xd6\x0a\x73\xe4\x8e\xc5\x77\x16\x37\xbf\x22\xfa\x30\x81\xf1\xca\x73\x4a\x38\xfa\xdd\x92\x2a\x51\xca\x94\xaa\x8e\x63\x72\xbf\x92\x06\xbf\xcd\xc4\xe6\x60\x7f\xd2\x2f\x3e\x11\xab\x82\x98\xcd\xcb\x74\x4d\x8a\x33\xae\x5f\x3c\x8f\x0e\xec\xfd\x32\x9f\x15\x64\xae\x12\x3e\xb3\x4e\x4b\x8a\xde\x45\x54\xdf\x3f\x1b\x86\x67\xf7\xed\x1f\x70\xaa\xf3\x12\x5a\x2b\x3a\x3c\x69\x9e\x40\x8f\x7c\x38\x75\xa2\x25\x3c\x69\x1e\x18\x9b\x7e\x93\xc4\xfb\x49\xd6\xff\x14\x69\x5a\x4a\xc8\x09\xce\x20\xb7\x59\xa9\xcf\xbc\x65\xcd\xb1\xa9\x19\x69\x01\x85\xa4\xa6\x0b\x10\x79\x06\x97\x74\x49\xae\x99\x28\xd1\x19\x6a\x3b\x61\xfd\xde\xf7\xe3\x9a\xbd\xe6\x49\xf6\x93\x1a\x65\xbf\xdf\x4b\xf5\x0d\x6e\xd0\x79\x4a\xcd\x3e\xd7\xfd\x14\x63\xfc\x33\xd3\x4b\x67\x50\x23\x5f\x36\xfb\xf8\xea\x63\x34\x44\x3f\xb1\x75\x65\xa8\x02\x60\xdb\xc1\xfe\x8d\x53\x30\x67\x52\x69\xa0\x37\x34\x2d\x5d\x2e\x40\x21\xe9\xb8\xca\xe5\x5a\x0a\x71\xe5\xb2\x45\xe2\x89\x77\x94\x03\xae\xeb\xb4\xaf\x93\x25\xe1\x88\xae\xbe\xf4\x77\x29\x44\x3e\xb4\x49\x1b\x2c\xc8\xd8\x70\x5c\xde\x56\x7e\xb3\xd1\x21\x5b\xfa\x0b\xfb\x35\xf0\x65\x9d\xf7\x7a\x6d\x7e\x04\x2b\x4d\xa9\x52\x2e\x31\xcc\x7b\xb4\x21\x55\x13\xc8\xf7\x63\x5f\xc5\x78\xa1\x6d\x9f\x57\x39\x77\xd7\x33\x92\xea\x9b\xdd\x1c\x0d\xb3\x62\x9a\x7d\xbf\x0d\x9a\x55\x69\x99\xf5\xaf\x39\x09\xe9\x47\xc3\x2f\x9a\x87\xce\x1b\xb6\x1e\xaf\xf9\xf5\x44\xc7\xa5\xef\xec\x10\x9a\x1e\x72\x9d\x98\xd4\xeb\x79\x36\xbd\x6a\xba\x80\x4f\x34\xac\xf2\x43\x70\x26\x43\xc9\x35\xcb\x01\xf7\xf9\xb5\xd3\x69\x36\x4a\xae\xfe\xbc\xcc\xf3\x8d\xb9\xac\x65\x2f\x6a\xb9\x4c\xa4\x94\xd8\x8b\x67\xcd\x51\xec\x57\xbd\x1e\xfa\x6e\x71\xc8\x3a\x46\xab\x02\xe7\xbf\x1d\x1c\xc0\xf7\xe3\x50\xee\xfe\x22\xbc\x27\xa8\x13\xb4\x76\xf5\xc5\xa7\x5b\xbd\xa9\xd2\x49\x9c\xfd\x53\x40\x7c\x22\x0a\x94\x0a\xe7\xb0\xf5\xa8\xa9\xea\xce\x2a\xab\x1b\x88\x86\x8d\x5c\x45\xec\xde\x5f\x35\xad\xce\x75\xaa\x1c\x2f\x4f\x44\xf2\x5c\xac\x95\xcb\xe8\xb6\xb7\xdb\x88\xf3\x93\x1d\x85\xe0\x76\xf3\xbb\xcf\x9f\x0f\x12\x62\x7c\x95\x10\x86\x99\xa0\x61\x8e\x55\x13\x0a\xfa\x3a\xde\x28\x57\x12\x30\x49\x39\xc6\x0d\xf1\xb7\xb3\xaa\x25\x73\xa7\xfb\xb0\x81\x68\x08\x51\xb8\x01\x1c\x3d\x38\x5d\xe9\xf0\xce\x7c\xa5\xc0\xf0\x8e\xc2\x9c\xa5\x5a\xbe\x0d\xa7\x69\x14\xac\x26\xa8\x03\x9d\xfc\x05\x7b\x84\x2e\xb6\xc2\x7a\xff\x3e\xb6\x1a\x09\x05\x35\x53\xd5\x36\xa4\x83\x27\x75\x07\x53\x41\xbd\x7f\x2f\x4f\xaa\xcd\x94\x81\xda\x95\x67\xe5\x96\xd0\x8f\x36\xe5\xaa\x66\xe5\xd6\x26\x73\xc5\xaf\x44\x64\xed\xf0\x6d\xc3\x70\x04\x37\xc1\xab\xd4\xb4\x30\xd1\xf7\xb6\x11\x19\x70\x8e\x86\xdb\xee\x36\xae\x99\xda\x28\x14\x9a\x59\xc6\x7d\x16\x5f\xaf\xd9\x56\x65\x2e\xab\xf6\xc2\x06\xe2\x38\x86\xc1\xb0\x25\xbe\xda\x12\xed\x0a\xf0\xe1\xd6\xdb\x0a\x76\x1b\xfc\xc8\x4b\x98\xc6\x56\x4b\x00\xd7\xc3\xef\xc7\x75\xe6\xb2\x35\x09\xe6\x6b\xdc\x26\x1e\x81\xfb\xe5\xe3\x78\x7a\xf6\xe6\xec\xc3\xac\xf1\x3c\x3b\xfd\xf4\x1e\x7b\xfb\xff\x00\x00\x00\xff\xff\xaf\xf6\xfd\x2a\x21\x5a\x00\x00") func templatesServerServerGotmplBytes() ([]byte, error) { return bindataRead( @@ -762,8 +788,8 @@ func templatesServerServerGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/server/server.gotmpl", size: 23049, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x72, 0x85, 0x28, 0x2d, 0x49, 0x40, 0x62, 0x64, 0x9, 0xda, 0x68, 0x50, 0x3a, 0xa3, 0x17, 0x89, 0x3a, 0x99, 0x62, 0x59, 0xb3, 0x94, 0x22, 0x67, 0x40, 0x12, 0xa2, 0x85, 0xf1, 0x47, 0x63, 0x1d}} + info := bindataFileInfo{name: "templates/server/server.gotmpl", size: 23073, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xdc, 0x34, 0xbc, 0xd0, 0x2f, 0x20, 0x15, 0x85, 0x71, 0xdc, 0x8b, 0xf9, 0x3d, 0x41, 0x19, 0x50, 0xb7, 0x48, 0xd1, 0x28, 0xac, 0x66, 0x89, 0x17, 0x42, 0x9e, 0xa9, 0xd6, 0x71, 0x34, 0x49, 0xd8}} return a, nil } @@ -787,7 +813,47 @@ func templatesServerUrlbuilderGotmpl() (*asset, error) { return a, nil } -var _templatesStructfieldGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x55\x4d\x8f\xd3\x30\x10\xbd\xe7\x57\x8c\xac\x1c\x76\xa5\x6d\x96\x73\x25\x2e\x7c\x89\x22\xd8\x4a\x64\x85\x38\xae\x65\x4f\xc2\xa0\xd8\x09\xb6\x8b\x28\x56\xfe\x3b\x72\x9c\x4f\x48\xbb\xaa\x10\x5a\x6e\x8d\x3d\x6f\xde\x9b\xe7\x67\xd7\x7b\x90\x58\x90\x46\x60\xd6\x99\x83\x70\x05\x61\x25\x19\xb4\x6d\x02\xe0\xfd\x06\xa8\x00\x5d\x3b\x48\xb3\x9d\x7d\xc1\x2d\xde\x1f\x1b\x84\x4d\xb7\x0b\x70\x7b\x0b\xde\x83\x43\xd5\x54\xdc\x21\x30\x59\x0b\xeb\x0c\xe9\x92\x41\x06\x7d\x4d\xe8\x31\x55\x34\xa6\x6e\xd0\xb8\xe3\x27\x5e\x91\xe4\x8e\x6a\xfd\xaa\x16\xf9\x80\x19\x49\x51\xcb\xb6\x4d\xbc\x87\x86\x5b\xc1\x2b\xfa\x89\x90\xdd\x71\x85\x6d\xbb\x24\xb4\xe2\x0b\x2a\x1e\x34\x45\x46\x78\xe8\x1b\xa4\x81\x08\xb6\xcf\x07\x1d\x61\xcd\x70\x5d\x22\xa4\x74\x03\x69\x1c\xf5\x9e\x97\xa1\x24\xcd\xf2\xe1\xd3\xce\x55\x53\x01\xa5\x83\x94\xe0\x19\x44\x5e\xd4\x72\x7d\xaa\xb1\x1d\x03\x49\xc2\x01\xeb\x7e\xce\x58\x58\xde\x09\x65\xbd\xae\x69\xce\xca\xe2\x25\x2d\xd9\x57\x5b\x6b\x76\xba\xdd\x20\xb0\x97\x9f\x7d\xfe\xf0\x3e\xd8\x16\xf4\xff\x50\xd5\x96\x79\x3f\x5f\x63\xf3\x99\x06\xc8\xcb\x83\x75\xb5\x0a\xa2\xe3\xd0\x8b\x85\x11\xf0\x90\x4c\xd8\x24\x40\x97\x21\xea\xc4\x8e\x6d\xb3\x08\xde\xb2\x89\x26\xcd\xde\xf2\x3f\xf3\xb4\x39\x61\x4b\x16\xe7\xcd\xf6\x86\x4a\xd2\xbc\xea\xf5\xcf\x4f\x8a\x6b\x09\x57\x21\xa8\x43\xed\x47\xfc\x76\x20\x83\xf2\x7a\x5c\xd9\xd9\xd7\xaa\x71\xc7\xbd\x22\xe7\x30\x28\xbf\xa9\x15\x05\xc7\xdd\x71\x1c\xc6\xfb\xce\x84\x11\xf1\x2e\xdf\xdf\xc5\x78\x86\xfa\x18\xee\xdf\x5d\x8b\x1f\x2c\x99\x9d\xc0\xdc\x11\x77\x68\x2a\x7c\xe2\x5b\x35\x49\x0e\xc0\x8b\x2f\x55\x48\xdd\x96\x6d\xe2\x88\x17\x84\x24\x8c\x22\xba\x1d\xb0\x68\xa8\xe3\x34\xe7\x93\xd3\x19\xb5\x2b\xb8\xc0\xff\xe0\x0d\x82\x13\x8f\xd0\xd5\xf5\x79\xc7\x92\x1c\xdd\x2a\xee\x2c\xea\x7a\x71\x4c\x2b\xf9\x79\x4a\x5b\xe0\xf1\x14\xfd\x7b\x57\x16\x79\x69\x0c\x7d\x5f\xff\xcb\x12\x5c\xe1\x9c\xe0\x4d\xd8\x7f\x44\xdb\x19\x92\xd5\x0b\xfc\x77\x1c\xbf\x02\x00\x00\xff\xff\x19\x4c\x16\x4a\x76\x07\x00\x00") +var _templatesSimpleschemaDefaultsinitGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xd2\x4f\x8f\xd3\x3c\x10\x06\xf0\x7b\x3f\xc5\xf3\x46\xda\x17\x7b\xb5\xa4\xf7\xa2\x3d\xa0\xae\x90\xf6\x86\x04\x5c\xf8\x23\xad\x69\x9c\x74\x90\x63\x97\xf1\x24\x62\x65\xf9\xbb\x23\x27\xe9\xb6\x74\x2f\x1c\x91\xe0\xe8\xcc\xf8\x19\xe7\xa7\x49\xe9\x25\xa8\x85\xf1\x0d\xea\xfb\xf8\x96\xa9\x27\xa1\xd1\x96\xc3\x76\x88\x12\xfa\x37\x81\x7b\x23\x62\x19\xca\x07\x81\x8a\xc2\xe4\xbb\x6d\xf0\x62\xc8\x47\xd4\x1f\x2d\x07\x54\xea\x73\x55\x69\x8d\x9c\x57\x28\x71\x96\x19\x9b\x5b\xa4\x84\xd1\xb0\x37\x7d\xc9\xbb\xcb\xf9\xce\xb6\x66\x70\x52\x7f\xf0\xbd\xe1\xb8\x37\xee\xbd\xfd\x21\xea\xd3\x97\xaf\x8f\x62\x55\x4a\x38\x30\x79\x69\x51\x5d\x7d\xaf\x50\x2f\xcd\xc8\x59\x6b\xbc\x9a\x22\xff\xbb\x85\x27\x87\xb4\x02\x80\x3e\x76\x65\x46\xdb\x4b\xfd\x6e\xbe\xa8\x2a\xf2\xa3\x71\xd4\xa0\x59\xee\x8e\xc6\x0d\x16\x6d\xe0\x8b\xa7\x20\xe7\x0d\xae\xc6\xea\xc6\x32\xeb\x29\xed\x60\x3c\xed\x54\x1f\x3b\x8d\xf5\x7a\x3e\xc5\xf2\x27\xb2\xb7\x88\x07\xbb\xa3\x96\x76\x46\x28\x78\x50\xc4\x32\x66\x05\xe4\x55\x01\xb4\x2e\xda\xd2\x5c\xdf\xc7\xd7\xcc\xe6\x71\x76\x58\x68\x03\x43\xcd\xbe\xdb\x3d\xb9\xe6\x57\xe5\xe3\xa7\x4b\x6b\x7d\x2a\x9d\x25\x9e\x64\xbf\xc5\xe0\x4f\x8c\x47\xc2\x87\x94\x9e\x08\x63\x05\x55\xba\x9e\x20\x75\xce\x0f\xfa\x06\xff\x3f\x93\x38\xd6\xff\x5c\xe3\xd9\xf2\xa8\x5c\x2c\xa7\x5d\x7c\x0e\xaa\x2f\x0a\x93\x5d\x59\x4b\xa4\xb4\xbe\x46\xdc\x87\xc1\x35\xfe\x85\xa0\xb3\x52\xc6\xb2\xdd\xa0\x1b\x0c\x37\xb8\x5e\xff\x13\x86\xf5\x4d\x59\xb4\x73\xec\x89\xf3\x7c\x65\x7f\xc3\x52\x2d\x0f\x8f\x90\x00\x67\x45\xc8\x77\x93\x27\x5a\xea\x06\xb6\x08\x83\xe8\xbf\x5d\xfc\xcc\xfb\x67\x00\x00\x00\xff\xff\xd4\x61\x99\x8a\x84\x05\x00\x00") + +func templatesSimpleschemaDefaultsinitGotmplBytes() ([]byte, error) { + return bindataRead( + _templatesSimpleschemaDefaultsinitGotmpl, + "templates/simpleschema/defaultsinit.gotmpl", + ) +} + +func templatesSimpleschemaDefaultsinitGotmpl() (*asset, error) { + bytes, err := templatesSimpleschemaDefaultsinitGotmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/simpleschema/defaultsinit.gotmpl", size: 1412, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa1, 0x40, 0xf1, 0x21, 0x40, 0xcf, 0xe0, 0xa4, 0xc3, 0x2d, 0x68, 0x7b, 0xa0, 0x7, 0xb2, 0xfa, 0xf3, 0x74, 0xa9, 0xbf, 0xce, 0x4b, 0x8d, 0x60, 0x2e, 0xbd, 0x1f, 0xe6, 0xd7, 0xb2, 0x52, 0x32}} + return a, nil +} + +var _templatesSimpleschemaDefaultsvarGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x94\x4f\x6f\xd3\x40\x10\xc5\xef\xfd\x14\x23\x23\x44\x5a\x15\xf7\x8e\xc4\x01\x25\x02\xe5\xc6\xa1\x5c\x10\x97\xa1\x1e\xdb\x03\xfb\x27\xcc\x8e\x03\x61\xb5\xdf\x1d\x6d\xed\x24\xdb\x24\x2d\xe9\xa1\x97\x28\xd1\x8e\xe7\xbd\xfd\xbd\x17\xc7\xf8\x16\xd6\x28\x0e\x2d\x41\xbd\x5c\xa4\xb4\xa0\x16\x07\xa3\x17\xf9\x80\x5b\xa8\x97\xe1\xb3\xb0\x65\xe5\x35\x41\x4a\x17\x00\xf9\x60\x25\xec\x14\x2a\xa8\x20\xa5\xf7\x31\x3e\xf8\x3d\x8d\x8c\xcf\xce\x87\xa0\xde\x7e\xf4\x62\x51\x95\x64\x3c\xde\x0d\x04\x15\x76\xdd\xdc\x3b\x45\x76\x01\xea\xaf\x24\x1e\xaa\xd9\xb7\xaa\xda\x0e\x8e\xa3\xf5\x27\x7f\xbb\x59\x65\xfd\xd9\x56\xac\x85\xea\xf5\xab\x75\x05\xf5\xe4\x17\x52\xba\x8c\xf1\xe6\x2a\xef\x6c\xad\x82\xe6\x79\x76\xac\x8c\x86\xff\x92\x80\xf6\xa8\xa0\xf8\x93\xc2\x24\x0b\x57\x37\x85\x1b\x32\x81\x0e\x44\xef\xdd\xa4\xf4\xff\xad\x42\xbf\x06\x16\x0a\xf0\xc5\x59\x94\xd0\xa3\xb9\xa5\x3f\x3a\xbb\xbc\x06\xaa\xbb\x1a\x16\xa8\x74\x7d\xff\xa9\x6c\xf3\xb7\x41\x50\xd9\xbb\x03\x03\xae\xd9\xc3\x2b\xdd\x3c\x17\x80\x50\x37\x18\x14\xe8\x7c\x1e\x9c\x92\x3b\x32\x3e\x69\x17\xca\x3b\xdd\x31\xb9\x0f\x22\xb8\xd9\x5e\xbf\xf1\xe0\xbc\x16\x0b\xa0\x15\x6f\x61\xe5\x43\xe0\xef\x86\xa0\x19\x3d\x04\x60\x07\x8e\x82\x52\x03\x98\x9f\x0f\xa5\x4e\xde\x3b\xef\xd9\x34\xc7\x9d\x3a\xab\x55\xc7\x5b\x1e\x69\xd7\x89\xfc\x76\xce\x47\xf2\x41\x05\x95\xba\x0d\xfc\x66\xed\x0f\x63\x7b\xaa\x18\x07\x69\xc4\x38\xde\x73\x59\x90\x2d\x02\x39\x3f\x8f\x77\x10\xd8\xae\x0c\x41\x30\x7c\x77\x32\xa9\xc7\x5a\x52\xf2\xd8\x66\xf6\x3c\xa2\xe7\x83\xfa\x11\xbc\xab\x77\xb4\xf6\xa4\x4e\x55\xb6\x94\x8a\xf1\x01\xb3\xfc\x7f\xea\xfd\x60\x1a\xf7\x46\xa1\xc7\x8c\xa3\x47\xdd\x23\xb8\xeb\xc9\x22\x70\x00\x62\xed\x49\x0a\x6c\x5e\x46\xde\x4f\xd5\xf7\xe4\x4b\xea\x85\x1c\x14\xfa\xff\x02\x00\x00\xff\xff\xe5\xf4\x97\x06\x49\x05\x00\x00") + +func templatesSimpleschemaDefaultsvarGotmplBytes() ([]byte, error) { + return bindataRead( + _templatesSimpleschemaDefaultsvarGotmpl, + "templates/simpleschema/defaultsvar.gotmpl", + ) +} + +func templatesSimpleschemaDefaultsvarGotmpl() (*asset, error) { + bytes, err := templatesSimpleschemaDefaultsvarGotmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/simpleschema/defaultsvar.gotmpl", size: 1353, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe2, 0xe2, 0x60, 0x51, 0xf9, 0x3, 0xda, 0x54, 0xe, 0xff, 0x69, 0x27, 0xe6, 0x28, 0xdc, 0xd4, 0xbc, 0x4f, 0xac, 0xdf, 0xe8, 0xdc, 0x1, 0xdb, 0xe4, 0x2f, 0x62, 0xa0, 0xbb, 0x71, 0x22, 0x35}} + return a, nil +} + +var _templatesStructfieldGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x94\x31\x6b\xfb\x30\x10\xc5\x77\x7f\x8a\x43\xfc\x87\x7f\x86\x38\x7b\xc7\xb6\x14\xb2\x94\x42\x42\xe7\x1c\xd2\x39\x55\xb1\x25\x21\x5d\x0a\xa9\xd0\x77\x2f\x72\xe2\xc4\x06\xc7\xa1\x94\x92\x6e\xc6\xa7\xbb\xdf\xbd\xe7\x67\xc5\x08\x8a\x2a\x6d\x08\x44\x60\xbf\x93\x5c\x69\xaa\x95\x80\x94\x0a\x80\x18\xe7\xa0\x2b\x30\x96\xe1\x5f\xb9\x0c\xf7\x18\x68\xbd\x77\x04\xf3\xb6\x0a\xb0\x58\x40\x8c\xc0\xd4\xb8\x1a\x99\x40\x28\x2b\x03\x7b\x6d\xb6\x02\x4a\x38\x9e\xc9\x33\xce\x27\x9c\xb7\x8e\x3c\xef\x5f\xb1\xd6\x0a\x59\x5b\xf3\x68\xe5\xaa\xeb\x39\x41\xc9\xa8\x94\x8a\x18\xc1\x61\x90\x58\xeb\x4f\x82\xf2\x19\x1b\x4a\x69\x08\x0c\xf2\x8d\x1a\xcc\x3b\x1d\x88\xb9\x5a\xbe\x78\x6d\x78\x8d\xdb\x00\x87\x19\x64\x54\x7e\x2a\xf2\xe0\x4e\x2b\xef\x5c\x4d\x37\x96\x7a\x5e\x2d\x37\x7e\x57\xe9\xe6\x3d\x58\x73\x27\xe6\xa2\x38\xae\x5e\x3e\xec\x02\xdb\x66\x8d\xdb\xce\x88\xfe\x8b\x13\x6c\x93\xa5\xc8\xb6\x02\x81\xbc\x6e\x99\xfe\x92\x4f\xbd\x4c\x2c\x2b\x94\xf4\x07\x82\x01\x17\x92\xf1\x7f\x36\xed\x58\xb1\x22\x1e\xed\x9b\xec\x9a\x0d\x3e\xd3\x48\x7e\x6e\x69\x0b\x5c\x4f\xd1\xef\xbb\x32\xc8\x8b\xf3\xfa\x63\xfc\x1e\x91\xd8\x50\x1f\xf0\x94\xeb\x57\x76\x9b\x80\x8c\xfe\xc0\x3f\x63\x7c\x05\x00\x00\xff\xff\xaa\xad\x95\xa9\x0b\x05\x00\x00") func templatesStructfieldGotmplBytes() ([]byte, error) { return bindataRead( @@ -802,8 +868,8 @@ func templatesStructfieldGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/structfield.gotmpl", size: 1910, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x52, 0x92, 0x5, 0x7b, 0xfd, 0x5c, 0x15, 0xc8, 0x62, 0x64, 0x3a, 0xd1, 0xd4, 0x9, 0xca, 0xfd, 0x38, 0x1d, 0xa9, 0x4c, 0xdc, 0x5b, 0x30, 0xb9, 0x5a, 0xc6, 0xd8, 0x22, 0xa8, 0xd6, 0xb8, 0x6f}} + info := bindataFileInfo{name: "templates/structfield.gotmpl", size: 1291, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7f, 0xa1, 0x92, 0x88, 0xe4, 0xd, 0x48, 0xd6, 0x1e, 0xcf, 0x48, 0xdd, 0x6f, 0x8, 0xce, 0x2, 0x63, 0x13, 0x23, 0x1d, 0x37, 0x21, 0x88, 0xb4, 0x66, 0xd8, 0x1f, 0x70, 0x3f, 0x27, 0x88, 0xc9}} return a, nil } @@ -827,7 +893,7 @@ func templatesSwagger_json_embedGotmpl() (*asset, error) { return a, nil } -var _templatesValidationCustomformatGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x91\xcd\x4a\x04\x31\x10\x84\xef\x79\x8a\x32\x20\xcc\xc0\x9a\x07\x50\xf6\xe0\x41\x41\x10\x14\x56\xbc\x37\x6e\x67\x0c\xc4\xcc\xd8\xc9\xfa\x43\x93\x77\x97\xcc\x8e\xe0\x61\x0e\x1e\xf7\x56\x24\x55\x95\xfa\x88\xea\x05\x82\x87\xbb\xcb\xd7\x31\x50\xe6\x3d\x6a\x35\x68\x47\x2c\x82\xcb\x2d\x3e\x28\x86\x3d\x15\x76\xb7\xa3\xbc\x51\x79\xf0\x9d\xea\x9c\x78\xa4\xf2\x8a\x5a\x55\xff\x4a\x8e\x99\x51\xab\xb5\x4d\xa7\x56\xb6\x81\x2a\x26\x09\xa9\x78\xd8\xf3\x77\x0b\x77\x3f\xbe\x50\x09\x63\x5a\xbd\xdc\x7d\xd2\x30\xb0\x1c\x1f\xfb\x75\xb8\x65\xdb\xd3\xf7\xd4\xda\x3b\x55\xf7\x4c\xf1\xc0\x37\x5f\x93\x70\xce\xc7\xae\xde\xed\x8a\x84\x34\x74\xfd\x06\x7e\x8e\xe7\xfe\x6a\xa6\x38\xdb\x22\x85\x08\x35\x0d\x76\x59\x78\x6a\x8c\x2b\x40\xff\xe4\x49\xcb\x97\x09\x97\x83\xa4\x66\x30\x40\x35\x3f\x01\x00\x00\xff\xff\x01\xdb\x67\xc9\xd9\x01\x00\x00") +var _templatesValidationCustomformatGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x8e\x41\xca\xc2\x30\x10\x46\xf7\x3d\xc5\xf7\x07\x7e\x50\x90\x1c\x40\xe9\xd6\x95\xa0\x50\x2f\x10\x6c\x52\x07\x6a\xa2\xd3\x51\x17\xc3\xdc\x5d\x1a\x11\x5c\xb8\x7b\xbc\x37\x30\x1f\x25\x44\x66\xac\x5b\x3c\xc2\x48\x7d\x90\xe8\xb7\x85\x2f\x41\xf6\x69\xa1\x0a\x4a\xf0\x87\x20\x67\x98\xa9\x7e\x63\x1c\xa7\x08\x33\xe7\x66\xce\x3d\xcc\x56\x50\xc5\x95\x29\x4b\x82\xfb\xbf\x39\xf8\x5d\x39\x05\xa1\x92\x7f\xc6\xee\x19\x86\x21\xf2\xfb\xd9\xe7\xc2\x1f\x4b\x27\x4c\x79\xa8\x22\xd5\x36\x2d\x37\x75\xe2\x5f\x8b\x4c\x23\xb4\x01\x38\xca\x9d\xf3\x6c\x1b\x6b\x5e\x01\x00\x00\xff\xff\x86\x82\x64\xad\xc2\x00\x00\x00") func templatesValidationCustomformatGotmplBytes() ([]byte, error) { return bindataRead( @@ -842,12 +908,72 @@ func templatesValidationCustomformatGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/validation/customformat.gotmpl", size: 473, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x21, 0x62, 0x2d, 0xb8, 0x17, 0x7, 0xcb, 0xa3, 0xb, 0xe0, 0xa4, 0xc4, 0xc7, 0x3c, 0xc4, 0x11, 0x74, 0x28, 0x61, 0x83, 0x41, 0x6f, 0xe1, 0x5, 0x73, 0xcb, 0x2f, 0x47, 0xe0, 0xa3, 0x22, 0xeb}} + info := bindataFileInfo{name: "templates/validation/customformat.gotmpl", size: 194, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0x99, 0xde, 0x16, 0x1f, 0x38, 0xaf, 0xe8, 0x4d, 0xe9, 0x62, 0xf1, 0x21, 0xc7, 0xc4, 0x36, 0x27, 0xe2, 0xb7, 0xa0, 0x6b, 0x57, 0x5c, 0x6c, 0xb9, 0x3a, 0x30, 0x57, 0x56, 0x4e, 0x97, 0xe7}} + return a, nil +} + +var _templatesValidationMaximumGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x94\x4f\x4b\xf3\x40\x10\xc6\xef\xf9\x14\xf3\x2e\xbc\x90\x88\xee\x49\x3c\x28\x3d\x78\xe8\xa1\xa0\xd2\x83\xf5\xbe\x36\x13\x3b\xb0\xdd\xa4\xfb\xa7\xa4\x2c\xfb\xdd\x65\x63\xd2\xa6\x0a\x5a\x62\xb1\xe8\x6d\xb3\xc9\xf3\x30\xbf\xe1\x47\xbc\xbf\x00\x2a\xa0\xd4\x90\x2e\x84\x99\x6a\x2c\xa8\x06\x3e\x53\x39\x6a\xb9\x21\xf5\xf2\xb8\xa9\x10\x18\x29\xcb\x32\x08\x21\x01\x68\x03\x42\xe5\x5f\x25\xae\x2e\x59\x06\xa9\x2a\x2d\xf0\x89\xb9\x95\x24\x0c\xe6\x4d\x09\x15\x80\x5a\xc3\xf5\x08\xd6\x42\x52\x2e\x2c\xf2\x7b\x51\xd3\xd2\x2d\x27\xca\xa6\xde\xc7\x7e\x3e\x15\x76\x01\x21\x78\xdf\x3f\xa2\x34\x08\x21\x30\x16\xcf\x2a\x87\x10\xce\xc1\x7b\xa8\x34\x29\x5b\x00\xfb\xbf\x62\xc0\xef\xca\xb9\xb0\x54\xaa\xee\x65\x2c\x9b\x98\x07\x27\xa5\x78\x96\x31\x7d\xb6\x0d\x7b\xcf\x9f\x84\x74\x38\xae\x2b\x8d\xc6\xec\x42\xdd\x3c\xdd\xe3\xb8\x9e\x4b\x67\x68\x8d\xbb\xfb\xec\xa6\x81\xf8\x37\x02\x45\x12\x7c\xbb\x99\x76\xc0\x9f\x44\x6c\x36\x9d\x0e\x00\xcd\xbe\x47\xda\x14\x27\x7d\xe8\xad\x1c\x9f\x78\xe1\xa2\x4a\x6f\x1f\x1f\xec\x92\x1b\x26\xd3\x8c\x7e\xb3\x4d\x87\xfa\x74\x7c\x4a\x77\x02\xa3\xf6\x9c\xda\x47\x7f\x2f\x0a\xae\x3e\x1a\x52\xc8\x52\x0c\x51\xe4\xef\xeb\x71\x5c\xc2\x76\xcf\xa7\x77\xa3\xf7\xf3\xe9\xee\x35\x5a\xa7\x55\x0c\x27\x21\x79\x0d\x00\x00\xff\xff\x8e\xc3\xec\x31\xd7\x06\x00\x00") + +func templatesValidationMaximumGotmplBytes() ([]byte, error) { + return bindataRead( + _templatesValidationMaximumGotmpl, + "templates/validation/maximum.gotmpl", + ) +} + +func templatesValidationMaximumGotmpl() (*asset, error) { + bytes, err := templatesValidationMaximumGotmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/validation/maximum.gotmpl", size: 1751, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xaf, 0x39, 0xcc, 0x19, 0xf5, 0x15, 0xf6, 0x52, 0xcb, 0x71, 0x12, 0x92, 0x7c, 0xf9, 0x55, 0x7c, 0xf8, 0x86, 0x5d, 0x37, 0xcc, 0x70, 0x31, 0x51, 0x8d, 0x32, 0x64, 0x73, 0x82, 0xfc, 0xd7, 0xd1}} return a, nil } -var _templatesValidationPrimitiveGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x95\xcf\x6e\xd3\x40\x10\xc6\xef\x79\x8a\xc1\x08\xc9\x46\xc8\x27\xc4\x01\xd4\x03\x2a\x41\x44\x2a\x50\xa9\x88\x73\x97\x64\xec\x8e\xb4\x1e\xa7\xb3\xe3\x90\x6a\xb5\xef\x8e\xd6\xf1\x3f\x41\x13\x61\x91\x53\xb9\x79\xf7\xdb\x9d\x99\xef\xe7\x19\xdb\x7b\x2a\x20\xff\x4c\x7c\x85\x5c\xea\x5d\x08\x0b\x2a\x00\x45\xe0\xed\x05\xec\x8c\xa5\x8d\x51\x1c\xe5\xd4\x7b\x88\xe7\xaf\x8d\xde\x41\x08\xde\x4f\x1e\xd1\x3a\x0c\x21\x49\xbc\x47\xde\x84\xf0\x0a\xbc\x87\xad\x10\x6b\x01\xc9\x8b\xfb\x04\xf2\xab\x7a\x6d\x94\x6a\x86\x4e\x8c\x81\x56\xee\x4b\x63\xad\xf9\x61\x11\x42\x48\x5f\x7a\x0f\xc8\x9b\x36\x5c\xfe\xdd\xd8\x06\x97\xfb\xad\xa0\x73\x54\x73\x9b\xed\x8f\x2b\xd9\xe4\x46\xa7\x5e\x36\x4e\xeb\xea\x63\x2d\x95\x51\x45\x81\x10\xf2\x1b\x15\xe2\x32\x1d\x0f\xc7\xfc\x53\xd3\xd9\xbb\xd6\xf3\xb3\x0b\x60\xb2\xe0\x17\x00\x82\xda\x08\xc7\xdd\x45\x58\x74\x96\x16\x1d\x2c\xb3\x3f\x09\xab\x97\x9f\x16\xac\xd1\xf4\x2c\x58\xd7\x6d\x5c\x7e\x1c\x55\x27\x3e\x1d\x50\xb7\xde\x8f\x8e\x6f\xe7\x75\x15\x31\x55\x4d\x75\x74\x00\xa3\x78\xa8\x06\xef\x21\xbf\xf9\x69\xca\x12\xe5\xdb\xc3\x16\x21\x21\x56\x2c\x51\x12\x08\x61\xc5\x3a\x94\x73\x6e\xac\xa7\xf2\xd2\x21\xaf\x75\x11\x5f\x61\x6b\x33\x96\xf1\xe6\x75\xfa\x18\xe3\xd3\x6f\x25\xeb\x27\xf4\xc0\xa4\x5d\x2d\xf7\x6b\xdb\x38\xda\xe1\xb0\x3d\x77\x6c\x4f\x00\x3e\x88\xff\x1d\xe0\x9e\xc9\x6f\x80\xfb\xed\x79\x80\x1b\xab\xb4\xb5\xf8\xb5\x38\xc2\x78\xd0\xcf\x07\xae\x25\xf1\x2f\x00\x26\x35\xcf\x32\xbb\xe4\x63\xad\x14\x95\x4b\xe3\xf0\xdc\xdd\x61\x78\x03\x29\xd7\x1a\x5d\xbe\x17\x31\x0f\x59\xb7\xfc\x64\xdc\x07\x72\x6b\xa1\x8a\xd8\x68\x2d\xd9\x70\x6c\xc5\x8a\x52\x98\x35\x66\xb3\xd0\xcc\xfe\x3b\x8c\xb5\x3f\xdf\x25\x3d\x9b\xc9\xd7\xb8\x45\xb2\x8a\x8d\x6b\xac\xc3\xb1\x8f\x55\x1a\x1c\x02\xfd\x25\xfe\x5f\x01\x00\x00\xff\xff\xaa\xd3\x6b\x2e\xb1\x08\x00\x00") +var _templatesValidationMinimumGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x94\x4d\x4b\xc3\x40\x10\x86\xef\xf9\x15\xe3\x82\x90\x88\xee\x49\x3c\x28\x3d\x78\xe8\xa1\xa0\xd2\x83\xf5\xbe\x36\x13\x3b\xb0\x9d\xb4\xfb\x51\x5a\x96\xfd\xef\xb2\x25\xe9\x87\x42\x29\xb1\x58\xf4\xb6\xd9\xe4\x7d\x99\x67\x78\x48\x08\x37\x40\x15\x4c\x94\x1d\x1a\xac\x68\x09\x72\xc4\x25\x1a\xbd\x22\xfe\x78\x5d\xcd\x10\x04\xb1\x13\x10\x63\x06\xd0\x7c\xab\xb8\x84\xfc\x70\xe0\xee\x56\x14\x90\x73\xed\x40\x0e\xec\xa3\x26\x65\xb1\x2c\x52\x09\x55\x80\xc6\xc0\x7d\x0f\x16\x4a\x53\xa9\x1c\xca\x67\x62\x9a\xfa\xe9\x80\x5d\x1e\x42\xea\x97\x43\xe5\x26\x10\x63\x08\xbb\x47\xd4\x16\x21\x46\x21\xd2\x99\x4b\x88\xf1\x1a\x42\x80\x99\x21\x76\x15\x88\xcb\xb9\x00\xf9\x54\x8f\x95\xa3\x9a\xdb\x97\xa9\x6c\x60\x5f\xbc\xd6\xea\x5d\xa7\xf4\xd5\x26\x1c\x82\x7c\x53\xda\x63\x7f\x39\x33\x68\xed\x36\xd4\xce\xd3\x3e\xf6\x97\x63\xed\x2d\x2d\x70\x7b\x5f\x3c\xac\x21\x2e\x7a\xc0\xa4\x21\x34\x9b\x69\x06\xfc\x4d\xc4\xf5\xa6\xf3\x0e\xa0\xc5\xcf\x48\xd7\xc5\xd9\x2e\xf4\x46\x8e\x03\x5e\xf8\xad\x49\x47\xbb\xe4\xbb\xc9\x34\xa2\xbf\x6c\xd3\xb1\x3e\x9d\x9e\xd2\x9f\xc1\xa8\x3d\xa7\xf6\xd1\xbf\x8a\x82\xf3\xef\x86\x54\xba\x56\x5d\x14\xf9\xff\x7a\x9c\x96\xb0\xd9\xf3\xf9\xdd\xd8\xf9\xf9\xb4\xf7\x06\x9d\x37\x9c\xc2\x59\xcc\x3e\x03\x00\x00\xff\xff\x40\xcf\x39\x3c\xd2\x06\x00\x00") + +func templatesValidationMinimumGotmplBytes() ([]byte, error) { + return bindataRead( + _templatesValidationMinimumGotmpl, + "templates/validation/minimum.gotmpl", + ) +} + +func templatesValidationMinimumGotmpl() (*asset, error) { + bytes, err := templatesValidationMinimumGotmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/validation/minimum.gotmpl", size: 1746, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8c, 0xef, 0x7c, 0x4e, 0xab, 0x95, 0x1, 0x48, 0x54, 0x55, 0xcc, 0xfa, 0xe5, 0xfb, 0x31, 0x50, 0x75, 0x8e, 0xe5, 0x63, 0xfc, 0x5, 0xd9, 0xa0, 0x8f, 0x2f, 0x49, 0x25, 0x8, 0x1d, 0x8c, 0xc5}} + return a, nil +} + +var _templatesValidationMultipleofGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x94\x3f\xaf\xd3\x30\x14\xc5\xf7\x7c\x8a\x43\x24\xa4\xa4\x2a\x79\xcb\xd3\x1b\x40\x6f\x60\x60\x88\xc4\x9f\x0e\x94\xdd\x6d\xae\x5b\x0b\x63\xa7\xf6\x4d\xd5\xca\xf2\x77\x47\x4e\x53\x48\x61\xa0\xad\x4a\x25\xd8\xac\xf8\x9e\x93\xfb\xbb\xf7\xc8\x21\xbc\x82\x92\x10\xa6\x41\xb1\x16\x7e\xe6\x48\xaa\x1d\xaa\xb9\x69\xc8\xe9\xbd\x32\xab\xcf\xfb\x96\x90\x2b\xc3\x79\x89\x42\xf9\xda\x30\xad\xc8\xa1\xfa\xd0\x69\x56\xad\xa6\x4f\xb2\x44\x8c\x21\x3c\x4c\x92\x0f\xaf\x09\x9c\x14\xca\x43\x18\xa8\x43\xf5\x14\x8b\x8e\xfb\xbb\x6f\x83\x0a\x52\x2c\xd9\xba\x54\x66\x2c\x4f\x21\x85\xd6\x58\x88\xe5\x57\xb0\xed\x0b\xa5\xb6\x82\x9f\x1e\xb1\x25\xe7\x95\x35\xb0\x07\xef\xad\xd0\xaa\x11\x49\x39\x79\x88\x31\x03\xce\xef\xff\xe9\x31\x11\x18\xcb\xa8\x6a\xff\x56\x2b\xe1\xa9\x49\xad\x67\x4a\x82\x9c\xc3\xeb\xe7\xa3\x3b\x8d\xe0\x6a\xc3\x45\x08\xe9\x17\xd5\x4c\xf0\xba\x47\x1d\x1f\x49\x7b\x42\x8c\x79\x9e\xce\xa6\x41\x8c\x53\x84\x80\xd6\x29\xc3\x12\xf9\xcb\x4d\x8e\xea\xbd\x5d\x0a\x4e\x10\xc3\x65\x32\xab\xfd\xc7\x4e\x6b\xb1\xd0\x49\x3d\xf9\x21\x0e\xa1\xfa\x22\x74\x47\xef\x76\xad\x23\xef\x7f\x8a\x46\x2d\x21\xc6\xf2\x4d\xdf\xf2\x8b\x67\x18\xa5\x11\x86\x39\x0c\xbd\xdc\x19\xa8\x1f\x6d\x71\x05\x56\x79\x36\x57\xef\x91\x8d\x11\xcf\x5e\x7c\xf7\xa7\xe4\x66\xc0\x45\x66\xd7\xc5\x68\xae\xfe\x91\x1c\x5d\x90\xa4\xdb\x33\x75\x7f\x37\x4b\x27\x69\x3a\x05\xfd\x35\x04\xb4\xf9\x7d\xfb\xc3\x93\x74\xcd\xfa\xff\xb7\xd5\xdf\x96\x67\x18\xec\x5d\xf7\x3e\x7a\x52\x8e\xdf\x1d\x71\xe7\x4c\x12\x67\x31\xfb\x1e\x00\x00\xff\xff\xfe\x0a\xb4\x3e\x18\x07\x00\x00") + +func templatesValidationMultipleofGotmplBytes() ([]byte, error) { + return bindataRead( + _templatesValidationMultipleofGotmpl, + "templates/validation/multipleOf.gotmpl", + ) +} + +func templatesValidationMultipleofGotmpl() (*asset, error) { + bytes, err := templatesValidationMultipleofGotmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/validation/multipleOf.gotmpl", size: 1816, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0xc2, 0xb4, 0xea, 0x79, 0x1, 0xdf, 0x9a, 0x76, 0xea, 0x7a, 0xbe, 0x8a, 0x8c, 0x4, 0xa9, 0x1a, 0x0, 0x9e, 0xf4, 0x1, 0x39, 0x31, 0xe, 0x7d, 0x48, 0x94, 0x63, 0x3, 0xbf, 0xd0, 0xa4}} + return a, nil +} + +var _templatesValidationPrimitiveGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x92\x51\x6b\xd5\x40\x10\x85\xdf\xf3\x2b\xc6\x88\x70\x23\x92\x1f\xa0\xf4\x41\x6b\xc5\x40\xd5\x82\xe2\x73\xc7\xdc\x49\x3b\x74\x33\x1b\x77\x27\xa5\xb2\xcc\x7f\x97\x4d\xf7\xde\x5e\x21\x54\x0b\xde\xb7\xec\x9e\x33\x67\xbf\xec\xd9\x94\x78\x80\xf6\x13\xcb\x39\xc9\x95\x5e\x9b\x55\x3c\x00\x85\x00\xaf\x4f\xe0\x16\x1d\x6f\x51\xe9\x41\xde\xa4\x04\xd9\x7f\x81\x7a\x0d\x66\x29\x1d\x7c\x92\x8b\x64\x56\xd7\x29\x91\x6c\xcd\x5e\x41\x4a\x30\x05\x16\x1d\xa0\x7e\xf1\xb3\x86\xf6\xdc\xf7\xa8\xec\x05\x8a\xd8\x7e\xf3\x5f\x35\xb0\x5c\x95\x8d\x43\x8a\xe6\xcd\x02\xf1\xec\x04\x84\x1d\xa4\x0a\x20\x90\xce\x41\xf2\x6e\x65\x55\x39\xa3\x2a\xf4\x78\xf7\x28\xfd\x4e\x3e\x32\xfd\x03\xc5\x93\xe8\x2f\x50\x95\x82\xac\xb3\x17\xf1\x88\xe4\x97\x29\x51\xec\x71\xa2\x77\xd8\xdf\x28\xf7\x37\xf1\x00\xe9\xf2\x69\x3d\xb0\xf0\x38\x8f\x66\x15\xe4\x73\x94\xc6\xc9\xa1\x12\xd4\xe5\x77\xd8\x4b\xb1\xd4\xd0\x82\xad\xd4\xf8\xd7\xf1\x7b\xcb\xfa\xf8\xec\x94\x27\x47\x5f\x86\x47\x13\xf6\xae\xd5\x90\x33\x59\x00\x56\x9a\xc8\xca\x29\x46\xfa\xaf\x55\xf0\x00\x28\x5b\xd8\x88\x57\x68\xbb\xf8\x36\x04\xfc\xd5\x94\xe5\x47\x8c\xef\x39\xf6\x81\x47\x16\x54\x1f\x9a\xbd\xad\x13\xa5\x30\x60\x4f\x4d\x5e\x7d\x9e\x9d\xc3\x1f\x8e\xc0\xec\x65\x4a\x40\xb2\x5d\x58\xda\xef\xe8\x66\x3a\xbb\x9b\x02\xc5\xc8\x5e\x16\xd4\x0c\xde\xc5\xd3\x39\xaa\x1f\x3f\xf8\x30\x2e\x3d\x83\x59\x7b\xff\x20\x36\xcd\x3e\xe0\x4f\xf6\xe7\xb7\xf5\xee\x6e\x76\xdc\x6d\x17\x97\x2b\xe9\xc0\x6c\x40\x17\x29\x8f\xba\x98\x31\x34\xcc\xb4\x0f\xfa\xc7\x17\xf4\x3b\x00\x00\xff\xff\x64\x29\xc0\xde\x88\x04\x00\x00") func templatesValidationPrimitiveGotmplBytes() ([]byte, error) { return bindataRead( @@ -862,12 +988,12 @@ func templatesValidationPrimitiveGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/validation/primitive.gotmpl", size: 2225, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa5, 0xc1, 0x1f, 0x2b, 0x1c, 0x3c, 0xf9, 0xf1, 0x51, 0xcb, 0xc2, 0xbe, 0xbc, 0x41, 0xca, 0x4d, 0x31, 0x2f, 0x60, 0xf, 0x71, 0x54, 0xaa, 0x40, 0x1b, 0x71, 0xc4, 0xa8, 0xaa, 0xdb, 0xfc, 0x22}} + info := bindataFileInfo{name: "templates/validation/primitive.gotmpl", size: 1160, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x35, 0x51, 0x4f, 0x1b, 0x47, 0xcc, 0x6e, 0x7b, 0x5, 0xd4, 0x8f, 0xb4, 0x2c, 0x3f, 0x55, 0xd2, 0xab, 0xda, 0xe3, 0xdf, 0x9c, 0x14, 0x22, 0xa2, 0xb5, 0x9b, 0xe2, 0x76, 0xa5, 0x82, 0xb2, 0x1e}} return a, nil } -var _templatesValidationStructfieldGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x92\x41\x6b\xfb\x30\x0c\xc5\xef\xf9\x14\x22\xf0\x3f\xfe\xd7\x7b\x19\xbb\x6c\x1d\x14\x36\x32\x56\xb6\xbb\xa9\x95\x4c\x90\x28\xa9\x63\x77\x2d\x26\xdf\x7d\xc4\x76\x13\x27\x24\xbd\xf9\xe9\xe9\xf7\x24\x1b\x5b\x0b\x12\x73\x62\x84\xb4\x51\x75\x83\x4a\x5f\xbf\x45\x49\x52\x68\xaa\xf9\xa5\x3e\x1e\xb4\x22\x2e\x52\xe8\xba\x24\xb1\xf6\x3f\x50\x0e\x0f\x9f\x78\x32\xa4\x50\xf6\xc5\xcd\x06\x6e\x72\x0b\x5a\x19\x74\x5d\xc8\x72\x46\x08\x99\x71\x79\x1d\x08\x21\xa1\xd7\x77\x90\x77\x71\xa1\xca\x54\x81\x08\x6a\x0b\xd6\x3a\x77\x77\x39\x96\xa6\xa5\x33\x8e\x6d\x8f\xbd\xe7\x53\xac\x9d\xf0\x8b\xf1\xc4\x71\xbc\x57\x0b\xf1\x43\xdb\xd3\x2c\x7e\xe4\x17\xe3\x4d\xa9\xa9\x29\x31\xcb\x6f\x13\x42\x01\xb2\xdc\x4d\x99\x75\xac\xbc\xc0\x1b\x72\xa1\x7f\xc6\x37\x00\x5f\x08\x09\xb1\xbf\x72\xc7\x69\x00\xf1\x34\x20\xf6\x97\x02\x3e\x84\xd6\xa8\x38\xe0\x41\x79\x36\xb2\x56\x76\xdf\x6b\xac\xda\x68\x75\xa7\x87\xcd\x07\x77\x65\xf1\x09\x4d\x3c\xa1\x23\x77\x89\xfe\x62\x3a\x19\x8c\x03\x7c\xe5\xce\x67\xdb\xb7\xcf\xa6\xd5\x75\xf5\x5a\xab\xca\x5d\x2c\x80\x5e\xfb\xb1\x87\x5f\x51\x14\xa8\x7c\x69\x6d\xf6\x8e\x87\x3f\xd5\x1f\x1d\xd9\x28\x62\x9d\x43\xfa\xef\x9c\x8e\x0d\x11\x1c\x8e\x5d\x97\xfc\x05\x00\x00\xff\xff\xa2\xaa\xcd\x0b\x8d\x03\x00\x00") +var _templatesValidationStructfieldGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x93\x5f\x6b\x83\x30\x10\xc0\xdf\xfb\x29\x0e\x61\x8f\x5b\xdf\xcb\xd8\xcb\xd6\x41\x61\xa3\x65\x65\x7b\x0f\xf5\x74\x07\x7a\xda\x98\x74\x2d\xc1\xef\x3e\x34\xa9\x26\xd6\xf4\xcd\xfb\xf3\xfb\xdd\x25\x44\x63\x20\xc5\x8c\x18\x21\xa9\x65\x55\xa3\x54\x97\x1f\x51\x50\x2a\x14\x55\xfc\x56\x1d\xf6\x4a\x12\xe7\x09\xb4\xed\x62\x61\xcc\x23\x50\x06\x4f\x5f\x78\xd4\x24\x31\xed\x92\xcb\x25\x5c\xc3\x15\x28\xa9\xb1\xef\x42\x4e\x27\x84\x48\xb7\x5c\x5c\x06\x42\xa4\xd0\xc5\x77\x90\x4f\x71\xa6\x52\x97\x8e\x70\xd1\x0a\x8c\xe9\xab\xeb\xf3\xa1\xd0\x0d\x9d\x70\x6c\x7b\xee\x6a\xd6\x62\x4c\xc0\xcf\xea\x89\x7d\xbd\x8d\x66\xf4\x43\xdb\xcb\x44\x3f\xf2\xb3\x7a\x5d\x28\xaa\x0b\xdc\x66\xd7\x09\x2e\x01\xdb\xac\x9f\x32\xe9\x88\xdc\xc0\x07\x72\xae\x7e\xc7\x3b\x00\x9b\x70\x06\xbf\x1e\x39\x63\x28\x20\x0e\x05\x7e\x7d\x4e\xb0\x13\x4a\xa1\x64\x87\xbb\xc8\xb2\x5e\x29\xb2\xfb\x46\x61\xd9\x78\xab\xf7\xf1\xb0\xf9\x50\x8d\x2c\x1e\xd0\xc4\x01\xed\x55\x23\xf4\xce\x3e\x65\x42\x5f\x31\x26\x07\x4f\xd8\x17\x39\xc8\xad\x4c\x9c\x6f\x65\xd3\xbe\x39\xd9\x37\xd3\x51\xa3\x7f\x34\x9b\xb9\xf3\x1b\x6c\x9a\x57\xdd\xa8\xaa\x7c\xaf\x64\xd9\x5f\xb9\x03\x6d\x6c\x67\xef\xff\x44\x9e\xa3\xb4\xa9\xd8\xec\x35\x0f\xaf\xbd\xfb\xec\xc9\x5a\x12\xab\x0c\x92\x87\x53\x32\x36\x78\xb0\xfb\x6c\xdb\xc5\x7f\x00\x00\x00\xff\xff\x51\x78\x39\xe4\x27\x04\x00\x00") func templatesValidationStructfieldGotmplBytes() ([]byte, error) { return bindataRead( @@ -882,8 +1008,8 @@ func templatesValidationStructfieldGotmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/validation/structfield.gotmpl", size: 909, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf6, 0x13, 0x95, 0x70, 0x16, 0x59, 0x7, 0x37, 0x93, 0xb, 0x23, 0xc4, 0x1f, 0xd2, 0xb4, 0x7, 0x7, 0x84, 0xf7, 0xb2, 0x67, 0x1b, 0x9d, 0x7f, 0x24, 0x5b, 0x50, 0x51, 0x88, 0x64, 0xb0, 0xaa}} + info := bindataFileInfo{name: "templates/validation/structfield.gotmpl", size: 1063, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1b, 0x49, 0x4f, 0x3d, 0xe9, 0x1a, 0xb7, 0x39, 0x75, 0x84, 0x6, 0xd8, 0x9, 0xa, 0x6c, 0x86, 0xb7, 0xef, 0x10, 0x2e, 0x1e, 0xfc, 0xab, 0xe9, 0xbf, 0xb9, 0xf0, 0x64, 0x65, 0xda, 0xe5, 0x7d}} return a, nil } @@ -988,6 +1114,7 @@ var _bindata = map[string]func() (*asset, error){ "templates/contrib/stratoscale/server/server.gotmpl": templatesContribStratoscaleServerServerGotmpl, "templates/docstring.gotmpl": templatesDocstringGotmpl, "templates/header.gotmpl": templatesHeaderGotmpl, + "templates/markdown/docs.gotmpl": templatesMarkdownDocsGotmpl, "templates/model.gotmpl": templatesModelGotmpl, "templates/schema.gotmpl": templatesSchemaGotmpl, "templates/schemabody.gotmpl": templatesSchemabodyGotmpl, @@ -1012,9 +1139,14 @@ var _bindata = map[string]func() (*asset, error){ "templates/server/responses.gotmpl": templatesServerResponsesGotmpl, "templates/server/server.gotmpl": templatesServerServerGotmpl, "templates/server/urlbuilder.gotmpl": templatesServerUrlbuilderGotmpl, + "templates/simpleschema/defaultsinit.gotmpl": templatesSimpleschemaDefaultsinitGotmpl, + "templates/simpleschema/defaultsvar.gotmpl": templatesSimpleschemaDefaultsvarGotmpl, "templates/structfield.gotmpl": templatesStructfieldGotmpl, "templates/swagger_json_embed.gotmpl": templatesSwagger_json_embedGotmpl, "templates/validation/customformat.gotmpl": templatesValidationCustomformatGotmpl, + "templates/validation/maximum.gotmpl": templatesValidationMaximumGotmpl, + "templates/validation/minimum.gotmpl": templatesValidationMinimumGotmpl, + "templates/validation/multipleOf.gotmpl": templatesValidationMultipleofGotmpl, "templates/validation/primitive.gotmpl": templatesValidationPrimitiveGotmpl, "templates/validation/structfield.gotmpl": templatesValidationStructfieldGotmpl, } @@ -1082,8 +1214,11 @@ var _bintree = &bintree{nil, map[string]*bintree{ }}, }}, }}, - "docstring.gotmpl": &bintree{templatesDocstringGotmpl, map[string]*bintree{}}, - "header.gotmpl": &bintree{templatesHeaderGotmpl, map[string]*bintree{}}, + "docstring.gotmpl": &bintree{templatesDocstringGotmpl, map[string]*bintree{}}, + "header.gotmpl": &bintree{templatesHeaderGotmpl, map[string]*bintree{}}, + "markdown": &bintree{nil, map[string]*bintree{ + "docs.gotmpl": &bintree{templatesMarkdownDocsGotmpl, map[string]*bintree{}}, + }}, "model.gotmpl": &bintree{templatesModelGotmpl, map[string]*bintree{}}, "schema.gotmpl": &bintree{templatesSchemaGotmpl, map[string]*bintree{}}, "schemabody.gotmpl": &bintree{templatesSchemabodyGotmpl, map[string]*bintree{}}, @@ -1112,10 +1247,17 @@ var _bintree = &bintree{nil, map[string]*bintree{ "server.gotmpl": &bintree{templatesServerServerGotmpl, map[string]*bintree{}}, "urlbuilder.gotmpl": &bintree{templatesServerUrlbuilderGotmpl, map[string]*bintree{}}, }}, + "simpleschema": &bintree{nil, map[string]*bintree{ + "defaultsinit.gotmpl": &bintree{templatesSimpleschemaDefaultsinitGotmpl, map[string]*bintree{}}, + "defaultsvar.gotmpl": &bintree{templatesSimpleschemaDefaultsvarGotmpl, map[string]*bintree{}}, + }}, "structfield.gotmpl": &bintree{templatesStructfieldGotmpl, map[string]*bintree{}}, "swagger_json_embed.gotmpl": &bintree{templatesSwagger_json_embedGotmpl, map[string]*bintree{}}, "validation": &bintree{nil, map[string]*bintree{ "customformat.gotmpl": &bintree{templatesValidationCustomformatGotmpl, map[string]*bintree{}}, + "maximum.gotmpl": &bintree{templatesValidationMaximumGotmpl, map[string]*bintree{}}, + "minimum.gotmpl": &bintree{templatesValidationMinimumGotmpl, map[string]*bintree{}}, + "multipleOf.gotmpl": &bintree{templatesValidationMultipleofGotmpl, map[string]*bintree{}}, "primitive.gotmpl": &bintree{templatesValidationPrimitiveGotmpl, map[string]*bintree{}}, "structfield.gotmpl": &bintree{templatesValidationStructfieldGotmpl, map[string]*bintree{}}, }}, diff --git a/vendor/github.com/go-swagger/go-swagger/generator/client.go b/vendor/github.com/go-swagger/go-swagger/generator/client.go index 65915bc6d9f4a..037938e353345 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/client.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/client.go @@ -84,10 +84,11 @@ func (c *clientGenerator) Generate() error { } if c.GenOpts.IncludeModel { - for _, mod := range app.Models { - if mod.IsStream { + for _, m := range app.Models { + if m.IsStream { continue } + mod := m if err := c.GenOpts.renderDefinition(&mod); err != nil { return err } @@ -95,8 +96,10 @@ func (c *clientGenerator) Generate() error { } if c.GenOpts.IncludeHandler { - for _, opg := range app.OperationGroups { - for _, op := range opg.Operations { + for _, g := range app.OperationGroups { + opg := g + for _, o := range opg.Operations { + op := o if err := c.GenOpts.renderOperation(&op); err != nil { return err } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/formats.go b/vendor/github.com/go-swagger/go-swagger/generator/formats.go index f041ef9ec70b7..3d127333f4781 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/formats.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/formats.go @@ -57,7 +57,7 @@ var zeroes = map[string]string{ "strfmt.UUID3": "strfmt.UUID3(\"\")", "strfmt.UUID4": "strfmt.UUID4(\"\")", "strfmt.UUID5": "strfmt.UUID5(\"\")", - //"file": "runtime.File", + // "file": "runtime.File", } // conversion functions from string representation to a numerical or boolean diff --git a/vendor/github.com/go-swagger/go-swagger/generator/language.go b/vendor/github.com/go-swagger/go-swagger/generator/language.go index a8dc0cfdeadcc..4b5fb6bc316c6 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/language.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/language.go @@ -262,7 +262,7 @@ func GoLangOpts() *LanguageOpts { if err != nil { return "", err } - return strings.Replace(strings.Replace(strings.Replace(string(b), "}", ",}", -1), "[", "{", -1), "]", ",}", -1), nil + return strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(string(b), "}", ",}"), "[", "{"), "]", ",}"), nil } opts.BaseImportFunc = func(tgt string) string { diff --git a/vendor/github.com/go-swagger/go-swagger/generator/model.go b/vendor/github.com/go-swagger/go-swagger/generator/model.go index c005d0284554f..df089b5e93705 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/model.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/model.go @@ -186,7 +186,7 @@ func shallowValidationLookup(sch GenSchema) bool { if sch.Required || hasFormatValidation(sch.resolvedType) { return true } - if sch.MaxLength != nil || sch.MinLength != nil || sch.Pattern != "" || sch.MultipleOf != nil || sch.Minimum != nil || sch.Maximum != nil || len(sch.Enum) > 0 || len(sch.ItemsEnum) > 0 { + if sch.HasStringValidations() || sch.HasNumberValidations() || sch.HasEnum() || len(sch.ItemsEnum) > 0 || sch.HasObjectValidations() { return true } for _, a := range sch.AllOf { @@ -230,7 +230,7 @@ func makeGenDefinitionHierarchy(name, pkg, container string, schema spec.Schema, // Check if model is imported from external package using x-go-type receiver := "m" // models are resolved in the current package - resolver := newTypeResolver("", specDoc) + resolver := newTypeResolver("", "", specDoc) resolver.ModelName = name analyzed := analysis.New(specDoc.Spec()) @@ -375,7 +375,7 @@ func makeGenDefinitionHierarchy(name, pkg, container string, schema spec.Schema, } func findImports(sch *GenSchema) map[string]string { - imp := map[string]string{} + imp := make(map[string]string, 20) t := sch.resolvedType if t.Pkg != "" && t.PkgAlias != "" { imp[t.PkgAlias] = t.Pkg @@ -404,7 +404,8 @@ func findImports(sch *GenSchema) map[string]string { } } if sch.Properties != nil { - for _, p := range sch.Properties { + for _, props := range sch.Properties { + p := props sub := findImports(&p) for k, v := range sub { imp[k] = v @@ -418,7 +419,8 @@ func findImports(sch *GenSchema) map[string]string { } } if sch.AllOf != nil { - for _, p := range sch.AllOf { + for _, props := range sch.AllOf { + p := props sub := findImports(&p) for k, v := range sub { imp[k] = v @@ -426,8 +428,11 @@ func findImports(sch *GenSchema) map[string]string { } } for k, v := range sch.ExtraImports { - imp[k] = v + if k != "" && v != "" { + imp[k] = v + } } + return imp } @@ -621,33 +626,39 @@ func (sg *schemaGenContext) NewAdditionalProperty(schema spec.Schema) *schemaGen return pg } -func hasSliceValidations(model *spec.Schema) (hasSliceValidations bool) { - hasSliceValidations = model.MaxItems != nil || model.MinItems != nil || model.UniqueItems || len(model.Enum) > 0 - return +func hasContextValidations(model *spec.Schema) bool { + // always assume ref needs context validate + // TODO: find away to determine ref needs context validate or not + if model.ReadOnly || model.Ref.String() != "" { + return true + } + return false } -func hasValidations(model *spec.Schema, isRequired bool) (hasValidation bool) { - // NOTE: needsValidation has gone deprecated and is replaced by top-level's shallowValidationLookup() - hasNumberValidation := model.Maximum != nil || model.Minimum != nil || model.MultipleOf != nil - hasStringValidation := model.MaxLength != nil || model.MinLength != nil || model.Pattern != "" - hasEnum := len(model.Enum) > 0 +func hasValidations(model *spec.Schema, isRequired bool) bool { + if isRequired { + return true + } + + v := model.Validations() + if v.HasNumberValidations() || v.HasStringValidations() || v.HasArrayValidations() || v.HasEnum() || v.HasObjectValidations() { + return true + } // since this was added to deal with discriminator, we'll fix this when testing discriminated types - simpleObject := len(model.Properties) > 0 && model.Discriminator == "" + if len(model.Properties) > 0 && model.Discriminator == "" { + return true + } // lift validations from allOf branches - hasAllOfValidation := false for _, s := range model.AllOf { - hasAllOfValidation = hasValidations(&s, false) - hasAllOfValidation = s.Ref.String() != "" || hasAllOfValidation - if hasAllOfValidation { - break + schema := s + if s.Ref.String() != "" || hasValidations(&schema, false) { + return true } } - hasValidation = hasNumberValidation || hasStringValidation || hasSliceValidations(model) || hasEnum || simpleObject || hasAllOfValidation || isRequired - - return + return false } func hasFormatValidation(tpe resolvedType) bool { @@ -660,34 +671,25 @@ func hasFormatValidation(tpe resolvedType) bool { return false } -// handleFormatConflicts handles all conflicting model properties when a format is set -func handleFormatConflicts(model *spec.Schema) { - switch model.Format { - case "date", "datetime", "uuid", "bsonobjectid", "base64", "duration": - model.MinLength = nil - model.MaxLength = nil - model.Pattern = "" - // more cases should be inserted here if they arise - } -} - func (sg *schemaGenContext) schemaValidations() sharedValidations { model := sg.Schema - // resolve any conflicting properties if the model has a format - handleFormatConflicts(&model) isRequired := sg.Required if model.Default != nil || model.ReadOnly { // when readOnly or default is specified, this disables Required validation (Swagger-specific) isRequired = false + if sg.Required { + log.Printf("warn: properties with a default value or readOnly should not be required [%s]", sg.Name) + } } - hasSliceValidations := model.MaxItems != nil || model.MinItems != nil || model.UniqueItems || len(model.Enum) > 0 - hasValidations := hasValidations(&model, isRequired) - s := sharedValidationsFromSchema(model, sg.Required) - s.HasValidations = hasValidations - s.HasSliceValidations = hasSliceValidations - return s + v := model.Validations() + return sharedValidations{ + Required: sg.Required, /* TODO(fred): guard for cases with discriminator field, default and readOnly*/ + SchemaValidations: v, + HasSliceValidations: v.HasArrayValidations() || v.HasEnum(), + HasValidations: hasValidations(&model, isRequired), + } } func mergeValidation(other *schemaGenContext) bool { @@ -708,6 +710,7 @@ func mergeValidation(other *schemaGenContext) bool { func (sg *schemaGenContext) MergeResult(other *schemaGenContext, liftsRequired bool) { sg.GenSchema.HasValidations = sg.GenSchema.HasValidations || mergeValidation(other) + sg.GenSchema.HasContextValidations = sg.GenSchema.HasContextValidations || other.GenSchema.HasContextValidations if liftsRequired && other.GenSchema.AdditionalProperties != nil && other.GenSchema.AdditionalProperties.Required { sg.GenSchema.Required = true @@ -743,21 +746,20 @@ func (sg *schemaGenContext) buildProperties() error { debugLog("building properties %s (parent: %s)", sg.Name, sg.Container) for k, v := range sg.Schema.Properties { - debugLogAsJSON("building property %s[%q] (tup: %t) (BaseType: %t)", - sg.Name, k, sg.IsTuple, sg.GenSchema.IsBaseType, sg.Schema) - debugLog("property %s[%q] (tup: %t) HasValidations: %t)", - sg.Name, k, sg.IsTuple, sg.GenSchema.HasValidations) + debugLogAsJSON("building property %s[%q] (IsTuple: %t) (IsBaseType: %t) (HasValidations: %t)", + sg.Name, k, sg.IsTuple, sg.GenSchema.IsBaseType, sg.GenSchema.HasValidations, v) + + vv := v // check if this requires de-anonymizing, if so lift this as a new struct and extra schema - tpe, err := sg.TypeResolver.ResolveSchema(&v, true, sg.IsTuple || swag.ContainsStrings(sg.Schema.Required, k)) - if sg.Schema.Discriminator == k { - tpe.IsNullable = false - } + tpe, err := sg.TypeResolver.ResolveSchema(&vv, true, sg.IsTuple || swag.ContainsStrings(sg.Schema.Required, k)) if err != nil { return err } + if sg.Schema.Discriminator == k { + tpe.IsNullable = false + } - vv := v var hasValidation bool if tpe.IsComplexObject && tpe.IsAnonymous && len(v.Properties) > 0 { // this is an anonymous complex construct: build a new new type for it @@ -904,8 +906,13 @@ func (sg *schemaGenContext) buildProperties() error { emprop.GenSchema.Extensions = emprop.Schema.Extensions // set custom serializer tag - if customTag, found := emprop.Schema.Extensions[xGoCustomTag]; found { - emprop.GenSchema.CustomTag = customTag.(string) + if customTag, found := tpe.Extensions[xGoCustomTag]; found { + tagAsStr, ok := customTag.(string) + if ok { + emprop.GenSchema.CustomTag = tagAsStr + } else { + log.Printf("warning: expect %s extension to be a string, got: %v. Skipped", xGoCustomTag, customTag) + } } sg.GenSchema.Properties = append(sg.GenSchema.Properties, emprop.GenSchema) } @@ -926,7 +933,8 @@ func (sg *schemaGenContext) buildAllOf() error { sg.Container = sg.Name } debugLogAsJSON("building all of for %d entries", len(sg.Schema.AllOf), sg.Schema) - for i, sch := range sg.Schema.AllOf { + for i, schema := range sg.Schema.AllOf { + sch := schema tpe, ert := sg.TypeResolver.ResolveSchema(&sch, sch.Ref.String() == "", false) if ert != nil { return ert @@ -1006,7 +1014,12 @@ func (sg *schemaGenContext) buildAllOf() error { log.Printf("warning: cannot generate serializable allOf with conflicting array definitions in %s", sg.Container) } - sg.GenSchema.IsNullable = true + // AllOf types are always considered nullable, except when an extension says otherwise + if override, ok := sg.TypeResolver.isNullableOverride(&sg.Schema); ok { + sg.GenSchema.IsNullable = override + } else { + sg.GenSchema.IsNullable = true + } // prevent IsAliased to bubble up (e.g. when a single branch is itself aliased) sg.GenSchema.IsAliased = sg.GenSchema.IsAliased && len(sg.GenSchema.AllOf) < 2 @@ -1037,7 +1050,7 @@ func newMapStack(context *schemaGenContext) (first, last *mapStack, err error) { } if !tpe.IsMap { - //reached the end of the rabbit hole + // reached the end of the rabbit hole if tpe.IsComplexObject && tpe.IsAnonymous { // found an anonymous object: create the struct from a newly created definition nw := l.Context.makeNewStruct(l.Context.makeRefName()+" Anon", *l.Type.AdditionalProperties.Schema) @@ -1047,6 +1060,7 @@ func newMapStack(context *schemaGenContext) (first, last *mapStack, err error) { l.Type.AdditionalProperties.Schema = sch l.ValueRef = l.Context.NewAdditionalProperty(*sch) } + // other cases where to stop are: a $ref or a simple object break } @@ -1060,7 +1074,7 @@ func newMapStack(context *schemaGenContext) (first, last *mapStack, err error) { l = l.Next } - //return top and bottom entries of this stack of AdditionalProperties + // return top and bottom entries of this stack of AdditionalProperties return ms, l, nil } @@ -1442,7 +1456,7 @@ func (sg *schemaGenContext) buildArray() error { // items from maps of aliased or nullable type remain required // NOTE(fredbi): since this is reset below, this Required = true serves the obscure purpose - // of indirectly lifting validations from the slice. This is carried on differently now. + // of indirectly lifting validations from the slice. This is carried out differently now. // elProp.Required = true if err := elProp.makeGenSchema(); err != nil { @@ -1484,7 +1498,7 @@ func (sg *schemaGenContext) buildArray() error { // lift validations sg.GenSchema.HasValidations = sg.GenSchema.HasValidations || schemaCopy.HasValidations - sg.GenSchema.HasSliceValidations = hasSliceValidations(&sg.Schema) + sg.GenSchema.HasSliceValidations = sg.Schema.Validations().HasArrayValidations() || sg.Schema.Validations().HasEnum() // prevents bubbling custom formatter flag sg.GenSchema.IsCustomFormatter = false @@ -1516,7 +1530,8 @@ func (sg *schemaGenContext) buildItems() error { if sg.Named { sg.GenSchema.Name = sg.Name sg.GenSchema.GoType = sg.TypeResolver.goTypeName(sg.Name) - for i, s := range sg.Schema.Items.Schemas { + for i, sch := range sg.Schema.Items.Schemas { + s := sch elProp := sg.NewTupleElement(&s, i) if s.Ref.String() == "" { @@ -1630,7 +1645,11 @@ func (sg *schemaGenContext) buildAdditionalItems() error { } func (sg *schemaGenContext) buildXMLNameWithTags() error { - if sg.WithXML || sg.Schema.XML != nil { + // render some "xml" struct tag under one the following conditions: + // - consumes/produces in spec contains xml + // - struct tags CLI option contains xml + // - XML object present in spec for this schema + if sg.WithXML || swag.ContainsStrings(sg.StructTags, "xml") || sg.Schema.XML != nil { sg.GenSchema.XMLName = sg.Name if sg.Schema.XML != nil { @@ -1641,10 +1660,6 @@ func (sg *schemaGenContext) buildXMLNameWithTags() error { sg.GenSchema.XMLName += ",attr" } } - - if !sg.GenSchema.Required && sg.GenSchema.IsEmptyOmitted { - sg.GenSchema.XMLName += ",omitempty" - } } return nil } @@ -1730,7 +1745,7 @@ func (sg *schemaGenContext) shortCircuitNamedRef() (bool, error) { tpe.IsMap = false tpe.IsArray = false tpe.IsAnonymous = false - tpe.IsNullable = sg.TypeResolver.IsNullable(&sg.Schema) + tpe.IsNullable = sg.TypeResolver.isNullable(&sg.Schema) item := sg.NewCompositionBranch(sg.Schema, 0) if err := item.makeGenSchema(); err != nil { @@ -1759,13 +1774,13 @@ func (sg *schemaGenContext) liftSpecialAllOf() error { var seenNullable bool var schemaToLift spec.Schema - for _, sch := range sg.Schema.AllOf { - + for _, schema := range sg.Schema.AllOf { + sch := schema tpe, err := sg.TypeResolver.ResolveSchema(&sch, true, true) if err != nil { return err } - if sg.TypeResolver.IsNullable(&sch) { + if sg.TypeResolver.isNullable(&sch) { seenNullable = true } if len(sch.Type) > 0 || len(sch.Properties) > 0 || sch.Ref.GetURL() != nil || len(sch.AllOf) > 0 { @@ -1839,6 +1854,21 @@ func goName(sch *spec.Schema, orig string) string { return orig } +func (sg *schemaGenContext) derefMapElement(outer *GenSchema, sch *GenSchema, elem *GenSchema) { + derefType := strings.TrimPrefix(elem.GoType, "*") + + if outer.IsAliased { + nesting := strings.TrimSuffix(strings.TrimSuffix(outer.AliasedType, elem.GoType), "*") + outer.AliasedType = nesting + derefType + outer.GoType = derefType + } else { + nesting := strings.TrimSuffix(strings.TrimSuffix(outer.GoType, elem.GoType), "*") + outer.GoType = nesting + derefType + } + + elem.GoType = derefType +} + func (sg *schemaGenContext) checkNeedsPointer(outer *GenSchema, sch *GenSchema, elem *GenSchema) { derefType := strings.TrimPrefix(elem.GoType, "*") switch { @@ -1876,10 +1906,21 @@ func (sg *schemaGenContext) buildMapOfNullable(sch *GenSchema) { // render element of aliased or anonyous map as a pointer it := elem.Items for it != nil { - if it.IsPrimitive && it.IsNullable { + switch { + case it.IsPrimitive && it.IsNullable: sg.checkNeedsPointer(outer, sch, it) - } else if it.IsMap { + case it.IsMap: sg.buildMapOfNullable(it) + case !it.IsPrimitive && !it.IsArray && it.IsComplexObject && it.IsNullable: + // structs in map are not rendered as pointer by default + // unless some x-nullable overrides says so + _, forced := it.Extensions[xNullable] + if !forced { + _, forced = it.Extensions[xIsNullable] + } + if !forced { + sg.derefMapElement(outer, sch, it) + } } it = it.Items } @@ -1893,12 +1934,18 @@ func (sg *schemaGenContext) makeGenSchema() error { debugLogAsJSON("making gen schema (anon: %t, req: %t, tuple: %t) %s\n", !sg.Named, sg.Required, sg.IsTuple, sg.Name, sg.Schema) - ex := "" + sg.GenSchema.Example = "" if sg.Schema.Example != nil { - ex = fmt.Sprintf("%#v", sg.Schema.Example) + data, err := asJSON(sg.Schema.Example) + if err != nil { + return err + } + // Deleting the unnecessary double quotes for string types + // otherwise the generate spec will generate as "\"foo\"" + sg.GenSchema.Example = strings.Trim(data, "\"") } + sg.GenSchema.ExternalDocs = trimExternalDoc(sg.Schema.ExternalDocs) sg.GenSchema.IsExported = true - sg.GenSchema.Example = ex sg.GenSchema.Path = sg.Path sg.GenSchema.IndexVar = sg.IndexVar sg.GenSchema.Location = body @@ -1960,12 +2007,37 @@ func (sg *schemaGenContext) makeGenSchema() error { // include format validations, excluding binary sg.GenSchema.HasValidations = sg.GenSchema.HasValidations || hasFormatValidation(tpe) + // include context validations + sg.GenSchema.HasContextValidations = sg.GenSchema.HasContextValidations || hasContextValidations(&sg.Schema) && !tpe.IsInterface && !tpe.IsStream && !tpe.SkipExternalValidation + // usage of a polymorphic base type is rendered with getter funcs on private properties. // In the case of aliased types, the value expression remains unchanged to the receiver. if tpe.IsArray && tpe.ElemType != nil && tpe.ElemType.IsBaseType && sg.GenSchema.ValueExpression != sg.GenSchema.ReceiverName { sg.GenSchema.ValueExpression += asMethod } + if tpe.IsExternal { // anonymous external types + extType, pkg, alias := sg.TypeResolver.knownDefGoType(sg.GenSchema.Name, sg.Schema, sg.TypeResolver.goTypeName) + if pkg != "" && alias != "" { + sg.GenSchema.ExtraImports[alias] = pkg + } + + if !tpe.IsEmbedded { + sg.GenSchema.resolvedType = tpe + sg.GenSchema.Required = sg.Required + // assume we validate everything but interface and io.Reader - validation may be disabled by using the noValidation hint + sg.GenSchema.HasValidations = !(tpe.IsInterface || tpe.IsStream || tpe.SkipExternalValidation) + sg.GenSchema.IsAliased = sg.GenSchema.HasValidations + + log.Printf("INFO: type %s is external, with inferred spec type %s, referred to as %s", sg.GenSchema.Name, sg.GenSchema.GoType, extType) + sg.GenSchema.GoType = extType + sg.GenSchema.AliasedType = extType + return nil + } + // TODO: case for embedded types as anonymous definitions + return fmt.Errorf("ERROR: inline definitions embedded types are not supported") + } + debugLog("gschema nullable: %t", sg.GenSchema.IsNullable) if e := sg.buildAdditionalProperties(); e != nil { return e diff --git a/vendor/github.com/go-swagger/go-swagger/generator/operation.go b/vendor/github.com/go-swagger/go-swagger/generator/operation.go index 0beef7040b9f8..36e5840e3bb0b 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/operation.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/operation.go @@ -193,7 +193,8 @@ func (o *operationGenerator) Generate() error { operations = append(operations, op) sort.Sort(operations) - for _, op := range operations { + for _, pp := range operations { + op := pp if o.GenOpts.DumpData { _ = dumpData(swag.ToDynamicJSON(op)) continue @@ -312,7 +313,7 @@ func (b *codeGenOpBuilder) MakeOperation() (GenOperation, error) { // // In all cases, resetting definitions to the _original_ (untransformed) spec is not an option: // we take from there the spec possibly already transformed by the GenDefinitions stage. - resolver := newTypeResolver(b.GenOpts.LanguageOpts.ManglePackageName(b.ModelsPackage, defaultModelsTarget), b.Doc) + resolver := newTypeResolver(b.GenOpts.LanguageOpts.ManglePackageName(b.ModelsPackage, defaultModelsTarget), b.DefaultImports[b.ModelsPackage], b.Doc) receiver := "o" operation := b.Operation @@ -399,6 +400,7 @@ func (b *codeGenOpBuilder) MakeOperation() (GenOperation, error) { defaultResponse = &gr } } + // Always render a default response, even when no responses were defined if operation.Responses == nil || (operation.Responses.Default == nil && len(srs) == 0) { gr, err := b.MakeResponse(receiver, b.Name+" default", false, resolver, -1, spec.Response{}) @@ -408,44 +410,41 @@ func (b *codeGenOpBuilder) MakeOperation() (GenOperation, error) { defaultResponse = &gr } - if b.Principal == "" { - b.Principal = iface - } - swsp := resolver.Doc.Spec() - var extraSchemes []string - if ess, ok := operation.Extensions.GetStringSlice(xSchemes); ok { - extraSchemes = append(extraSchemes, ess...) - } - if ess1, ok := swsp.Extensions.GetStringSlice(xSchemes); ok { - extraSchemes = concatUnique(ess1, extraSchemes) - } - sort.Strings(extraSchemes) - schemes := concatUnique(swsp.Schemes, operation.Schemes) - sort.Strings(schemes) + schemes, extraSchemes := gatherURISchemes(swsp, operation) + originalSchemes := operation.Schemes + originalExtraSchemes := getExtraSchemes(operation.Extensions) + produces := producesOrDefault(operation.Produces, swsp.Produces, b.DefaultProduces) sort.Strings(produces) + consumes := producesOrDefault(operation.Consumes, swsp.Consumes, b.DefaultConsumes) sort.Strings(consumes) - var hasStreamingResponse bool - if defaultResponse != nil && defaultResponse.Schema != nil && defaultResponse.Schema.IsStream { - hasStreamingResponse = true - } var successResponse *GenResponse - for _, sr := range successResponses { + for _, resp := range successResponses { + sr := resp if sr.IsSuccess { successResponse = &sr break } } - for _, sr := range successResponses { - if !hasStreamingResponse && sr.Schema != nil && sr.Schema.IsStream { - hasStreamingResponse = true - break + + var hasStreamingResponse bool + if defaultResponse != nil && defaultResponse.Schema != nil && defaultResponse.Schema.IsStream { + hasStreamingResponse = true + } + + if !hasStreamingResponse { + for _, sr := range successResponses { + if !hasStreamingResponse && sr.Schema != nil && sr.Schema.IsStream { + hasStreamingResponse = true + break + } } } + if !hasStreamingResponse { for _, r := range responses { if r.Schema != nil && r.Schema.IsStream { @@ -488,8 +487,9 @@ func (b *codeGenOpBuilder) MakeOperation() (GenOperation, error) { HasBodyParams: hasBodyParams, HasStreamingResponse: hasStreamingResponse, Authorized: b.Authed, - Security: b.makeSecurityRequirements(receiver), + Security: b.makeSecurityRequirements(receiver), // resolved security requirements, for codegen SecurityDefinitions: b.makeSecuritySchemes(receiver), + SecurityRequirements: securityRequirements(operation.Security), // raw security requirements, for doc Principal: b.Principal, Responses: responses, DefaultResponse: defaultResponse, @@ -497,12 +497,19 @@ func (b *codeGenOpBuilder) MakeOperation() (GenOperation, error) { SuccessResponses: successResponses, ExtraSchemas: gatherExtraSchemas(b.ExtraSchemas), Schemes: schemeOrDefault(schemes, b.DefaultScheme), - ProducesMediaTypes: produces, - ConsumesMediaTypes: consumes, - ExtraSchemes: extraSchemes, + SchemeOverrides: originalSchemes, // raw operation schemes, for doc + ProducesMediaTypes: produces, // resolved produces, for codegen + ConsumesMediaTypes: consumes, // resolved consumes, for codegen + Produces: operation.Produces, // for doc + Consumes: operation.Consumes, // for doc + ExtraSchemes: extraSchemes, // resolved schemes, for codegen + ExtraSchemeOverrides: originalExtraSchemes, // raw operation extra schemes, for doc TimeoutName: timeoutName, Extensions: operation.Extensions, StrictResponders: b.GenOpts.StrictResponders, + + PrincipalIsNullable: b.GenOpts.PrincipalIsNullable(), + ExternalDocs: trimExternalDoc(operation.ExternalDocs), }, nil } @@ -523,26 +530,15 @@ func schemeOrDefault(schemes []string, defaultScheme string) []string { return schemes } -func concatUnique(collections ...[]string) []string { - resultSet := make(map[string]struct{}) - for _, c := range collections { - for _, i := range c { - if _, ok := resultSet[i]; !ok { - resultSet[i] = struct{}{} - } - } - } - var result []string - for k := range resultSet { - result = append(result, k) - } - return result -} - func (b *codeGenOpBuilder) MakeResponse(receiver, name string, isSuccess bool, resolver *typeResolver, code int, resp spec.Response) (GenResponse, error) { debugLog("[%s %s] making id %q", b.Method, b.Path, b.Operation.ID) // assume minimal flattening has been carried on, so there is not $ref in response (but some may remain in response schema) + examples := make(GenResponseExamples, 0, len(resp.Examples)) + for k, v := range resp.Examples { + examples = append(examples, GenResponseExample{MediaType: k, Example: v}) + } + sort.Sort(examples) res := GenResponse{ Package: b.GenOpts.LanguageOpts.ManglePackageName(b.APIPackage, defaultOperationsTarget), @@ -559,6 +555,7 @@ func (b *codeGenOpBuilder) MakeResponse(receiver, name string, isSuccess bool, r Extensions: resp.Extensions, StrictResponders: b.GenOpts.StrictResponders, OperationName: b.Name, + Examples: examples, } // prepare response headers @@ -583,26 +580,29 @@ func (b *codeGenOpBuilder) MakeResponse(receiver, name string, isSuccess bool, r } func (b *codeGenOpBuilder) MakeHeader(receiver, name string, hdr spec.Header) (GenHeader, error) { - tpe := typeForHeader(hdr) //simpleResolvedType(hdr.Type, hdr.Format, hdr.Items) + tpe := simpleResolvedType(hdr.Type, hdr.Format, hdr.Items, &hdr.CommonValidations) id := swag.ToGoName(name) res := GenHeader{ - sharedValidations: sharedValidationsFromSimple(hdr.CommonValidations, true), // NOTE: Required is not defined by the Swagger schema for header. Set arbitrarily to true for convenience in templates. - resolvedType: tpe, - Package: b.GenOpts.LanguageOpts.ManglePackageName(b.APIPackage, defaultOperationsTarget), - ReceiverName: receiver, - ID: id, - Name: name, - Path: fmt.Sprintf("%q", name), - ValueExpression: fmt.Sprintf("%s.%s", receiver, id), - Description: trimBOM(hdr.Description), - Default: hdr.Default, - HasDefault: hdr.Default != nil, - Converter: stringConverters[tpe.GoType], - Formatter: stringFormatters[tpe.GoType], - ZeroValue: tpe.Zero(), - CollectionFormat: hdr.CollectionFormat, - IndexVar: "i", + sharedValidations: sharedValidations{ + Required: true, + SchemaValidations: hdr.Validations(), // NOTE: Required is not defined by the Swagger schema for header. Set arbitrarily to true for convenience in templates. + }, + resolvedType: tpe, + Package: b.GenOpts.LanguageOpts.ManglePackageName(b.APIPackage, defaultOperationsTarget), + ReceiverName: receiver, + ID: id, + Name: name, + Path: fmt.Sprintf("%q", name), + ValueExpression: fmt.Sprintf("%s.%s", receiver, id), + Description: trimBOM(hdr.Description), + Default: hdr.Default, + HasDefault: hdr.Default != nil, + Converter: stringConverters[tpe.GoType], + Formatter: stringFormatters[tpe.GoType], + ZeroValue: tpe.Zero(), + CollectionFormat: hdr.CollectionFormat, + IndexVar: "i", } res.HasValidations, res.HasSliceValidations = b.HasValidations(hdr.CommonValidations, res.resolvedType) @@ -625,8 +625,12 @@ func (b *codeGenOpBuilder) MakeHeader(receiver, name string, hdr spec.Header) (G func (b *codeGenOpBuilder) MakeHeaderItem(receiver, paramName, indexVar, path, valueExpression string, items, parent *spec.Items) (GenItems, error) { var res GenItems - res.resolvedType = simpleResolvedType(items.Type, items.Format, items.Items) - res.sharedValidations = sharedValidationsFromSimple(items.CommonValidations, false) + res.resolvedType = simpleResolvedType(items.Type, items.Format, items.Items, &items.CommonValidations) + + res.sharedValidations = sharedValidations{ + Required: false, + SchemaValidations: items.Validations(), + } res.Name = paramName res.Path = path res.Location = "header" @@ -656,18 +660,20 @@ func (b *codeGenOpBuilder) MakeHeaderItem(receiver, paramName, indexVar, path, v // HasValidations resolves the validation status for simple schema objects func (b *codeGenOpBuilder) HasValidations(sh spec.CommonValidations, rt resolvedType) (hasValidations bool, hasSliceValidations bool) { - hasNumberValidation := sh.Maximum != nil || sh.Minimum != nil || sh.MultipleOf != nil - hasStringValidation := sh.MaxLength != nil || sh.MinLength != nil || sh.Pattern != "" - hasSliceValidations = sh.MaxItems != nil || sh.MinItems != nil || sh.UniqueItems || len(sh.Enum) > 0 - hasValidations = hasNumberValidation || hasStringValidation || hasSliceValidations || hasFormatValidation(rt) + hasSliceValidations = sh.HasArrayValidations() || sh.HasEnum() + hasValidations = sh.HasNumberValidations() || sh.HasStringValidations() || hasSliceValidations || hasFormatValidation(rt) return } func (b *codeGenOpBuilder) MakeParameterItem(receiver, paramName, indexVar, path, valueExpression, location string, resolver *typeResolver, items, parent *spec.Items) (GenItems, error) { debugLog("making parameter item recv=%s param=%s index=%s valueExpr=%s path=%s location=%s", receiver, paramName, indexVar, valueExpression, path, location) var res GenItems - res.resolvedType = simpleResolvedType(items.Type, items.Format, items.Items) - res.sharedValidations = sharedValidationsFromSimple(items.CommonValidations, false) + res.resolvedType = simpleResolvedType(items.Type, items.Format, items.Items, &items.CommonValidations) + + res.sharedValidations = sharedValidations{ + Required: false, + SchemaValidations: items.Validations(), + } res.Name = paramName res.Path = path res.Location = location @@ -741,8 +747,11 @@ func (b *codeGenOpBuilder) MakeParameter(receiver string, resolver *typeResolver } } else { // Process parameters declared in other inputs: path, query, header (SimpleSchema) - res.resolvedType = simpleResolvedType(param.Type, param.Format, param.Items) - res.sharedValidations = sharedValidationsFromSimple(param.CommonValidations, param.Required) + res.resolvedType = simpleResolvedType(param.Type, param.Format, param.Items, ¶m.CommonValidations) + res.sharedValidations = sharedValidations{ + Required: param.Required, + SchemaValidations: param.Validations(), + } res.ZeroValue = res.resolvedType.Zero() @@ -960,7 +969,7 @@ func (b *codeGenOpBuilder) setBodyParamValidation(p *GenParameter) { // makeSecuritySchemes produces a sorted list of security schemes for this operation func (b *codeGenOpBuilder) makeSecuritySchemes(receiver string) GenSecuritySchemes { - return gatherSecuritySchemes(b.SecurityDefinitions, b.Name, b.Principal, receiver) + return gatherSecuritySchemes(b.SecurityDefinitions, b.Name, b.Principal, receiver, b.GenOpts.PrincipalIsNullable()) } // makeSecurityRequirements produces a sorted list of security requirements for this operation. @@ -1006,7 +1015,7 @@ func (b *codeGenOpBuilder) saveResolveContext(resolver *typeResolver, schema *sp if b.PristineDoc == nil { b.PristineDoc = b.Doc.Pristine() } - rslv := newTypeResolver(b.GenOpts.LanguageOpts.ManglePackageName(resolver.ModelsPackage, defaultModelsTarget), b.PristineDoc) + rslv := newTypeResolver(b.GenOpts.LanguageOpts.ManglePackageName(resolver.ModelsPackage, defaultModelsTarget), b.DefaultImports[b.ModelsPackage], b.PristineDoc) return rslv, b.cloneSchema(schema) } @@ -1026,7 +1035,7 @@ func (b *codeGenOpBuilder) liftExtraSchemas(resolver, rslv *typeResolver, bs *sp pkg := b.GenOpts.LanguageOpts.ManglePackageName(resolver.ModelsPackage, defaultModelsTarget) // make a resolver for current package (i.e. operations) - pg.TypeResolver = newTypeResolver("", rslv.Doc).withKeepDefinitionsPackage(pkg) + pg.TypeResolver = newTypeResolver("", b.DefaultImports[b.APIPackage], rslv.Doc).withKeepDefinitionsPackage(pkg) pg.ExtraSchemas = make(map[string]GenSchema, len(sc.ExtraSchemas)) pg.UseContainerInName = true @@ -1062,7 +1071,10 @@ func (b *codeGenOpBuilder) buildOperationSchema(schemaPath, containerName, schem if sch == nil { sch = &spec.Schema{} } - rslv := resolver + shallowClonedResolver := *resolver + shallowClonedResolver.ModelsFullPkg = b.DefaultImports[b.ModelsPackage] + rslv := &shallowClonedResolver + sc := schemaGenContext{ Path: schemaPath, Name: containerName, @@ -1203,7 +1215,7 @@ func (b *codeGenOpBuilder) analyzeTags() (string, []string, bool) { } } if tag == b.APIPackage { - // confict with "operations" package is handled separately + // conflict with "operations" package is handled separately tag = renameOperationPackage(intersected, tag) } b.APIPackage = b.GenOpts.LanguageOpts.ManglePackageName(tag, b.APIPackage) // actual package name @@ -1238,11 +1250,14 @@ func deconflictPrincipal(pkg string) string { // deconflictPkg renames package names which conflict with standard imports func deconflictPkg(pkg string, renamer func(string) string) string { switch pkg { - case "api", "httptransport", "formats": + // package conflict with variables + case "api", "httptransport", "formats", "server": fallthrough + // package conflict with go-openapi imports case "errors", "runtime", "middleware", "security", "spec", "strfmt", "loads", "swag", "validate": fallthrough - case "tls", "http", "fmt", "strings", "log": + // package conflict with stdlib/other lib imports + case "tls", "http", "fmt", "strings", "log", "flags", "pflag", "json", "time": return renamer(pkg) } return pkg @@ -1260,5 +1275,16 @@ func renameOperationPackage(seenTags []string, pkg string) string { } func renamePrincipalPackage(pkg string) string { + // favors readability over perfect deconfliction return "auth" } + +func renameServerPackage(pkg string) string { + // favors readability over perfect deconfliction + return "swagger" + pkg + "srv" +} + +func renameAPIPackage(pkg string) string { + // favors readability over perfect deconfliction + return "swagger" + pkg +} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/shared.go b/vendor/github.com/go-swagger/go-swagger/generator/shared.go index 9321bf00f67a3..a79f6cd32389e 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/shared.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/shared.go @@ -197,6 +197,29 @@ func DefaultSectionOpts(gen *GenOpts) { } +// MarkdownOpts for rendering a spec as markdown +func MarkdownOpts() *LanguageOpts { + opts := &LanguageOpts{} + opts.Init() + return opts +} + +// MarkdownSectionOpts for a given opts and output file. +func MarkdownSectionOpts(gen *GenOpts, output string) { + gen.Sections.Models = nil + gen.Sections.OperationGroups = nil + gen.Sections.Operations = nil + gen.LanguageOpts = MarkdownOpts() + gen.Sections.Application = []TemplateOpts{ + { + Name: "markdowndocs", + Source: "asset:markdownDocs", + Target: filepath.Dir(output), + FileName: filepath.Base(output), + }, + } +} + // TemplateOpts allows for codegen customization type TemplateOpts struct { Name string `mapstructure:"name"` @@ -241,6 +264,7 @@ type GenOpts struct { ServerPackage string ClientPackage string Principal string + PrincipalCustomIface bool // user-provided interface for Principal (non-nullable) Target string Sections SectionOpts LanguageOpts *LanguageOpts @@ -268,6 +292,8 @@ type GenOpts struct { AllowEnumCI bool StrictResponders bool AcceptDefinitionsOnly bool + + templates *Repository // a shallow clone of the global template repository } // CheckOpts carries out some global consistency checks on options. @@ -362,12 +388,23 @@ func (g *GenOpts) SpecPath() string { return specRel } +// PrincipalIsNullable indicates whether the principal type used for authentication +// may be used as a pointer +func (g *GenOpts) PrincipalIsNullable() bool { + debugLog("Principal: %s, %t, isnullable: %t", g.Principal, g.PrincipalCustomIface, g.Principal != iface && !g.PrincipalCustomIface) + return g.Principal != iface && !g.PrincipalCustomIface +} + // EnsureDefaults for these gen opts func (g *GenOpts) EnsureDefaults() error { if g.defaultsEnsured { return nil } + g.templates = templates.ShallowClone() + + g.templates.LoadDefaults() + if g.LanguageOpts == nil { g.LanguageOpts = DefaultLanguageFunc() } @@ -401,6 +438,7 @@ func (g *GenOpts) EnsureDefaults() error { if g.Principal == "" { g.Principal = iface + g.PrincipalCustomIface = false } g.defaultsEnsured = true @@ -426,7 +464,9 @@ func (g *GenOpts) location(t *TemplateOpts, data interface{}) (string, string, e var tags []string tagsF := v.FieldByName("Tags") if tagsF.IsValid() { - tags = tagsF.Interface().([]string) + if tt, ok := tagsF.Interface().([]string); ok { + tags = tt + } } var useTags bool @@ -482,7 +522,7 @@ func (g *GenOpts) render(t *TemplateOpts, data interface{}) ([]byte, error) { var templ *template.Template if strings.HasPrefix(strings.ToLower(t.Source), "asset:") { - tt, err := templates.Get(strings.TrimPrefix(t.Source, "asset:")) + tt, err := g.templates.Get(strings.TrimPrefix(t.Source, "asset:")) if err != nil { return nil, err } @@ -492,7 +532,7 @@ func (g *GenOpts) render(t *TemplateOpts, data interface{}) ([]byte, error) { if templ == nil { // try to load from repository (and enable dependencies) name := swag.ToJSONName(strings.TrimSuffix(t.Source, ".gotmpl")) - tt, err := templates.Get(name) + tt, err := g.templates.Get(name) if err == nil { templ = tt } @@ -611,7 +651,8 @@ func (g *GenOpts) shouldRenderOperations() bool { func (g *GenOpts) renderApplication(app *GenApp) error { log.Printf("rendering %d templates for application %s", len(g.Sections.Application), app.Name) - for _, templ := range g.Sections.Application { + for _, tp := range g.Sections.Application { + templ := tp if !g.shouldRenderApp(&templ, app) { continue } @@ -624,7 +665,8 @@ func (g *GenOpts) renderApplication(app *GenApp) error { func (g *GenOpts) renderOperationGroup(gg *GenOperationGroup) error { log.Printf("rendering %d templates for operation group %s", len(g.Sections.OperationGroups), g.Name) - for _, templ := range g.Sections.OperationGroups { + for _, tp := range g.Sections.OperationGroups { + templ := tp if !g.shouldRenderOperations() { continue } @@ -638,7 +680,8 @@ func (g *GenOpts) renderOperationGroup(gg *GenOperationGroup) error { func (g *GenOpts) renderOperation(gg *GenOperation) error { log.Printf("rendering %d templates for operation %s", len(g.Sections.Operations), g.Name) - for _, templ := range g.Sections.Operations { + for _, tp := range g.Sections.Operations { + templ := tp if !g.shouldRenderOperations() { continue } @@ -652,7 +695,8 @@ func (g *GenOpts) renderOperation(gg *GenOperation) error { func (g *GenOpts) renderDefinition(gg *GenDefinition) error { log.Printf("rendering %d templates for model %s", len(g.Sections.Models), gg.Name) - for _, templ := range g.Sections.Models { + for _, tp := range g.Sections.Models { + templ := tp if !g.IncludeModel { continue } @@ -665,20 +709,18 @@ func (g *GenOpts) renderDefinition(gg *GenDefinition) error { } func (g *GenOpts) setTemplates() error { - templates.LoadDefaults() - if g.Template != "" { // set contrib templates - if err := templates.LoadContrib(g.Template); err != nil { + if err := g.templates.LoadContrib(g.Template); err != nil { return err } } - templates.SetAllowOverride(g.AllowTemplateOverride) + g.templates.SetAllowOverride(g.AllowTemplateOverride) if g.TemplateDir != "" { // set custom templates - if err := templates.LoadDir(g.TemplateDir); err != nil { + if err := g.templates.LoadDir(g.TemplateDir); err != nil { return err } } @@ -690,27 +732,33 @@ func (g *GenOpts) defaultImports() map[string]string { baseImport := g.LanguageOpts.baseImport(g.Target) defaultImports := make(map[string]string, 50) + var modelsAlias, importPath string if g.ExistingModels == "" { // generated models - importPath := path.Join( + importPath = path.Join( baseImport, g.LanguageOpts.ManglePackagePath(g.ModelPackage, defaultModelsTarget)) - defaultImports[g.LanguageOpts.ManglePackageName(g.ModelPackage, defaultModelsTarget)] = importPath + modelsAlias = g.LanguageOpts.ManglePackageName(g.ModelPackage, defaultModelsTarget) } else { // external models - importPath := g.LanguageOpts.ManglePackagePath(g.ExistingModels, "") - defaultImports["models"] = importPath + importPath = g.LanguageOpts.ManglePackagePath(g.ExistingModels, "") + modelsAlias = path.Base(defaultModelsTarget) } + defaultImports[modelsAlias] = importPath + // resolve model representing an authenticated principal alias, _, target := g.resolvePrincipal() - if alias != "" { - if pth, _ := path.Split(target); pth != "" { - // if principal is specified with an path, generate this import - defaultImports[alias] = target - } else { - // if principal is specified with a relative path, assume it is located in generated target - defaultImports[alias] = path.Join(baseImport, target) - } + if alias == "" || target == g.ModelPackage || path.Base(target) == modelsAlias { + // if principal is specified with the models generation package, do not import any extra package + return defaultImports + } + + if pth, _ := path.Split(target); pth != "" { + // if principal is specified with a path, assume this is a fully qualified package and generate this import + defaultImports[alias] = target + } else { + // if principal is specified with a relative path (no "/", e.g. internal.Principal), assume it is located in generated target + defaultImports[alias] = path.Join(baseImport, target) } return defaultImports } @@ -873,16 +921,18 @@ func trimBOM(in string) string { } // gatherSecuritySchemes produces a sorted representation from a map of spec security schemes -func gatherSecuritySchemes(securitySchemes map[string]spec.SecurityScheme, appName, principal, receiver string) (security GenSecuritySchemes) { +func gatherSecuritySchemes(securitySchemes map[string]spec.SecurityScheme, appName, principal, receiver string, nullable bool) (security GenSecuritySchemes) { for scheme, req := range securitySchemes { isOAuth2 := strings.ToLower(req.Type) == "oauth2" - var scopes []string + scopes := make([]string, 0, len(req.Scopes)) + genScopes := make([]GenSecurityScope, 0, len(req.Scopes)) if isOAuth2 { - for k := range req.Scopes { + for k, v := range req.Scopes { scopes = append(scopes, k) + genScopes = append(genScopes, GenSecurityScope{Name: k, Description: v}) } + sort.Strings(scopes) } - sort.Strings(scopes) security = append(security, GenSecurityScheme{ AppName: appName, @@ -893,6 +943,7 @@ func gatherSecuritySchemes(securitySchemes map[string]spec.SecurityScheme, appNa IsAPIKeyAuth: strings.ToLower(req.Type) == "apikey", IsOAuth2: isOAuth2, Scopes: scopes, + ScopesDesc: genScopes, Principal: principal, Source: req.In, // from original spec @@ -903,12 +954,26 @@ func gatherSecuritySchemes(securitySchemes map[string]spec.SecurityScheme, appNa AuthorizationURL: req.AuthorizationURL, TokenURL: req.TokenURL, Extensions: req.Extensions, + + PrincipalIsNullable: nullable, }) } sort.Sort(security) return } +// securityRequirements just clones the original SecurityRequirements from either the spec +// or an operation, without any modification. This is used to generate documentation. +func securityRequirements(orig []map[string][]string) (result []analysis.SecurityRequirement) { + for _, r := range orig { + for k, v := range r { + result = append(result, analysis.SecurityRequirement{Name: k, Scopes: v}) + } + } + // TODO(fred): sort this for stable generation + return +} + // gatherExtraSchemas produces a sorted list of extra schemas. // // ExtraSchemas are inlined types rendered in the same model file. @@ -927,42 +992,23 @@ func gatherExtraSchemas(extraMap map[string]GenSchema) (extras GenSchemaList) { return } -func sharedValidationsFromSimple(v spec.CommonValidations, isRequired bool) (sh sharedValidations) { - sh = sharedValidations{ - Required: isRequired, - Maximum: v.Maximum, - ExclusiveMaximum: v.ExclusiveMaximum, - Minimum: v.Minimum, - ExclusiveMinimum: v.ExclusiveMinimum, - MaxLength: v.MaxLength, - MinLength: v.MinLength, - Pattern: v.Pattern, - MaxItems: v.MaxItems, - MinItems: v.MinItems, - UniqueItems: v.UniqueItems, - MultipleOf: v.MultipleOf, - Enum: v.Enum, +func getExtraSchemes(ext spec.Extensions) []string { + if ess, ok := ext.GetStringSlice(xSchemes); ok { + return ess } - return + return nil } -func sharedValidationsFromSchema(v spec.Schema, isRequired bool) (sh sharedValidations) { - sh = sharedValidations{ - Required: isRequired, - Maximum: v.Maximum, - ExclusiveMaximum: v.ExclusiveMaximum, - Minimum: v.Minimum, - ExclusiveMinimum: v.ExclusiveMinimum, - MaxLength: v.MaxLength, - MinLength: v.MinLength, - Pattern: v.Pattern, - MaxItems: v.MaxItems, - MinItems: v.MinItems, - UniqueItems: v.UniqueItems, - MultipleOf: v.MultipleOf, - Enum: v.Enum, - } - return +func gatherURISchemes(swsp *spec.Swagger, operation spec.Operation) ([]string, []string) { + var extraSchemes []string + extraSchemes = append(extraSchemes, getExtraSchemes(operation.Extensions)...) + extraSchemes = concatUnique(getExtraSchemes(swsp.Extensions), extraSchemes) + sort.Strings(extraSchemes) + + schemes := concatUnique(swsp.Schemes, operation.Schemes) + sort.Strings(schemes) + + return schemes, extraSchemes } func dumpData(data interface{}) error { @@ -978,3 +1024,20 @@ func importAlias(pkg string) string { _, k := path.Split(pkg) return k } + +// concatUnique concatenate collections of strings with deduplication +func concatUnique(collections ...[]string) []string { + resultSet := make(map[string]struct{}) + for _, c := range collections { + for _, i := range c { + if _, ok := resultSet[i]; !ok { + resultSet[i] = struct{}{} + } + } + } + result := make([]string, 0, len(resultSet)) + for k := range resultSet { + result = append(result, k) + } + return result +} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/spec.go b/vendor/github.com/go-swagger/go-swagger/generator/spec.go index 68e08ce44532c..1c1ddbaed6801 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/spec.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/spec.go @@ -119,7 +119,7 @@ func (g *GenOpts) printFlattenOpts() { log.Printf("preprocessing spec with option: %s", preprocessingOption) } -//findSwaggerSpec fetches a default swagger spec if none is provided +// findSwaggerSpec fetches a default swagger spec if none is provided func findSwaggerSpec(nm string) (string, error) { specs := []string{"swagger.json", "swagger.yml", "swagger.yaml"} if nm != "" { @@ -168,7 +168,7 @@ func WithAutoXOrder(specPath string) string { for i, prop := range props { if pSlice, ok := prop.Value.(yaml.MapSlice); ok { isObject := false - xOrderIndex := -1 //Find if x-order already exists + xOrderIndex := -1 // find if x-order already exists for i, v := range pSlice { if v.Key == "type" && v.Value == object { @@ -180,7 +180,7 @@ func WithAutoXOrder(specPath string) string { } } - if xOrderIndex > -1 { //Override existing x-order + if xOrderIndex > -1 { // override existing x-order pSlice[xOrderIndex] = yaml.MapItem{Key: xOrder, Value: i} } else { // append new x-order pSlice = append(pSlice, yaml.MapItem{Key: xOrder, Value: i}) diff --git a/vendor/github.com/go-swagger/go-swagger/generator/structs.go b/vendor/github.com/go-swagger/go-swagger/generator/structs.go index 16ae892f04339..3e88c9a910396 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/structs.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/structs.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" + "github.com/go-openapi/analysis" "github.com/go-openapi/spec" ) @@ -94,6 +95,106 @@ type GenSchema struct { WantsMarshalBinary bool // do we generate MarshalBinary interface? StructTags []string ExtraImports map[string]string // non-standard imports detected when using external types + ExternalDocs *spec.ExternalDocumentation +} + +func (g GenSchema) renderMarshalTag() string { + if g.HasBaseType { + return "-" + } + + var result strings.Builder + + result.WriteString(g.OriginalName) + + if !g.Required && g.IsEmptyOmitted { + result.WriteString(",omitempty") + } + + if g.IsJSONString { + result.WriteString(",string") + } + + return result.String() +} + +// PrintTags takes care of rendering tags for a struct field +func (g GenSchema) PrintTags() string { + tags := make(map[string]string, 3) + orderedTags := make([]string, 0, 3) + + tags["json"] = g.renderMarshalTag() + orderedTags = append(orderedTags, "json") + + if len(g.XMLName) > 0 { + if !g.Required && g.IsEmptyOmitted { + tags["xml"] = g.XMLName + ",omitempty" + } else { + tags["xml"] = g.XMLName + } + orderedTags = append(orderedTags, "xml") + } + + // Add extra struct tags, only if the tag hasn't already been set, i.e. example. + // Extra struct tags have the same value has the `json` tag. + for _, tag := range g.StructTags { + if _, exists := tags[tag]; exists { + // dedupe + continue + } + + if tag == "example" && len(g.Example) > 0 { + // only add example tag if it's contained in the struct tags + tags["example"] = g.Example // json representation of the example object + } else { + tags[tag] = tags["json"] + } + + orderedTags = append(orderedTags, tag) + } + + // Assemble the tags in key value pairs with the value properly quoted. + kvPairs := make([]string, 0, len(orderedTags)+1) + for _, key := range orderedTags { + kvPairs = append(kvPairs, fmt.Sprintf("%s:%s", key, strconv.Quote(tags[key]))) + } + + if len(g.CustomTag) > 0 { + kvPairs = append(kvPairs, g.CustomTag) + } + + // Join the key value pairs by a space. + completeTag := strings.Join(kvPairs, " ") + + // If the values contain a backtick, we cannot render the tag using backticks because Go does not support + // escaping backticks in raw string literals. + valuesHaveBacktick := false + for _, value := range tags { + if !strconv.CanBackquote(value) { + valuesHaveBacktick = true + break + } + } + + if !valuesHaveBacktick { + return fmt.Sprintf("`%s`", completeTag) + } + + // We have to escape the tag again to put it in a literal with double quotes as the tag format uses double quotes. + return strconv.Quote(completeTag) +} + +// UnderlyingType tells the go type or the aliased go type +func (g GenSchema) UnderlyingType() string { + if g.IsAliased { + return g.AliasedType + } + return g.GoType +} + +// ToString returns a string conversion expression for the schema +func (g GenSchema) ToString() string { + return g.resolvedType.ToString(g.ValueExpression) } func (g GenSchemaList) Len() int { return len(g) } @@ -122,32 +223,13 @@ func (g GenSchemaList) Less(i, j int) bool { } type sharedValidations struct { - HasValidations bool - Required bool - - // String validations - MaxLength *int64 - MinLength *int64 - Pattern string - - // Number validations - MultipleOf *float64 - Minimum *float64 - Maximum *float64 - ExclusiveMinimum bool - ExclusiveMaximum bool + spec.SchemaValidations - Enum []interface{} - ItemsEnum []interface{} - - // Slice validations - MinItems *int64 - MaxItems *int64 - UniqueItems bool - HasSliceValidations bool - - // Not used yet (perhaps intended for maxProperties, minProperties validations?) - NeedsSize bool + HasValidations bool + HasContextValidations bool + Required bool + HasSliceValidations bool + ItemsEnum []interface{} // NOTE: "patternProperties" and "dependencies" not supported by Swagger 2.0 } @@ -176,6 +258,20 @@ type GenResponse struct { StrictResponders bool OperationName string + Examples GenResponseExamples +} + +// GenResponseExamples is a sortable collection []GenResponseExample +type GenResponseExamples []GenResponseExample + +func (g GenResponseExamples) Len() int { return len(g) } +func (g GenResponseExamples) Swap(i, j int) { g[i], g[j] = g[j], g[i] } +func (g GenResponseExamples) Less(i, j int) bool { return g[i].MediaType < g[j].MediaType } + +// GenResponseExample captures an example provided for a response for some mime type +type GenResponseExample struct { + MediaType string + Example interface{} } // GenHeader represents a header on a response for code generation @@ -210,11 +306,16 @@ type GenHeader struct { // ItemsDepth returns a string "items.items..." with as many items as the level of nesting of the array. // For a header objects it always returns "". -func (g *GenHeader) ItemsDepth() string { +func (h *GenHeader) ItemsDepth() string { // NOTE: this is currently used by templates to generate explicit comments in nested structures return "" } +// ToString returns a string conversion expression for the header +func (h GenHeader) ToString() string { + return h.resolvedType.ToString(h.ValueExpression) +} + // GenHeaders is a sorted collection of headers for codegen type GenHeaders []GenHeader @@ -260,8 +361,8 @@ type GenParameter struct { Child *GenItems Parent *GenItems - /// Unused - //BodyParam *GenParameter + // Unused + // BodyParam *GenParameter Default interface{} HasDefault bool @@ -323,6 +424,16 @@ func (g *GenParameter) ItemsDepth() string { return "" } +// UnderlyingType tells the go type or the aliased go type +func (g GenParameter) UnderlyingType() string { + return g.GoType +} + +// ToString returns a string conversion expression for the parameter +func (g GenParameter) ToString() string { + return g.resolvedType.ToString(g.ValueExpression) +} + // GenParameters represents a sorted parameter collection type GenParameters []GenParameter @@ -377,6 +488,16 @@ func (g *GenItems) ItemsDepth() string { return strings.Repeat("items.", i) } +// UnderlyingType tells the go type or the aliased go type +func (g GenItems) UnderlyingType() string { + return g.GoType +} + +// ToString returns a string conversion expression for the item +func (g GenItems) ToString() string { + return g.resolvedType.ToString(g.ValueExpression) +} + // GenOperationGroup represents a named (tagged) group of operations type GenOperationGroup struct { GenCommon @@ -470,10 +591,12 @@ type GenOperation struct { ExtraSchemas GenSchemaList PackageAlias string - Authorized bool - Security []GenSecurityRequirements - SecurityDefinitions GenSecuritySchemes - Principal string + Authorized bool + Security []GenSecurityRequirements // resolved security requirements for the operation + SecurityDefinitions GenSecuritySchemes + SecurityRequirements []analysis.SecurityRequirement // original security requirements as per the spec (for doc) + Principal string + PrincipalIsNullable bool SuccessResponse *GenResponse SuccessResponses []GenResponse @@ -494,15 +617,20 @@ type GenOperation struct { HasBodyParams bool HasStreamingResponse bool - Schemes []string - ExtraSchemes []string - ProducesMediaTypes []string - ConsumesMediaTypes []string - TimeoutName string + Schemes []string + ExtraSchemes []string + SchemeOverrides []string // original scheme overrides for operation, as per spec (for doc) + ExtraSchemeOverrides []string // original extra scheme overrides for operation, as per spec (for doc) + ProducesMediaTypes []string + ConsumesMediaTypes []string + TimeoutName string Extensions map[string]interface{} StrictResponders bool + ExternalDocs *spec.ExternalDocumentation + Produces []string // original produces for operation (for doc) + Consumes []string // original consumes for operation (for doc) } // GenOperations represents a list of operations to generate @@ -517,28 +645,33 @@ func (g GenOperations) Swap(i, j int) { g[i], g[j] = g[j], g[i] } // from a swagger spec type GenApp struct { GenCommon - APIPackage string - Package string - ReceiverName string - Name string - Principal string - DefaultConsumes string - DefaultProduces string - Host string - BasePath string - Info *spec.Info - ExternalDocs *spec.ExternalDocumentation - Imports map[string]string - DefaultImports map[string]string - Schemes []string - ExtraSchemes []string - Consumes GenSerGroups - Produces GenSerGroups - SecurityDefinitions GenSecuritySchemes - Models []GenDefinition - Operations GenOperations - OperationGroups GenOperationGroups - SwaggerJSON string + APIPackage string + ServerPackageAlias string + APIPackageAlias string + Package string + ReceiverName string + Name string + Principal string + PrincipalIsNullable bool + DefaultConsumes string + DefaultProduces string + Host string + BasePath string + Info *spec.Info + ExternalDocs *spec.ExternalDocumentation + Tags []spec.Tag + Imports map[string]string + DefaultImports map[string]string + Schemes []string + ExtraSchemes []string + Consumes GenSerGroups + Produces GenSerGroups + SecurityDefinitions GenSecuritySchemes + SecurityRequirements []analysis.SecurityRequirement // original security requirements as per the spec (for doc) + Models []GenDefinition + Operations GenOperations + OperationGroups GenOperationGroups + SwaggerJSON string // Embedded specs: this is important for when the generated server adds routes. // NOTE: there is a distinct advantage to having this in runtime rather than generated code. // We are not ever going to generate the router. @@ -613,16 +746,18 @@ type GenSerializer struct { // GenSecurityScheme represents a security scheme for code generation type GenSecurityScheme struct { - AppName string - ID string - Name string - ReceiverName string - IsBasicAuth bool - IsAPIKeyAuth bool - IsOAuth2 bool - Scopes []string - Source string - Principal string + AppName string + ID string + Name string + ReceiverName string + IsBasicAuth bool + IsAPIKeyAuth bool + IsOAuth2 bool + Scopes []string + Source string + Principal string + PrincipalIsNullable bool + // from spec.SecurityScheme Description string Type string @@ -631,6 +766,7 @@ type GenSecurityScheme struct { AuthorizationURL string TokenURL string Extensions map[string]interface{} + ScopesDesc []GenSecurityScope } // GenSecuritySchemes sorted representation of serializers @@ -646,6 +782,12 @@ type GenSecurityRequirement struct { Scopes []string } +// GenSecurityScope represents a scope descriptor for an OAuth2 security scheme +type GenSecurityScope struct { + Name string + Description string +} + // GenSecurityRequirements represents a compounded security requirement specification. // In a []GenSecurityRequirements complete requirements specification, // outer elements are interpreted as optional requirements (OR), and diff --git a/vendor/github.com/go-swagger/go-swagger/generator/support.go b/vendor/github.com/go-swagger/go-swagger/generator/support.go index a1184ff8e8ce0..3697e255daf68 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/support.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/support.go @@ -49,6 +49,25 @@ func GenerateSupport(name string, modelNames, operationIDs []string, opts *GenOp return generator.GenerateSupport(nil) } +// GenerateMarkdown documentation for a swagger specification +func GenerateMarkdown(output string, modelNames, operationIDs []string, opts *GenOpts) error { + if output == "." || output == "" { + output = "markdown.md" + } + + if err := opts.EnsureDefaults(); err != nil { + return err + } + MarkdownSectionOpts(opts, output) + + generator, err := newAppGenerator("", modelNames, operationIDs, opts) + if err != nil { + return err + } + + return generator.GenerateMarkdown() +} + func newAppGenerator(name string, modelNames, operationIDs []string, opts *GenOpts) (*appGenerator, error) { if err := opts.CheckOpts(); err != nil { return nil, err @@ -142,7 +161,8 @@ func (a *appGenerator) Generate() error { // templates are now lazy loaded so there is concurrent map access I can't guard if a.GenOpts.IncludeModel { log.Printf("rendering %d models", len(app.Models)) - for _, mod := range app.Models { + for _, md := range app.Models { + mod := md mod.IncludeModel = true mod.IncludeValidator = a.GenOpts.IncludeValidator if err := a.GenOpts.renderDefinition(&mod); err != nil { @@ -153,9 +173,11 @@ func (a *appGenerator) Generate() error { if a.GenOpts.IncludeHandler { log.Printf("rendering %d operation groups (tags)", app.OperationGroups.Len()) - for _, opg := range app.OperationGroups { + for _, g := range app.OperationGroups { + opg := g log.Printf("rendering %d operations for %s", opg.Operations.Len(), opg.Name) - for _, op := range opg.Operations { + for _, p := range opg.Operations { + op := p if err := a.GenOpts.renderOperation(&op); err != nil { return err } @@ -190,11 +212,23 @@ func (a *appGenerator) GenerateSupport(ap *GenApp) error { baseImport := a.GenOpts.LanguageOpts.baseImport(a.Target) serverPath := path.Join(baseImport, a.GenOpts.LanguageOpts.ManglePackagePath(a.ServerPackage, defaultServerTarget)) - app.DefaultImports[importAlias(serverPath)] = serverPath + + pkgAlias := deconflictPkg(importAlias(serverPath), renameServerPackage) + app.DefaultImports[pkgAlias] = serverPath + app.ServerPackageAlias = pkgAlias return a.GenOpts.renderApplication(app) } +func (a *appGenerator) GenerateMarkdown() error { + app, err := a.makeCodegenApp() + if err != nil { + return err + } + + return a.GenOpts.renderApplication(&app) +} + func (a *appGenerator) makeSecuritySchemes() GenSecuritySchemes { requiredSecuritySchemes := make(map[string]spec.SecurityScheme, len(a.Analyzed.RequiredSecuritySchemes())) for _, scheme := range a.Analyzed.RequiredSecuritySchemes() { @@ -202,7 +236,7 @@ func (a *appGenerator) makeSecuritySchemes() GenSecuritySchemes { requiredSecuritySchemes[scheme] = *req } } - return gatherSecuritySchemes(requiredSecuritySchemes, a.Name, a.Principal, a.Receiver) + return gatherSecuritySchemes(requiredSecuritySchemes, a.Name, a.Principal, a.Receiver, a.GenOpts.PrincipalIsNullable()) } func (a *appGenerator) makeCodegenApp() (GenApp, error) { @@ -219,9 +253,14 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) { baseImport := a.GenOpts.LanguageOpts.baseImport(a.Target) defaultImports := a.GenOpts.defaultImports() - imports := a.GenOpts.initImports(a.OperationsPackage) - log.Println("planning definitions") + imports := make(map[string]string, 50) + alias := deconflictPkg(a.GenOpts.LanguageOpts.ManglePackageName(a.OperationsPackage, defaultOperationsTarget), renameAPIPackage) + imports[alias] = path.Join( + baseImport, + a.GenOpts.LanguageOpts.ManglePackagePath(a.OperationsPackage, defaultOperationsTarget)) + + log.Printf("planning definitions (found: %d)", len(a.Models)) genModels := make(GenDefinitions, 0, len(a.Models)) for mn, m := range a.Models { @@ -250,7 +289,7 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) { } sort.Sort(genModels) - log.Println("planning operations") + log.Printf("planning operations (found: %d)", len(a.Operations)) genOps := make(GenOperations, 0, len(a.Operations)) for operationName, opp := range a.Operations { @@ -318,15 +357,16 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) { } sort.Sort(genOps) - log.Println("grouping operations into packages") - opsGroupedByPackage := make(map[string]GenOperations, len(genOps)) for _, operation := range genOps { opsGroupedByPackage[operation.PackageAlias] = append(opsGroupedByPackage[operation.PackageAlias], operation) } + log.Printf("grouping operations into packages (packages: %d)", len(opsGroupedByPackage)) + opGroups := make(GenOperationGroups, 0, len(opsGroupedByPackage)) for k, v := range opsGroupedByPackage { + log.Printf("operations for package packages %q (found: %d)", k, len(v)) sort.Sort(v) // trim duplicate extra schemas within the same package vv := make(GenOperations, 0, len(v)) @@ -368,8 +408,7 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) { log.Println("planning meta data and facades") - var collectedSchemes []string - var extraSchemes []string + var collectedSchemes, extraSchemes []string for _, op := range genOps { collectedSchemes = concatUnique(collectedSchemes, op.Schemes) extraSchemes = concatUnique(extraSchemes, op.ExtraSchemes) @@ -395,31 +434,36 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) { Copyright: a.GenOpts.Copyright, TargetImportPath: baseImport, }, - APIPackage: a.GenOpts.LanguageOpts.ManglePackageName(a.ServerPackage, defaultServerTarget), - Package: a.Package, - ReceiverName: receiver, - Name: a.Name, - Host: host, - BasePath: basePath, - Schemes: schemeOrDefault(collectedSchemes, a.DefaultScheme), - ExtraSchemes: extraSchemes, - ExternalDocs: sw.ExternalDocs, - Info: sw.Info, - Consumes: consumes, - Produces: produces, - DefaultConsumes: a.DefaultConsumes, - DefaultProduces: a.DefaultProduces, - DefaultImports: defaultImports, - Imports: imports, - SecurityDefinitions: security, - Models: genModels, - Operations: genOps, - OperationGroups: opGroups, - Principal: a.GenOpts.PrincipalAlias(), - SwaggerJSON: generateReadableSpec(jsonb), - FlatSwaggerJSON: generateReadableSpec(flatjsonb), - ExcludeSpec: a.GenOpts.ExcludeSpec, - GenOpts: a.GenOpts, + APIPackage: a.GenOpts.LanguageOpts.ManglePackageName(a.ServerPackage, defaultServerTarget), + APIPackageAlias: alias, + Package: a.Package, + ReceiverName: receiver, + Name: a.Name, + Host: host, + BasePath: basePath, + Schemes: schemeOrDefault(collectedSchemes, a.DefaultScheme), + ExtraSchemes: extraSchemes, + ExternalDocs: trimExternalDoc(sw.ExternalDocs), + Tags: trimTags(sw.Tags), + Info: trimInfo(sw.Info), + Consumes: consumes, + Produces: produces, + DefaultConsumes: a.DefaultConsumes, + DefaultProduces: a.DefaultProduces, + DefaultImports: defaultImports, + Imports: imports, + SecurityDefinitions: security, + SecurityRequirements: securityRequirements(a.SpecDoc.Spec().Security), // top level securityRequirements + Models: genModels, + Operations: genOps, + OperationGroups: opGroups, + Principal: a.GenOpts.PrincipalAlias(), + SwaggerJSON: generateReadableSpec(jsonb), + FlatSwaggerJSON: generateReadableSpec(flatjsonb), + ExcludeSpec: a.GenOpts.ExcludeSpec, + GenOpts: a.GenOpts, + + PrincipalIsNullable: a.GenOpts.PrincipalIsNullable(), }, nil } @@ -438,3 +482,52 @@ func generateReadableSpec(spec []byte) string { } return buf.String() } + +func trimExternalDoc(in *spec.ExternalDocumentation) *spec.ExternalDocumentation { + if in == nil { + return nil + } + + return &spec.ExternalDocumentation{ + URL: in.URL, + Description: trimBOM(in.Description), + } +} + +func trimInfo(in *spec.Info) *spec.Info { + if in == nil { + return nil + } + + return &spec.Info{ + InfoProps: spec.InfoProps{ + Contact: in.Contact, + Title: trimBOM(in.Title), + Description: trimBOM(in.Description), + TermsOfService: trimBOM(in.TermsOfService), + License: in.License, + Version: in.Version, + }, + VendorExtensible: in.VendorExtensible, + } +} + +func trimTags(in []spec.Tag) []spec.Tag { + if in == nil { + return nil + } + + tags := make([]spec.Tag, 0, len(in)) + + for _, tag := range in { + tags = append(tags, spec.Tag{ + TagProps: spec.TagProps{ + Name: tag.Name, + Description: trimBOM(tag.Description), + ExternalDocs: trimExternalDoc(tag.ExternalDocs), + }, + }) + } + + return tags +} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/template_repo.go b/vendor/github.com/go-swagger/go-swagger/generator/template_repo.go index c84951a185957..9ea18470ec653 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/template_repo.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/template_repo.go @@ -5,10 +5,14 @@ import ( "encoding/json" "fmt" "io/ioutil" + "math" "os" "path" "path/filepath" + "reflect" + "strconv" "strings" + "sync" "text/template" "text/template/parse" "unicode" @@ -16,6 +20,7 @@ import ( "log" "github.com/go-openapi/inflect" + "github.com/go-openapi/runtime" "github.com/go-openapi/swag" "github.com/kr/pretty" ) @@ -28,6 +33,8 @@ var ( FuncMapFunc func(*LanguageOpts) template.FuncMap templates *Repository + + docFormat map[string]string ) func initTemplateRepo() { @@ -40,6 +47,11 @@ func initTemplateRepo() { assets = defaultAssets() protectedTemplates = defaultProtectedTemplates() templates = NewRepository(FuncMapFunc(DefaultLanguageFunc())) + + docFormat = map[string]string{ + "binary": "binary (byte stream)", + "byte": "byte (base64 string)", + } } // DefaultFuncMap yields a map with default functions for use n the templates. @@ -72,9 +84,11 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap { }, "dropPackage": dropPackage, "upper": strings.ToUpper, + "lower": strings.ToLower, "contains": swag.ContainsStrings, "padSurround": padSurround, "joinFilePath": filepath.Join, + "joinPath": path.Join, "comment": padComment, "blockcomment": blockComment, "inspect": pretty.Sprint, @@ -85,6 +99,44 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap { "stringContains": strings.Contains, "imports": lang.imports, "dict": dict, + "isInteger": isInteger, + "escapeBackticks": func(arg string) string { + return strings.ReplaceAll(arg, "`", "`+\"`\"+`") + }, + "paramDocType": func(param GenParameter) string { + return resolvedDocType(param.SwaggerType, param.SwaggerFormat, param.Child) + }, + "headerDocType": func(header GenHeader) string { + return resolvedDocType(header.SwaggerType, header.SwaggerFormat, header.Child) + }, + "schemaDocType": func(in interface{}) string { + switch schema := in.(type) { + case GenSchema: + return resolvedDocSchemaType(schema.SwaggerType, schema.SwaggerFormat, schema.Items) + case *GenSchema: + if schema == nil { + return "" + } + return resolvedDocSchemaType(schema.SwaggerType, schema.SwaggerFormat, schema.Items) + case GenDefinition: + return resolvedDocSchemaType(schema.SwaggerType, schema.SwaggerFormat, schema.Items) + case *GenDefinition: + if schema == nil { + return "" + } + return resolvedDocSchemaType(schema.SwaggerType, schema.SwaggerFormat, schema.Items) + default: + panic("dev error: schemaDocType should be called with GenSchema or GenDefinition") + } + }, + "schemaDocMapType": func(schema GenSchema) string { + return resolvedDocElemType("object", schema.SwaggerFormat, &schema.resolvedType) + }, + "docCollectionFormat": resolvedDocCollectionFormat, + "trimSpace": strings.TrimSpace, + "httpStatus": httpStatus, + "cleanupEnumVariant": cleanupEnumVariant, + "gt0": gt0, }) } @@ -98,6 +150,9 @@ func defaultAssets() map[string][]byte { "schemavalidator.gotmpl": MustAsset("templates/schemavalidator.gotmpl"), "schemapolymorphic.gotmpl": MustAsset("templates/schemapolymorphic.gotmpl"), "schemaembedded.gotmpl": MustAsset("templates/schemaembedded.gotmpl"), + "validation/minimum.gotmpl": MustAsset("templates/validation/minimum.gotmpl"), + "validation/maximum.gotmpl": MustAsset("templates/validation/maximum.gotmpl"), + "validation/multipleOf.gotmpl": MustAsset("templates/validation/multipleOf.gotmpl"), // schema serialization templates "additionalpropertiesserializer.gotmpl": MustAsset("templates/serializers/additionalpropertiesserializer.gotmpl"), @@ -117,6 +172,10 @@ func defaultAssets() map[string][]byte { "model.gotmpl": MustAsset("templates/model.gotmpl"), "header.gotmpl": MustAsset("templates/header.gotmpl"), + // simple schema generation helpers templates + "simpleschema/defaultsvar.gotmpl": MustAsset("templates/simpleschema/defaultsvar.gotmpl"), + "simpleschema/defaultsinit.gotmpl": MustAsset("templates/simpleschema/defaultsinit.gotmpl"), + "swagger_json_embed.gotmpl": MustAsset("templates/swagger_json_embed.gotmpl"), // server templates @@ -135,6 +194,8 @@ func defaultAssets() map[string][]byte { "client/response.gotmpl": MustAsset("templates/client/response.gotmpl"), "client/client.gotmpl": MustAsset("templates/client/client.gotmpl"), "client/facade.gotmpl": MustAsset("templates/client/facade.gotmpl"), + + "markdown/docs.gotmpl": MustAsset("templates/markdown/docs.gotmpl"), } } @@ -167,13 +228,20 @@ func defaultProtectedTemplates() map[string]bool { "tuplefield": true, "tuplefieldIface": true, "typeSchemaType": true, - "validationCustomformat": true, - "validationPrimitive": true, - "validationStructfield": true, - "withBaseTypeBody": true, - "withoutBaseTypeBody": true, - - // all serializers TODO(fred) + "simpleschemaDefaultsvar": true, + "simpleschemaDefaultsinit": true, + + // validation helpers + "validationCustomformat": true, + "validationPrimitive": true, + "validationStructfield": true, + "withBaseTypeBody": true, + "withoutBaseTypeBody": true, + "validationMinimum": true, + "validationMaximum": true, + "validationMultipleOf": true, + + // all serializers "additionalPropertiesSerializer": true, "tupleSerializer": true, "schemaSerializer": true, @@ -213,6 +281,31 @@ type Repository struct { templates map[string]*template.Template funcs template.FuncMap allowOverride bool + mux sync.Mutex +} + +// ShallowClone a repository. +// +// Clones the maps of files and templates, so as to be able to use +// the cloned repo concurrently. +func (t *Repository) ShallowClone() *Repository { + clone := &Repository{ + files: make(map[string]string, len(t.files)), + templates: make(map[string]*template.Template, len(t.templates)), + funcs: t.funcs, + allowOverride: t.allowOverride, + } + + t.mux.Lock() + defer t.mux.Unlock() + + for k, file := range t.files { + clone.files[k] = file + } + for k, tpl := range t.templates { + clone.templates[k] = tpl + } + return clone } // LoadDefaults will load the embedded templates @@ -532,7 +625,7 @@ func padComment(str string, pads ...string) string { } func blockComment(str string) string { - return strings.Replace(str, "*/", "[*]/", -1) + return strings.ReplaceAll(str, "*/", "[*]/") } func pascalize(arg string) string { @@ -566,6 +659,28 @@ func prefixForName(arg string) string { return "Nr" } +func replaceSpecialChar(in rune) string { + switch in { + case '.': + return "-Dot-" + case '+': + return "-Plus-" + case '-': + return "-Dash-" + case '#': + return "-Hashtag-" + } + return string(in) +} + +func cleanupEnumVariant(in string) string { + replaced := "" + for _, char := range in { + replaced += replaceSpecialChar(char) + } + return replaced +} + func dict(values ...interface{}) (map[string]interface{}, error) { if len(values)%2 != 0 { return nil, fmt.Errorf("expected even number of arguments, got %d", len(values)) @@ -580,3 +695,132 @@ func dict(values ...interface{}) (map[string]interface{}, error) { } return dict, nil } + +func isInteger(arg interface{}) bool { + // is integer determines if a value may be represented by an integer + switch val := arg.(type) { + case int8, int16, int32, int, int64, uint8, uint16, uint32, uint, uint64: + return true + case *int8, *int16, *int32, *int, *int64, *uint8, *uint16, *uint32, *uint, *uint64: + v := reflect.ValueOf(arg) + return !v.IsNil() + case float64: + return math.Round(val) == val + case *float64: + return val != nil && math.Round(*val) == *val + case float32: + return math.Round(float64(val)) == float64(val) + case *float32: + return val != nil && math.Round(float64(*val)) == float64(*val) + case string: + _, err := strconv.ParseInt(val, 10, 64) + return err == nil + case *string: + if val == nil { + return false + } + _, err := strconv.ParseInt(*val, 10, 64) + return err == nil + default: + return false + } +} + +func resolvedDocCollectionFormat(cf string, child *GenItems) string { + if child == nil { + return cf + } + ccf := cf + if ccf == "" { + ccf = "csv" + } + rcf := resolvedDocCollectionFormat(child.CollectionFormat, child.Child) + if rcf == "" { + return ccf + } + return ccf + "|" + rcf +} + +func resolvedDocType(tn, ft string, child *GenItems) string { + if tn == "array" { + if child == nil { + return "[]any" + } + return "[]" + resolvedDocType(child.SwaggerType, child.SwaggerFormat, child.Child) + } + + if ft != "" { + if doc, ok := docFormat[ft]; ok { + return doc + } + return fmt.Sprintf("%s (formatted %s)", ft, tn) + } + + return tn +} + +func resolvedDocSchemaType(tn, ft string, child *GenSchema) string { + if tn == "array" { + if child == nil { + return "[]any" + } + return "[]" + resolvedDocSchemaType(child.SwaggerType, child.SwaggerFormat, child.Items) + } + + if tn == "object" { + if child == nil || child.ElemType == nil { + return "map of any" + } + if child.IsMap { + return "map of " + resolvedDocElemType(child.SwaggerType, child.SwaggerFormat, &child.resolvedType) + } + + return child.GoType + } + + if ft != "" { + if doc, ok := docFormat[ft]; ok { + return doc + } + return fmt.Sprintf("%s (formatted %s)", ft, tn) + } + + return tn +} + +func resolvedDocElemType(tn, ft string, schema *resolvedType) string { + if schema == nil { + return "" + } + if schema.IsMap { + return "map of " + resolvedDocElemType(schema.ElemType.SwaggerType, schema.ElemType.SwaggerFormat, schema.ElemType) + } + + if schema.IsArray { + return "[]" + resolvedDocElemType(schema.ElemType.SwaggerType, schema.ElemType.SwaggerFormat, schema.ElemType) + } + + if ft != "" { + if doc, ok := docFormat[ft]; ok { + return doc + } + return fmt.Sprintf("%s (formatted %s)", ft, tn) + } + + return tn +} + +func httpStatus(code int) string { + if name, ok := runtime.Statuses[code]; ok { + return name + } + // non-standard codes deserve some name + return fmt.Sprintf("Status %d", code) +} + +func gt0(in *int64) bool { + // gt0 returns true if the *int64 points to a value > 0 + // NOTE: plain {{ gt .MinProperties 0 }} just refuses to work normally + // with a pointer + return in != nil && *in > 0 +} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/types.go b/vendor/github.com/go-swagger/go-swagger/generator/types.go index e4d2493a370a1..df7472eaec44b 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/types.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/types.go @@ -17,8 +17,8 @@ package generator import ( "fmt" "log" - "path" "path/filepath" + "reflect" "strings" "github.com/go-openapi/loads" @@ -69,10 +69,14 @@ func initTypes() { } } -func simpleResolvedType(tn, fmt string, items *spec.Items) (result resolvedType) { +func simpleResolvedType(tn, fmt string, items *spec.Items, v *spec.CommonValidations) (result resolvedType) { result.SwaggerType = tn result.SwaggerFormat = fmt + defer func() { + guardValidations(result.SwaggerType, v) + }() + if tn == file { // special case of swagger type "file", rendered as io.ReadCloser interface result.IsPrimitive = true @@ -82,7 +86,11 @@ func simpleResolvedType(tn, fmt string, items *spec.Items) (result resolvedType) } if fmt != "" { - fmtn := strings.Replace(fmt, "-", "", -1) + defer func() { + guardFormatConflicts(result.SwaggerFormat, v) + }() + + fmtn := strings.ReplaceAll(fmt, "-", "") if fmm, ok := formatMapping[tn]; ok { if tpe, ok := fmm[fmtn]; ok { result.GoType = tpe @@ -114,7 +122,7 @@ func simpleResolvedType(tn, fmt string, items *spec.Items) (result resolvedType) result.GoType = "[]" + iface return } - res := simpleResolvedType(items.Type, items.Format, items.Items) + res := simpleResolvedType(items.Type, items.Format, items.Items, &items.CommonValidations) result.GoType = "[]" + res.GoType return } @@ -123,22 +131,18 @@ func simpleResolvedType(tn, fmt string, items *spec.Items) (result resolvedType) return } -func typeForHeader(header spec.Header) resolvedType { - return simpleResolvedType(header.Type, header.Format, header.Items) -} - -func newTypeResolver(pkg string, doc *loads.Document) *typeResolver { +func newTypeResolver(pkg, fullPkg string, doc *loads.Document) *typeResolver { resolver := typeResolver{ModelsPackage: pkg, Doc: doc} resolver.KnownDefs = make(map[string]struct{}, len(doc.Spec().Definitions)) for k, sch := range doc.Spec().Definitions { - tpe, _, _ := knownDefGoType(k, sch, nil) + tpe, _, _ := resolver.knownDefGoType(k, sch, nil) resolver.KnownDefs[tpe] = struct{}{} } return &resolver } // knownDefGoType returns go type, package and package alias for definition -func knownDefGoType(def string, schema spec.Schema, clear func(string) string) (string, string, string) { +func (t typeResolver) knownDefGoType(def string, schema spec.Schema, clear func(string) string) (string, string, string) { debugLog("known def type: %q", def) ext := schema.Extensions nm, hasGoName := ext.GetString(xGoName) @@ -147,8 +151,7 @@ func knownDefGoType(def string, schema spec.Schema, clear func(string) string) ( debugLog("known def type %s named from %s as %q", def, xGoName, nm) def = nm } - extType, isExternalType := hasExternalType(ext) - + extType, isExternalType := t.resolveExternalType(ext) if !isExternalType || extType.Embedded { if clear == nil { debugLog("known def type no clear: %q", def) @@ -159,7 +162,11 @@ func knownDefGoType(def string, schema spec.Schema, clear func(string) string) ( } // external type definition trumps regular type resolution - log.Printf("type %s imported as external type %s.%s", def, extType.Import.Package, extType.Type) + if extType.Import.Alias == "" { + debugLog("type %s imported as external type %s, assumed in current package", def, extType.Type) + return extType.Type, extType.Import.Package, extType.Import.Alias + } + debugLog("type %s imported as external type from %s as %s.%s", def, extType.Import.Package, extType.Import.Alias, extType.Type) return extType.Import.Alias + "." + extType.Type, extType.Import.Package, extType.Import.Alias } @@ -179,8 +186,9 @@ type externalTypeDefinition struct { Alias string } Hints struct { - Kind string - Nullable bool + Kind string + Nullable *bool + NoValidation *bool } Embedded bool } @@ -190,23 +198,57 @@ func hasExternalType(ext spec.Extensions) (*externalTypeDefinition, bool) { if !ok { return nil, false } + var extType externalTypeDefinition err := mapstructure.Decode(v, &extType) if err != nil { log.Printf("warning: x-go-type extension could not be decoded (%v). Skipped", v) return nil, false } - if extType.Import.Package != "" && extType.Import.Alias == "" { - // NOTE(fred): possible name conflict here (TODO(fred): deconflict this default alias) - extType.Import.Alias = path.Base(extType.Import.Package) + + return &extType, true +} + +func (t typeResolver) resolveExternalType(ext spec.Extensions) (*externalTypeDefinition, bool) { + extType, hasExt := hasExternalType(ext) + if !hasExt { + return nil, false } + + // NOTE: + // * basic deconfliction of the default alias + // * if no package is specified, defaults to models (as provided from CLI or defaut generation location for models) + toAlias := func(pkg string) string { + mangled := GoLangOpts().ManglePackageName(pkg, "") + return deconflictPkg(mangled, func(in string) string { + return in + "ext" + }) + } + + switch { + case extType.Import.Package != "" && extType.Import.Alias == "": + extType.Import.Alias = toAlias(extType.Import.Package) + case extType.Import.Package == "" && extType.Import.Alias != "": + extType.Import.Package = t.ModelsFullPkg + case extType.Import.Package == "" && extType.Import.Alias == "": + // in this case, the external type is assumed to be present in the current package. + // For completion, whenever this type is used in anonymous types declared by operations, + // we assume this is the package where models are expected to be found. + extType.Import.Package = t.ModelsFullPkg + if extType.Import.Package != "" { + extType.Import.Alias = toAlias(extType.Import.Package) + } + } + debugLogAsJSON("known def external %s type", xGoType, extType) - return &extType, true + + return extType, true } type typeResolver struct { Doc *loads.Document - ModelsPackage string + ModelsPackage string // package alias (e.g. "models") + ModelsFullPkg string // fully qualified package (e.g. "github.com/example/models") ModelName string KnownDefs map[string]struct{} // unexported fields @@ -216,7 +258,7 @@ type typeResolver struct { // NewWithModelName clones a type resolver and specifies a new model name func (t *typeResolver) NewWithModelName(name string) *typeResolver { - tt := newTypeResolver(t.ModelsPackage, t.Doc) + tt := newTypeResolver(t.ModelsPackage, t.ModelsFullPkg, t.Doc) tt.ModelName = name // propagates kept definitions @@ -236,24 +278,12 @@ func (t *typeResolver) withKeepDefinitionsPackage(definitionsPackage string) *ty return t } -// IsNullable hints the generator as to render the type with a pointer or not. -// -// A schema is deemed nullable (i.e. rendered by a pointer) when: -// - a custom extension says it has to be so -// - it is an object with properties -// - it is a composed object (allOf) -// -// The interpretation of Required as a mean to make a type nullable is carried on elsewhere. -func (t *typeResolver) IsNullable(schema *spec.Schema) bool { - nullable := t.isNullable(schema) - return nullable || len(schema.AllOf) > 0 -} - func (t *typeResolver) resolveSchemaRef(schema *spec.Schema, isRequired bool) (returns bool, result resolvedType, err error) { if schema.Ref.String() == "" { return } debugLog("resolving ref (anon: %t, req: %t) %s", false, isRequired, schema.Ref.String()) + returns = true var ref *spec.Schema var er error @@ -264,6 +294,13 @@ func (t *typeResolver) resolveSchemaRef(schema *spec.Schema, isRequired bool) (r err = er return } + + extType, isExternalType := t.resolveExternalType(schema.Extensions) + if isExternalType { + // deal with validations for an aliased external type + result.SkipExternalValidation = swag.BoolValue(extType.Hints.NoValidation) + } + res, er := t.ResolveSchema(ref, false, isRequired) if er != nil { err = er @@ -272,7 +309,7 @@ func (t *typeResolver) resolveSchemaRef(schema *spec.Schema, isRequired bool) (r result = res tn := filepath.Base(schema.Ref.GetURL().Fragment) - tpe, pkg, alias := knownDefGoType(tn, *ref, t.goTypeName) + tpe, pkg, alias := t.knownDefGoType(tn, *ref, t.goTypeName) debugLog("type name %s, package %s, alias %s", tpe, pkg, alias) if tpe != "" { result.GoType = tpe @@ -281,7 +318,7 @@ func (t *typeResolver) resolveSchemaRef(schema *spec.Schema, isRequired bool) (r } result.HasDiscriminator = res.HasDiscriminator result.IsBaseType = result.HasDiscriminator - result.IsNullable = t.IsNullable(ref) + result.IsNullable = result.IsNullable || t.isNullable(ref) // this has to be overriden for slices and maps result.IsEnumCI = false return } @@ -304,7 +341,7 @@ func (t *typeResolver) resolveFormat(schema *spec.Schema, isAnonymous bool, isRe } debugLog("resolving format (anon: %t, req: %t)", isAnonymous, isRequired) - schFmt := strings.Replace(schema.Format, "-", "", -1) + schFmt := strings.ReplaceAll(schema.Format, "-", "") if fmm, ok := formatMapping[result.SwaggerType]; ok { if tpe, ok := fmm[schFmt]; ok { returns = true @@ -334,13 +371,33 @@ func (t *typeResolver) resolveFormat(schema *spec.Schema, isAnonymous bool, isRe case number, integer: result.IsNullable = nullableNumber(schema, isRequired) default: - result.IsNullable = t.IsNullable(schema) + result.IsNullable = t.isNullable(schema) } } + + guardFormatConflicts(schema.Format, schema) return } +// isNullable hints the generator as to render the type with a pointer or not. +// +// A schema is deemed nullable (i.e. rendered by a pointer) when: +// - a custom extension says it has to be so +// - it is an object with properties +// - it is a composed object (allOf) +// +// The interpretation of Required as a mean to make a type nullable is carried out elsewhere. func (t *typeResolver) isNullable(schema *spec.Schema) bool { + + if nullable, ok := t.isNullableOverride(schema); ok { + return nullable + } + + return len(schema.Properties) > 0 || len(schema.AllOf) > 0 +} + +// isNullableOverride determines a nullable flag forced by an extension +func (t *typeResolver) isNullableOverride(schema *spec.Schema) (bool, bool) { check := func(extension string) (bool, bool) { v, found := schema.Extensions[extension] nullable, cast := v.(bool) @@ -348,12 +405,14 @@ func (t *typeResolver) isNullable(schema *spec.Schema) bool { } if nullable, ok := check(xIsNullable); ok { - return nullable + return nullable, ok } + if nullable, ok := check(xNullable); ok { - return nullable + return nullable, ok } - return len(schema.Properties) > 0 + + return false, false } func (t *typeResolver) firstType(schema *spec.Schema) string { @@ -402,9 +461,30 @@ func (t *typeResolver) resolveArray(schema *spec.Schema, isAnonymous, isRequired err = er return } - // override the general nullability rule from ResolveSchema(): - // only complex items are nullable (when not discriminated, not forced by x-nullable) - rt.IsNullable = t.IsNullable(schema.Items.Schema) && !rt.HasDiscriminator + + // Override the general nullability rule from ResolveSchema() in array elements: + // - only complex items are nullable (when not discriminated, not forced by x-nullable) + // - arrays of allOf have non nullable elements when not forced by x-nullable + elem := schema.Items.Schema + if elem.Ref.String() != "" { + // drill into $ref to figure out whether we want the element type to nullable or not + resolved, erf := spec.ResolveRef(t.Doc.Spec(), &elem.Ref) + if erf != nil { + debugLog("error resolving ref %s: %v", schema.Ref.String(), erf) + } + elem = resolved + } + + debugLogAsJSON("resolved item for %s", rt.GoType, elem) + if nullable, ok := t.isNullableOverride(elem); ok { + debugLog("found nullable override in element %s: %t", rt.GoType, nullable) + rt.IsNullable = nullable + } else { + // this differs from isNullable for elements with AllOf + debugLog("no nullable override in element %s: Properties: %t, HasDiscriminator: %t", rt.GoType, len(elem.Properties) > 0, rt.HasDiscriminator) + rt.IsNullable = len(elem.Properties) > 0 && !rt.HasDiscriminator + } + result.GoType = "[]" + rt.GoType if rt.IsNullable && !strings.HasPrefix(rt.GoType, "*") { result.GoType = "[]*" + rt.GoType @@ -448,7 +528,7 @@ func (t *typeResolver) resolveObject(schema *spec.Schema, isAnonymous bool) (res result.IsBaseType = schema.Discriminator != "" if !isAnonymous { result.SwaggerType = object - tpe, pkg, alias := knownDefGoType(t.ModelName, *schema, t.goTypeName) + tpe, pkg, alias := t.knownDefGoType(t.ModelName, *schema, t.goTypeName) result.GoType = tpe result.Pkg = pkg result.PkgAlias = alias @@ -457,12 +537,18 @@ func (t *typeResolver) resolveObject(schema *spec.Schema, isAnonymous bool) (res result.GoType = t.goTypeName(t.ModelName) result.IsComplexObject = true var isNullable bool - for _, p := range schema.AllOf { - if t.IsNullable(&p) { + for _, sch := range schema.AllOf { + p := sch + if t.isNullable(&p) { isNullable = true } } - result.IsNullable = isNullable + if override, ok := t.isNullableOverride(schema); ok { + // prioritize x-nullable extensions + result.IsNullable = override + } else { + result.IsNullable = isNullable + } result.SwaggerType = object return } @@ -471,7 +557,7 @@ func (t *typeResolver) resolveObject(schema *spec.Schema, isAnonymous bool) (res // resolved type, this should also flag the object as anonymous, // when a ref is found, the anonymous flag will be reset if len(schema.Properties) > 0 { - result.IsNullable = t.IsNullable(schema) + result.IsNullable = t.isNullable(schema) result.IsComplexObject = true // no return here, still need to check for additional properties } @@ -489,6 +575,12 @@ func (t *typeResolver) resolveObject(schema *spec.Schema, isAnonymous bool) (res result.SwaggerType = object + if et.IsExternal { + // external AdditionalProperties are a special case because we look ahead into schemas + extType, _, _ := t.knownDefGoType(t.ModelName, *sch, t.goTypeName) + et.GoType = extType + } + // only complex map elements are nullable (when not forced by x-nullable) // TODO: figure out if required to check when not discriminated like arrays? et.IsNullable = t.isNullable(schema.AdditionalProperties.Schema) @@ -544,11 +636,16 @@ func (t *typeResolver) resolveObject(schema *spec.Schema, isAnonymous bool) (res } // an object without property and without AdditionalProperties schema is rendered as interface{} - result.GoType = iface result.IsMap = true result.SwaggerType = object result.IsNullable = false - result.IsInterface = len(schema.Properties) == 0 + // an object without properties but with MinProperties or MaxProperties is rendered as map[string]interface{} + result.IsInterface = len(schema.Properties) == 0 && !schema.Validations().HasObjectValidations() + if result.IsInterface { + result.GoType = iface + } else { + result.GoType = "map[string]interface{}" + } return } @@ -656,21 +753,38 @@ func hasEnumCI(ve spec.Extensions) bool { return ok && isEnumCI } -func (t *typeResolver) shortCircuitResolveExternal(tpe, pkg, alias string, extType *externalTypeDefinition, schema *spec.Schema) resolvedType { +func (t *typeResolver) shortCircuitResolveExternal(tpe, pkg, alias string, extType *externalTypeDefinition, schema *spec.Schema, isRequired bool) resolvedType { // short circuit type resolution for external types + debugLogAsJSON("shortCircuitResolveExternal", extType) + var result resolvedType result.Extensions = schema.Extensions result.GoType = tpe result.Pkg = pkg result.PkgAlias = alias + result.IsInterface = false + // by default consider that we have a type with validations. Use hint "interface" or "noValidation" to disable validations + result.SkipExternalValidation = swag.BoolValue(extType.Hints.NoValidation) + result.IsNullable = isRequired + result.setKind(extType.Hints.Kind) - result.IsNullable = t.IsNullable(schema) + if result.IsInterface || result.IsStream { + result.IsNullable = false + } + if extType.Hints.Nullable != nil { + result.IsNullable = swag.BoolValue(extType.Hints.Nullable) + } + + if nullable, ok := t.isNullableOverride(schema); ok { + result.IsNullable = nullable // x-nullable directive rules them all + } // other extensions if result.IsArray { result.IsEmptyOmitted = false tpe = "array" } + result.setExtensions(schema, tpe) return result } @@ -687,32 +801,73 @@ func (t *typeResolver) ResolveSchema(schema *spec.Schema, isAnonymous, isRequire return } - extType, isExternalType := hasExternalType(schema.Extensions) + extType, isExternalType := t.resolveExternalType(schema.Extensions) if isExternalType { - tpe, pkg, alias := knownDefGoType(t.ModelName, *schema, t.goTypeName) - debugLog("found type declared as external, imported from %s as %s. Has type hints? %t, rendered has embedded? %t", - pkg, tpe, extType.Hints.Kind != "", extType.Embedded) + tpe, pkg, alias := t.knownDefGoType(t.ModelName, *schema, t.goTypeName) + debugLog("found type %s declared as external, imported from %s as %s. Has type hints? %t, rendered has embedded? %t", + t.ModelName, pkg, tpe, extType.Hints.Kind != "", extType.Embedded) if extType.Hints.Kind != "" && !extType.Embedded { // use hint to qualify type debugLog("short circuits external type resolution with hint for %s", tpe) - result = t.shortCircuitResolveExternal(tpe, pkg, alias, extType, schema) + result = t.shortCircuitResolveExternal(tpe, pkg, alias, extType, schema, isRequired) + result.IsExternal = isAnonymous // mark anonymous external types only, not definitions return } // use spec to qualify type debugLog("marking type %s as external embedded: %t", tpe, extType.Embedded) - // mark this type as an embedded external definition if requested - defer func() { + defer func() { // enforce bubbling up decisions taken about being an external type + // mark this type as an embedded external definition if requested result.IsEmbedded = extType.Embedded + result.IsExternal = isAnonymous // for non-embedded, mark anonymous external types only, not definitions + + result.IsAnonymous = false + result.IsAliased = true + result.IsNullable = isRequired + if extType.Hints.Nullable != nil { + result.IsNullable = swag.BoolValue(extType.Hints.Nullable) + } + + result.IsMap = false + result.AliasedType = result.GoType + result.IsInterface = false + if result.IsEmbedded { result.ElemType = &resolvedType{ - GoType: extType.Import.Alias + "." + extType.Type, - Pkg: extType.Import.Package, - PkgAlias: extType.Import.Alias, - IsNullable: extType.Hints.Nullable, + IsExternal: isAnonymous, // mark anonymous external types only, not definitions + IsInterface: false, + Pkg: extType.Import.Package, + PkgAlias: extType.Import.Alias, + SkipExternalValidation: swag.BoolValue(extType.Hints.NoValidation), + } + if extType.Import.Alias != "" { + result.ElemType.GoType = extType.Import.Alias + "." + extType.Type + } else { + result.ElemType.GoType = extType.Type + } + result.ElemType.setKind(extType.Hints.Kind) + if result.IsInterface || result.IsStream { + result.ElemType.IsNullable = false + } + if extType.Hints.Nullable != nil { + result.ElemType.IsNullable = swag.BoolValue(extType.Hints.Nullable) } - result.setKind(extType.Hints.Kind) + // embedded external: by default consider validation is skipped for the external type + // + // NOTE: at this moment the template generates a type assertion, so this setting does not really matter + // for embedded types. + if extType.Hints.NoValidation != nil { + result.ElemType.SkipExternalValidation = swag.BoolValue(extType.Hints.NoValidation) + } else { + result.ElemType.SkipExternalValidation = true + } + } else { + // non-embedded external type: by default consider that validation is enabled (SkipExternalValidation: false) + result.SkipExternalValidation = swag.BoolValue(extType.Hints.NoValidation) + } + if nullable, ok := t.isNullableOverride(schema); ok { + result.IsNullable = nullable } }() } @@ -720,15 +875,16 @@ func (t *typeResolver) ResolveSchema(schema *spec.Schema, isAnonymous, isRequire tpe := t.firstType(schema) var returns bool + guardValidations(tpe, schema, schema.Type...) + returns, result, err = t.resolveSchemaRef(schema, isRequired) if returns { if !isAnonymous { result.IsMap = false result.IsComplexObject = true - debugLog("not anonymous ref") } - debugLog("anonymous after ref") + return } @@ -793,6 +949,18 @@ func (t *typeResolver) ResolveSchema(schema *spec.Schema, isAnonymous, isRequire result.HasDiscriminator = schema.Discriminator != "" case "null": + if schema.Validations().HasObjectValidations() { + // no explicit object type, but inferred from object validations: + // this makes the type a map[string]interface{} instead of interface{} + result, err = t.resolveObject(schema, isAnonymous) + if err != nil { + result = resolvedType{} + break + } + result.HasDiscriminator = schema.Discriminator != "" + break + } + result.GoType = iface result.SwaggerType = object result.IsNullable = false @@ -801,9 +969,89 @@ func (t *typeResolver) ResolveSchema(schema *spec.Schema, isAnonymous, isRequire default: err = fmt.Errorf("unresolvable: %v (format %q)", schema.Type, schema.Format) } + return } +func warnSkipValidation(types interface{}) func(string, interface{}) { + return func(validation string, value interface{}) { + value = reflect.Indirect(reflect.ValueOf(value)).Interface() + log.Printf("warning: validation %s (value: %v) not compatible with type %v. Skipped", validation, value, types) + } +} + +// guardValidations removes (with a warning) validations that don't fit with the schema type. +// +// Notice that the "enum" validation is allowed on any type but file. +func guardValidations(tpe string, schema interface { + Validations() spec.SchemaValidations + SetValidations(spec.SchemaValidations) +}, types ...string) { + + v := schema.Validations() + if len(types) == 0 { + types = []string{tpe} + } + defer func() { + schema.SetValidations(v) + }() + + if tpe != array { + v.ClearArrayValidations(warnSkipValidation(types)) + } + + if tpe != str && tpe != file { + v.ClearStringValidations(warnSkipValidation(types)) + } + + if tpe != object { + v.ClearObjectValidations(warnSkipValidation(types)) + } + + if tpe != number && tpe != integer { + v.ClearNumberValidations(warnSkipValidation(types)) + } + + if tpe == file { + // keep MinLength/MaxLength on file + if v.Pattern != "" { + warnSkipValidation(types)("pattern", v.Pattern) + v.Pattern = "" + } + if v.HasEnum() { + warnSkipValidation(types)("enum", v.Enum) + v.Enum = nil + } + } + + // other cases: mapped as interface{}: no validations allowed but Enum +} + +// guardFormatConflicts handles all conflicting properties +// (for schema model or simple schema) when a format is set. +// +// At this moment, validation guards already handle all known conflicts, but for the +// special case of binary (i.e. io.Reader). +func guardFormatConflicts(format string, schema interface { + Validations() spec.SchemaValidations + SetValidations(spec.SchemaValidations) +}) { + v := schema.Validations() + msg := fmt.Sprintf("for format %q", format) + + // for this format, no additional validations are supported + if format == "binary" { + // no validations supported on binary fields at this moment (io.Reader) + v.ClearStringValidations(warnSkipValidation(msg)) + if v.HasEnum() { + warnSkipValidation(msg) + v.Enum = nil + } + schema.SetValidations(v) + } + // more cases should be inserted here if they arise +} + // resolvedType is a swagger type that has been resolved and analyzed for usage // in a template type resolvedType struct { @@ -820,6 +1068,7 @@ type resolvedType struct { IsJSONString bool IsEnumCI bool IsBase64 bool + IsExternal bool // A tuple gets rendered as an anonymous struct with P{index} as property name IsTuple bool @@ -855,9 +1104,12 @@ type resolvedType struct { // is generated in models that embeds the external type, with the Validate // method. IsEmbedded bool + + SkipExternalValidation bool } -func (rt *resolvedType) Zero() string { +// Zero returns an initializer for the type +func (rt resolvedType) Zero() string { // if type is aliased, provide zero from the aliased type if rt.IsAliased { if zr, ok := zeroes[rt.AliasedType]; ok { @@ -889,10 +1141,39 @@ func (rt *resolvedType) Zero() string { return "" } +// ToString returns a string conversion for a type akin to a string +func (rt resolvedType) ToString(value string) string { + if !rt.IsPrimitive || rt.SwaggerType != "string" || rt.IsStream { + return "" + } + if rt.IsCustomFormatter { + if rt.IsAliased { + return fmt.Sprintf("%s(%s).String()", rt.AliasedType, value) + } + return fmt.Sprintf("%s.String()", value) + } + var deref string + if rt.IsNullable { + deref = "*" + } + if rt.GoType == "string" || rt.GoType == "*string" { + return fmt.Sprintf("%s%s", deref, value) + } + + return fmt.Sprintf("string(%s%s)", deref, value) +} + func (rt *resolvedType) setExtensions(schema *spec.Schema, origType string) { rt.IsEnumCI = hasEnumCI(schema.Extensions) rt.setIsEmptyOmitted(schema, origType) rt.setIsJSONString(schema, origType) + + if customTag, found := schema.Extensions[xGoCustomTag]; found { + if rt.Extensions == nil { + rt.Extensions = make(spec.Extensions) + } + rt.Extensions[xGoCustomTag] = customTag + } } func (rt *resolvedType) setIsEmptyOmitted(schema *spec.Schema, tpe string) { diff --git a/vendor/github.com/go-swagger/go-swagger/scan/README.md b/vendor/github.com/go-swagger/go-swagger/scan/README.md new file mode 100644 index 0000000000000..1ae6f766f7276 --- /dev/null +++ b/vendor/github.com/go-swagger/go-swagger/scan/README.md @@ -0,0 +1,3 @@ +# scan + +Pre go1.11 version of the go source parser, without support for go modules. diff --git a/vendor/github.com/go-swagger/go-swagger/scan/classifier.go b/vendor/github.com/go-swagger/go-swagger/scan/classifier.go index c47bed812cc3b..29cff417d6e03 100644 --- a/vendor/github.com/go-swagger/go-swagger/scan/classifier.go +++ b/vendor/github.com/go-swagger/go-swagger/scan/classifier.go @@ -119,7 +119,7 @@ func (pc *programClassifier) Classify(prog *loader.Program) (*classifiedProgram, if seenStruct == "" || seenStruct == matches[1] { seenStruct = matches[1] } else { - return nil, fmt.Errorf("classifier: already annotated as %s, can't also be %q", seenStruct, matches[1]) + return nil, fmt.Errorf("classifier: already annotated as %s, can't also be %q - %s", seenStruct, matches[1], cline.Text) } case "meta": if !mt { @@ -134,7 +134,7 @@ func (pc *programClassifier) Classify(prog *loader.Program) (*classifiedProgram, if seenStruct == "" || seenStruct == matches[1] { seenStruct = matches[1] } else { - return nil, fmt.Errorf("classifier: already annotated as %s, can't also be %q", seenStruct, matches[1]) + return nil, fmt.Errorf("classifier: already annotated as %s, can't also be %q - %s", seenStruct, matches[1], cline.Text) } case "response": if !rs { @@ -144,7 +144,7 @@ func (pc *programClassifier) Classify(prog *loader.Program) (*classifiedProgram, if seenStruct == "" || seenStruct == matches[1] { seenStruct = matches[1] } else { - return nil, fmt.Errorf("classifier: already annotated as %s, can't also be %q", seenStruct, matches[1]) + return nil, fmt.Errorf("classifier: already annotated as %s, can't also be %q - %s", seenStruct, matches[1], cline.Text) } case "strfmt", "name", "discriminated", "file", "enum", "default", "alias", "type": // TODO: perhaps collect these and pass along to avoid lookups later on diff --git a/vendor/github.com/go-swagger/go-swagger/scan/doc.go b/vendor/github.com/go-swagger/go-swagger/scan/doc.go index 60cf2b1d85c49..42abe26415fe2 100644 --- a/vendor/github.com/go-swagger/go-swagger/scan/doc.go +++ b/vendor/github.com/go-swagger/go-swagger/scan/doc.go @@ -16,6 +16,8 @@ /*Package scan provides a scanner for go files that produces a swagger spec document. +This package is intended for pre-go1.11 versions, and does not support go modules. + You give it a main file and it will parse all the files that are required by that main package to produce a swagger specification. diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go index b174616315118..b404f4bec2742 100644 --- a/vendor/github.com/google/uuid/hash.go +++ b/vendor/github.com/google/uuid/hash.go @@ -26,8 +26,8 @@ var ( // NewMD5 and NewSHA1. func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { h.Reset() - h.Write(space[:]) - h.Write(data) + h.Write(space[:]) //nolint:errcheck + h.Write(data) //nolint:errcheck s := h.Sum(nil) var uuid UUID copy(uuid[:], s) diff --git a/vendor/github.com/google/uuid/sql.go b/vendor/github.com/google/uuid/sql.go index f326b54db37a6..2e02ec06c0121 100644 --- a/vendor/github.com/google/uuid/sql.go +++ b/vendor/github.com/google/uuid/sql.go @@ -9,7 +9,7 @@ import ( "fmt" ) -// Scan implements sql.Scanner so UUIDs can be read from databases transparently +// Scan implements sql.Scanner so UUIDs can be read from databases transparently. // Currently, database types that map to string and []byte are supported. Please // consult database-specific driver documentation for matching types. func (uuid *UUID) Scan(src interface{}) error { diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index 524404cc5227b..60d26bb50c6a9 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -35,6 +35,12 @@ const ( var rander = rand.Reader // random function +type invalidLengthError struct{ len int } + +func (err invalidLengthError) Error() string { + return fmt.Sprintf("invalid UUID length: %d", err.len) +} + // Parse decodes s into a UUID or returns an error. Both the standard UUID // forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the @@ -68,7 +74,7 @@ func Parse(s string) (UUID, error) { } return uuid, nil default: - return uuid, fmt.Errorf("invalid UUID length: %d", len(s)) + return uuid, invalidLengthError{len(s)} } // s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx @@ -112,7 +118,7 @@ func ParseBytes(b []byte) (UUID, error) { } return uuid, nil default: - return uuid, fmt.Errorf("invalid UUID length: %d", len(b)) + return uuid, invalidLengthError{len(b)} } // s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go index c110465db5900..86160fbd0725f 100644 --- a/vendor/github.com/google/uuid/version4.go +++ b/vendor/github.com/google/uuid/version4.go @@ -14,6 +14,14 @@ func New() UUID { return Must(NewRandom()) } +// NewString creates a new random UUID and returns it as a string or panics. +// NewString is equivalent to the expression +// +// uuid.New().String() +func NewString() string { + return Must(NewRandom()).String() +} + // NewRandom returns a Random (Version 4) UUID. // // The strength of the UUIDs is based on the strength of the crypto/rand diff --git a/vendor/github.com/gorilla/handlers/compress.go b/vendor/github.com/gorilla/handlers/compress.go index e46a7bfd6c84a..1e95f1ccbfa51 100644 --- a/vendor/github.com/gorilla/handlers/compress.go +++ b/vendor/github.com/gorilla/handlers/compress.go @@ -10,33 +10,34 @@ import ( "io" "net/http" "strings" + + "github.com/felixge/httpsnoop" ) -type compressResponseWriter struct { - io.Writer - http.ResponseWriter - http.Hijacker - http.Flusher - http.CloseNotifier -} +const acceptEncoding string = "Accept-Encoding" -func (w *compressResponseWriter) WriteHeader(c int) { - w.ResponseWriter.Header().Del("Content-Length") - w.ResponseWriter.WriteHeader(c) +type compressResponseWriter struct { + compressor io.Writer + w http.ResponseWriter } -func (w *compressResponseWriter) Header() http.Header { - return w.ResponseWriter.Header() +func (cw *compressResponseWriter) WriteHeader(c int) { + cw.w.Header().Del("Content-Length") + cw.w.WriteHeader(c) } -func (w *compressResponseWriter) Write(b []byte) (int, error) { - h := w.ResponseWriter.Header() +func (cw *compressResponseWriter) Write(b []byte) (int, error) { + h := cw.w.Header() if h.Get("Content-Type") == "" { h.Set("Content-Type", http.DetectContentType(b)) } h.Del("Content-Length") - return w.Writer.Write(b) + return cw.compressor.Write(b) +} + +func (cw *compressResponseWriter) ReadFrom(r io.Reader) (int64, error) { + return io.Copy(cw.compressor, r) } type flusher interface { @@ -45,12 +46,12 @@ type flusher interface { func (w *compressResponseWriter) Flush() { // Flush compressed data if compressor supports it. - if f, ok := w.Writer.(flusher); ok { + if f, ok := w.compressor.(flusher); ok { f.Flush() } // Flush HTTP response. - if w.Flusher != nil { - w.Flusher.Flush() + if f, ok := w.w.(http.Flusher); ok { + f.Flush() } } @@ -74,77 +75,69 @@ func CompressHandlerLevel(h http.Handler, level int) http.Handler { level = gzip.DefaultCompression } + const ( + gzipEncoding = "gzip" + flateEncoding = "deflate" + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - L: - for _, enc := range strings.Split(r.Header.Get("Accept-Encoding"), ",") { - switch strings.TrimSpace(enc) { - case "gzip": - w.Header().Set("Content-Encoding", "gzip") - r.Header.Del("Accept-Encoding") - w.Header().Add("Vary", "Accept-Encoding") - - gw, _ := gzip.NewWriterLevel(w, level) - defer gw.Close() - - h, hok := w.(http.Hijacker) - if !hok { /* w is not Hijacker... oh well... */ - h = nil - } - - f, fok := w.(http.Flusher) - if !fok { - f = nil - } - - cn, cnok := w.(http.CloseNotifier) - if !cnok { - cn = nil - } - - w = &compressResponseWriter{ - Writer: gw, - ResponseWriter: w, - Hijacker: h, - Flusher: f, - CloseNotifier: cn, - } - - break L - case "deflate": - w.Header().Set("Content-Encoding", "deflate") - r.Header.Del("Accept-Encoding") - w.Header().Add("Vary", "Accept-Encoding") - - fw, _ := flate.NewWriter(w, level) - defer fw.Close() - - h, hok := w.(http.Hijacker) - if !hok { /* w is not Hijacker... oh well... */ - h = nil - } - - f, fok := w.(http.Flusher) - if !fok { - f = nil - } - - cn, cnok := w.(http.CloseNotifier) - if !cnok { - cn = nil - } - - w = &compressResponseWriter{ - Writer: fw, - ResponseWriter: w, - Hijacker: h, - Flusher: f, - CloseNotifier: cn, - } - - break L + // detect what encoding to use + var encoding string + for _, curEnc := range strings.Split(r.Header.Get(acceptEncoding), ",") { + curEnc = strings.TrimSpace(curEnc) + if curEnc == gzipEncoding || curEnc == flateEncoding { + encoding = curEnc + break } } + // always add Accept-Encoding to Vary to prevent intermediate caches corruption + w.Header().Add("Vary", acceptEncoding) + + // if we weren't able to identify an encoding we're familiar with, pass on the + // request to the handler and return + if encoding == "" { + h.ServeHTTP(w, r) + return + } + + if r.Header.Get("Upgrade") != "" { + h.ServeHTTP(w, r) + return + } + + // wrap the ResponseWriter with the writer for the chosen encoding + var encWriter io.WriteCloser + if encoding == gzipEncoding { + encWriter, _ = gzip.NewWriterLevel(w, level) + } else if encoding == flateEncoding { + encWriter, _ = flate.NewWriter(w, level) + } + defer encWriter.Close() + + w.Header().Set("Content-Encoding", encoding) + r.Header.Del(acceptEncoding) + + cw := &compressResponseWriter{ + w: w, + compressor: encWriter, + } + + w = httpsnoop.Wrap(w, httpsnoop.Hooks{ + Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc { + return cw.Write + }, + WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc { + return cw.WriteHeader + }, + Flush: func(httpsnoop.FlushFunc) httpsnoop.FlushFunc { + return cw.Flush + }, + ReadFrom: func(rff httpsnoop.ReadFromFunc) httpsnoop.ReadFromFunc { + return cw.ReadFrom + }, + }) + h.ServeHTTP(w, r) }) } diff --git a/vendor/github.com/gorilla/handlers/go.mod b/vendor/github.com/gorilla/handlers/go.mod index d9c9815cff656..58e6a85ec3a60 100644 --- a/vendor/github.com/gorilla/handlers/go.mod +++ b/vendor/github.com/gorilla/handlers/go.mod @@ -1 +1,5 @@ module github.com/gorilla/handlers + +go 1.14 + +require github.com/felixge/httpsnoop v1.0.1 diff --git a/vendor/github.com/gorilla/handlers/go.sum b/vendor/github.com/gorilla/handlers/go.sum new file mode 100644 index 0000000000000..8c2645804e787 --- /dev/null +++ b/vendor/github.com/gorilla/handlers/go.sum @@ -0,0 +1,2 @@ +github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= diff --git a/vendor/github.com/gorilla/handlers/handlers.go b/vendor/github.com/gorilla/handlers/handlers.go index d03f2bf136ca0..0509482ad7a3e 100644 --- a/vendor/github.com/gorilla/handlers/handlers.go +++ b/vendor/github.com/gorilla/handlers/handlers.go @@ -51,10 +51,6 @@ type responseLogger struct { size int } -func (l *responseLogger) Header() http.Header { - return l.w.Header() -} - func (l *responseLogger) Write(b []byte) (int, error) { size, err := l.w.Write(b) l.size += size @@ -74,39 +70,16 @@ func (l *responseLogger) Size() int { return l.size } -func (l *responseLogger) Flush() { - f, ok := l.w.(http.Flusher) - if ok { - f.Flush() - } -} - -type hijackLogger struct { - responseLogger -} - -func (l *hijackLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) { - h := l.responseLogger.w.(http.Hijacker) - conn, rw, err := h.Hijack() - if err == nil && l.responseLogger.status == 0 { +func (l *responseLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) { + conn, rw, err := l.w.(http.Hijacker).Hijack() + if err == nil && l.status == 0 { // The status will be StatusSwitchingProtocols if there was no error and // WriteHeader has not been called yet - l.responseLogger.status = http.StatusSwitchingProtocols + l.status = http.StatusSwitchingProtocols } return conn, rw, err } -type closeNotifyWriter struct { - loggingResponseWriter - http.CloseNotifier -} - -type hijackCloseNotifier struct { - loggingResponseWriter - http.Hijacker - http.CloseNotifier -} - // isContentType validates the Content-Type header matches the supplied // contentType. That is, its type and subtype match. func isContentType(h http.Header, contentType string) bool { diff --git a/vendor/github.com/gorilla/handlers/handlers_go18.go b/vendor/github.com/gorilla/handlers/handlers_go18.go deleted file mode 100644 index 40f69146b9124..0000000000000 --- a/vendor/github.com/gorilla/handlers/handlers_go18.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build go1.8 - -package handlers - -import ( - "fmt" - "net/http" -) - -type loggingResponseWriter interface { - commonLoggingResponseWriter - http.Pusher -} - -func (l *responseLogger) Push(target string, opts *http.PushOptions) error { - p, ok := l.w.(http.Pusher) - if !ok { - return fmt.Errorf("responseLogger does not implement http.Pusher") - } - return p.Push(target, opts) -} - -func (c *compressResponseWriter) Push(target string, opts *http.PushOptions) error { - p, ok := c.ResponseWriter.(http.Pusher) - if !ok { - return fmt.Errorf("compressResponseWriter does not implement http.Pusher") - } - return p.Push(target, opts) -} diff --git a/vendor/github.com/gorilla/handlers/handlers_pre18.go b/vendor/github.com/gorilla/handlers/handlers_pre18.go deleted file mode 100644 index 197836abba138..0000000000000 --- a/vendor/github.com/gorilla/handlers/handlers_pre18.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !go1.8 - -package handlers - -type loggingResponseWriter interface { - commonLoggingResponseWriter -} diff --git a/vendor/github.com/gorilla/handlers/logging.go b/vendor/github.com/gorilla/handlers/logging.go index 88c25e72dc466..228465eba003d 100644 --- a/vendor/github.com/gorilla/handlers/logging.go +++ b/vendor/github.com/gorilla/handlers/logging.go @@ -12,6 +12,8 @@ import ( "strconv" "time" "unicode/utf8" + + "github.com/felixge/httpsnoop" ) // Logging @@ -39,10 +41,10 @@ type loggingHandler struct { func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { t := time.Now() - logger := makeLogger(w) + logger, w := makeLogger(w) url := *req.URL - h.handler.ServeHTTP(logger, req) + h.handler.ServeHTTP(w, req) if req.MultipartForm != nil { req.MultipartForm.RemoveAll() } @@ -58,27 +60,16 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { h.formatter(h.writer, params) } -func makeLogger(w http.ResponseWriter) loggingResponseWriter { - var logger loggingResponseWriter = &responseLogger{w: w, status: http.StatusOK} - if _, ok := w.(http.Hijacker); ok { - logger = &hijackLogger{responseLogger{w: w, status: http.StatusOK}} - } - h, ok1 := logger.(http.Hijacker) - c, ok2 := w.(http.CloseNotifier) - if ok1 && ok2 { - return hijackCloseNotifier{logger, h, c} - } - if ok2 { - return &closeNotifyWriter{logger, c} - } - return logger -} - -type commonLoggingResponseWriter interface { - http.ResponseWriter - http.Flusher - Status() int - Size() int +func makeLogger(w http.ResponseWriter) (*responseLogger, http.ResponseWriter) { + logger := &responseLogger{w: w, status: http.StatusOK} + return logger, httpsnoop.Wrap(w, httpsnoop.Hooks{ + Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc { + return logger.Write + }, + WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc { + return logger.WriteHeader + }, + }) } const lowerhex = "0123456789abcdef" @@ -145,7 +136,6 @@ func appendQuoted(buf []byte, s string) []byte { } } return buf - } // buildCommonLogLine builds a log entry for req in Apache Common Log Format. @@ -160,7 +150,6 @@ func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int } host, _, err := net.SplitHostPort(req.RemoteAddr) - if err != nil { host = req.RemoteAddr } diff --git a/vendor/github.com/gorilla/handlers/recovery.go b/vendor/github.com/gorilla/handlers/recovery.go index b1be9dc83e727..4c4c1d9c6cefe 100644 --- a/vendor/github.com/gorilla/handlers/recovery.go +++ b/vendor/github.com/gorilla/handlers/recovery.go @@ -19,7 +19,7 @@ type recoveryHandler struct { // RecoveryOption provides a functional approach to define // configuration for a handler; such as setting the logging -// whether or not to print strack traces on panic. +// whether or not to print stack traces on panic. type RecoveryOption func(http.Handler) func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler { @@ -86,6 +86,11 @@ func (h recoveryHandler) log(v ...interface{}) { } if h.printStack { - debug.PrintStack() + stack := string(debug.Stack()) + if h.logger != nil { + h.logger.Println(stack) + } else { + log.Println(stack) + } } } diff --git a/vendor/github.com/klauspost/compress/flate/gen_inflate.go b/vendor/github.com/klauspost/compress/flate/gen_inflate.go deleted file mode 100644 index 35fc072a3efa3..0000000000000 --- a/vendor/github.com/klauspost/compress/flate/gen_inflate.go +++ /dev/null @@ -1,294 +0,0 @@ -// +build generate - -//go:generate go run $GOFILE && gofmt -w inflate_gen.go - -package main - -import ( - "os" - "strings" -) - -func main() { - f, err := os.Create("inflate_gen.go") - if err != nil { - panic(err) - } - defer f.Close() - types := []string{"*bytes.Buffer", "*bytes.Reader", "*bufio.Reader", "*strings.Reader"} - names := []string{"BytesBuffer", "BytesReader", "BufioReader", "StringsReader"} - imports := []string{"bytes", "bufio", "io", "strings", "math/bits"} - f.WriteString(`// Code generated by go generate gen_inflate.go. DO NOT EDIT. - -package flate - -import ( -`) - - for _, imp := range imports { - f.WriteString("\t\"" + imp + "\"\n") - } - f.WriteString(")\n\n") - - template := ` - -// Decode a single Huffman block from f. -// hl and hd are the Huffman states for the lit/length values -// and the distance values, respectively. If hd == nil, using the -// fixed distance encoding associated with fixed Huffman blocks. -func (f *decompressor) $FUNCNAME$() { - const ( - stateInit = iota // Zero value must be stateInit - stateDict - ) - fr := f.r.($TYPE$) - - switch f.stepState { - case stateInit: - goto readLiteral - case stateDict: - goto copyHistory - } - -readLiteral: - // Read literal and/or (length, distance) according to RFC section 3.2.3. - { - var v int - { - // Inlined v, err := f.huffSym(f.hl) - // Since a huffmanDecoder can be empty or be composed of a degenerate tree - // with single element, huffSym must error on these two edge cases. In both - // cases, the chunks slice will be 0 for the invalid sequence, leading it - // satisfy the n == 0 check below. - n := uint(f.hl.maxRead) - // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, - // but is smart enough to keep local variables in registers, so use nb and b, - // inline call to moreBits and reassign b,nb back to f on return. - nb, b := f.nb, f.b - for { - for nb < n { - c, err := fr.ReadByte() - if err != nil { - f.b = b - f.nb = nb - f.err = noEOF(err) - return - } - f.roffset++ - b |= uint32(c) << (nb & regSizeMaskUint32) - nb += 8 - } - chunk := f.hl.chunks[b&(huffmanNumChunks-1)] - n = uint(chunk & huffmanCountMask) - if n > huffmanChunkBits { - chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask] - n = uint(chunk & huffmanCountMask) - } - if n <= nb { - if n == 0 { - f.b = b - f.nb = nb - if debugDecode { - fmt.Println("huffsym: n==0") - } - f.err = CorruptInputError(f.roffset) - return - } - f.b = b >> (n & regSizeMaskUint32) - f.nb = nb - n - v = int(chunk >> huffmanValueShift) - break - } - } - } - - var length int - switch { - case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).$FUNCNAME$ - f.stepState = stateInit - return - } - goto readLiteral - case v == 256: - f.finishBlock() - return - // otherwise, reference to older data - case v < 265: - length = v - (257 - 3) - case v < maxNumLit: - val := decCodeToLen[(v - 257)] - length = int(val.length) + 3 - n := uint(val.extra) - for f.nb < n { - c, err := fr.ReadByte() - if err != nil { - if debugDecode { - fmt.Println("morebits n>0:", err) - } - f.err = err - return - } - f.roffset++ - f.b |= uint32(c) << f.nb - f.nb += 8 - } - length += int(f.b & uint32(1<<(n®SizeMaskUint32)-1)) - f.b >>= n & regSizeMaskUint32 - f.nb -= n - default: - if debugDecode { - fmt.Println(v, ">= maxNumLit") - } - f.err = CorruptInputError(f.roffset) - return - } - - var dist uint32 - if f.hd == nil { - for f.nb < 5 { - c, err := fr.ReadByte() - if err != nil { - if debugDecode { - fmt.Println("morebits f.nb<5:", err) - } - f.err = err - return - } - f.roffset++ - f.b |= uint32(c) << f.nb - f.nb += 8 - } - dist = uint32(bits.Reverse8(uint8(f.b & 0x1F << 3))) - f.b >>= 5 - f.nb -= 5 - } else { - // Since a huffmanDecoder can be empty or be composed of a degenerate tree - // with single element, huffSym must error on these two edge cases. In both - // cases, the chunks slice will be 0 for the invalid sequence, leading it - // satisfy the n == 0 check below. - n := uint(f.hd.maxRead) - // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, - // but is smart enough to keep local variables in registers, so use nb and b, - // inline call to moreBits and reassign b,nb back to f on return. - nb, b := f.nb, f.b - for { - for nb < n { - c, err := fr.ReadByte() - if err != nil { - f.b = b - f.nb = nb - f.err = noEOF(err) - return - } - f.roffset++ - b |= uint32(c) << (nb & regSizeMaskUint32) - nb += 8 - } - chunk := f.hd.chunks[b&(huffmanNumChunks-1)] - n = uint(chunk & huffmanCountMask) - if n > huffmanChunkBits { - chunk = f.hd.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hd.linkMask] - n = uint(chunk & huffmanCountMask) - } - if n <= nb { - if n == 0 { - f.b = b - f.nb = nb - if debugDecode { - fmt.Println("huffsym: n==0") - } - f.err = CorruptInputError(f.roffset) - return - } - f.b = b >> (n & regSizeMaskUint32) - f.nb = nb - n - dist = uint32(chunk >> huffmanValueShift) - break - } - } - } - - switch { - case dist < 4: - dist++ - case dist < maxNumDist: - nb := uint(dist-2) >> 1 - // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << (nb & regSizeMaskUint32) - for f.nb < nb { - c, err := fr.ReadByte() - if err != nil { - if debugDecode { - fmt.Println("morebits f.nb>= nb & regSizeMaskUint32 - f.nb -= nb - dist = 1<<((nb+1)®SizeMaskUint32) + 1 + extra - default: - if debugDecode { - fmt.Println("dist too big:", dist, maxNumDist) - } - f.err = CorruptInputError(f.roffset) - return - } - - // No check on length; encoding can be prescient. - if dist > uint32(f.dict.histSize()) { - if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) - } - f.err = CorruptInputError(f.roffset) - return - } - - f.copyLen, f.copyDist = length, int(dist) - goto copyHistory - } - -copyHistory: - // Perform a backwards copy according to RFC section 3.2.3. - { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) - if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) - } - f.copyLen -= cnt - - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).$FUNCNAME$ // We need to continue this work - f.stepState = stateDict - return - } - goto readLiteral - } -} - -` - for i, t := range types { - s := strings.Replace(template, "$FUNCNAME$", "huffman"+names[i], -1) - s = strings.Replace(s, "$TYPE$", t, -1) - f.WriteString(s) - } - f.WriteString("func (f *decompressor) huffmanBlockDecoder() func() {\n") - f.WriteString("\tswitch f.r.(type) {\n") - for i, t := range types { - f.WriteString("\t\tcase " + t + ":\n") - f.WriteString("\t\t\treturn f.huffman" + names[i] + "\n") - } - f.WriteString("\t\tdefault:\n") - f.WriteString("\t\t\treturn f.huffmanBlockGeneric") - f.WriteString("\t}\n}\n") -} diff --git a/vendor/github.com/klauspost/compress/huff0/README.md b/vendor/github.com/klauspost/compress/huff0/README.md index e12da4db2fd19..8b6e5c66383d7 100644 --- a/vendor/github.com/klauspost/compress/huff0/README.md +++ b/vendor/github.com/klauspost/compress/huff0/README.md @@ -14,7 +14,9 @@ but it can be used as a secondary step to compressors (like Snappy) that does no ## News - * Mar 2018: First implementation released. Consider this beta software for now. +This is used as part of the [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and decompression package. + +This ensures that most functionality is well tested. # Usage diff --git a/vendor/github.com/klauspost/compress/zstd/README.md b/vendor/github.com/klauspost/compress/zstd/README.md index 08e553f7530d7..7680bfe1dd6c9 100644 --- a/vendor/github.com/klauspost/compress/zstd/README.md +++ b/vendor/github.com/klauspost/compress/zstd/README.md @@ -24,22 +24,21 @@ Godoc Documentation: https://godoc.org/github.com/klauspost/compress/zstd ### Status: STABLE - there may always be subtle bugs, a wide variety of content has been tested and the library is actively -used by several projects. This library is being continuously [fuzz-tested](https://github.com/klauspost/compress-fuzz), -kindly supplied by [fuzzit.dev](https://fuzzit.dev/). +used by several projects. This library is being [fuzz-tested](https://github.com/klauspost/compress-fuzz) for all updates. There may still be specific combinations of data types/size/settings that could lead to edge cases, so as always, testing is recommended. For now, a high speed (fastest) and medium-fast (default) compressor has been implemented. -The "Fastest" compression ratio is roughly equivalent to zstd level 1. -The "Default" compression ratio is roughly equivalent to zstd level 3 (default). +* The "Fastest" compression ratio is roughly equivalent to zstd level 1. +* The "Default" compression ratio is roughly equivalent to zstd level 3 (default). +* The "Better" compression ratio is roughly equivalent to zstd level 7. +* The "Best" compression ratio is roughly equivalent to zstd level 11. In terms of speed, it is typically 2x as fast as the stdlib deflate/gzip in its fastest mode. The compression ratio compared to stdlib is around level 3, but usually 3x as fast. -Compared to cgo zstd, the speed is around level 3 (default), but compression slightly worse, between level 1&2. - ### Usage @@ -140,7 +139,7 @@ I have collected some speed examples to compare speed and compression against ot * `file` is the input file. * `out` is the compressor used. `zskp` is this package. `zstd` is the Datadog cgo library. `gzstd/gzkp` is gzip standard and this library. -* `level` is the compression level used. For `zskp` level 1 is "fastest", level 2 is "default". +* `level` is the compression level used. For `zskp` level 1 is "fastest", level 2 is "default"; 3 is "better", 4 is "best". * `insize`/`outsize` is the input/output size. * `millis` is the number of milliseconds used for compression. * `mb/s` is megabytes (2^20 bytes) per second. @@ -154,11 +153,13 @@ file out level insize outsize millis mb/s silesia.tar zskp 1 211947520 73101992 643 313.87 silesia.tar zskp 2 211947520 67504318 969 208.38 silesia.tar zskp 3 211947520 65177448 1899 106.44 +silesia.tar zskp 4 211947520 61381950 8115 24.91 cgo zstd: silesia.tar zstd 1 211947520 73605392 543 371.56 silesia.tar zstd 3 211947520 66793289 864 233.68 silesia.tar zstd 6 211947520 62916450 1913 105.66 +silesia.tar zstd 9 211947520 60212393 5063 39.92 gzip, stdlib/this package: silesia.tar gzstd 1 211947520 80007735 1654 122.21 @@ -171,9 +172,11 @@ file out level insize outsize millis mb/s gob-stream zskp 1 1911399616 235022249 3088 590.30 gob-stream zskp 2 1911399616 205669791 3786 481.34 gob-stream zskp 3 1911399616 185792019 9324 195.48 +gob-stream zskp 4 1911399616 171537212 32113 56.76 gob-stream zstd 1 1911399616 249810424 2637 691.26 gob-stream zstd 3 1911399616 208192146 3490 522.31 gob-stream zstd 6 1911399616 193632038 6687 272.56 +gob-stream zstd 9 1911399616 177620386 16175 112.70 gob-stream gzstd 1 1911399616 357382641 10251 177.82 gob-stream gzkp 1 1911399616 362156523 5695 320.08 @@ -185,9 +188,11 @@ file out level insize outsize millis mb/s enwik9 zskp 1 1000000000 343848582 3609 264.18 enwik9 zskp 2 1000000000 317276632 5746 165.97 enwik9 zskp 3 1000000000 294540704 11725 81.34 +enwik9 zskp 4 1000000000 276609671 44029 21.66 enwik9 zstd 1 1000000000 358072021 3110 306.65 enwik9 zstd 3 1000000000 313734672 4784 199.35 enwik9 zstd 6 1000000000 295138875 10290 92.68 +enwik9 zstd 9 1000000000 278348700 28549 33.40 enwik9 gzstd 1 1000000000 382578136 9604 99.30 enwik9 gzkp 1 1000000000 383825945 6544 145.73 @@ -198,9 +203,11 @@ file out level insize outsize millis mb/s github-june-2days-2019.json zskp 1 6273951764 699045015 10620 563.40 github-june-2days-2019.json zskp 2 6273951764 617881763 11687 511.96 github-june-2days-2019.json zskp 3 6273951764 537511906 29252 204.54 +github-june-2days-2019.json zskp 4 6273951764 512796117 97791 61.18 github-june-2days-2019.json zstd 1 6273951764 766284037 8450 708.00 github-june-2days-2019.json zstd 3 6273951764 661889476 10927 547.57 github-june-2days-2019.json zstd 6 6273951764 642756859 22996 260.18 +github-june-2days-2019.json zstd 9 6273951764 601974523 52413 114.16 github-june-2days-2019.json gzstd 1 6273951764 1164400847 29948 199.79 github-june-2days-2019.json gzkp 1 6273951764 1128755542 19236 311.03 @@ -211,9 +218,11 @@ file out level insize outsize millis mb/s rawstudio-mint14.tar zskp 1 8558382592 3667489370 20210 403.84 rawstudio-mint14.tar zskp 2 8558382592 3364592300 31873 256.07 rawstudio-mint14.tar zskp 3 8558382592 3224594213 71751 113.75 +rawstudio-mint14.tar zskp 4 8558382592 3027332295 486243 16.79 rawstudio-mint14.tar zstd 1 8558382592 3609250104 17136 476.27 rawstudio-mint14.tar zstd 3 8558382592 3341679997 29262 278.92 rawstudio-mint14.tar zstd 6 8558382592 3235846406 77904 104.77 +rawstudio-mint14.tar zstd 9 8558382592 3160778861 140946 57.91 rawstudio-mint14.tar gzstd 1 8558382592 3926257486 57722 141.40 rawstudio-mint14.tar gzkp 1 8558382592 3970463184 41749 195.49 @@ -224,9 +233,11 @@ file out level insize outsize millis mb/s nyc-taxi-data-10M.csv zskp 1 3325605752 641339945 8925 355.35 nyc-taxi-data-10M.csv zskp 2 3325605752 591748091 11268 281.44 nyc-taxi-data-10M.csv zskp 3 3325605752 538490114 19880 159.53 +nyc-taxi-data-10M.csv zskp 4 3325605752 495986829 89368 35.49 nyc-taxi-data-10M.csv zstd 1 3325605752 687399637 8233 385.18 nyc-taxi-data-10M.csv zstd 3 3325605752 598514411 10065 315.07 nyc-taxi-data-10M.csv zstd 6 3325605752 570522953 20038 158.27 +nyc-taxi-data-10M.csv zstd 9 3325605752 517554797 64565 49.12 nyc-taxi-data-10M.csv gzstd 1 3325605752 928656485 23876 132.83 nyc-taxi-data-10M.csv gzkp 1 3325605752 924718719 16388 193.53 ``` diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go index 4733ea876a1da..b51d922bda691 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -613,7 +613,7 @@ func (b *blockDec) decodeCompressed(hist *history) error { // Decode treeless literal block. if litType == literalsBlockTreeless { // TODO: We could send the history early WITHOUT the stream history. - // This would allow decoding treeless literials before the byte history is available. + // This would allow decoding treeless literals before the byte history is available. // Silencia stats: Treeless 4393, with: 32775, total: 37168, 11% treeless. // So not much obvious gain here. diff --git a/vendor/github.com/klauspost/compress/zstd/blockenc.go b/vendor/github.com/klauspost/compress/zstd/blockenc.go index 083fbb502f40e..c85c40255d5f4 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockenc.go +++ b/vendor/github.com/klauspost/compress/zstd/blockenc.go @@ -76,6 +76,7 @@ func (b *blockEnc) reset(prev *blockEnc) { if prev != nil { b.recentOffsets = prev.prevRecentOffsets } + b.dictLitEnc = nil } // reset will reset the block for a new encode, but in the same stream, diff --git a/vendor/github.com/klauspost/compress/zstd/decodeheader.go b/vendor/github.com/klauspost/compress/zstd/decodeheader.go new file mode 100644 index 0000000000000..87896c5eaa789 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/decodeheader.go @@ -0,0 +1,202 @@ +// Copyright 2020+ Klaus Post. All rights reserved. +// License information can be found in the LICENSE file. + +package zstd + +import ( + "bytes" + "errors" + "io" +) + +// HeaderMaxSize is the maximum size of a Frame and Block Header. +// If less is sent to Header.Decode it *may* still contain enough information. +const HeaderMaxSize = 14 + 3 + +// Header contains information about the first frame and block within that. +type Header struct { + // Window Size the window of data to keep while decoding. + // Will only be set if HasFCS is false. + WindowSize uint64 + + // Frame content size. + // Expected size of the entire frame. + FrameContentSize uint64 + + // Dictionary ID. + // If 0, no dictionary. + DictionaryID uint32 + + // First block information. + FirstBlock struct { + // OK will be set if first block could be decoded. + OK bool + + // Is this the last block of a frame? + Last bool + + // Is the data compressed? + // If true CompressedSize will be populated. + // Unfortunately DecompressedSize cannot be determined + // without decoding the blocks. + Compressed bool + + // DecompressedSize is the expected decompressed size of the block. + // Will be 0 if it cannot be determined. + DecompressedSize int + + // CompressedSize of the data in the block. + // Does not include the block header. + // Will be equal to DecompressedSize if not Compressed. + CompressedSize int + } + + // Skippable will be true if the frame is meant to be skipped. + // No other information will be populated. + Skippable bool + + // If set there is a checksum present for the block content. + HasCheckSum bool + + // If this is true FrameContentSize will have a valid value + HasFCS bool + + SingleSegment bool +} + +// Decode the header from the beginning of the stream. +// This will decode the frame header and the first block header if enough bytes are provided. +// It is recommended to provide at least HeaderMaxSize bytes. +// If the frame header cannot be read an error will be returned. +// If there isn't enough input, io.ErrUnexpectedEOF is returned. +// The FirstBlock.OK will indicate if enough information was available to decode the first block header. +func (h *Header) Decode(in []byte) error { + if len(in) < 4 { + return io.ErrUnexpectedEOF + } + b, in := in[:4], in[4:] + if !bytes.Equal(b, frameMagic) { + if !bytes.Equal(b[1:4], skippableFrameMagic) || b[0]&0xf0 != 0x50 { + return ErrMagicMismatch + } + *h = Header{Skippable: true} + return nil + } + if len(in) < 1 { + return io.ErrUnexpectedEOF + } + + // Clear output + *h = Header{} + fhd, in := in[0], in[1:] + h.SingleSegment = fhd&(1<<5) != 0 + h.HasCheckSum = fhd&(1<<2) != 0 + + if fhd&(1<<3) != 0 { + return errors.New("Reserved bit set on frame header") + } + + // Read Window_Descriptor + // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor + if !h.SingleSegment { + if len(in) < 1 { + return io.ErrUnexpectedEOF + } + var wd byte + wd, in = in[0], in[1:] + windowLog := 10 + (wd >> 3) + windowBase := uint64(1) << windowLog + windowAdd := (windowBase / 8) * uint64(wd&0x7) + h.WindowSize = windowBase + windowAdd + } + + // Read Dictionary_ID + // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary_id + if size := fhd & 3; size != 0 { + if size == 3 { + size = 4 + } + if len(in) < int(size) { + return io.ErrUnexpectedEOF + } + b, in = in[:size], in[size:] + if b == nil { + return io.ErrUnexpectedEOF + } + switch size { + case 1: + h.DictionaryID = uint32(b[0]) + case 2: + h.DictionaryID = uint32(b[0]) | (uint32(b[1]) << 8) + case 4: + h.DictionaryID = uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24) + } + } + + // Read Frame_Content_Size + // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#frame_content_size + var fcsSize int + v := fhd >> 6 + switch v { + case 0: + if h.SingleSegment { + fcsSize = 1 + } + default: + fcsSize = 1 << v + } + + if fcsSize > 0 { + h.HasFCS = true + if len(in) < fcsSize { + return io.ErrUnexpectedEOF + } + b, in = in[:fcsSize], in[fcsSize:] + if b == nil { + return io.ErrUnexpectedEOF + } + switch fcsSize { + case 1: + h.FrameContentSize = uint64(b[0]) + case 2: + // When FCS_Field_Size is 2, the offset of 256 is added. + h.FrameContentSize = uint64(b[0]) | (uint64(b[1]) << 8) + 256 + case 4: + h.FrameContentSize = uint64(b[0]) | (uint64(b[1]) << 8) | (uint64(b[2]) << 16) | (uint64(b[3]) << 24) + case 8: + d1 := uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24) + d2 := uint32(b[4]) | (uint32(b[5]) << 8) | (uint32(b[6]) << 16) | (uint32(b[7]) << 24) + h.FrameContentSize = uint64(d1) | (uint64(d2) << 32) + } + } + + // Frame Header done, we will not fail from now on. + if len(in) < 3 { + return nil + } + tmp, in := in[:3], in[3:] + bh := uint32(tmp[0]) | (uint32(tmp[1]) << 8) | (uint32(tmp[2]) << 16) + h.FirstBlock.Last = bh&1 != 0 + blockType := blockType((bh >> 1) & 3) + // find size. + cSize := int(bh >> 3) + switch blockType { + case blockTypeReserved: + return nil + case blockTypeRLE: + h.FirstBlock.Compressed = true + h.FirstBlock.DecompressedSize = cSize + h.FirstBlock.CompressedSize = 1 + case blockTypeCompressed: + h.FirstBlock.Compressed = true + h.FirstBlock.CompressedSize = cSize + case blockTypeRaw: + h.FirstBlock.DecompressedSize = cSize + h.FirstBlock.CompressedSize = cSize + default: + panic("Invalid block type") + } + + h.FirstBlock.OK = true + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/decoder.go b/vendor/github.com/klauspost/compress/zstd/decoder.go index cdda0de58b447..1d41c25d2926e 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder.go @@ -5,7 +5,6 @@ package zstd import ( - "bytes" "errors" "io" "sync" @@ -85,6 +84,10 @@ func NewReader(r io.Reader, opts ...DOption) (*Decoder, error) { d.current.output = make(chan decodeOutput, d.o.concurrent) d.current.flushed = true + if r == nil { + d.current.err = ErrDecoderNilInput + } + // Transfer option dicts. d.dicts = make(map[uint32]dict, len(d.o.dicts)) for _, dc := range d.o.dicts { @@ -111,7 +114,7 @@ func NewReader(r io.Reader, opts ...DOption) (*Decoder, error) { // When the stream is done, io.EOF will be returned. func (d *Decoder) Read(p []byte) (int, error) { if d.stream == nil { - return 0, errors.New("no input has been initialized") + return 0, ErrDecoderNilInput } var n int for { @@ -152,12 +155,20 @@ func (d *Decoder) Read(p []byte) (int, error) { // Reset will reset the decoder the supplied stream after the current has finished processing. // Note that this functionality cannot be used after Close has been called. +// Reset can be called with a nil reader to release references to the previous reader. +// After being called with a nil reader, no other operations than Reset or DecodeAll or Close +// should be used. func (d *Decoder) Reset(r io.Reader) error { if d.current.err == ErrDecoderClosed { return d.current.err } + + d.drainOutput() + if r == nil { - return errors.New("nil Reader sent as input") + d.current.err = ErrDecoderNilInput + d.current.flushed = true + return nil } if d.stream == nil { @@ -166,14 +177,14 @@ func (d *Decoder) Reset(r io.Reader) error { go d.startStreamDecoder(d.stream) } - d.drainOutput() - // If bytes buffer and < 1MB, do sync decoding anyway. - if bb, ok := r.(*bytes.Buffer); ok && bb.Len() < 1<<20 { + if bb, ok := r.(byter); ok && bb.Len() < 1<<20 { + var bb2 byter + bb2 = bb if debug { println("*bytes.Buffer detected, doing sync decode, len:", bb.Len()) } - b := bb.Bytes() + b := bb2.Bytes() var dst []byte if cap(d.current.b) > 0 { dst = d.current.b @@ -249,7 +260,7 @@ func (d *Decoder) drainOutput() { // Any error encountered during the write is also returned. func (d *Decoder) WriteTo(w io.Writer) (int64, error) { if d.stream == nil { - return 0, errors.New("no input has been initialized") + return 0, ErrDecoderNilInput } var n int64 for { diff --git a/vendor/github.com/klauspost/compress/zstd/enc_best.go b/vendor/github.com/klauspost/compress/zstd/enc_best.go new file mode 100644 index 0000000000000..c4baa42c6484b --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/enc_best.go @@ -0,0 +1,484 @@ +// Copyright 2019+ Klaus Post. All rights reserved. +// License information can be found in the LICENSE file. +// Based on work by Yann Collet, released under BSD License. + +package zstd + +import ( + "fmt" + "math/bits" +) + +const ( + bestLongTableBits = 20 // Bits used in the long match table + bestLongTableSize = 1 << bestLongTableBits // Size of the table + + // Note: Increasing the short table bits or making the hash shorter + // can actually lead to compression degradation since it will 'steal' more from the + // long match table and match offsets are quite big. + // This greatly depends on the type of input. + bestShortTableBits = 16 // Bits used in the short match table + bestShortTableSize = 1 << bestShortTableBits // Size of the table +) + +// bestFastEncoder uses 2 tables, one for short matches (5 bytes) and one for long matches. +// The long match table contains the previous entry with the same hash, +// effectively making it a "chain" of length 2. +// When we find a long match we choose between the two values and select the longest. +// When we find a short match, after checking the long, we check if we can find a long at n+1 +// and that it is longer (lazy matching). +type bestFastEncoder struct { + fastBase + table [bestShortTableSize]prevEntry + longTable [bestLongTableSize]prevEntry + dictTable []prevEntry + dictLongTable []prevEntry +} + +// Encode improves compression... +func (e *bestFastEncoder) Encode(blk *blockEnc, src []byte) { + const ( + // Input margin is the number of bytes we read (8) + // and the maximum we will read ahead (2) + inputMargin = 8 + 4 + minNonLiteralBlockSize = 16 + ) + + // Protect against e.cur wraparound. + for e.cur >= bufferReset { + if len(e.hist) == 0 { + for i := range e.table[:] { + e.table[i] = prevEntry{} + } + for i := range e.longTable[:] { + e.longTable[i] = prevEntry{} + } + e.cur = e.maxMatchOff + break + } + // Shift down everything in the table that isn't already too far away. + minOff := e.cur + int32(len(e.hist)) - e.maxMatchOff + for i := range e.table[:] { + v := e.table[i].offset + v2 := e.table[i].prev + if v < minOff { + v = 0 + v2 = 0 + } else { + v = v - e.cur + e.maxMatchOff + if v2 < minOff { + v2 = 0 + } else { + v2 = v2 - e.cur + e.maxMatchOff + } + } + e.table[i] = prevEntry{ + offset: v, + prev: v2, + } + } + for i := range e.longTable[:] { + v := e.longTable[i].offset + v2 := e.longTable[i].prev + if v < minOff { + v = 0 + v2 = 0 + } else { + v = v - e.cur + e.maxMatchOff + if v2 < minOff { + v2 = 0 + } else { + v2 = v2 - e.cur + e.maxMatchOff + } + } + e.longTable[i] = prevEntry{ + offset: v, + prev: v2, + } + } + e.cur = e.maxMatchOff + break + } + + s := e.addBlock(src) + blk.size = len(src) + if len(src) < minNonLiteralBlockSize { + blk.extraLits = len(src) + blk.literals = blk.literals[:len(src)] + copy(blk.literals, src) + return + } + + // Override src + src = e.hist + sLimit := int32(len(src)) - inputMargin + const kSearchStrength = 12 + + // nextEmit is where in src the next emitLiteral should start from. + nextEmit := s + cv := load6432(src, s) + + // Relative offsets + offset1 := int32(blk.recentOffsets[0]) + offset2 := int32(blk.recentOffsets[1]) + offset3 := int32(blk.recentOffsets[2]) + + addLiterals := func(s *seq, until int32) { + if until == nextEmit { + return + } + blk.literals = append(blk.literals, src[nextEmit:until]...) + s.litLen = uint32(until - nextEmit) + } + _ = addLiterals + + if debug { + println("recent offsets:", blk.recentOffsets) + } + +encodeLoop: + for { + // We allow the encoder to optionally turn off repeat offsets across blocks + canRepeat := len(blk.sequences) > 2 + + if debugAsserts && canRepeat && offset1 == 0 { + panic("offset0 was 0") + } + + type match struct { + offset int32 + s int32 + length int32 + rep int32 + } + matchAt := func(offset int32, s int32, first uint32, rep int32) match { + if s-offset >= e.maxMatchOff || load3232(src, offset) != first { + return match{offset: offset, s: s} + } + return match{offset: offset, s: s, length: 4 + e.matchlen(s+4, offset+4, src), rep: rep} + } + + bestOf := func(a, b match) match { + aScore := b.s - a.s + a.length + bScore := a.s - b.s + b.length + if a.rep < 0 { + aScore = aScore - int32(bits.Len32(uint32(a.offset)))/8 + } + if b.rep < 0 { + bScore = bScore - int32(bits.Len32(uint32(b.offset)))/8 + } + if aScore >= bScore { + return a + } + return b + } + const goodEnough = 100 + + nextHashL := hash8(cv, bestLongTableBits) + nextHashS := hash4x64(cv, bestShortTableBits) + candidateL := e.longTable[nextHashL] + candidateS := e.table[nextHashS] + + best := bestOf(matchAt(candidateL.offset-e.cur, s, uint32(cv), -1), matchAt(candidateL.prev-e.cur, s, uint32(cv), -1)) + best = bestOf(best, matchAt(candidateS.offset-e.cur, s, uint32(cv), -1)) + best = bestOf(best, matchAt(candidateS.prev-e.cur, s, uint32(cv), -1)) + if canRepeat && best.length < goodEnough { + best = bestOf(best, matchAt(s-offset1+1, s+1, uint32(cv>>8), 1)) + best = bestOf(best, matchAt(s-offset2+1, s+1, uint32(cv>>8), 2)) + best = bestOf(best, matchAt(s-offset3+1, s+1, uint32(cv>>8), 3)) + best = bestOf(best, matchAt(s-offset1+3, s+3, uint32(cv>>24), 1)) + best = bestOf(best, matchAt(s-offset2+3, s+3, uint32(cv>>24), 2)) + best = bestOf(best, matchAt(s-offset3+3, s+3, uint32(cv>>24), 3)) + } + // Load next and check... + e.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: candidateL.offset} + e.table[nextHashS] = prevEntry{offset: s + e.cur, prev: candidateS.offset} + + // Look far ahead, unless we have a really long match already... + if best.length < goodEnough { + // No match found, move forward on input, no need to check forward... + if best.length < 4 { + s += 1 + (s-nextEmit)>>(kSearchStrength-1) + if s >= sLimit { + break encodeLoop + } + cv = load6432(src, s) + continue + } + + s++ + candidateS = e.table[hash4x64(cv>>8, bestShortTableBits)] + cv = load6432(src, s) + cv2 := load6432(src, s+1) + candidateL = e.longTable[hash8(cv, bestLongTableBits)] + candidateL2 := e.longTable[hash8(cv2, bestLongTableBits)] + + best = bestOf(best, matchAt(candidateS.offset-e.cur, s, uint32(cv), -1)) + best = bestOf(best, matchAt(candidateL.offset-e.cur, s, uint32(cv), -1)) + best = bestOf(best, matchAt(candidateL.prev-e.cur, s, uint32(cv), -1)) + best = bestOf(best, matchAt(candidateL2.offset-e.cur, s+1, uint32(cv2), -1)) + best = bestOf(best, matchAt(candidateL2.prev-e.cur, s+1, uint32(cv2), -1)) + } + + // We have a match, we can store the forward value + if best.rep > 0 { + s = best.s + var seq seq + seq.matchLen = uint32(best.length - zstdMinMatch) + + // We might be able to match backwards. + // Extend as long as we can. + start := best.s + // We end the search early, so we don't risk 0 literals + // and have to do special offset treatment. + startLimit := nextEmit + 1 + + tMin := s - e.maxMatchOff + if tMin < 0 { + tMin = 0 + } + repIndex := best.offset + for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 { + repIndex-- + start-- + seq.matchLen++ + } + addLiterals(&seq, start) + + // rep 0 + seq.offset = uint32(best.rep) + if debugSequences { + println("repeat sequence", seq, "next s:", s) + } + blk.sequences = append(blk.sequences, seq) + + // Index match start+1 (long) -> s - 1 + index0 := s + s = best.s + best.length + + nextEmit = s + if s >= sLimit { + if debug { + println("repeat ended", s, best.length) + + } + break encodeLoop + } + // Index skipped... + off := index0 + e.cur + for index0 < s-1 { + cv0 := load6432(src, index0) + h0 := hash8(cv0, bestLongTableBits) + h1 := hash4x64(cv0, bestShortTableBits) + e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} + e.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset} + off++ + index0++ + } + switch best.rep { + case 2: + offset1, offset2 = offset2, offset1 + case 3: + offset1, offset2, offset3 = offset3, offset1, offset2 + } + cv = load6432(src, s) + continue + } + + // A 4-byte match has been found. Update recent offsets. + // We'll later see if more than 4 bytes. + s = best.s + t := best.offset + offset1, offset2, offset3 = s-t, offset1, offset2 + + if debugAsserts && s <= t { + panic(fmt.Sprintf("s (%d) <= t (%d)", s, t)) + } + + if debugAsserts && canRepeat && int(offset1) > len(src) { + panic("invalid offset") + } + + // Extend the n-byte match as long as possible. + l := best.length + + // Extend backwards + tMin := s - e.maxMatchOff + if tMin < 0 { + tMin = 0 + } + for t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength { + s-- + t-- + l++ + } + + // Write our sequence + var seq seq + seq.litLen = uint32(s - nextEmit) + seq.matchLen = uint32(l - zstdMinMatch) + if seq.litLen > 0 { + blk.literals = append(blk.literals, src[nextEmit:s]...) + } + seq.offset = uint32(s-t) + 3 + s += l + if debugSequences { + println("sequence", seq, "next s:", s) + } + blk.sequences = append(blk.sequences, seq) + nextEmit = s + if s >= sLimit { + break encodeLoop + } + + // Index match start+1 (long) -> s - 1 + index0 := s - l + 1 + // every entry + for index0 < s-1 { + cv0 := load6432(src, index0) + h0 := hash8(cv0, bestLongTableBits) + h1 := hash4x64(cv0, bestShortTableBits) + off := index0 + e.cur + e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} + e.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset} + index0++ + } + + cv = load6432(src, s) + if !canRepeat { + continue + } + + // Check offset 2 + for { + o2 := s - offset2 + if load3232(src, o2) != uint32(cv) { + // Do regular search + break + } + + // Store this, since we have it. + nextHashS := hash4x64(cv, bestShortTableBits) + nextHashL := hash8(cv, bestLongTableBits) + + // We have at least 4 byte match. + // No need to check backwards. We come straight from a match + l := 4 + e.matchlen(s+4, o2+4, src) + + e.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: e.longTable[nextHashL].offset} + e.table[nextHashS] = prevEntry{offset: s + e.cur, prev: e.table[nextHashS].offset} + seq.matchLen = uint32(l) - zstdMinMatch + seq.litLen = 0 + + // Since litlen is always 0, this is offset 1. + seq.offset = 1 + s += l + nextEmit = s + if debugSequences { + println("sequence", seq, "next s:", s) + } + blk.sequences = append(blk.sequences, seq) + + // Swap offset 1 and 2. + offset1, offset2 = offset2, offset1 + if s >= sLimit { + // Finished + break encodeLoop + } + cv = load6432(src, s) + } + } + + if int(nextEmit) < len(src) { + blk.literals = append(blk.literals, src[nextEmit:]...) + blk.extraLits = len(src) - int(nextEmit) + } + blk.recentOffsets[0] = uint32(offset1) + blk.recentOffsets[1] = uint32(offset2) + blk.recentOffsets[2] = uint32(offset3) + if debug { + println("returning, recent offsets:", blk.recentOffsets, "extra literals:", blk.extraLits) + } +} + +// EncodeNoHist will encode a block with no history and no following blocks. +// Most notable difference is that src will not be copied for history and +// we do not need to check for max match length. +func (e *bestFastEncoder) EncodeNoHist(blk *blockEnc, src []byte) { + e.Encode(blk, src) +} + +// ResetDict will reset and set a dictionary if not nil +func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) { + e.resetBase(d, singleBlock) + if d == nil { + return + } + // Init or copy dict table + if len(e.dictTable) != len(e.table) || d.id != e.lastDictID { + if len(e.dictTable) != len(e.table) { + e.dictTable = make([]prevEntry, len(e.table)) + } + end := int32(len(d.content)) - 8 + e.maxMatchOff + for i := e.maxMatchOff; i < end; i += 4 { + const hashLog = bestShortTableBits + + cv := load6432(d.content, i-e.maxMatchOff) + nextHash := hash4x64(cv, hashLog) // 0 -> 4 + nextHash1 := hash4x64(cv>>8, hashLog) // 1 -> 5 + nextHash2 := hash4x64(cv>>16, hashLog) // 2 -> 6 + nextHash3 := hash4x64(cv>>24, hashLog) // 3 -> 7 + e.dictTable[nextHash] = prevEntry{ + prev: e.dictTable[nextHash].offset, + offset: i, + } + e.dictTable[nextHash1] = prevEntry{ + prev: e.dictTable[nextHash1].offset, + offset: i + 1, + } + e.dictTable[nextHash2] = prevEntry{ + prev: e.dictTable[nextHash2].offset, + offset: i + 2, + } + e.dictTable[nextHash3] = prevEntry{ + prev: e.dictTable[nextHash3].offset, + offset: i + 3, + } + } + e.lastDictID = d.id + } + + // Init or copy dict table + if len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID { + if len(e.dictLongTable) != len(e.longTable) { + e.dictLongTable = make([]prevEntry, len(e.longTable)) + } + if len(d.content) >= 8 { + cv := load6432(d.content, 0) + h := hash8(cv, bestLongTableBits) + e.dictLongTable[h] = prevEntry{ + offset: e.maxMatchOff, + prev: e.dictLongTable[h].offset, + } + + end := int32(len(d.content)) - 8 + e.maxMatchOff + off := 8 // First to read + for i := e.maxMatchOff + 1; i < end; i++ { + cv = cv>>8 | (uint64(d.content[off]) << 56) + h := hash8(cv, bestLongTableBits) + e.dictLongTable[h] = prevEntry{ + offset: i, + prev: e.dictLongTable[h].offset, + } + off++ + } + } + e.lastDictID = d.id + } + // Reset table to initial state + copy(e.longTable[:], e.dictLongTable) + + e.cur = e.maxMatchOff + // Reset table to initial state + copy(e.table[:], e.dictTable) +} diff --git a/vendor/github.com/klauspost/compress/zstd/encoder_options.go b/vendor/github.com/klauspost/compress/zstd/encoder_options.go index 1209915bcce7b..a7312f42af7fe 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder_options.go @@ -47,6 +47,8 @@ func (o encoderOptions) encoder() encoder { return &doubleFastEncoder{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize)}}} case SpeedBetterCompression: return &betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize)}} + case SpeedBestCompression: + return &bestFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize)}} case SpeedFastest: return &fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize)}} } @@ -143,20 +145,20 @@ const ( // By using this, notice that CPU usage may go up in the future. SpeedBetterCompression + // SpeedBestCompression will choose the best available compression option. + // This will offer the best compression no matter the CPU cost. + SpeedBestCompression + // speedLast should be kept as the last actual compression option. // The is not for external usage, but is used to keep track of the valid options. speedLast - - // SpeedBestCompression will choose the best available compression option. - // For now this is not implemented. - SpeedBestCompression = SpeedBetterCompression ) // EncoderLevelFromString will convert a string representation of an encoding level back // to a compression level. The compare is not case sensitive. // If the string wasn't recognized, (false, SpeedDefault) will be returned. func EncoderLevelFromString(s string) (bool, EncoderLevel) { - for l := EncoderLevel(speedNotSet + 1); l < speedLast; l++ { + for l := speedNotSet + 1; l < speedLast; l++ { if strings.EqualFold(s, l.String()) { return true, l } @@ -173,7 +175,9 @@ func EncoderLevelFromZstd(level int) EncoderLevel { return SpeedFastest case level >= 3 && level < 6: return SpeedDefault - case level > 5: + case level >= 6 && level < 10: + return SpeedBetterCompression + case level >= 10: return SpeedBetterCompression } return SpeedDefault @@ -188,6 +192,8 @@ func (e EncoderLevel) String() string { return "default" case SpeedBetterCompression: return "better" + case SpeedBestCompression: + return "best" default: return "invalid" } @@ -209,6 +215,8 @@ func WithEncoderLevel(l EncoderLevel) EOption { o.windowSize = 8 << 20 case SpeedBetterCompression: o.windowSize = 16 << 20 + case SpeedBestCompression: + o.windowSize = 32 << 20 } } if !o.customALEntropy { diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec.go b/vendor/github.com/klauspost/compress/zstd/seqdec.go index b5c8ef133296a..1dd39e63b7e83 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec.go @@ -181,11 +181,18 @@ func (s *sequenceDecs) decode(seqs int, br *bitReader, hist []byte) error { return fmt.Errorf("output (%d) bigger than max block size", size) } if size > cap(s.out) { - // Not enough size, will be extremely rarely triggered, + // Not enough size, which can happen under high volume block streaming conditions // but could be if destination slice is too small for sync operations. - // We add maxBlockSize to the capacity. - s.out = append(s.out, make([]byte, maxBlockSize)...) - s.out = s.out[:len(s.out)-maxBlockSize] + // over-allocating here can create a large amount of GC pressure so we try to keep + // it as contained as possible + used := len(s.out) - startSize + addBytes := 256 + ll + ml + used>>2 + // Clamp to max block size. + if used+addBytes > maxBlockSize { + addBytes = maxBlockSize - used + } + s.out = append(s.out, make([]byte, addBytes)...) + s.out = s.out[:len(s.out)-addBytes] } if ml > maxMatchLen { return fmt.Errorf("match len (%d) bigger than max allowed length", ml) diff --git a/vendor/github.com/klauspost/compress/zstd/zstd.go b/vendor/github.com/klauspost/compress/zstd/zstd.go index 0807719c8b906..9056beef271a4 100644 --- a/vendor/github.com/klauspost/compress/zstd/zstd.go +++ b/vendor/github.com/klauspost/compress/zstd/zstd.go @@ -4,6 +4,7 @@ package zstd import ( + "bytes" "errors" "log" "math" @@ -73,6 +74,10 @@ var ( // ErrDecoderClosed will be returned if the Decoder was used after // Close has been called. ErrDecoderClosed = errors.New("decoder used after Close") + + // ErrDecoderNilInput is returned when a nil Reader was provided + // and an operation other than Reset/DecodeAll/Close was attempted. + ErrDecoderNilInput = errors.New("nil input provided as reader") ) func println(a ...interface{}) { @@ -142,3 +147,10 @@ func load64(b []byte, i int) uint64 { return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 } + +type byter interface { + Bytes() []byte + Len() int +} + +var _ byter = &bytes.Buffer{} diff --git a/vendor/github.com/kr/pretty/formatter.go b/vendor/github.com/kr/pretty/formatter.go index df61d8d19e6c1..bf4b598d06794 100644 --- a/vendor/github.com/kr/pretty/formatter.go +++ b/vendor/github.com/kr/pretty/formatter.go @@ -37,7 +37,7 @@ func (fo formatter) passThrough(f fmt.State, c rune) { s := "%" for i := 0; i < 128; i++ { if f.Flag(i) { - s += string(i) + s += string(rune(i)) } } if w, ok := f.Width(); ok { diff --git a/vendor/github.com/lib/pq/.gitignore b/vendor/github.com/lib/pq/.gitignore index 0f1d00e1196ca..3243952a4d600 100644 --- a/vendor/github.com/lib/pq/.gitignore +++ b/vendor/github.com/lib/pq/.gitignore @@ -2,3 +2,5 @@ *.test *~ *.swp +.idea +.vscode \ No newline at end of file diff --git a/vendor/github.com/lib/pq/.travis.yml b/vendor/github.com/lib/pq/.travis.yml index 68e89e88da199..f378207f2049c 100644 --- a/vendor/github.com/lib/pq/.travis.yml +++ b/vendor/github.com/lib/pq/.travis.yml @@ -1,7 +1,6 @@ language: go go: - - 1.13.x - 1.14.x - 1.15.x - master diff --git a/vendor/github.com/lib/pq/array.go b/vendor/github.com/lib/pq/array.go index e4933e227649a..405da23683b1e 100644 --- a/vendor/github.com/lib/pq/array.go +++ b/vendor/github.com/lib/pq/array.go @@ -35,19 +35,31 @@ func Array(a interface{}) interface { return (*BoolArray)(&a) case []float64: return (*Float64Array)(&a) + case []float32: + return (*Float32Array)(&a) case []int64: return (*Int64Array)(&a) + case []int32: + return (*Int32Array)(&a) case []string: return (*StringArray)(&a) + case [][]byte: + return (*ByteaArray)(&a) case *[]bool: return (*BoolArray)(a) case *[]float64: return (*Float64Array)(a) + case *[]float32: + return (*Float32Array)(a) case *[]int64: return (*Int64Array)(a) + case *[]int32: + return (*Int32Array)(a) case *[]string: return (*StringArray)(a) + case *[][]byte: + return (*ByteaArray)(a) } return GenericArray{a} @@ -267,6 +279,70 @@ func (a Float64Array) Value() (driver.Value, error) { return "{}", nil } +// Float32Array represents a one-dimensional array of the PostgreSQL double +// precision type. +type Float32Array []float32 + +// Scan implements the sql.Scanner interface. +func (a *Float32Array) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + return a.scanBytes(src) + case string: + return a.scanBytes([]byte(src)) + case nil: + *a = nil + return nil + } + + return fmt.Errorf("pq: cannot convert %T to Float32Array", src) +} + +func (a *Float32Array) scanBytes(src []byte) error { + elems, err := scanLinearArray(src, []byte{','}, "Float32Array") + if err != nil { + return err + } + if *a != nil && len(elems) == 0 { + *a = (*a)[:0] + } else { + b := make(Float32Array, len(elems)) + for i, v := range elems { + var x float64 + if x, err = strconv.ParseFloat(string(v), 32); err != nil { + return fmt.Errorf("pq: parsing array element index %d: %v", i, err) + } + b[i] = float32(x) + } + *a = b + } + return nil +} + +// Value implements the driver.Valuer interface. +func (a Float32Array) Value() (driver.Value, error) { + if a == nil { + return nil, nil + } + + if n := len(a); n > 0 { + // There will be at least two curly brackets, N bytes of values, + // and N-1 bytes of delimiters. + b := make([]byte, 1, 1+2*n) + b[0] = '{' + + b = strconv.AppendFloat(b, float64(a[0]), 'f', -1, 32) + for i := 1; i < n; i++ { + b = append(b, ',') + b = strconv.AppendFloat(b, float64(a[i]), 'f', -1, 32) + } + + return string(append(b, '}')), nil + } + + return "{}", nil +} + // GenericArray implements the driver.Valuer and sql.Scanner interfaces for // an array or slice of any dimension. type GenericArray struct{ A interface{} } @@ -483,6 +559,69 @@ func (a Int64Array) Value() (driver.Value, error) { return "{}", nil } +// Int32Array represents a one-dimensional array of the PostgreSQL integer types. +type Int32Array []int32 + +// Scan implements the sql.Scanner interface. +func (a *Int32Array) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + return a.scanBytes(src) + case string: + return a.scanBytes([]byte(src)) + case nil: + *a = nil + return nil + } + + return fmt.Errorf("pq: cannot convert %T to Int32Array", src) +} + +func (a *Int32Array) scanBytes(src []byte) error { + elems, err := scanLinearArray(src, []byte{','}, "Int32Array") + if err != nil { + return err + } + if *a != nil && len(elems) == 0 { + *a = (*a)[:0] + } else { + b := make(Int32Array, len(elems)) + for i, v := range elems { + var x int + if x, err = strconv.Atoi(string(v)); err != nil { + return fmt.Errorf("pq: parsing array element index %d: %v", i, err) + } + b[i] = int32(x) + } + *a = b + } + return nil +} + +// Value implements the driver.Valuer interface. +func (a Int32Array) Value() (driver.Value, error) { + if a == nil { + return nil, nil + } + + if n := len(a); n > 0 { + // There will be at least two curly brackets, N bytes of values, + // and N-1 bytes of delimiters. + b := make([]byte, 1, 1+2*n) + b[0] = '{' + + b = strconv.AppendInt(b, int64(a[0]), 10) + for i := 1; i < n; i++ { + b = append(b, ',') + b = strconv.AppendInt(b, int64(a[i]), 10) + } + + return string(append(b, '}')), nil + } + + return "{}", nil +} + // StringArray represents a one-dimensional array of the PostgreSQL character types. type StringArray []string diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go index f313c1498613f..db0b6cef5e0ed 100644 --- a/vendor/github.com/lib/pq/conn.go +++ b/vendor/github.com/lib/pq/conn.go @@ -18,6 +18,7 @@ import ( "path/filepath" "strconv" "strings" + "sync/atomic" "time" "unicode" @@ -38,13 +39,18 @@ var ( errNoLastInsertID = errors.New("no LastInsertId available after the empty statement") ) +// Compile time validation that our types implement the expected interfaces +var ( + _ driver.Driver = Driver{} +) + // Driver is the Postgres database driver. type Driver struct{} // Open opens a new connection to the database. name is a connection string. // Most users should only use it through database/sql package from the standard // library. -func (d *Driver) Open(name string) (driver.Conn, error) { +func (d Driver) Open(name string) (driver.Conn, error) { return Open(name) } @@ -136,7 +142,7 @@ type conn struct { // If true, this connection is bad and all public-facing functions should // return ErrBadConn. - bad bool + bad *atomic.Value // If set, this connection should never use the binary format when // receiving query results from prepared statements. Only provided for @@ -294,9 +300,12 @@ func (c *Connector) open(ctx context.Context) (cn *conn, err error) { o := c.opts + bad := &atomic.Value{} + bad.Store(false) cn = &conn{ opts: o, dialer: c.dialer, + bad: bad, } err = cn.handleDriverSettings(o) if err != nil { @@ -501,9 +510,22 @@ func (cn *conn) isInTransaction() bool { cn.txnStatus == txnStatusInFailedTransaction } +func (cn *conn) setBad() { + if cn.bad != nil { + cn.bad.Store(true) + } +} + +func (cn *conn) getBad() bool { + if cn.bad != nil { + return cn.bad.Load().(bool) + } + return false +} + func (cn *conn) checkIsInTransaction(intxn bool) { if cn.isInTransaction() != intxn { - cn.bad = true + cn.setBad() errorf("unexpected transaction status %v", cn.txnStatus) } } @@ -513,7 +535,7 @@ func (cn *conn) Begin() (_ driver.Tx, err error) { } func (cn *conn) begin(mode string) (_ driver.Tx, err error) { - if cn.bad { + if cn.getBad() { return nil, driver.ErrBadConn } defer cn.errRecover(&err) @@ -524,11 +546,11 @@ func (cn *conn) begin(mode string) (_ driver.Tx, err error) { return nil, err } if commandTag != "BEGIN" { - cn.bad = true + cn.setBad() return nil, fmt.Errorf("unexpected command tag %s", commandTag) } if cn.txnStatus != txnStatusIdleInTransaction { - cn.bad = true + cn.setBad() return nil, fmt.Errorf("unexpected transaction status %v", cn.txnStatus) } return cn, nil @@ -542,7 +564,7 @@ func (cn *conn) closeTxn() { func (cn *conn) Commit() (err error) { defer cn.closeTxn() - if cn.bad { + if cn.getBad() { return driver.ErrBadConn } defer cn.errRecover(&err) @@ -564,12 +586,12 @@ func (cn *conn) Commit() (err error) { _, commandTag, err := cn.simpleExec("COMMIT") if err != nil { if cn.isInTransaction() { - cn.bad = true + cn.setBad() } return err } if commandTag != "COMMIT" { - cn.bad = true + cn.setBad() return fmt.Errorf("unexpected command tag %s", commandTag) } cn.checkIsInTransaction(false) @@ -578,7 +600,7 @@ func (cn *conn) Commit() (err error) { func (cn *conn) Rollback() (err error) { defer cn.closeTxn() - if cn.bad { + if cn.getBad() { return driver.ErrBadConn } defer cn.errRecover(&err) @@ -590,7 +612,7 @@ func (cn *conn) rollback() (err error) { _, commandTag, err := cn.simpleExec("ROLLBACK") if err != nil { if cn.isInTransaction() { - cn.bad = true + cn.setBad() } return err } @@ -630,7 +652,7 @@ func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err case 'T', 'D': // ignore any results default: - cn.bad = true + cn.setBad() errorf("unknown response for simple query: %q", t) } } @@ -652,7 +674,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) { // the user can close, though, to avoid connections from being // leaked. A "rows" with done=true works fine for that purpose. if err != nil { - cn.bad = true + cn.setBad() errorf("unexpected message %q in simple query execution", t) } if res == nil { @@ -663,8 +685,11 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) { // Set the result and tag to the last command complete if there wasn't a // query already run. Although queries usually return from here and cede // control to Next, a query with zero results does not. - if t == 'C' && res.colNames == nil { + if t == 'C' { res.result, res.tag = cn.parseComplete(r.string()) + if res.colNames != nil { + return + } } res.done = true case 'Z': @@ -676,7 +701,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) { err = parseError(r) case 'D': if res == nil { - cn.bad = true + cn.setBad() errorf("unexpected DataRow in simple query execution") } // the query didn't fail; kick off to Next @@ -691,7 +716,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) { // To work around a bug in QueryRow in Go 1.2 and earlier, wait // until the first DataRow has been received. default: - cn.bad = true + cn.setBad() errorf("unknown response for simple query: %q", t) } } @@ -784,7 +809,7 @@ func (cn *conn) prepareTo(q, stmtName string) *stmt { } func (cn *conn) Prepare(q string) (_ driver.Stmt, err error) { - if cn.bad { + if cn.getBad() { return nil, driver.ErrBadConn } defer cn.errRecover(&err) @@ -823,7 +848,7 @@ func (cn *conn) Query(query string, args []driver.Value) (driver.Rows, error) { } func (cn *conn) query(query string, args []driver.Value) (_ *rows, err error) { - if cn.bad { + if cn.getBad() { return nil, driver.ErrBadConn } if cn.inCopy { @@ -857,7 +882,7 @@ func (cn *conn) query(query string, args []driver.Value) (_ *rows, err error) { // Implement the optional "Execer" interface for one-shot queries func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err error) { - if cn.bad { + if cn.getBad() { return nil, driver.ErrBadConn } defer cn.errRecover(&err) @@ -891,9 +916,20 @@ func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err return r, err } +type safeRetryError struct { + Err error +} + +func (se *safeRetryError) Error() string { + return se.Err.Error() +} + func (cn *conn) send(m *writeBuf) { - _, err := cn.c.Write(m.wrap()) + n, err := cn.c.Write(m.wrap()) if err != nil { + if n == 0 { + err = &safeRetryError{Err: err} + } panic(err) } } @@ -918,7 +954,7 @@ func (cn *conn) sendSimpleMessage(typ byte) (err error) { // the message yourself. func (cn *conn) saveMessage(typ byte, buf *readBuf) { if cn.saveMessageType != 0 { - cn.bad = true + cn.setBad() errorf("unexpected saveMessageType %d", cn.saveMessageType) } cn.saveMessageType = typ @@ -1288,7 +1324,7 @@ func (st *stmt) Close() (err error) { if st.closed { return nil } - if st.cn.bad { + if st.cn.getBad() { return driver.ErrBadConn } defer st.cn.errRecover(&err) @@ -1302,14 +1338,14 @@ func (st *stmt) Close() (err error) { t, _ := st.cn.recv1() if t != '3' { - st.cn.bad = true + st.cn.setBad() errorf("unexpected close response: %q", t) } st.closed = true t, r := st.cn.recv1() if t != 'Z' { - st.cn.bad = true + st.cn.setBad() errorf("expected ready for query, but got: %q", t) } st.cn.processReadyForQuery(r) @@ -1318,7 +1354,7 @@ func (st *stmt) Close() (err error) { } func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) { - if st.cn.bad { + if st.cn.getBad() { return nil, driver.ErrBadConn } defer st.cn.errRecover(&err) @@ -1331,7 +1367,7 @@ func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) { } func (st *stmt) Exec(v []driver.Value) (res driver.Result, err error) { - if st.cn.bad { + if st.cn.getBad() { return nil, driver.ErrBadConn } defer st.cn.errRecover(&err) @@ -1418,7 +1454,7 @@ func (cn *conn) parseComplete(commandTag string) (driver.Result, string) { if affectedRows == nil && strings.HasPrefix(commandTag, "INSERT ") { parts := strings.Split(commandTag, " ") if len(parts) != 3 { - cn.bad = true + cn.setBad() errorf("unexpected INSERT command tag %s", commandTag) } affectedRows = &parts[len(parts)-1] @@ -1430,7 +1466,7 @@ func (cn *conn) parseComplete(commandTag string) (driver.Result, string) { } n, err := strconv.ParseInt(*affectedRows, 10, 64) if err != nil { - cn.bad = true + cn.setBad() errorf("could not parse commandTag: %s", err) } return driver.RowsAffected(n), commandTag @@ -1497,7 +1533,7 @@ func (rs *rows) Next(dest []driver.Value) (err error) { } conn := rs.cn - if conn.bad { + if conn.getBad() { return driver.ErrBadConn } defer conn.errRecover(&err) @@ -1522,7 +1558,7 @@ func (rs *rows) Next(dest []driver.Value) (err error) { case 'D': n := rs.rb.int16() if err != nil { - conn.bad = true + conn.setBad() errorf("unexpected DataRow after error %s", err) } if n < len(dest) { @@ -1717,7 +1753,7 @@ func (cn *conn) readReadyForQuery() { cn.processReadyForQuery(r) return default: - cn.bad = true + cn.setBad() errorf("unexpected message %q; expected ReadyForQuery", t) } } @@ -1737,7 +1773,7 @@ func (cn *conn) readParseResponse() { cn.readReadyForQuery() panic(err) default: - cn.bad = true + cn.setBad() errorf("unexpected Parse response %q", t) } } @@ -1762,7 +1798,7 @@ func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames [ cn.readReadyForQuery() panic(err) default: - cn.bad = true + cn.setBad() errorf("unexpected Describe statement response %q", t) } } @@ -1780,7 +1816,7 @@ func (cn *conn) readPortalDescribeResponse() rowsHeader { cn.readReadyForQuery() panic(err) default: - cn.bad = true + cn.setBad() errorf("unexpected Describe response %q", t) } panic("not reached") @@ -1796,7 +1832,7 @@ func (cn *conn) readBindResponse() { cn.readReadyForQuery() panic(err) default: - cn.bad = true + cn.setBad() errorf("unexpected Bind response %q", t) } } @@ -1823,7 +1859,7 @@ func (cn *conn) postExecuteWorkaround() { cn.saveMessage(t, r) return default: - cn.bad = true + cn.setBad() errorf("unexpected message during extended query execution: %q", t) } } @@ -1836,7 +1872,7 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co switch t { case 'C': if err != nil { - cn.bad = true + cn.setBad() errorf("unexpected CommandComplete after error %s", err) } res, commandTag = cn.parseComplete(r.string()) @@ -1850,7 +1886,7 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co err = parseError(r) case 'T', 'D', 'I': if err != nil { - cn.bad = true + cn.setBad() errorf("unexpected %q after error %s", t, err) } if t == 'I' { @@ -1858,7 +1894,7 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co } // ignore any results default: - cn.bad = true + cn.setBad() errorf("unknown %s response: %q", protocolState, t) } } diff --git a/vendor/github.com/lib/pq/conn_go18.go b/vendor/github.com/lib/pq/conn_go18.go index 09e2ea4648eb9..8cab67c9d2d45 100644 --- a/vendor/github.com/lib/pq/conn_go18.go +++ b/vendor/github.com/lib/pq/conn_go18.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "io/ioutil" + "sync/atomic" "time" ) @@ -89,10 +90,21 @@ func (cn *conn) Ping(ctx context.Context) error { func (cn *conn) watchCancel(ctx context.Context) func() { if done := ctx.Done(); done != nil { - finished := make(chan struct{}) + finished := make(chan struct{}, 1) go func() { select { case <-done: + select { + case finished <- struct{}{}: + default: + // We raced with the finish func, let the next query handle this with the + // context. + return + } + + // Set the connection state to bad so it does not get reused. + cn.setBad() + // At this point the function level context is canceled, // so it must not be used for the additional network // request to cancel the query. @@ -101,13 +113,14 @@ func (cn *conn) watchCancel(ctx context.Context) func() { defer cancel() _ = cn.cancel(ctxCancel) - finished <- struct{}{} case <-finished: } }() return func() { select { case <-finished: + cn.setBad() + cn.Close() case finished <- struct{}{}: } } @@ -123,8 +136,11 @@ func (cn *conn) cancel(ctx context.Context) error { defer c.Close() { + bad := &atomic.Value{} + bad.Store(false) can := conn{ - c: c, + c: c, + bad: bad, } err = can.ssl(cn.opts) if err != nil { diff --git a/vendor/github.com/lib/pq/copy.go b/vendor/github.com/lib/pq/copy.go index 9d4f850c3e741..bb3cbd7b996f5 100644 --- a/vendor/github.com/lib/pq/copy.go +++ b/vendor/github.com/lib/pq/copy.go @@ -176,13 +176,13 @@ func (ci *copyin) resploop() { func (ci *copyin) setBad() { ci.Lock() - ci.cn.bad = true + ci.cn.setBad() ci.Unlock() } func (ci *copyin) isBad() bool { ci.Lock() - b := ci.cn.bad + b := ci.cn.getBad() ci.Unlock() return b } diff --git a/vendor/github.com/lib/pq/error.go b/vendor/github.com/lib/pq/error.go index 3d66ba7c52e50..c19c349f13d8f 100644 --- a/vendor/github.com/lib/pq/error.go +++ b/vendor/github.com/lib/pq/error.go @@ -484,7 +484,7 @@ func (cn *conn) errRecover(err *error) { case nil: // Do nothing case runtime.Error: - cn.bad = true + cn.setBad() panic(v) case *Error: if v.Fatal() { @@ -493,8 +493,11 @@ func (cn *conn) errRecover(err *error) { *err = v } case *net.OpError: - cn.bad = true + cn.setBad() *err = v + case *safeRetryError: + cn.setBad() + *err = driver.ErrBadConn case error: if v == io.EOF || v.(error).Error() == "remote error: handshake failure" { *err = driver.ErrBadConn @@ -503,13 +506,13 @@ func (cn *conn) errRecover(err *error) { } default: - cn.bad = true + cn.setBad() panic(fmt.Sprintf("unknown error: %#v", e)) } // Any time we return ErrBadConn, we need to remember it since *Tx doesn't // mark the connection bad in database/sql. if *err == driver.ErrBadConn { - cn.bad = true + cn.setBad() } } diff --git a/vendor/github.com/magiconair/properties/.travis.yml b/vendor/github.com/magiconair/properties/.travis.yml index f07376f9cbed0..1a30a6cbd934e 100644 --- a/vendor/github.com/magiconair/properties/.travis.yml +++ b/vendor/github.com/magiconair/properties/.travis.yml @@ -1,5 +1,6 @@ language: go go: + - 1.3.x - 1.4.x - 1.5.x - 1.6.x @@ -9,4 +10,7 @@ go: - "1.10.x" - "1.11.x" - "1.12.x" + - "1.13.x" + - "1.14.x" + - "1.15.x" - tip diff --git a/vendor/github.com/magiconair/properties/CHANGELOG.md b/vendor/github.com/magiconair/properties/CHANGELOG.md index 176626a15a306..ff8d02535ac04 100644 --- a/vendor/github.com/magiconair/properties/CHANGELOG.md +++ b/vendor/github.com/magiconair/properties/CHANGELOG.md @@ -1,8 +1,29 @@ ## Changelog +### [1.8.2](https://github.com/magiconair/properties/tree/v1.8.2) - 25 Aug 2020 + + * [PR #36](https://github.com/magiconair/properties/pull/36): Escape backslash on write + + This patch ensures that backslashes are escaped on write. Existing applications which + rely on the old behavior may need to be updated. + + Thanks to [@apesternikov](https://github.com/apesternikov) for the patch. + + * [PR #42](https://github.com/magiconair/properties/pull/42): Made Content-Type check whitespace agnostic in LoadURL() + + Thanks to [@aliras1](https://github.com/aliras1) for the patch. + + * [PR #41](https://github.com/magiconair/properties/pull/41): Make key/value separator configurable on Write() + + Thanks to [@mkjor](https://github.com/mkjor) for the patch. + + * [PR #40](https://github.com/magiconair/properties/pull/40): Add method to return a sorted list of keys + + Thanks to [@mkjor](https://github.com/mkjor) for the patch. + ### [1.8.1](https://github.com/magiconair/properties/tree/v1.8.1) - 10 May 2019 - * [PR #26](https://github.com/magiconair/properties/pull/35): Close body always after request + * [PR #35](https://github.com/magiconair/properties/pull/35): Close body always after request This patch ensures that in `LoadURL` the response body is always closed. diff --git a/vendor/github.com/magiconair/properties/LICENSE b/vendor/github.com/magiconair/properties/LICENSE.md similarity index 84% rename from vendor/github.com/magiconair/properties/LICENSE rename to vendor/github.com/magiconair/properties/LICENSE.md index b387087c55672..79c87e3e6ffba 100644 --- a/vendor/github.com/magiconair/properties/LICENSE +++ b/vendor/github.com/magiconair/properties/LICENSE.md @@ -1,15 +1,14 @@ -goproperties - properties file decoder for Go - -Copyright (c) 2013-2018 - Frank Schroeder +Copyright (c) 2013-2020, Frank Schroeder All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, + + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. diff --git a/vendor/github.com/magiconair/properties/README.md b/vendor/github.com/magiconair/properties/README.md index 42ed5c37c19ce..e2edda025bd1d 100644 --- a/vendor/github.com/magiconair/properties/README.md +++ b/vendor/github.com/magiconair/properties/README.md @@ -1,6 +1,5 @@ [![](https://img.shields.io/github/tag/magiconair/properties.svg?style=flat-square&label=release)](https://github.com/magiconair/properties/releases) [![Travis CI Status](https://img.shields.io/travis/magiconair/properties.svg?branch=master&style=flat-square&label=travis)](https://travis-ci.org/magiconair/properties) -[![CircleCI Status](https://img.shields.io/circleci/project/github/magiconair/properties.svg?label=circle+ci&style=flat-square)](https://circleci.com/gh/magiconair/properties) [![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg?style=flat-square)](https://raw.githubusercontent.com/magiconair/properties/master/LICENSE) [![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](http://godoc.org/github.com/magiconair/properties) diff --git a/vendor/github.com/magiconair/properties/go.mod b/vendor/github.com/magiconair/properties/go.mod index 02a6f86557f4d..4ff090bdcc92f 100644 --- a/vendor/github.com/magiconair/properties/go.mod +++ b/vendor/github.com/magiconair/properties/go.mod @@ -1 +1,3 @@ module github.com/magiconair/properties + +go 1.13 diff --git a/vendor/github.com/magiconair/properties/load.go b/vendor/github.com/magiconair/properties/load.go index ab953253547f0..c83c2dadd6cda 100644 --- a/vendor/github.com/magiconair/properties/load.go +++ b/vendor/github.com/magiconair/properties/load.go @@ -132,11 +132,12 @@ func (l *Loader) LoadURL(url string) (*Properties, error) { } ct := resp.Header.Get("Content-Type") + ct = strings.Join(strings.Fields(ct), "") var enc Encoding switch strings.ToLower(ct) { - case "text/plain", "text/plain; charset=iso-8859-1", "text/plain; charset=latin1": + case "text/plain", "text/plain;charset=iso-8859-1", "text/plain;charset=latin1": enc = ISO_8859_1 - case "", "text/plain; charset=utf-8": + case "", "text/plain;charset=utf-8": enc = UTF8 default: return nil, fmt.Errorf("properties: invalid content type %s", ct) diff --git a/vendor/github.com/magiconair/properties/properties.go b/vendor/github.com/magiconair/properties/properties.go index cb3d1a3326f30..0d0fc2820307c 100644 --- a/vendor/github.com/magiconair/properties/properties.go +++ b/vendor/github.com/magiconair/properties/properties.go @@ -8,11 +8,13 @@ package properties // BUG(frank): Write() does not allow to configure the newline character. Therefore, on Windows LF is used. import ( + "bytes" "fmt" "io" "log" "os" "regexp" + "sort" "strconv" "strings" "time" @@ -69,6 +71,9 @@ type Properties struct { // Stores the keys in order of appearance. k []string + + // WriteSeparator specifies the separator of key and value while writing the properties. + WriteSeparator string } // NewProperties creates a new Properties struct with the default @@ -111,7 +116,7 @@ func (p *Properties) Get(key string) (value string, ok bool) { // circular references and malformed expressions // so we panic if we still get an error here. if err != nil { - ErrorHandler(fmt.Errorf("%s in %q", err, key+" = "+v)) + ErrorHandler(err) } return expanded, true @@ -586,6 +591,12 @@ func (p *Properties) String() string { return s } +// Sort sorts the properties keys in alphabetical order. +// This is helpfully before writing the properties. +func (p *Properties) Sort() { + sort.Strings(p.k) +} + // Write writes all unexpanded 'key = value' pairs to the given writer. // Write returns the number of bytes written and any write error encountered. func (p *Properties) Write(w io.Writer, enc Encoding) (n int, err error) { @@ -635,8 +646,11 @@ func (p *Properties) WriteComment(w io.Writer, prefix string, enc Encoding) (n i } } } - - x, err = fmt.Fprintf(w, "%s = %s\n", encode(key, " :", enc), encode(value, "", enc)) + sep := " = " + if p.WriteSeparator != "" { + sep = p.WriteSeparator + } + x, err = fmt.Fprintf(w, "%s%s%s\n", encode(key, " :", enc), sep, encode(value, "", enc)) if err != nil { return } @@ -753,7 +767,12 @@ func expand(s string, keys []string, prefix, postfix string, values map[string]s for _, k := range keys { if key == k { - return "", fmt.Errorf("circular reference") + var b bytes.Buffer + b.WriteString("circular reference in:\n") + for _, k1 := range keys { + fmt.Fprintf(&b, "%s=%s\n", k1, values[k1]) + } + return "", fmt.Errorf(b.String()) } } @@ -820,6 +839,8 @@ func escape(r rune, special string) string { return "\\r" case '\t': return "\\t" + case '\\': + return "\\\\" default: if strings.ContainsRune(special, r) { return "\\" + string(r) diff --git a/vendor/github.com/markbates/goth/README.md b/vendor/github.com/markbates/goth/README.md index e55c3bf9c6811..d3f1088e01d9c 100644 --- a/vendor/github.com/markbates/goth/README.md +++ b/vendor/github.com/markbates/goth/README.md @@ -50,8 +50,10 @@ $ go get github.com/markbates/goth * MicrosoftOnline * Naver * Nextcloud +* Okta * OneDrive * OpenID Connect (auto discovery) +* Oura * Paypal * SalesForce * Shopify @@ -144,6 +146,7 @@ Would I love to see more providers? Certainly! Would you love to contribute one? 1. Fork it 2. Create your feature branch (git checkout -b my-new-feature) 3. Write Tests! -4. Commit your changes (git commit -am 'Add some feature') -5. Push to the branch (git push origin my-new-feature) -6. Create new Pull Request +4. Make sure the codebase adhere to the Go coding standards by executing `gofmt -s -w ./` +5. Commit your changes (git commit -am 'Add some feature') +6. Push to the branch (git push origin my-new-feature) +7. Create new Pull Request diff --git a/vendor/github.com/markbates/goth/go.mod b/vendor/github.com/markbates/goth/go.mod index 5a8da2c999c3a..bff7b3ad26fd9 100644 --- a/vendor/github.com/markbates/goth/go.mod +++ b/vendor/github.com/markbates/goth/go.mod @@ -1,6 +1,6 @@ module github.com/markbates/goth -go 1.14 +go 1.15 require ( cloud.google.com/go v0.67.0 // indirect diff --git a/vendor/github.com/markbates/goth/providers/discord/discord.go b/vendor/github.com/markbates/goth/providers/discord/discord.go index e93ec60cd8a1c..f784ae632acb9 100644 --- a/vendor/github.com/markbates/goth/providers/discord/discord.go +++ b/vendor/github.com/markbates/goth/providers/discord/discord.go @@ -16,9 +16,9 @@ import ( ) const ( - authURL string = "https://discordapp.com/api/oauth2/authorize" - tokenURL string = "https://discordapp.com/api/oauth2/token" - userEndpoint string = "https://discordapp.com/api/users/@me" + authURL string = "https://discord.com/api/oauth2/authorize" + tokenURL string = "https://discord.com/api/oauth2/token" + userEndpoint string = "https://discord.com/api/users/@me" ) const ( diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go index 04c4229c4b716..41215d7fc4ff4 100644 --- a/vendor/github.com/mattn/go-colorable/colorable_windows.go +++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go @@ -719,7 +719,7 @@ loop: n256setup() } attr &= backgroundMask - attr |= n256foreAttr[n256] + attr |= n256foreAttr[n256%len(n256foreAttr)] i += 2 } } else if len(token) == 5 && token[i+1] == "2" { @@ -761,7 +761,7 @@ loop: n256setup() } attr &= foregroundMask - attr |= n256backAttr[n256] + attr |= n256backAttr[n256%len(n256backAttr)] i += 2 } } else if len(token) == 5 && token[i+1] == "2" { diff --git a/vendor/github.com/mattn/go-runewidth/go.mod b/vendor/github.com/mattn/go-runewidth/go.mod index fa7f4d864e49d..8a9d524ece526 100644 --- a/vendor/github.com/mattn/go-runewidth/go.mod +++ b/vendor/github.com/mattn/go-runewidth/go.mod @@ -1,3 +1,5 @@ module github.com/mattn/go-runewidth go 1.9 + +require github.com/rivo/uniseg v0.1.0 diff --git a/vendor/github.com/mattn/go-runewidth/go.sum b/vendor/github.com/mattn/go-runewidth/go.sum new file mode 100644 index 0000000000000..02135660b6f3e --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/go.sum @@ -0,0 +1,2 @@ +github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go index 19f8e0449b75d..f3871a624aca3 100644 --- a/vendor/github.com/mattn/go-runewidth/runewidth.go +++ b/vendor/github.com/mattn/go-runewidth/runewidth.go @@ -2,6 +2,8 @@ package runewidth import ( "os" + + "github.com/rivo/uniseg" ) //go:generate go run script/generate.go @@ -10,9 +12,6 @@ var ( // EastAsianWidth will be set true if the current locale is CJK EastAsianWidth bool - // ZeroWidthJoiner is flag to set to use UTR#51 ZWJ - ZeroWidthJoiner bool - // DefaultCondition is a condition in current locale DefaultCondition = &Condition{} ) @@ -30,7 +29,6 @@ func handleEnv() { } // update DefaultCondition DefaultCondition.EastAsianWidth = EastAsianWidth - DefaultCondition.ZeroWidthJoiner = ZeroWidthJoiner } type interval struct { @@ -85,15 +83,13 @@ var nonprint = table{ // Condition have flag EastAsianWidth whether the current locale is CJK or not. type Condition struct { - EastAsianWidth bool - ZeroWidthJoiner bool + EastAsianWidth bool } // NewCondition return new instance of Condition which is current locale. func NewCondition() *Condition { return &Condition{ - EastAsianWidth: EastAsianWidth, - ZeroWidthJoiner: ZeroWidthJoiner, + EastAsianWidth: EastAsianWidth, } } @@ -110,38 +106,20 @@ func (c *Condition) RuneWidth(r rune) int { } } -func (c *Condition) stringWidth(s string) (width int) { - for _, r := range []rune(s) { - width += c.RuneWidth(r) - } - return width -} - -func (c *Condition) stringWidthZeroJoiner(s string) (width int) { - r1, r2 := rune(0), rune(0) - for _, r := range []rune(s) { - if r == 0xFE0E || r == 0xFE0F { - continue - } - w := c.RuneWidth(r) - if r2 == 0x200D && inTables(r, emoji) && inTables(r1, emoji) { - if width < w { - width = w - } - } else { - width += w - } - r1, r2 = r2, r - } - return width -} - // StringWidth return width as you can see func (c *Condition) StringWidth(s string) (width int) { - if c.ZeroWidthJoiner { - return c.stringWidthZeroJoiner(s) + g := uniseg.NewGraphemes(s) + for g.Next() { + var chWidth int + for _, r := range g.Runes() { + chWidth = c.RuneWidth(r) + if chWidth > 0 { + break // Our best guess at this point is to use the width of the first non-zero-width rune. + } + } + width += chWidth } - return c.stringWidth(s) + return } // Truncate return string truncated with w cells @@ -149,19 +127,25 @@ func (c *Condition) Truncate(s string, w int, tail string) string { if c.StringWidth(s) <= w { return s } - r := []rune(s) - tw := c.StringWidth(tail) - w -= tw - width := 0 - i := 0 - for ; i < len(r); i++ { - cw := c.RuneWidth(r[i]) - if width+cw > w { + w -= c.StringWidth(tail) + var width int + pos := len(s) + g := uniseg.NewGraphemes(s) + for g.Next() { + var chWidth int + for _, r := range g.Runes() { + chWidth = c.RuneWidth(r) + if chWidth > 0 { + break // See StringWidth() for details. + } + } + if width+chWidth > w { + pos, _ = g.Positions() break } - width += cw + width += chWidth } - return string(r[0:i]) + tail + return s[:pos] + tail } // Wrap return string wrapped with w cells @@ -169,7 +153,7 @@ func (c *Condition) Wrap(s string, w int) string { width := 0 out := "" for _, r := range []rune(s) { - cw := RuneWidth(r) + cw := c.RuneWidth(r) if r == '\n' { out += string(r) width = 0 diff --git a/vendor/github.com/mattn/go-sqlite3/README.md b/vendor/github.com/mattn/go-sqlite3/README.md index 274d8f2983205..746621f9fdac9 100644 --- a/vendor/github.com/mattn/go-sqlite3/README.md +++ b/vendor/github.com/mattn/go-sqlite3/README.md @@ -15,7 +15,7 @@ Latest stable version is v1.14 or later not v2. sqlite3 driver conforming to the built-in database/sql interface -Supported Golang version: See .github/workflows/go.yaml +Supported Golang version: See [.github/workflows/go.yaml](./.github/workflows/go.yaml) [This package follows the official Golang Release Policy.](https://golang.org/doc/devel/release.html#policy) @@ -125,6 +125,8 @@ Boolean values can be one of: | Time Zone Location | `_loc` | auto | Specify location of time format. | | Transaction Lock | `_txlock` |
  • immediate
  • deferred
  • exclusive
| Specify locking behavior for transactions. | | Writable Schema | `_writable_schema` | `Boolean` | When this pragma is on, the SQLITE_MASTER tables in which database can be changed using ordinary UPDATE, INSERT, and DELETE statements. Warning: misuse of this pragma can easily result in a corrupt database file. | +| Cache Size | `_cache_size` | `int` | Maximum cache size; default is 2000K (2M). See [PRAGMA cache_size](https://sqlite.org/pragma.html#pragma_cache_size) | + ## DSN Examples diff --git a/vendor/github.com/mattn/go-sqlite3/doc.go b/vendor/github.com/mattn/go-sqlite3/doc.go index c721f7708f7d7..ac27633b3ac09 100644 --- a/vendor/github.com/mattn/go-sqlite3/doc.go +++ b/vendor/github.com/mattn/go-sqlite3/doc.go @@ -79,9 +79,8 @@ Then, you can use this extension. Connection Hook -You can hook and inject your code when the connection is established. database/sql -doesn't provide a way to get native go-sqlite3 interfaces. So if you want, -you need to set ConnectHook and get the SQLiteConn. +You can hook and inject your code when the connection is established by setting +ConnectHook to get the SQLiteConn. sql.Register("sqlite3_with_hook_example", &sqlite3.SQLiteDriver{ @@ -91,21 +90,45 @@ you need to set ConnectHook and get the SQLiteConn. }, }) +You can also use database/sql.Conn.Raw (Go >= 1.13): + + conn, err := db.Conn(context.Background()) + // if err != nil { ... } + defer conn.Close() + err = conn.Raw(func (driverConn interface{}) error { + sqliteConn := driverConn.(*sqlite3.SQLiteConn) + // ... use sqliteConn + }) + // if err != nil { ... } + Go SQlite3 Extensions -If you want to register Go functions as SQLite extension functions, -call RegisterFunction from ConnectHook. +If you want to register Go functions as SQLite extension functions +you can make a custom driver by calling RegisterFunction from +ConnectHook. regex = func(re, s string) (bool, error) { return regexp.MatchString(re, s) } - sql.Register("sqlite3_with_go_func", + sql.Register("sqlite3_extended", &sqlite3.SQLiteDriver{ ConnectHook: func(conn *sqlite3.SQLiteConn) error { return conn.RegisterFunc("regexp", regex, true) }, }) +You can then use the custom driver by passing its name to sql.Open. + + var i int + conn, err := sql.Open("sqlite3_extended", "./foo.db") + if err != nil { + panic(err) + } + err = db.QueryRow(`SELECT regexp("foo.*", "seafood")`).Scan(&i) + if err != nil { + panic(err) + } + See the documentation of RegisterFunc for more details. */ diff --git a/vendor/github.com/mattn/go-sqlite3/go.mod b/vendor/github.com/mattn/go-sqlite3/go.mod index 5e56bb96b7385..3d0854a0bbbfe 100644 --- a/vendor/github.com/mattn/go-sqlite3/go.mod +++ b/vendor/github.com/mattn/go-sqlite3/go.mod @@ -1,3 +1,3 @@ module github.com/mattn/go-sqlite3 -go 1.10 +go 1.12 diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c index a5c272c92d0f6..c1a4d8f92c4af 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c @@ -1,7 +1,7 @@ #ifndef USE_LIBSQLITE3 /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.33.0. By combining all the individual C code files into this +** version 3.34.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -1172,9 +1172,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.33.0" -#define SQLITE_VERSION_NUMBER 3033000 -#define SQLITE_SOURCE_ID "2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f" +#define SQLITE_VERSION "3.34.0" +#define SQLITE_VERSION_NUMBER 3034000 +#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -1553,6 +1553,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) +#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) @@ -7235,6 +7236,57 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); */ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); +/* +** CAPI3REF: Determine the transaction state of a database +** METHOD: sqlite3 +** +** ^The sqlite3_txn_state(D,S) interface returns the current +** [transaction state] of schema S in database connection D. ^If S is NULL, +** then the highest transaction state of any schema on database connection D +** is returned. Transaction states are (in order of lowest to highest): +**
    +**
  1. SQLITE_TXN_NONE +**
  2. SQLITE_TXN_READ +**
  3. SQLITE_TXN_WRITE +**
+** ^If the S argument to sqlite3_txn_state(D,S) is not the name of +** a valid schema, then -1 is returned. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); + +/* +** CAPI3REF: Allowed return values from [sqlite3_txn_state()] +** KEYWORDS: {transaction state} +** +** These constants define the current transaction state of a database file. +** ^The [sqlite3_txn_state(D,S)] interface returns one of these +** constants in order to describe the transaction state of schema S +** in [database connection] D. +** +**
+** [[SQLITE_TXN_NONE]]
SQLITE_TXN_NONE
+**
The SQLITE_TXN_NONE state means that no transaction is currently +** pending.
+** +** [[SQLITE_TXN_READ]]
SQLITE_TXN_READ
+**
The SQLITE_TXN_READ state means that the database is currently +** in a read transaction. Content has been read from the database file +** but nothing in the database file has changed. The transaction state +** will advanced to SQLITE_TXN_WRITE if any changes occur and there are +** no other conflicting concurrent write transactions. The transaction +** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or +** [COMMIT].
+** +** [[SQLITE_TXN_WRITE]]
SQLITE_TXN_WRITE
+**
The SQLITE_TXN_WRITE state means that the database is currently +** in a write transaction. Content has been written to the database file +** but has not yet committed. The transaction state will change to +** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
+*/ +#define SQLITE_TXN_NONE 0 +#define SQLITE_TXN_READ 1 +#define SQLITE_TXN_WRITE 2 + /* ** CAPI3REF: Find the next prepared statement ** METHOD: sqlite3 @@ -8761,7 +8813,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESULT_INTREAL 27 #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 -#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_SEEK_COUNT 30 +#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -10241,10 +10294,11 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE ** ** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] -** method of a [virtual table], then it returns true if and only if the +** method of a [virtual table], then it might return true if the ** column is being fetched as part of an UPDATE operation during which the -** column value will not change. Applications might use this to substitute -** a return value that is less expensive to compute and that the corresponding +** column value will not change. The virtual table implementation can use +** this hint as permission to substitute a return value that is less +** expensive to compute and that the corresponding ** [xUpdate] method understands as a "no-change" value. ** ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that @@ -10253,6 +10307,12 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. ** In that case, [sqlite3_value_nochange(X)] will return true for the ** same column in the [xUpdate] method. +** +** The sqlite3_vtab_nochange() routine is an optimization. Virtual table +** implementations should continue to give a correct answer even if the +** sqlite3_vtab_nochange() interface were to always return false. In the +** current implementation, the sqlite3_vtab_nochange() interface does always +** returns false for the enhanced [UPDATE FROM] statement. */ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); @@ -10394,6 +10454,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction +** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty @@ -10426,6 +10487,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); /* ** CAPI3REF: The pre-update hook. +** METHOD: sqlite3 ** ** ^These interfaces are only available if SQLite is compiled using the ** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. @@ -10466,7 +10528,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback ** function is not defined for operations on WITHOUT ROWID tables, or for -** INSERT operations on rowid tables. +** DELETE operations on rowid tables. ** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces @@ -10528,6 +10590,7 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); /* ** CAPI3REF: Low-level system error code +** METHOD: sqlite3 ** ** ^Attempt to return the underlying operating system error code or error ** number that caused the most recent I/O error or failure to open a file. @@ -13298,11 +13361,7 @@ struct fts5_api { ** The maximum depth of an expression tree. This is limited to ** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might ** want to place more severe limits on the complexity of an -** expression. -** -** A value of 0 used to mean that the limit was not enforced. -** But that is no longer true. The limit is now strictly enforced -** at all times. +** expression. A value of 0 means that there is no limit. */ #ifndef SQLITE_MAX_EXPR_DEPTH # define SQLITE_MAX_EXPR_DEPTH 1000 @@ -15083,16 +15142,24 @@ SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int); SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int); SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, Pgno*, int flags); -SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*); -SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*); +SQLITE_PRIVATE int sqlite3BtreeTxnState(Btree*); SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*); + SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree); #ifndef SQLITE_OMIT_SHARED_CACHE SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); #endif + +/* Savepoints are named, nestable SQL transactions mostly implemented */ +/* in vdbe.c and pager.c See https://sqlite.org/lang_savepoint.html */ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int); +/* "Checkpoint" only refers to WAL. See https://sqlite.org/wal.html#ckpt */ +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); +#endif + SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); @@ -15329,6 +15396,12 @@ SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt); SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree*); +#else +# define sqlite3BtreeSeekCount(X) 0 +#endif + #ifndef NDEBUG SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); #endif @@ -15682,64 +15755,65 @@ typedef struct VdbeOpList VdbeOpList; #define OP_String8 115 /* same as TK_STRING, synopsis: r[P2]='P4' */ #define OP_Close 116 #define OP_ColumnsUsed 117 -#define OP_SeekHit 118 /* synopsis: seekHit=P2 */ -#define OP_Sequence 119 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 120 /* synopsis: r[P2]=rowid */ -#define OP_Insert 121 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_Delete 122 -#define OP_ResetCount 123 -#define OP_SorterCompare 124 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 125 /* synopsis: r[P2]=data */ -#define OP_RowData 126 /* synopsis: r[P2]=data */ -#define OP_Rowid 127 /* synopsis: r[P2]=rowid */ -#define OP_NullRow 128 -#define OP_SeekEnd 129 -#define OP_IdxInsert 130 /* synopsis: key=r[P2] */ -#define OP_SorterInsert 131 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 132 /* synopsis: key=r[P2@P3] */ -#define OP_DeferredSeek 133 /* synopsis: Move P3 to P1.rowid if needed */ -#define OP_IdxRowid 134 /* synopsis: r[P2]=rowid */ -#define OP_FinishSeek 135 -#define OP_Destroy 136 -#define OP_Clear 137 -#define OP_ResetSorter 138 -#define OP_CreateBtree 139 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ -#define OP_SqlExec 140 -#define OP_ParseSchema 141 -#define OP_LoadAnalysis 142 -#define OP_DropTable 143 -#define OP_DropIndex 144 -#define OP_DropTrigger 145 -#define OP_IntegrityCk 146 -#define OP_RowSetAdd 147 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 148 -#define OP_FkCounter 149 /* synopsis: fkctr[P1]+=P2 */ +#define OP_SeekScan 118 /* synopsis: Scan-ahead up to P1 rows */ +#define OP_SeekHit 119 /* synopsis: set P2<=seekHit<=P3 */ +#define OP_Sequence 120 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 121 /* synopsis: r[P2]=rowid */ +#define OP_Insert 122 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_Delete 123 +#define OP_ResetCount 124 +#define OP_SorterCompare 125 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 126 /* synopsis: r[P2]=data */ +#define OP_RowData 127 /* synopsis: r[P2]=data */ +#define OP_Rowid 128 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 129 +#define OP_SeekEnd 130 +#define OP_IdxInsert 131 /* synopsis: key=r[P2] */ +#define OP_SorterInsert 132 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 133 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 134 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 135 /* synopsis: r[P2]=rowid */ +#define OP_FinishSeek 136 +#define OP_Destroy 137 +#define OP_Clear 138 +#define OP_ResetSorter 139 +#define OP_CreateBtree 140 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_SqlExec 141 +#define OP_ParseSchema 142 +#define OP_LoadAnalysis 143 +#define OP_DropTable 144 +#define OP_DropIndex 145 +#define OP_DropTrigger 146 +#define OP_IntegrityCk 147 +#define OP_RowSetAdd 148 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 149 #define OP_Real 150 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_MemMax 151 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 152 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggInverse 153 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -#define OP_AggStep 154 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep1 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggValue 156 /* synopsis: r[P3]=value N=P2 */ -#define OP_AggFinal 157 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 158 -#define OP_CursorLock 159 -#define OP_CursorUnlock 160 -#define OP_TableLock 161 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 162 -#define OP_VCreate 163 -#define OP_VDestroy 164 -#define OP_VOpen 165 -#define OP_VColumn 166 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 167 -#define OP_Pagecount 168 -#define OP_MaxPgcnt 169 -#define OP_Trace 170 -#define OP_CursorHint 171 -#define OP_ReleaseReg 172 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 173 -#define OP_Explain 174 -#define OP_Abortable 175 +#define OP_FkCounter 151 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 152 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 154 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 156 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 157 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 158 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 159 +#define OP_CursorLock 160 +#define OP_CursorUnlock 161 +#define OP_TableLock 162 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 163 +#define OP_VCreate 164 +#define OP_VDestroy 165 +#define OP_VOpen 166 +#define OP_VColumn 167 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 168 +#define OP_Pagecount 169 +#define OP_MaxPgcnt 170 +#define OP_Trace 171 +#define OP_CursorHint 172 +#define OP_ReleaseReg 173 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 174 +#define OP_Explain 175 +#define OP_Abortable 176 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -15766,15 +15840,15 @@ typedef struct VdbeOpList VdbeOpList; /* 88 */ 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ /* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26, 0x26,\ /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\ -/* 112 */ 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,\ -/* 120 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ -/* 128 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\ -/* 136 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ -/* 144 */ 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x10, 0x04,\ -/* 152 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 112 */ 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ +/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 128 */ 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10,\ +/* 136 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ +/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00,\ +/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -} +/* 168 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 176 */ 0x00,} /* The sqlite3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -17551,6 +17625,7 @@ struct Table { #define TF_OOOHidden 0x0400 /* Out-of-Order hidden columns */ #define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */ #define TF_Shadow 0x1000 /* True for a shadow table */ +#define TF_HasStat4 0x2000 /* STAT4 info available for this table */ /* ** Test to see whether or not a table is a virtual table. This is @@ -18079,7 +18154,7 @@ struct Expr { #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ #define EP_Win 0x008000 /* Contains window functions */ #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ - /* 0x020000 // available for reuse */ +#define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */ #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ @@ -18317,9 +18392,9 @@ struct SrcList { #define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ -#define WHERE_SEEK_TABLE 0x0400 /* Do not defer seeks on main table */ + /* 0x0400 not currently used */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ -#define WHERE_SEEK_UNIQ_TABLE 0x1000 /* Do not defer seeks if unique */ + /* 0x1000 not currently used */ /* 0x2000 not currently used */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ @@ -18516,9 +18591,6 @@ struct Select { ** statements within triggers whose only purpose is ** the side-effects of functions. ** -** All of the above are free to ignore their ORDER BY clause. Those that -** follow must honor the ORDER BY clause. -** ** SRT_Output Generate a row of output (using the OP_ResultRow ** opcode) for each row in the result set. ** @@ -18575,13 +18647,18 @@ struct Select { #define SRT_Except 2 /* Remove result from a UNION index */ #define SRT_Exists 3 /* Store 1 if the result is not empty */ #define SRT_Discard 4 /* Do not save the results anywhere */ -#define SRT_Fifo 5 /* Store result as data with an automatic rowid */ -#define SRT_DistFifo 6 /* Like SRT_Fifo, but unique results only */ +#define SRT_DistFifo 5 /* Like SRT_Fifo, but unique results only */ +#define SRT_DistQueue 6 /* Like SRT_Queue, but unique results only */ + +/* The DISTINCT clause is ignored for all of the above. Not that +** IgnorableDistinct() implies IgnorableOrderby() */ +#define IgnorableDistinct(X) ((X->eDest)<=SRT_DistQueue) + #define SRT_Queue 7 /* Store result in an queue */ -#define SRT_DistQueue 8 /* Like SRT_Queue, but unique results only */ +#define SRT_Fifo 8 /* Store result as data with an automatic rowid */ /* The ORDER BY clause is ignored for all of the above */ -#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue) +#define IgnorableOrderby(X) ((X->eDest)<=SRT_Fifo) #define SRT_Output 9 /* Output each row of result */ #define SRT_Mem 10 /* Store result in a memory cell */ @@ -19548,7 +19625,7 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table*, Column*); SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*,Token*); SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); -SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*); SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); SQLITE_PRIVATE void sqlite3AddGenerated(Parse*,Expr*,Token*); @@ -20796,7 +20873,7 @@ struct VdbeCursor { Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ - Bool seekHit:1; /* See the OP_SeekHit and OP_IfNoHope opcodes */ + u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ Btree *pBtx; /* Separate file holding temporary table */ i64 seqCount; /* Sequence counter */ u32 *aAltMap; /* Mapping from table to index column numbers */ @@ -27792,12 +27869,17 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ if( nOld==nNew ){ pNew = pOld; }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_int64 nUsed; sqlite3_mutex_enter(mem0.mutex); sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); nDiff = nNew - nOld; - if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= + if( nDiff>0 && (nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)) >= mem0.alarmThreshold-nDiff ){ sqlite3MallocAlarm(nDiff); + if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){ + sqlite3_mutex_leave(mem0.mutex); + return 0; + } } pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT @@ -28104,12 +28186,15 @@ SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){ } /* -** Take actions at the end of an API call to indicate an OOM error +** Take actions at the end of an API call to deal with error codes. */ -static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ - sqlite3OomClear(db); - sqlite3Error(db, SQLITE_NOMEM); - return SQLITE_NOMEM_BKPT; +static SQLITE_NOINLINE int apiHandleError(sqlite3 *db, int rc){ + if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomClear(db); + sqlite3Error(db, SQLITE_NOMEM); + return SQLITE_NOMEM_BKPT; + } + return rc & db->errMask; } /* @@ -28131,8 +28216,8 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ */ assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); - if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ - return apiOomError(db); + if( db->mallocFailed || rc ){ + return apiHandleError(db, rc); } return rc & db->errMask; } @@ -28568,11 +28653,10 @@ SQLITE_API void sqlite3_str_vappendf( v = va_arg(ap,int); } if( v<0 ){ - if( v==SMALLEST_INT64 ){ - longvalue = ((u64)1)<<63; - }else{ - longvalue = -v; - } + testcase( v==SMALLEST_INT64 ); + testcase( v==(-1) ); + longvalue = ~v; + longvalue++; prefix = '-'; }else{ longvalue = v; @@ -31868,6 +31952,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc incr = 1; }else{ incr = 2; + length &= ~1; assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); for(i=3-enc; i0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 153 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), - /* 154 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 155 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 156 */ "AggValue" OpHelp("r[P3]=value N=P2"), - /* 157 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 158 */ "Expire" OpHelp(""), - /* 159 */ "CursorLock" OpHelp(""), - /* 160 */ "CursorUnlock" OpHelp(""), - /* 161 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 162 */ "VBegin" OpHelp(""), - /* 163 */ "VCreate" OpHelp(""), - /* 164 */ "VDestroy" OpHelp(""), - /* 165 */ "VOpen" OpHelp(""), - /* 166 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 167 */ "VRename" OpHelp(""), - /* 168 */ "Pagecount" OpHelp(""), - /* 169 */ "MaxPgcnt" OpHelp(""), - /* 170 */ "Trace" OpHelp(""), - /* 171 */ "CursorHint" OpHelp(""), - /* 172 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 173 */ "Noop" OpHelp(""), - /* 174 */ "Explain" OpHelp(""), - /* 175 */ "Abortable" OpHelp(""), + /* 151 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 152 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 153 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 154 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 155 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 156 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 157 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 158 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 159 */ "Expire" OpHelp(""), + /* 160 */ "CursorLock" OpHelp(""), + /* 161 */ "CursorUnlock" OpHelp(""), + /* 162 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 163 */ "VBegin" OpHelp(""), + /* 164 */ "VCreate" OpHelp(""), + /* 165 */ "VDestroy" OpHelp(""), + /* 166 */ "VOpen" OpHelp(""), + /* 167 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 168 */ "VRename" OpHelp(""), + /* 169 */ "Pagecount" OpHelp(""), + /* 170 */ "MaxPgcnt" OpHelp(""), + /* 171 */ "Trace" OpHelp(""), + /* 172 */ "CursorHint" OpHelp(""), + /* 173 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 174 */ "Noop" OpHelp(""), + /* 175 */ "Explain" OpHelp(""), + /* 176 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -33473,7 +33559,8 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ # if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) # if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \ - && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0)) + && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))\ + && (!defined(TARGET_OS_MACCATALYST) || (TARGET_OS_MACCATALYST==0)) # undef HAVE_GETHOSTUUID # define HAVE_GETHOSTUUID 1 # else @@ -35093,6 +35180,9 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ return rc; } +/* Forward declaration*/ +static int unixSleep(sqlite3_vfs*,int); + /* ** Set a posix-advisory-lock. ** @@ -35122,7 +35212,7 @@ static int osSetPosixAdvisoryLock( ** generic posix, however, there is no such API. So we simply try the ** lock once every millisecond until either the timeout expires, or until ** the lock is obtained. */ - usleep(1000); + unixSleep(0,1000); rc = osFcntl(h,F_SETLK,pLock); tm--; } @@ -35693,6 +35783,7 @@ static int unixClose(sqlite3_file *id){ } sqlite3_mutex_leave(pInode->pLockMutex); releaseInodeInfo(pFile); + assert( pFile->pShm==0 ); rc = closeUnixFile(id); unixLeaveMutex(); return rc; @@ -36919,7 +37010,24 @@ static int unixRead( if( got==amt ){ return SQLITE_OK; }else if( got<0 ){ - /* lastErrno set by seekAndRead */ + /* pFile->lastErrno has been set by seekAndRead(). + ** Usually we return SQLITE_IOERR_READ here, though for some + ** kinds of errors we return SQLITE_IOERR_CORRUPTFS. The + ** SQLITE_IOERR_CORRUPTFS will be converted into SQLITE_CORRUPT + ** prior to returning to the application by the sqlite3ApiExit() + ** routine. + */ + switch( pFile->lastErrno ){ + case ERANGE: + case EIO: +#ifdef ENXIO + case ENXIO: +#endif +#ifdef EDEVERR + case EDEVERR: +#endif + return SQLITE_IOERR_CORRUPTFS; + } return SQLITE_IOERR_READ; }else{ storeLastErrno(pFile, 0); /* not a system error */ @@ -37803,6 +37911,7 @@ struct unixShmNode { char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ + int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */ #ifdef SQLITE_DEBUG u8 exclMask; /* Mask of exclusive locks held */ u8 sharedMask; /* Mask of shared locks held */ @@ -38343,6 +38452,38 @@ static int unixShmMap( return rc; } +/* +** Check that the pShmNode->aLock[] array comports with the locking bitmasks +** held by each client. Return true if it does, or false otherwise. This +** is to be used in an assert(). e.g. +** +** assert( assertLockingArrayOk(pShmNode) ); +*/ +#ifdef SQLITE_DEBUG +static int assertLockingArrayOk(unixShmNode *pShmNode){ + unixShm *pX; + int aLock[SQLITE_SHM_NLOCK]; + assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); + + memset(aLock, 0, sizeof(aLock)); + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + int i; + for(i=0; iexclMask & (1<sharedMask & (1<=0 ); + aLock[i]++; + } + } + } + + assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) ); + return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0); +} +#endif + /* ** Change the lock state for a shared-memory segment. ** @@ -38359,10 +38500,10 @@ static int unixShmLock( ){ unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ unixShm *p = pDbFd->pShm; /* The shared memory being locked */ - unixShm *pX; /* For looping over all siblings */ unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */ int rc = SQLITE_OK; /* Result code */ u16 mask; /* Mask of locks to take or release */ + int *aLock = pShmNode->aLock; assert( pShmNode==pDbFd->pInode->pShmNode ); assert( pShmNode->pInode==pDbFd->pInode ); @@ -38401,78 +38542,76 @@ static int unixShmLock( mask = (1<<(ofst+n)) - (1<1 || mask==(1<pShmMutex); + assert( assertLockingArrayOk(pShmNode) ); if( flags & SQLITE_SHM_UNLOCK ){ - u16 allMask = 0; /* Mask of locks held by siblings */ + if( (p->exclMask|p->sharedMask) & mask ){ + int ii; + int bUnlock = 1; - /* See if any siblings hold this same lock */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( pX==p ) continue; - assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); - allMask |= pX->sharedMask; - } + for(ii=ofst; ii((p->sharedMask & (1<sharedMask & (1<1 ); + aLock[ofst]--; + } - /* Undo the local locks */ - if( rc==SQLITE_OK ){ - p->exclMask &= ~mask; - p->sharedMask &= ~mask; + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } } }else if( flags & SQLITE_SHM_SHARED ){ - u16 allShared = 0; /* Union of locks held by connections other than "p" */ - - /* Find out which shared locks are already held by sibling connections. - ** If any sibling already holds an exclusive lock, go ahead and return - ** SQLITE_BUSY. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 ){ + assert( n==1 ); + assert( (p->exclMask & (1<sharedMask & mask)==0 ){ + if( aLock[ofst]<0 ){ rc = SQLITE_BUSY; - break; - } - allShared |= pX->sharedMask; - } - - /* Get shared locks at the system level, if necessary */ - if( rc==SQLITE_OK ){ - if( (allShared & mask)==0 ){ + }else if( aLock[ofst]==0 ){ rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); - }else{ - rc = SQLITE_OK; } - } - /* Get the local shared locks */ - if( rc==SQLITE_OK ){ - p->sharedMask |= mask; + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + aLock[ofst]++; + } } }else{ /* Make sure no sibling connections hold locks that will block this - ** lock. If any do, return SQLITE_BUSY right away. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + ** lock. If any do, return SQLITE_BUSY right away. */ + int ii; + for(ii=ofst; iisharedMask & mask)==0 ); + if( ALWAYS((p->exclMask & (1<sharedMask & mask)==0 ); p->exclMask |= mask; + for(ii=ofst; iipShmMutex); OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", p->id, osGetpid(0), p->sharedMask, p->exclMask)); @@ -39849,7 +39988,26 @@ static int unixAccess( } /* +** If the last component of the pathname in z[0]..z[j-1] is something +** other than ".." then back it out and return true. If the last +** component is empty or if it is ".." then return false. +*/ +static int unixBackupDir(const char *z, int *pJ){ + int j = *pJ; + int i; + if( j<=0 ) return 0; + for(i=j-1; ALWAYS(i>0) && z[i-1]!='/'; i--){} + if( z[i]=='.' && i==j-2 && z[i+1]=='.' ) return 0; + *pJ = i-1; + return 1; +} + +/* +** Convert a relative pathname into a full pathname. Also +** simplify the pathname as follows: ** +** Remove all instances of /./ +** Remove all isntances of /X/../ for any X */ static int mkFullPathname( const char *zPath, /* Input path */ @@ -39858,6 +40016,7 @@ static int mkFullPathname( ){ int nPath = sqlite3Strlen30(zPath); int iOff = 0; + int i, j; if( zPath[0]!='/' ){ if( osGetcwd(zOut, nOut-2)==0 ){ return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); @@ -39872,6 +40031,41 @@ static int mkFullPathname( return SQLITE_CANTOPEN_BKPT; } sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); + + /* Remove duplicate '/' characters. Except, two // at the beginning + ** of a pathname is allowed since this is important on windows. */ + for(i=j=1; zOut[i]; i++){ + zOut[j++] = zOut[i]; + while( zOut[i]=='/' && zOut[i+1]=='/' ) i++; + } + zOut[j] = 0; + + assert( zOut[0]=='/' ); + for(i=j=0; zOut[i]; i++){ + if( zOut[i]=='/' ){ + /* Skip over internal "/." directory components */ + if( zOut[i+1]=='.' && zOut[i+2]=='/' ){ + i += 1; + continue; + } + + /* If this is a "/.." directory component then back out the + ** previous term of the directory if it is something other than "..". + */ + if( zOut[i+1]=='.' + && zOut[i+2]=='.' + && zOut[i+3]=='/' + && unixBackupDir(zOut, &j) + ){ + i += 2; + continue; + } + } + if( ALWAYS(j>=0) ) zOut[j] = zOut[i]; + j++; + } + if( NEVER(j==0) ) zOut[j++] = '/'; + zOut[j] = 0; return SQLITE_OK; } @@ -40092,7 +40286,8 @@ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ UNUSED_PARAMETER(NotUsed); return microseconds; #elif defined(HAVE_USLEEP) && HAVE_USLEEP - usleep(microseconds); + if( microseconds>=1000000 ) sleep(microseconds/1000000); + if( microseconds%1000000 ) usleep(microseconds%1000000); UNUSED_PARAMETER(NotUsed); return microseconds; #else @@ -40665,7 +40860,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ if( nTries==1 ){ conchModTime = buf.st_mtimespec; - usleep(500000); /* wait 0.5 sec and try the lock again*/ + unixSleep(0,500000); /* wait 0.5 sec and try the lock again*/ continue; } @@ -40691,7 +40886,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ /* don't break the lock on short read or a version mismatch */ return SQLITE_BUSY; } - usleep(10000000); /* wait 10 sec and try the lock again */ + unixSleep(0,10000000); /* wait 10 sec and try the lock again */ continue; } @@ -46812,7 +47007,11 @@ static int winOpen( dwCreationDisposition = OPEN_EXISTING; } - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + if( 0==sqlite3_uri_boolean(zName, "exclusive", 0) ){ + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + }else{ + dwShareMode = 0; + } if( isDelete ){ #if SQLITE_OS_WINCE @@ -47965,11 +48164,14 @@ static const sqlite3_io_methods memdb_io_methods = { ** Close an memdb-file. ** ** The pData pointer is owned by the application, so there is nothing -** to free. +** to free. Unless the SQLITE_DESERIALIZE_FREEONCLOSE flag is set, +** in which case we own the pData pointer and need to free it. */ static int memdbClose(sqlite3_file *pFile){ MemFile *p = (MemFile *)pFile; - if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData); + if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){ + sqlite3_free(p->aData); + } return SQLITE_OK; } @@ -48412,8 +48614,12 @@ SQLITE_API int sqlite3_deserialize( goto end_deserialize; } zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema); - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } if( rc ) goto end_deserialize; db->init.iDb = (u8)iDb; db->init.reopenMemdb = 1; @@ -48428,6 +48634,7 @@ SQLITE_API int sqlite3_deserialize( rc = SQLITE_ERROR; }else{ p->aData = pData; + pData = 0; p->sz = szDb; p->szAlloc = szBuf; p->szMax = szBuf; @@ -48440,6 +48647,9 @@ SQLITE_API int sqlite3_deserialize( end_deserialize: sqlite3_finalize(pStmt); + if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){ + sqlite3_free(pData); + } sqlite3_mutex_leave(db->mutex); return rc; } @@ -54195,6 +54405,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ i64 nSuperJournal; /* Size of super-journal file */ char *zJournal; /* Pointer to one journal within MJ file */ char *zSuperPtr; /* Space to hold super-journal filename */ + char *zFree = 0; /* Free this buffer */ int nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ /* Allocate space for both the pJournal and pSuper file descriptors. @@ -54219,11 +54430,13 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ rc = sqlite3OsFileSize(pSuper, &nSuperJournal); if( rc!=SQLITE_OK ) goto delsuper_out; nSuperPtr = pVfs->mxPathname+1; - zSuperJournal = sqlite3Malloc(nSuperJournal + nSuperPtr + 2); - if( !zSuperJournal ){ + zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2); + if( !zFree ){ rc = SQLITE_NOMEM_BKPT; goto delsuper_out; } + zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0; + zSuperJournal = &zFree[4]; zSuperPtr = &zSuperJournal[nSuperJournal+2]; rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0); if( rc!=SQLITE_OK ) goto delsuper_out; @@ -54271,7 +54484,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ rc = sqlite3OsDelete(pVfs, zSuper, 0); delsuper_out: - sqlite3_free(zSuperJournal); + sqlite3_free(zFree); if( pSuper ){ sqlite3OsClose(pSuper); assert( !isOpen(pJournal) ); @@ -54609,7 +54822,11 @@ static int pager_playback(Pager *pPager, int isHot){ pPager->changeCountDone = pPager->tempFile; if( rc==SQLITE_OK ){ - zSuper = pPager->pTmpSpace; + /* Leave 4 bytes of space before the super-journal filename in memory. + ** This is because it may end up being passed to sqlite3OsOpen(), in + ** which case it requires 4 0x00 bytes in memory immediately before + ** the filename. */ + zSuper = &pPager->pTmpSpace[4]; rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); testcase( rc!=SQLITE_OK ); } @@ -54626,6 +54843,8 @@ static int pager_playback(Pager *pPager, int isHot){ /* If there was a super-journal and this routine will return success, ** see if it is possible to delete the super-journal. */ + assert( zSuper==&pPager->pTmpSpace[4] ); + memset(&zSuper[-4], 0, 4); rc = pager_delsuper(pPager, zSuper); testcase( rc!=SQLITE_OK ); } @@ -63829,6 +64048,9 @@ struct Btree { u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */ Btree *pNext; /* List of other sharable Btrees from the same db */ Btree *pPrev; /* Back pointer of the same list */ +#ifdef SQLITE_DEBUG + u64 nSeek; /* Calls to sqlite3BtreeMovetoUnpacked() */ +#endif #ifndef SQLITE_OMIT_SHARED_CACHE BtLock lock; /* Object used to lock page 1 */ #endif @@ -63840,11 +64062,25 @@ struct Btree { ** If the shared-data extension is enabled, there may be multiple users ** of the Btree structure. At most one of these may open a write transaction, ** but any number may have active read transactions. +** +** These values must match SQLITE_TXN_NONE, SQLITE_TXN_READ, and +** SQLITE_TXN_WRITE */ #define TRANS_NONE 0 #define TRANS_READ 1 #define TRANS_WRITE 2 +#if TRANS_NONE!=SQLITE_TXN_NONE +# error wrong numeric code for no-transaction +#endif +#if TRANS_READ!=SQLITE_TXN_READ +# error wrong numeric code for read-transaction +#endif +#if TRANS_WRITE!=SQLITE_TXN_WRITE +# error wrong numeric code for write-transaction +#endif + + /* ** An instance of this object represents a single database file. ** @@ -64596,6 +64832,17 @@ SQLITE_API int sqlite3_enable_shared_cache(int enable){ #define hasReadConflicts(a, b) 0 #endif +#ifdef SQLITE_DEBUG +/* +** Return and reset the seek counter for a Btree object. +*/ +SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){ + u64 n = pBt->nSeek; + pBt->nSeek = 0; + return n; +} +#endif + /* ** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single ** (MemPage*) as an argument. The (MemPage*) must not be NULL. @@ -67089,7 +67336,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( ** do not change the pager-cache size. */ if( sqlite3BtreeSchema(p, 0, 0)==0 ){ - sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE); + sqlite3BtreeSetCacheSize(p, SQLITE_DEFAULT_CACHE_SIZE); } pFile = sqlite3PagerFile(pBt->pPager); @@ -69943,6 +70190,10 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( } } +#ifdef SQLITE_DEBUG + pCur->pBtree->nSeek++; /* Performance measurement during testing */ +#endif + if( pIdxKey ){ xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); pIdxKey->errCode = 0; @@ -70219,7 +70470,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ pPage = pCur->pPage; idx = ++pCur->ix; - if( !pPage->isInit ){ + if( !pPage->isInit || sqlite3FaultSim(412) ){ /* The only known way for this to happen is for there to be a ** recursive SQL function that does a DELETE operation as part of a ** SELECT which deletes content out from under an active cursor @@ -74794,11 +75045,12 @@ SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){ } /* -** Return non-zero if a transaction is active. +** Return one of SQLITE_TXN_NONE, SQLITE_TXN_READ, or SQLITE_TXN_WRITE +** to describe the current transaction state of Btree p. */ -SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeTxnState(Btree *p){ assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); - return (p && (p->inTrans==TRANS_WRITE)); + return p ? p->inTrans : 0; } #ifndef SQLITE_OMIT_WAL @@ -74827,14 +75079,8 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int * #endif /* -** Return non-zero if a read (or write) transaction is active. +** Return true if there is currently a backup running on Btree p. */ -SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree *p){ - assert( p ); - assert( sqlite3_mutex_held(p->db->mutex) ); - return p->inTrans!=TRANS_NONE; -} - SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ assert( p ); assert( sqlite3_mutex_held(p->db->mutex) ); @@ -75180,7 +75426,7 @@ static int setDestPgsz(sqlite3_backup *p){ ** message in database handle db. */ static int checkReadTransaction(sqlite3 *db, Btree *p){ - if( sqlite3BtreeIsInReadTrans(p) ){ + if( sqlite3BtreeTxnState(p)!=SQLITE_TXN_NONE ){ sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use"); return SQLITE_ERROR; } @@ -75411,7 +75657,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ ** one now. If a transaction is opened here, then it will be closed ** before this function exits. */ - if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ + if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){ rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); bCloseTrans = 1; } @@ -75783,7 +76029,7 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ sqlite3BtreeEnter(pTo); sqlite3BtreeEnter(pFrom); - assert( sqlite3BtreeIsInTrans(pTo) ); + assert( sqlite3BtreeTxnState(pTo)==SQLITE_TXN_WRITE ); pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); if( pFd->pMethods ){ i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); @@ -75819,7 +76065,7 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); } - assert( sqlite3BtreeIsInTrans(pTo)==0 ); + assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE ); copy_finished: sqlite3BtreeLeave(pFrom); sqlite3BtreeLeave(pTo); @@ -78214,6 +78460,7 @@ SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ int j; sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); + sqlite3MayAbort(p->pParse); } /* @@ -78442,7 +78689,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename || opcode==OP_VDestroy || opcode==OP_VCreate - || (opcode==OP_ParseSchema && pOp->p4.z==0) + || opcode==OP_ParseSchema || ((opcode==OP_Halt || opcode==OP_HaltIfNull) && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) ){ @@ -79260,7 +79507,7 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayComment( sqlite3_str_appendf(&x, "%d", v1); }else if( pCtx->argc>1 ){ sqlite3_str_appendf(&x, "%d..%d", v1, v1+pCtx->argc-1); - }else{ + }else if( x.accError==0 ){ assert( x.nChar>2 ); x.nChar -= 2; ii++; @@ -80402,7 +80649,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ */ for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( sqlite3BtreeIsInTrans(pBt) ){ + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ /* Whether or not a database might need a super-journal depends upon ** its journal mode (among other things). This matrix determines which ** journal modes use a super-journal and which do not */ @@ -80537,7 +80784,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ */ for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( sqlite3BtreeIsInTrans(pBt) ){ + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ char const *zFile = sqlite3BtreeGetJournalname(pBt); if( zFile==0 ){ continue; /* Ignore TEMP and :memory: databases */ @@ -82033,9 +82280,12 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem static int sqlite3IntFloatCompare(i64 i, double r){ if( sizeof(LONGDOUBLE_TYPE)>8 ){ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; + testcase( xr ); + testcase( x==r ); if( xr ) return +1; - return 0; + if( x>r ) return +1; /*NO_TEST*/ /* work around bugs in gcov */ + return 0; /*NO_TEST*/ /* work around bugs in gcov */ }else{ i64 y; double s; @@ -88815,7 +89065,8 @@ case OP_AutoCommit: { ** active. ** If P2 is non-zero, then a write-transaction is started, or if a ** read-transaction is already active, it is upgraded to a write-transaction. -** If P2 is zero, then a read-transaction is started. +** If P2 is zero, then a read-transaction is started. If P2 is 2 or more +** then an exclusive transaction is started. ** ** P1 is the index of the database file on which the transaction is ** started. Index 0 is the main database file and index 1 is the @@ -88849,6 +89100,7 @@ case OP_Transaction: { assert( p->bIsReader ); assert( p->readOnly==0 || pOp->p2==0 ); + assert( pOp->p2>=0 && pOp->p2<=2 ); assert( pOp->p1>=0 && pOp->p1nDb ); assert( DbMaskTest(p->btreeMask, pOp->p1) ); if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ @@ -88874,7 +89126,7 @@ case OP_Transaction: { && pOp->p2 && (db->autoCommit==0 || db->nVdbeRead>1) ){ - assert( sqlite3BtreeIsInTrans(pBt) ); + assert( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ); if( p->iStatement==0 ){ assert( db->nStatement>=0 && db->nSavepoint>=0 ); db->nStatement++; @@ -89227,7 +89479,7 @@ case OP_OpenDup: { } -/* Opcode: OpenEphemeral P1 P2 * P4 P5 +/* Opcode: OpenEphemeral P1 P2 P3 P4 P5 ** Synopsis: nColumn=P2 ** ** Open a new cursor P1 to a transient table. @@ -89247,6 +89499,10 @@ case OP_OpenDup: { ** in btree.h. These flags control aspects of the operation of ** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are ** added automatically. +** +** If P3 is positive, then reg[P3] is modified slightly so that it +** can be used as zero-length data for OP_Insert. This is an optimization +** that avoids an extra OP_Blob opcode to initialize that register. */ /* Opcode: OpenAutoindex P1 P2 * P4 * ** Synopsis: nColumn=P2 @@ -89269,6 +89525,15 @@ case OP_OpenEphemeral: { SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); + if( pOp->p3>0 ){ + /* Make register reg[P3] into a value that can be used as the data + ** form sqlite3BtreeInsert() where the length of the data is zero. */ + assert( pOp->p2==0 ); /* Only used when number of columns is zero */ + assert( pOp->opcode==OP_OpenEphemeral ); + assert( aMem[pOp->p3].flags & MEM_Null ); + aMem[pOp->p3].n = 0; + aMem[pOp->p3].z = ""; + } pCx = p->apCsr[pOp->p1]; if( pCx && pCx->pBtx ){ /* If the ephermeral table is already open, erase all existing content @@ -89711,22 +89976,172 @@ case OP_SeekGT: { /* jump, in3, group */ break; } -/* Opcode: SeekHit P1 P2 * * * -** Synopsis: seekHit=P2 + +/* Opcode: SeekScan P1 P2 * * * +** Synopsis: Scan-ahead up to P1 rows +** +** This opcode is a prefix opcode to OP_SeekGE. In other words, this +** opcode must be immediately followed by OP_SeekGE. This constraint is +** checked by assert() statements. +** +** This opcode uses the P1 through P4 operands of the subsequent +** OP_SeekGE. In the text that follows, the operands of the subsequent +** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only +** the P1 and P2 operands of this opcode are also used, and are called +** This.P1 and This.P2. +** +** This opcode helps to optimize IN operators on a multi-column index +** where the IN operator is on the later terms of the index by avoiding +** unnecessary seeks on the btree, substituting steps to the next row +** of the b-tree instead. A correct answer is obtained if this opcode +** is omitted or is a no-op. +** +** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which +** is the desired entry that we want the cursor SeekGE.P1 to be pointing +** to. Call this SeekGE.P4/P5 row the "target". +** +** If the SeekGE.P1 cursor is not currently pointing to a valid row, +** then this opcode is a no-op and control passes through into the OP_SeekGE. +** +** If the SeekGE.P1 cursor is pointing to a valid row, then that row +** might be the target row, or it might be near and slightly before the +** target row. This opcode attempts to position the cursor on the target +** row by, perhaps by invoking sqlite3BtreeStep() on the cursor +** between 0 and This.P1 times. +** +** There are three possible outcomes from this opcode:
    +** +**
  1. If after This.P1 steps, the cursor is still point to a place that +** is earlier in the btree than the target row, +** then fall through into the subsquence OP_SeekGE opcode. +** +**
  2. If the cursor is successfully moved to the target row by 0 or more +** sqlite3BtreeNext() calls, then jump to This.P2, which will land just +** past the OP_IdxGT opcode that follows the OP_SeekGE. +** +**
  3. If the cursor ends up past the target row (indicating the the target +** row does not exist in the btree) then jump to SeekOP.P2. +**
+*/ +case OP_SeekScan: { + VdbeCursor *pC; + int res; + int nStep; + UnpackedRecord r; + + assert( pOp[1].opcode==OP_SeekGE ); + + /* pOp->p2 points to the first instruction past the OP_IdxGT that + ** follows the OP_SeekGE. */ + assert( pOp->p2>=(int)(pOp-aOp)+2 ); + assert( aOp[pOp->p2-1].opcode==OP_IdxGT ); + assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); + assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); + assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); + + assert( pOp->p1>0 ); + pC = p->apCsr[pOp[1].p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( !pC->isTable ); + if( !sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... cursor not valid - fall through\n"); + } +#endif + break; + } + nStep = pOp->p1; + assert( nStep>=1 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp[1].p4.i; + r.default_rc = 0; + r.aMem = &aMem[pOp[1].p3]; +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; i0 ){ + seekscan_search_fail: +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... %d steps and then skip\n", pOp->p1 - nStep); + } +#endif + VdbeBranchTaken(1,3); + pOp++; + goto jump_to_p2; + } + if( res==0 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... %d steps and then success\n", pOp->p1 - nStep); + } +#endif + VdbeBranchTaken(2,3); + goto jump_to_p2; + break; + } + if( nStep<=0 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... fall through after %d steps\n", pOp->p1); + } +#endif + VdbeBranchTaken(0,3); + break; + } + nStep--; + rc = sqlite3BtreeNext(pC->uc.pCursor, 0); + if( rc ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + goto seekscan_search_fail; + }else{ + goto abort_due_to_error; + } + } + } + + break; +} + + +/* Opcode: SeekHit P1 P2 P3 * * +** Synopsis: set P2<=seekHit<=P3 +** +** Increase or decrease the seekHit value for cursor P1, if necessary, +** so that it is no less than P2 and no greater than P3. ** -** Set the seekHit flag on cursor P1 to the value in P2. -** The seekHit flag is used by the IfNoHope opcode. +** The seekHit integer represents the maximum of terms in an index for which +** there is known to be at least one match. If the seekHit value is smaller +** than the total number of equality terms in an index lookup, then the +** OP_IfNoHope opcode might run to see if the IN loop can be abandoned +** early, thus saving work. This is part of the IN-early-out optimization. ** -** P1 must be a valid b-tree cursor. P2 must be a boolean value, -** either 0 or 1. +** P1 must be a valid b-tree cursor. */ case OP_SeekHit: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pOp->p2==0 || pOp->p2==1 ); - pC->seekHit = pOp->p2 & 1; + assert( pOp->p3>=pOp->p2 ); + if( pC->seekHitp2 ){ + pC->seekHit = pOp->p2; + }else if( pC->seekHit>pOp->p3 ){ + pC->seekHit = pOp->p3; + } break; } @@ -89784,16 +90199,20 @@ case OP_IfNotOpen: { /* jump */ ** Synopsis: key=r[P3@P4] ** ** Register P3 is the first of P4 registers that form an unpacked -** record. +** record. Cursor P1 is an index btree. P2 is a jump destination. +** In other words, the operands to this opcode are the same as the +** operands to OP_NotFound and OP_IdxGT. ** -** Cursor P1 is on an index btree. If the seekHit flag is set on P1, then -** this opcode is a no-op. But if the seekHit flag of P1 is clear, then -** check to see if there is any entry in P1 that matches the -** prefix identified by P3 and P4. If no entry matches the prefix, -** jump to P2. Otherwise fall through. +** This opcode is an optimization attempt only. If this opcode always +** falls through, the correct answer is still obtained, but extra works +** is performed. ** -** This opcode behaves like OP_NotFound if the seekHit -** flag is clear and it behaves like OP_Noop if the seekHit flag is set. +** A value of N in the seekHit flag of cursor P1 means that there exists +** a key P3:N that will match some record in the index. We want to know +** if it is possible for a record P3:P4 to match some record in the +** index. If it is not possible, we can skips some work. So if seekHit +** is less than P4, attempt to find out if a match is possible by running +** OP_NotFound. ** ** This opcode is used in IN clause processing for a multi-column key. ** If an IN clause is attached to an element of the key other than the @@ -89835,7 +90254,7 @@ case OP_IfNoHope: { /* jump, in3 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - if( pC->seekHit ) break; + if( pC->seekHit>=pOp->p4.i ) break; /* Fall through into OP_NotFound */ /* no break */ deliberate_fall_through } @@ -89917,6 +90336,7 @@ case OP_Found: { /* jump, in3 */ }else{ VdbeBranchTaken(takeJump||alreadyExists==0,2); if( takeJump || !alreadyExists ) goto jump_to_p2; + if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i; } break; } @@ -90273,7 +90693,7 @@ case OP_Insert: { if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; - assert( pData->flags & (MEM_Blob|MEM_Str) ); + assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 ); x.pData = pData->z; x.nData = pData->n; seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); @@ -91149,7 +91569,7 @@ case OP_FinishSeek: { break; } -/* Opcode: IdxGE P1 P2 P3 P4 P5 +/* Opcode: IdxGE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index @@ -91160,7 +91580,7 @@ case OP_FinishSeek: { ** If the P1 index entry is greater than or equal to the key value ** then jump to P2. Otherwise fall through to the next instruction. */ -/* Opcode: IdxGT P1 P2 P3 P4 P5 +/* Opcode: IdxGT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index @@ -91171,7 +91591,7 @@ case OP_FinishSeek: { ** If the P1 index entry is greater than the key value ** then jump to P2. Otherwise fall through to the next instruction. */ -/* Opcode: IdxLT P1 P2 P3 P4 P5 +/* Opcode: IdxLT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index @@ -91182,7 +91602,7 @@ case OP_FinishSeek: { ** If the P1 index entry is less than the key value then jump to P2. ** Otherwise fall through to the next instruction. */ -/* Opcode: IdxLE P1 P2 P3 P4 P5 +/* Opcode: IdxLE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index @@ -91208,7 +91628,6 @@ case OP_IdxGE: { /* jump */ assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0); assert( pC->deferredMoveto==0 ); - assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; @@ -91229,8 +91648,31 @@ case OP_IdxGE: { /* jump */ } } #endif - res = 0; /* Not needed. Only used to silence a warning. */ - rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); + + /* Inlined version of sqlite3VdbeIdxKeyCompare() */ + { + i64 nCellKey = 0; + BtCursor *pCur; + Mem m; + + assert( pC->eCurType==CURTYPE_BTREE ); + pCur = pC->uc.pCursor; + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); + /* nCellKey will always be between 0 and 0xffffffff because of the way + ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ + if( nCellKey<=0 || nCellKey>0x7fffffff ){ + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); + if( rc ) goto abort_due_to_error; + res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0); + sqlite3VdbeMemRelease(&m); + } + /* End of inlined sqlite3VdbeIdxKeyCompare() */ + assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) ); if( (pOp->opcode&1)==(OP_IdxLT&1) ){ assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); @@ -91240,7 +91682,7 @@ case OP_IdxGE: { /* jump */ res++; } VdbeBranchTaken(res>0,2); - if( rc ) goto abort_due_to_error; + assert( rc==SQLITE_OK ); if( res>0 ) goto jump_to_p2; break; } @@ -92366,7 +92808,7 @@ case OP_JournalMode: { /* out2 */ /* Open a transaction on the database file. Regardless of the journal ** mode, this transaction always uses a rollback journal. */ - assert( sqlite3BtreeIsInTrans(pBt)==0 ); + assert( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ); if( rc==SQLITE_OK ){ rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); } @@ -93306,7 +93748,11 @@ default: { /* This is really OP_Noop, OP_Explain */ ** an error of some kind. */ abort_due_to_error: - if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT; + if( db->mallocFailed ){ + rc = SQLITE_NOMEM_BKPT; + }else if( rc==SQLITE_IOERR_CORRUPTFS ){ + rc = SQLITE_CORRUPT_BKPT; + } assert( rc ); if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); @@ -94855,13 +95301,16 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( if( pSorter==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ + Btree *pBt = db->aDb[0].pBt; pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); pKeyInfo->db = 0; if( nField && nWorker==0 ){ pKeyInfo->nKeyField = nField; } - pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); + sqlite3BtreeEnter(pBt); + pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); + sqlite3BtreeLeave(pBt); pSorter->nTask = nWorker + 1; pSorter->iPrev = (u8)(nWorker - 1); pSorter->bUseThreads = (pSorter->nTask>1); @@ -98831,7 +99280,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( !ExprHasProperty(pExpr, EP_Reduced) ); /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", ** and "x IS NOT FALSE". */ - if( pRight && pRight->op==TK_ID ){ + if( pRight && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){ int rc = resolveExprStep(pWalker, pRight); if( rc==WRC_Abort ) return WRC_Abort; if( pRight->op==TK_TRUEFALSE ){ @@ -99040,6 +99489,7 @@ static int resolveCompoundOrderBy( Expr *pE, *pDup; if( pItem->done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); + if( NEVER(pE==0) ) continue; if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); @@ -99219,6 +99669,7 @@ static int resolveOrderGroupBy( for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ Expr *pE = pItem->pExpr; Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE); + if( NEVER(pE2==0) ) continue; if( zType[0]!='G' ){ iCol = resolveAsName(pParse, pSelect->pEList, pE2); if( iCol>0 ){ @@ -99759,8 +100210,10 @@ SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){ */ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ int op; - while( ExprHasProperty(pExpr, EP_Skip) ){ - assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW ); + while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ + assert( pExpr->op==TK_COLLATE + || pExpr->op==TK_IF_NULL_ROW + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); pExpr = pExpr->pLeft; assert( pExpr!=0 ); } @@ -99830,7 +100283,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con */ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){ while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ - assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW ); + assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; } return pExpr; @@ -99849,7 +100302,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ assert( pExpr->op==TK_FUNCTION ); pExpr = pExpr->x.pList->a[0].pExpr; }else{ - assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW ); + assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; } } @@ -100483,6 +100936,7 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){ ** Expr.flags. */ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ + if( pParse->nErr ) return; if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){ p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); } @@ -103335,6 +103789,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n */ static void exprToRegister(Expr *pExpr, int iReg){ Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); + if( NEVER(p==0) ) return; p->op2 = p->op; p->op = TK_REGISTER; p->iTable = iReg; @@ -104322,6 +104777,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; pExpr = sqlite3ExprSkipCollateAndLikely(pExpr); if( ConstFactorOk(pParse) + && ALWAYS(pExpr!=0) && pExpr->op!=TK_REGISTER && sqlite3ExprIsConstantNotJoin(pExpr) ){ @@ -106996,13 +107452,21 @@ static int renameResolveTrigger(Parse *pParse){ int i; for(i=0; inSrc && rc==SQLITE_OK; i++){ struct SrcList_item *p = &pSrc->a[i]; - p->pTab = sqlite3LocateTableItem(pParse, 0, p); p->iCursor = pParse->nTab++; - if( p->pTab==0 ){ - rc = SQLITE_ERROR; + if( p->pSelect ){ + sqlite3SelectPrep(pParse, p->pSelect, 0); + sqlite3ExpandSubquery(pParse, p); + assert( i>0 ); + assert( pStep->pFrom->a[i-1].pSelect ); + sqlite3SelectPrep(pParse, pStep->pFrom->a[i-1].pSelect, 0); }else{ - p->pTab->nTabRef++; - rc = sqlite3ViewGetColumnNames(pParse, p->pTab); + p->pTab = sqlite3LocateTableItem(pParse, 0, p); + if( p->pTab==0 ){ + rc = SQLITE_ERROR; + }else{ + p->pTab->nTabRef++; + rc = sqlite3ViewGetColumnNames(pParse, p->pTab); + } } } sNC.pSrcList = pSrc; @@ -107064,6 +107528,12 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); } + if( pStep->pFrom ){ + int i; + for(i=0; ipFrom->nSrc; i++){ + sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect); + } + } } } @@ -109322,6 +109792,7 @@ static int loadStatTbl( } pSpace = (tRowcnt*)&pIdx->aSample[nSample]; pIdx->aAvgEq = pSpace; pSpace += nIdxCol; + pIdx->pTable->tabFlags |= TF_HasStat4; for(i=0; iaSample[i].anEq = pSpace; pSpace += nIdxCol; pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; @@ -109788,7 +110259,9 @@ static void detachFunc( sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); goto detach_error; } - if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){ + if( sqlite3BtreeTxnState(pDb->pBt)!=SQLITE_TXN_NONE + || sqlite3BtreeIsInBackup(pDb->pBt) + ){ sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); goto detach_error; } @@ -110448,7 +110921,7 @@ SQLITE_PRIVATE void sqlite3TableLock( u8 isWriteLock, /* True for a write lock */ const char *zName /* Name of the table to be locked */ ){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); + Parse *pToplevel; int i; int nBytes; TableLock *p; @@ -110456,6 +110929,7 @@ SQLITE_PRIVATE void sqlite3TableLock( if( iDb==1 ) return; if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return; + pToplevel = sqlite3ParseToplevel(pParse); for(i=0; inTableLock; i++){ p = &pToplevel->aTableLock[i]; if( p->iDb==iDb && p->iTab==iTab ){ @@ -110485,10 +110959,8 @@ SQLITE_PRIVATE void sqlite3TableLock( */ static void codeTableLocks(Parse *pParse){ int i; - Vdbe *pVdbe; - - pVdbe = sqlite3GetVdbe(pParse); - assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */ + Vdbe *pVdbe = pParse->pVdbe; + assert( pVdbe!=0 ); for(i=0; inTableLock; i++){ TableLock *p = &pParse->aTableLock[i]; @@ -112013,8 +112485,10 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey( ** Add a new CHECK constraint to the table currently under construction. */ SQLITE_PRIVATE void sqlite3AddCheckConstraint( - Parse *pParse, /* Parsing context */ - Expr *pCheckExpr /* The check expression */ + Parse *pParse, /* Parsing context */ + Expr *pCheckExpr, /* The check expression */ + const char *zStart, /* Opening "(" */ + const char *zEnd /* Closing ")" */ ){ #ifndef SQLITE_OMIT_CHECK Table *pTab = pParse->pNewTable; @@ -112025,6 +112499,13 @@ SQLITE_PRIVATE void sqlite3AddCheckConstraint( pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); if( pParse->constraintName.n ){ sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); + }else{ + Token t; + for(zStart++; sqlite3Isspace(zStart[0]); zStart++){} + while( sqlite3Isspace(zEnd[-1]) ){ zEnd--; } + t.z = zStart; + t.n = (int)(zEnd - t.z); + sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1); } }else #endif @@ -112043,7 +112524,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ char *zColl; /* Dequoted name of collation sequence */ sqlite3 *db; - if( (p = pParse->pNewTable)==0 ) return; + if( (p = pParse->pNewTable)==0 || IN_RENAME_OBJECT ) return; i = p->nCol-1; db = pParse->db; zColl = sqlite3NameFromToken(db, pToken); @@ -112278,12 +112759,15 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){ int nByte; if( pIdx->nColumn>=N ) return SQLITE_OK; assert( pIdx->isResized==0 ); - nByte = (sizeof(char*) + sizeof(i16) + 1)*N; + nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N; zExtra = sqlite3DbMallocZero(db, nByte); if( zExtra==0 ) return SQLITE_NOMEM_BKPT; memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); pIdx->azColl = (const char**)zExtra; zExtra += sizeof(char*)*N; + memcpy(zExtra, pIdx->aiRowLogEst, sizeof(LogEst)*(pIdx->nKeyCol+1)); + pIdx->aiRowLogEst = (LogEst*)zExtra; + zExtra += sizeof(LogEst)*N; memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn); pIdx->aiColumn = (i16*)zExtra; zExtra += sizeof(i16)*N; @@ -114844,7 +115328,7 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ assert(pList || pParse->db->mallocFailed ); if( pList ){ for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pItem->iCursor>=0 ) break; + if( pItem->iCursor>=0 ) continue; pItem->iCursor = pParse->nTab++; if( pItem->pSelect ){ sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); @@ -114861,15 +115345,15 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ struct SrcList_item *pItem; if( pList==0 ) return; for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - sqlite3DbFree(db, pItem->zDatabase); + if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); sqlite3DbFree(db, pItem->zName); - sqlite3DbFree(db, pItem->zAlias); + if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias); if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); sqlite3DeleteTable(db, pItem->pTab); - sqlite3SelectDelete(db, pItem->pSelect); - sqlite3ExprDelete(db, pItem->pOn); - sqlite3IdListDelete(db, pItem->pUsing); + if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); + if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn); + if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing); } sqlite3DbFreeNN(db, pList); } @@ -115041,7 +115525,16 @@ SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ if( !v ) return; if( type!=TK_DEFERRED ){ for(i=0; inDb; i++){ - sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); + int eTxnType; + Btree *pBt = db->aDb[i].pBt; + if( pBt && sqlite3BtreeIsReadonly(pBt) ){ + eTxnType = 0; /* Read txn */ + }else if( type==TK_EXCLUSIVE ){ + eTxnType = 2; /* Exclusive txn */ + }else{ + eTxnType = 1; /* Write txn */ + } + sqlite3VdbeAddOp2(v, OP_Transaction, i, eTxnType); sqlite3VdbeUsesBtree(v, i); } } @@ -115130,13 +115623,11 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ ** will occur at the end of the top-level VDBE and will be generated ** later, by sqlite3FinishCoding(). */ -SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - - assert( iDb>=0 && iDbdb->nDb ); - assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 ); +static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){ + assert( iDb>=0 && iDbdb->nDb ); + assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 ); assert( iDbdb, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(pToplevel->db, iDb, 0) ); if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb); if( !OMIT_TEMPDB && iDb==1 ){ @@ -115144,6 +115635,10 @@ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ } } } +SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ + sqlite3CodeVerifySchemaAtToplevel(sqlite3ParseToplevel(pParse), iDb); +} + /* ** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each @@ -115175,7 +115670,7 @@ SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb) */ SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - sqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchemaAtToplevel(pToplevel, iDb); DbMaskSet(pToplevel->writeMask, iDb); pToplevel->isMultiWrite |= setStatement; } @@ -115226,7 +115721,9 @@ SQLITE_PRIVATE void sqlite3HaltConstraint( i8 p4type, /* P4_STATIC or P4_TRANSIENT */ u8 p5Errmsg /* P5_ErrMsg type */ ){ - Vdbe *v = sqlite3GetVdbe(pParse); + Vdbe *v; + assert( pParse->pVdbe!=0 ); + v = sqlite3GetVdbe(pParse); assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested ); if( onError==OE_Abort ){ sqlite3MayAbort(pParse); @@ -116507,7 +117004,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( }else #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ { - u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK|WHERE_SEEK_TABLE; + u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; if( sNC.ncFlags & NC_VarSelect ) bComplex = 1; wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); if( HasRowid(pTab) ){ @@ -116543,6 +117040,9 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); + if( sqlite3WhereUsesDeferredSeek(pWInfo) ){ + sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur); + } /* Keep track of the number of rows to be deleted */ if( memCnt ){ @@ -116577,6 +117077,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); + addrBypass = sqlite3VdbeMakeLabel(pParse); }else{ if( pPk ){ /* Add the PK key for this row to the temporary table */ @@ -116590,13 +117091,6 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( nKey = 1; /* OP_DeferredSeek always uses a single rowid */ sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); } - } - - /* If this DELETE cannot use the ONEPASS strategy, this is the - ** end of the WHERE loop */ - if( eOnePass!=ONEPASS_OFF ){ - addrBypass = sqlite3VdbeMakeLabel(pParse); - }else{ sqlite3WhereEnd(pWInfo); } @@ -117027,10 +117521,6 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( } if( regOut ){ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); - if( pIdx->pTable->pSelect ){ - const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx); - sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); - } } sqlite3ReleaseTempRange(pParse, regBase, nCol); return regBase; @@ -119046,6 +119536,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), FUNCTION(substr, 2, 0, 0, substrFunc ), FUNCTION(substr, 3, 0, 0, substrFunc ), + FUNCTION(substring, 2, 0, 0, substrFunc ), + FUNCTION(substring, 3, 0, 0, substrFunc ), WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0), WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0), WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0), @@ -120586,7 +121078,8 @@ SQLITE_PRIVATE void sqlite3OpenTable( ){ Vdbe *v; assert( !IsVirtual(pTab) ); - v = sqlite3GetVdbe(pParse); + assert( pParse->pVdbe!=0 ); + v = pParse->pVdbe; assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); sqlite3TableLock(pParse, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName); @@ -122085,7 +122578,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( isUpdate = regOldData!=0; db = pParse->db; - v = sqlite3GetVdbe(pParse); + v = pParse->pVdbe; assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ nCol = pTab->nCol; @@ -122239,7 +122732,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( sqlite3VdbeGoto(v, ignoreDest); }else{ char *zName = pCheck->a[i].zEName; - if( zName==0 ) zName = pTab->zName; + assert( zName!=0 || pParse->db->mallocFailed ); if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, onError, zName, P4_TRANSIENT, @@ -122858,7 +123351,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION) ); - v = sqlite3GetVdbe(pParse); + v = pParse->pVdbe; assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ @@ -122959,7 +123452,7 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices( return 0; } iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - v = sqlite3GetVdbe(pParse); + v = pParse->pVdbe; assert( v!=0 ); if( iBase<0 ) iBase = pParse->nTab; iDataCur = iBase++; @@ -123931,6 +124424,8 @@ struct sqlite3_api_routines { int,const char**); void (*free_filename)(char*); sqlite3_file *(*database_file_object)(const char*); + /* Version 3.34.0 and later */ + int (*txn_state)(sqlite3*,const char*); }; /* @@ -124235,6 +124730,8 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_create_filename sqlite3_api->create_filename #define sqlite3_free_filename sqlite3_api->free_filename #define sqlite3_database_file_object sqlite3_api->database_file_object +/* Version 3.34.0 and later */ +#define sqlite3_txn_state sqlite3_api->txn_state #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -124717,6 +125214,8 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_create_filename, sqlite3_free_filename, sqlite3_database_file_object, + /* Version 3.34.0 and later */ + sqlite3_txn_state, }; /* True if x is the directory separator character @@ -125877,7 +126376,9 @@ static int getTempStore(const char *z){ static int invalidateTempStorage(Parse *pParse){ sqlite3 *db = pParse->db; if( db->aDb[1].pBt!=0 ){ - if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){ + if( !db->autoCommit + || sqlite3BtreeTxnState(db->aDb[1].pBt)!=SQLITE_TXN_NONE + ){ sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " "from within a transaction"); return SQLITE_ERROR; @@ -127197,7 +127698,7 @@ SQLITE_PRIVATE void sqlite3Pragma( aiCols = 0; if( pParent ){ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); - assert( x==0 ); + assert( x==0 || db->mallocFailed ); } addrOk = sqlite3VdbeMakeLabel(pParse); @@ -127222,7 +127723,7 @@ SQLITE_PRIVATE void sqlite3Pragma( int jmp = sqlite3VdbeCurrentAddr(v)+2; sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v); sqlite3VdbeGoto(v, addrOk); - assert( pFK->nCol==1 ); + assert( pFK->nCol==1 || db->mallocFailed ); } /* Generate code to report an FK violation to the caller. */ @@ -128580,7 +129081,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed before this function returns. */ sqlite3BtreeEnter(pDb->pBt); - if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ + if( sqlite3BtreeTxnState(pDb->pBt)==SQLITE_TXN_NONE ){ rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); if( rc!=SQLITE_OK ){ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); @@ -128823,7 +129324,7 @@ static void schemaIsValid(Parse *pParse){ /* If there is not already a read-only (or read-write) transaction opened ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed immediately after reading the meta-value. */ - if( !sqlite3BtreeIsInReadTrans(pBt) ){ + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_NONE ){ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); @@ -129086,6 +129587,7 @@ static int sqlite3LockAndPrepare( sqlite3BtreeLeaveAll(db); rc = sqlite3ApiExit(db, rc); assert( (rc&db->errMask)==rc ); + db->busyHandler.nBusy = 0; sqlite3_mutex_leave(db->mutex); return rc; } @@ -131272,6 +131774,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( char *zName; /* Column name */ int nName; /* Size of name in zName[] */ Hash ht; /* Hash table of column names */ + Table *pTab; sqlite3HashInit(&ht); if( pEList ){ @@ -131294,15 +131797,13 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( /* If the column contains an "AS " phrase, use as the name */ }else{ Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr); - while( pColExpr->op==TK_DOT ){ + while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){ pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } - if( pColExpr->op==TK_COLUMN ){ + if( pColExpr->op==TK_COLUMN && (pTab = pColExpr->y.pTab)!=0 ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; - Table *pTab = pColExpr->y.pTab; - assert( pTab!=0 ); if( iCol<0 ) iCol = pTab->iPKey; zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; }else if( pColExpr->op==TK_ID ){ @@ -131640,6 +132141,7 @@ static void generateWithRecursiveQuery( int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */ Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ Select *pSetup = p->pPrior; /* The setup query */ + Select *pFirstRec; /* Left-most recursive term */ int addrTop; /* Top of the loop */ int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ int iCurrent = 0; /* The Current table */ @@ -131715,7 +132217,25 @@ static void generateWithRecursiveQuery( /* Detach the ORDER BY clause from the compound SELECT */ p->pOrderBy = 0; + /* Figure out how many elements of the compound SELECT are part of the + ** recursive query. Make sure no recursive elements use aggregate + ** functions. Mark the recursive elements as UNION ALL even if they + ** are really UNION because the distinctness will be enforced by the + ** iDistinct table. pFirstRec is left pointing to the left-most + ** recursive term of the CTE. + */ + pFirstRec = p; + for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){ + if( pFirstRec->selFlags & SF_Aggregate ){ + sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); + goto end_of_recursive_query; + } + pFirstRec->op = TK_ALL; + if( (pFirstRec->pPrior->selFlags & SF_Recursive)==0 ) break; + } + /* Store the results of the setup-query in Queue. */ + pSetup = pFirstRec->pPrior; pSetup->pNext = 0; ExplainQueryPlan((pParse, 1, "SETUP")); rc = sqlite3Select(pParse, pSetup, &destQueue); @@ -131748,15 +132268,11 @@ static void generateWithRecursiveQuery( /* Execute the recursive SELECT taking the single row in Current as ** the value for the recursive-table. Store the results in the Queue. */ - if( p->selFlags & SF_Aggregate ){ - sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); - }else{ - p->pPrior = 0; - ExplainQueryPlan((pParse, 1, "RECURSIVE STEP")); - sqlite3Select(pParse, p, &destQueue); - assert( p->pPrior==0 ); - p->pPrior = pSetup; - } + pFirstRec->pPrior = 0; + ExplainQueryPlan((pParse, 1, "RECURSIVE STEP")); + sqlite3Select(pParse, p, &destQueue); + assert( pFirstRec->pPrior==0 ); + pFirstRec->pPrior = pSetup; /* Keep running the loop until the Queue is empty */ sqlite3VdbeGoto(v, addrTop); @@ -131825,6 +132341,16 @@ static int multiSelectValues( return rc; } +/* +** Return true if the SELECT statement which is known to be the recursive +** part of a recursive CTE still has its anchor terms attached. If the +** anchor terms have already been removed, then return false. +*/ +static int hasAnchor(Select *p){ + while( p && (p->selFlags & SF_Recursive)!=0 ){ p = p->pPrior; } + return p!=0; +} + /* ** This routine is called to process a compound query form from ** two or more separate queries using UNION, UNION ALL, EXCEPT, or @@ -131910,7 +132436,7 @@ static int multiSelect( assert( p->pEList->nExpr==pPrior->pEList->nExpr ); #ifndef SQLITE_OMIT_CTE - if( p->selFlags & SF_Recursive ){ + if( (p->selFlags & SF_Recursive)!=0 && hasAnchor(p) ){ generateWithRecursiveQuery(pParse, p, &dest); }else #endif @@ -132002,6 +132528,7 @@ static int multiSelect( assert( p->pEList ); } + /* Code the SELECT statements to our left */ assert( !pPrior->pOrderBy ); @@ -132806,7 +133333,7 @@ static Expr *substExpr( ifNullRow.op = TK_IF_NULL_ROW; ifNullRow.pLeft = pCopy; ifNullRow.iTable = pSubst->iNewTable; - ifNullRow.flags = EP_Skip; + ifNullRow.flags = EP_IfNullRow; pCopy = &ifNullRow; } testcase( ExprHasProperty(pCopy, EP_Subquery) ); @@ -132815,8 +133342,7 @@ static Expr *substExpr( ExprSetProperty(pNew, EP_CanBeNull); } if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){ - pNew->iRightJoinTable = pExpr->iRightJoinTable; - ExprSetProperty(pNew, EP_FromJoin); + sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable); } sqlite3ExprDelete(db, pExpr); pExpr = pNew; @@ -134095,8 +134621,10 @@ static int withExpand( ExprList *pEList; Select *pSel; Select *pLeft; /* Left-most SELECT statement */ + Select *pRecTerm; /* Left-most recursive term */ int bMayRecursive; /* True if compound joined by UNION [ALL] */ With *pSavedWith; /* Initial value of pParse->pWith */ + int iRecTab = -1; /* Cursor for recursive table */ /* If pCte->zCteErr is non-NULL at this point, then this is an illegal ** recursive reference to CTE pCte. Leave an error in pParse and return @@ -134121,44 +134649,48 @@ static int withExpand( assert( pFrom->pSelect ); /* Check if this is a recursive CTE. */ - pSel = pFrom->pSelect; + pRecTerm = pSel = pFrom->pSelect; bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); - if( bMayRecursive ){ + while( bMayRecursive && pRecTerm->op==pSel->op ){ int i; - SrcList *pSrc = pFrom->pSelect->pSrc; + SrcList *pSrc = pRecTerm->pSrc; + assert( pRecTerm->pPrior!=0 ); for(i=0; inSrc; i++){ struct SrcList_item *pItem = &pSrc->a[i]; if( pItem->zDatabase==0 && pItem->zName!=0 && 0==sqlite3StrICmp(pItem->zName, pCte->zName) - ){ + ){ pItem->pTab = pTab; - pItem->fg.isRecursive = 1; pTab->nTabRef++; - pSel->selFlags |= SF_Recursive; + pItem->fg.isRecursive = 1; + if( pRecTerm->selFlags & SF_Recursive ){ + sqlite3ErrorMsg(pParse, + "multiple references to recursive table: %s", pCte->zName + ); + return SQLITE_ERROR; + } + pRecTerm->selFlags |= SF_Recursive; + if( iRecTab<0 ) iRecTab = pParse->nTab++; + pItem->iCursor = iRecTab; } } + if( (pRecTerm->selFlags & SF_Recursive)==0 ) break; + pRecTerm = pRecTerm->pPrior; } - /* Only one recursive reference is permitted. */ - if( pTab->nTabRef>2 ){ - sqlite3ErrorMsg( - pParse, "multiple references to recursive table: %s", pCte->zName - ); - return SQLITE_ERROR; - } - assert( pTab->nTabRef==1 || - ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 )); - pCte->zCteErr = "circular reference: %s"; pSavedWith = pParse->pWith; pParse->pWith = pWith; - if( bMayRecursive ){ - Select *pPrior = pSel->pPrior; - assert( pPrior->pWith==0 ); - pPrior->pWith = pSel->pWith; - sqlite3WalkSelect(pWalker, pPrior); - pPrior->pWith = 0; + if( pSel->selFlags & SF_Recursive ){ + assert( pRecTerm!=0 ); + assert( (pRecTerm->selFlags & SF_Recursive)==0 ); + assert( pRecTerm->pNext!=0 ); + assert( (pRecTerm->pNext->selFlags & SF_Recursive)!=0 ); + assert( pRecTerm->pWith==0 ); + pRecTerm->pWith = pSel->pWith; + sqlite3WalkSelect(pWalker, pRecTerm); + pRecTerm->pWith = 0; }else{ sqlite3WalkSelect(pWalker, pSel); } @@ -135108,13 +135640,11 @@ SQLITE_PRIVATE int sqlite3Select( assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); - if( IgnorableOrderby(pDest) ){ - assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || - pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || - pDest->eDest==SRT_Queue || pDest->eDest==SRT_DistFifo || - pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo); - /* If ORDER BY makes no difference in the output then neither does - ** DISTINCT so it can be removed too. */ + if( IgnorableDistinct(pDest) ){ + assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || + pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || + pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); + /* All of these destinations are also able to ignore the ORDER BY clause */ sqlite3ExprListDelete(db, p->pOrderBy); p->pOrderBy = 0; p->selFlags &= ~SF_Distinct; @@ -136548,22 +137078,11 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( pTab = sqlite3SrcListLookup(pParse, pTableName); if( !pTab ){ /* The table does not exist. */ - if( db->init.iDb==1 ){ - /* Ticket #3810. - ** Normally, whenever a table is dropped, all associated triggers are - ** dropped too. But if a TEMP trigger is created on a non-TEMP table - ** and the table is dropped by a different database connection, the - ** trigger is not visible to the database connection that does the - ** drop so the trigger cannot be dropped. This results in an - ** "orphaned trigger" - a trigger whose associated table is missing. - */ - db->init.orphanTrigger = 1; - } - goto trigger_cleanup; + goto trigger_orphan_error; } if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); - goto trigger_cleanup; + goto trigger_orphan_error; } /* Check that the trigger name is not reserved and that no trigger of the @@ -136601,12 +137120,12 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0); - goto trigger_cleanup; + goto trigger_orphan_error; } if( !pTab->pSelect && tr_tm==TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" " trigger on table: %S", pTableName, 0); - goto trigger_cleanup; + goto trigger_orphan_error; } #ifndef SQLITE_OMIT_AUTHORIZATION @@ -136666,6 +137185,23 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( }else{ assert( pParse->pNewTrigger==pTrigger ); } + return; + +trigger_orphan_error: + if( db->init.iDb==1 ){ + /* Ticket #3810. + ** Normally, whenever a table is dropped, all associated triggers are + ** dropped too. But if a TEMP trigger is created on a non-TEMP table + ** and the table is dropped by a different database connection, the + ** trigger is not visible to the database connection that does the + ** drop so the trigger cannot be dropped. This results in an + ** "orphaned trigger" - a trigger whose associated table is missing. + ** + ** 2020-11-05 see also https://sqlite.org/forum/forumpost/157dc791df + */ + db->init.orphanTrigger = 1; + } + goto trigger_cleanup; } /* @@ -137836,7 +138372,7 @@ static void updateFromSelect( #endif pList = sqlite3ExprListAppend(pParse, pList, pNew); } - eDest = SRT_Upfrom; + eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom; }else if( pTab->pSelect ){ for(i=0; inCol; i++){ pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i)); @@ -138253,6 +138789,8 @@ SQLITE_PRIVATE void sqlite3Update( if( nChangeFrom==0 && HasRowid(pTab) ){ sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); + iEph = pParse->nTab++; + addrOpen = sqlite3VdbeAddOp3(v, OP_OpenEphemeral, iEph, 0, regRowSet); }else{ assert( pPk!=0 || HasRowid(pTab) ); nPk = pPk ? pPk->nKeyCol : 0; @@ -138307,7 +138845,7 @@ SQLITE_PRIVATE void sqlite3Update( ** be deleted as a result of REPLACE conflict handling. Any of these ** things might disturb a cursor being used to scan through the table ** or index, causing a single-pass approach to malfunction. */ - flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE; + flags = WHERE_ONEPASS_DESIRED; if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ flags |= WHERE_ONEPASS_MULTIROW; } @@ -138344,9 +138882,10 @@ SQLITE_PRIVATE void sqlite3Update( ** leave it in register regOldRowid. */ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); if( eOnePass==ONEPASS_OFF ){ - /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */ aRegIdx[nAllIdx] = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iEph, regRowSet, regOldRowid); + }else{ + if( ALWAYS(addrOpen) ) sqlite3VdbeChangeToNoop(v, addrOpen); } }else{ /* Read the PK of the current row into an array of registers. In @@ -138434,8 +138973,9 @@ SQLITE_PRIVATE void sqlite3Update( VdbeCoverage(v); } }else{ - labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak, - regOldRowid); + sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); + labelContinue = sqlite3VdbeMakeLabel(pParse); + addrTop = sqlite3VdbeAddOp2(v, OP_Rowid, iEph, regOldRowid); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); VdbeCoverage(v); @@ -138685,11 +139225,9 @@ SQLITE_PRIVATE void sqlite3Update( }else if( eOnePass==ONEPASS_MULTI ){ sqlite3VdbeResolveLabel(v, labelContinue); sqlite3WhereEnd(pWInfo); - }else if( pPk || nChangeFrom ){ + }else{ sqlite3VdbeResolveLabel(v, labelContinue); sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); - }else{ - sqlite3VdbeGoto(v, labelContinue); } sqlite3VdbeResolveLabel(v, labelBreak); @@ -138789,12 +139327,26 @@ static void updateVirtualTable( regArg = pParse->nMem + 1; pParse->nMem += nArg; if( pSrc->nSrc>1 ){ + Index *pPk = 0; Expr *pRow; ExprList *pList; - if( pRowid ){ - pRow = sqlite3ExprDup(db, pRowid, 0); + if( HasRowid(pTab) ){ + if( pRowid ){ + pRow = sqlite3ExprDup(db, pRowid, 0); + }else{ + pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0); + } }else{ - pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0); + i16 iPk; /* PRIMARY KEY column */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol==1 ); + iPk = pPk->aiColumn[0]; + if( aXRef[iPk]>=0 ){ + pRow = sqlite3ExprDup(db, pChanges->a[aXRef[iPk]].pExpr, 0); + }else{ + pRow = exprRowColumn(pParse, iPk); + } } pList = sqlite3ExprListAppend(pParse, 0, pRow); @@ -138808,7 +139360,7 @@ static void updateVirtualTable( } } - updateFromSelect(pParse, ephemTab, 0, pList, pSrc, pWhere, 0, 0); + updateFromSelect(pParse, ephemTab, pPk, pList, pSrc, pWhere, 0, 0); sqlite3ExprListDelete(db, pList); eOnePass = ONEPASS_OFF; }else{ @@ -139510,8 +140062,8 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( BTREE_APPLICATION_ID, 0, /* Preserve the application id */ }; - assert( 1==sqlite3BtreeIsInTrans(pTemp) ); - assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) ); + assert( SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pTemp) ); + assert( pOut!=0 || SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pMain) ); /* Copy Btree meta values */ for(i=0; ia[iParent] when this term disabled */ int leftCursor; /* Cursor number of X in "X " */ - int iField; /* Field in (?,?,?) IN (SELECT...) vector */ union { - int leftColumn; /* Column number of X in "X " */ + struct { + int leftColumn; /* Column number of X in "X " */ + int iField; /* Field in (?,?,?) IN (SELECT...) vector */ + } x; /* Opcode other than OP_OR or OP_AND */ WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */ } u; @@ -141409,6 +141963,7 @@ struct WhereInfo { unsigned sorted :1; /* True if really sorted (not just grouped) */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ + int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ WhereExprMod *pExprMods; /* Expression modifications */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ @@ -141537,6 +142092,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */ +#define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */ #endif /* !defined(SQLITE_WHEREINT_H) */ @@ -141950,7 +142506,7 @@ static Expr *removeUnindexableInClauseTerms( for(i=iEq; inLTerm; i++){ if( pLoop->aLTerm[i]->pExpr==pX ){ - int iField = pLoop->aLTerm[i]->iField - 1; + int iField = pLoop->aLTerm[i]->u.x.iField - 1; if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; @@ -142093,6 +142649,9 @@ static int codeEqualityTerm( if( pLevel->u.in.nIn==0 ){ pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); } + if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ + pLoop->wsFlags |= WHERE_IN_EARLYOUT; + } i = pLevel->u.in.nIn; pLevel->u.in.nIn += nEq; @@ -142119,7 +142678,6 @@ static int codeEqualityTerm( if( iEq>0 ){ pIn->iBase = iReg - i; pIn->nPrefix = i; - pLoop->wsFlags |= WHERE_IN_EARLYOUT; }else{ pIn->nPrefix = 0; } @@ -142129,6 +142687,14 @@ static int codeEqualityTerm( pIn++; } } + testcase( iEq>0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 + && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); + if( iEq>0 + && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 + ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); + } }else{ pLevel->u.in.nIn = 0; } @@ -142915,6 +143481,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC); VdbeCoverage(v); pLoop->u.vtab.needFree = 0; + /* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed + ** the u.vtab.idxStr. NULL it out to prevent a use-after-free */ + if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0; pLevel->p1 = iCur; pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; pLevel->p2 = sqlite3VdbeCurrentAddr(v); @@ -143173,6 +143742,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ int omitTable; /* True if we use the index only */ int regBignull = 0; /* big-null flag register */ + int addrSeekScan = 0; /* Opcode of the OP_SeekScan, if any */ pIdx = pLoop->u.btree.pIndex; iIdxCur = pLevel->iIdxCur; @@ -143311,9 +143881,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** above has already left the cursor sitting on the correct row, ** so no further seeking is needed */ }else{ - if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ - sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); - } if( regBignull ){ sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); VdbeComment((v, "NULL-scan pass ctr")); @@ -143321,6 +143888,20 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); + if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){ + assert( regBignull==0 ); + /* TUNING: The OP_SeekScan opcode seeks to reduce the number + ** of expensive seek operations by replacing a single seek with + ** 1 or more step operations. The question is, how many steps + ** should we try before giving up and going with a seek. The cost + ** of a seek is proportional to the logarithm of the of the number + ** of entries in the tree, so basing the number of steps to try + ** on the estimated number of rows in the btree seems like a good + ** guess. */ + addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, + (pIdx->aiRowLogEst[0]+9)/10); + VdbeCoverage(v); + } sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); VdbeCoverage(v); VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); @@ -143403,6 +143984,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); + if( addrSeekScan ) sqlite3VdbeJumpHere(v, addrSeekScan); } if( regBignull ){ /* During a NULL-scan, check to see if we have reached the end of @@ -143422,8 +144004,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } - if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ - sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); + if( (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0 ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq); } /* Seek the table cursor, if required */ @@ -143432,17 +144014,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ - if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) - || ( (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE)!=0 - && (pWInfo->eOnePass==ONEPASS_SINGLE || pLoop->nLTerm==0) ) - ){ - iRowidReg = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); - VdbeCoverage(v); - }else{ - codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); - } + codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); }else if( iCur!=iIdxCur ){ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); @@ -143569,7 +144141,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int iRetInit; /* Address of regReturn init */ int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ - u16 wctrlFlags; /* Flags for sub-WHERE clause */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ Table *pTab = pTabItem->pTab; @@ -143670,7 +144241,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** eliminating duplicates from other WHERE clauses, the action for each ** sub-WHERE clause is to to invoke the main loop body as a subroutine. */ - wctrlFlags = WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE); ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR")); for(ii=0; iinTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; @@ -143689,7 +144259,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, - wctrlFlags, iCovCur); + WHERE_OR_SUBCLAUSE, iCovCur); assert( pSubWInfo || pParse->nErr || db->mallocFailed ); if( pSubWInfo ){ WhereLoop *pSubLoop; @@ -143787,6 +144357,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( }else{ pCov = 0; } + if( sqlite3WhereUsesDeferredSeek(pSubWInfo) ){ + pWInfo->bDeferredSeek = 1; + } /* Finish the loop through table entries that match term pOrTerm. */ sqlite3WhereEnd(pSubWInfo); @@ -143939,7 +144512,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( #endif assert( !ExprHasProperty(pE, EP_FromJoin) ); assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); - pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady, + pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady, WO_EQ|WO_IN|WO_IS, 0); if( pAlt==0 ) continue; if( pAlt->wtFlags & (TERM_CODED) ) continue; @@ -144795,7 +145368,7 @@ static void exprAnalyzeOrTerm( assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); continue; } - iColumn = pOrTerm->u.leftColumn; + iColumn = pOrTerm->u.x.leftColumn; iCursor = pOrTerm->leftCursor; pLeft = pOrTerm->pExpr->pLeft; break; @@ -144817,7 +145390,7 @@ static void exprAnalyzeOrTerm( assert( pOrTerm->eOperator & WO_EQ ); if( pOrTerm->leftCursor!=iCursor ){ pOrTerm->wtFlags &= ~TERM_OR_OK; - }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR + }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) )){ okToChngToIN = 0; @@ -144852,7 +145425,7 @@ static void exprAnalyzeOrTerm( if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue; assert( pOrTerm->eOperator & WO_EQ ); assert( pOrTerm->leftCursor==iCursor ); - assert( pOrTerm->u.leftColumn==iColumn ); + assert( pOrTerm->u.x.leftColumn==iColumn ); pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); pLeft = pOrTerm->pExpr->pLeft; @@ -145088,15 +145661,15 @@ static void exprAnalyze( Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; - if( pTerm->iField>0 ){ + if( pTerm->u.x.iField>0 ){ assert( op==TK_IN ); assert( pLeft->op==TK_VECTOR ); - pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr; + pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr; } if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){ pTerm->leftCursor = aiCurCol[0]; - pTerm->u.leftColumn = aiCurCol[1]; + pTerm->u.x.leftColumn = aiCurCol[1]; pTerm->eOperator = operatorMask(op) & opMask; } if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; @@ -145106,7 +145679,7 @@ static void exprAnalyze( WhereTerm *pNew; Expr *pDup; u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ - assert( pTerm->iField==0 ); + assert( pTerm->u.x.iField==0 ); if( pTerm->leftCursor>=0 ){ int idxNew; pDup = sqlite3ExprDup(db, pExpr, 0); @@ -145132,7 +145705,7 @@ static void exprAnalyze( } pNew->wtFlags |= exprCommute(pParse, pDup); pNew->leftCursor = aiCurCol[0]; - pNew->u.leftColumn = aiCurCol[1]; + pNew->u.x.leftColumn = aiCurCol[1]; testcase( (prereqLeft | extraRight) != prereqLeft ); pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; @@ -145306,7 +145879,7 @@ static void exprAnalyze( pNewTerm = &pWC->a[idxNew]; pNewTerm->prereqRight = prereqExpr; pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.leftColumn = pLeft->iColumn; + pNewTerm->u.x.leftColumn = pLeft->iColumn; pNewTerm->eOperator = WO_AUX; pNewTerm->eMatchOp = eOp2; markTermAsChild(pWC, idxNew, idxTerm); @@ -145353,13 +145926,13 @@ static void exprAnalyze( /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create ** a virtual term for each vector component. The expression object ** used by each such virtual term is pExpr (the full vector IN(...) - ** expression). The WhereTerm.iField variable identifies the index within + ** expression). The WhereTerm.u.x.iField variable identifies the index within ** the vector on the LHS that the virtual term represents. ** ** This only works if the RHS is a simple SELECT (not a compound) that does ** not use window functions. */ - if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0 + if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->u.x.iField==0 && pExpr->pLeft->op==TK_VECTOR && pExpr->x.pSelect->pPrior==0 #ifndef SQLITE_OMIT_WINDOWFUNC @@ -145370,7 +145943,7 @@ static void exprAnalyze( for(i=0; ipLeft); i++){ int idxNew; idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); - pWC->a[idxNew].iField = i+1; + pWC->a[idxNew].u.x.iField = i+1; exprAnalyze(pSrc, pWC, idxNew); markTermAsChild(pWC, idxNew, idxTerm); } @@ -145405,7 +145978,7 @@ static void exprAnalyze( pNewTerm = &pWC->a[idxNew]; pNewTerm->prereqRight = 0; pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.leftColumn = pLeft->iColumn; + pNewTerm->u.x.leftColumn = pLeft->iColumn; pNewTerm->eOperator = WO_GT; markTermAsChild(pWC, idxNew, idxTerm); pTerm = &pWC->a[idxTerm]; @@ -145448,6 +146021,7 @@ static void exprAnalyze( SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr); pWC->op = op; + assert( pE2!=0 || pExpr==0 ); if( pE2==0 ) return; if( pE2->op!=op ){ whereClauseInsert(pWC, pExpr, 0); @@ -145847,6 +146421,16 @@ static void createMask(WhereMaskSet *pMaskSet, int iCursor){ pMaskSet->ix[pMaskSet->n++] = iCursor; } +/* +** If the right-hand branch of the expression is a TK_COLUMN, then return +** a pointer to the right-hand branch. Otherwise, return NULL. +*/ +static Expr *whereRightSubexprIsColumn(Expr *p){ + p = sqlite3ExprSkipCollateAndLikely(p->pRight); + if( ALWAYS(p!=0) && p->op==TK_COLUMN ) return p; + return 0; +} + /* ** Advance to the next WhereTerm that matches according to the criteria ** established when the pScan object was initialized by whereScanInit(). @@ -145869,7 +146453,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ do{ for(pTerm=pWC->a+k; knTerm; k++, pTerm++){ if( pTerm->leftCursor==iCur - && pTerm->u.leftColumn==iColumn + && pTerm->u.x.leftColumn==iColumn && (iColumn!=XN_EXPR || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft, pScan->pIdxExpr,iCur)==0) @@ -145877,8 +146461,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ ){ if( (pTerm->eOperator & WO_EQUIV)!=0 && pScan->nEquivaiCur) - && (pX = sqlite3ExprSkipCollateAndLikely(pTerm->pExpr->pRight))->op - ==TK_COLUMN + && (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0 ){ int j; for(j=0; jnEquiv; j++){ @@ -146074,7 +146657,8 @@ static int findIndexCol( for(i=0; inExpr; i++){ Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr); - if( p->op==TK_COLUMN + if( ALWAYS(p!=0) + && p->op==TK_COLUMN && p->iColumn==pIdx->aiColumn[iCol] && p->iTable==iBase ){ @@ -146138,6 +146722,7 @@ static int isDistinctRedundant( */ for(i=0; inExpr; i++){ Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr); + if( NEVER(p==0) ) continue; if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1; } @@ -146291,8 +146876,8 @@ static int termCanDriveIndex( return 0; } if( (pTerm->prereqRight & notReady)!=0 ) return 0; - if( pTerm->u.leftColumn<0 ) return 0; - aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity; + if( pTerm->u.x.leftColumn<0 ) return 0; + aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity; if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; testcase( pTerm->pExpr->op==TK_IS ); return 1; @@ -146363,7 +146948,7 @@ static void constructAutomaticIndex( sqlite3ExprDup(pParse->db, pExpr, 0)); } if( termCanDriveIndex(pTerm, pSrc, notReady) ){ - int iCol = pTerm->u.leftColumn; + int iCol = pTerm->u.x.leftColumn; Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); testcase( iCol==BMS ); testcase( iCol==BMS-1 ); @@ -146416,14 +147001,14 @@ static void constructAutomaticIndex( idxCols = 0; for(pTerm=pWC->a; pTermu.leftColumn; + int iCol = pTerm->u.x.leftColumn; Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); testcase( iCol==BMS-1 ); testcase( iCol==BMS ); if( (idxCols & cMask)==0 ){ Expr *pX = pTerm->pExpr; idxCols |= cMask; - pIdx->aiColumn[n] = pTerm->u.leftColumn; + pIdx->aiColumn[n] = pTerm->u.x.leftColumn; pColl = sqlite3ExprCompareCollSeq(pParse, pX); assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; @@ -146544,7 +147129,7 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator & WO_ALL ); if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; - assert( pTerm->u.leftColumn>=(-1) ); + assert( pTerm->u.x.leftColumn>=(-1) ); nTerm++; } @@ -146604,8 +147189,8 @@ static sqlite3_index_info *allocateIndexInfo( ){ continue; } - assert( pTerm->u.leftColumn>=(-1) ); - pIdxCons[j].iColumn = pTerm->u.leftColumn; + assert( pTerm->u.x.leftColumn>=(-1) ); + pIdxCons[j].iColumn = pTerm->u.x.leftColumn; pIdxCons[j].iTermOffset = i; op = pTerm->eOperator & WO_ALL; if( op==WO_IN ) op = WO_EQ; @@ -147368,9 +147953,9 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C'; if( pTerm->eOperator & WO_SINGLE ){ sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", - pTerm->leftCursor, pTerm->u.leftColumn); + pTerm->leftCursor, pTerm->u.x.leftColumn); }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){ - sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld", + sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", pTerm->u.pOrInfo->indexable); }else{ sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); @@ -147384,8 +147969,8 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx", pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight); } - if( pTerm->iField ){ - sqlite3DebugPrintf(" iField=%d", pTerm->iField); + if( pTerm->u.x.iField ){ + sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField); } if( pTerm->iParent>=0 ){ sqlite3DebugPrintf(" iParent=%d", pTerm->iParent); @@ -148052,9 +148637,9 @@ static int whereLoopAddBtreeIndex( pNew = pBuilder->pNew; if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; - WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d\n", + WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n", pProbe->pTable->zName,pProbe->zName, - pNew->u.btree.nEq, pNew->nSkip)); + pNew->u.btree.nEq, pNew->nSkip, pNew->rRun)); assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); @@ -148148,7 +148733,7 @@ static int whereLoopAddBtreeIndex( /* "x IN (value, value, ...)" */ nIn = sqlite3LogEst(pExpr->x.pList->nExpr); } - if( pProbe->hasStat1 ){ + if( pProbe->hasStat1 && rLogSize>=10 ){ LogEst M, logK, safetyMargin; /* Let: ** N = the total number of rows in the table @@ -148167,7 +148752,8 @@ static int whereLoopAddBtreeIndex( ** a safety margin of 2 (LogEst: 10) that favors using the IN operator ** with the index, as using an index has better worst-case behavior. ** If we do not have real sqlite_stat1 data, always prefer to use - ** the index. + ** the index. Do not bother with this optimization on very small + ** tables (less than 2 rows) as it is pointless in that case. */ M = pProbe->aiRowLogEst[saved_nEq]; logK = estLog(nIn); @@ -148176,7 +148762,7 @@ static int whereLoopAddBtreeIndex( WHERETRACE(0x40, ("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n", saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize)); - continue; + pNew->wsFlags |= WHERE_IN_SEEKSCAN; }else{ WHERETRACE(0x40, ("IN operator preferred on column %d of \"%s\" (%d>=%d)\n", @@ -148422,6 +149008,7 @@ static int indexMightHelpWithOrderBy( if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; for(ii=0; iinExpr; ii++){ Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); + if( NEVER(pExpr==0) ) continue; if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ if( pExpr->iColumn<0 ) return 1; for(jj=0; jjnKeyCol; jj++){ @@ -148653,8 +149240,23 @@ static int whereLoopAddBtree( /* Full table scan */ pNew->iSortIdx = b ? iSortIdx : 0; - /* TUNING: Cost of full table scan is (N*3.0). */ + /* TUNING: Cost of full table scan is 3.0*N. The 3.0 factor is an + ** extra cost designed to discourage the use of full table scans, + ** since index lookups have better worst-case performance if our + ** stat guesses are wrong. Reduce the 3.0 penalty slightly + ** (to 2.75) if we have valid STAT4 information for the table. + ** At 2.75, a full table scan is preferred over using an index on + ** a column with just two distinct values where each value has about + ** an equal number of appearances. Without STAT4 data, we still want + ** to use an index in that case, since the constraint might be for + ** the scarcer of the two values, and in that case an index lookup is + ** better. + */ +#ifdef SQLITE_ENABLE_STAT4 + pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0); +#else pNew->rRun = rSize + 16; +#endif ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); @@ -149385,6 +149987,7 @@ static i8 wherePathSatisfiesOrderBy( for(i=0; ia[i].pExpr); + if( NEVER(pOBExpr==0) ) continue; if( pOBExpr->op!=TK_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, @@ -149511,6 +150114,7 @@ static i8 wherePathSatisfiesOrderBy( pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); testcase( wctrlFlags & WHERE_GROUPBY ); testcase( wctrlFlags & WHERE_DISTINCTBY ); + if( NEVER(pOBExpr==0) ) continue; if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; if( iColumn>=XN_ROWID ){ if( pOBExpr->op!=TK_COLUMN ) continue; @@ -149665,16 +150269,24 @@ static LogEst whereSortingCost( ** cost = (3.0 * N * log(N)) * (Y/X) ** ** The (Y/X) term is implemented using stack variable rScale - ** below. */ + ** below. + */ LogEst rScale, rSortCost; assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; rSortCost = nRow + rScale + 16; /* Multiple by log(M) where M is the number of output rows. - ** Use the LIMIT for M if it is smaller */ + ** Use the LIMIT for M if it is smaller. Or if this sort is for + ** a DISTINCT operator, M will be the number of distinct output + ** rows, so fudge it downwards a bit. + */ if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimitiLimit; + }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){ + /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT + ** reduces the number of output rows by a factor of 2 */ + if( nRow>10 ) nRow -= 10; assert( 10==sqlite3LogEst(2) ); } rSortCost += estLog(nRow); return rSortCost; @@ -150801,6 +151413,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 && (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED ){ @@ -150858,6 +151471,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* Done. */ VdbeModuleComment((v, "Begin WHERE-core")); + pWInfo->iEndWhere = sqlite3VdbeCurrentAddr(v); return pWInfo; /* Jump here if malloc fails */ @@ -150901,6 +151515,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ WhereLoop *pLoop; SrcList *pTabList = pWInfo->pTabList; sqlite3 *db = pParse->db; + int iEnd = sqlite3VdbeCurrentAddr(v); /* Generate loop termination code. */ @@ -150961,7 +151576,9 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ if( pIn->nPrefix ){ - assert( pLoop->wsFlags & WHERE_IN_EARLYOUT ); + int bEarlyOut = + (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0; if( pLevel->iLeftJoin ){ /* For LEFT JOIN queries, cursor pIn->iCur may not have been ** opened yet. This occurs for WHERE clauses such as @@ -150972,12 +151589,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ** jump over the OP_Next or OP_Prev instruction about to ** be coded. */ sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, - sqlite3VdbeCurrentAddr(v) + 2 + - ((pLoop->wsFlags & WHERE_VIRTUALTABLE)==0) - ); + sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut); VdbeCoverage(v); } - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + if( bEarlyOut ){ sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, sqlite3VdbeCurrentAddr(v)+2, pIn->iBase, pIn->nPrefix); @@ -151038,7 +151653,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ assert( pWInfo->nLevel<=pTabList->nSrc ); for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ int k, last; - VdbeOp *pOp; + VdbeOp *pOp, *pLastOp; Index *pIdx = 0; struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; @@ -151096,20 +151711,31 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ pIdx = pLevel->u.pCovidx; } if( pIdx - && (pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable)) && !db->mallocFailed ){ - last = sqlite3VdbeCurrentAddr(v); - k = pLevel->addrBody; + if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){ + last = iEnd; + }else{ + last = pWInfo->iEndWhere; + } + k = pLevel->addrBody + 1; #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeAddopTrace ){ printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); } + /* Proof that the "+1" on the k value above is safe */ + pOp = sqlite3VdbeGetOp(v, k - 1); + assert( pOp->opcode!=OP_Column || pOp->p1!=pLevel->iTabCur ); + assert( pOp->opcode!=OP_Rowid || pOp->p1!=pLevel->iTabCur ); + assert( pOp->opcode!=OP_IfNullRow || pOp->p1!=pLevel->iTabCur ); #endif pOp = sqlite3VdbeGetOp(v, k); - for(; kp1!=pLevel->iTabCur ) continue; - if( pOp->opcode==OP_Column + pLastOp = pOp + (last - k); + assert( pOpp1!=pLevel->iTabCur ){ + /* no-op */ + }else if( pOp->opcode==OP_Column #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC || pOp->opcode==OP_Offset #endif @@ -151140,7 +151766,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); } - } +#ifdef SQLITE_DEBUG + k++; +#endif + }while( (++pOp)flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n"); #endif @@ -154209,8 +154838,10 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( /************** End of window.c **********************************************/ /************** Begin file parse.c *******************************************/ +/* This file is automatically generated by Lemon from input grammar +** source file "parse.y". */ /* -** 2000-05-29 +** 2001-09-15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -154220,22 +154851,15 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( ** May you share freely, never taking more than you give. ** ************************************************************************* -** Driver template for the LEMON parser generator. -** -** The "lemon" program processes an LALR(1) input grammar file, then uses -** this template to construct a parser. The "lemon" program inserts text -** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the -** interstitial "-" characters) contained in this template is changed into -** the value of the %name directive from the grammar. Otherwise, the content -** of this template is copied straight through into the generate parser -** source file. +** This file contains SQLite's SQL parser. ** -** The following is the concatenation of all %include directives from the -** input grammar file: +** The canonical source code to this file ("parse.y") is a Lemon grammar +** file that specifies the input grammar and actions to take while parsing. +** That input file is processed by Lemon to generate a C-language +** implementation of a parser for the given grammer. You might be reading +** this comment as part of the translated C-code. Edits should be made +** to the original parse.y sources. */ -/* #include */ -/* #include */ -/************ Begin %include sections from the grammar ************************/ /* #include "sqliteInt.h" */ @@ -154419,11 +155043,191 @@ static void updateDeleteLimitError( # error too many tokens in the grammar #endif /**************** End of %include directives **********************************/ -/* These constants specify the various numeric values for terminal symbols -** in a format understandable to "makeheaders". This section is blank unless -** "lemon" is run with the "-m" command-line option. -***************** Begin makeheaders token definitions *************************/ -/**************** End makeheaders token definitions ***************************/ +/* These constants specify the various numeric values for terminal symbols. +***************** Begin token definitions *************************************/ +#ifndef TK_SEMI +#define TK_SEMI 1 +#define TK_EXPLAIN 2 +#define TK_QUERY 3 +#define TK_PLAN 4 +#define TK_BEGIN 5 +#define TK_TRANSACTION 6 +#define TK_DEFERRED 7 +#define TK_IMMEDIATE 8 +#define TK_EXCLUSIVE 9 +#define TK_COMMIT 10 +#define TK_END 11 +#define TK_ROLLBACK 12 +#define TK_SAVEPOINT 13 +#define TK_RELEASE 14 +#define TK_TO 15 +#define TK_TABLE 16 +#define TK_CREATE 17 +#define TK_IF 18 +#define TK_NOT 19 +#define TK_EXISTS 20 +#define TK_TEMP 21 +#define TK_LP 22 +#define TK_RP 23 +#define TK_AS 24 +#define TK_WITHOUT 25 +#define TK_COMMA 26 +#define TK_ABORT 27 +#define TK_ACTION 28 +#define TK_AFTER 29 +#define TK_ANALYZE 30 +#define TK_ASC 31 +#define TK_ATTACH 32 +#define TK_BEFORE 33 +#define TK_BY 34 +#define TK_CASCADE 35 +#define TK_CAST 36 +#define TK_CONFLICT 37 +#define TK_DATABASE 38 +#define TK_DESC 39 +#define TK_DETACH 40 +#define TK_EACH 41 +#define TK_FAIL 42 +#define TK_OR 43 +#define TK_AND 44 +#define TK_IS 45 +#define TK_MATCH 46 +#define TK_LIKE_KW 47 +#define TK_BETWEEN 48 +#define TK_IN 49 +#define TK_ISNULL 50 +#define TK_NOTNULL 51 +#define TK_NE 52 +#define TK_EQ 53 +#define TK_GT 54 +#define TK_LE 55 +#define TK_LT 56 +#define TK_GE 57 +#define TK_ESCAPE 58 +#define TK_ID 59 +#define TK_COLUMNKW 60 +#define TK_DO 61 +#define TK_FOR 62 +#define TK_IGNORE 63 +#define TK_INITIALLY 64 +#define TK_INSTEAD 65 +#define TK_NO 66 +#define TK_KEY 67 +#define TK_OF 68 +#define TK_OFFSET 69 +#define TK_PRAGMA 70 +#define TK_RAISE 71 +#define TK_RECURSIVE 72 +#define TK_REPLACE 73 +#define TK_RESTRICT 74 +#define TK_ROW 75 +#define TK_ROWS 76 +#define TK_TRIGGER 77 +#define TK_VACUUM 78 +#define TK_VIEW 79 +#define TK_VIRTUAL 80 +#define TK_WITH 81 +#define TK_NULLS 82 +#define TK_FIRST 83 +#define TK_LAST 84 +#define TK_CURRENT 85 +#define TK_FOLLOWING 86 +#define TK_PARTITION 87 +#define TK_PRECEDING 88 +#define TK_RANGE 89 +#define TK_UNBOUNDED 90 +#define TK_EXCLUDE 91 +#define TK_GROUPS 92 +#define TK_OTHERS 93 +#define TK_TIES 94 +#define TK_GENERATED 95 +#define TK_ALWAYS 96 +#define TK_REINDEX 97 +#define TK_RENAME 98 +#define TK_CTIME_KW 99 +#define TK_ANY 100 +#define TK_BITAND 101 +#define TK_BITOR 102 +#define TK_LSHIFT 103 +#define TK_RSHIFT 104 +#define TK_PLUS 105 +#define TK_MINUS 106 +#define TK_STAR 107 +#define TK_SLASH 108 +#define TK_REM 109 +#define TK_CONCAT 110 +#define TK_COLLATE 111 +#define TK_BITNOT 112 +#define TK_ON 113 +#define TK_INDEXED 114 +#define TK_STRING 115 +#define TK_JOIN_KW 116 +#define TK_CONSTRAINT 117 +#define TK_DEFAULT 118 +#define TK_NULL 119 +#define TK_PRIMARY 120 +#define TK_UNIQUE 121 +#define TK_CHECK 122 +#define TK_REFERENCES 123 +#define TK_AUTOINCR 124 +#define TK_INSERT 125 +#define TK_DELETE 126 +#define TK_UPDATE 127 +#define TK_SET 128 +#define TK_DEFERRABLE 129 +#define TK_FOREIGN 130 +#define TK_DROP 131 +#define TK_UNION 132 +#define TK_ALL 133 +#define TK_EXCEPT 134 +#define TK_INTERSECT 135 +#define TK_SELECT 136 +#define TK_VALUES 137 +#define TK_DISTINCT 138 +#define TK_DOT 139 +#define TK_FROM 140 +#define TK_JOIN 141 +#define TK_USING 142 +#define TK_ORDER 143 +#define TK_GROUP 144 +#define TK_HAVING 145 +#define TK_LIMIT 146 +#define TK_WHERE 147 +#define TK_INTO 148 +#define TK_NOTHING 149 +#define TK_FLOAT 150 +#define TK_BLOB 151 +#define TK_INTEGER 152 +#define TK_VARIABLE 153 +#define TK_CASE 154 +#define TK_WHEN 155 +#define TK_THEN 156 +#define TK_ELSE 157 +#define TK_INDEX 158 +#define TK_ALTER 159 +#define TK_ADD 160 +#define TK_WINDOW 161 +#define TK_OVER 162 +#define TK_FILTER 163 +#define TK_COLUMN 164 +#define TK_AGG_FUNCTION 165 +#define TK_AGG_COLUMN 166 +#define TK_TRUEFALSE 167 +#define TK_ISNOT 168 +#define TK_FUNCTION 169 +#define TK_UMINUS 170 +#define TK_UPLUS 171 +#define TK_TRUTH 172 +#define TK_REGISTER 173 +#define TK_VECTOR 174 +#define TK_SELECT_COLUMN 175 +#define TK_IF_NULL_ROW 176 +#define TK_ASTERISK 177 +#define TK_SPAN 178 +#define TK_SPACE 179 +#define TK_ILLEGAL 180 +#endif +/**************** End token definitions ***************************************/ /* The next sections is a series of control #defines. ** various aspects of the generated parser. @@ -155429,6 +156233,7 @@ typedef struct yyParser yyParser; #ifndef NDEBUG /* #include */ +/* #include */ static FILE *yyTraceFILE = 0; static char *yyTracePrompt = 0; #endif /* NDEBUG */ @@ -156548,7 +157353,7 @@ static YYACTIONTYPE yy_find_shift_action( #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ - assert( i>=0 && i=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) ); return yy_action[i]; } }while(1); @@ -157476,8 +158281,9 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); #ifndef NDEBUG - if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + if( yyTraceFILE ){ yysize = yyRuleInfoNRhs[yyruleno]; if( yysize ){ fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", @@ -157696,7 +158502,7 @@ static YYACTIONTYPE yy_reduce( SQLITE_IDXTYPE_UNIQUE);} break; case 39: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy202);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy202,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} break; case 40: /* ccons ::= REFERENCES nm eidlist_opt refargs */ {sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy242,yymsp[0].minor.yy192);} @@ -157775,7 +158581,7 @@ static YYACTIONTYPE yy_reduce( SQLITE_IDXTYPE_UNIQUE);} break; case 68: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy202);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy202,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} break; case 69: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { @@ -161897,7 +162703,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){ sqlite3BtreeEnterAll(db); for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( pBt && sqlite3BtreeIsInTrans(pBt) ){ + if( pBt && sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ Pager *pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerFlush(pPager); if( rc==SQLITE_BUSY ){ @@ -162241,6 +163047,36 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ return SQLITE_OK; } +/* +** Return the transaction state for a single databse, or the maximum +** transaction state over all attached databases if zSchema is null. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3 *db, const char *zSchema){ + int iDb, nDb; + int iTxn = -1; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( zSchema ){ + nDb = iDb = sqlite3FindDbName(db, zSchema); + if( iDb<0 ) nDb--; + }else{ + iDb = 0; + nDb = db->nDb-1; + } + for(; iDb<=nDb; iDb++){ + Btree *pBt = db->aDb[iDb].pBt; + int x = pBt!=0 ? sqlite3BtreeTxnState(pBt) : SQLITE_TXN_NONE; + if( x>iTxn ) iTxn = x; + } + sqlite3_mutex_leave(db->mutex); + return iTxn; +} + /* ** Two variations on the public interface for closing a database ** connection. The sqlite3_close() version returns SQLITE_BUSY and @@ -162401,7 +163237,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ for(i=0; inDb; i++){ Btree *p = db->aDb[i].pBt; if( p ){ - if( sqlite3BtreeIsInTrans(p) ){ + if( sqlite3BtreeTxnState(p)==SQLITE_TXN_WRITE ){ inTrans = 1; } sqlite3BtreeRollback(p, tripCode, !schemaChange); @@ -164822,7 +165658,9 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo } rc = SQLITE_OK; }else{ + int nSave = db->busyHandler.nBusy; rc = sqlite3OsFileControl(fd, op, pArg); + db->busyHandler.nBusy = nSave; } sqlite3BtreeLeave(pBtree); } @@ -165205,6 +166043,25 @@ SQLITE_API int sqlite3_test_control(int op, ...){ sqlite3ResultIntReal(pCtx); break; } + + /* sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT, + ** sqlite3 *db, // Database connection + ** u64 *pnSeek // Write seek count here + ** ); + ** + ** This test-control queries the seek-counter on the "main" database + ** file. The seek-counter is written into *pnSeek and is then reset. + ** The seek-count is only available if compiled with SQLITE_DEBUG. + */ + case SQLITE_TESTCTRL_SEEK_COUNT: { + sqlite3 *db = va_arg(ap, sqlite3*); + u64 *pn = va_arg(ap, sqlite3_uint64*); + *pn = sqlite3BtreeSeekCount(db->aDb->pBt); + (void)db; /* Silence harmless unused variable warning */ + break; + } + + } va_end(ap); #endif /* SQLITE_UNTESTABLE */ @@ -165440,7 +166297,7 @@ SQLITE_API int sqlite3_snapshot_get( int iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInTrans(pBt) ){ + if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); @@ -165476,10 +166333,10 @@ SQLITE_API int sqlite3_snapshot_open( iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( sqlite3BtreeIsInTrans(pBt)==0 ){ + if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ){ Pager *pPager = sqlite3BtreePager(pBt); int bUnlock = 0; - if( sqlite3BtreeIsInReadTrans(pBt) ){ + if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_NONE ){ if( db->nVdbeActive==0 ){ rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot); if( rc==SQLITE_OK ){ @@ -165528,7 +166385,7 @@ SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ + if( SQLITE_TXN_NONE==sqlite3BtreeTxnState(pBt) ){ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); @@ -188819,7 +189676,7 @@ static int nodeAcquire( ** are the leaves, and so on. If the depth as specified on the root node ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. */ - if( pNode && iNode==1 ){ + if( pNode && rc==SQLITE_OK && iNode==1 ){ pRtree->iDepth = readInt16(pNode->zData); if( pRtree->iDepth>RTREE_MAX_DEPTH ){ rc = SQLITE_CORRUPT_VTAB; @@ -193505,7 +194362,7 @@ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){ geopolyAddSegments(p, p1, 1); geopolyAddSegments(p, p2, 2); pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent); - rX = pThisEvent->x==0.0 ? -1.0 : 0.0; + rX = pThisEvent && pThisEvent->x==0.0 ? -1.0 : 0.0; memset(aOverlap, 0, sizeof(aOverlap)); while( pThisEvent ){ if( pThisEvent->x!=rX ){ @@ -208688,6 +209545,7 @@ struct Fts5Config { Fts5Tokenizer *pTok; fts5_tokenizer *pTokApi; int bLock; /* True when table is preparing statement */ + int ePattern; /* FTS_PATTERN_XXX constant */ /* Values loaded from the %_config table */ int iCookie; /* Incremented when %_config is modified */ @@ -208708,17 +209566,19 @@ struct Fts5Config { }; /* Current expected value of %_config table 'version' field */ -#define FTS5_CURRENT_VERSION 4 +#define FTS5_CURRENT_VERSION 4 #define FTS5_CONTENT_NORMAL 0 #define FTS5_CONTENT_NONE 1 #define FTS5_CONTENT_EXTERNAL 2 -#define FTS5_DETAIL_FULL 0 -#define FTS5_DETAIL_NONE 1 -#define FTS5_DETAIL_COLUMNS 2 - +#define FTS5_DETAIL_FULL 0 +#define FTS5_DETAIL_NONE 1 +#define FTS5_DETAIL_COLUMNS 2 +#define FTS5_PATTERN_NONE 0 +#define FTS5_PATTERN_LIKE 65 /* matches SQLITE_INDEX_CONSTRAINT_LIKE */ +#define FTS5_PATTERN_GLOB 66 /* matches SQLITE_INDEX_CONSTRAINT_GLOB */ static int sqlite3Fts5ConfigParse( Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char** @@ -208988,7 +209848,7 @@ static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int); /* ** Functions called by the storage module as part of integrity-check. */ -static int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum); +static int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum, int bUseCksum); /* ** Called during virtual module initialization to register UDF @@ -209058,8 +209918,7 @@ static int sqlite3Fts5GetTokenizer( Fts5Global*, const char **azArg, int nArg, - Fts5Tokenizer**, - fts5_tokenizer**, + Fts5Config*, char **pzErr ); @@ -209143,7 +210002,7 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**); static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*); static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); -static int sqlite3Fts5StorageIntegrity(Fts5Storage *p); +static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg); static int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**); static void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*); @@ -209188,11 +210047,19 @@ struct Fts5Token { /* Parse a MATCH expression. */ static int sqlite3Fts5ExprNew( Fts5Config *pConfig, + int bPhraseToAnd, int iCol, /* Column on LHS of MATCH operator */ const char *zExpr, Fts5Expr **ppNew, char **pzErr ); +static int sqlite3Fts5ExprPattern( + Fts5Config *pConfig, + int bGlob, + int iCol, + const char *zText, + Fts5Expr **pp +); /* ** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc); @@ -209301,6 +210168,10 @@ static int sqlite3Fts5AuxInit(fts5_api*); */ static int sqlite3Fts5TokenizerInit(fts5_api*); +static int sqlite3Fts5TokenizerPattern( + int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), + Fts5Tokenizer *pTok +); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ @@ -209347,6 +210218,8 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); #define FTS5_PLUS 14 #define FTS5_STAR 15 +/* This file is automatically generated by Lemon from input grammar +** source file "fts5parse.y". */ /* ** 2000-05-29 ** @@ -209371,8 +210244,6 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); ** The following is the concatenation of all %include directives from the ** input grammar file: */ -/* #include */ -/* #include */ /************ Begin %include sections from the grammar ************************/ /* #include "fts5Int.h" */ @@ -209402,11 +210273,26 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); #define fts5YYMALLOCARGTYPE u64 /**************** End of %include directives **********************************/ -/* These constants specify the various numeric values for terminal symbols -** in a format understandable to "makeheaders". This section is blank unless -** "lemon" is run with the "-m" command-line option. -***************** Begin makeheaders token definitions *************************/ -/**************** End makeheaders token definitions ***************************/ +/* These constants specify the various numeric values for terminal symbols. +***************** Begin token definitions *************************************/ +#ifndef FTS5_OR +#define FTS5_OR 1 +#define FTS5_AND 2 +#define FTS5_NOT 3 +#define FTS5_TERM 4 +#define FTS5_COLON 5 +#define FTS5_MINUS 6 +#define FTS5_LCP 7 +#define FTS5_RCP 8 +#define FTS5_STRING 9 +#define FTS5_LP 10 +#define FTS5_RP 11 +#define FTS5_CARET 12 +#define FTS5_COMMA 13 +#define FTS5_PLUS 14 +#define FTS5_STAR 15 +#endif +/**************** End token definitions ***************************************/ /* The next sections is a series of control #defines. ** various aspects of the generated parser. @@ -209689,6 +210575,7 @@ typedef struct fts5yyParser fts5yyParser; #ifndef NDEBUG /* #include */ +/* #include */ static FILE *fts5yyTraceFILE = 0; static char *fts5yyTracePrompt = 0; #endif /* NDEBUG */ @@ -210103,7 +210990,7 @@ static fts5YYACTIONTYPE fts5yy_find_shift_action( #endif /* fts5YYWILDCARD */ return fts5yy_default[stateno]; }else{ - assert( i>=0 && i=0 && i<(int)(sizeof(fts5yy_action)/sizeof(fts5yy_action[0])) ); return fts5yy_action[i]; } }while(1); @@ -210317,8 +211204,9 @@ static fts5YYACTIONTYPE fts5yy_reduce( (void)fts5yyLookahead; (void)fts5yyLookaheadToken; fts5yymsp = fts5yypParser->fts5yytos; + assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); #ifndef NDEBUG - if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){ + if( fts5yyTraceFILE ){ fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; if( fts5yysize ){ fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", @@ -211383,7 +212271,7 @@ static int fts5Bm25GetData( int rc = SQLITE_OK; /* Return code */ Fts5Bm25Data *p; /* Object to return */ - p = pApi->xGetAuxdata(pFts, 0); + p = (Fts5Bm25Data*)pApi->xGetAuxdata(pFts, 0); if( p==0 ){ int nPhrase; /* Number of phrases in query */ sqlite3_int64 nRow = 0; /* Number of rows in table */ @@ -211457,7 +212345,7 @@ static void fts5Bm25Function( ){ const double k1 = 1.2; /* Constant "k1" from BM25 formula */ const double b = 0.75; /* Constant "b" from BM25 formula */ - int rc = SQLITE_OK; /* Error code */ + int rc; /* Error code */ double score = 0.0; /* SQL function return value */ Fts5Bm25Data *pData; /* Values allocated/calculated once only */ int i; /* Iterator variable */ @@ -211489,17 +212377,15 @@ static void fts5Bm25Function( D = (double)nTok; } - /* Determine the BM25 score for the current row. */ - for(i=0; rc==SQLITE_OK && inPhrase; i++){ - score += pData->aIDF[i] * ( - ( aFreq[i] * (k1 + 1.0) ) / - ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) ) - ); - } - - /* If no error has occurred, return the calculated score. Otherwise, - ** throw an SQL exception. */ + /* Determine and return the BM25 score for the current row. Or, if an + ** error has occurred, throw an exception. */ if( rc==SQLITE_OK ){ + for(i=0; inPhrase; i++){ + score += pData->aIDF[i] * ( + ( aFreq[i] * (k1 + 1.0) ) / + ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) ) + ); + } sqlite3_result_double(pCtx, -1.0 * score); }else{ sqlite3_result_error_code(pCtx, rc); @@ -212263,7 +213149,7 @@ static int fts5ConfigParseSpecial( rc = SQLITE_ERROR; }else{ rc = sqlite3Fts5GetTokenizer(pGlobal, - (const char**)azArg, (int)nArg, &pConfig->pTok, &pConfig->pTokApi, + (const char**)azArg, (int)nArg, pConfig, pzErr ); } @@ -212335,9 +213221,7 @@ static int fts5ConfigParseSpecial( */ static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){ assert( pConfig->pTok==0 && pConfig->pTokApi==0 ); - return sqlite3Fts5GetTokenizer( - pGlobal, 0, 0, &pConfig->pTok, &pConfig->pTokApi, 0 - ); + return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0); } /* @@ -213029,6 +213913,7 @@ struct Fts5Parse { int nPhrase; /* Size of apPhrase array */ Fts5ExprPhrase **apPhrase; /* Array of all phrases */ Fts5ExprNode *pExpr; /* Result of a successful parse */ + int bPhraseToAnd; /* Convert "a+b" to "a AND b" */ }; static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){ @@ -213117,6 +214002,7 @@ static void fts5ParseFree(void *p){ sqlite3_free(p); } static int sqlite3Fts5ExprNew( Fts5Config *pConfig, /* FTS5 Configuration */ + int bPhraseToAnd, int iCol, const char *zExpr, /* Expression text */ Fts5Expr **ppNew, @@ -213132,6 +214018,7 @@ static int sqlite3Fts5ExprNew( *ppNew = 0; *pzErr = 0; memset(&sParse, 0, sizeof(sParse)); + sParse.bPhraseToAnd = bPhraseToAnd; pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc); if( pEngine==0 ){ return SQLITE_NOMEM; } sParse.pConfig = pConfig; @@ -213174,6 +214061,7 @@ static int sqlite3Fts5ExprNew( pNew->pConfig = pConfig; pNew->apExprPhrase = sParse.apPhrase; pNew->nPhrase = sParse.nPhrase; + pNew->bDesc = 0; sParse.apPhrase = 0; } }else{ @@ -213185,6 +214073,81 @@ static int sqlite3Fts5ExprNew( return sParse.rc; } +/* +** This function is only called when using the special 'trigram' tokenizer. +** Argument zText contains the text of a LIKE or GLOB pattern matched +** against column iCol. This function creates and compiles an FTS5 MATCH +** expression that will match a superset of the rows matched by the LIKE or +** GLOB. If successful, SQLITE_OK is returned. Otherwise, an SQLite error +** code. +*/ +static int sqlite3Fts5ExprPattern( + Fts5Config *pConfig, int bGlob, int iCol, const char *zText, Fts5Expr **pp +){ + i64 nText = strlen(zText); + char *zExpr = (char*)sqlite3_malloc64(nText*4 + 1); + int rc = SQLITE_OK; + + if( zExpr==0 ){ + rc = SQLITE_NOMEM; + }else{ + char aSpec[3]; + int iOut = 0; + int i = 0; + int iFirst = 0; + + if( bGlob==0 ){ + aSpec[0] = '_'; + aSpec[1] = '%'; + aSpec[2] = 0; + }else{ + aSpec[0] = '*'; + aSpec[1] = '?'; + aSpec[2] = '['; + } + + while( i<=nText ){ + if( i==nText + || zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2] + ){ + if( i-iFirst>=3 ){ + int jj; + zExpr[iOut++] = '"'; + for(jj=iFirst; jj0 ){ + int bAnd = 0; + if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ + bAnd = 1; + if( pConfig->eDetail==FTS5_DETAIL_NONE ){ + iCol = pConfig->nCol; + } + } + zExpr[iOut] = '\0'; + rc = sqlite3Fts5ExprNew(pConfig, bAnd, iCol, zExpr, pp,pConfig->pzErrmsg); + }else{ + *pp = 0; + } + sqlite3_free(zExpr); + } + + return rc; +} + /* ** Free the expression node object passed as the only argument. */ @@ -214562,6 +215525,20 @@ static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){ pParse->pExpr = p; } +static int parseGrowPhraseArray(Fts5Parse *pParse){ + if( (pParse->nPhrase % 8)==0 ){ + sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8); + Fts5ExprPhrase **apNew; + apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte); + if( apNew==0 ){ + pParse->rc = SQLITE_NOMEM; + return SQLITE_NOMEM; + } + pParse->apPhrase = apNew; + } + return SQLITE_OK; +} + /* ** This function is called by the parser to process a string token. The ** string may or may not be quoted. In any case it is tokenized and a @@ -214597,16 +215574,9 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( }else{ if( pAppend==0 ){ - if( (pParse->nPhrase % 8)==0 ){ - sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8); - Fts5ExprPhrase **apNew; - apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte); - if( apNew==0 ){ - pParse->rc = SQLITE_NOMEM; - fts5ExprPhraseFree(sCtx.pPhrase); - return 0; - } - pParse->apPhrase = apNew; + if( parseGrowPhraseArray(pParse) ){ + fts5ExprPhraseFree(sCtx.pPhrase); + return 0; } pParse->nPhrase++; } @@ -215013,6 +215983,67 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ } } +/* +** This function is used when parsing LIKE or GLOB patterns against +** trigram indexes that specify either detail=column or detail=none. +** It converts a phrase: +** +** abc + def + ghi +** +** into an AND tree: +** +** abc AND def AND ghi +*/ +static Fts5ExprNode *fts5ParsePhraseToAnd( + Fts5Parse *pParse, + Fts5ExprNearset *pNear +){ + int nTerm = pNear->apPhrase[0]->nTerm; + int ii; + int nByte; + Fts5ExprNode *pRet; + + assert( pNear->nPhrase==1 ); + assert( pParse->bPhraseToAnd ); + + nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*); + pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); + if( pRet ){ + pRet->eType = FTS5_AND; + pRet->nChild = nTerm; + fts5ExprAssignXNext(pRet); + pParse->nPhrase--; + for(ii=0; iirc, sizeof(Fts5ExprPhrase) + ); + if( pPhrase ){ + if( parseGrowPhraseArray(pParse) ){ + fts5ExprPhraseFree(pPhrase); + }else{ + pParse->apPhrase[pParse->nPhrase++] = pPhrase; + pPhrase->nTerm = 1; + pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup( + &pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1 + ); + pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING, + 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase) + ); + } + } + } + + if( pParse->rc ){ + sqlite3Fts5ParseNodeFree(pRet); + pRet = 0; + }else{ + sqlite3Fts5ParseNearsetFree(pNear); + } + } + + return pRet; +} + /* ** Allocate and return a new expression object. If anything goes wrong (i.e. ** OOM error), leave an error code in pParse and return NULL. @@ -215037,51 +216068,58 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( if( eType!=FTS5_STRING && pLeft==0 ) return pRight; if( eType!=FTS5_STRING && pRight==0 ) return pLeft; - if( eType==FTS5_NOT ){ - nChild = 2; - }else if( eType==FTS5_AND || eType==FTS5_OR ){ - nChild = 2; - if( pLeft->eType==eType ) nChild += pLeft->nChild-1; - if( pRight->eType==eType ) nChild += pRight->nChild-1; - } + if( eType==FTS5_STRING + && pParse->bPhraseToAnd + && pNear->apPhrase[0]->nTerm>1 + ){ + pRet = fts5ParsePhraseToAnd(pParse, pNear); + }else{ + if( eType==FTS5_NOT ){ + nChild = 2; + }else if( eType==FTS5_AND || eType==FTS5_OR ){ + nChild = 2; + if( pLeft->eType==eType ) nChild += pLeft->nChild-1; + if( pRight->eType==eType ) nChild += pRight->nChild-1; + } - nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); - pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); + nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); + pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); - if( pRet ){ - pRet->eType = eType; - pRet->pNear = pNear; - fts5ExprAssignXNext(pRet); - if( eType==FTS5_STRING ){ - int iPhrase; - for(iPhrase=0; iPhrasenPhrase; iPhrase++){ - pNear->apPhrase[iPhrase]->pNode = pRet; - if( pNear->apPhrase[iPhrase]->nTerm==0 ){ - pRet->xNext = 0; - pRet->eType = FTS5_EOF; + if( pRet ){ + pRet->eType = eType; + pRet->pNear = pNear; + fts5ExprAssignXNext(pRet); + if( eType==FTS5_STRING ){ + int iPhrase; + for(iPhrase=0; iPhrasenPhrase; iPhrase++){ + pNear->apPhrase[iPhrase]->pNode = pRet; + if( pNear->apPhrase[iPhrase]->nTerm==0 ){ + pRet->xNext = 0; + pRet->eType = FTS5_EOF; + } } - } - if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){ - Fts5ExprPhrase *pPhrase = pNear->apPhrase[0]; - if( pNear->nPhrase!=1 - || pPhrase->nTerm>1 - || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) - ){ - assert( pParse->rc==SQLITE_OK ); - pParse->rc = SQLITE_ERROR; - assert( pParse->zErr==0 ); - pParse->zErr = sqlite3_mprintf( - "fts5: %s queries are not supported (detail!=full)", - pNear->nPhrase==1 ? "phrase": "NEAR" - ); - sqlite3_free(pRet); - pRet = 0; + if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){ + Fts5ExprPhrase *pPhrase = pNear->apPhrase[0]; + if( pNear->nPhrase!=1 + || pPhrase->nTerm>1 + || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) + ){ + assert( pParse->rc==SQLITE_OK ); + pParse->rc = SQLITE_ERROR; + assert( pParse->zErr==0 ); + pParse->zErr = sqlite3_mprintf( + "fts5: %s queries are not supported (detail!=full)", + pNear->nPhrase==1 ? "phrase": "NEAR" + ); + sqlite3_free(pRet); + pRet = 0; + } } + }else{ + fts5ExprAddChildren(pRet, pLeft); + fts5ExprAddChildren(pRet, pRight); } - }else{ - fts5ExprAddChildren(pRet, pLeft); - fts5ExprAddChildren(pRet, pRight); } } } @@ -215302,8 +216340,17 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){ int iTerm; if( pNear->pColset ){ - int iCol = pNear->pColset->aiCol[0]; - zRet = fts5PrintfAppend(zRet, "%s : ", pConfig->azCol[iCol]); + int ii; + Fts5Colset *pColset = pNear->pColset; + if( pColset->nCol>1 ) zRet = fts5PrintfAppend(zRet, "{"); + for(ii=0; iinCol; ii++){ + zRet = fts5PrintfAppend(zRet, "%s%s", + pConfig->azCol[pColset->aiCol[ii]], ii==pColset->nCol-1 ? "" : " " + ); + } + if( zRet ){ + zRet = fts5PrintfAppend(zRet, "%s : ", pColset->nCol>1 ? "}" : ""); + } if( zRet==0 ) return 0; } @@ -215426,7 +216473,7 @@ static void fts5ExprFunction( rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr); + rc = sqlite3Fts5ExprNew(pConfig, 0, pConfig->nCol, zExpr, &pExpr, &zErr); } if( rc==SQLITE_OK ){ char *zText; @@ -216099,7 +217146,6 @@ static int sqlite3Fts5HashWrite( p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1); } - nIncr += p->nData; }else{ /* Appending to an existing hash-entry. Check that there is enough @@ -216132,8 +217178,9 @@ static int sqlite3Fts5HashWrite( /* If this is a new rowid, append the 4-byte size field for the previous ** entry, and the new rowid for this entry. */ if( iRowid!=p->iRowid ){ + u64 iDiff = (u64)iRowid - (u64)p->iRowid; fts5HashAddPoslistSize(pHash, p, 0); - p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid); + p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iDiff); p->iRowid = iRowid; bNew = 1; p->iSzPoslist = p->nData; @@ -218108,7 +219155,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){ ASSERT_SZLEAF_OK(pIter->pLeaf); while( 1 ){ - i64 iDelta = 0; + u64 iDelta = 0; if( eDetail==FTS5_DETAIL_NONE ){ /* todo */ @@ -218123,7 +219170,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){ i += nPos; } if( i>=n ) break; - i += fts5GetVarint(&a[i], (u64*)&iDelta); + i += fts5GetVarint(&a[i], &iDelta); pIter->iRowid += iDelta; /* If necessary, grow the pIter->aRowidOffset[] array. */ @@ -218222,7 +219269,7 @@ static void fts5SegIterNext_Reverse( if( pIter->iRowidOffset>0 ){ u8 *a = pIter->pLeaf->p; int iOff; - i64 iDelta; + u64 iDelta; pIter->iRowidOffset--; pIter->iLeafOffset = pIter->aRowidOffset[pIter->iRowidOffset]; @@ -218231,7 +219278,7 @@ static void fts5SegIterNext_Reverse( if( p->pConfig->eDetail!=FTS5_DETAIL_NONE ){ iOff += pIter->nPos; } - fts5GetVarint(&a[iOff], (u64*)&iDelta); + fts5GetVarint(&a[iOff], &iDelta); pIter->iRowid -= iDelta; }else{ fts5SegIterReverseNewPage(p, pIter); @@ -221351,7 +222398,9 @@ static void fts5MergePrefixLists( ** at most 20 bytes of unexpected space. */ fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferZero(&tmp); - sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10); + sqlite3Fts5BufferSize(&p->rc, &tmp, + i1.nPoslist + i2.nPoslist + 10 + 10 + FTS5_DATA_ZERO_PADDING + ); if( p->rc ) break; sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); @@ -221425,9 +222474,10 @@ static void fts5MergePrefixLists( } assert_nc( out.n<=(p1->n+p2->n+9) ); - fts5BufferSet(&p->rc, p1, out.n, out.p); + fts5BufferFree(p1); fts5BufferFree(&tmp); - fts5BufferFree(&out); + memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING); + *p1 = out; } } @@ -222413,7 +223463,7 @@ static void fts5IndexIntegrityCheckSegment( ** error, or some other SQLite error code if another error (e.g. OOM) ** occurs. */ -static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ +static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){ int eDetail = p->pConfig->eDetail; u64 cksum2 = 0; /* Checksum based on contents of indexes */ Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */ @@ -222474,6 +223524,7 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ }else{ poslist.n = 0; fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist); + fts5BufferAppendBlob(&p->rc, &poslist, 4, (const u8*)"\0\0\0\0"); while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){ int iCol = FTS5_POS2COLUMN(iPos); int iTokOff = FTS5_POS2OFFSET(iPos); @@ -222484,7 +223535,7 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3); fts5MultiIterFree(pIter); - if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT; + if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ) p->rc = FTS5_CORRUPT; fts5StructureRelease(pStruct); #ifdef SQLITE_DEBUG @@ -223448,6 +224499,23 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ #endif } +static int fts5UsePatternMatch( + Fts5Config *pConfig, + struct sqlite3_index_constraint *p +){ + assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); + assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); + if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ + return 1; + } + if( pConfig->ePattern==FTS5_PATTERN_LIKE + && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB) + ){ + return 1; + } + return 0; +} + /* ** Implementation of the xBestIndex method for FTS5 tables. Within the ** WHERE constraint, it searches for the following: @@ -223477,7 +224545,9 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ ** ** Match against table column: "m" ** Match against rank column: "r" -** Match against other column: "" +** Match against other column: "M" +** LIKE against other column: "L" +** GLOB against other column: "G" ** Equality constraint against the rowid: "=" ** A < or <= against the rowid: "<" ** A > or >= against the rowid: ">" @@ -223538,7 +224608,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ return SQLITE_ERROR; } - idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1); + idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1); if( idxStr==0 ) return SQLITE_NOMEM; pInfo->idxStr = idxStr; pInfo->needToFreeIdxStr = 1; @@ -223562,25 +224632,29 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ if( bSeenRank ) continue; idxStr[iIdxStr++] = 'r'; bSeenRank = 1; - }else{ + }else if( iCol>=0 ){ bSeenMatch = 1; - idxStr[iIdxStr++] = 'm'; - if( iColaConstraintUsage[i].argvIndex = ++iCons; pInfo->aConstraintUsage[i].omit = 1; } - } - else if( p->usable && bSeenEq==0 - && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 - ){ - idxStr[iIdxStr++] = '='; - bSeenEq = 1; - pInfo->aConstraintUsage[i].argvIndex = ++iCons; + }else if( p->usable ){ + if( iCol>=0 && iColop==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB ); + idxStr[iIdxStr++] = p->op==FTS5_PATTERN_LIKE ? 'L' : 'G'; + sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); + idxStr += strlen(&idxStr[iIdxStr]); + pInfo->aConstraintUsage[i].argvIndex = ++iCons; + assert( idxStr[iIdxStr]=='\0' ); + }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ + idxStr[iIdxStr++] = '='; + bSeenEq = 1; + pInfo->aConstraintUsage[i].argvIndex = ++iCons; + } } } @@ -224213,19 +225287,14 @@ static int fts5FilterMethod( case 'r': pRank = apVal[i]; break; - case 'm': { + case 'M': { const char *zText = (const char*)sqlite3_value_text(apVal[i]); if( zText==0 ) zText = ""; - - if( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ){ - iCol = 0; - do{ - iCol = iCol*10 + (idxStr[iIdxStr]-'0'); - iIdxStr++; - }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); - }else{ - iCol = pConfig->nCol; - } + iCol = 0; + do{ + iCol = iCol*10 + (idxStr[iIdxStr]-'0'); + iIdxStr++; + }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); if( zText[0]=='*' ){ /* The user has issued a query of the form "MATCH '*...'". This @@ -224235,7 +225304,7 @@ static int fts5FilterMethod( goto filter_out; }else{ char **pzErr = &pTab->p.base.zErrMsg; - rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr); + rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); pExpr = 0; @@ -224245,6 +225314,25 @@ static int fts5FilterMethod( break; } + case 'L': + case 'G': { + int bGlob = (idxStr[iIdxStr-1]=='G'); + const char *zText = (const char*)sqlite3_value_text(apVal[i]); + iCol = 0; + do{ + iCol = iCol*10 + (idxStr[iIdxStr]-'0'); + iIdxStr++; + }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); + if( zText ){ + rc = sqlite3Fts5ExprPattern(pConfig, bGlob, iCol, zText, &pExpr); + } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); + pExpr = 0; + } + if( rc!=SQLITE_OK ) goto filter_out; + break; + } case '=': pRowidEq = apVal[i]; break; @@ -224492,7 +225580,8 @@ static int fts5SpecialInsert( int nMerge = sqlite3_value_int(pVal); rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge); }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){ - rc = sqlite3Fts5StorageIntegrity(pTab->pStorage); + int iArg = sqlite3_value_int(pVal); + rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, iArg); #ifdef SQLITE_DEBUG }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){ pConfig->bPrefixIndex = sqlite3_value_int(pVal); @@ -225655,8 +226744,7 @@ static int sqlite3Fts5GetTokenizer( Fts5Global *pGlobal, const char **azArg, int nArg, - Fts5Tokenizer **ppTok, - fts5_tokenizer **ppTokApi, + Fts5Config *pConfig, char **pzErr ){ Fts5TokenizerModule *pMod; @@ -225668,16 +226756,22 @@ static int sqlite3Fts5GetTokenizer( rc = SQLITE_ERROR; *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); }else{ - rc = pMod->x.xCreate(pMod->pUserData, &azArg[1], (nArg?nArg-1:0), ppTok); - *ppTokApi = &pMod->x; - if( rc!=SQLITE_OK && pzErr ){ - *pzErr = sqlite3_mprintf("error in tokenizer constructor"); + rc = pMod->x.xCreate( + pMod->pUserData, &azArg[1], (nArg?nArg-1:0), &pConfig->pTok + ); + pConfig->pTokApi = &pMod->x; + if( rc!=SQLITE_OK ){ + if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor"); + }else{ + pConfig->ePattern = sqlite3Fts5TokenizerPattern( + pMod->x.xCreate, pConfig->pTok + ); } } if( rc!=SQLITE_OK ){ - *ppTokApi = 0; - *ppTok = 0; + pConfig->pTokApi = 0; + pConfig->pTok = 0; } return rc; @@ -225726,7 +226820,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b", -1, SQLITE_TRANSIENT); } /* @@ -226289,9 +227383,16 @@ static int fts5StorageDeleteFromIndex( zText, nText, (void*)&ctx, fts5StorageInsertCallback ); p->aTotalSize[iCol-1] -= (i64)ctx.szCol; + if( p->aTotalSize[iCol-1]<0 ){ + rc = FTS5_CORRUPT; + } } } - p->nTotalRow--; + if( rc==SQLITE_OK && p->nTotalRow<1 ){ + rc = FTS5_CORRUPT; + }else{ + p->nTotalRow--; + } rc2 = sqlite3_reset(pSeek); if( rc==SQLITE_OK ) rc = rc2; @@ -226734,13 +227835,14 @@ static int fts5StorageIntegrityCallback( ** some other SQLite error code if an error occurs while attempting to ** determine this. */ -static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ +static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){ Fts5Config *pConfig = p->pConfig; - int rc; /* Return code */ + int rc = SQLITE_OK; /* Return code */ int *aColSize; /* Array of size pConfig->nCol */ i64 *aTotalSize; /* Array of size pConfig->nCol */ Fts5IntegrityCtx ctx; sqlite3_stmt *pScan; + int bUseCksum; memset(&ctx, 0, sizeof(Fts5IntegrityCtx)); ctx.pConfig = p->pConfig; @@ -226749,83 +227851,88 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ aColSize = (int*)&aTotalSize[pConfig->nCol]; memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol); - /* Generate the expected index checksum based on the contents of the - ** %_content table. This block stores the checksum in ctx.cksum. */ - rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); - if( rc==SQLITE_OK ){ - int rc2; - while( SQLITE_ROW==sqlite3_step(pScan) ){ - int i; - ctx.iRowid = sqlite3_column_int64(pScan, 0); - ctx.szCol = 0; - if( pConfig->bColumnsize ){ - rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize); - } - if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){ - rc = sqlite3Fts5TermsetNew(&ctx.pTermset); - } - for(i=0; rc==SQLITE_OK && inCol; i++){ - if( pConfig->abUnindexed[i] ) continue; - ctx.iCol = i; + bUseCksum = (pConfig->eContent==FTS5_CONTENT_NORMAL + || (pConfig->eContent==FTS5_CONTENT_EXTERNAL && iArg) + ); + if( bUseCksum ){ + /* Generate the expected index checksum based on the contents of the + ** %_content table. This block stores the checksum in ctx.cksum. */ + rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); + if( rc==SQLITE_OK ){ + int rc2; + while( SQLITE_ROW==sqlite3_step(pScan) ){ + int i; + ctx.iRowid = sqlite3_column_int64(pScan, 0); ctx.szCol = 0; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - rc = sqlite3Fts5TermsetNew(&ctx.pTermset); + if( pConfig->bColumnsize ){ + rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize); } - if( rc==SQLITE_OK ){ - const char *zText = (const char*)sqlite3_column_text(pScan, i+1); - int nText = sqlite3_column_bytes(pScan, i+1); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageIntegrityCallback - ); - } - if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ - rc = FTS5_CORRUPT; + if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){ + rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } - aTotalSize[i] += ctx.szCol; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - sqlite3Fts5TermsetFree(ctx.pTermset); - ctx.pTermset = 0; + for(i=0; rc==SQLITE_OK && inCol; i++){ + if( pConfig->abUnindexed[i] ) continue; + ctx.iCol = i; + ctx.szCol = 0; + if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + rc = sqlite3Fts5TermsetNew(&ctx.pTermset); + } + if( rc==SQLITE_OK ){ + const char *zText = (const char*)sqlite3_column_text(pScan, i+1); + int nText = sqlite3_column_bytes(pScan, i+1); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, + zText, nText, + (void*)&ctx, + fts5StorageIntegrityCallback + ); + } + if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ + rc = FTS5_CORRUPT; + } + aTotalSize[i] += ctx.szCol; + if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + sqlite3Fts5TermsetFree(ctx.pTermset); + ctx.pTermset = 0; + } } - } - sqlite3Fts5TermsetFree(ctx.pTermset); - ctx.pTermset = 0; + sqlite3Fts5TermsetFree(ctx.pTermset); + ctx.pTermset = 0; - if( rc!=SQLITE_OK ) break; + if( rc!=SQLITE_OK ) break; + } + rc2 = sqlite3_reset(pScan); + if( rc==SQLITE_OK ) rc = rc2; } - rc2 = sqlite3_reset(pScan); - if( rc==SQLITE_OK ) rc = rc2; - } - /* Test that the "totals" (sometimes called "averages") record looks Ok */ - if( rc==SQLITE_OK ){ - int i; - rc = fts5StorageLoadTotals(p, 0); - for(i=0; rc==SQLITE_OK && inCol; i++){ - if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT; + /* Test that the "totals" (sometimes called "averages") record looks Ok */ + if( rc==SQLITE_OK ){ + int i; + rc = fts5StorageLoadTotals(p, 0); + for(i=0; rc==SQLITE_OK && inCol; i++){ + if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT; + } } - } - /* Check that the %_docsize and %_content tables contain the expected - ** number of rows. */ - if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ - i64 nRow = 0; - rc = fts5StorageCount(p, "content", &nRow); - if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; - } - if( rc==SQLITE_OK && pConfig->bColumnsize ){ - i64 nRow = 0; - rc = fts5StorageCount(p, "docsize", &nRow); - if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; + /* Check that the %_docsize and %_content tables contain the expected + ** number of rows. */ + if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ + i64 nRow = 0; + rc = fts5StorageCount(p, "content", &nRow); + if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; + } + if( rc==SQLITE_OK && pConfig->bColumnsize ){ + i64 nRow = 0; + rc = fts5StorageCount(p, "docsize", &nRow); + if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; + } } /* Pass the expected checksum down to the FTS index module. It will ** verify, amongst other things, that it matches the checksum generated by ** inspecting the index itself. */ if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum); + rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum, bUseCksum); } sqlite3_free(aTotalSize); @@ -228267,6 +229374,133 @@ static int fts5PorterTokenize( ); } +/************************************************************************** +** Start of trigram implementation. +*/ +typedef struct TrigramTokenizer TrigramTokenizer; +struct TrigramTokenizer { + int bFold; /* True to fold to lower-case */ +}; + +/* +** Free a trigram tokenizer. +*/ +static void fts5TriDelete(Fts5Tokenizer *p){ + sqlite3_free(p); +} + +/* +** Allocate a trigram tokenizer. +*/ +static int fts5TriCreate( + void *pUnused, + const char **azArg, + int nArg, + Fts5Tokenizer **ppOut +){ + int rc = SQLITE_OK; + TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); + UNUSED_PARAM(pUnused); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + int i; + pNew->bFold = 1; + for(i=0; rc==SQLITE_OK && ibFold = (zArg[0]=='0'); + } + }else{ + rc = SQLITE_ERROR; + } + } + if( rc!=SQLITE_OK ){ + fts5TriDelete((Fts5Tokenizer*)pNew); + pNew = 0; + } + } + *ppOut = (Fts5Tokenizer*)pNew; + return rc; +} + +/* +** Trigram tokenizer tokenize routine. +*/ +static int fts5TriTokenize( + Fts5Tokenizer *pTok, + void *pCtx, + int unusedFlags, + const char *pText, int nText, + int (*xToken)(void*, int, const char*, int, int, int) +){ + TrigramTokenizer *p = (TrigramTokenizer*)pTok; + int rc = SQLITE_OK; + char aBuf[32]; + const unsigned char *zIn = (const unsigned char*)pText; + const unsigned char *zEof = &zIn[nText]; + u32 iCode; + + UNUSED_PARAM(unusedFlags); + while( 1 ){ + char *zOut = aBuf; + int iStart = zIn - (const unsigned char*)pText; + const unsigned char *zNext; + + READ_UTF8(zIn, zEof, iCode); + if( iCode==0 ) break; + zNext = zIn; + if( zInbFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); + WRITE_UTF8(zOut, iCode); + READ_UTF8(zIn, zEof, iCode); + if( iCode==0 ) break; + }else{ + break; + } + if( zInbFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); + WRITE_UTF8(zOut, iCode); + READ_UTF8(zIn, zEof, iCode); + if( iCode==0 ) break; + if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); + WRITE_UTF8(zOut, iCode); + }else{ + break; + } + rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf); + if( rc!=SQLITE_OK ) break; + zIn = zNext; + } + + return rc; +} + +/* +** Argument xCreate is a pointer to a constructor function for a tokenizer. +** pTok is a tokenizer previously created using the same method. This function +** returns one of FTS5_PATTERN_NONE, FTS5_PATTERN_LIKE or FTS5_PATTERN_GLOB +** indicating the style of pattern matching that the tokenizer can support. +** In practice, this is: +** +** "trigram" tokenizer, case_sensitive=1 - FTS5_PATTERN_GLOB +** "trigram" tokenizer, case_sensitive=0 (the default) - FTS5_PATTERN_LIKE +** all other tokenizers - FTS5_PATTERN_NONE +*/ +static int sqlite3Fts5TokenizerPattern( + int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), + Fts5Tokenizer *pTok +){ + if( xCreate==fts5TriCreate ){ + TrigramTokenizer *p = (TrigramTokenizer*)pTok; + return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; + } + return FTS5_PATTERN_NONE; +} + /* ** Register all built-in tokenizers with FTS5. */ @@ -228278,6 +229512,7 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}}, { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }}, + { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}}, }; int rc = SQLITE_OK; /* Return code */ @@ -229070,8 +230305,10 @@ static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ } iTbl++; } + aAscii[0] = 0; /* 0x00 is never a token character */ } + /* ** 2015 May 30 ** @@ -230509,9 +231746,9 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=230511 +#if __LINE__!=231748 #undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0alt2" +#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089falt2" #endif /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h index 983bc41513a9c..cc3b023bfa9a4 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h @@ -124,9 +124,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.33.0" -#define SQLITE_VERSION_NUMBER 3033000 -#define SQLITE_SOURCE_ID "2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f" +#define SQLITE_VERSION "3.34.0" +#define SQLITE_VERSION_NUMBER 3034000 +#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -505,6 +505,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) +#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) @@ -6187,6 +6188,57 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); */ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); +/* +** CAPI3REF: Determine the transaction state of a database +** METHOD: sqlite3 +** +** ^The sqlite3_txn_state(D,S) interface returns the current +** [transaction state] of schema S in database connection D. ^If S is NULL, +** then the highest transaction state of any schema on database connection D +** is returned. Transaction states are (in order of lowest to highest): +**
    +**
  1. SQLITE_TXN_NONE +**
  2. SQLITE_TXN_READ +**
  3. SQLITE_TXN_WRITE +**
+** ^If the S argument to sqlite3_txn_state(D,S) is not the name of +** a valid schema, then -1 is returned. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); + +/* +** CAPI3REF: Allowed return values from [sqlite3_txn_state()] +** KEYWORDS: {transaction state} +** +** These constants define the current transaction state of a database file. +** ^The [sqlite3_txn_state(D,S)] interface returns one of these +** constants in order to describe the transaction state of schema S +** in [database connection] D. +** +**
+** [[SQLITE_TXN_NONE]]
SQLITE_TXN_NONE
+**
The SQLITE_TXN_NONE state means that no transaction is currently +** pending.
+** +** [[SQLITE_TXN_READ]]
SQLITE_TXN_READ
+**
The SQLITE_TXN_READ state means that the database is currently +** in a read transaction. Content has been read from the database file +** but nothing in the database file has changed. The transaction state +** will advanced to SQLITE_TXN_WRITE if any changes occur and there are +** no other conflicting concurrent write transactions. The transaction +** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or +** [COMMIT].
+** +** [[SQLITE_TXN_WRITE]]
SQLITE_TXN_WRITE
+**
The SQLITE_TXN_WRITE state means that the database is currently +** in a write transaction. Content has been written to the database file +** but has not yet committed. The transaction state will change to +** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
+*/ +#define SQLITE_TXN_NONE 0 +#define SQLITE_TXN_READ 1 +#define SQLITE_TXN_WRITE 2 + /* ** CAPI3REF: Find the next prepared statement ** METHOD: sqlite3 @@ -7713,7 +7765,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESULT_INTREAL 27 #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 -#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_SEEK_COUNT 30 +#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -9193,10 +9246,11 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE ** ** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] -** method of a [virtual table], then it returns true if and only if the +** method of a [virtual table], then it might return true if the ** column is being fetched as part of an UPDATE operation during which the -** column value will not change. Applications might use this to substitute -** a return value that is less expensive to compute and that the corresponding +** column value will not change. The virtual table implementation can use +** this hint as permission to substitute a return value that is less +** expensive to compute and that the corresponding ** [xUpdate] method understands as a "no-change" value. ** ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that @@ -9205,6 +9259,12 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. ** In that case, [sqlite3_value_nochange(X)] will return true for the ** same column in the [xUpdate] method. +** +** The sqlite3_vtab_nochange() routine is an optimization. Virtual table +** implementations should continue to give a correct answer even if the +** sqlite3_vtab_nochange() interface were to always return false. In the +** current implementation, the sqlite3_vtab_nochange() interface does always +** returns false for the enhanced [UPDATE FROM] statement. */ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); @@ -9346,6 +9406,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction +** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty @@ -9378,6 +9439,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); /* ** CAPI3REF: The pre-update hook. +** METHOD: sqlite3 ** ** ^These interfaces are only available if SQLite is compiled using the ** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. @@ -9418,7 +9480,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback ** function is not defined for operations on WITHOUT ROWID tables, or for -** INSERT operations on rowid tables. +** DELETE operations on rowid tables. ** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces @@ -9480,6 +9542,7 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); /* ** CAPI3REF: Low-level system error code +** METHOD: sqlite3 ** ** ^Attempt to return the underlying operating system error code or error ** number that caused the most recent I/O error or failure to open a file. diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3.go b/vendor/github.com/mattn/go-sqlite3/sqlite3.go index 63e1c4f7e51af..d1ff406375672 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3.go +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3.go @@ -15,10 +15,8 @@ package sqlite3 #cgo CFLAGS: -DHAVE_USLEEP=1 #cgo CFLAGS: -DSQLITE_ENABLE_FTS3 #cgo CFLAGS: -DSQLITE_ENABLE_FTS3_PARENTHESIS -#cgo CFLAGS: -DSQLITE_ENABLE_FTS4_UNICODE61 #cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15 #cgo CFLAGS: -DSQLITE_OMIT_DEPRECATED -#cgo CFLAGS: -DSQLITE_DISABLE_INTRINSIC #cgo CFLAGS: -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 #cgo CFLAGS: -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT #cgo CFLAGS: -Wno-deprecated-declarations @@ -1041,6 +1039,8 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { secureDelete := "DEFAULT" synchronousMode := "NORMAL" writableSchema := -1 + vfsName := "" + var cacheSize *int64 pos := strings.IndexRune(dsn, '?') if pos >= 1 { @@ -1364,6 +1364,22 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { } } + // Cache size (_cache_size) + // + // https://sqlite.org/pragma.html#pragma_cache_size + // + if val := params.Get("_cache_size"); val != "" { + iv, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return nil, fmt.Errorf("Invalid _cache_size: %v: %v", val, err) + } + cacheSize = &iv + } + + if val := params.Get("vfs"); val != "" { + vfsName = val + } + if !strings.HasPrefix(dsn, "file:") { dsn = dsn[:pos] } @@ -1372,9 +1388,14 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { var db *C.sqlite3 name := C.CString(dsn) defer C.free(unsafe.Pointer(name)) + var vfs *C.char + if vfsName != "" { + vfs = C.CString(vfsName) + defer C.free(unsafe.Pointer(vfs)) + } rv := C._sqlite3_open_v2(name, &db, mutex|C.SQLITE_OPEN_READWRITE|C.SQLITE_OPEN_CREATE, - nil) + vfs) if rv != 0 { // Save off the error _before_ closing the database. // This is safe even if db is nil. @@ -1667,6 +1688,14 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { } } + // Cache Size + if cacheSize != nil { + if err := exec(fmt.Sprintf("PRAGMA cache_size = %d;", *cacheSize)); err != nil { + C.sqlite3_close_v2(db) + return nil, err + } + } + if len(d.Extensions) > 0 { if err := conn.loadExtensions(d.Extensions); err != nil { conn.Close() diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go index c0a6214e5d25d..8fd6cdffe71eb 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go @@ -226,11 +226,43 @@ static sqlite3_module goModule = { 0 // xRollbackTo }; +// See https://sqlite.org/vtab.html#eponymous_only_virtual_tables +static sqlite3_module goModuleEponymousOnly = { + 0, // iVersion + 0, // xCreate - create a table, which here is null + cXConnect, // xConnect - connect to an existing table + cXBestIndex, // xBestIndex - Determine search strategy + cXDisconnect, // xDisconnect - Disconnect from a table + cXDestroy, // xDestroy - Drop a table + cXOpen, // xOpen - open a cursor + cXClose, // xClose - close a cursor + cXFilter, // xFilter - configure scan constraints + cXNext, // xNext - advance a cursor + cXEof, // xEof + cXColumn, // xColumn - read data + cXRowid, // xRowid - read data + cXUpdate, // xUpdate - write data +// Not implemented + 0, // xBegin - begin transaction + 0, // xSync - sync transaction + 0, // xCommit - commit transaction + 0, // xRollback - rollback transaction + 0, // xFindFunction - function overloading + 0, // xRename - rename the table + 0, // xSavepoint + 0, // xRelease + 0 // xRollbackTo +}; + void goMDestroy(void*); static int _sqlite3_create_module(sqlite3 *db, const char *zName, uintptr_t pClientData) { return sqlite3_create_module_v2(db, zName, &goModule, (void*) pClientData, goMDestroy); } + +static int _sqlite3_create_module_eponymous_only(sqlite3 *db, const char *zName, uintptr_t pClientData) { + return sqlite3_create_module_v2(db, zName, &goModuleEponymousOnly, (void*) pClientData, goMDestroy); +} */ import "C" @@ -595,6 +627,13 @@ type Module interface { DestroyModule() } +// EponymousOnlyModule is a "virtual table module" (as above), but +// for defining "eponymous only" virtual tables See: https://sqlite.org/vtab.html#eponymous_only_virtual_tables +type EponymousOnlyModule interface { + Module + EponymousOnlyModule() +} + // VTab describes a particular instance of the virtual table. // See: http://sqlite.org/c3ref/vtab.html type VTab interface { @@ -652,9 +691,19 @@ func (c *SQLiteConn) CreateModule(moduleName string, module Module) error { mname := C.CString(moduleName) defer C.free(unsafe.Pointer(mname)) udm := sqliteModule{c, moduleName, module} - rv := C._sqlite3_create_module(c.db, mname, C.uintptr_t(uintptr(newHandle(c, &udm)))) - if rv != C.SQLITE_OK { - return c.lastError() + switch module.(type) { + case EponymousOnlyModule: + rv := C._sqlite3_create_module_eponymous_only(c.db, mname, C.uintptr_t(uintptr(newHandle(c, &udm)))) + if rv != C.SQLITE_OK { + return c.lastError() + } + return nil + case Module: + rv := C._sqlite3_create_module(c.db, mname, C.uintptr_t(uintptr(newHandle(c, &udm)))) + if rv != C.SQLITE_OK { + return c.lastError() + } + return nil } return nil } diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_type.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_type.go index 437bf0a41351c..b4128db4b3b8d 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3_type.go +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3_type.go @@ -31,12 +31,12 @@ func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) { func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) { return 0, 0, false } -*/ // ColumnTypeNullable implement RowsColumnTypeNullable. func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) { - return true, true + return false, false } +*/ // ColumnTypeScanType implement RowsColumnTypeScanType. func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type { diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go index 1971a480e6c3c..b6739bf62cafa 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go @@ -15,7 +15,9 @@ package sqlite3 // This code should improve performance on windows because // without the presence of usleep SQLite waits 1 second. // -// Source: https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa +// Source: https://github.com/php/php-src/blob/PHP-5.0/win32/time.c +// License: https://github.com/php/php-src/blob/PHP-5.0/LICENSE +// Details: https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa /* #include diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h b/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h index 2844f706f505c..b2b6e0c8ddae8 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h @@ -336,6 +336,8 @@ struct sqlite3_api_routines { int,const char**); void (*free_filename)(char*); sqlite3_file *(*database_file_object)(const char*); + /* Version 3.34.0 and later */ + int (*txn_state)(sqlite3*,const char*); }; /* @@ -640,6 +642,8 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_create_filename sqlite3_api->create_filename #define sqlite3_free_filename sqlite3_api->free_filename #define sqlite3_database_file_object sqlite3_api->database_file_object +/* Version 3.34.0 and later */ +#define sqlite3_txn_state sqlite3_api->txn_state #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/vendor/github.com/minio/md5-simd/LICENSE.Golang b/vendor/github.com/minio/md5-simd/LICENSE.Golang new file mode 100644 index 0000000000000..6a66aea5eafe0 --- /dev/null +++ b/vendor/github.com/minio/md5-simd/LICENSE.Golang @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/minio/md5-simd/block-generic.go b/vendor/github.com/minio/md5-simd/block-generic.go index eb333b93ffd6d..76667213936e2 100644 --- a/vendor/github.com/minio/md5-simd/block-generic.go +++ b/vendor/github.com/minio/md5-simd/block-generic.go @@ -1,6 +1,6 @@ // Copyright 2013 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// license that can be found in the LICENSE.Golang file. // Code generated by go run gen.go -output md5block.go; DO NOT EDIT. diff --git a/vendor/github.com/minio/minio-go/v7/README.md b/vendor/github.com/minio/minio-go/v7/README.md index 4fec6ff89fe12..ab5bcb53f331d 100644 --- a/vendor/github.com/minio/minio-go/v7/README.md +++ b/vendor/github.com/minio/minio-go/v7/README.md @@ -248,4 +248,4 @@ The full API Reference is available here. [Contributors Guide](https://github.com/minio/minio-go/blob/master/CONTRIBUTING.md) ## License -This SDK is distributed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0), see [LICENSE](./LICENSE) and [NOTICE](./NOTICE) for more information. +This SDK is distributed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0), see [LICENSE](https://github.com/minio/minio-go/blob/master/LICENSE) and [NOTICE](https://github.com/minio/minio-go/blob/master/NOTICE) for more information. diff --git a/vendor/github.com/minio/minio-go/v7/api-compose-object.go b/vendor/github.com/minio/minio-go/v7/api-compose-object.go index e55f9f7b5b45a..edcd44e74a6a1 100644 --- a/vendor/github.com/minio/minio-go/v7/api-compose-object.go +++ b/vendor/github.com/minio/minio-go/v7/api-compose-object.go @@ -215,7 +215,7 @@ func (c Client) copyObjectDo(ctx context.Context, srcBucket, srcObject, destBuck headers.Set(amzBucketReplicationStatus, string(dstOpts.Internal.ReplicationStatus)) } if !dstOpts.Internal.SourceMTime.IsZero() { - headers.Set(minIOBucketSourceMTime, dstOpts.Internal.SourceMTime.Format(time.RFC3339)) + headers.Set(minIOBucketSourceMTime, dstOpts.Internal.SourceMTime.Format(time.RFC3339Nano)) } if dstOpts.Internal.SourceETag != "" { headers.Set(minIOBucketSourceETag, dstOpts.Internal.SourceETag) diff --git a/vendor/github.com/minio/minio-go/v7/api-error-response.go b/vendor/github.com/minio/minio-go/v7/api-error-response.go index f439a8870d46e..c45c4fdcb2434 100644 --- a/vendor/github.com/minio/minio-go/v7/api-error-response.go +++ b/vendor/github.com/minio/minio-go/v7/api-error-response.go @@ -102,7 +102,7 @@ const ( // structure as error. func httpRespToErrorResponse(resp *http.Response, bucketName, objectName string) error { if resp == nil { - msg := "Response is empty. " + reportIssue + msg := "Empty http response. " + reportIssue return errInvalidArgument(msg) } diff --git a/vendor/github.com/minio/minio-go/v7/api-get-options.go b/vendor/github.com/minio/minio-go/v7/api-get-options.go index 6b924fa0e0d4b..04b156fc01208 100644 --- a/vendor/github.com/minio/minio-go/v7/api-get-options.go +++ b/vendor/github.com/minio/minio-go/v7/api-get-options.go @@ -28,6 +28,7 @@ import ( //AdvancedGetOptions for internal use by MinIO server - not intended for client use. type AdvancedGetOptions struct { ReplicationDeleteMarker bool + ReplicationProxyRequest bool } // GetObjectOptions are used to specify additional headers or options @@ -53,6 +54,11 @@ func (o GetObjectOptions) Header() http.Header { if o.ServerSideEncryption != nil && o.ServerSideEncryption.Type() == encrypt.SSEC { o.ServerSideEncryption.Marshal(headers) } + // this header is set for active-active replication scenario where GET/HEAD + // to site A is proxy'd to site B if object/version missing on site A. + if o.Internal.ReplicationProxyRequest { + headers.Set(minIOBucketReplicationProxyRequest, "true") + } return headers } diff --git a/vendor/github.com/minio/minio-go/v7/api-put-object.go b/vendor/github.com/minio/minio-go/v7/api-put-object.go index 9428c7fee693f..0cbb0a7a30f7d 100644 --- a/vendor/github.com/minio/minio-go/v7/api-put-object.go +++ b/vendor/github.com/minio/minio-go/v7/api-put-object.go @@ -147,7 +147,7 @@ func (opts PutObjectOptions) Header() (header http.Header) { header.Set(amzBucketReplicationStatus, string(opts.Internal.ReplicationStatus)) } if !opts.Internal.SourceMTime.IsZero() { - header.Set(minIOBucketSourceMTime, opts.Internal.SourceMTime.Format(time.RFC3339)) + header.Set(minIOBucketSourceMTime, opts.Internal.SourceMTime.Format(time.RFC3339Nano)) } if opts.Internal.SourceETag != "" { header.Set(minIOBucketSourceETag, opts.Internal.SourceETag) diff --git a/vendor/github.com/minio/minio-go/v7/api-remove.go b/vendor/github.com/minio/minio-go/v7/api-remove.go index 920612c4fea98..7ac3f26aa835c 100644 --- a/vendor/github.com/minio/minio-go/v7/api-remove.go +++ b/vendor/github.com/minio/minio-go/v7/api-remove.go @@ -107,7 +107,7 @@ func (c Client) removeObject(ctx context.Context, bucketName, objectName string, headers.Set(minIOBucketReplicationDeleteMarker, "true") } if !opts.Internal.ReplicationMTime.IsZero() { - headers.Set(minIOBucketSourceMTime, opts.Internal.ReplicationMTime.Format(time.RFC3339)) + headers.Set(minIOBucketSourceMTime, opts.Internal.ReplicationMTime.Format(time.RFC3339Nano)) } if !opts.Internal.ReplicationStatus.Empty() { headers.Set(amzBucketReplicationStatus, string(opts.Internal.ReplicationStatus)) diff --git a/vendor/github.com/minio/minio-go/v7/api.go b/vendor/github.com/minio/minio-go/v7/api.go index 69ed02cfe0133..c71e9c7ab6568 100644 --- a/vendor/github.com/minio/minio-go/v7/api.go +++ b/vendor/github.com/minio/minio-go/v7/api.go @@ -108,7 +108,7 @@ type Options struct { // Global constants. const ( libraryName = "minio-go" - libraryVersion = "v7.0.6" + libraryVersion = "v7.0.7" ) // User Agent should always following the below style. diff --git a/vendor/github.com/minio/minio-go/v7/constants.go b/vendor/github.com/minio/minio-go/v7/constants.go index 4f45ce5895d3f..5e5aec7c2ef7f 100644 --- a/vendor/github.com/minio/minio-go/v7/constants.go +++ b/vendor/github.com/minio/minio-go/v7/constants.go @@ -87,4 +87,5 @@ const ( minIOBucketSourceETag = "X-Minio-Source-Etag" minIOBucketReplicationDeleteMarker = "X-Minio-Source-DeleteMarker" + minIOBucketReplicationProxyRequest = "X-Minio-Source-Proxy-Request" ) diff --git a/vendor/github.com/minio/minio-go/v7/go.mod b/vendor/github.com/minio/minio-go/v7/go.mod index 34bbb6fdd6e76..95a07c1fe5ee9 100644 --- a/vendor/github.com/minio/minio-go/v7/go.mod +++ b/vendor/github.com/minio/minio-go/v7/go.mod @@ -11,6 +11,7 @@ require ( github.com/kr/pretty v0.1.0 // indirect github.com/minio/md5-simd v1.1.0 github.com/minio/sha256-simd v0.1.1 + github.com/minio/sio v0.2.1 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect diff --git a/vendor/github.com/minio/minio-go/v7/go.sum b/vendor/github.com/minio/minio-go/v7/go.sum index 6a5c22f1a0a04..e6302e61613b6 100644 --- a/vendor/github.com/minio/minio-go/v7/go.sum +++ b/vendor/github.com/minio/minio-go/v7/go.sum @@ -36,6 +36,8 @@ github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4= github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sio v0.2.1 h1:NjzKiIMSMcHediVQR0AFVx2tp7Wxh9tKPfDI3kH7aHQ= +github.com/minio/sio v0.2.1/go.mod h1:8b0yPp2avGThviy/+OCJBI6OMpvxoUuiLvE6F1lebhw= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= @@ -63,6 +65,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/vendor/github.com/minio/minio-go/v7/pkg/encrypt/server-side.go b/vendor/github.com/minio/minio-go/v7/pkg/encrypt/server-side.go index 5276f63fc1e0c..ce7d2153106f7 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/encrypt/server-side.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/encrypt/server-side.go @@ -34,7 +34,7 @@ const ( // sseKmsKeyID is the AWS SSE-KMS key id. sseKmsKeyID = sseGenericHeader + "-Aws-Kms-Key-Id" // sseEncryptionContext is the AWS SSE-KMS Encryption Context data. - sseEncryptionContext = sseGenericHeader + "-Encryption-Context" + sseEncryptionContext = sseGenericHeader + "-Context" // sseCustomerAlgorithm is the AWS SSE-C algorithm HTTP header key. sseCustomerAlgorithm = sseGenericHeader + "-Customer-Algorithm" diff --git a/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go b/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go index 216588f74de9d..169ff7dceb56a 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go @@ -53,15 +53,6 @@ type NoncurrentVersionExpiration struct { NoncurrentDays ExpirationDays `xml:"NoncurrentDays,omitempty"` } -// NoncurrentVersionTransition structure, set this action to request server to -// transition noncurrent object versions to different set storage classes -// at a specific period in the object's lifetime. -type NoncurrentVersionTransition struct { - XMLName xml.Name `xml:"NoncurrentVersionTransition,omitempty" json:"-"` - StorageClass string `xml:"StorageClass,omitempty" json:"StorageClass,omitempty"` - NoncurrentDays ExpirationDays `xml:"NoncurrentDays,omitempty" json:"NoncurrentDays,omitempty"` -} - // MarshalXML if non-current days not set to non zero value func (n NoncurrentVersionExpiration) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if n.IsDaysNull() { @@ -76,13 +67,28 @@ func (n NoncurrentVersionExpiration) IsDaysNull() bool { return n.NoncurrentDays == ExpirationDays(0) } +// NoncurrentVersionTransition structure, set this action to request server to +// transition noncurrent object versions to different set storage classes +// at a specific period in the object's lifetime. +type NoncurrentVersionTransition struct { + XMLName xml.Name `xml:"NoncurrentVersionTransition,omitempty" json:"-"` + StorageClass string `xml:"StorageClass,omitempty" json:"StorageClass,omitempty"` + NoncurrentDays ExpirationDays `xml:"NoncurrentDays,omitempty" json:"NoncurrentDays,omitempty"` +} + +// IsDaysNull returns true if days field is null +func (n NoncurrentVersionTransition) IsDaysNull() bool { + return n.NoncurrentDays == ExpirationDays(0) +} + // MarshalXML is extended to leave out // tags func (n NoncurrentVersionTransition) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - if n.NoncurrentDays == ExpirationDays(0) { + if n.IsDaysNull() { return nil } - return e.EncodeElement(&n, start) + type noncurrentVersionTransitionWrapper NoncurrentVersionTransition + return e.EncodeElement(noncurrentVersionTransitionWrapper(n), start) } // Tag structure key/value pair representing an object tag to apply lifecycle configuration diff --git a/vendor/github.com/minio/minio-go/v7/pkg/notification/notification.go b/vendor/github.com/minio/minio-go/v7/pkg/notification/notification.go index 05c79bb48b3a1..b17e6c54fbbb0 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/notification/notification.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/notification/notification.go @@ -180,20 +180,28 @@ func EqualFilterRuleList(a, b []FilterRule) bool { // Equal returns whether this `Config` is equal to another defined by the passed parameters func (t *Config) Equal(events []EventType, prefix, suffix string) bool { - //Compare events + if t == nil { + return false + } + + // Compare events passEvents := EqualEventTypeList(t.Events, events) - //Compare filters - var newFilter []FilterRule + // Compare filters + var newFilterRules []FilterRule if prefix != "" { - newFilter = append(newFilter, FilterRule{Name: "prefix", Value: prefix}) + newFilterRules = append(newFilterRules, FilterRule{Name: "prefix", Value: prefix}) } if suffix != "" { - newFilter = append(newFilter, FilterRule{Name: "suffix", Value: suffix}) + newFilterRules = append(newFilterRules, FilterRule{Name: "suffix", Value: suffix}) + } + + var currentFilterRules []FilterRule + if t.Filter != nil { + currentFilterRules = t.Filter.S3Key.FilterRules } - passFilters := EqualFilterRuleList(t.Filter.S3Key.FilterRules, newFilter) - // if it matches events and filters, mark the index for deletion + passFilters := EqualFilterRuleList(currentFilterRules, newFilterRules) return passEvents && passFilters } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go b/vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go index 908381690195d..6df89821443ce 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go @@ -195,6 +195,14 @@ func (c *Config) AddRule(opts Options) error { }, DeleteMarkerReplication: DeleteMarkerReplication{Status: dmStatus}, DeleteReplication: DeleteReplication{Status: vDeleteStatus}, + // MinIO enables replica metadata syncing by default in the case of bi-directional replication to allow + // automatic failover as the expectation in this case is that replica and source should be identical. + // However AWS leaves this configurable https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-for-metadata-changes.html + SourceSelectionCriteria: SourceSelectionCriteria{ + ReplicaModifications: ReplicaModifications{ + Status: Enabled, + }, + }, } // validate rule after overlaying priority for pre-existing rule being disabled. @@ -378,6 +386,7 @@ type Rule struct { DeleteReplication DeleteReplication `xml:"DeleteReplication"` Destination Destination `xml:"Destination"` Filter Filter `xml:"Filter" json:"Filter"` + SourceSelectionCriteria SourceSelectionCriteria `xml:"SourceSelectionCriteria" json:"SourceSelectionCriteria"` } // Validate validates the rule for correctness @@ -396,6 +405,10 @@ func (r Rule) Validate() error { return fmt.Errorf("Priority must be set for the rule") } + if err := r.validateStatus(); err != nil { + return err + } + return nil } @@ -569,3 +582,29 @@ type DeleteReplication struct { func (d DeleteReplication) IsEmpty() bool { return len(d.Status) == 0 } + +// ReplicaModifications specifies if replica modification sync is enabled +type ReplicaModifications struct { + Status Status `xml:"Status" json:"Status"` +} + +// SourceSelectionCriteria - specifies additional source selection criteria in ReplicationConfiguration. +type SourceSelectionCriteria struct { + ReplicaModifications ReplicaModifications `xml:"ReplicaModifications" json:"ReplicaModifications"` +} + +// IsValid - checks whether SourceSelectionCriteria is valid or not. +func (s SourceSelectionCriteria) IsValid() bool { + return s.ReplicaModifications.Status == Enabled || s.ReplicaModifications.Status == Disabled +} + +// Validate source selection criteria +func (s SourceSelectionCriteria) Validate() error { + if (s == SourceSelectionCriteria{}) { + return nil + } + if !s.IsValid() { + return fmt.Errorf("Invalid ReplicaModification status") + } + return nil +} diff --git a/vendor/github.com/minio/minio-go/v7/post-policy.go b/vendor/github.com/minio/minio-go/v7/post-policy.go index d489d981ad40d..31a7308ccf28d 100644 --- a/vendor/github.com/minio/minio-go/v7/post-policy.go +++ b/vendor/github.com/minio/minio-go/v7/post-policy.go @@ -170,6 +170,24 @@ func (p *PostPolicy) SetContentType(contentType string) error { return nil } +// SetContentTypeStartsWith - Sets what content-type of the object for this policy +// based upload can start with. +func (p *PostPolicy) SetContentTypeStartsWith(contentTypeStartsWith string) error { + if strings.TrimSpace(contentTypeStartsWith) == "" || contentTypeStartsWith == "" { + return errInvalidArgument("No content type specified.") + } + policyCond := policyCondition{ + matchType: "starts-with", + condition: "$Content-Type", + value: contentTypeStartsWith, + } + if err := p.addNewPolicy(policyCond); err != nil { + return err + } + p.formData["Content-Type"] = contentTypeStartsWith + return nil +} + // SetContentLengthRange - Set new min and max content length // condition for all incoming uploads. func (p *PostPolicy) SetContentLengthRange(min, max int64) error { diff --git a/vendor/github.com/mitchellh/mapstructure/.travis.yml b/vendor/github.com/mitchellh/mapstructure/.travis.yml deleted file mode 100644 index 5e31a95a8b8ef..0000000000000 --- a/vendor/github.com/mitchellh/mapstructure/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - "1.14.x" - - tip - -script: - - go test - - go test -bench . -benchmem diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md index 3378f7e66edf4..1955f2878c810 100644 --- a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md +++ b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md @@ -1,3 +1,19 @@ +## unreleased + +* Fix regression where `*time.Time` value would be set to empty and not be sent + to decode hooks properly [GH-232] + +## 1.4.0 + +* A new decode hook type `DecodeHookFuncValue` has been added that has + access to the full values. [GH-183] +* Squash is now supported with embedded fields that are struct pointers [GH-205] +* Empty strings will convert to 0 for all numeric types when weakly decoding [GH-206] + +## 1.3.3 + +* Decoding maps from maps creates a settable value for decode hooks [GH-203] + ## 1.3.2 * Decode into interface type with a struct value is supported [GH-187] diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go index 1f0abc65ab7e2..92e6f76fff437 100644 --- a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go +++ b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go @@ -1,6 +1,7 @@ package mapstructure import ( + "encoding" "errors" "fmt" "net" @@ -16,10 +17,11 @@ func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { // Create variables here so we can reference them with the reflect pkg var f1 DecodeHookFuncType var f2 DecodeHookFuncKind + var f3 DecodeHookFuncValue // Fill in the variables into this interface and the rest is done // automatically using the reflect package. - potential := []interface{}{f1, f2} + potential := []interface{}{f1, f2, f3} v := reflect.ValueOf(h) vt := v.Type() @@ -38,13 +40,15 @@ func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { // that took reflect.Kind instead of reflect.Type. func DecodeHookExec( raw DecodeHookFunc, - from reflect.Type, to reflect.Type, - data interface{}) (interface{}, error) { + from reflect.Value, to reflect.Value) (interface{}, error) { + switch f := typedDecodeHook(raw).(type) { case DecodeHookFuncType: - return f(from, to, data) + return f(from.Type(), to.Type(), from.Interface()) case DecodeHookFuncKind: - return f(from.Kind(), to.Kind(), data) + return f(from.Kind(), to.Kind(), from.Interface()) + case DecodeHookFuncValue: + return f(from, to) default: return nil, errors.New("invalid decode hook signature") } @@ -56,22 +60,16 @@ func DecodeHookExec( // The composed funcs are called in order, with the result of the // previous transformation. func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data interface{}) (interface{}, error) { + return func(f reflect.Value, t reflect.Value) (interface{}, error) { var err error + var data interface{} + newFrom := f for _, f1 := range fs { - data, err = DecodeHookExec(f1, f, t, data) + data, err = DecodeHookExec(f1, newFrom, t) if err != nil { return nil, err } - - // Modify the from kind to be correct with the new data - f = nil - if val := reflect.ValueOf(data); val.IsValid() { - f = val.Type() - } + newFrom = reflect.ValueOf(data) } return data, nil @@ -215,3 +213,44 @@ func WeaklyTypedHook( return data, nil } + +func RecursiveStructToMapHookFunc() DecodeHookFunc { + return func(f reflect.Value, t reflect.Value) (interface{}, error) { + if f.Kind() != reflect.Struct { + return f.Interface(), nil + } + + var i interface{} = struct{}{} + if t.Type() != reflect.TypeOf(&i).Elem() { + return f.Interface(), nil + } + + m := make(map[string]interface{}) + t.Set(reflect.ValueOf(m)) + + return f.Interface(), nil + } +} + +// TextUnmarshallerHookFunc returns a DecodeHookFunc that applies +// strings to the UnmarshalText function, when the target type +// implements the encoding.TextUnmarshaler interface +func TextUnmarshallerHookFunc() DecodeHookFuncType { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + result := reflect.New(t).Interface() + unmarshaller, ok := result.(encoding.TextUnmarshaler) + if !ok { + return data, nil + } + if err := unmarshaller.UnmarshalText([]byte(data.(string))); err != nil { + return nil, err + } + return result, nil + } +} diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go index b384d9d928f95..3643901f55f16 100644 --- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go +++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go @@ -72,6 +72,17 @@ // "name": "alice", // } // +// When decoding from a struct to a map, the squash tag squashes the struct +// fields into a single map. Using the example structs from above: +// +// Friend{Person: Person{Name: "alice"}} +// +// Will be decoded into a map: +// +// map[string]interface{}{ +// "name": "alice", +// } +// // DecoderConfig has a field that changes the behavior of mapstructure // to always squash embedded structs. // @@ -161,10 +172,11 @@ import ( // data transformations. See "DecodeHook" in the DecoderConfig // struct. // -// The type should be DecodeHookFuncType or DecodeHookFuncKind. -// Either is accepted. Types are a superset of Kinds (Types can return -// Kinds) and are generally a richer thing to use, but Kinds are simpler -// if you only need those. +// The type must be one of DecodeHookFuncType, DecodeHookFuncKind, or +// DecodeHookFuncValue. +// Values are a superset of Types (Values can return types), and Types are a +// superset of Kinds (Types can return Kinds) and are generally a richer thing +// to use, but Kinds are simpler if you only need those. // // The reason DecodeHookFunc is multi-typed is for backwards compatibility: // we started with Kinds and then realized Types were the better solution, @@ -180,15 +192,22 @@ type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface // source and target types. type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) +// DecodeHookFuncRaw is a DecodeHookFunc which has complete access to both the source and target +// values. +type DecodeHookFuncValue func(from reflect.Value, to reflect.Value) (interface{}, error) + // DecoderConfig is the configuration that is used to create a new decoder // and allows customization of various aspects of decoding. type DecoderConfig struct { // DecodeHook, if set, will be called before any decoding and any // type conversion (if WeaklyTypedInput is on). This lets you modify - // the values before they're set down onto the resulting struct. + // the values before they're set down onto the resulting struct. The + // DecodeHook is called for every map and value in the input. This means + // that if a struct has embedded fields with squash tags the decode hook + // is called only once with all of the input data, not once for each + // embedded struct. // - // If an error is returned, the entire decode will fail with that - // error. + // If an error is returned, the entire decode will fail with that error. DecodeHook DecodeHookFunc // If ErrorUnused is true, then it is an error for there to exist @@ -409,9 +428,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e if d.config.DecodeHook != nil { // We have a DecodeHook, so let's pre-process the input. var err error - input, err = DecodeHookExec( - d.config.DecodeHook, - inputVal.Type(), outVal.Type(), input) + input, err = DecodeHookExec(d.config.DecodeHook, inputVal, outVal) if err != nil { return fmt.Errorf("error decoding '%s': %s", name, err) } @@ -562,8 +579,8 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) if !converted { return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) + "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", + name, val.Type(), dataVal.Type(), data) } return nil @@ -588,7 +605,12 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er val.SetInt(0) } case dataKind == reflect.String && d.config.WeaklyTypedInput: - i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits()) + str := dataVal.String() + if str == "" { + str = "0" + } + + i, err := strconv.ParseInt(str, 0, val.Type().Bits()) if err == nil { val.SetInt(i) } else { @@ -604,8 +626,8 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er val.SetInt(i) default: return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) + "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", + name, val.Type(), dataVal.Type(), data) } return nil @@ -640,7 +662,12 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e val.SetUint(0) } case dataKind == reflect.String && d.config.WeaklyTypedInput: - i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits()) + str := dataVal.String() + if str == "" { + str = "0" + } + + i, err := strconv.ParseUint(str, 0, val.Type().Bits()) if err == nil { val.SetUint(i) } else { @@ -660,8 +687,8 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e val.SetUint(uint64(i)) default: return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) + "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", + name, val.Type(), dataVal.Type(), data) } return nil @@ -691,8 +718,8 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) e } default: return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) + "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", + name, val.Type(), dataVal.Type(), data) } return nil @@ -717,7 +744,12 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) val.SetFloat(0) } case dataKind == reflect.String && d.config.WeaklyTypedInput: - f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits()) + str := dataVal.String() + if str == "" { + str = "0" + } + + f, err := strconv.ParseFloat(str, val.Type().Bits()) if err == nil { val.SetFloat(f) } else { @@ -733,8 +765,8 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) val.SetFloat(i) default: return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) + "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", + name, val.Type(), dataVal.Type(), data) } return nil @@ -785,7 +817,7 @@ func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val ref for i := 0; i < dataVal.Len(); i++ { err := d.decode( - fmt.Sprintf("%s[%d]", name, i), + name+"["+strconv.Itoa(i)+"]", dataVal.Index(i).Interface(), val) if err != nil { return err @@ -818,7 +850,7 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle } for _, k := range dataVal.MapKeys() { - fieldName := fmt.Sprintf("%s[%s]", name, k) + fieldName := name + "[" + k.String() + "]" // First decode the key into the proper type currentKey := reflect.Indirect(reflect.New(valKeyType)) @@ -871,6 +903,7 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re // If Squash is set in the config, we squash the field down. squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous + // Determine the name of the key in the map if index := strings.Index(tagValue, ","); index != -1 { if tagValue[:index] == "-" { @@ -883,8 +916,16 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re // If "squash" is specified in the tag, we squash the field down. squash = !squash && strings.Index(tagValue[index+1:], "squash") != -1 - if squash && v.Kind() != reflect.Struct { - return fmt.Errorf("cannot squash non-struct type '%s'", v.Type()) + if squash { + // When squashing, the embedded type can be a pointer to a struct. + if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct { + v = v.Elem() + } + + // The final type must be a struct + if v.Kind() != reflect.Struct { + return fmt.Errorf("cannot squash non-struct type '%s'", v.Type()) + } } keyName = tagValue[:index] } else if len(tagValue) > 0 { @@ -906,11 +947,22 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re mType := reflect.MapOf(vKeyType, vElemType) vMap := reflect.MakeMap(mType) - err := d.decode(keyName, x.Interface(), vMap) + // Creating a pointer to a map so that other methods can completely + // overwrite the map if need be (looking at you decodeMapFromMap). The + // indirection allows the underlying map to be settable (CanSet() == true) + // where as reflect.MakeMap returns an unsettable map. + addrVal := reflect.New(vMap.Type()) + reflect.Indirect(addrVal).Set(vMap) + + err := d.decode(keyName, x.Interface(), reflect.Indirect(addrVal)) if err != nil { return err } + // the underlying map may have been completely overwritten so pull + // it indirectly out of the enclosing value. + vMap = reflect.Indirect(addrVal) + if squash { for _, k := range vMap.MapKeys() { valMap.SetMapIndex(k, vMap.MapIndex(k)) @@ -984,8 +1036,8 @@ func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) e dataVal := reflect.Indirect(reflect.ValueOf(data)) if val.Type() != dataVal.Type() { return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) + "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", + name, val.Type(), dataVal.Type(), data) } val.Set(dataVal) return nil @@ -1051,7 +1103,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) } currentField := valSlice.Index(i) - fieldName := fmt.Sprintf("%s[%d]", name, i) + fieldName := name + "[" + strconv.Itoa(i) + "]" if err := d.decode(fieldName, currentData, currentField); err != nil { errors = appendErrors(errors, err) } @@ -1118,7 +1170,7 @@ func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) currentData := dataVal.Index(i).Interface() currentField := valArray.Index(i) - fieldName := fmt.Sprintf("%s[%d]", name, i) + fieldName := name + "[" + strconv.Itoa(i) + "]" if err := d.decode(fieldName, currentData, currentField); err != nil { errors = appendErrors(errors, err) } @@ -1154,13 +1206,23 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) // Not the most efficient way to do this but we can optimize later if // we want to. To convert from struct to struct we go to map first // as an intermediary. - m := make(map[string]interface{}) - mval := reflect.Indirect(reflect.ValueOf(&m)) - if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil { + + // Make a new map to hold our result + mapType := reflect.TypeOf((map[string]interface{})(nil)) + mval := reflect.MakeMap(mapType) + + // Creating a pointer to a map so that other methods can completely + // overwrite the map if need be (looking at you decodeMapFromMap). The + // indirection allows the underlying map to be settable (CanSet() == true) + // where as reflect.MakeMap returns an unsettable map. + addrVal := reflect.New(mval.Type()) + + reflect.Indirect(addrVal).Set(mval) + if err := d.decodeMapFromStruct(name, dataVal, reflect.Indirect(addrVal), mval); err != nil { return err } - result := d.decodeStructFromMap(name, mval, val) + result := d.decodeStructFromMap(name, reflect.Indirect(addrVal), val) return result default: @@ -1211,10 +1273,14 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e for i := 0; i < structType.NumField(); i++ { fieldType := structType.Field(i) - fieldKind := fieldType.Type.Kind() + fieldVal := structVal.Field(i) + if fieldVal.Kind() == reflect.Ptr && fieldVal.Elem().Kind() == reflect.Struct { + // Handle embedded struct pointers as embedded structs. + fieldVal = fieldVal.Elem() + } // If "squash" is specified in the tag, we squash the field down. - squash := d.config.Squash && fieldKind == reflect.Struct && fieldType.Anonymous + squash := d.config.Squash && fieldVal.Kind() == reflect.Struct && fieldType.Anonymous remain := false // We always parse the tags cause we're looking for other tags too @@ -1232,21 +1298,21 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e } if squash { - if fieldKind != reflect.Struct { + if fieldVal.Kind() != reflect.Struct { errors = appendErrors(errors, - fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind)) + fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldVal.Kind())) } else { - structs = append(structs, structVal.FieldByName(fieldType.Name)) + structs = append(structs, fieldVal) } continue } // Build our field if remain { - remainField = &field{fieldType, structVal.Field(i)} + remainField = &field{fieldType, fieldVal} } else { // Normal struct field, store it away - fields = append(fields, field{fieldType, structVal.Field(i)}) + fields = append(fields, field{fieldType, fieldVal}) } } } @@ -1305,7 +1371,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e // If the name is empty string, then we're at the root, and we // don't dot-join the fields. if name != "" { - fieldName = fmt.Sprintf("%s.%s", name, fieldName) + fieldName = name + "." + fieldName } if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil { @@ -1352,7 +1418,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e for rawKey := range dataValKeysUnused { key := rawKey.(string) if name != "" { - key = fmt.Sprintf("%s.%s", name, key) + key = name + "." + key } d.config.Metadata.Unused = append(d.config.Metadata.Unused, key) diff --git a/vendor/github.com/niklasfasching/go-org/org/drawer.go b/vendor/github.com/niklasfasching/go-org/org/drawer.go index eee590d8c4479..55763023fca9b 100644 --- a/vendor/github.com/niklasfasching/go-org/org/drawer.go +++ b/vendor/github.com/niklasfasching/go-org/org/drawer.go @@ -15,7 +15,7 @@ type PropertyDrawer struct { } var beginDrawerRegexp = regexp.MustCompile(`^(\s*):(\S+):\s*$`) -var endDrawerRegexp = regexp.MustCompile(`^(\s*):END:\s*$`) +var endDrawerRegexp = regexp.MustCompile(`(?i)^(\s*):END:\s*$`) var propertyRegexp = regexp.MustCompile(`^(\s*):(\S+):(\s+(.*)$|$)`) func lexDrawer(line string) (token, bool) { diff --git a/vendor/github.com/niklasfasching/go-org/org/html_writer.go b/vendor/github.com/niklasfasching/go-org/org/html_writer.go index d66e6effb33a4..f2e75a001eb77 100644 --- a/vendor/github.com/niklasfasching/go-org/org/html_writer.go +++ b/vendor/github.com/niklasfasching/go-org/org/html_writer.go @@ -15,8 +15,9 @@ import ( // HTMLWriter exports an org document into a html document. type HTMLWriter struct { - ExtendingWriter Writer - HighlightCodeBlock func(source, lang string, inline bool) string + ExtendingWriter Writer + HighlightCodeBlock func(source, lang string, inline bool) string + PrettyRelativeLinks bool strings.Builder document *Document @@ -342,6 +343,16 @@ func (w *HTMLWriter) WriteRegularLink(l RegularLink) { if l.Protocol == "file" { url = url[len("file:"):] } + if isRelative := l.Protocol == "file" || l.Protocol == ""; isRelative && w.PrettyRelativeLinks { + if !strings.HasPrefix(url, "/") { + url = "../" + url + } + if strings.HasSuffix(url, ".org") { + url = strings.TrimSuffix(url, ".org") + "/" + } + } else if isRelative && strings.HasSuffix(url, ".org") { + url = strings.TrimSuffix(url, ".org") + ".html" + } if prefix := w.document.Links[l.Protocol]; prefix != "" { url = html.EscapeString(prefix) + strings.TrimPrefix(url, l.Protocol+":") } diff --git a/vendor/github.com/olivere/elastic/v7/client.go b/vendor/github.com/olivere/elastic/v7/client.go index bd8993c990841..38a93faa3a752 100644 --- a/vendor/github.com/olivere/elastic/v7/client.go +++ b/vendor/github.com/olivere/elastic/v7/client.go @@ -25,7 +25,7 @@ import ( const ( // Version is the current version of Elastic. - Version = "7.0.21" + Version = "7.0.22" // DefaultURL is the default endpoint of Elasticsearch on the local machine. // It is used e.g. when initializing a new Client without a specific URL. @@ -145,6 +145,7 @@ type Client struct { gzipEnabled bool // gzip compression enabled or disabled (default) requiredPlugins []string // list of required plugins retrier Retrier // strategy for retries + retryStatusCodes []int // HTTP status codes where to retry automatically (with retrier) headers http.Header // a list of default headers to add to each request } @@ -247,6 +248,7 @@ func NewSimpleClient(options ...ClientOptionFunc) (*Client, error) { sendGetBodyAs: DefaultSendGetBodyAs, gzipEnabled: DefaultGzipEnabled, retrier: noRetries, // no retries by default + retryStatusCodes: nil, // no automatic retries for specific HTTP status codes deprecationlog: noDeprecationLog, } @@ -332,6 +334,7 @@ func DialContext(ctx context.Context, options ...ClientOptionFunc) (*Client, err sendGetBodyAs: DefaultSendGetBodyAs, gzipEnabled: DefaultGzipEnabled, retrier: noRetries, // no retries by default + retryStatusCodes: nil, // no automatic retries for specific HTTP status codes deprecationlog: noDeprecationLog, } @@ -726,6 +729,17 @@ func SetRetrier(retrier Retrier) ClientOptionFunc { } } +// SetRetryStatusCodes specifies the HTTP status codes where the client +// will retry automatically. Notice that retries call the specified retrier, +// so calling SetRetryStatusCodes without setting a Retrier won't do anything +// for retries. +func SetRetryStatusCodes(statusCodes ...int) ClientOptionFunc { + return func(c *Client) error { + c.retryStatusCodes = statusCodes + return nil + } +} + // SetHeaders adds a list of default HTTP headers that will be added to // each requests executed by PerformRequest. func SetHeaders(headers http.Header) ClientOptionFunc { @@ -1262,15 +1276,16 @@ func (c *Client) mustActiveConn() error { // PerformRequestOptions must be passed into PerformRequest. type PerformRequestOptions struct { - Method string - Path string - Params url.Values - Body interface{} - ContentType string - IgnoreErrors []int - Retrier Retrier - Headers http.Header - MaxResponseSize int64 + Method string + Path string + Params url.Values + Body interface{} + ContentType string + IgnoreErrors []int + Retrier Retrier + RetryStatusCodes []int + Headers http.Header + MaxResponseSize int64 } // PerformRequest does a HTTP request to Elasticsearch. @@ -1294,9 +1309,23 @@ func (c *Client) PerformRequest(ctx context.Context, opt PerformRequestOptions) if opt.Retrier != nil { retrier = opt.Retrier } + retryStatusCodes := c.retryStatusCodes + if opt.RetryStatusCodes != nil { + retryStatusCodes = opt.RetryStatusCodes + } defaultHeaders := c.headers c.mu.RUnlock() + // retry returns true if statusCode indicates the request is to be retried + retry := func(statusCode int) bool { + for _, code := range retryStatusCodes { + if code == statusCode { + return true + } + } + return false + } + var err error var conn *conn var req *Request @@ -1404,6 +1433,21 @@ func (c *Client) PerformRequest(ctx context.Context, opt PerformRequestOptions) time.Sleep(wait) continue // try again } + if retry(res.StatusCode) { + n++ + wait, ok, rerr := retrier.Retry(ctx, n, (*http.Request)(req), res, err) + if rerr != nil { + c.errorf("elastic: %s is dead", conn.URL()) + conn.MarkAsDead() + return nil, rerr + } + if ok { + // retry + retried = true + time.Sleep(wait) + continue // try again + } + } defer res.Body.Close() // Tracing @@ -1698,30 +1742,82 @@ func (c *Client) Aliases() *AliasesService { return NewAliasesService(c) } -// IndexGetTemplate gets an index template. -// Use XXXTemplate funcs to manage search templates. +// -- Legacy templates -- + +// IndexGetTemplate gets an index template (v1/legacy version before 7.8). +// +// This service implements the legacy version of index templates as described +// in https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html. +// +// See e.g. IndexPutIndexTemplate and IndexPutComponentTemplate for the new version(s). func (c *Client) IndexGetTemplate(names ...string) *IndicesGetTemplateService { return NewIndicesGetTemplateService(c).Name(names...) } -// IndexTemplateExists gets check if an index template exists. -// Use XXXTemplate funcs to manage search templates. +// IndexTemplateExists gets check if an index template exists (v1/legacy version before 7.8). +// +// This service implements the legacy version of index templates as described +// in https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html. +// +// See e.g. IndexPutIndexTemplate and IndexPutComponentTemplate for the new version(s). func (c *Client) IndexTemplateExists(name string) *IndicesExistsTemplateService { return NewIndicesExistsTemplateService(c).Name(name) } -// IndexPutTemplate creates or updates an index template. -// Use XXXTemplate funcs to manage search templates. +// IndexPutTemplate creates or updates an index template (v1/legacy version before 7.8). +// +// This service implements the legacy version of index templates as described +// in https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html. +// +// See e.g. IndexPutIndexTemplate and IndexPutComponentTemplate for the new version(s). func (c *Client) IndexPutTemplate(name string) *IndicesPutTemplateService { return NewIndicesPutTemplateService(c).Name(name) } -// IndexDeleteTemplate deletes an index template. -// Use XXXTemplate funcs to manage search templates. +// IndexDeleteTemplate deletes an index template (v1/legacy version before 7.8). +// +// This service implements the legacy version of index templates as described +// in https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html. +// +// See e.g. IndexPutIndexTemplate and IndexPutComponentTemplate for the new version(s). func (c *Client) IndexDeleteTemplate(name string) *IndicesDeleteTemplateService { return NewIndicesDeleteTemplateService(c).Name(name) } +// -- Index templates -- + +// IndexPutIndexTemplate creates or updates an index template (new version after 7.8). +// +// This service implements the new version of index templates as described +// on https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-put-template.html. +// +// See e.g. IndexPutTemplate for the v1/legacy version. +func (c *Client) IndexPutIndexTemplate(name string) *IndicesPutIndexTemplateService { + return NewIndicesPutIndexTemplateService(c).Name(name) +} + +// IndexGetIndexTemplate returns an index template (new version after 7.8). +// +// This service implements the new version of index templates as described +// on https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-get-template.html. +// +// See e.g. IndexPutTemplate for the v1/legacy version. +func (c *Client) IndexGetIndexTemplate(name string) *IndicesGetIndexTemplateService { + return NewIndicesGetIndexTemplateService(c).Name(name) +} + +// IndexDeleteIndexTemplate deletes an index template (new version after 7.8). +// +// This service implements the new version of index templates as described +// on https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-delete-template.html. +// +// See e.g. IndexPutTemplate for the v1/legacy version. +func (c *Client) IndexDeleteIndexTemplate(name string) *IndicesDeleteIndexTemplateService { + return NewIndicesDeleteIndexTemplateService(c).Name(name) +} + +// -- TODO Component templates -- + // GetMapping gets a mapping. func (c *Client) GetMapping() *IndicesGetMappingService { return NewIndicesGetMappingService(c) @@ -1930,6 +2026,23 @@ func (c *Client) XPackInfo() *XPackInfoService { return NewXPackInfoService(c) } +// -- X-Pack Async Search -- + +// XPackAsyncSearchSubmit starts an asynchronous search. +func (c *Client) XPackAsyncSearchSubmit() *XPackAsyncSearchSubmit { + return NewXPackAsyncSearchSubmit(c) +} + +// XPackAsyncSearchGet retrieves the outcome of an asynchronous search. +func (c *Client) XPackAsyncSearchGet() *XPackAsyncSearchGet { + return NewXPackAsyncSearchGet(c) +} + +// XPackAsyncSearchDelete deletes an asynchronous search. +func (c *Client) XPackAsyncSearchDelete() *XPackAsyncSearchDelete { + return NewXPackAsyncSearchDelete(c) +} + // -- X-Pack Index Lifecycle Management -- // XPackIlmPutLifecycle adds or modifies an ilm policy. diff --git a/vendor/github.com/olivere/elastic/v7/docker-compose.yml b/vendor/github.com/olivere/elastic/v7/docker-compose.yml index eda566185f5c5..1adc197d0027e 100644 --- a/vendor/github.com/olivere/elastic/v7/docker-compose.yml +++ b/vendor/github.com/olivere/elastic/v7/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.9.2 + image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.9.3 hostname: elasticsearch environment: - cluster.name=elasticsearch @@ -28,7 +28,7 @@ services: ports: - 9200:9200 platinum: - image: docker.elastic.co/elasticsearch/elasticsearch:7.9.2 + image: docker.elastic.co/elasticsearch/elasticsearch:7.9.3 hostname: elasticsearch-platinum environment: - cluster.name=platinum diff --git a/vendor/github.com/olivere/elastic/v7/go.mod b/vendor/github.com/olivere/elastic/v7/go.mod index 3a382986783bd..1aae642e74963 100644 --- a/vendor/github.com/olivere/elastic/v7/go.mod +++ b/vendor/github.com/olivere/elastic/v7/go.mod @@ -3,8 +3,9 @@ module github.com/olivere/elastic/v7 go 1.14 require ( - github.com/aws/aws-sdk-go v1.34.13 + github.com/aws/aws-sdk-go v1.35.20 github.com/fortytw2/leaktest v1.3.0 + github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/google/go-cmp v0.5.2 github.com/mailru/easyjson v0.7.6 github.com/opentracing/opentracing-go v1.2.0 @@ -12,5 +13,6 @@ require ( github.com/smartystreets/assertions v1.1.1 // indirect github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 github.com/smartystreets/gunit v1.4.2 // indirect - go.opencensus.io v0.22.4 + github.com/stretchr/testify v1.5.1 // indirect + go.opencensus.io v0.22.5 ) diff --git a/vendor/github.com/olivere/elastic/v7/indices_delete_index_template.go b/vendor/github.com/olivere/elastic/v7/indices_delete_index_template.go new file mode 100644 index 0000000000000..1e7d22b0bcc4e --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/indices_delete_index_template.go @@ -0,0 +1,186 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/olivere/elastic/v7/uritemplates" +) + +// IndicesDeleteIndexTemplateService deletes index templates. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the new version (7.8 or later). If you want +// the old version, please use the IndicesDeleteTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-delete-template.html +// for more details. +type IndicesDeleteIndexTemplateService struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + name string + timeout string + masterTimeout string +} + +// NewIndicesDeleteIndexTemplateService creates a new IndicesDeleteIndexTemplateService. +func NewIndicesDeleteIndexTemplateService(client *Client) *IndicesDeleteIndexTemplateService { + return &IndicesDeleteIndexTemplateService{ + client: client, + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *IndicesDeleteIndexTemplateService) Pretty(pretty bool) *IndicesDeleteIndexTemplateService { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *IndicesDeleteIndexTemplateService) Human(human bool) *IndicesDeleteIndexTemplateService { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *IndicesDeleteIndexTemplateService) ErrorTrace(errorTrace bool) *IndicesDeleteIndexTemplateService { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *IndicesDeleteIndexTemplateService) FilterPath(filterPath ...string) *IndicesDeleteIndexTemplateService { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *IndicesDeleteIndexTemplateService) Header(name string, value string) *IndicesDeleteIndexTemplateService { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *IndicesDeleteIndexTemplateService) Headers(headers http.Header) *IndicesDeleteIndexTemplateService { + s.headers = headers + return s +} + +// Name is the name of the template. +func (s *IndicesDeleteIndexTemplateService) Name(name string) *IndicesDeleteIndexTemplateService { + s.name = name + return s +} + +// Timeout is an explicit operation timeout. +func (s *IndicesDeleteIndexTemplateService) Timeout(timeout string) *IndicesDeleteIndexTemplateService { + s.timeout = timeout + return s +} + +// MasterTimeout specifies the timeout for connection to master. +func (s *IndicesDeleteIndexTemplateService) MasterTimeout(masterTimeout string) *IndicesDeleteIndexTemplateService { + s.masterTimeout = masterTimeout + return s +} + +// buildURL builds the URL for the operation. +func (s *IndicesDeleteIndexTemplateService) buildURL() (string, url.Values, error) { + // Build URL + path, err := uritemplates.Expand("/_index_template/{name}", map[string]string{ + "name": s.name, + }) + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.timeout != "" { + params.Set("timeout", s.timeout) + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *IndicesDeleteIndexTemplateService) Validate() error { + var invalid []string + if s.name == "" { + invalid = append(invalid, "Name") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *IndicesDeleteIndexTemplateService) Do(ctx context.Context) (*IndicesDeleteIndexTemplateResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "DELETE", + Path: path, + Params: params, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(IndicesDeleteIndexTemplateResponse) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + return nil, err + } + return ret, nil +} + +// IndicesDeleteIndexTemplateResponse is the response of IndicesDeleteIndexTemplateService.Do. +type IndicesDeleteIndexTemplateResponse struct { + Acknowledged bool `json:"acknowledged"` + ShardsAcknowledged bool `json:"shards_acknowledged"` + Index string `json:"index,omitempty"` +} diff --git a/vendor/github.com/olivere/elastic/v7/indices_delete_template.go b/vendor/github.com/olivere/elastic/v7/indices_delete_template.go index e1ed3e68aa362..7dd5506046f36 100644 --- a/vendor/github.com/olivere/elastic/v7/indices_delete_template.go +++ b/vendor/github.com/olivere/elastic/v7/indices_delete_template.go @@ -14,8 +14,14 @@ import ( "github.com/olivere/elastic/v7/uritemplates" ) -// IndicesDeleteTemplateService deletes index templates. -// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/indices-templates.html. +// IndicesDeleteTemplateService deletes templates. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the legacy version (7.7 or lower). If you want +// the new version, please use the IndicesDeleteIndexTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-delete-template-v1.html +// for more details. type IndicesDeleteTemplateService struct { client *Client diff --git a/vendor/github.com/olivere/elastic/v7/indices_exists_template.go b/vendor/github.com/olivere/elastic/v7/indices_exists_template.go index c5c9bbdc5b0ea..53f29fea6971e 100644 --- a/vendor/github.com/olivere/elastic/v7/indices_exists_template.go +++ b/vendor/github.com/olivere/elastic/v7/indices_exists_template.go @@ -26,8 +26,9 @@ type IndicesExistsTemplateService struct { filterPath []string // list of filters used to reduce the response headers http.Header // custom request-level HTTP headers - name string - local *bool + name string + local *bool + masterTimeout string } // NewIndicesExistsTemplateService creates a new IndicesExistsTemplateService. @@ -90,6 +91,12 @@ func (s *IndicesExistsTemplateService) Local(local bool) *IndicesExistsTemplateS return s } +// MasterTimeout specifies the timeout for connection to master. +func (s *IndicesExistsTemplateService) MasterTimeout(masterTimeout string) *IndicesExistsTemplateService { + s.masterTimeout = masterTimeout + return s +} + // buildURL builds the URL for the operation. func (s *IndicesExistsTemplateService) buildURL() (string, url.Values, error) { // Build URL @@ -115,7 +122,10 @@ func (s *IndicesExistsTemplateService) buildURL() (string, url.Values, error) { params.Set("filter_path", strings.Join(s.filterPath, ",")) } if s.local != nil { - params.Set("local", fmt.Sprintf("%v", *s.local)) + params.Set("local", fmt.Sprint(*s.local)) + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) } return path, params, nil } diff --git a/vendor/github.com/olivere/elastic/v7/indices_get_index_template.go b/vendor/github.com/olivere/elastic/v7/indices_get_index_template.go new file mode 100644 index 0000000000000..0c3baef23589f --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/indices_get_index_template.go @@ -0,0 +1,214 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/olivere/elastic/v7/uritemplates" +) + +// IndicesGetIndexTemplateService returns an index template. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the new version (7.8 or later). If you want +// the old version, please use the IndicesGetTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-get-template.html +// for more details. +type IndicesGetIndexTemplateService struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + name []string + masterTimeout string + flatSettings *bool + local *bool +} + +// NewIndicesGetIndexTemplateService creates a new IndicesGetIndexTemplateService. +func NewIndicesGetIndexTemplateService(client *Client) *IndicesGetIndexTemplateService { + return &IndicesGetIndexTemplateService{ + client: client, + name: make([]string, 0), + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *IndicesGetIndexTemplateService) Pretty(pretty bool) *IndicesGetIndexTemplateService { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *IndicesGetIndexTemplateService) Human(human bool) *IndicesGetIndexTemplateService { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *IndicesGetIndexTemplateService) ErrorTrace(errorTrace bool) *IndicesGetIndexTemplateService { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *IndicesGetIndexTemplateService) FilterPath(filterPath ...string) *IndicesGetIndexTemplateService { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *IndicesGetIndexTemplateService) Header(name string, value string) *IndicesGetIndexTemplateService { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *IndicesGetIndexTemplateService) Headers(headers http.Header) *IndicesGetIndexTemplateService { + s.headers = headers + return s +} + +// Name is the name of the index template. +func (s *IndicesGetIndexTemplateService) Name(name ...string) *IndicesGetIndexTemplateService { + s.name = append(s.name, name...) + return s +} + +// FlatSettings is returns settings in flat format (default: false). +func (s *IndicesGetIndexTemplateService) FlatSettings(flatSettings bool) *IndicesGetIndexTemplateService { + s.flatSettings = &flatSettings + return s +} + +// Local indicates whether to return local information, i.e. do not retrieve +// the state from master node (default: false). +func (s *IndicesGetIndexTemplateService) Local(local bool) *IndicesGetIndexTemplateService { + s.local = &local + return s +} + +// MasterTimeout specifies the timeout for connection to master. +func (s *IndicesGetIndexTemplateService) MasterTimeout(masterTimeout string) *IndicesGetIndexTemplateService { + s.masterTimeout = masterTimeout + return s +} + +// buildURL builds the URL for the operation. +func (s *IndicesGetIndexTemplateService) buildURL() (string, url.Values, error) { + // Build URL + var err error + var path string + if len(s.name) > 0 { + path, err = uritemplates.Expand("/_index_template/{name}", map[string]string{ + "name": strings.Join(s.name, ","), + }) + } else { + path = "/_template" + } + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.flatSettings != nil { + params.Set("flat_settings", fmt.Sprintf("%v", *s.flatSettings)) + } + if s.local != nil { + params.Set("local", fmt.Sprintf("%v", *s.local)) + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *IndicesGetIndexTemplateService) Validate() error { + return nil +} + +// Do executes the operation. +func (s *IndicesGetIndexTemplateService) Do(ctx context.Context) (*IndicesGetIndexTemplateResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "GET", + Path: path, + Params: params, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + var ret *IndicesGetIndexTemplateResponse + if err := s.client.decoder.Decode(res.Body, &ret); err != nil { + return nil, err + } + return ret, nil +} + +// IndicesGetIndexTemplateResponse is the response of IndicesGetIndexTemplateService.Do. +type IndicesGetIndexTemplateResponse struct { + IndexTemplates []IndicesGetIndexTemplates `json:"index_templates"` +} + +type IndicesGetIndexTemplates struct { + Name string `json:"name"` + IndexTemplate *IndicesGetIndexTemplate `json:"index_template"` +} + +type IndicesGetIndexTemplate struct { + IndexPatterns []string `json:"index_patterns,omitempty"` + ComposedOf []string `json:"composed_of,omitempty"` + Priority int `json:"priority,omitempty"` + Version int `json:"version,omitempty"` + Template *IndicesGetIndexTemplateData `json:"template,omitempty"` +} + +type IndicesGetIndexTemplateData struct { + Settings map[string]interface{} `json:"settings,omitempty"` + Mappings map[string]interface{} `json:"mappings,omitempty"` + Aliases map[string]interface{} `json:"aliases,omitempty"` +} diff --git a/vendor/github.com/olivere/elastic/v7/indices_get_template.go b/vendor/github.com/olivere/elastic/v7/indices_get_template.go index aeafe9128eb0b..28bb4a0e5c8f5 100644 --- a/vendor/github.com/olivere/elastic/v7/indices_get_template.go +++ b/vendor/github.com/olivere/elastic/v7/indices_get_template.go @@ -14,8 +14,14 @@ import ( "github.com/olivere/elastic/v7/uritemplates" ) -// IndicesGetTemplateService returns an index template. -// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/indices-templates.html. +// IndicesGetTemplateService returns an index template (v1). +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the legacy version (7.7 or lower). If you want +// the new version, please use the IndicesGetIndexTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-get-template-v1.html +// for more details. type IndicesGetTemplateService struct { client *Client diff --git a/vendor/github.com/olivere/elastic/v7/indices_put_index_template.go b/vendor/github.com/olivere/elastic/v7/indices_put_index_template.go new file mode 100644 index 0000000000000..fb77657891d54 --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/indices_put_index_template.go @@ -0,0 +1,226 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/olivere/elastic/v7/uritemplates" +) + +// IndicesPutIndexTemplateService creates or updates index templates. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the new version (7.8 or higher) for managing +// index templates. If you want the v1/legacy version, please see e.g. +// IndicesPutTemplateService and friends. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-put-template.html +// for more details on this API. +type IndicesPutIndexTemplateService struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + name string + create *bool + cause string + masterTimeout string + + bodyJson interface{} + bodyString string +} + +// NewIndicesPutIndexTemplateService creates a new IndicesPutIndexTemplateService. +func NewIndicesPutIndexTemplateService(client *Client) *IndicesPutIndexTemplateService { + return &IndicesPutIndexTemplateService{ + client: client, + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *IndicesPutIndexTemplateService) Pretty(pretty bool) *IndicesPutIndexTemplateService { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *IndicesPutIndexTemplateService) Human(human bool) *IndicesPutIndexTemplateService { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *IndicesPutIndexTemplateService) ErrorTrace(errorTrace bool) *IndicesPutIndexTemplateService { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *IndicesPutIndexTemplateService) FilterPath(filterPath ...string) *IndicesPutIndexTemplateService { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *IndicesPutIndexTemplateService) Header(name string, value string) *IndicesPutIndexTemplateService { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *IndicesPutIndexTemplateService) Headers(headers http.Header) *IndicesPutIndexTemplateService { + s.headers = headers + return s +} + +// Name is the name of the index template. +func (s *IndicesPutIndexTemplateService) Name(name string) *IndicesPutIndexTemplateService { + s.name = name + return s +} + +// Create indicates whether the index template should only be added if +// new or can also replace an existing one. +func (s *IndicesPutIndexTemplateService) Create(create bool) *IndicesPutIndexTemplateService { + s.create = &create + return s +} + +// Cause is the user-defined reason for creating/updating the the index template. +func (s *IndicesPutIndexTemplateService) Cause(cause string) *IndicesPutIndexTemplateService { + s.cause = cause + return s +} + +// MasterTimeout specifies the timeout for connection to master. +func (s *IndicesPutIndexTemplateService) MasterTimeout(masterTimeout string) *IndicesPutIndexTemplateService { + s.masterTimeout = masterTimeout + return s +} + +// BodyJson is the index template definition as a JSON serializable +// type, e.g. map[string]interface{}. +func (s *IndicesPutIndexTemplateService) BodyJson(body interface{}) *IndicesPutIndexTemplateService { + s.bodyJson = body + return s +} + +// BodyString is the index template definition as a raw string. +func (s *IndicesPutIndexTemplateService) BodyString(body string) *IndicesPutIndexTemplateService { + s.bodyString = body + return s +} + +// buildURL builds the URL for the operation. +func (s *IndicesPutIndexTemplateService) buildURL() (string, url.Values, error) { + // Build URL + path, err := uritemplates.Expand("/_index_template/{name}", map[string]string{ + "name": s.name, + }) + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.create != nil { + params.Set("create", fmt.Sprint(*s.create)) + } + if s.cause != "" { + params.Set("cause", s.cause) + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *IndicesPutIndexTemplateService) Validate() error { + var invalid []string + if s.name == "" { + invalid = append(invalid, "Name") + } + if s.bodyString == "" && s.bodyJson == nil { + invalid = append(invalid, "BodyJson") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *IndicesPutIndexTemplateService) Do(ctx context.Context) (*IndicesPutIndexTemplateResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Setup HTTP request body + var body interface{} + if s.bodyJson != nil { + body = s.bodyJson + } else { + body = s.bodyString + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "PUT", + Path: path, + Params: params, + Body: body, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(IndicesPutIndexTemplateResponse) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + return nil, err + } + return ret, nil +} + +// IndicesPutIndexTemplateResponse is the response of IndicesPutIndexTemplateService.Do. +type IndicesPutIndexTemplateResponse struct { + Acknowledged bool `json:"acknowledged"` + ShardsAcknowledged bool `json:"shards_acknowledged"` + Index string `json:"index,omitempty"` +} diff --git a/vendor/github.com/olivere/elastic/v7/indices_put_template.go b/vendor/github.com/olivere/elastic/v7/indices_put_template.go index 4ced8e8f496a0..bafa81ed91bc7 100644 --- a/vendor/github.com/olivere/elastic/v7/indices_put_template.go +++ b/vendor/github.com/olivere/elastic/v7/indices_put_template.go @@ -14,8 +14,14 @@ import ( "github.com/olivere/elastic/v7/uritemplates" ) -// IndicesPutTemplateService creates or updates index mappings. -// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/indices-templates.html. +// IndicesPutTemplateService creates or updates templates. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the legacy version (7.7 or lower). If you want +// the new version, please use the IndicesPutIndexTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html +// for more details. type IndicesPutTemplateService struct { client *Client diff --git a/vendor/github.com/olivere/elastic/v7/xpack_async_search_delete.go b/vendor/github.com/olivere/elastic/v7/xpack_async_search_delete.go new file mode 100644 index 0000000000000..0c323440ddccc --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/xpack_async_search_delete.go @@ -0,0 +1,154 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" +) + +// XPackAsyncSearchDelete allows removing an asynchronous search result, +// previously being started with XPackAsyncSearchSubmit service. +// +// For more details, see the documentation at +// https://www.elastic.co/guide/en/elasticsearch/reference/7.9/async-search.html +type XPackAsyncSearchDelete struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + // ID of asynchronous search as returned by XPackAsyncSearchSubmit.Do. + id string +} + +// NewXPackAsyncSearchDelete creates a new XPackAsyncSearchDelete. +func NewXPackAsyncSearchDelete(client *Client) *XPackAsyncSearchDelete { + return &XPackAsyncSearchDelete{ + client: client, + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *XPackAsyncSearchDelete) Pretty(pretty bool) *XPackAsyncSearchDelete { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *XPackAsyncSearchDelete) Human(human bool) *XPackAsyncSearchDelete { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *XPackAsyncSearchDelete) ErrorTrace(errorTrace bool) *XPackAsyncSearchDelete { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *XPackAsyncSearchDelete) FilterPath(filterPath ...string) *XPackAsyncSearchDelete { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *XPackAsyncSearchDelete) Header(name string, value string) *XPackAsyncSearchDelete { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *XPackAsyncSearchDelete) Headers(headers http.Header) *XPackAsyncSearchDelete { + s.headers = headers + return s +} + +// ID of the asynchronous search. +func (s *XPackAsyncSearchDelete) ID(id string) *XPackAsyncSearchDelete { + s.id = id + return s +} + +// buildURL builds the URL for the operation. +func (s *XPackAsyncSearchDelete) buildURL() (string, url.Values, error) { + path := fmt.Sprintf("/_async_search/%s", url.PathEscape(s.id)) + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *XPackAsyncSearchDelete) Validate() error { + var invalid []string + if s.id == "" { + invalid = append(invalid, "ID") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *XPackAsyncSearchDelete) Do(ctx context.Context) (*XPackAsyncSearchDeleteResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "DELETE", + Path: path, + Params: params, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(XPackAsyncSearchDeleteResponse) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + return nil, err + } + return ret, nil +} + +// XPackAsyncSearchDeleteResponse is the outcome of calling XPackAsyncSearchDelete.Do. +type XPackAsyncSearchDeleteResponse struct { + Acknowledged bool `json:"acknowledged"` +} diff --git a/vendor/github.com/olivere/elastic/v7/xpack_async_search_get.go b/vendor/github.com/olivere/elastic/v7/xpack_async_search_get.go new file mode 100644 index 0000000000000..d39d49268c51d --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/xpack_async_search_get.go @@ -0,0 +1,178 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" +) + +// XPackAsyncSearchGet allows retrieving an asynchronous search result, +// previously being started with XPackAsyncSearchSubmit service. +// +// For more details, see the documentation at +// https://www.elastic.co/guide/en/elasticsearch/reference/7.9/async-search.html +type XPackAsyncSearchGet struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + // ID of asynchronous search as returned by XPackAsyncSearchSubmit.Do. + id string + // waitForCompletionTimeout is the duration the call should wait for a result + // before timing out. The default is 1 second. + waitForCompletionTimeout string + // keepAlive asks Elasticsearch to keep the ID and its results even + // after the search has been completed. + keepAlive string +} + +// NewXPackAsyncSearchGet creates a new XPackAsyncSearchGet. +func NewXPackAsyncSearchGet(client *Client) *XPackAsyncSearchGet { + return &XPackAsyncSearchGet{ + client: client, + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *XPackAsyncSearchGet) Pretty(pretty bool) *XPackAsyncSearchGet { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *XPackAsyncSearchGet) Human(human bool) *XPackAsyncSearchGet { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *XPackAsyncSearchGet) ErrorTrace(errorTrace bool) *XPackAsyncSearchGet { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *XPackAsyncSearchGet) FilterPath(filterPath ...string) *XPackAsyncSearchGet { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *XPackAsyncSearchGet) Header(name string, value string) *XPackAsyncSearchGet { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *XPackAsyncSearchGet) Headers(headers http.Header) *XPackAsyncSearchGet { + s.headers = headers + return s +} + +// ID of the asynchronous search. +func (s *XPackAsyncSearchGet) ID(id string) *XPackAsyncSearchGet { + s.id = id + return s +} + +// WaitForCompletionTimeout specifies the time the service waits for retrieving +// a complete result. If the timeout expires, you'll get the current results which +// might not be complete. +func (s *XPackAsyncSearchGet) WaitForCompletionTimeout(waitForCompletionTimeout string) *XPackAsyncSearchGet { + s.waitForCompletionTimeout = waitForCompletionTimeout + return s +} + +// KeepAlive is the time the search results are kept by Elasticsearch before +// being garbage collected. +func (s *XPackAsyncSearchGet) KeepAlive(keepAlive string) *XPackAsyncSearchGet { + s.keepAlive = keepAlive + return s +} + +// buildURL builds the URL for the operation. +func (s *XPackAsyncSearchGet) buildURL() (string, url.Values, error) { + path := fmt.Sprintf("/_async_search/%s", url.PathEscape(s.id)) + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.waitForCompletionTimeout != "" { + params.Set("wait_for_completion_timeout", s.waitForCompletionTimeout) + } + if s.keepAlive != "" { + params.Set("keep_alive", s.keepAlive) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *XPackAsyncSearchGet) Validate() error { + var invalid []string + if s.id == "" { + invalid = append(invalid, "ID") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *XPackAsyncSearchGet) Do(ctx context.Context) (*XPackAsyncSearchResult, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "GET", + Path: path, + Params: params, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(XPackAsyncSearchResult) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + ret.Header = res.Header + return nil, err + } + ret.Header = res.Header + return ret, nil +} diff --git a/vendor/github.com/olivere/elastic/v7/xpack_async_search_submit.go b/vendor/github.com/olivere/elastic/v7/xpack_async_search_submit.go new file mode 100644 index 0000000000000..f2c13b69d09a2 --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/xpack_async_search_submit.go @@ -0,0 +1,718 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/url" + "reflect" + "strings" + + "github.com/olivere/elastic/v7/uritemplates" +) + +// XPackAsyncSearchSubmit is an XPack API for asynchronously +// searching for documents in Elasticsearch. +// +// For more details, see the documentation at +// https://www.elastic.co/guide/en/elasticsearch/reference/7.9/async-search.html +type XPackAsyncSearchSubmit struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + searchSource *SearchSource // q + source interface{} + searchType string // search_type + index []string + typ []string + routing string // routing + preference string // preference + requestCache *bool // request_cache + ignoreUnavailable *bool // ignore_unavailable + ignoreThrottled *bool // ignore_throttled + allowNoIndices *bool // allow_no_indices + expandWildcards string // expand_wildcards + lenient *bool // lenient + maxResponseSize int64 + allowPartialSearchResults *bool // allow_partial_search_results + typedKeys *bool // typed_keys + seqNoPrimaryTerm *bool // seq_no_primary_term + batchedReduceSize *int // batched_reduce_size + maxConcurrentShardRequests *int // max_concurrent_shard_requests + preFilterShardSize *int // pre_filter_shard_size + restTotalHitsAsInt *bool // rest_total_hits_as_int + + ccsMinimizeRoundtrips *bool // ccs_minimize_roundtrips + + waitForCompletionTimeout string // e.g. "1s" + keepOnCompletion *bool + keepAlive string // e.g. "1h" +} + +// NewXPackAsyncSearchSubmit creates a new service for asynchronously +// searching in Elasticsearch. +func NewXPackAsyncSearchSubmit(client *Client) *XPackAsyncSearchSubmit { + builder := &XPackAsyncSearchSubmit{ + client: client, + searchSource: NewSearchSource(), + } + return builder +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *XPackAsyncSearchSubmit) Pretty(pretty bool) *XPackAsyncSearchSubmit { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *XPackAsyncSearchSubmit) Human(human bool) *XPackAsyncSearchSubmit { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *XPackAsyncSearchSubmit) ErrorTrace(errorTrace bool) *XPackAsyncSearchSubmit { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *XPackAsyncSearchSubmit) FilterPath(filterPath ...string) *XPackAsyncSearchSubmit { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *XPackAsyncSearchSubmit) Header(name string, value string) *XPackAsyncSearchSubmit { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *XPackAsyncSearchSubmit) Headers(headers http.Header) *XPackAsyncSearchSubmit { + s.headers = headers + return s +} + +// SearchSource sets the search source builder to use with this service. +func (s *XPackAsyncSearchSubmit) SearchSource(searchSource *SearchSource) *XPackAsyncSearchSubmit { + s.searchSource = searchSource + if s.searchSource == nil { + s.searchSource = NewSearchSource() + } + return s +} + +// Source allows the user to set the request body manually without using +// any of the structs and interfaces in Elastic. +func (s *XPackAsyncSearchSubmit) Source(source interface{}) *XPackAsyncSearchSubmit { + s.source = source + return s +} + +// Index sets the names of the indices to use for search. +func (s *XPackAsyncSearchSubmit) Index(index ...string) *XPackAsyncSearchSubmit { + s.index = append(s.index, index...) + return s +} + +// Type adds search restrictions for a list of types. +// +// Deprecated: Types are in the process of being removed. Instead of using a type, prefer to +// filter on a field on the document. +func (s *XPackAsyncSearchSubmit) Type(typ ...string) *XPackAsyncSearchSubmit { + s.typ = append(s.typ, typ...) + return s +} + +// Timeout sets the timeout to use, e.g. "1s" or "1000ms". +func (s *XPackAsyncSearchSubmit) Timeout(timeout string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Timeout(timeout) + return s +} + +// Profile sets the Profile API flag on the search source. +// When enabled, a search executed by this service will return query +// profiling data. +func (s *XPackAsyncSearchSubmit) Profile(profile bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Profile(profile) + return s +} + +// Collapse adds field collapsing. +func (s *XPackAsyncSearchSubmit) Collapse(collapse *CollapseBuilder) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Collapse(collapse) + return s +} + +// TimeoutInMillis sets the timeout in milliseconds. +func (s *XPackAsyncSearchSubmit) TimeoutInMillis(timeoutInMillis int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.TimeoutInMillis(timeoutInMillis) + return s +} + +// TerminateAfter specifies the maximum number of documents to collect for +// each shard, upon reaching which the query execution will terminate early. +func (s *XPackAsyncSearchSubmit) TerminateAfter(terminateAfter int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.TerminateAfter(terminateAfter) + return s +} + +// SearchType sets the search operation type. Valid values are: +// "dfs_query_then_fetch" and "query_then_fetch". +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/search-request-search-type.html +// for details. +func (s *XPackAsyncSearchSubmit) SearchType(searchType string) *XPackAsyncSearchSubmit { + s.searchType = searchType + return s +} + +// Routing is a list of specific routing values to control the shards +// the search will be executed on. +func (s *XPackAsyncSearchSubmit) Routing(routings ...string) *XPackAsyncSearchSubmit { + s.routing = strings.Join(routings, ",") + return s +} + +// Preference sets the preference to execute the search. Defaults to +// randomize across shards ("random"). Can be set to "_local" to prefer +// local shards, "_primary" to execute on primary shards only, +// or a custom value which guarantees that the same order will be used +// across different requests. +func (s *XPackAsyncSearchSubmit) Preference(preference string) *XPackAsyncSearchSubmit { + s.preference = preference + return s +} + +// RequestCache indicates whether the cache should be used for this +// request or not, defaults to index level setting. +func (s *XPackAsyncSearchSubmit) RequestCache(requestCache bool) *XPackAsyncSearchSubmit { + s.requestCache = &requestCache + return s +} + +// Query sets the query to perform, e.g. MatchAllQuery. +func (s *XPackAsyncSearchSubmit) Query(query Query) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Query(query) + return s +} + +// PostFilter will be executed after the query has been executed and +// only affects the search hits, not the aggregations. +// This filter is always executed as the last filtering mechanism. +func (s *XPackAsyncSearchSubmit) PostFilter(postFilter Query) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.PostFilter(postFilter) + return s +} + +// FetchSource indicates whether the response should contain the stored +// _source for every hit. +func (s *XPackAsyncSearchSubmit) FetchSource(fetchSource bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.FetchSource(fetchSource) + return s +} + +// FetchSourceContext indicates how the _source should be fetched. +func (s *XPackAsyncSearchSubmit) FetchSourceContext(fetchSourceContext *FetchSourceContext) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.FetchSourceContext(fetchSourceContext) + return s +} + +// Highlight adds highlighting to the search. +func (s *XPackAsyncSearchSubmit) Highlight(highlight *Highlight) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Highlight(highlight) + return s +} + +// GlobalSuggestText defines the global text to use with all suggesters. +// This avoids repetition. +func (s *XPackAsyncSearchSubmit) GlobalSuggestText(globalText string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.GlobalSuggestText(globalText) + return s +} + +// Suggester adds a suggester to the search. +func (s *XPackAsyncSearchSubmit) Suggester(suggester Suggester) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Suggester(suggester) + return s +} + +// Aggregation adds an aggreation to perform as part of the search. +func (s *XPackAsyncSearchSubmit) Aggregation(name string, aggregation Aggregation) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Aggregation(name, aggregation) + return s +} + +// MinScore sets the minimum score below which docs will be filtered out. +func (s *XPackAsyncSearchSubmit) MinScore(minScore float64) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.MinScore(minScore) + return s +} + +// From index to start the search from. Defaults to 0. +func (s *XPackAsyncSearchSubmit) From(from int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.From(from) + return s +} + +// Size is the number of search hits to return. Defaults to 10. +func (s *XPackAsyncSearchSubmit) Size(size int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Size(size) + return s +} + +// Explain indicates whether each search hit should be returned with +// an explanation of the hit (ranking). +func (s *XPackAsyncSearchSubmit) Explain(explain bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Explain(explain) + return s +} + +// Version indicates whether each search hit should be returned with +// a version associated to it. +func (s *XPackAsyncSearchSubmit) Version(version bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Version(version) + return s +} + +// Sort adds a sort order. +func (s *XPackAsyncSearchSubmit) Sort(field string, ascending bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Sort(field, ascending) + return s +} + +// SortWithInfo adds a sort order. +func (s *XPackAsyncSearchSubmit) SortWithInfo(info SortInfo) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.SortWithInfo(info) + return s +} + +// SortBy adds a sort order. +func (s *XPackAsyncSearchSubmit) SortBy(sorter ...Sorter) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.SortBy(sorter...) + return s +} + +// DocvalueField adds a single field to load from the field data cache +// and return as part of the search. +func (s *XPackAsyncSearchSubmit) DocvalueField(docvalueField string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DocvalueField(docvalueField) + return s +} + +// DocvalueFieldWithFormat adds a single field to load from the field data cache +// and return as part of the search. +func (s *XPackAsyncSearchSubmit) DocvalueFieldWithFormat(docvalueField DocvalueField) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DocvalueFieldWithFormat(docvalueField) + return s +} + +// DocvalueFields adds one or more fields to load from the field data cache +// and return as part of the search. +func (s *XPackAsyncSearchSubmit) DocvalueFields(docvalueFields ...string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DocvalueFields(docvalueFields...) + return s +} + +// DocvalueFieldsWithFormat adds one or more fields to load from the field data cache +// and return as part of the search. +func (s *XPackAsyncSearchSubmit) DocvalueFieldsWithFormat(docvalueFields ...DocvalueField) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DocvalueFieldsWithFormat(docvalueFields...) + return s +} + +// NoStoredFields indicates that no stored fields should be loaded, resulting in only +// id and type to be returned per field. +func (s *XPackAsyncSearchSubmit) NoStoredFields() *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.NoStoredFields() + return s +} + +// StoredField adds a single field to load and return (note, must be stored) as +// part of the search request. If none are specified, the source of the +// document will be returned. +func (s *XPackAsyncSearchSubmit) StoredField(fieldName string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.StoredField(fieldName) + return s +} + +// StoredFields sets the fields to load and return as part of the search request. +// If none are specified, the source of the document will be returned. +func (s *XPackAsyncSearchSubmit) StoredFields(fields ...string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.StoredFields(fields...) + return s +} + +// TrackScores is applied when sorting and controls if scores will be +// tracked as well. Defaults to false. +func (s *XPackAsyncSearchSubmit) TrackScores(trackScores bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.TrackScores(trackScores) + return s +} + +// TrackTotalHits controls if the total hit count for the query should be tracked. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.1/search-request-track-total-hits.html +// for details. +func (s *XPackAsyncSearchSubmit) TrackTotalHits(trackTotalHits interface{}) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.TrackTotalHits(trackTotalHits) + return s +} + +// SearchAfter allows a different form of pagination by using a live cursor, +// using the results of the previous page to help the retrieval of the next. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/search-request-search-after.html +func (s *XPackAsyncSearchSubmit) SearchAfter(sortValues ...interface{}) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.SearchAfter(sortValues...) + return s +} + +// DefaultRescoreWindowSize sets the rescore window size for rescores +// that don't specify their window. +func (s *XPackAsyncSearchSubmit) DefaultRescoreWindowSize(defaultRescoreWindowSize int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DefaultRescoreWindowSize(defaultRescoreWindowSize) + return s +} + +// Rescorer adds a rescorer to the search. +func (s *XPackAsyncSearchSubmit) Rescorer(rescore *Rescore) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Rescorer(rescore) + return s +} + +// IgnoreUnavailable indicates whether the specified concrete indices +// should be ignored when unavailable (missing or closed). +func (s *XPackAsyncSearchSubmit) IgnoreUnavailable(ignoreUnavailable bool) *XPackAsyncSearchSubmit { + s.ignoreUnavailable = &ignoreUnavailable + return s +} + +// IgnoreThrottled indicates whether specified concrete, expanded or aliased +// indices should be ignored when throttled. +func (s *XPackAsyncSearchSubmit) IgnoreThrottled(ignoreThrottled bool) *XPackAsyncSearchSubmit { + s.ignoreThrottled = &ignoreThrottled + return s +} + +// AllowNoIndices indicates whether to ignore if a wildcard indices +// expression resolves into no concrete indices. (This includes `_all` string +// or when no indices have been specified). +func (s *XPackAsyncSearchSubmit) AllowNoIndices(allowNoIndices bool) *XPackAsyncSearchSubmit { + s.allowNoIndices = &allowNoIndices + return s +} + +// ExpandWildcards indicates whether to expand wildcard expression to +// concrete indices that are open, closed or both. +func (s *XPackAsyncSearchSubmit) ExpandWildcards(expandWildcards string) *XPackAsyncSearchSubmit { + s.expandWildcards = expandWildcards + return s +} + +// Lenient specifies whether format-based query failures (such as providing +// text to a numeric field) should be ignored. +func (s *XPackAsyncSearchSubmit) Lenient(lenient bool) *XPackAsyncSearchSubmit { + s.lenient = &lenient + return s +} + +// MaxResponseSize sets an upper limit on the response body size that we accept, +// to guard against OOM situations. +func (s *XPackAsyncSearchSubmit) MaxResponseSize(maxResponseSize int64) *XPackAsyncSearchSubmit { + s.maxResponseSize = maxResponseSize + return s +} + +// AllowPartialSearchResults indicates if an error should be returned if +// there is a partial search failure or timeout. +func (s *XPackAsyncSearchSubmit) AllowPartialSearchResults(enabled bool) *XPackAsyncSearchSubmit { + s.allowPartialSearchResults = &enabled + return s +} + +// TypedKeys specifies whether aggregation and suggester names should be +// prefixed by their respective types in the response. +func (s *XPackAsyncSearchSubmit) TypedKeys(enabled bool) *XPackAsyncSearchSubmit { + s.typedKeys = &enabled + return s +} + +// SeqNoPrimaryTerm specifies whether to return sequence number and +// primary term of the last modification of each hit. +func (s *XPackAsyncSearchSubmit) SeqNoPrimaryTerm(enabled bool) *XPackAsyncSearchSubmit { + s.seqNoPrimaryTerm = &enabled + return s +} + +// BatchedReduceSize specifies the number of shard results that should be reduced +// at once on the coordinating node. This value should be used as a protection +// mechanism to reduce the memory overhead per search request if the potential +// number of shards in the request can be large. +func (s *XPackAsyncSearchSubmit) BatchedReduceSize(size int) *XPackAsyncSearchSubmit { + s.batchedReduceSize = &size + return s +} + +// MaxConcurrentShardRequests specifies the number of concurrent shard requests +// this search executes concurrently. This value should be used to limit the +// impact of the search on the cluster in order to limit the number of +// concurrent shard requests. +func (s *XPackAsyncSearchSubmit) MaxConcurrentShardRequests(max int) *XPackAsyncSearchSubmit { + s.maxConcurrentShardRequests = &max + return s +} + +// PreFilterShardSize specifies a threshold that enforces a pre-filter roundtrip +// to prefilter search shards based on query rewriting if the number of shards +// the search request expands to exceeds the threshold. This filter roundtrip +// can limit the number of shards significantly if for instance a shard can +// not match any documents based on it's rewrite method i.e. if date filters are +// mandatory to match but the shard bounds and the query are disjoint. +func (s *XPackAsyncSearchSubmit) PreFilterShardSize(threshold int) *XPackAsyncSearchSubmit { + s.preFilterShardSize = &threshold + return s +} + +// RestTotalHitsAsInt indicates whether hits.total should be rendered as an +// integer or an object in the rest search response. +func (s *XPackAsyncSearchSubmit) RestTotalHitsAsInt(enabled bool) *XPackAsyncSearchSubmit { + s.restTotalHitsAsInt = &enabled + return s +} + +// CCSMinimizeRoundtrips indicates whether network round-trips should be minimized +// as part of cross-cluster search requests execution. +func (s *XPackAsyncSearchSubmit) CCSMinimizeRoundtrips(enabled bool) *XPackAsyncSearchSubmit { + s.ccsMinimizeRoundtrips = &enabled + return s +} + +// WaitForCompletionTimeout is suitable for DoAsync only. It specifies the +// timeout for the Search to wait for completion before returning an ID to +// return the results asynchronously. In other words: If the search takes +// longer than this value (default is 1 second), then you need to call +// GetAsync to retrieve its final results. +func (s *XPackAsyncSearchSubmit) WaitForCompletionTimeout(timeout string) *XPackAsyncSearchSubmit { + s.waitForCompletionTimeout = timeout + return s +} + +// KeepOnCompletion is suitable for DoAsync only. It indicates whether the +// asynchronous search ID and its results should be kept even after the +// search (and its results) are completed and retrieved. +func (s *XPackAsyncSearchSubmit) KeepOnCompletion(keepOnCompletion bool) *XPackAsyncSearchSubmit { + s.keepOnCompletion = &keepOnCompletion + return s +} + +// KeepAlive can only be used with DoAsync. If set, KeepAlive specifies the +// duration after which search ID and its results are removed from the +// Elasticsearch cluster and hence can no longer be retrieved with GetAsync. +func (s *XPackAsyncSearchSubmit) KeepAlive(keepAlive string) *XPackAsyncSearchSubmit { + s.keepAlive = keepAlive + return s +} + +// buildURL builds the URL for the operation. +func (s *XPackAsyncSearchSubmit) buildURL() (string, url.Values, error) { + var err error + var path string + + if len(s.index) > 0 && len(s.typ) > 0 { + path, err = uritemplates.Expand("/{index}/{type}/_async_search", map[string]string{ + "index": strings.Join(s.index, ","), + "type": strings.Join(s.typ, ","), + }) + } else if len(s.index) > 0 { + path, err = uritemplates.Expand("/{index}/_async_search", map[string]string{ + "index": strings.Join(s.index, ","), + }) + } else if len(s.typ) > 0 { + path, err = uritemplates.Expand("/_all/{type}/_async_search", map[string]string{ + "type": strings.Join(s.typ, ","), + }) + } else { + path = "/_async_search" + } + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.searchType != "" { + params.Set("search_type", s.searchType) + } + if s.routing != "" { + params.Set("routing", s.routing) + } + if s.preference != "" { + params.Set("preference", s.preference) + } + if v := s.requestCache; v != nil { + params.Set("request_cache", fmt.Sprint(*v)) + } + if v := s.allowNoIndices; v != nil { + params.Set("allow_no_indices", fmt.Sprint(*v)) + } + if s.expandWildcards != "" { + params.Set("expand_wildcards", s.expandWildcards) + } + if v := s.lenient; v != nil { + params.Set("lenient", fmt.Sprint(*v)) + } + if v := s.ignoreUnavailable; v != nil { + params.Set("ignore_unavailable", fmt.Sprint(*v)) + } + if v := s.ignoreThrottled; v != nil { + params.Set("ignore_throttled", fmt.Sprint(*v)) + } + if s.seqNoPrimaryTerm != nil { + params.Set("seq_no_primary_term", fmt.Sprint(*s.seqNoPrimaryTerm)) + } + if v := s.allowPartialSearchResults; v != nil { + params.Set("allow_partial_search_results", fmt.Sprint(*v)) + } + if v := s.typedKeys; v != nil { + params.Set("typed_keys", fmt.Sprint(*v)) + } + if v := s.batchedReduceSize; v != nil { + params.Set("batched_reduce_size", fmt.Sprint(*v)) + } + if v := s.maxConcurrentShardRequests; v != nil { + params.Set("max_concurrent_shard_requests", fmt.Sprint(*v)) + } + if v := s.preFilterShardSize; v != nil { + params.Set("pre_filter_shard_size", fmt.Sprint(*v)) + } + if v := s.restTotalHitsAsInt; v != nil { + params.Set("rest_total_hits_as_int", fmt.Sprint(*v)) + } + if v := s.ccsMinimizeRoundtrips; v != nil { + params.Set("ccs_minimize_roundtrips", fmt.Sprint(*v)) + } + if s.waitForCompletionTimeout != "" { + params.Set("wait_for_completion_timeout", s.waitForCompletionTimeout) + } + if v := s.keepOnCompletion; v != nil { + params.Set("keep_on_completion", fmt.Sprint(*v)) + } + if s.keepAlive != "" { + params.Set("keep_alive", s.keepAlive) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *XPackAsyncSearchSubmit) Validate() error { + return nil +} + +// Do executes the search and returns a XPackAsyncSearchResult. +func (s *XPackAsyncSearchSubmit) Do(ctx context.Context) (*XPackAsyncSearchResult, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Perform request + var body interface{} + if s.source != nil { + body = s.source + } else { + src, err := s.searchSource.Source() + if err != nil { + return nil, err + } + body = src + } + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "POST", + Path: path, + Params: params, + Body: body, + Headers: s.headers, + MaxResponseSize: s.maxResponseSize, + }) + if err != nil { + return nil, err + } + + // Return search results + ret := new(XPackAsyncSearchResult) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + ret.Header = res.Header + return nil, err + } + ret.Header = res.Header + return ret, nil +} + +// XPackAsyncSearchResult is the outcome of starting an asynchronous search +// or retrieving a search result with XPackAsyncSearchGet. +type XPackAsyncSearchResult struct { + Header http.Header `json:"-"` + ID string `json:"id,omitempty"` + IsRunning bool `json:"is_running"` + IsPartial bool `json:"is_partial"` + StartTimeMillis int64 `json:"start_time_in_millis,omitempty"` + ExpirationTimeMillis int64 `json:"expiration_time_in_millis,omitempty"` + Response *SearchResult `json:"response,omitempty"` + Error *ErrorDetails `json:"error,omitempty"` +} + +// Each is a utility function to iterate over all hits. It saves you from +// checking for nil values. Notice that Each will ignore errors in +// serializing JSON and hits with empty/nil _source will get an empty +// value +func (r *XPackAsyncSearchResult) Each(typ reflect.Type) []interface{} { + if r == nil || r.Response == nil || r.Response.Hits == nil || r.Response.Hits.Hits == nil || len(r.Response.Hits.Hits) == 0 { + return nil + } + var slice []interface{} + for _, hit := range r.Response.Hits.Hits { + v := reflect.New(typ).Elem() + if hit.Source == nil { + slice = append(slice, v.Interface()) + continue + } + if err := json.Unmarshal(hit.Source, v.Addr().Interface()); err == nil { + slice = append(slice, v.Interface()) + } + } + return slice +} diff --git a/vendor/github.com/pquerna/otp/.travis.yml b/vendor/github.com/pquerna/otp/.travis.yml index 5a9ed93afbf02..016c02c717512 100644 --- a/vendor/github.com/pquerna/otp/.travis.yml +++ b/vendor/github.com/pquerna/otp/.travis.yml @@ -1,7 +1,10 @@ +arch: + - amd64 + - ppc64le language: go env: - GO111MODULE=on go: - - "1.12" + - "1.15" diff --git a/vendor/github.com/pquerna/otp/README.md b/vendor/github.com/pquerna/otp/README.md index 148e8980d6d1d..4cb9b71dc3051 100644 --- a/vendor/github.com/pquerna/otp/README.md +++ b/vendor/github.com/pquerna/otp/README.md @@ -1,6 +1,6 @@ # otp: One Time Password utilities Go / Golang -[![GoDoc](https://godoc.org/github.com/pquerna/otp?status.svg)](https://godoc.org/github.com/pquerna/otp) [![Build Status](https://travis-ci.org/pquerna/otp.svg?branch=master)](https://travis-ci.org/pquerna/otp) +[![PkgGoDev](https://pkg.go.dev/badge/github.com/pquerna/otp)](https://pkg.go.dev/github.com/pquerna/otp) [![Build Status](https://travis-ci.org/pquerna/otp.svg?branch=master)](https://travis-ci.org/pquerna/otp) # Why One Time Passwords? diff --git a/vendor/github.com/pquerna/otp/hotp/hotp.go b/vendor/github.com/pquerna/otp/hotp/hotp.go index 5e99e2218e47c..7b94734045b18 100644 --- a/vendor/github.com/pquerna/otp/hotp/hotp.go +++ b/vendor/github.com/pquerna/otp/hotp/hotp.go @@ -19,6 +19,7 @@ package hotp import ( "github.com/pquerna/otp" + "io" "crypto/hmac" "crypto/rand" @@ -152,6 +153,8 @@ type GenerateOpts struct { Digits otp.Digits // Algorithm to use for HMAC. Defaults to SHA1. Algorithm otp.Algorithm + // Reader to use for generating HOTP Key. + Rand io.Reader } var b32NoPadding = base32.StdEncoding.WithPadding(base32.NoPadding) @@ -175,6 +178,10 @@ func Generate(opts GenerateOpts) (*otp.Key, error) { opts.Digits = otp.DigitsSix } + if opts.Rand == nil { + opts.Rand = rand.Reader + } + // otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example v := url.Values{} @@ -182,7 +189,7 @@ func Generate(opts GenerateOpts) (*otp.Key, error) { v.Set("secret", b32NoPadding.EncodeToString(opts.Secret)) } else { secret := make([]byte, opts.SecretSize) - _, err := rand.Read(secret) + _, err := opts.Rand.Read(secret) if err != nil { return nil, err } diff --git a/vendor/github.com/pquerna/otp/otp.go b/vendor/github.com/pquerna/otp/otp.go index 5db93029cee1a..9f20983709ffa 100644 --- a/vendor/github.com/pquerna/otp/otp.go +++ b/vendor/github.com/pquerna/otp/otp.go @@ -31,6 +31,7 @@ import ( "image" "net/url" "strings" + "strconv" ) // Error when attempting to convert the secret from base32 to raw bytes. @@ -138,6 +139,18 @@ func (k *Key) Secret() string { return q.Get("secret") } +// Period returns a tiny int representing the rotation time in seconds. +func (k *Key) Period() uint64 { + q := k.url.Query() + + if u, err := strconv.ParseUint(q.Get("period"), 10, 64); err == nil { + return u + } + + // If no period is defined 30 seconds is the default per (rfc6238) + return 30 +} + // URL returns the OTP URL as a string func (k *Key) URL() string { return k.url.String() @@ -148,6 +161,9 @@ func (k *Key) URL() string { type Algorithm int const ( + // AlgorithmSHA1 should be used for compatibility with Google Authenticator. + // + // See https://github.com/pquerna/otp/issues/55 for additional details. AlgorithmSHA1 Algorithm = iota AlgorithmSHA256 AlgorithmSHA512 diff --git a/vendor/github.com/pquerna/otp/totp/totp.go b/vendor/github.com/pquerna/otp/totp/totp.go index b46fa567e60d4..db5ed36d828e9 100644 --- a/vendor/github.com/pquerna/otp/totp/totp.go +++ b/vendor/github.com/pquerna/otp/totp/totp.go @@ -20,6 +20,7 @@ package totp import ( "github.com/pquerna/otp" "github.com/pquerna/otp/hotp" + "io" "crypto/rand" "encoding/base32" @@ -142,6 +143,8 @@ type GenerateOpts struct { Digits otp.Digits // Algorithm to use for HMAC. Defaults to SHA1. Algorithm otp.Algorithm + // Reader to use for generating TOTP Key. + Rand io.Reader } var b32NoPadding = base32.StdEncoding.WithPadding(base32.NoPadding) @@ -169,6 +172,10 @@ func Generate(opts GenerateOpts) (*otp.Key, error) { opts.Digits = otp.DigitsSix } + if opts.Rand == nil { + opts.Rand = rand.Reader + } + // otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example v := url.Values{} @@ -176,7 +183,7 @@ func Generate(opts GenerateOpts) (*otp.Key, error) { v.Set("secret", b32NoPadding.EncodeToString(opts.Secret)) } else { secret := make([]byte, opts.SecretSize) - _, err := rand.Read(secret) + _, err := opts.Rand.Read(secret) if err != nil { return nil, err } diff --git a/vendor/github.com/rivo/uniseg/LICENSE.txt b/vendor/github.com/rivo/uniseg/LICENSE.txt new file mode 100644 index 0000000000000..5040f1ef808d9 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Oliver Kuederle + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/rivo/uniseg/README.md b/vendor/github.com/rivo/uniseg/README.md new file mode 100644 index 0000000000000..f8da293e15eaa --- /dev/null +++ b/vendor/github.com/rivo/uniseg/README.md @@ -0,0 +1,62 @@ +# Unicode Text Segmentation for Go + +[![Godoc Reference](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/rivo/uniseg) +[![Go Report](https://img.shields.io/badge/go%20report-A%2B-brightgreen.svg)](https://goreportcard.com/report/github.com/rivo/uniseg) + +This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](http://unicode.org/reports/tr29/) (Unicode version 12.0.0). + +At this point, only the determination of grapheme cluster boundaries is implemented. + +## Background + +In Go, [strings are read-only slices of bytes](https://blog.golang.org/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples: + +|String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters| +|-|-|-|-| +|Käse|6 bytes: `4b 61 cc 88 73 65`|5 code points: `4b 61 308 73 65`|4 clusters: `[4b],[61 308],[73],[65]`| +|🏳️‍🌈|14 bytes: `f0 9f 8f b3 ef b8 8f e2 80 8d f0 9f 8c 88`|4 code points: `1f3f3 fe0f 200d 1f308`|1 cluster: `[1f3f3 fe0f 200d 1f308]`| +|🇩🇪|8 bytes: `f0 9f 87 a9 f0 9f 87 aa`|2 code points: `1f1e9 1f1ea`|1 cluster: `[1f1e9 1f1ea]`| + +This package provides a tool to iterate over these grapheme clusters. This may be used to determine the number of user-perceived characters, to split strings in their intended places, or to extract individual characters which form a unit. + +## Installation + +```bash +go get github.com/rivo/uniseg +``` + +## Basic Example + +```go +package uniseg + +import ( + "fmt" + + "github.com/rivo/uniseg" +) + +func main() { + gr := uniseg.NewGraphemes("👍🏼!") + for gr.Next() { + fmt.Printf("%x ", gr.Runes()) + } + // Output: [1f44d 1f3fc] [21] +} +``` + +## Documentation + +Refer to https://godoc.org/github.com/rivo/uniseg for the package's documentation. + +## Dependencies + +This package does not depend on any packages outside the standard library. + +## Your Feedback + +Add your issue here on GitHub. Feel free to get in touch if you have any questions. + +## Version + +Version tags will be introduced once Golang modules are official. Consider this version 0.1. diff --git a/vendor/github.com/rivo/uniseg/doc.go b/vendor/github.com/rivo/uniseg/doc.go new file mode 100644 index 0000000000000..60c737d7b3e1a --- /dev/null +++ b/vendor/github.com/rivo/uniseg/doc.go @@ -0,0 +1,8 @@ +/* +Package uniseg implements Unicode Text Segmentation according to Unicode +Standard Annex #29 (http://unicode.org/reports/tr29/). + +At this point, only the determination of grapheme cluster boundaries is +implemented. +*/ +package uniseg diff --git a/vendor/github.com/rivo/uniseg/go.mod b/vendor/github.com/rivo/uniseg/go.mod new file mode 100644 index 0000000000000..a54280b2ded33 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/go.mod @@ -0,0 +1,3 @@ +module github.com/rivo/uniseg + +go 1.12 diff --git a/vendor/github.com/rivo/uniseg/grapheme.go b/vendor/github.com/rivo/uniseg/grapheme.go new file mode 100644 index 0000000000000..207157f5e4cf2 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/grapheme.go @@ -0,0 +1,268 @@ +package uniseg + +import "unicode/utf8" + +// The states of the grapheme cluster parser. +const ( + grAny = iota + grCR + grControlLF + grL + grLVV + grLVTT + grPrepend + grExtendedPictographic + grExtendedPictographicZWJ + grRIOdd + grRIEven +) + +// The grapheme cluster parser's breaking instructions. +const ( + grNoBoundary = iota + grBoundary +) + +// The grapheme cluster parser's state transitions. Maps (state, property) to +// (new state, breaking instruction, rule number). The breaking instruction +// always refers to the boundary between the last and next code point. +// +// This map is queried as follows: +// +// 1. Find specific state + specific property. Stop if found. +// 2. Find specific state + any property. +// 3. Find any state + specific property. +// 4. If only (2) or (3) (but not both) was found, stop. +// 5. If both (2) and (3) were found, use state and breaking instruction from +// the transition with the lower rule number, prefer (3) if rule numbers +// are equal. Stop. +// 6. Assume grAny and grBoundary. +var grTransitions = map[[2]int][3]int{ + // GB5 + {grAny, prCR}: {grCR, grBoundary, 50}, + {grAny, prLF}: {grControlLF, grBoundary, 50}, + {grAny, prControl}: {grControlLF, grBoundary, 50}, + + // GB4 + {grCR, prAny}: {grAny, grBoundary, 40}, + {grControlLF, prAny}: {grAny, grBoundary, 40}, + + // GB3. + {grCR, prLF}: {grAny, grNoBoundary, 30}, + + // GB6. + {grAny, prL}: {grL, grBoundary, 9990}, + {grL, prL}: {grL, grNoBoundary, 60}, + {grL, prV}: {grLVV, grNoBoundary, 60}, + {grL, prLV}: {grLVV, grNoBoundary, 60}, + {grL, prLVT}: {grLVTT, grNoBoundary, 60}, + + // GB7. + {grAny, prLV}: {grLVV, grBoundary, 9990}, + {grAny, prV}: {grLVV, grBoundary, 9990}, + {grLVV, prV}: {grLVV, grNoBoundary, 70}, + {grLVV, prT}: {grLVTT, grNoBoundary, 70}, + + // GB8. + {grAny, prLVT}: {grLVTT, grBoundary, 9990}, + {grAny, prT}: {grLVTT, grBoundary, 9990}, + {grLVTT, prT}: {grLVTT, grNoBoundary, 80}, + + // GB9. + {grAny, prExtend}: {grAny, grNoBoundary, 90}, + {grAny, prZWJ}: {grAny, grNoBoundary, 90}, + + // GB9a. + {grAny, prSpacingMark}: {grAny, grNoBoundary, 91}, + + // GB9b. + {grAny, prPreprend}: {grPrepend, grBoundary, 9990}, + {grPrepend, prAny}: {grAny, grNoBoundary, 92}, + + // GB11. + {grAny, prExtendedPictographic}: {grExtendedPictographic, grBoundary, 9990}, + {grExtendedPictographic, prExtend}: {grExtendedPictographic, grNoBoundary, 110}, + {grExtendedPictographic, prZWJ}: {grExtendedPictographicZWJ, grNoBoundary, 110}, + {grExtendedPictographicZWJ, prExtendedPictographic}: {grExtendedPictographic, grNoBoundary, 110}, + + // GB12 / GB13. + {grAny, prRegionalIndicator}: {grRIOdd, grBoundary, 9990}, + {grRIOdd, prRegionalIndicator}: {grRIEven, grNoBoundary, 120}, + {grRIEven, prRegionalIndicator}: {grRIOdd, grBoundary, 120}, +} + +// Graphemes implements an iterator over Unicode extended grapheme clusters, +// specified in the Unicode Standard Annex #29. Grapheme clusters correspond to +// "user-perceived characters". These characters often consist of multiple +// code points (e.g. the "woman kissing woman" emoji consists of 8 code points: +// woman + ZWJ + heavy black heart (2 code points) + ZWJ + kiss mark + ZWJ + +// woman) and the rules described in Annex #29 must be applied to group those +// code points into clusters perceived by the user as one character. +type Graphemes struct { + // The code points over which this class iterates. + codePoints []rune + + // The (byte-based) indices of the code points into the original string plus + // len(original string). Thus, len(indices) = len(codePoints) + 1. + indices []int + + // The current grapheme cluster to be returned. These are indices into + // codePoints/indices. If start == end, we either haven't started iterating + // yet (0) or the iteration has already completed (1). + start, end int + + // The index of the next code point to be parsed. + pos int + + // The current state of the code point parser. + state int +} + +// NewGraphemes returns a new grapheme cluster iterator. +func NewGraphemes(s string) *Graphemes { + l := utf8.RuneCountInString(s) + codePoints := make([]rune, l) + indices := make([]int, l+1) + i := 0 + for pos, r := range s { + codePoints[i] = r + indices[i] = pos + i++ + } + indices[l] = len(s) + g := &Graphemes{ + codePoints: codePoints, + indices: indices, + } + g.Next() // Parse ahead. + return g +} + +// Next advances the iterator by one grapheme cluster and returns false if no +// clusters are left. This function must be called before the first cluster is +// accessed. +func (g *Graphemes) Next() bool { + g.start = g.end + + // The state transition gives us a boundary instruction BEFORE the next code + // point so we always need to stay ahead by one code point. + + // Parse the next code point. + for g.pos <= len(g.codePoints) { + // GB2. + if g.pos == len(g.codePoints) { + g.end = g.pos + g.pos++ + break + } + + // Determine the property of the next character. + nextProperty := property(g.codePoints[g.pos]) + g.pos++ + + // Find the applicable transition. + var boundary bool + transition, ok := grTransitions[[2]int{g.state, nextProperty}] + if ok { + // We have a specific transition. We'll use it. + g.state = transition[0] + boundary = transition[1] == grBoundary + } else { + // No specific transition found. Try the less specific ones. + transAnyProp, okAnyProp := grTransitions[[2]int{g.state, prAny}] + transAnyState, okAnyState := grTransitions[[2]int{grAny, nextProperty}] + if okAnyProp && okAnyState { + // Both apply. We'll use a mix (see comments for grTransitions). + g.state = transAnyState[0] + boundary = transAnyState[1] == grBoundary + if transAnyProp[2] < transAnyState[2] { + g.state = transAnyProp[0] + boundary = transAnyProp[1] == grBoundary + } + } else if okAnyProp { + // We only have a specific state. + g.state = transAnyProp[0] + boundary = transAnyProp[1] == grBoundary + // This branch will probably never be reached because okAnyState will + // always be true given the current transition map. But we keep it here + // for future modifications to the transition map where this may not be + // true anymore. + } else if okAnyState { + // We only have a specific property. + g.state = transAnyState[0] + boundary = transAnyState[1] == grBoundary + } else { + // No known transition. GB999: Any x Any. + g.state = grAny + boundary = true + } + } + + // If we found a cluster boundary, let's stop here. The current cluster will + // be the one that just ended. + if g.pos-1 == 0 /* GB1 */ || boundary { + g.end = g.pos - 1 + break + } + } + + return g.start != g.end +} + +// Runes returns a slice of runes (code points) which corresponds to the current +// grapheme cluster. If the iterator is already past the end or Next() has not +// yet been called, nil is returned. +func (g *Graphemes) Runes() []rune { + if g.start == g.end { + return nil + } + return g.codePoints[g.start:g.end] +} + +// Str returns a substring of the original string which corresponds to the +// current grapheme cluster. If the iterator is already past the end or Next() +// has not yet been called, an empty string is returned. +func (g *Graphemes) Str() string { + if g.start == g.end { + return "" + } + return string(g.codePoints[g.start:g.end]) +} + +// Bytes returns a byte slice which corresponds to the current grapheme cluster. +// If the iterator is already past the end or Next() has not yet been called, +// nil is returned. +func (g *Graphemes) Bytes() []byte { + if g.start == g.end { + return nil + } + return []byte(string(g.codePoints[g.start:g.end])) +} + +// Positions returns the interval of the current grapheme cluster as byte +// positions into the original string. The first returned value "from" indexes +// the first byte and the second returned value "to" indexes the first byte that +// is not included anymore, i.e. str[from:to] is the current grapheme cluster of +// the original string "str". If Next() has not yet been called, both values are +// 0. If the iterator is already past the end, both values are 1. +func (g *Graphemes) Positions() (int, int) { + return g.indices[g.start], g.indices[g.end] +} + +// Reset puts the iterator into its initial state such that the next call to +// Next() sets it to the first grapheme cluster again. +func (g *Graphemes) Reset() { + g.start, g.end, g.pos, g.state = 0, 0, 0, grAny + g.Next() // Parse ahead again. +} + +// GraphemeClusterCount returns the number of user-perceived characters +// (grapheme clusters) for the given string. To calculate this number, it +// iterates through the string using the Graphemes iterator. +func GraphemeClusterCount(s string) (n int) { + g := NewGraphemes(s) + for g.Next() { + n++ + } + return +} diff --git a/vendor/github.com/rivo/uniseg/properties.go b/vendor/github.com/rivo/uniseg/properties.go new file mode 100644 index 0000000000000..a75ab588399b6 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/properties.go @@ -0,0 +1,1658 @@ +package uniseg + +// The unicode properties. Only the ones needed in the context of this package +// are included. +const ( + prAny = iota + prPreprend + prCR + prLF + prControl + prExtend + prRegionalIndicator + prSpacingMark + prL + prV + prT + prLV + prLVT + prZWJ + prExtendedPictographic +) + +// Maps code point ranges to their properties. In the context of this package, +// any code point that is not contained may map to "prAny". The code point +// ranges in this slice are numerically sorted. +// +// These ranges were taken from +// http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakProperty.txt +// as well as +// https://unicode.org/Public/emoji/latest/emoji-data.txt +// ("Extended_Pictographic" only) on March 11, 2019. See +// https://www.unicode.org/license.html for the Unicode license agreement. +var codePoints = [][3]int{ + {0x0000, 0x0009, prControl}, // Cc [10] .. + {0x000A, 0x000A, prLF}, // Cc + {0x000B, 0x000C, prControl}, // Cc [2] .. + {0x000D, 0x000D, prCR}, // Cc + {0x000E, 0x001F, prControl}, // Cc [18] .. + {0x007F, 0x009F, prControl}, // Cc [33] .. + {0x00A9, 0x00A9, prExtendedPictographic}, // 1.1 [1] (©️) copyright + {0x00AD, 0x00AD, prControl}, // Cf SOFT HYPHEN + {0x00AE, 0x00AE, prExtendedPictographic}, // 1.1 [1] (®️) registered + {0x0300, 0x036F, prExtend}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X + {0x0483, 0x0487, prExtend}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prExtend}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x0591, 0x05BD, prExtend}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BF, 0x05BF, prExtend}, // Mn HEBREW POINT RAFE + {0x05C1, 0x05C2, prExtend}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C4, 0x05C5, prExtend}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C7, 0x05C7, prExtend}, // Mn HEBREW POINT QAMATS QATAN + {0x0600, 0x0605, prPreprend}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x0610, 0x061A, prExtend}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061C, 0x061C, prControl}, // Cf ARABIC LETTER MARK + {0x064B, 0x065F, prExtend}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0670, 0x0670, prExtend}, // Mn ARABIC LETTER SUPERSCRIPT ALEF + {0x06D6, 0x06DC, prExtend}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prPreprend}, // Cf ARABIC END OF AYAH + {0x06DF, 0x06E4, prExtend}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E7, 0x06E8, prExtend}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06EA, 0x06ED, prExtend}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x070F, 0x070F, prPreprend}, // Cf SYRIAC ABBREVIATION MARK + {0x0711, 0x0711, prExtend}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0730, 0x074A, prExtend}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x07A6, 0x07B0, prExtend}, // Mn [11] THAANA ABAFILI..THAANA SUKUN + {0x07EB, 0x07F3, prExtend}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07FD, 0x07FD, prExtend}, // Mn NKO DANTAYALAN + {0x0816, 0x0819, prExtend}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081B, 0x0823, prExtend}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0825, 0x0827, prExtend}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0829, 0x082D, prExtend}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0859, 0x085B, prExtend}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x08D3, 0x08E1, prExtend}, // Mn [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prPreprend}, // Cf ARABIC DISPUTED END OF AYAH + {0x08E3, 0x0902, prExtend}, // Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prSpacingMark}, // Mc DEVANAGARI SIGN VISARGA + {0x093A, 0x093A, prExtend}, // Mn DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prSpacingMark}, // Mc DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prExtend}, // Mn DEVANAGARI SIGN NUKTA + {0x093E, 0x0940, prSpacingMark}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prExtend}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prSpacingMark}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prExtend}, // Mn DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prSpacingMark}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0951, 0x0957, prExtend}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0962, 0x0963, prExtend}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0981, 0x0981, prExtend}, // Mn BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prSpacingMark}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x09BC, 0x09BC, prExtend}, // Mn BENGALI SIGN NUKTA + {0x09BE, 0x09BE, prExtend}, // Mc BENGALI VOWEL SIGN AA + {0x09BF, 0x09C0, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN I..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prExtend}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prExtend}, // Mn BENGALI SIGN VIRAMA + {0x09D7, 0x09D7, prExtend}, // Mc BENGALI AU LENGTH MARK + {0x09E2, 0x09E3, prExtend}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09FE, 0x09FE, prExtend}, // Mn BENGALI SANDHI MARK + {0x0A01, 0x0A02, prExtend}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prSpacingMark}, // Mc GURMUKHI SIGN VISARGA + {0x0A3C, 0x0A3C, prExtend}, // Mn GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prSpacingMark}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prExtend}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prExtend}, // Mn GURMUKHI SIGN UDAAT + {0x0A70, 0x0A71, prExtend}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A75, 0x0A75, prExtend}, // Mn GURMUKHI SIGN YAKASH + {0x0A81, 0x0A82, prExtend}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prSpacingMark}, // Mc GUJARATI SIGN VISARGA + {0x0ABC, 0x0ABC, prExtend}, // Mn GUJARATI SIGN NUKTA + {0x0ABE, 0x0AC0, prSpacingMark}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prExtend}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prExtend}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prSpacingMark}, // Mc GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prSpacingMark}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prExtend}, // Mn GUJARATI SIGN VIRAMA + {0x0AE2, 0x0AE3, prExtend}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AFA, 0x0AFF, prExtend}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prExtend}, // Mn ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prSpacingMark}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B3C, 0x0B3C, prExtend}, // Mn ORIYA SIGN NUKTA + {0x0B3E, 0x0B3E, prExtend}, // Mc ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prExtend}, // Mn ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prSpacingMark}, // Mc ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prExtend}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prSpacingMark}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prSpacingMark}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prExtend}, // Mn ORIYA SIGN VIRAMA + {0x0B56, 0x0B56, prExtend}, // Mn ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prExtend}, // Mc ORIYA AU LENGTH MARK + {0x0B62, 0x0B63, prExtend}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B82, 0x0B82, prExtend}, // Mn TAMIL SIGN ANUSVARA + {0x0BBE, 0x0BBE, prExtend}, // Mc TAMIL VOWEL SIGN AA + {0x0BBF, 0x0BBF, prSpacingMark}, // Mc TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prExtend}, // Mn TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prSpacingMark}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prSpacingMark}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prSpacingMark}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prExtend}, // Mn TAMIL SIGN VIRAMA + {0x0BD7, 0x0BD7, prExtend}, // Mc TAMIL AU LENGTH MARK + {0x0C00, 0x0C00, prExtend}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prSpacingMark}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prExtend}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C3E, 0x0C40, prExtend}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prSpacingMark}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prExtend}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prExtend}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prExtend}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C62, 0x0C63, prExtend}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C81, 0x0C81, prExtend}, // Mn KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prSpacingMark}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0CBC, 0x0CBC, prExtend}, // Mn KANNADA SIGN NUKTA + {0x0CBE, 0x0CBE, prSpacingMark}, // Mc KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prExtend}, // Mn KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC1, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN U + {0x0CC2, 0x0CC2, prExtend}, // Mc KANNADA VOWEL SIGN UU + {0x0CC3, 0x0CC4, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN VOCALIC R..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prExtend}, // Mn KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prExtend}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prExtend}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CE2, 0x0CE3, prExtend}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0D00, 0x0D01, prExtend}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prSpacingMark}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D3B, 0x0D3C, prExtend}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3E, 0x0D3E, prExtend}, // Mc MALAYALAM VOWEL SIGN AA + {0x0D3F, 0x0D40, prSpacingMark}, // Mc [2] MALAYALAM VOWEL SIGN I..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prExtend}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prSpacingMark}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prSpacingMark}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prExtend}, // Mn MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prPreprend}, // Lo MALAYALAM LETTER DOT REPH + {0x0D57, 0x0D57, prExtend}, // Mc MALAYALAM AU LENGTH MARK + {0x0D62, 0x0D63, prExtend}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D82, 0x0D83, prSpacingMark}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0DCA, 0x0DCA, prExtend}, // Mn SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DCF, prExtend}, // Mc SINHALA VOWEL SIGN AELA-PILLA + {0x0DD0, 0x0DD1, prSpacingMark}, // Mc [2] SINHALA VOWEL SIGN KETTI AEDA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prExtend}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prExtend}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDE, prSpacingMark}, // Mc [7] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA + {0x0DDF, 0x0DDF, prExtend}, // Mc SINHALA VOWEL SIGN GAYANUKITTA + {0x0DF2, 0x0DF3, prSpacingMark}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0E31, 0x0E31, prExtend}, // Mn THAI CHARACTER MAI HAN-AKAT + {0x0E33, 0x0E33, prSpacingMark}, // Lo THAI CHARACTER SARA AM + {0x0E34, 0x0E3A, prExtend}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E47, 0x0E4E, prExtend}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0EB1, 0x0EB1, prExtend}, // Mn LAO VOWEL SIGN MAI KAN + {0x0EB3, 0x0EB3, prSpacingMark}, // Lo LAO VOWEL SIGN AM + {0x0EB4, 0x0EBC, prExtend}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EC8, 0x0ECD, prExtend}, // Mn [6] LAO TONE MAI EK..LAO NIGGAHITA + {0x0F18, 0x0F19, prExtend}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F35, 0x0F35, prExtend}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F37, 0x0F37, prExtend}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F39, 0x0F39, prExtend}, // Mn TIBETAN MARK TSA -PHRU + {0x0F3E, 0x0F3F, prSpacingMark}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F71, 0x0F7E, prExtend}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prSpacingMark}, // Mc TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prExtend}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F86, 0x0F87, prExtend}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F8D, 0x0F97, prExtend}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prExtend}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FC6, 0x0FC6, prExtend}, // Mn TIBETAN SYMBOL PADMA GDAN + {0x102D, 0x1030, prExtend}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prSpacingMark}, // Mc MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prExtend}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1039, 0x103A, prExtend}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prSpacingMark}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prExtend}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x1056, 0x1057, prSpacingMark}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prExtend}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105E, 0x1060, prExtend}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1071, 0x1074, prExtend}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1082, 0x1082, prExtend}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1084, 0x1084, prSpacingMark}, // Mc MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prExtend}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x108D, 0x108D, prExtend}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x109D, 0x109D, prExtend}, // Mn MYANMAR VOWEL SIGN AITON AI + {0x1100, 0x115F, prL}, // Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER + {0x1160, 0x11A7, prV}, // Lo [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE + {0x11A8, 0x11FF, prT}, // Lo [88] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG SSANGNIEUN + {0x135D, 0x135F, prExtend}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1712, 0x1714, prExtend}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1732, 0x1734, prExtend}, // Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD + {0x1752, 0x1753, prExtend}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1772, 0x1773, prExtend}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x17B4, 0x17B5, prExtend}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prSpacingMark}, // Mc KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prExtend}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prSpacingMark}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prExtend}, // Mn KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prSpacingMark}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prExtend}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17DD, 0x17DD, prExtend}, // Mn KHMER SIGN ATTHACAN + {0x180B, 0x180D, prExtend}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prControl}, // Cf MONGOLIAN VOWEL SEPARATOR + {0x1885, 0x1886, prExtend}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x18A9, 0x18A9, prExtend}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA + {0x1920, 0x1922, prExtend}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prSpacingMark}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prExtend}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prSpacingMark}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prSpacingMark}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prExtend}, // Mn LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prSpacingMark}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prExtend}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1A17, 0x1A18, prExtend}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prSpacingMark}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prExtend}, // Mn BUGINESE VOWEL SIGN AE + {0x1A55, 0x1A55, prSpacingMark}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prExtend}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prSpacingMark}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prExtend}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prExtend}, // Mn TAI THAM SIGN SAKOT + {0x1A62, 0x1A62, prExtend}, // Mn TAI THAM VOWEL SIGN MAI SAT + {0x1A65, 0x1A6C, prExtend}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prSpacingMark}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prExtend}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prExtend}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1AB0, 0x1ABD, prExtend}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prExtend}, // Me COMBINING PARENTHESES OVERLAY + {0x1B00, 0x1B03, prExtend}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prSpacingMark}, // Mc BALINESE SIGN BISAH + {0x1B34, 0x1B34, prExtend}, // Mn BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prExtend}, // Mc BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prExtend}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prSpacingMark}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prExtend}, // Mn BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prSpacingMark}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prExtend}, // Mn BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prSpacingMark}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B6B, 0x1B73, prExtend}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B80, 0x1B81, prExtend}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prSpacingMark}, // Mc SUNDANESE SIGN PANGWISAD + {0x1BA1, 0x1BA1, prSpacingMark}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prExtend}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prSpacingMark}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prExtend}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prSpacingMark}, // Mc SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prExtend}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BE6, 0x1BE6, prExtend}, // Mn BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prSpacingMark}, // Mc BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prExtend}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prSpacingMark}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prExtend}, // Mn BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prSpacingMark}, // Mc BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prExtend}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prSpacingMark}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1C24, 0x1C2B, prSpacingMark}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prExtend}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prSpacingMark}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prExtend}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1CD0, 0x1CD2, prExtend}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD4, 0x1CE0, prExtend}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prSpacingMark}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prExtend}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CED, 0x1CED, prExtend}, // Mn VEDIC SIGN TIRYAK + {0x1CF4, 0x1CF4, prExtend}, // Mn VEDIC TONE CANDRA ABOVE + {0x1CF7, 0x1CF7, prSpacingMark}, // Mc VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prExtend}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1DC0, 0x1DF9, prExtend}, // Mn [58] COMBINING DOTTED GRAVE ACCENT..COMBINING WIDE INVERTED BRIDGE BELOW + {0x1DFB, 0x1DFF, prExtend}, // Mn [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x200B, 0x200B, prControl}, // Cf ZERO WIDTH SPACE + {0x200C, 0x200C, prExtend}, // Cf ZERO WIDTH NON-JOINER + {0x200D, 0x200D, prZWJ}, // Cf ZERO WIDTH JOINER + {0x200E, 0x200F, prControl}, // Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK + {0x2028, 0x2028, prControl}, // Zl LINE SEPARATOR + {0x2029, 0x2029, prControl}, // Zp PARAGRAPH SEPARATOR + {0x202A, 0x202E, prControl}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x203C, 0x203C, prExtendedPictographic}, // 1.1 [1] (‼️) double exclamation mark + {0x2049, 0x2049, prExtendedPictographic}, // 3.0 [1] (⁉️) exclamation question mark + {0x2060, 0x2064, prControl}, // Cf [5] WORD JOINER..INVISIBLE PLUS + {0x2065, 0x2065, prControl}, // Cn + {0x2066, 0x206F, prControl}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x20D0, 0x20DC, prExtend}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prExtend}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prExtend}, // Mn COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prExtend}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prExtend}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2122, 0x2122, prExtendedPictographic}, // 1.1 [1] (™️) trade mark + {0x2139, 0x2139, prExtendedPictographic}, // 3.0 [1] (ℹ️) information + {0x2194, 0x2199, prExtendedPictographic}, // 1.1 [6] (↔️..↙️) left-right arrow..down-left arrow + {0x21A9, 0x21AA, prExtendedPictographic}, // 1.1 [2] (↩️..↪️) right arrow curving left..left arrow curving right + {0x231A, 0x231B, prExtendedPictographic}, // 1.1 [2] (⌚..⌛) watch..hourglass done + {0x2328, 0x2328, prExtendedPictographic}, // 1.1 [1] (⌨️) keyboard + {0x2388, 0x2388, prExtendedPictographic}, // 3.0 [1] (⎈) HELM SYMBOL + {0x23CF, 0x23CF, prExtendedPictographic}, // 4.0 [1] (⏏️) eject button + {0x23E9, 0x23F3, prExtendedPictographic}, // 6.0 [11] (⏩..⏳) fast-forward button..hourglass not done + {0x23F8, 0x23FA, prExtendedPictographic}, // 7.0 [3] (⏸️..⏺️) pause button..record button + {0x24C2, 0x24C2, prExtendedPictographic}, // 1.1 [1] (Ⓜ️) circled M + {0x25AA, 0x25AB, prExtendedPictographic}, // 1.1 [2] (▪️..▫️) black small square..white small square + {0x25B6, 0x25B6, prExtendedPictographic}, // 1.1 [1] (▶️) play button + {0x25C0, 0x25C0, prExtendedPictographic}, // 1.1 [1] (◀️) reverse button + {0x25FB, 0x25FE, prExtendedPictographic}, // 3.2 [4] (◻️..◾) white medium square..black medium-small square + {0x2600, 0x2605, prExtendedPictographic}, // 1.1 [6] (☀️..★) sun..BLACK STAR + {0x2607, 0x2612, prExtendedPictographic}, // 1.1 [12] (☇..☒) LIGHTNING..BALLOT BOX WITH X + {0x2614, 0x2615, prExtendedPictographic}, // 4.0 [2] (☔..☕) umbrella with rain drops..hot beverage + {0x2616, 0x2617, prExtendedPictographic}, // 3.2 [2] (☖..☗) WHITE SHOGI PIECE..BLACK SHOGI PIECE + {0x2618, 0x2618, prExtendedPictographic}, // 4.1 [1] (☘️) shamrock + {0x2619, 0x2619, prExtendedPictographic}, // 3.0 [1] (☙) REVERSED ROTATED FLORAL HEART BULLET + {0x261A, 0x266F, prExtendedPictographic}, // 1.1 [86] (☚..♯) BLACK LEFT POINTING INDEX..MUSIC SHARP SIGN + {0x2670, 0x2671, prExtendedPictographic}, // 3.0 [2] (♰..♱) WEST SYRIAC CROSS..EAST SYRIAC CROSS + {0x2672, 0x267D, prExtendedPictographic}, // 3.2 [12] (♲..♽) UNIVERSAL RECYCLING SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL + {0x267E, 0x267F, prExtendedPictographic}, // 4.1 [2] (♾️..♿) infinity..wheelchair symbol + {0x2680, 0x2685, prExtendedPictographic}, // 3.2 [6] (⚀..⚅) DIE FACE-1..DIE FACE-6 + {0x2690, 0x2691, prExtendedPictographic}, // 4.0 [2] (⚐..⚑) WHITE FLAG..BLACK FLAG + {0x2692, 0x269C, prExtendedPictographic}, // 4.1 [11] (⚒️..⚜️) hammer and pick..fleur-de-lis + {0x269D, 0x269D, prExtendedPictographic}, // 5.1 [1] (⚝) OUTLINED WHITE STAR + {0x269E, 0x269F, prExtendedPictographic}, // 5.2 [2] (⚞..⚟) THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT + {0x26A0, 0x26A1, prExtendedPictographic}, // 4.0 [2] (⚠️..⚡) warning..high voltage + {0x26A2, 0x26B1, prExtendedPictographic}, // 4.1 [16] (⚢..⚱️) DOUBLED FEMALE SIGN..funeral urn + {0x26B2, 0x26B2, prExtendedPictographic}, // 5.0 [1] (⚲) NEUTER + {0x26B3, 0x26BC, prExtendedPictographic}, // 5.1 [10] (⚳..⚼) CERES..SESQUIQUADRATE + {0x26BD, 0x26BF, prExtendedPictographic}, // 5.2 [3] (⚽..⚿) soccer ball..SQUARED KEY + {0x26C0, 0x26C3, prExtendedPictographic}, // 5.1 [4] (⛀..⛃) WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING + {0x26C4, 0x26CD, prExtendedPictographic}, // 5.2 [10] (⛄..⛍) snowman without snow..DISABLED CAR + {0x26CE, 0x26CE, prExtendedPictographic}, // 6.0 [1] (⛎) Ophiuchus + {0x26CF, 0x26E1, prExtendedPictographic}, // 5.2 [19] (⛏️..⛡) pick..RESTRICTED LEFT ENTRY-2 + {0x26E2, 0x26E2, prExtendedPictographic}, // 6.0 [1] (⛢) ASTRONOMICAL SYMBOL FOR URANUS + {0x26E3, 0x26E3, prExtendedPictographic}, // 5.2 [1] (⛣) HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE + {0x26E4, 0x26E7, prExtendedPictographic}, // 6.0 [4] (⛤..⛧) PENTAGRAM..INVERTED PENTAGRAM + {0x26E8, 0x26FF, prExtendedPictographic}, // 5.2 [24] (⛨..⛿) BLACK CROSS ON SHIELD..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE + {0x2700, 0x2700, prExtendedPictographic}, // 7.0 [1] (✀) BLACK SAFETY SCISSORS + {0x2701, 0x2704, prExtendedPictographic}, // 1.1 [4] (✁..✄) UPPER BLADE SCISSORS..WHITE SCISSORS + {0x2705, 0x2705, prExtendedPictographic}, // 6.0 [1] (✅) check mark button + {0x2708, 0x2709, prExtendedPictographic}, // 1.1 [2] (✈️..✉️) airplane..envelope + {0x270A, 0x270B, prExtendedPictographic}, // 6.0 [2] (✊..✋) raised fist..raised hand + {0x270C, 0x2712, prExtendedPictographic}, // 1.1 [7] (✌️..✒️) victory hand..black nib + {0x2714, 0x2714, prExtendedPictographic}, // 1.1 [1] (✔️) check mark + {0x2716, 0x2716, prExtendedPictographic}, // 1.1 [1] (✖️) multiplication sign + {0x271D, 0x271D, prExtendedPictographic}, // 1.1 [1] (✝️) latin cross + {0x2721, 0x2721, prExtendedPictographic}, // 1.1 [1] (✡️) star of David + {0x2728, 0x2728, prExtendedPictographic}, // 6.0 [1] (✨) sparkles + {0x2733, 0x2734, prExtendedPictographic}, // 1.1 [2] (✳️..✴️) eight-spoked asterisk..eight-pointed star + {0x2744, 0x2744, prExtendedPictographic}, // 1.1 [1] (❄️) snowflake + {0x2747, 0x2747, prExtendedPictographic}, // 1.1 [1] (❇️) sparkle + {0x274C, 0x274C, prExtendedPictographic}, // 6.0 [1] (❌) cross mark + {0x274E, 0x274E, prExtendedPictographic}, // 6.0 [1] (❎) cross mark button + {0x2753, 0x2755, prExtendedPictographic}, // 6.0 [3] (❓..❕) question mark..white exclamation mark + {0x2757, 0x2757, prExtendedPictographic}, // 5.2 [1] (❗) exclamation mark + {0x2763, 0x2767, prExtendedPictographic}, // 1.1 [5] (❣️..❧) heart exclamation..ROTATED FLORAL HEART BULLET + {0x2795, 0x2797, prExtendedPictographic}, // 6.0 [3] (➕..➗) plus sign..division sign + {0x27A1, 0x27A1, prExtendedPictographic}, // 1.1 [1] (➡️) right arrow + {0x27B0, 0x27B0, prExtendedPictographic}, // 6.0 [1] (➰) curly loop + {0x27BF, 0x27BF, prExtendedPictographic}, // 6.0 [1] (➿) double curly loop + {0x2934, 0x2935, prExtendedPictographic}, // 3.2 [2] (⤴️..⤵️) right arrow curving up..right arrow curving down + {0x2B05, 0x2B07, prExtendedPictographic}, // 4.0 [3] (⬅️..⬇️) left arrow..down arrow + {0x2B1B, 0x2B1C, prExtendedPictographic}, // 5.1 [2] (⬛..⬜) black large square..white large square + {0x2B50, 0x2B50, prExtendedPictographic}, // 5.1 [1] (⭐) star + {0x2B55, 0x2B55, prExtendedPictographic}, // 5.2 [1] (⭕) hollow red circle + {0x2CEF, 0x2CF1, prExtend}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2D7F, 0x2D7F, prExtend}, // Mn TIFINAGH CONSONANT JOINER + {0x2DE0, 0x2DFF, prExtend}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x302A, 0x302D, prExtend}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prExtend}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3030, 0x3030, prExtendedPictographic}, // 1.1 [1] (〰️) wavy dash + {0x303D, 0x303D, prExtendedPictographic}, // 3.2 [1] (〽️) part alternation mark + {0x3099, 0x309A, prExtend}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x3297, 0x3297, prExtendedPictographic}, // 1.1 [1] (㊗️) Japanese “congratulations” button + {0x3299, 0x3299, prExtendedPictographic}, // 1.1 [1] (㊙️) Japanese “secret” button + {0xA66F, 0xA66F, prExtend}, // Mn COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prExtend}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA674, 0xA67D, prExtend}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA69E, 0xA69F, prExtend}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6F0, 0xA6F1, prExtend}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA802, 0xA802, prExtend}, // Mn SYLOTI NAGRI SIGN DVISVARA + {0xA806, 0xA806, prExtend}, // Mn SYLOTI NAGRI SIGN HASANTA + {0xA80B, 0xA80B, prExtend}, // Mn SYLOTI NAGRI SIGN ANUSVARA + {0xA823, 0xA824, prSpacingMark}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prExtend}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prSpacingMark}, // Mc SYLOTI NAGRI VOWEL SIGN OO + {0xA880, 0xA881, prSpacingMark}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA8B4, 0xA8C3, prSpacingMark}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prExtend}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8E0, 0xA8F1, prExtend}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8FF, 0xA8FF, prExtend}, // Mn DEVANAGARI VOWEL SIGN AY + {0xA926, 0xA92D, prExtend}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA947, 0xA951, prExtend}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prSpacingMark}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA960, 0xA97C, prL}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prExtend}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prSpacingMark}, // Mc JAVANESE SIGN WIGNYAN + {0xA9B3, 0xA9B3, prExtend}, // Mn JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prSpacingMark}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prExtend}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prSpacingMark}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prExtend}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prSpacingMark}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9E5, 0xA9E5, prExtend}, // Mn MYANMAR SIGN SHAN SAW + {0xAA29, 0xAA2E, prExtend}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prSpacingMark}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prExtend}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prSpacingMark}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prExtend}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA43, 0xAA43, prExtend}, // Mn CHAM CONSONANT SIGN FINAL NG + {0xAA4C, 0xAA4C, prExtend}, // Mn CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prSpacingMark}, // Mc CHAM CONSONANT SIGN FINAL H + {0xAA7C, 0xAA7C, prExtend}, // Mn MYANMAR SIGN TAI LAING TONE-2 + {0xAAB0, 0xAAB0, prExtend}, // Mn TAI VIET MAI KANG + {0xAAB2, 0xAAB4, prExtend}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB7, 0xAAB8, prExtend}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAABE, 0xAABF, prExtend}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC1, 0xAAC1, prExtend}, // Mn TAI VIET TONE MAI THO + {0xAAEB, 0xAAEB, prSpacingMark}, // Mc MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prExtend}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF5, 0xAAF5, prSpacingMark}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prExtend}, // Mn MEETEI MAYEK VIRAMA + {0xABE3, 0xABE4, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEC, 0xABEC, prSpacingMark}, // Mc MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prExtend}, // Mn MEETEI MAYEK APUN IYEK + {0xAC00, 0xAC00, prLV}, // Lo HANGUL SYLLABLE GA + {0xAC01, 0xAC1B, prLVT}, // Lo [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH + {0xAC1C, 0xAC1C, prLV}, // Lo HANGUL SYLLABLE GAE + {0xAC1D, 0xAC37, prLVT}, // Lo [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH + {0xAC38, 0xAC38, prLV}, // Lo HANGUL SYLLABLE GYA + {0xAC39, 0xAC53, prLVT}, // Lo [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH + {0xAC54, 0xAC54, prLV}, // Lo HANGUL SYLLABLE GYAE + {0xAC55, 0xAC6F, prLVT}, // Lo [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH + {0xAC70, 0xAC70, prLV}, // Lo HANGUL SYLLABLE GEO + {0xAC71, 0xAC8B, prLVT}, // Lo [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH + {0xAC8C, 0xAC8C, prLV}, // Lo HANGUL SYLLABLE GE + {0xAC8D, 0xACA7, prLVT}, // Lo [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH + {0xACA8, 0xACA8, prLV}, // Lo HANGUL SYLLABLE GYEO + {0xACA9, 0xACC3, prLVT}, // Lo [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH + {0xACC4, 0xACC4, prLV}, // Lo HANGUL SYLLABLE GYE + {0xACC5, 0xACDF, prLVT}, // Lo [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH + {0xACE0, 0xACE0, prLV}, // Lo HANGUL SYLLABLE GO + {0xACE1, 0xACFB, prLVT}, // Lo [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH + {0xACFC, 0xACFC, prLV}, // Lo HANGUL SYLLABLE GWA + {0xACFD, 0xAD17, prLVT}, // Lo [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH + {0xAD18, 0xAD18, prLV}, // Lo HANGUL SYLLABLE GWAE + {0xAD19, 0xAD33, prLVT}, // Lo [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH + {0xAD34, 0xAD34, prLV}, // Lo HANGUL SYLLABLE GOE + {0xAD35, 0xAD4F, prLVT}, // Lo [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH + {0xAD50, 0xAD50, prLV}, // Lo HANGUL SYLLABLE GYO + {0xAD51, 0xAD6B, prLVT}, // Lo [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH + {0xAD6C, 0xAD6C, prLV}, // Lo HANGUL SYLLABLE GU + {0xAD6D, 0xAD87, prLVT}, // Lo [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH + {0xAD88, 0xAD88, prLV}, // Lo HANGUL SYLLABLE GWEO + {0xAD89, 0xADA3, prLVT}, // Lo [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH + {0xADA4, 0xADA4, prLV}, // Lo HANGUL SYLLABLE GWE + {0xADA5, 0xADBF, prLVT}, // Lo [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH + {0xADC0, 0xADC0, prLV}, // Lo HANGUL SYLLABLE GWI + {0xADC1, 0xADDB, prLVT}, // Lo [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH + {0xADDC, 0xADDC, prLV}, // Lo HANGUL SYLLABLE GYU + {0xADDD, 0xADF7, prLVT}, // Lo [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH + {0xADF8, 0xADF8, prLV}, // Lo HANGUL SYLLABLE GEU + {0xADF9, 0xAE13, prLVT}, // Lo [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH + {0xAE14, 0xAE14, prLV}, // Lo HANGUL SYLLABLE GYI + {0xAE15, 0xAE2F, prLVT}, // Lo [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH + {0xAE30, 0xAE30, prLV}, // Lo HANGUL SYLLABLE GI + {0xAE31, 0xAE4B, prLVT}, // Lo [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH + {0xAE4C, 0xAE4C, prLV}, // Lo HANGUL SYLLABLE GGA + {0xAE4D, 0xAE67, prLVT}, // Lo [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH + {0xAE68, 0xAE68, prLV}, // Lo HANGUL SYLLABLE GGAE + {0xAE69, 0xAE83, prLVT}, // Lo [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH + {0xAE84, 0xAE84, prLV}, // Lo HANGUL SYLLABLE GGYA + {0xAE85, 0xAE9F, prLVT}, // Lo [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH + {0xAEA0, 0xAEA0, prLV}, // Lo HANGUL SYLLABLE GGYAE + {0xAEA1, 0xAEBB, prLVT}, // Lo [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH + {0xAEBC, 0xAEBC, prLV}, // Lo HANGUL SYLLABLE GGEO + {0xAEBD, 0xAED7, prLVT}, // Lo [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH + {0xAED8, 0xAED8, prLV}, // Lo HANGUL SYLLABLE GGE + {0xAED9, 0xAEF3, prLVT}, // Lo [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH + {0xAEF4, 0xAEF4, prLV}, // Lo HANGUL SYLLABLE GGYEO + {0xAEF5, 0xAF0F, prLVT}, // Lo [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH + {0xAF10, 0xAF10, prLV}, // Lo HANGUL SYLLABLE GGYE + {0xAF11, 0xAF2B, prLVT}, // Lo [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH + {0xAF2C, 0xAF2C, prLV}, // Lo HANGUL SYLLABLE GGO + {0xAF2D, 0xAF47, prLVT}, // Lo [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH + {0xAF48, 0xAF48, prLV}, // Lo HANGUL SYLLABLE GGWA + {0xAF49, 0xAF63, prLVT}, // Lo [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH + {0xAF64, 0xAF64, prLV}, // Lo HANGUL SYLLABLE GGWAE + {0xAF65, 0xAF7F, prLVT}, // Lo [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH + {0xAF80, 0xAF80, prLV}, // Lo HANGUL SYLLABLE GGOE + {0xAF81, 0xAF9B, prLVT}, // Lo [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH + {0xAF9C, 0xAF9C, prLV}, // Lo HANGUL SYLLABLE GGYO + {0xAF9D, 0xAFB7, prLVT}, // Lo [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH + {0xAFB8, 0xAFB8, prLV}, // Lo HANGUL SYLLABLE GGU + {0xAFB9, 0xAFD3, prLVT}, // Lo [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH + {0xAFD4, 0xAFD4, prLV}, // Lo HANGUL SYLLABLE GGWEO + {0xAFD5, 0xAFEF, prLVT}, // Lo [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH + {0xAFF0, 0xAFF0, prLV}, // Lo HANGUL SYLLABLE GGWE + {0xAFF1, 0xB00B, prLVT}, // Lo [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH + {0xB00C, 0xB00C, prLV}, // Lo HANGUL SYLLABLE GGWI + {0xB00D, 0xB027, prLVT}, // Lo [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH + {0xB028, 0xB028, prLV}, // Lo HANGUL SYLLABLE GGYU + {0xB029, 0xB043, prLVT}, // Lo [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH + {0xB044, 0xB044, prLV}, // Lo HANGUL SYLLABLE GGEU + {0xB045, 0xB05F, prLVT}, // Lo [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH + {0xB060, 0xB060, prLV}, // Lo HANGUL SYLLABLE GGYI + {0xB061, 0xB07B, prLVT}, // Lo [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH + {0xB07C, 0xB07C, prLV}, // Lo HANGUL SYLLABLE GGI + {0xB07D, 0xB097, prLVT}, // Lo [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH + {0xB098, 0xB098, prLV}, // Lo HANGUL SYLLABLE NA + {0xB099, 0xB0B3, prLVT}, // Lo [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH + {0xB0B4, 0xB0B4, prLV}, // Lo HANGUL SYLLABLE NAE + {0xB0B5, 0xB0CF, prLVT}, // Lo [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH + {0xB0D0, 0xB0D0, prLV}, // Lo HANGUL SYLLABLE NYA + {0xB0D1, 0xB0EB, prLVT}, // Lo [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH + {0xB0EC, 0xB0EC, prLV}, // Lo HANGUL SYLLABLE NYAE + {0xB0ED, 0xB107, prLVT}, // Lo [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH + {0xB108, 0xB108, prLV}, // Lo HANGUL SYLLABLE NEO + {0xB109, 0xB123, prLVT}, // Lo [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH + {0xB124, 0xB124, prLV}, // Lo HANGUL SYLLABLE NE + {0xB125, 0xB13F, prLVT}, // Lo [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH + {0xB140, 0xB140, prLV}, // Lo HANGUL SYLLABLE NYEO + {0xB141, 0xB15B, prLVT}, // Lo [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH + {0xB15C, 0xB15C, prLV}, // Lo HANGUL SYLLABLE NYE + {0xB15D, 0xB177, prLVT}, // Lo [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH + {0xB178, 0xB178, prLV}, // Lo HANGUL SYLLABLE NO + {0xB179, 0xB193, prLVT}, // Lo [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH + {0xB194, 0xB194, prLV}, // Lo HANGUL SYLLABLE NWA + {0xB195, 0xB1AF, prLVT}, // Lo [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH + {0xB1B0, 0xB1B0, prLV}, // Lo HANGUL SYLLABLE NWAE + {0xB1B1, 0xB1CB, prLVT}, // Lo [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH + {0xB1CC, 0xB1CC, prLV}, // Lo HANGUL SYLLABLE NOE + {0xB1CD, 0xB1E7, prLVT}, // Lo [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH + {0xB1E8, 0xB1E8, prLV}, // Lo HANGUL SYLLABLE NYO + {0xB1E9, 0xB203, prLVT}, // Lo [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH + {0xB204, 0xB204, prLV}, // Lo HANGUL SYLLABLE NU + {0xB205, 0xB21F, prLVT}, // Lo [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH + {0xB220, 0xB220, prLV}, // Lo HANGUL SYLLABLE NWEO + {0xB221, 0xB23B, prLVT}, // Lo [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH + {0xB23C, 0xB23C, prLV}, // Lo HANGUL SYLLABLE NWE + {0xB23D, 0xB257, prLVT}, // Lo [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH + {0xB258, 0xB258, prLV}, // Lo HANGUL SYLLABLE NWI + {0xB259, 0xB273, prLVT}, // Lo [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH + {0xB274, 0xB274, prLV}, // Lo HANGUL SYLLABLE NYU + {0xB275, 0xB28F, prLVT}, // Lo [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH + {0xB290, 0xB290, prLV}, // Lo HANGUL SYLLABLE NEU + {0xB291, 0xB2AB, prLVT}, // Lo [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH + {0xB2AC, 0xB2AC, prLV}, // Lo HANGUL SYLLABLE NYI + {0xB2AD, 0xB2C7, prLVT}, // Lo [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH + {0xB2C8, 0xB2C8, prLV}, // Lo HANGUL SYLLABLE NI + {0xB2C9, 0xB2E3, prLVT}, // Lo [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH + {0xB2E4, 0xB2E4, prLV}, // Lo HANGUL SYLLABLE DA + {0xB2E5, 0xB2FF, prLVT}, // Lo [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH + {0xB300, 0xB300, prLV}, // Lo HANGUL SYLLABLE DAE + {0xB301, 0xB31B, prLVT}, // Lo [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH + {0xB31C, 0xB31C, prLV}, // Lo HANGUL SYLLABLE DYA + {0xB31D, 0xB337, prLVT}, // Lo [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH + {0xB338, 0xB338, prLV}, // Lo HANGUL SYLLABLE DYAE + {0xB339, 0xB353, prLVT}, // Lo [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH + {0xB354, 0xB354, prLV}, // Lo HANGUL SYLLABLE DEO + {0xB355, 0xB36F, prLVT}, // Lo [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH + {0xB370, 0xB370, prLV}, // Lo HANGUL SYLLABLE DE + {0xB371, 0xB38B, prLVT}, // Lo [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH + {0xB38C, 0xB38C, prLV}, // Lo HANGUL SYLLABLE DYEO + {0xB38D, 0xB3A7, prLVT}, // Lo [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH + {0xB3A8, 0xB3A8, prLV}, // Lo HANGUL SYLLABLE DYE + {0xB3A9, 0xB3C3, prLVT}, // Lo [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH + {0xB3C4, 0xB3C4, prLV}, // Lo HANGUL SYLLABLE DO + {0xB3C5, 0xB3DF, prLVT}, // Lo [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH + {0xB3E0, 0xB3E0, prLV}, // Lo HANGUL SYLLABLE DWA + {0xB3E1, 0xB3FB, prLVT}, // Lo [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH + {0xB3FC, 0xB3FC, prLV}, // Lo HANGUL SYLLABLE DWAE + {0xB3FD, 0xB417, prLVT}, // Lo [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH + {0xB418, 0xB418, prLV}, // Lo HANGUL SYLLABLE DOE + {0xB419, 0xB433, prLVT}, // Lo [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH + {0xB434, 0xB434, prLV}, // Lo HANGUL SYLLABLE DYO + {0xB435, 0xB44F, prLVT}, // Lo [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH + {0xB450, 0xB450, prLV}, // Lo HANGUL SYLLABLE DU + {0xB451, 0xB46B, prLVT}, // Lo [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH + {0xB46C, 0xB46C, prLV}, // Lo HANGUL SYLLABLE DWEO + {0xB46D, 0xB487, prLVT}, // Lo [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH + {0xB488, 0xB488, prLV}, // Lo HANGUL SYLLABLE DWE + {0xB489, 0xB4A3, prLVT}, // Lo [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH + {0xB4A4, 0xB4A4, prLV}, // Lo HANGUL SYLLABLE DWI + {0xB4A5, 0xB4BF, prLVT}, // Lo [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH + {0xB4C0, 0xB4C0, prLV}, // Lo HANGUL SYLLABLE DYU + {0xB4C1, 0xB4DB, prLVT}, // Lo [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH + {0xB4DC, 0xB4DC, prLV}, // Lo HANGUL SYLLABLE DEU + {0xB4DD, 0xB4F7, prLVT}, // Lo [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH + {0xB4F8, 0xB4F8, prLV}, // Lo HANGUL SYLLABLE DYI + {0xB4F9, 0xB513, prLVT}, // Lo [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH + {0xB514, 0xB514, prLV}, // Lo HANGUL SYLLABLE DI + {0xB515, 0xB52F, prLVT}, // Lo [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH + {0xB530, 0xB530, prLV}, // Lo HANGUL SYLLABLE DDA + {0xB531, 0xB54B, prLVT}, // Lo [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH + {0xB54C, 0xB54C, prLV}, // Lo HANGUL SYLLABLE DDAE + {0xB54D, 0xB567, prLVT}, // Lo [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH + {0xB568, 0xB568, prLV}, // Lo HANGUL SYLLABLE DDYA + {0xB569, 0xB583, prLVT}, // Lo [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH + {0xB584, 0xB584, prLV}, // Lo HANGUL SYLLABLE DDYAE + {0xB585, 0xB59F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH + {0xB5A0, 0xB5A0, prLV}, // Lo HANGUL SYLLABLE DDEO + {0xB5A1, 0xB5BB, prLVT}, // Lo [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH + {0xB5BC, 0xB5BC, prLV}, // Lo HANGUL SYLLABLE DDE + {0xB5BD, 0xB5D7, prLVT}, // Lo [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH + {0xB5D8, 0xB5D8, prLV}, // Lo HANGUL SYLLABLE DDYEO + {0xB5D9, 0xB5F3, prLVT}, // Lo [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH + {0xB5F4, 0xB5F4, prLV}, // Lo HANGUL SYLLABLE DDYE + {0xB5F5, 0xB60F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH + {0xB610, 0xB610, prLV}, // Lo HANGUL SYLLABLE DDO + {0xB611, 0xB62B, prLVT}, // Lo [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH + {0xB62C, 0xB62C, prLV}, // Lo HANGUL SYLLABLE DDWA + {0xB62D, 0xB647, prLVT}, // Lo [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH + {0xB648, 0xB648, prLV}, // Lo HANGUL SYLLABLE DDWAE + {0xB649, 0xB663, prLVT}, // Lo [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH + {0xB664, 0xB664, prLV}, // Lo HANGUL SYLLABLE DDOE + {0xB665, 0xB67F, prLVT}, // Lo [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH + {0xB680, 0xB680, prLV}, // Lo HANGUL SYLLABLE DDYO + {0xB681, 0xB69B, prLVT}, // Lo [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH + {0xB69C, 0xB69C, prLV}, // Lo HANGUL SYLLABLE DDU + {0xB69D, 0xB6B7, prLVT}, // Lo [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH + {0xB6B8, 0xB6B8, prLV}, // Lo HANGUL SYLLABLE DDWEO + {0xB6B9, 0xB6D3, prLVT}, // Lo [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH + {0xB6D4, 0xB6D4, prLV}, // Lo HANGUL SYLLABLE DDWE + {0xB6D5, 0xB6EF, prLVT}, // Lo [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH + {0xB6F0, 0xB6F0, prLV}, // Lo HANGUL SYLLABLE DDWI + {0xB6F1, 0xB70B, prLVT}, // Lo [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH + {0xB70C, 0xB70C, prLV}, // Lo HANGUL SYLLABLE DDYU + {0xB70D, 0xB727, prLVT}, // Lo [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH + {0xB728, 0xB728, prLV}, // Lo HANGUL SYLLABLE DDEU + {0xB729, 0xB743, prLVT}, // Lo [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH + {0xB744, 0xB744, prLV}, // Lo HANGUL SYLLABLE DDYI + {0xB745, 0xB75F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH + {0xB760, 0xB760, prLV}, // Lo HANGUL SYLLABLE DDI + {0xB761, 0xB77B, prLVT}, // Lo [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH + {0xB77C, 0xB77C, prLV}, // Lo HANGUL SYLLABLE RA + {0xB77D, 0xB797, prLVT}, // Lo [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH + {0xB798, 0xB798, prLV}, // Lo HANGUL SYLLABLE RAE + {0xB799, 0xB7B3, prLVT}, // Lo [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH + {0xB7B4, 0xB7B4, prLV}, // Lo HANGUL SYLLABLE RYA + {0xB7B5, 0xB7CF, prLVT}, // Lo [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH + {0xB7D0, 0xB7D0, prLV}, // Lo HANGUL SYLLABLE RYAE + {0xB7D1, 0xB7EB, prLVT}, // Lo [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH + {0xB7EC, 0xB7EC, prLV}, // Lo HANGUL SYLLABLE REO + {0xB7ED, 0xB807, prLVT}, // Lo [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH + {0xB808, 0xB808, prLV}, // Lo HANGUL SYLLABLE RE + {0xB809, 0xB823, prLVT}, // Lo [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH + {0xB824, 0xB824, prLV}, // Lo HANGUL SYLLABLE RYEO + {0xB825, 0xB83F, prLVT}, // Lo [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH + {0xB840, 0xB840, prLV}, // Lo HANGUL SYLLABLE RYE + {0xB841, 0xB85B, prLVT}, // Lo [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH + {0xB85C, 0xB85C, prLV}, // Lo HANGUL SYLLABLE RO + {0xB85D, 0xB877, prLVT}, // Lo [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH + {0xB878, 0xB878, prLV}, // Lo HANGUL SYLLABLE RWA + {0xB879, 0xB893, prLVT}, // Lo [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH + {0xB894, 0xB894, prLV}, // Lo HANGUL SYLLABLE RWAE + {0xB895, 0xB8AF, prLVT}, // Lo [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH + {0xB8B0, 0xB8B0, prLV}, // Lo HANGUL SYLLABLE ROE + {0xB8B1, 0xB8CB, prLVT}, // Lo [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH + {0xB8CC, 0xB8CC, prLV}, // Lo HANGUL SYLLABLE RYO + {0xB8CD, 0xB8E7, prLVT}, // Lo [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH + {0xB8E8, 0xB8E8, prLV}, // Lo HANGUL SYLLABLE RU + {0xB8E9, 0xB903, prLVT}, // Lo [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH + {0xB904, 0xB904, prLV}, // Lo HANGUL SYLLABLE RWEO + {0xB905, 0xB91F, prLVT}, // Lo [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH + {0xB920, 0xB920, prLV}, // Lo HANGUL SYLLABLE RWE + {0xB921, 0xB93B, prLVT}, // Lo [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH + {0xB93C, 0xB93C, prLV}, // Lo HANGUL SYLLABLE RWI + {0xB93D, 0xB957, prLVT}, // Lo [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH + {0xB958, 0xB958, prLV}, // Lo HANGUL SYLLABLE RYU + {0xB959, 0xB973, prLVT}, // Lo [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH + {0xB974, 0xB974, prLV}, // Lo HANGUL SYLLABLE REU + {0xB975, 0xB98F, prLVT}, // Lo [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH + {0xB990, 0xB990, prLV}, // Lo HANGUL SYLLABLE RYI + {0xB991, 0xB9AB, prLVT}, // Lo [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH + {0xB9AC, 0xB9AC, prLV}, // Lo HANGUL SYLLABLE RI + {0xB9AD, 0xB9C7, prLVT}, // Lo [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH + {0xB9C8, 0xB9C8, prLV}, // Lo HANGUL SYLLABLE MA + {0xB9C9, 0xB9E3, prLVT}, // Lo [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH + {0xB9E4, 0xB9E4, prLV}, // Lo HANGUL SYLLABLE MAE + {0xB9E5, 0xB9FF, prLVT}, // Lo [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH + {0xBA00, 0xBA00, prLV}, // Lo HANGUL SYLLABLE MYA + {0xBA01, 0xBA1B, prLVT}, // Lo [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH + {0xBA1C, 0xBA1C, prLV}, // Lo HANGUL SYLLABLE MYAE + {0xBA1D, 0xBA37, prLVT}, // Lo [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH + {0xBA38, 0xBA38, prLV}, // Lo HANGUL SYLLABLE MEO + {0xBA39, 0xBA53, prLVT}, // Lo [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH + {0xBA54, 0xBA54, prLV}, // Lo HANGUL SYLLABLE ME + {0xBA55, 0xBA6F, prLVT}, // Lo [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH + {0xBA70, 0xBA70, prLV}, // Lo HANGUL SYLLABLE MYEO + {0xBA71, 0xBA8B, prLVT}, // Lo [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH + {0xBA8C, 0xBA8C, prLV}, // Lo HANGUL SYLLABLE MYE + {0xBA8D, 0xBAA7, prLVT}, // Lo [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH + {0xBAA8, 0xBAA8, prLV}, // Lo HANGUL SYLLABLE MO + {0xBAA9, 0xBAC3, prLVT}, // Lo [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH + {0xBAC4, 0xBAC4, prLV}, // Lo HANGUL SYLLABLE MWA + {0xBAC5, 0xBADF, prLVT}, // Lo [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH + {0xBAE0, 0xBAE0, prLV}, // Lo HANGUL SYLLABLE MWAE + {0xBAE1, 0xBAFB, prLVT}, // Lo [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH + {0xBAFC, 0xBAFC, prLV}, // Lo HANGUL SYLLABLE MOE + {0xBAFD, 0xBB17, prLVT}, // Lo [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH + {0xBB18, 0xBB18, prLV}, // Lo HANGUL SYLLABLE MYO + {0xBB19, 0xBB33, prLVT}, // Lo [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH + {0xBB34, 0xBB34, prLV}, // Lo HANGUL SYLLABLE MU + {0xBB35, 0xBB4F, prLVT}, // Lo [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH + {0xBB50, 0xBB50, prLV}, // Lo HANGUL SYLLABLE MWEO + {0xBB51, 0xBB6B, prLVT}, // Lo [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH + {0xBB6C, 0xBB6C, prLV}, // Lo HANGUL SYLLABLE MWE + {0xBB6D, 0xBB87, prLVT}, // Lo [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH + {0xBB88, 0xBB88, prLV}, // Lo HANGUL SYLLABLE MWI + {0xBB89, 0xBBA3, prLVT}, // Lo [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH + {0xBBA4, 0xBBA4, prLV}, // Lo HANGUL SYLLABLE MYU + {0xBBA5, 0xBBBF, prLVT}, // Lo [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH + {0xBBC0, 0xBBC0, prLV}, // Lo HANGUL SYLLABLE MEU + {0xBBC1, 0xBBDB, prLVT}, // Lo [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH + {0xBBDC, 0xBBDC, prLV}, // Lo HANGUL SYLLABLE MYI + {0xBBDD, 0xBBF7, prLVT}, // Lo [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH + {0xBBF8, 0xBBF8, prLV}, // Lo HANGUL SYLLABLE MI + {0xBBF9, 0xBC13, prLVT}, // Lo [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH + {0xBC14, 0xBC14, prLV}, // Lo HANGUL SYLLABLE BA + {0xBC15, 0xBC2F, prLVT}, // Lo [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH + {0xBC30, 0xBC30, prLV}, // Lo HANGUL SYLLABLE BAE + {0xBC31, 0xBC4B, prLVT}, // Lo [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH + {0xBC4C, 0xBC4C, prLV}, // Lo HANGUL SYLLABLE BYA + {0xBC4D, 0xBC67, prLVT}, // Lo [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH + {0xBC68, 0xBC68, prLV}, // Lo HANGUL SYLLABLE BYAE + {0xBC69, 0xBC83, prLVT}, // Lo [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH + {0xBC84, 0xBC84, prLV}, // Lo HANGUL SYLLABLE BEO + {0xBC85, 0xBC9F, prLVT}, // Lo [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH + {0xBCA0, 0xBCA0, prLV}, // Lo HANGUL SYLLABLE BE + {0xBCA1, 0xBCBB, prLVT}, // Lo [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH + {0xBCBC, 0xBCBC, prLV}, // Lo HANGUL SYLLABLE BYEO + {0xBCBD, 0xBCD7, prLVT}, // Lo [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH + {0xBCD8, 0xBCD8, prLV}, // Lo HANGUL SYLLABLE BYE + {0xBCD9, 0xBCF3, prLVT}, // Lo [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH + {0xBCF4, 0xBCF4, prLV}, // Lo HANGUL SYLLABLE BO + {0xBCF5, 0xBD0F, prLVT}, // Lo [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH + {0xBD10, 0xBD10, prLV}, // Lo HANGUL SYLLABLE BWA + {0xBD11, 0xBD2B, prLVT}, // Lo [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH + {0xBD2C, 0xBD2C, prLV}, // Lo HANGUL SYLLABLE BWAE + {0xBD2D, 0xBD47, prLVT}, // Lo [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH + {0xBD48, 0xBD48, prLV}, // Lo HANGUL SYLLABLE BOE + {0xBD49, 0xBD63, prLVT}, // Lo [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH + {0xBD64, 0xBD64, prLV}, // Lo HANGUL SYLLABLE BYO + {0xBD65, 0xBD7F, prLVT}, // Lo [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH + {0xBD80, 0xBD80, prLV}, // Lo HANGUL SYLLABLE BU + {0xBD81, 0xBD9B, prLVT}, // Lo [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH + {0xBD9C, 0xBD9C, prLV}, // Lo HANGUL SYLLABLE BWEO + {0xBD9D, 0xBDB7, prLVT}, // Lo [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH + {0xBDB8, 0xBDB8, prLV}, // Lo HANGUL SYLLABLE BWE + {0xBDB9, 0xBDD3, prLVT}, // Lo [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH + {0xBDD4, 0xBDD4, prLV}, // Lo HANGUL SYLLABLE BWI + {0xBDD5, 0xBDEF, prLVT}, // Lo [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH + {0xBDF0, 0xBDF0, prLV}, // Lo HANGUL SYLLABLE BYU + {0xBDF1, 0xBE0B, prLVT}, // Lo [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH + {0xBE0C, 0xBE0C, prLV}, // Lo HANGUL SYLLABLE BEU + {0xBE0D, 0xBE27, prLVT}, // Lo [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH + {0xBE28, 0xBE28, prLV}, // Lo HANGUL SYLLABLE BYI + {0xBE29, 0xBE43, prLVT}, // Lo [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH + {0xBE44, 0xBE44, prLV}, // Lo HANGUL SYLLABLE BI + {0xBE45, 0xBE5F, prLVT}, // Lo [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH + {0xBE60, 0xBE60, prLV}, // Lo HANGUL SYLLABLE BBA + {0xBE61, 0xBE7B, prLVT}, // Lo [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH + {0xBE7C, 0xBE7C, prLV}, // Lo HANGUL SYLLABLE BBAE + {0xBE7D, 0xBE97, prLVT}, // Lo [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH + {0xBE98, 0xBE98, prLV}, // Lo HANGUL SYLLABLE BBYA + {0xBE99, 0xBEB3, prLVT}, // Lo [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH + {0xBEB4, 0xBEB4, prLV}, // Lo HANGUL SYLLABLE BBYAE + {0xBEB5, 0xBECF, prLVT}, // Lo [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH + {0xBED0, 0xBED0, prLV}, // Lo HANGUL SYLLABLE BBEO + {0xBED1, 0xBEEB, prLVT}, // Lo [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH + {0xBEEC, 0xBEEC, prLV}, // Lo HANGUL SYLLABLE BBE + {0xBEED, 0xBF07, prLVT}, // Lo [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH + {0xBF08, 0xBF08, prLV}, // Lo HANGUL SYLLABLE BBYEO + {0xBF09, 0xBF23, prLVT}, // Lo [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH + {0xBF24, 0xBF24, prLV}, // Lo HANGUL SYLLABLE BBYE + {0xBF25, 0xBF3F, prLVT}, // Lo [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH + {0xBF40, 0xBF40, prLV}, // Lo HANGUL SYLLABLE BBO + {0xBF41, 0xBF5B, prLVT}, // Lo [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH + {0xBF5C, 0xBF5C, prLV}, // Lo HANGUL SYLLABLE BBWA + {0xBF5D, 0xBF77, prLVT}, // Lo [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH + {0xBF78, 0xBF78, prLV}, // Lo HANGUL SYLLABLE BBWAE + {0xBF79, 0xBF93, prLVT}, // Lo [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH + {0xBF94, 0xBF94, prLV}, // Lo HANGUL SYLLABLE BBOE + {0xBF95, 0xBFAF, prLVT}, // Lo [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH + {0xBFB0, 0xBFB0, prLV}, // Lo HANGUL SYLLABLE BBYO + {0xBFB1, 0xBFCB, prLVT}, // Lo [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH + {0xBFCC, 0xBFCC, prLV}, // Lo HANGUL SYLLABLE BBU + {0xBFCD, 0xBFE7, prLVT}, // Lo [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH + {0xBFE8, 0xBFE8, prLV}, // Lo HANGUL SYLLABLE BBWEO + {0xBFE9, 0xC003, prLVT}, // Lo [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH + {0xC004, 0xC004, prLV}, // Lo HANGUL SYLLABLE BBWE + {0xC005, 0xC01F, prLVT}, // Lo [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH + {0xC020, 0xC020, prLV}, // Lo HANGUL SYLLABLE BBWI + {0xC021, 0xC03B, prLVT}, // Lo [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH + {0xC03C, 0xC03C, prLV}, // Lo HANGUL SYLLABLE BBYU + {0xC03D, 0xC057, prLVT}, // Lo [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH + {0xC058, 0xC058, prLV}, // Lo HANGUL SYLLABLE BBEU + {0xC059, 0xC073, prLVT}, // Lo [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH + {0xC074, 0xC074, prLV}, // Lo HANGUL SYLLABLE BBYI + {0xC075, 0xC08F, prLVT}, // Lo [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH + {0xC090, 0xC090, prLV}, // Lo HANGUL SYLLABLE BBI + {0xC091, 0xC0AB, prLVT}, // Lo [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH + {0xC0AC, 0xC0AC, prLV}, // Lo HANGUL SYLLABLE SA + {0xC0AD, 0xC0C7, prLVT}, // Lo [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH + {0xC0C8, 0xC0C8, prLV}, // Lo HANGUL SYLLABLE SAE + {0xC0C9, 0xC0E3, prLVT}, // Lo [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH + {0xC0E4, 0xC0E4, prLV}, // Lo HANGUL SYLLABLE SYA + {0xC0E5, 0xC0FF, prLVT}, // Lo [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH + {0xC100, 0xC100, prLV}, // Lo HANGUL SYLLABLE SYAE + {0xC101, 0xC11B, prLVT}, // Lo [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH + {0xC11C, 0xC11C, prLV}, // Lo HANGUL SYLLABLE SEO + {0xC11D, 0xC137, prLVT}, // Lo [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH + {0xC138, 0xC138, prLV}, // Lo HANGUL SYLLABLE SE + {0xC139, 0xC153, prLVT}, // Lo [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH + {0xC154, 0xC154, prLV}, // Lo HANGUL SYLLABLE SYEO + {0xC155, 0xC16F, prLVT}, // Lo [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH + {0xC170, 0xC170, prLV}, // Lo HANGUL SYLLABLE SYE + {0xC171, 0xC18B, prLVT}, // Lo [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH + {0xC18C, 0xC18C, prLV}, // Lo HANGUL SYLLABLE SO + {0xC18D, 0xC1A7, prLVT}, // Lo [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH + {0xC1A8, 0xC1A8, prLV}, // Lo HANGUL SYLLABLE SWA + {0xC1A9, 0xC1C3, prLVT}, // Lo [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH + {0xC1C4, 0xC1C4, prLV}, // Lo HANGUL SYLLABLE SWAE + {0xC1C5, 0xC1DF, prLVT}, // Lo [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH + {0xC1E0, 0xC1E0, prLV}, // Lo HANGUL SYLLABLE SOE + {0xC1E1, 0xC1FB, prLVT}, // Lo [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH + {0xC1FC, 0xC1FC, prLV}, // Lo HANGUL SYLLABLE SYO + {0xC1FD, 0xC217, prLVT}, // Lo [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH + {0xC218, 0xC218, prLV}, // Lo HANGUL SYLLABLE SU + {0xC219, 0xC233, prLVT}, // Lo [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH + {0xC234, 0xC234, prLV}, // Lo HANGUL SYLLABLE SWEO + {0xC235, 0xC24F, prLVT}, // Lo [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH + {0xC250, 0xC250, prLV}, // Lo HANGUL SYLLABLE SWE + {0xC251, 0xC26B, prLVT}, // Lo [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH + {0xC26C, 0xC26C, prLV}, // Lo HANGUL SYLLABLE SWI + {0xC26D, 0xC287, prLVT}, // Lo [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH + {0xC288, 0xC288, prLV}, // Lo HANGUL SYLLABLE SYU + {0xC289, 0xC2A3, prLVT}, // Lo [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH + {0xC2A4, 0xC2A4, prLV}, // Lo HANGUL SYLLABLE SEU + {0xC2A5, 0xC2BF, prLVT}, // Lo [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH + {0xC2C0, 0xC2C0, prLV}, // Lo HANGUL SYLLABLE SYI + {0xC2C1, 0xC2DB, prLVT}, // Lo [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH + {0xC2DC, 0xC2DC, prLV}, // Lo HANGUL SYLLABLE SI + {0xC2DD, 0xC2F7, prLVT}, // Lo [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH + {0xC2F8, 0xC2F8, prLV}, // Lo HANGUL SYLLABLE SSA + {0xC2F9, 0xC313, prLVT}, // Lo [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH + {0xC314, 0xC314, prLV}, // Lo HANGUL SYLLABLE SSAE + {0xC315, 0xC32F, prLVT}, // Lo [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH + {0xC330, 0xC330, prLV}, // Lo HANGUL SYLLABLE SSYA + {0xC331, 0xC34B, prLVT}, // Lo [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH + {0xC34C, 0xC34C, prLV}, // Lo HANGUL SYLLABLE SSYAE + {0xC34D, 0xC367, prLVT}, // Lo [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH + {0xC368, 0xC368, prLV}, // Lo HANGUL SYLLABLE SSEO + {0xC369, 0xC383, prLVT}, // Lo [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH + {0xC384, 0xC384, prLV}, // Lo HANGUL SYLLABLE SSE + {0xC385, 0xC39F, prLVT}, // Lo [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH + {0xC3A0, 0xC3A0, prLV}, // Lo HANGUL SYLLABLE SSYEO + {0xC3A1, 0xC3BB, prLVT}, // Lo [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH + {0xC3BC, 0xC3BC, prLV}, // Lo HANGUL SYLLABLE SSYE + {0xC3BD, 0xC3D7, prLVT}, // Lo [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH + {0xC3D8, 0xC3D8, prLV}, // Lo HANGUL SYLLABLE SSO + {0xC3D9, 0xC3F3, prLVT}, // Lo [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH + {0xC3F4, 0xC3F4, prLV}, // Lo HANGUL SYLLABLE SSWA + {0xC3F5, 0xC40F, prLVT}, // Lo [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH + {0xC410, 0xC410, prLV}, // Lo HANGUL SYLLABLE SSWAE + {0xC411, 0xC42B, prLVT}, // Lo [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH + {0xC42C, 0xC42C, prLV}, // Lo HANGUL SYLLABLE SSOE + {0xC42D, 0xC447, prLVT}, // Lo [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH + {0xC448, 0xC448, prLV}, // Lo HANGUL SYLLABLE SSYO + {0xC449, 0xC463, prLVT}, // Lo [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH + {0xC464, 0xC464, prLV}, // Lo HANGUL SYLLABLE SSU + {0xC465, 0xC47F, prLVT}, // Lo [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH + {0xC480, 0xC480, prLV}, // Lo HANGUL SYLLABLE SSWEO + {0xC481, 0xC49B, prLVT}, // Lo [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH + {0xC49C, 0xC49C, prLV}, // Lo HANGUL SYLLABLE SSWE + {0xC49D, 0xC4B7, prLVT}, // Lo [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH + {0xC4B8, 0xC4B8, prLV}, // Lo HANGUL SYLLABLE SSWI + {0xC4B9, 0xC4D3, prLVT}, // Lo [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH + {0xC4D4, 0xC4D4, prLV}, // Lo HANGUL SYLLABLE SSYU + {0xC4D5, 0xC4EF, prLVT}, // Lo [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH + {0xC4F0, 0xC4F0, prLV}, // Lo HANGUL SYLLABLE SSEU + {0xC4F1, 0xC50B, prLVT}, // Lo [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH + {0xC50C, 0xC50C, prLV}, // Lo HANGUL SYLLABLE SSYI + {0xC50D, 0xC527, prLVT}, // Lo [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH + {0xC528, 0xC528, prLV}, // Lo HANGUL SYLLABLE SSI + {0xC529, 0xC543, prLVT}, // Lo [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH + {0xC544, 0xC544, prLV}, // Lo HANGUL SYLLABLE A + {0xC545, 0xC55F, prLVT}, // Lo [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH + {0xC560, 0xC560, prLV}, // Lo HANGUL SYLLABLE AE + {0xC561, 0xC57B, prLVT}, // Lo [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH + {0xC57C, 0xC57C, prLV}, // Lo HANGUL SYLLABLE YA + {0xC57D, 0xC597, prLVT}, // Lo [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH + {0xC598, 0xC598, prLV}, // Lo HANGUL SYLLABLE YAE + {0xC599, 0xC5B3, prLVT}, // Lo [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH + {0xC5B4, 0xC5B4, prLV}, // Lo HANGUL SYLLABLE EO + {0xC5B5, 0xC5CF, prLVT}, // Lo [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH + {0xC5D0, 0xC5D0, prLV}, // Lo HANGUL SYLLABLE E + {0xC5D1, 0xC5EB, prLVT}, // Lo [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH + {0xC5EC, 0xC5EC, prLV}, // Lo HANGUL SYLLABLE YEO + {0xC5ED, 0xC607, prLVT}, // Lo [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH + {0xC608, 0xC608, prLV}, // Lo HANGUL SYLLABLE YE + {0xC609, 0xC623, prLVT}, // Lo [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH + {0xC624, 0xC624, prLV}, // Lo HANGUL SYLLABLE O + {0xC625, 0xC63F, prLVT}, // Lo [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH + {0xC640, 0xC640, prLV}, // Lo HANGUL SYLLABLE WA + {0xC641, 0xC65B, prLVT}, // Lo [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH + {0xC65C, 0xC65C, prLV}, // Lo HANGUL SYLLABLE WAE + {0xC65D, 0xC677, prLVT}, // Lo [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH + {0xC678, 0xC678, prLV}, // Lo HANGUL SYLLABLE OE + {0xC679, 0xC693, prLVT}, // Lo [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH + {0xC694, 0xC694, prLV}, // Lo HANGUL SYLLABLE YO + {0xC695, 0xC6AF, prLVT}, // Lo [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH + {0xC6B0, 0xC6B0, prLV}, // Lo HANGUL SYLLABLE U + {0xC6B1, 0xC6CB, prLVT}, // Lo [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH + {0xC6CC, 0xC6CC, prLV}, // Lo HANGUL SYLLABLE WEO + {0xC6CD, 0xC6E7, prLVT}, // Lo [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH + {0xC6E8, 0xC6E8, prLV}, // Lo HANGUL SYLLABLE WE + {0xC6E9, 0xC703, prLVT}, // Lo [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH + {0xC704, 0xC704, prLV}, // Lo HANGUL SYLLABLE WI + {0xC705, 0xC71F, prLVT}, // Lo [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH + {0xC720, 0xC720, prLV}, // Lo HANGUL SYLLABLE YU + {0xC721, 0xC73B, prLVT}, // Lo [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH + {0xC73C, 0xC73C, prLV}, // Lo HANGUL SYLLABLE EU + {0xC73D, 0xC757, prLVT}, // Lo [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH + {0xC758, 0xC758, prLV}, // Lo HANGUL SYLLABLE YI + {0xC759, 0xC773, prLVT}, // Lo [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH + {0xC774, 0xC774, prLV}, // Lo HANGUL SYLLABLE I + {0xC775, 0xC78F, prLVT}, // Lo [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH + {0xC790, 0xC790, prLV}, // Lo HANGUL SYLLABLE JA + {0xC791, 0xC7AB, prLVT}, // Lo [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH + {0xC7AC, 0xC7AC, prLV}, // Lo HANGUL SYLLABLE JAE + {0xC7AD, 0xC7C7, prLVT}, // Lo [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH + {0xC7C8, 0xC7C8, prLV}, // Lo HANGUL SYLLABLE JYA + {0xC7C9, 0xC7E3, prLVT}, // Lo [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH + {0xC7E4, 0xC7E4, prLV}, // Lo HANGUL SYLLABLE JYAE + {0xC7E5, 0xC7FF, prLVT}, // Lo [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH + {0xC800, 0xC800, prLV}, // Lo HANGUL SYLLABLE JEO + {0xC801, 0xC81B, prLVT}, // Lo [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH + {0xC81C, 0xC81C, prLV}, // Lo HANGUL SYLLABLE JE + {0xC81D, 0xC837, prLVT}, // Lo [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH + {0xC838, 0xC838, prLV}, // Lo HANGUL SYLLABLE JYEO + {0xC839, 0xC853, prLVT}, // Lo [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH + {0xC854, 0xC854, prLV}, // Lo HANGUL SYLLABLE JYE + {0xC855, 0xC86F, prLVT}, // Lo [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH + {0xC870, 0xC870, prLV}, // Lo HANGUL SYLLABLE JO + {0xC871, 0xC88B, prLVT}, // Lo [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH + {0xC88C, 0xC88C, prLV}, // Lo HANGUL SYLLABLE JWA + {0xC88D, 0xC8A7, prLVT}, // Lo [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH + {0xC8A8, 0xC8A8, prLV}, // Lo HANGUL SYLLABLE JWAE + {0xC8A9, 0xC8C3, prLVT}, // Lo [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH + {0xC8C4, 0xC8C4, prLV}, // Lo HANGUL SYLLABLE JOE + {0xC8C5, 0xC8DF, prLVT}, // Lo [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH + {0xC8E0, 0xC8E0, prLV}, // Lo HANGUL SYLLABLE JYO + {0xC8E1, 0xC8FB, prLVT}, // Lo [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH + {0xC8FC, 0xC8FC, prLV}, // Lo HANGUL SYLLABLE JU + {0xC8FD, 0xC917, prLVT}, // Lo [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH + {0xC918, 0xC918, prLV}, // Lo HANGUL SYLLABLE JWEO + {0xC919, 0xC933, prLVT}, // Lo [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH + {0xC934, 0xC934, prLV}, // Lo HANGUL SYLLABLE JWE + {0xC935, 0xC94F, prLVT}, // Lo [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH + {0xC950, 0xC950, prLV}, // Lo HANGUL SYLLABLE JWI + {0xC951, 0xC96B, prLVT}, // Lo [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH + {0xC96C, 0xC96C, prLV}, // Lo HANGUL SYLLABLE JYU + {0xC96D, 0xC987, prLVT}, // Lo [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH + {0xC988, 0xC988, prLV}, // Lo HANGUL SYLLABLE JEU + {0xC989, 0xC9A3, prLVT}, // Lo [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH + {0xC9A4, 0xC9A4, prLV}, // Lo HANGUL SYLLABLE JYI + {0xC9A5, 0xC9BF, prLVT}, // Lo [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH + {0xC9C0, 0xC9C0, prLV}, // Lo HANGUL SYLLABLE JI + {0xC9C1, 0xC9DB, prLVT}, // Lo [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH + {0xC9DC, 0xC9DC, prLV}, // Lo HANGUL SYLLABLE JJA + {0xC9DD, 0xC9F7, prLVT}, // Lo [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH + {0xC9F8, 0xC9F8, prLV}, // Lo HANGUL SYLLABLE JJAE + {0xC9F9, 0xCA13, prLVT}, // Lo [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH + {0xCA14, 0xCA14, prLV}, // Lo HANGUL SYLLABLE JJYA + {0xCA15, 0xCA2F, prLVT}, // Lo [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH + {0xCA30, 0xCA30, prLV}, // Lo HANGUL SYLLABLE JJYAE + {0xCA31, 0xCA4B, prLVT}, // Lo [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH + {0xCA4C, 0xCA4C, prLV}, // Lo HANGUL SYLLABLE JJEO + {0xCA4D, 0xCA67, prLVT}, // Lo [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH + {0xCA68, 0xCA68, prLV}, // Lo HANGUL SYLLABLE JJE + {0xCA69, 0xCA83, prLVT}, // Lo [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH + {0xCA84, 0xCA84, prLV}, // Lo HANGUL SYLLABLE JJYEO + {0xCA85, 0xCA9F, prLVT}, // Lo [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH + {0xCAA0, 0xCAA0, prLV}, // Lo HANGUL SYLLABLE JJYE + {0xCAA1, 0xCABB, prLVT}, // Lo [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH + {0xCABC, 0xCABC, prLV}, // Lo HANGUL SYLLABLE JJO + {0xCABD, 0xCAD7, prLVT}, // Lo [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH + {0xCAD8, 0xCAD8, prLV}, // Lo HANGUL SYLLABLE JJWA + {0xCAD9, 0xCAF3, prLVT}, // Lo [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH + {0xCAF4, 0xCAF4, prLV}, // Lo HANGUL SYLLABLE JJWAE + {0xCAF5, 0xCB0F, prLVT}, // Lo [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH + {0xCB10, 0xCB10, prLV}, // Lo HANGUL SYLLABLE JJOE + {0xCB11, 0xCB2B, prLVT}, // Lo [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH + {0xCB2C, 0xCB2C, prLV}, // Lo HANGUL SYLLABLE JJYO + {0xCB2D, 0xCB47, prLVT}, // Lo [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH + {0xCB48, 0xCB48, prLV}, // Lo HANGUL SYLLABLE JJU + {0xCB49, 0xCB63, prLVT}, // Lo [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH + {0xCB64, 0xCB64, prLV}, // Lo HANGUL SYLLABLE JJWEO + {0xCB65, 0xCB7F, prLVT}, // Lo [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH + {0xCB80, 0xCB80, prLV}, // Lo HANGUL SYLLABLE JJWE + {0xCB81, 0xCB9B, prLVT}, // Lo [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH + {0xCB9C, 0xCB9C, prLV}, // Lo HANGUL SYLLABLE JJWI + {0xCB9D, 0xCBB7, prLVT}, // Lo [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH + {0xCBB8, 0xCBB8, prLV}, // Lo HANGUL SYLLABLE JJYU + {0xCBB9, 0xCBD3, prLVT}, // Lo [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH + {0xCBD4, 0xCBD4, prLV}, // Lo HANGUL SYLLABLE JJEU + {0xCBD5, 0xCBEF, prLVT}, // Lo [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH + {0xCBF0, 0xCBF0, prLV}, // Lo HANGUL SYLLABLE JJYI + {0xCBF1, 0xCC0B, prLVT}, // Lo [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH + {0xCC0C, 0xCC0C, prLV}, // Lo HANGUL SYLLABLE JJI + {0xCC0D, 0xCC27, prLVT}, // Lo [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH + {0xCC28, 0xCC28, prLV}, // Lo HANGUL SYLLABLE CA + {0xCC29, 0xCC43, prLVT}, // Lo [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH + {0xCC44, 0xCC44, prLV}, // Lo HANGUL SYLLABLE CAE + {0xCC45, 0xCC5F, prLVT}, // Lo [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH + {0xCC60, 0xCC60, prLV}, // Lo HANGUL SYLLABLE CYA + {0xCC61, 0xCC7B, prLVT}, // Lo [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH + {0xCC7C, 0xCC7C, prLV}, // Lo HANGUL SYLLABLE CYAE + {0xCC7D, 0xCC97, prLVT}, // Lo [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH + {0xCC98, 0xCC98, prLV}, // Lo HANGUL SYLLABLE CEO + {0xCC99, 0xCCB3, prLVT}, // Lo [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH + {0xCCB4, 0xCCB4, prLV}, // Lo HANGUL SYLLABLE CE + {0xCCB5, 0xCCCF, prLVT}, // Lo [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH + {0xCCD0, 0xCCD0, prLV}, // Lo HANGUL SYLLABLE CYEO + {0xCCD1, 0xCCEB, prLVT}, // Lo [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH + {0xCCEC, 0xCCEC, prLV}, // Lo HANGUL SYLLABLE CYE + {0xCCED, 0xCD07, prLVT}, // Lo [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH + {0xCD08, 0xCD08, prLV}, // Lo HANGUL SYLLABLE CO + {0xCD09, 0xCD23, prLVT}, // Lo [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH + {0xCD24, 0xCD24, prLV}, // Lo HANGUL SYLLABLE CWA + {0xCD25, 0xCD3F, prLVT}, // Lo [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH + {0xCD40, 0xCD40, prLV}, // Lo HANGUL SYLLABLE CWAE + {0xCD41, 0xCD5B, prLVT}, // Lo [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH + {0xCD5C, 0xCD5C, prLV}, // Lo HANGUL SYLLABLE COE + {0xCD5D, 0xCD77, prLVT}, // Lo [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH + {0xCD78, 0xCD78, prLV}, // Lo HANGUL SYLLABLE CYO + {0xCD79, 0xCD93, prLVT}, // Lo [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH + {0xCD94, 0xCD94, prLV}, // Lo HANGUL SYLLABLE CU + {0xCD95, 0xCDAF, prLVT}, // Lo [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH + {0xCDB0, 0xCDB0, prLV}, // Lo HANGUL SYLLABLE CWEO + {0xCDB1, 0xCDCB, prLVT}, // Lo [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH + {0xCDCC, 0xCDCC, prLV}, // Lo HANGUL SYLLABLE CWE + {0xCDCD, 0xCDE7, prLVT}, // Lo [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH + {0xCDE8, 0xCDE8, prLV}, // Lo HANGUL SYLLABLE CWI + {0xCDE9, 0xCE03, prLVT}, // Lo [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH + {0xCE04, 0xCE04, prLV}, // Lo HANGUL SYLLABLE CYU + {0xCE05, 0xCE1F, prLVT}, // Lo [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH + {0xCE20, 0xCE20, prLV}, // Lo HANGUL SYLLABLE CEU + {0xCE21, 0xCE3B, prLVT}, // Lo [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH + {0xCE3C, 0xCE3C, prLV}, // Lo HANGUL SYLLABLE CYI + {0xCE3D, 0xCE57, prLVT}, // Lo [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH + {0xCE58, 0xCE58, prLV}, // Lo HANGUL SYLLABLE CI + {0xCE59, 0xCE73, prLVT}, // Lo [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH + {0xCE74, 0xCE74, prLV}, // Lo HANGUL SYLLABLE KA + {0xCE75, 0xCE8F, prLVT}, // Lo [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH + {0xCE90, 0xCE90, prLV}, // Lo HANGUL SYLLABLE KAE + {0xCE91, 0xCEAB, prLVT}, // Lo [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH + {0xCEAC, 0xCEAC, prLV}, // Lo HANGUL SYLLABLE KYA + {0xCEAD, 0xCEC7, prLVT}, // Lo [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH + {0xCEC8, 0xCEC8, prLV}, // Lo HANGUL SYLLABLE KYAE + {0xCEC9, 0xCEE3, prLVT}, // Lo [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH + {0xCEE4, 0xCEE4, prLV}, // Lo HANGUL SYLLABLE KEO + {0xCEE5, 0xCEFF, prLVT}, // Lo [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH + {0xCF00, 0xCF00, prLV}, // Lo HANGUL SYLLABLE KE + {0xCF01, 0xCF1B, prLVT}, // Lo [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH + {0xCF1C, 0xCF1C, prLV}, // Lo HANGUL SYLLABLE KYEO + {0xCF1D, 0xCF37, prLVT}, // Lo [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH + {0xCF38, 0xCF38, prLV}, // Lo HANGUL SYLLABLE KYE + {0xCF39, 0xCF53, prLVT}, // Lo [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH + {0xCF54, 0xCF54, prLV}, // Lo HANGUL SYLLABLE KO + {0xCF55, 0xCF6F, prLVT}, // Lo [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH + {0xCF70, 0xCF70, prLV}, // Lo HANGUL SYLLABLE KWA + {0xCF71, 0xCF8B, prLVT}, // Lo [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH + {0xCF8C, 0xCF8C, prLV}, // Lo HANGUL SYLLABLE KWAE + {0xCF8D, 0xCFA7, prLVT}, // Lo [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH + {0xCFA8, 0xCFA8, prLV}, // Lo HANGUL SYLLABLE KOE + {0xCFA9, 0xCFC3, prLVT}, // Lo [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH + {0xCFC4, 0xCFC4, prLV}, // Lo HANGUL SYLLABLE KYO + {0xCFC5, 0xCFDF, prLVT}, // Lo [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH + {0xCFE0, 0xCFE0, prLV}, // Lo HANGUL SYLLABLE KU + {0xCFE1, 0xCFFB, prLVT}, // Lo [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH + {0xCFFC, 0xCFFC, prLV}, // Lo HANGUL SYLLABLE KWEO + {0xCFFD, 0xD017, prLVT}, // Lo [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH + {0xD018, 0xD018, prLV}, // Lo HANGUL SYLLABLE KWE + {0xD019, 0xD033, prLVT}, // Lo [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH + {0xD034, 0xD034, prLV}, // Lo HANGUL SYLLABLE KWI + {0xD035, 0xD04F, prLVT}, // Lo [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH + {0xD050, 0xD050, prLV}, // Lo HANGUL SYLLABLE KYU + {0xD051, 0xD06B, prLVT}, // Lo [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH + {0xD06C, 0xD06C, prLV}, // Lo HANGUL SYLLABLE KEU + {0xD06D, 0xD087, prLVT}, // Lo [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH + {0xD088, 0xD088, prLV}, // Lo HANGUL SYLLABLE KYI + {0xD089, 0xD0A3, prLVT}, // Lo [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH + {0xD0A4, 0xD0A4, prLV}, // Lo HANGUL SYLLABLE KI + {0xD0A5, 0xD0BF, prLVT}, // Lo [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH + {0xD0C0, 0xD0C0, prLV}, // Lo HANGUL SYLLABLE TA + {0xD0C1, 0xD0DB, prLVT}, // Lo [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH + {0xD0DC, 0xD0DC, prLV}, // Lo HANGUL SYLLABLE TAE + {0xD0DD, 0xD0F7, prLVT}, // Lo [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH + {0xD0F8, 0xD0F8, prLV}, // Lo HANGUL SYLLABLE TYA + {0xD0F9, 0xD113, prLVT}, // Lo [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH + {0xD114, 0xD114, prLV}, // Lo HANGUL SYLLABLE TYAE + {0xD115, 0xD12F, prLVT}, // Lo [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH + {0xD130, 0xD130, prLV}, // Lo HANGUL SYLLABLE TEO + {0xD131, 0xD14B, prLVT}, // Lo [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH + {0xD14C, 0xD14C, prLV}, // Lo HANGUL SYLLABLE TE + {0xD14D, 0xD167, prLVT}, // Lo [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH + {0xD168, 0xD168, prLV}, // Lo HANGUL SYLLABLE TYEO + {0xD169, 0xD183, prLVT}, // Lo [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH + {0xD184, 0xD184, prLV}, // Lo HANGUL SYLLABLE TYE + {0xD185, 0xD19F, prLVT}, // Lo [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH + {0xD1A0, 0xD1A0, prLV}, // Lo HANGUL SYLLABLE TO + {0xD1A1, 0xD1BB, prLVT}, // Lo [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH + {0xD1BC, 0xD1BC, prLV}, // Lo HANGUL SYLLABLE TWA + {0xD1BD, 0xD1D7, prLVT}, // Lo [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH + {0xD1D8, 0xD1D8, prLV}, // Lo HANGUL SYLLABLE TWAE + {0xD1D9, 0xD1F3, prLVT}, // Lo [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH + {0xD1F4, 0xD1F4, prLV}, // Lo HANGUL SYLLABLE TOE + {0xD1F5, 0xD20F, prLVT}, // Lo [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH + {0xD210, 0xD210, prLV}, // Lo HANGUL SYLLABLE TYO + {0xD211, 0xD22B, prLVT}, // Lo [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH + {0xD22C, 0xD22C, prLV}, // Lo HANGUL SYLLABLE TU + {0xD22D, 0xD247, prLVT}, // Lo [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH + {0xD248, 0xD248, prLV}, // Lo HANGUL SYLLABLE TWEO + {0xD249, 0xD263, prLVT}, // Lo [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH + {0xD264, 0xD264, prLV}, // Lo HANGUL SYLLABLE TWE + {0xD265, 0xD27F, prLVT}, // Lo [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH + {0xD280, 0xD280, prLV}, // Lo HANGUL SYLLABLE TWI + {0xD281, 0xD29B, prLVT}, // Lo [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH + {0xD29C, 0xD29C, prLV}, // Lo HANGUL SYLLABLE TYU + {0xD29D, 0xD2B7, prLVT}, // Lo [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH + {0xD2B8, 0xD2B8, prLV}, // Lo HANGUL SYLLABLE TEU + {0xD2B9, 0xD2D3, prLVT}, // Lo [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH + {0xD2D4, 0xD2D4, prLV}, // Lo HANGUL SYLLABLE TYI + {0xD2D5, 0xD2EF, prLVT}, // Lo [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH + {0xD2F0, 0xD2F0, prLV}, // Lo HANGUL SYLLABLE TI + {0xD2F1, 0xD30B, prLVT}, // Lo [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH + {0xD30C, 0xD30C, prLV}, // Lo HANGUL SYLLABLE PA + {0xD30D, 0xD327, prLVT}, // Lo [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH + {0xD328, 0xD328, prLV}, // Lo HANGUL SYLLABLE PAE + {0xD329, 0xD343, prLVT}, // Lo [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH + {0xD344, 0xD344, prLV}, // Lo HANGUL SYLLABLE PYA + {0xD345, 0xD35F, prLVT}, // Lo [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH + {0xD360, 0xD360, prLV}, // Lo HANGUL SYLLABLE PYAE + {0xD361, 0xD37B, prLVT}, // Lo [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH + {0xD37C, 0xD37C, prLV}, // Lo HANGUL SYLLABLE PEO + {0xD37D, 0xD397, prLVT}, // Lo [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH + {0xD398, 0xD398, prLV}, // Lo HANGUL SYLLABLE PE + {0xD399, 0xD3B3, prLVT}, // Lo [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH + {0xD3B4, 0xD3B4, prLV}, // Lo HANGUL SYLLABLE PYEO + {0xD3B5, 0xD3CF, prLVT}, // Lo [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH + {0xD3D0, 0xD3D0, prLV}, // Lo HANGUL SYLLABLE PYE + {0xD3D1, 0xD3EB, prLVT}, // Lo [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH + {0xD3EC, 0xD3EC, prLV}, // Lo HANGUL SYLLABLE PO + {0xD3ED, 0xD407, prLVT}, // Lo [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH + {0xD408, 0xD408, prLV}, // Lo HANGUL SYLLABLE PWA + {0xD409, 0xD423, prLVT}, // Lo [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH + {0xD424, 0xD424, prLV}, // Lo HANGUL SYLLABLE PWAE + {0xD425, 0xD43F, prLVT}, // Lo [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH + {0xD440, 0xD440, prLV}, // Lo HANGUL SYLLABLE POE + {0xD441, 0xD45B, prLVT}, // Lo [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH + {0xD45C, 0xD45C, prLV}, // Lo HANGUL SYLLABLE PYO + {0xD45D, 0xD477, prLVT}, // Lo [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH + {0xD478, 0xD478, prLV}, // Lo HANGUL SYLLABLE PU + {0xD479, 0xD493, prLVT}, // Lo [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH + {0xD494, 0xD494, prLV}, // Lo HANGUL SYLLABLE PWEO + {0xD495, 0xD4AF, prLVT}, // Lo [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH + {0xD4B0, 0xD4B0, prLV}, // Lo HANGUL SYLLABLE PWE + {0xD4B1, 0xD4CB, prLVT}, // Lo [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH + {0xD4CC, 0xD4CC, prLV}, // Lo HANGUL SYLLABLE PWI + {0xD4CD, 0xD4E7, prLVT}, // Lo [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH + {0xD4E8, 0xD4E8, prLV}, // Lo HANGUL SYLLABLE PYU + {0xD4E9, 0xD503, prLVT}, // Lo [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH + {0xD504, 0xD504, prLV}, // Lo HANGUL SYLLABLE PEU + {0xD505, 0xD51F, prLVT}, // Lo [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH + {0xD520, 0xD520, prLV}, // Lo HANGUL SYLLABLE PYI + {0xD521, 0xD53B, prLVT}, // Lo [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH + {0xD53C, 0xD53C, prLV}, // Lo HANGUL SYLLABLE PI + {0xD53D, 0xD557, prLVT}, // Lo [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH + {0xD558, 0xD558, prLV}, // Lo HANGUL SYLLABLE HA + {0xD559, 0xD573, prLVT}, // Lo [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH + {0xD574, 0xD574, prLV}, // Lo HANGUL SYLLABLE HAE + {0xD575, 0xD58F, prLVT}, // Lo [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH + {0xD590, 0xD590, prLV}, // Lo HANGUL SYLLABLE HYA + {0xD591, 0xD5AB, prLVT}, // Lo [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH + {0xD5AC, 0xD5AC, prLV}, // Lo HANGUL SYLLABLE HYAE + {0xD5AD, 0xD5C7, prLVT}, // Lo [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH + {0xD5C8, 0xD5C8, prLV}, // Lo HANGUL SYLLABLE HEO + {0xD5C9, 0xD5E3, prLVT}, // Lo [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH + {0xD5E4, 0xD5E4, prLV}, // Lo HANGUL SYLLABLE HE + {0xD5E5, 0xD5FF, prLVT}, // Lo [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH + {0xD600, 0xD600, prLV}, // Lo HANGUL SYLLABLE HYEO + {0xD601, 0xD61B, prLVT}, // Lo [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH + {0xD61C, 0xD61C, prLV}, // Lo HANGUL SYLLABLE HYE + {0xD61D, 0xD637, prLVT}, // Lo [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH + {0xD638, 0xD638, prLV}, // Lo HANGUL SYLLABLE HO + {0xD639, 0xD653, prLVT}, // Lo [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH + {0xD654, 0xD654, prLV}, // Lo HANGUL SYLLABLE HWA + {0xD655, 0xD66F, prLVT}, // Lo [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH + {0xD670, 0xD670, prLV}, // Lo HANGUL SYLLABLE HWAE + {0xD671, 0xD68B, prLVT}, // Lo [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH + {0xD68C, 0xD68C, prLV}, // Lo HANGUL SYLLABLE HOE + {0xD68D, 0xD6A7, prLVT}, // Lo [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH + {0xD6A8, 0xD6A8, prLV}, // Lo HANGUL SYLLABLE HYO + {0xD6A9, 0xD6C3, prLVT}, // Lo [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH + {0xD6C4, 0xD6C4, prLV}, // Lo HANGUL SYLLABLE HU + {0xD6C5, 0xD6DF, prLVT}, // Lo [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH + {0xD6E0, 0xD6E0, prLV}, // Lo HANGUL SYLLABLE HWEO + {0xD6E1, 0xD6FB, prLVT}, // Lo [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH + {0xD6FC, 0xD6FC, prLV}, // Lo HANGUL SYLLABLE HWE + {0xD6FD, 0xD717, prLVT}, // Lo [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH + {0xD718, 0xD718, prLV}, // Lo HANGUL SYLLABLE HWI + {0xD719, 0xD733, prLVT}, // Lo [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH + {0xD734, 0xD734, prLV}, // Lo HANGUL SYLLABLE HYU + {0xD735, 0xD74F, prLVT}, // Lo [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH + {0xD750, 0xD750, prLV}, // Lo HANGUL SYLLABLE HEU + {0xD751, 0xD76B, prLVT}, // Lo [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH + {0xD76C, 0xD76C, prLV}, // Lo HANGUL SYLLABLE HYI + {0xD76D, 0xD787, prLVT}, // Lo [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH + {0xD788, 0xD788, prLV}, // Lo HANGUL SYLLABLE HI + {0xD789, 0xD7A3, prLVT}, // Lo [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prV}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prT}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xFB1E, 0xFB1E, prExtend}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA + {0xFE00, 0xFE0F, prExtend}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE20, 0xFE2F, prExtend}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFEFF, 0xFEFF, prControl}, // Cf ZERO WIDTH NO-BREAK SPACE + {0xFF9E, 0xFF9F, prExtend}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFF0, 0xFFF8, prControl}, // Cn [9] .. + {0xFFF9, 0xFFFB, prControl}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0x101FD, 0x101FD, prExtend}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x102E0, 0x102E0, prExtend}, // Mn COPTIC EPACT THOUSANDS MARK + {0x10376, 0x1037A, prExtend}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10A01, 0x10A03, prExtend}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prExtend}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prExtend}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A38, 0x10A3A, prExtend}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prExtend}, // Mn KHAROSHTHI VIRAMA + {0x10AE5, 0x10AE6, prExtend}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10D24, 0x10D27, prExtend}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10F46, 0x10F50, prExtend}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x11000, 0x11000, prSpacingMark}, // Mc BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prExtend}, // Mn BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prSpacingMark}, // Mc BRAHMI SIGN VISARGA + {0x11038, 0x11046, prExtend}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x1107F, 0x11081, prExtend}, // Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prSpacingMark}, // Mc KAITHI SIGN VISARGA + {0x110B0, 0x110B2, prSpacingMark}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prExtend}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prSpacingMark}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prExtend}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BD, 0x110BD, prPreprend}, // Cf KAITHI NUMBER SIGN + {0x110CD, 0x110CD, prPreprend}, // Cf KAITHI NUMBER SIGN ABOVE + {0x11100, 0x11102, prExtend}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11127, 0x1112B, prExtend}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prSpacingMark}, // Mc CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prExtend}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11145, 0x11146, prSpacingMark}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11173, 0x11173, prExtend}, // Mn MAHAJANI SIGN NUKTA + {0x11180, 0x11181, prExtend}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prSpacingMark}, // Mc SHARADA SIGN VISARGA + {0x111B3, 0x111B5, prSpacingMark}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prExtend}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prSpacingMark}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C2, 0x111C3, prPreprend}, // Lo [2] SHARADA SIGN JIHVAMULIYA..SHARADA SIGN UPADHMANIYA + {0x111C9, 0x111CC, prExtend}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x1122C, 0x1122E, prSpacingMark}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prExtend}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prSpacingMark}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prExtend}, // Mn KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prSpacingMark}, // Mc KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prExtend}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x1123E, 0x1123E, prExtend}, // Mn KHOJKI SIGN SUKUN + {0x112DF, 0x112DF, prExtend}, // Mn KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prSpacingMark}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prExtend}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x11300, 0x11301, prExtend}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prSpacingMark}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x1133B, 0x1133C, prExtend}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133E, 0x1133E, prExtend}, // Mc GRANTHA VOWEL SIGN AA + {0x1133F, 0x1133F, prSpacingMark}, // Mc GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prExtend}, // Mn GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prSpacingMark}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prSpacingMark}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prSpacingMark}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11357, 0x11357, prExtend}, // Mc GRANTHA AU LENGTH MARK + {0x11362, 0x11363, prSpacingMark}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prExtend}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prExtend}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11435, 0x11437, prSpacingMark}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prExtend}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prSpacingMark}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prExtend}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prSpacingMark}, // Mc NEWA SIGN VISARGA + {0x11446, 0x11446, prExtend}, // Mn NEWA SIGN NUKTA + {0x1145E, 0x1145E, prExtend}, // Mn NEWA SANDHI MARK + {0x114B0, 0x114B0, prExtend}, // Mc TIRHUTA VOWEL SIGN AA + {0x114B1, 0x114B2, prSpacingMark}, // Mc [2] TIRHUTA VOWEL SIGN I..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prExtend}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prSpacingMark}, // Mc TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prExtend}, // Mn TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BC, prSpacingMark}, // Mc [2] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN O + {0x114BD, 0x114BD, prExtend}, // Mc TIRHUTA VOWEL SIGN SHORT O + {0x114BE, 0x114BE, prSpacingMark}, // Mc TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prExtend}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prSpacingMark}, // Mc TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prExtend}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x115AF, 0x115AF, prExtend}, // Mc SIDDHAM VOWEL SIGN AA + {0x115B0, 0x115B1, prSpacingMark}, // Mc [2] SIDDHAM VOWEL SIGN I..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prExtend}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prSpacingMark}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prExtend}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prSpacingMark}, // Mc SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prExtend}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115DC, 0x115DD, prExtend}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11630, 0x11632, prSpacingMark}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prExtend}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prSpacingMark}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prExtend}, // Mn MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prSpacingMark}, // Mc MODI SIGN VISARGA + {0x1163F, 0x11640, prExtend}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x116AB, 0x116AB, prExtend}, // Mn TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prSpacingMark}, // Mc TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prExtend}, // Mn TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prSpacingMark}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prExtend}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prSpacingMark}, // Mc TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prExtend}, // Mn TAKRI SIGN NUKTA + {0x1171D, 0x1171F, prExtend}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11720, 0x11721, prSpacingMark}, // Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA + {0x11722, 0x11725, prExtend}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prSpacingMark}, // Mc AHOM VOWEL SIGN E + {0x11727, 0x1172B, prExtend}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x1182C, 0x1182E, prSpacingMark}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prExtend}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prSpacingMark}, // Mc DOGRA SIGN VISARGA + {0x11839, 0x1183A, prExtend}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x119D1, 0x119D3, prSpacingMark}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prExtend}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prExtend}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prSpacingMark}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prExtend}, // Mn NANDINAGARI SIGN VIRAMA + {0x119E4, 0x119E4, prSpacingMark}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A01, 0x11A0A, prExtend}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A33, 0x11A38, prExtend}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prSpacingMark}, // Mc ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prPreprend}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prExtend}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A47, 0x11A47, prExtend}, // Mn ZANABAZAR SQUARE SUBJOINER + {0x11A51, 0x11A56, prExtend}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prSpacingMark}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prExtend}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A84, 0x11A89, prPreprend}, // Lo [6] SOYOMBO SIGN JIHVAMULIYA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prExtend}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prSpacingMark}, // Mc SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prExtend}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11C2F, 0x11C2F, prSpacingMark}, // Mc BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prExtend}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prExtend}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prSpacingMark}, // Mc BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prExtend}, // Mn BHAIKSUKI SIGN VIRAMA + {0x11C92, 0x11CA7, prExtend}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prSpacingMark}, // Mc MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prExtend}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prSpacingMark}, // Mc MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prExtend}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prSpacingMark}, // Mc MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prExtend}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D31, 0x11D36, prExtend}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prExtend}, // Mn MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prExtend}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prExtend}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prPreprend}, // Lo MASARAM GONDI REPHA + {0x11D47, 0x11D47, prExtend}, // Mn MASARAM GONDI RA-KARA + {0x11D8A, 0x11D8E, prSpacingMark}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prExtend}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prSpacingMark}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prExtend}, // Mn GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prSpacingMark}, // Mc GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prExtend}, // Mn GUNJALA GONDI VIRAMA + {0x11EF3, 0x11EF4, prExtend}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prSpacingMark}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x13430, 0x13438, prControl}, // Cf [9] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END SEGMENT + {0x16AF0, 0x16AF4, prExtend}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16B30, 0x16B36, prExtend}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16F4F, 0x16F4F, prExtend}, // Mn MIAO SIGN CONSONANT MODIFIER BAR + {0x16F51, 0x16F87, prSpacingMark}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prExtend}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x1BC9D, 0x1BC9E, prExtend}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BCA0, 0x1BCA3, prControl}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1D165, 0x1D165, prExtend}, // Mc MUSICAL SYMBOL COMBINING STEM + {0x1D166, 0x1D166, prSpacingMark}, // Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prExtend}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16D, 0x1D16D, prSpacingMark}, // Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT + {0x1D16E, 0x1D172, prExtend}, // Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prControl}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prExtend}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D185, 0x1D18B, prExtend}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D1AA, 0x1D1AD, prExtend}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D242, 0x1D244, prExtend}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1DA00, 0x1DA36, prExtend}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA3B, 0x1DA6C, prExtend}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA75, 0x1DA75, prExtend}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA84, 0x1DA84, prExtend}, // Mn SIGNWRITING LOCATION HEAD NECK + {0x1DA9B, 0x1DA9F, prExtend}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prExtend}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1E000, 0x1E006, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prExtend}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prExtend}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prExtend}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E130, 0x1E136, prExtend}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E2EC, 0x1E2EF, prExtend}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E8D0, 0x1E8D6, prExtend}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E944, 0x1E94A, prExtend}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1F000, 0x1F02B, prExtendedPictographic}, // 5.1 [44] (🀀..🀫) MAHJONG TILE EAST WIND..MAHJONG TILE BACK + {0x1F02C, 0x1F02F, prExtendedPictographic}, // NA [4] (🀬..🀯) .. + {0x1F030, 0x1F093, prExtendedPictographic}, // 5.1[100] (🀰..🂓) DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06 + {0x1F094, 0x1F09F, prExtendedPictographic}, // NA [12] (🂔..🂟) .. + {0x1F0A0, 0x1F0AE, prExtendedPictographic}, // 6.0 [15] (🂠..🂮) PLAYING CARD BACK..PLAYING CARD KING OF SPADES + {0x1F0AF, 0x1F0B0, prExtendedPictographic}, // NA [2] (🂯..🂰) .. + {0x1F0B1, 0x1F0BE, prExtendedPictographic}, // 6.0 [14] (🂱..🂾) PLAYING CARD ACE OF HEARTS..PLAYING CARD KING OF HEARTS + {0x1F0BF, 0x1F0BF, prExtendedPictographic}, // 7.0 [1] (🂿) PLAYING CARD RED JOKER + {0x1F0C0, 0x1F0C0, prExtendedPictographic}, // NA [1] (🃀) + {0x1F0C1, 0x1F0CF, prExtendedPictographic}, // 6.0 [15] (🃁..🃏) PLAYING CARD ACE OF DIAMONDS..joker + {0x1F0D0, 0x1F0D0, prExtendedPictographic}, // NA [1] (🃐) + {0x1F0D1, 0x1F0DF, prExtendedPictographic}, // 6.0 [15] (🃑..🃟) PLAYING CARD ACE OF CLUBS..PLAYING CARD WHITE JOKER + {0x1F0E0, 0x1F0F5, prExtendedPictographic}, // 7.0 [22] (🃠..🃵) PLAYING CARD FOOL..PLAYING CARD TRUMP-21 + {0x1F0F6, 0x1F0FF, prExtendedPictographic}, // NA [10] (🃶..🃿) .. + {0x1F10D, 0x1F10F, prExtendedPictographic}, // NA [3] (🄍..🄏) .. + {0x1F12F, 0x1F12F, prExtendedPictographic}, // 11.0 [1] (🄯) COPYLEFT SYMBOL + {0x1F16C, 0x1F16C, prExtendedPictographic}, // 12.0 [1] (🅬) RAISED MR SIGN + {0x1F16D, 0x1F16F, prExtendedPictographic}, // NA [3] (🅭..🅯) .. + {0x1F170, 0x1F171, prExtendedPictographic}, // 6.0 [2] (🅰️..🅱️) A button (blood type)..B button (blood type) + {0x1F17E, 0x1F17E, prExtendedPictographic}, // 6.0 [1] (🅾️) O button (blood type) + {0x1F17F, 0x1F17F, prExtendedPictographic}, // 5.2 [1] (🅿️) P button + {0x1F18E, 0x1F18E, prExtendedPictographic}, // 6.0 [1] (🆎) AB button (blood type) + {0x1F191, 0x1F19A, prExtendedPictographic}, // 6.0 [10] (🆑..🆚) CL button..VS button + {0x1F1AD, 0x1F1E5, prExtendedPictographic}, // NA [57] (🆭..🇥) .. + {0x1F1E6, 0x1F1FF, prRegionalIndicator}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z + {0x1F201, 0x1F202, prExtendedPictographic}, // 6.0 [2] (🈁..🈂️) Japanese “here” button..Japanese “service charge” button + {0x1F203, 0x1F20F, prExtendedPictographic}, // NA [13] (🈃..🈏) .. + {0x1F21A, 0x1F21A, prExtendedPictographic}, // 5.2 [1] (🈚) Japanese “free of charge” button + {0x1F22F, 0x1F22F, prExtendedPictographic}, // 5.2 [1] (🈯) Japanese “reserved” button + {0x1F232, 0x1F23A, prExtendedPictographic}, // 6.0 [9] (🈲..🈺) Japanese “prohibited” button..Japanese “open for business” button + {0x1F23C, 0x1F23F, prExtendedPictographic}, // NA [4] (🈼..🈿) .. + {0x1F249, 0x1F24F, prExtendedPictographic}, // NA [7] (🉉..🉏) .. + {0x1F250, 0x1F251, prExtendedPictographic}, // 6.0 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button + {0x1F252, 0x1F25F, prExtendedPictographic}, // NA [14] (🉒..🉟) .. + {0x1F260, 0x1F265, prExtendedPictographic}, // 10.0 [6] (🉠..🉥) ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI + {0x1F266, 0x1F2FF, prExtendedPictographic}, // NA[154] (🉦..🋿) .. + {0x1F300, 0x1F320, prExtendedPictographic}, // 6.0 [33] (🌀..🌠) cyclone..shooting star + {0x1F321, 0x1F32C, prExtendedPictographic}, // 7.0 [12] (🌡️..🌬️) thermometer..wind face + {0x1F32D, 0x1F32F, prExtendedPictographic}, // 8.0 [3] (🌭..🌯) hot dog..burrito + {0x1F330, 0x1F335, prExtendedPictographic}, // 6.0 [6] (🌰..🌵) chestnut..cactus + {0x1F336, 0x1F336, prExtendedPictographic}, // 7.0 [1] (🌶️) hot pepper + {0x1F337, 0x1F37C, prExtendedPictographic}, // 6.0 [70] (🌷..🍼) tulip..baby bottle + {0x1F37D, 0x1F37D, prExtendedPictographic}, // 7.0 [1] (🍽️) fork and knife with plate + {0x1F37E, 0x1F37F, prExtendedPictographic}, // 8.0 [2] (🍾..🍿) bottle with popping cork..popcorn + {0x1F380, 0x1F393, prExtendedPictographic}, // 6.0 [20] (🎀..🎓) ribbon..graduation cap + {0x1F394, 0x1F39F, prExtendedPictographic}, // 7.0 [12] (🎔..🎟️) HEART WITH TIP ON THE LEFT..admission tickets + {0x1F3A0, 0x1F3C4, prExtendedPictographic}, // 6.0 [37] (🎠..🏄) carousel horse..person surfing + {0x1F3C5, 0x1F3C5, prExtendedPictographic}, // 7.0 [1] (🏅) sports medal + {0x1F3C6, 0x1F3CA, prExtendedPictographic}, // 6.0 [5] (🏆..🏊) trophy..person swimming + {0x1F3CB, 0x1F3CE, prExtendedPictographic}, // 7.0 [4] (🏋️..🏎️) person lifting weights..racing car + {0x1F3CF, 0x1F3D3, prExtendedPictographic}, // 8.0 [5] (🏏..🏓) cricket game..ping pong + {0x1F3D4, 0x1F3DF, prExtendedPictographic}, // 7.0 [12] (🏔️..🏟️) snow-capped mountain..stadium + {0x1F3E0, 0x1F3F0, prExtendedPictographic}, // 6.0 [17] (🏠..🏰) house..castle + {0x1F3F1, 0x1F3F7, prExtendedPictographic}, // 7.0 [7] (🏱..🏷️) WHITE PENNANT..label + {0x1F3F8, 0x1F3FA, prExtendedPictographic}, // 8.0 [3] (🏸..🏺) badminton..amphora + {0x1F3FB, 0x1F3FF, prExtend}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + {0x1F400, 0x1F43E, prExtendedPictographic}, // 6.0 [63] (🐀..🐾) rat..paw prints + {0x1F43F, 0x1F43F, prExtendedPictographic}, // 7.0 [1] (🐿️) chipmunk + {0x1F440, 0x1F440, prExtendedPictographic}, // 6.0 [1] (👀) eyes + {0x1F441, 0x1F441, prExtendedPictographic}, // 7.0 [1] (👁️) eye + {0x1F442, 0x1F4F7, prExtendedPictographic}, // 6.0[182] (👂..📷) ear..camera + {0x1F4F8, 0x1F4F8, prExtendedPictographic}, // 7.0 [1] (📸) camera with flash + {0x1F4F9, 0x1F4FC, prExtendedPictographic}, // 6.0 [4] (📹..📼) video camera..videocassette + {0x1F4FD, 0x1F4FE, prExtendedPictographic}, // 7.0 [2] (📽️..📾) film projector..PORTABLE STEREO + {0x1F4FF, 0x1F4FF, prExtendedPictographic}, // 8.0 [1] (📿) prayer beads + {0x1F500, 0x1F53D, prExtendedPictographic}, // 6.0 [62] (🔀..🔽) shuffle tracks button..downwards button + {0x1F546, 0x1F54A, prExtendedPictographic}, // 7.0 [5] (🕆..🕊️) WHITE LATIN CROSS..dove + {0x1F54B, 0x1F54F, prExtendedPictographic}, // 8.0 [5] (🕋..🕏) kaaba..BOWL OF HYGIEIA + {0x1F550, 0x1F567, prExtendedPictographic}, // 6.0 [24] (🕐..🕧) one o’clock..twelve-thirty + {0x1F568, 0x1F579, prExtendedPictographic}, // 7.0 [18] (🕨..🕹️) RIGHT SPEAKER..joystick + {0x1F57A, 0x1F57A, prExtendedPictographic}, // 9.0 [1] (🕺) man dancing + {0x1F57B, 0x1F5A3, prExtendedPictographic}, // 7.0 [41] (🕻..🖣) LEFT HAND TELEPHONE RECEIVER..BLACK DOWN POINTING BACKHAND INDEX + {0x1F5A4, 0x1F5A4, prExtendedPictographic}, // 9.0 [1] (🖤) black heart + {0x1F5A5, 0x1F5FA, prExtendedPictographic}, // 7.0 [86] (🖥️..🗺️) desktop computer..world map + {0x1F5FB, 0x1F5FF, prExtendedPictographic}, // 6.0 [5] (🗻..🗿) mount fuji..moai + {0x1F600, 0x1F600, prExtendedPictographic}, // 6.1 [1] (😀) grinning face + {0x1F601, 0x1F610, prExtendedPictographic}, // 6.0 [16] (😁..😐) beaming face with smiling eyes..neutral face + {0x1F611, 0x1F611, prExtendedPictographic}, // 6.1 [1] (😑) expressionless face + {0x1F612, 0x1F614, prExtendedPictographic}, // 6.0 [3] (😒..😔) unamused face..pensive face + {0x1F615, 0x1F615, prExtendedPictographic}, // 6.1 [1] (😕) confused face + {0x1F616, 0x1F616, prExtendedPictographic}, // 6.0 [1] (😖) confounded face + {0x1F617, 0x1F617, prExtendedPictographic}, // 6.1 [1] (😗) kissing face + {0x1F618, 0x1F618, prExtendedPictographic}, // 6.0 [1] (😘) face blowing a kiss + {0x1F619, 0x1F619, prExtendedPictographic}, // 6.1 [1] (😙) kissing face with smiling eyes + {0x1F61A, 0x1F61A, prExtendedPictographic}, // 6.0 [1] (😚) kissing face with closed eyes + {0x1F61B, 0x1F61B, prExtendedPictographic}, // 6.1 [1] (😛) face with tongue + {0x1F61C, 0x1F61E, prExtendedPictographic}, // 6.0 [3] (😜..😞) winking face with tongue..disappointed face + {0x1F61F, 0x1F61F, prExtendedPictographic}, // 6.1 [1] (😟) worried face + {0x1F620, 0x1F625, prExtendedPictographic}, // 6.0 [6] (😠..😥) angry face..sad but relieved face + {0x1F626, 0x1F627, prExtendedPictographic}, // 6.1 [2] (😦..😧) frowning face with open mouth..anguished face + {0x1F628, 0x1F62B, prExtendedPictographic}, // 6.0 [4] (😨..😫) fearful face..tired face + {0x1F62C, 0x1F62C, prExtendedPictographic}, // 6.1 [1] (😬) grimacing face + {0x1F62D, 0x1F62D, prExtendedPictographic}, // 6.0 [1] (😭) loudly crying face + {0x1F62E, 0x1F62F, prExtendedPictographic}, // 6.1 [2] (😮..😯) face with open mouth..hushed face + {0x1F630, 0x1F633, prExtendedPictographic}, // 6.0 [4] (😰..😳) anxious face with sweat..flushed face + {0x1F634, 0x1F634, prExtendedPictographic}, // 6.1 [1] (😴) sleeping face + {0x1F635, 0x1F640, prExtendedPictographic}, // 6.0 [12] (😵..🙀) dizzy face..weary cat + {0x1F641, 0x1F642, prExtendedPictographic}, // 7.0 [2] (🙁..🙂) slightly frowning face..slightly smiling face + {0x1F643, 0x1F644, prExtendedPictographic}, // 8.0 [2] (🙃..🙄) upside-down face..face with rolling eyes + {0x1F645, 0x1F64F, prExtendedPictographic}, // 6.0 [11] (🙅..🙏) person gesturing NO..folded hands + {0x1F680, 0x1F6C5, prExtendedPictographic}, // 6.0 [70] (🚀..🛅) rocket..left luggage + {0x1F6C6, 0x1F6CF, prExtendedPictographic}, // 7.0 [10] (🛆..🛏️) TRIANGLE WITH ROUNDED CORNERS..bed + {0x1F6D0, 0x1F6D0, prExtendedPictographic}, // 8.0 [1] (🛐) place of worship + {0x1F6D1, 0x1F6D2, prExtendedPictographic}, // 9.0 [2] (🛑..🛒) stop sign..shopping cart + {0x1F6D3, 0x1F6D4, prExtendedPictographic}, // 10.0 [2] (🛓..🛔) STUPA..PAGODA + {0x1F6D5, 0x1F6D5, prExtendedPictographic}, // 12.0 [1] (🛕) hindu temple + {0x1F6D6, 0x1F6DF, prExtendedPictographic}, // NA [10] (🛖..🛟) .. + {0x1F6E0, 0x1F6EC, prExtendedPictographic}, // 7.0 [13] (🛠️..🛬) hammer and wrench..airplane arrival + {0x1F6ED, 0x1F6EF, prExtendedPictographic}, // NA [3] (🛭..🛯) .. + {0x1F6F0, 0x1F6F3, prExtendedPictographic}, // 7.0 [4] (🛰️..🛳️) satellite..passenger ship + {0x1F6F4, 0x1F6F6, prExtendedPictographic}, // 9.0 [3] (🛴..🛶) kick scooter..canoe + {0x1F6F7, 0x1F6F8, prExtendedPictographic}, // 10.0 [2] (🛷..🛸) sled..flying saucer + {0x1F6F9, 0x1F6F9, prExtendedPictographic}, // 11.0 [1] (🛹) skateboard + {0x1F6FA, 0x1F6FA, prExtendedPictographic}, // 12.0 [1] (🛺) auto rickshaw + {0x1F6FB, 0x1F6FF, prExtendedPictographic}, // NA [5] (🛻..🛿) .. + {0x1F774, 0x1F77F, prExtendedPictographic}, // NA [12] (🝴..🝿) .. + {0x1F7D5, 0x1F7D8, prExtendedPictographic}, // 11.0 [4] (🟕..🟘) CIRCLED TRIANGLE..NEGATIVE CIRCLED SQUARE + {0x1F7D9, 0x1F7DF, prExtendedPictographic}, // NA [7] (🟙..🟟) .. + {0x1F7E0, 0x1F7EB, prExtendedPictographic}, // 12.0 [12] (🟠..🟫) orange circle..brown square + {0x1F7EC, 0x1F7FF, prExtendedPictographic}, // NA [20] (🟬..🟿) .. + {0x1F80C, 0x1F80F, prExtendedPictographic}, // NA [4] (🠌..🠏) .. + {0x1F848, 0x1F84F, prExtendedPictographic}, // NA [8] (🡈..🡏) .. + {0x1F85A, 0x1F85F, prExtendedPictographic}, // NA [6] (🡚..🡟) .. + {0x1F888, 0x1F88F, prExtendedPictographic}, // NA [8] (🢈..🢏) .. + {0x1F8AE, 0x1F8FF, prExtendedPictographic}, // NA [82] (🢮..🣿) .. + {0x1F90C, 0x1F90C, prExtendedPictographic}, // NA [1] (🤌) + {0x1F90D, 0x1F90F, prExtendedPictographic}, // 12.0 [3] (🤍..🤏) white heart..pinching hand + {0x1F910, 0x1F918, prExtendedPictographic}, // 8.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns + {0x1F919, 0x1F91E, prExtendedPictographic}, // 9.0 [6] (🤙..🤞) call me hand..crossed fingers + {0x1F91F, 0x1F91F, prExtendedPictographic}, // 10.0 [1] (🤟) love-you gesture + {0x1F920, 0x1F927, prExtendedPictographic}, // 9.0 [8] (🤠..🤧) cowboy hat face..sneezing face + {0x1F928, 0x1F92F, prExtendedPictographic}, // 10.0 [8] (🤨..🤯) face with raised eyebrow..exploding head + {0x1F930, 0x1F930, prExtendedPictographic}, // 9.0 [1] (🤰) pregnant woman + {0x1F931, 0x1F932, prExtendedPictographic}, // 10.0 [2] (🤱..🤲) breast-feeding..palms up together + {0x1F933, 0x1F93A, prExtendedPictographic}, // 9.0 [8] (🤳..🤺) selfie..person fencing + {0x1F93C, 0x1F93E, prExtendedPictographic}, // 9.0 [3] (🤼..🤾) people wrestling..person playing handball + {0x1F93F, 0x1F93F, prExtendedPictographic}, // 12.0 [1] (🤿) diving mask + {0x1F940, 0x1F945, prExtendedPictographic}, // 9.0 [6] (🥀..🥅) wilted flower..goal net + {0x1F947, 0x1F94B, prExtendedPictographic}, // 9.0 [5] (🥇..🥋) 1st place medal..martial arts uniform + {0x1F94C, 0x1F94C, prExtendedPictographic}, // 10.0 [1] (🥌) curling stone + {0x1F94D, 0x1F94F, prExtendedPictographic}, // 11.0 [3] (🥍..🥏) lacrosse..flying disc + {0x1F950, 0x1F95E, prExtendedPictographic}, // 9.0 [15] (🥐..🥞) croissant..pancakes + {0x1F95F, 0x1F96B, prExtendedPictographic}, // 10.0 [13] (🥟..🥫) dumpling..canned food + {0x1F96C, 0x1F970, prExtendedPictographic}, // 11.0 [5] (🥬..🥰) leafy green..smiling face with hearts + {0x1F971, 0x1F971, prExtendedPictographic}, // 12.0 [1] (🥱) yawning face + {0x1F972, 0x1F972, prExtendedPictographic}, // NA [1] (🥲) + {0x1F973, 0x1F976, prExtendedPictographic}, // 11.0 [4] (🥳..🥶) partying face..cold face + {0x1F977, 0x1F979, prExtendedPictographic}, // NA [3] (🥷..🥹) .. + {0x1F97A, 0x1F97A, prExtendedPictographic}, // 11.0 [1] (🥺) pleading face + {0x1F97B, 0x1F97B, prExtendedPictographic}, // 12.0 [1] (🥻) sari + {0x1F97C, 0x1F97F, prExtendedPictographic}, // 11.0 [4] (🥼..🥿) lab coat..flat shoe + {0x1F980, 0x1F984, prExtendedPictographic}, // 8.0 [5] (🦀..🦄) crab..unicorn + {0x1F985, 0x1F991, prExtendedPictographic}, // 9.0 [13] (🦅..🦑) eagle..squid + {0x1F992, 0x1F997, prExtendedPictographic}, // 10.0 [6] (🦒..🦗) giraffe..cricket + {0x1F998, 0x1F9A2, prExtendedPictographic}, // 11.0 [11] (🦘..🦢) kangaroo..swan + {0x1F9A3, 0x1F9A4, prExtendedPictographic}, // NA [2] (🦣..🦤) .. + {0x1F9A5, 0x1F9AA, prExtendedPictographic}, // 12.0 [6] (🦥..🦪) sloth..oyster + {0x1F9AB, 0x1F9AD, prExtendedPictographic}, // NA [3] (🦫..🦭) .. + {0x1F9AE, 0x1F9AF, prExtendedPictographic}, // 12.0 [2] (🦮..🦯) guide dog..probing cane + {0x1F9B0, 0x1F9B9, prExtendedPictographic}, // 11.0 [10] (🦰..🦹) red hair..supervillain + {0x1F9BA, 0x1F9BF, prExtendedPictographic}, // 12.0 [6] (🦺..🦿) safety vest..mechanical leg + {0x1F9C0, 0x1F9C0, prExtendedPictographic}, // 8.0 [1] (🧀) cheese wedge + {0x1F9C1, 0x1F9C2, prExtendedPictographic}, // 11.0 [2] (🧁..🧂) cupcake..salt + {0x1F9C3, 0x1F9CA, prExtendedPictographic}, // 12.0 [8] (🧃..🧊) beverage box..ice cube + {0x1F9CB, 0x1F9CC, prExtendedPictographic}, // NA [2] (🧋..🧌) .. + {0x1F9CD, 0x1F9CF, prExtendedPictographic}, // 12.0 [3] (🧍..🧏) person standing..deaf person + {0x1F9D0, 0x1F9E6, prExtendedPictographic}, // 10.0 [23] (🧐..🧦) face with monocle..socks + {0x1F9E7, 0x1F9FF, prExtendedPictographic}, // 11.0 [25] (🧧..🧿) red envelope..nazar amulet + {0x1FA00, 0x1FA53, prExtendedPictographic}, // 12.0 [84] (🨀..🩓) NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP + {0x1FA54, 0x1FA5F, prExtendedPictographic}, // NA [12] (🩔..🩟) .. + {0x1FA60, 0x1FA6D, prExtendedPictographic}, // 11.0 [14] (🩠..🩭) XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER + {0x1FA6E, 0x1FA6F, prExtendedPictographic}, // NA [2] (🩮..🩯) .. + {0x1FA70, 0x1FA73, prExtendedPictographic}, // 12.0 [4] (🩰..🩳) ballet shoes..shorts + {0x1FA74, 0x1FA77, prExtendedPictographic}, // NA [4] (🩴..🩷) .. + {0x1FA78, 0x1FA7A, prExtendedPictographic}, // 12.0 [3] (🩸..🩺) drop of blood..stethoscope + {0x1FA7B, 0x1FA7F, prExtendedPictographic}, // NA [5] (🩻..🩿) .. + {0x1FA80, 0x1FA82, prExtendedPictographic}, // 12.0 [3] (🪀..🪂) yo-yo..parachute + {0x1FA83, 0x1FA8F, prExtendedPictographic}, // NA [13] (🪃..🪏) .. + {0x1FA90, 0x1FA95, prExtendedPictographic}, // 12.0 [6] (🪐..🪕) ringed planet..banjo + {0x1FA96, 0x1FFFD, prExtendedPictographic}, // NA[1384] (🪖..🿽) .. + {0xE0000, 0xE0000, prControl}, // Cn + {0xE0001, 0xE0001, prControl}, // Cf LANGUAGE TAG + {0xE0002, 0xE001F, prControl}, // Cn [30] .. + {0xE0020, 0xE007F, prExtend}, // Cf [96] TAG SPACE..CANCEL TAG + {0xE0080, 0xE00FF, prControl}, // Cn [128] .. + {0xE0100, 0xE01EF, prExtend}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + {0xE01F0, 0xE0FFF, prControl}, // Cn [3600] .. +} + +// property returns the Unicode property value (see constants above) of the +// given code point. +func property(r rune) int { + // Run a binary search. + from := 0 + to := len(codePoints) + for to > from { + middle := (from + to) / 2 + cpRange := codePoints[middle] + if int(r) < cpRange[0] { + to = middle + continue + } + if int(r) > cpRange[1] { + from = middle + 1 + continue + } + return cpRange[2] + } + return prAny +} diff --git a/vendor/github.com/spf13/afero/.travis.yml b/vendor/github.com/spf13/afero/.travis.yml index fdaa99980c11c..1459644981a07 100644 --- a/vendor/github.com/spf13/afero/.travis.yml +++ b/vendor/github.com/spf13/afero/.travis.yml @@ -19,4 +19,4 @@ script: - go build -v ./... - go test -count=1 -cover -race -v ./... - go vet ./... - - FILES=$(gofmt -s -l . zipfs sftpfs mem); if [[ -n "${FILES}" ]]; then echo "You have go format errors; gofmt your changes"; exit 1; fi + - FILES=$(gofmt -s -l . zipfs sftpfs mem tarfs); if [[ -n "${FILES}" ]]; then echo "You have go format errors; gofmt your changes"; exit 1; fi diff --git a/vendor/github.com/spf13/afero/README.md b/vendor/github.com/spf13/afero/README.md index 16b06f2ba0c0c..c3e807aef8d13 100644 --- a/vendor/github.com/spf13/afero/README.md +++ b/vendor/github.com/spf13/afero/README.md @@ -227,7 +227,7 @@ operation and a mock filesystem during testing or as needed. ```go appfs := afero.NewOsFs() -appfs.MkdirAll("src/a", 0755)) +appfs.MkdirAll("src/a", 0755) ``` ## Memory Backed Storage @@ -241,7 +241,7 @@ safely. ```go mm := afero.NewMemMapFs() -mm.MkdirAll("src/a", 0755)) +mm.MkdirAll("src/a", 0755) ``` #### InMemoryFile @@ -306,7 +306,7 @@ Any Afero FileSystem can be used as an httpFs. ```go httpFs := afero.NewHttpFs() -fileserver := http.FileServer(httpFs.Dir())) +fileserver := http.FileServer(httpFs.Dir()) http.Handle("/", fileserver) ``` @@ -380,7 +380,6 @@ The following is a short list of possible backends we hope someone will implement: * SSH -* TAR * S3 # About the project diff --git a/vendor/github.com/spf13/afero/go.mod b/vendor/github.com/spf13/afero/go.mod index 4b2384b38da1f..abe4fe1cfdcfb 100644 --- a/vendor/github.com/spf13/afero/go.mod +++ b/vendor/github.com/spf13/afero/go.mod @@ -3,7 +3,7 @@ module github.com/spf13/afero require ( github.com/pkg/sftp v1.10.1 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 - golang.org/x/text v0.3.0 + golang.org/x/text v0.3.3 ) go 1.13 diff --git a/vendor/github.com/spf13/afero/go.sum b/vendor/github.com/spf13/afero/go.sum index 4b7664829a246..89d9bfbc41fdb 100644 --- a/vendor/github.com/spf13/afero/go.sum +++ b/vendor/github.com/spf13/afero/go.sum @@ -1,3 +1,4 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -5,16 +6,24 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/spf13/afero/mem/file.go b/vendor/github.com/spf13/afero/mem/file.go index 699f1fb0241fa..07b2e12ae55f7 100644 --- a/vendor/github.com/spf13/afero/mem/file.go +++ b/vendor/github.com/spf13/afero/mem/file.go @@ -225,11 +225,11 @@ func (f *File) Seek(offset int64, whence int) (int64, error) { return 0, ErrFileClosed } switch whence { - case 0: + case io.SeekStart: atomic.StoreInt64(&f.at, offset) - case 1: - atomic.AddInt64(&f.at, int64(offset)) - case 2: + case io.SeekCurrent: + atomic.AddInt64(&f.at, offset) + case io.SeekEnd: atomic.StoreInt64(&f.at, int64(len(f.fileData.data))+offset) } return f.at, nil @@ -260,7 +260,7 @@ func (f *File) Write(b []byte) (n int, err error) { } setModTime(f.fileData, time.Now()) - atomic.StoreInt64(&f.at, int64(len(f.fileData.data))) + atomic.AddInt64(&f.at, int64(n)) return } diff --git a/vendor/github.com/spf13/afero/memmap.go b/vendor/github.com/spf13/afero/memmap.go index 6be0e9c2d88ab..0fa959249957b 100644 --- a/vendor/github.com/spf13/afero/memmap.go +++ b/vendor/github.com/spf13/afero/memmap.go @@ -25,6 +25,8 @@ import ( "github.com/spf13/afero/mem" ) +const chmodBits = os.ModePerm | os.ModeSetuid | os.ModeSetgid | os.ModeSticky // Only a subset of bits are allowed to be changed. Documented under os.Chmod() + type MemMapFs struct { mu sync.RWMutex data map[string]*mem.FileData @@ -40,7 +42,9 @@ func (m *MemMapFs) getData() map[string]*mem.FileData { m.data = make(map[string]*mem.FileData) // Root should always exist, right? // TODO: what about windows? - m.data[FilePathSeparator] = mem.CreateDir(FilePathSeparator) + root := mem.CreateDir(FilePathSeparator) + mem.SetMode(root, os.ModeDir|0755) + m.data[FilePathSeparator] = root }) return m.data } @@ -52,7 +56,7 @@ func (m *MemMapFs) Create(name string) (File, error) { m.mu.Lock() file := mem.CreateFile(name) m.getData()[name] = file - m.registerWithParent(file) + m.registerWithParent(file, 0) m.mu.Unlock() return mem.NewFileHandle(file), nil } @@ -83,14 +87,14 @@ func (m *MemMapFs) findParent(f *mem.FileData) *mem.FileData { return pfile } -func (m *MemMapFs) registerWithParent(f *mem.FileData) { +func (m *MemMapFs) registerWithParent(f *mem.FileData, perm os.FileMode) { if f == nil { return } parent := m.findParent(f) if parent == nil { pdir := filepath.Dir(filepath.Clean(f.Name())) - err := m.lockfreeMkdir(pdir, 0777) + err := m.lockfreeMkdir(pdir, perm) if err != nil { //log.Println("Mkdir error:", err) return @@ -119,13 +123,15 @@ func (m *MemMapFs) lockfreeMkdir(name string, perm os.FileMode) error { } } else { item := mem.CreateDir(name) + mem.SetMode(item, os.ModeDir|perm) m.getData()[name] = item - m.registerWithParent(item) + m.registerWithParent(item, perm) } return nil } func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error { + perm &= chmodBits name = normalizePath(name) m.mu.RLock() @@ -137,8 +143,9 @@ func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error { m.mu.Lock() item := mem.CreateDir(name) + mem.SetMode(item, os.ModeDir|perm) m.getData()[name] = item - m.registerWithParent(item) + m.registerWithParent(item, perm) m.mu.Unlock() return m.setFileMode(name, perm|os.ModeDir) @@ -208,6 +215,7 @@ func (m *MemMapFs) lockfreeOpen(name string) (*mem.FileData, error) { } func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) { + perm &= chmodBits chmod := false file, err := m.openWrite(name) if err == nil && (flag&os.O_EXCL > 0) { @@ -300,7 +308,7 @@ func (m *MemMapFs) Rename(oldname, newname string) error { delete(m.getData(), oldname) mem.ChangeFileName(fileData, newname) m.getData()[newname] = fileData - m.registerWithParent(fileData) + m.registerWithParent(fileData, 0) m.mu.Unlock() m.mu.RLock() } else { @@ -309,6 +317,11 @@ func (m *MemMapFs) Rename(oldname, newname string) error { return nil } +func (m *MemMapFs) LstatIfPossible(name string) (os.FileInfo, bool, error) { + fileInfo, err := m.Stat(name) + return fileInfo, false, err +} + func (m *MemMapFs) Stat(name string) (os.FileInfo, error) { f, err := m.Open(name) if err != nil { @@ -319,7 +332,6 @@ func (m *MemMapFs) Stat(name string) (os.FileInfo, error) { } func (m *MemMapFs) Chmod(name string, mode os.FileMode) error { - const chmodBits = os.ModePerm | os.ModeSetuid | os.ModeSetgid | os.ModeSticky // Only a subset of bits are allowed to be changed. Documented under os.Chmod() mode &= chmodBits m.mu.RLock() diff --git a/vendor/github.com/spf13/afero/unionFile.go b/vendor/github.com/spf13/afero/unionFile.go index eda96312df6bb..985363eea7ec0 100644 --- a/vendor/github.com/spf13/afero/unionFile.go +++ b/vendor/github.com/spf13/afero/unionFile.go @@ -186,25 +186,22 @@ func (f *UnionFile) Readdir(c int) (ofi []os.FileInfo, err error) { } f.files = append(f.files, merged...) } + files := f.files[f.off:] - if c <= 0 && len(f.files) == 0 { - return f.files, nil + if c <= 0 { + return files, nil } - if f.off >= len(f.files) { + if len(files) == 0 { return nil, io.EOF } - if c <= 0 { - return f.files[f.off:], nil - } - - if c > len(f.files) { - c = len(f.files) + if c > len(files) { + c = len(files) } defer func() { f.off += c }() - return f.files[f.off:c], nil + return files[:c], nil } func (f *UnionFile) Readdirnames(c int) ([]string, error) { diff --git a/vendor/github.com/xanzy/go-gitlab/.golangci.yml b/vendor/github.com/xanzy/go-gitlab/.golangci.yml new file mode 100644 index 0000000000000..2d4daeb22e476 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/.golangci.yml @@ -0,0 +1,59 @@ +# This file contains all available configuration options +# with their default values. + +# Options for analysis running +run: + concurrency: 4 + timeout: 10m + issues-exit-code: 1 + # Include test files or not, default is true + tests: true + +# Output configuration options +output: + format: line-number + +# All available settings of specific linters +linters-settings: + misspell: + locale: US + ignore-words: + - noteable + unused: + # Treat code as a program (not a library) and report unused exported identifiers + check-exported: false + +linters: + enable: + - asciicheck + - deadcode + - dogsled + - errorlint + - exportloopref + - goconst + - golint + - gosimple + - govet + - ineffassign + - megacheck + - misspell + - nakedret + - nolintlint + - staticcheck + - structcheck + - typecheck + - unconvert + - unused + - varcheck + - whitespace + disable: + - errcheck + disable-all: false + fast: false + +issues: + # Maximum issues count per one linter (set to 0 to disable) + max-issues-per-linter: 0 + + # Maximum count of issues with the same text (set to 0 to disable) + max-same-issues: 0 diff --git a/vendor/github.com/xanzy/go-gitlab/.travis.yml b/vendor/github.com/xanzy/go-gitlab/.travis.yml index 79772fc5090ba..5e422eb8df18b 100644 --- a/vendor/github.com/xanzy/go-gitlab/.travis.yml +++ b/vendor/github.com/xanzy/go-gitlab/.travis.yml @@ -1,27 +1,21 @@ language: go + arch: - - amd64 - - ppc64le + - amd64 + - ppc64le go: - 1.13.x - 1.14.x + - 1.x - master -stages: - - lint - - test +before_install: + - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/v1.35.0/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.35.0 -jobs: - include: - - stage: lint - script: - - go get golang.org/x/lint/golint - - golint -set_exit_status - - go vet -v - - stage: test - script: - - go test -v +script: + - golangci-lint run + - go test -v matrix: allow_failures: diff --git a/vendor/github.com/xanzy/go-gitlab/applications.go b/vendor/github.com/xanzy/go-gitlab/applications.go index 1436ed011c643..496f7a810d74c 100644 --- a/vendor/github.com/xanzy/go-gitlab/applications.go +++ b/vendor/github.com/xanzy/go-gitlab/applications.go @@ -26,6 +26,7 @@ type ApplicationsService struct { client *Client } +// Application represents a GitLab application type Application struct { ID int `json:"id"` ApplicationID string `json:"application_id"` @@ -64,6 +65,8 @@ func (s *ApplicationsService) CreateApplication(opt *CreateApplicationOptions, o return a, resp, err } +// ListApplicationsOptions represents the available +// ListApplications() options. type ListApplicationsOptions ListOptions // ListApplications get a list of administrables applications by the authenticated user diff --git a/vendor/github.com/xanzy/go-gitlab/commits.go b/vendor/github.com/xanzy/go-gitlab/commits.go index 36b355b7fb59d..1a89f0ed41ea9 100644 --- a/vendor/github.com/xanzy/go-gitlab/commits.go +++ b/vendor/github.com/xanzy/go-gitlab/commits.go @@ -389,17 +389,18 @@ type GetCommitStatusesOptions struct { // // GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit type CommitStatus struct { - ID int `json:"id"` - SHA string `json:"sha"` - Ref string `json:"ref"` - Status string `json:"status"` - Name string `json:"name"` - TargetURL string `json:"target_url"` - Description string `json:"description"` - CreatedAt *time.Time `json:"created_at"` - StartedAt *time.Time `json:"started_at"` - FinishedAt *time.Time `json:"finished_at"` - Author Author `json:"author"` + ID int `json:"id"` + SHA string `json:"sha"` + Ref string `json:"ref"` + Status string `json:"status"` + CreatedAt *time.Time `json:"created_at"` + StartedAt *time.Time `json:"started_at"` + FinishedAt *time.Time `json:"finished_at"` + Name string `json:"name"` + AllowFailure bool `json:"allow_failure"` + Author Author `json:"author"` + Description string `json:"description"` + TargetURL string `json:"target_url"` } // GetCommitStatuses gets the statuses of a commit in a project. diff --git a/vendor/github.com/xanzy/go-gitlab/deployments.go b/vendor/github.com/xanzy/go-gitlab/deployments.go index 2855f914608e8..c510266a33f9a 100644 --- a/vendor/github.com/xanzy/go-gitlab/deployments.go +++ b/vendor/github.com/xanzy/go-gitlab/deployments.go @@ -34,6 +34,7 @@ type Deployment struct { IID int `json:"iid"` Ref string `json:"ref"` SHA string `json:"sha"` + Status string `json:"status"` CreatedAt *time.Time `json:"created_at"` UpdatedAt *time.Time `json:"updated_at"` User *ProjectUser `json:"user"` @@ -53,10 +54,12 @@ type Deployment struct { User *User `json:"user"` Commit *Commit `json:"commit"` Pipeline struct { - ID int `json:"id"` - SHA string `json:"sha"` - Ref string `json:"ref"` - Status string `json:"status"` + ID int `json:"id"` + SHA string `json:"sha"` + Ref string `json:"ref"` + Status string `json:"status"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` } `json:"pipeline"` Runner *Runner `json:"runner"` } `json:"deployable"` diff --git a/vendor/github.com/xanzy/go-gitlab/event_parsing.go b/vendor/github.com/xanzy/go-gitlab/event_parsing.go index a09b356c11e2f..675d6816bd0d1 100644 --- a/vendor/github.com/xanzy/go-gitlab/event_parsing.go +++ b/vendor/github.com/xanzy/go-gitlab/event_parsing.go @@ -12,6 +12,7 @@ type EventType string // List of available event types. const ( EventTypeBuild EventType = "Build Hook" + EventTypeDeployment EventType = "Deployment Hook" EventTypeIssue EventType = "Issue Hook" EventConfidentialIssue EventType = "Confidential Issue Hook" EventTypeJob EventType = "Job Hook" @@ -140,7 +141,7 @@ func ParseSystemhook(payload []byte) (event interface{}, err error) { event = &UserTeamSystemEvent{} default: switch e.ObjectKind { - case "merge_request": + case string(MergeRequestEventTargetType): event = &MergeEvent{} default: return nil, fmt.Errorf("unexpected system hook type %s", e.EventName) @@ -183,6 +184,8 @@ func ParseWebhook(eventType EventType, payload []byte) (event interface{}, err e switch eventType { case EventTypeBuild: event = &BuildEvent{} + case EventTypeDeployment: + event = &DeploymentEvent{} case EventTypeIssue, EventConfidentialIssue: event = &IssueEvent{} case EventTypeJob: @@ -204,7 +207,7 @@ func ParseWebhook(eventType EventType, payload []byte) (event interface{}, err e return nil, err } - if note.ObjectKind != "note" { + if note.ObjectKind != string(NoteEventTargetType) { return nil, fmt.Errorf("unexpected object kind %s", note.ObjectKind) } diff --git a/vendor/github.com/xanzy/go-gitlab/event_webhook_types.go b/vendor/github.com/xanzy/go-gitlab/event_webhook_types.go index d41379a4f3540..3ac08ca5f6b3b 100644 --- a/vendor/github.com/xanzy/go-gitlab/event_webhook_types.go +++ b/vendor/github.com/xanzy/go-gitlab/event_webhook_types.go @@ -175,10 +175,18 @@ type IssueEvent struct { } `json:"assignees"` Labels []Label `json:"labels"` Changes struct { + Description struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"description"` Labels struct { Previous []Label `json:"previous"` Current []Label `json:"current"` } `json:"labels"` + Title struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"title"` UpdatedByID struct { Previous int `json:"previous"` Current int `json:"current"` @@ -192,23 +200,24 @@ type IssueEvent struct { // TODO: link to docs instead of src once they are published. // https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/data_builder/build.rb type JobEvent struct { - ObjectKind string `json:"object_kind"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - BeforeSHA string `json:"before_sha"` - SHA string `json:"sha"` - BuildID int `json:"build_id"` - BuildName string `json:"build_name"` - BuildStage string `json:"build_stage"` - BuildStatus string `json:"build_status"` - BuildStartedAt string `json:"build_started_at"` - BuildFinishedAt string `json:"build_finished_at"` - BuildDuration float64 `json:"build_duration"` - BuildAllowFailure bool `json:"build_allow_failure"` - PipelineID int `json:"pipeline_id"` - ProjectID int `json:"project_id"` - ProjectName string `json:"project_name"` - User struct { + ObjectKind string `json:"object_kind"` + Ref string `json:"ref"` + Tag bool `json:"tag"` + BeforeSHA string `json:"before_sha"` + SHA string `json:"sha"` + BuildID int `json:"build_id"` + BuildName string `json:"build_name"` + BuildStage string `json:"build_stage"` + BuildStatus string `json:"build_status"` + BuildStartedAt string `json:"build_started_at"` + BuildFinishedAt string `json:"build_finished_at"` + BuildDuration float64 `json:"build_duration"` + BuildAllowFailure bool `json:"build_allow_failure"` + BuildFailureReason string `json:"build_failure_reason"` + PipelineID int `json:"pipeline_id"` + ProjectID int `json:"project_id"` + ProjectName string `json:"project_name"` + User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` @@ -226,6 +235,12 @@ type JobEvent struct { FinishedAt string `json:"finished_at"` } `json:"commit"` Repository *Repository `json:"repository"` + Runner struct { + ID int `json:"id"` + Active bool `json:"active"` + Shared bool `json:"is_shared"` + Description string `json:"description"` + } `json:"runner"` } // CommitCommentEvent represents a comment on a commit event. @@ -314,21 +329,30 @@ type MergeCommentEvent struct { Visibility VisibilityValue `json:"visibility"` } `json:"project"` ObjectAttributes struct { - ID int `json:"id"` - DiscussionID string `json:"discussion_id"` - Note string `json:"note"` - NoteableType string `json:"noteable_type"` - AuthorID int `json:"author_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` - ProjectID int `json:"project_id"` - Attachment string `json:"attachment"` - LineCode string `json:"line_code"` - CommitID string `json:"commit_id"` - NoteableID int `json:"noteable_id"` - System bool `json:"system"` - StDiff *Diff `json:"st_diff"` - URL string `json:"url"` + Attachment string `json:"attachment"` + AuthorID int `json:"author_id"` + ChangePosition *NotePosition `json:"change_position"` + CommitID string `json:"commit_id"` + CreatedAt string `json:"created_at"` + DiscussionID string `json:"discussion_id"` + ID int `json:"id"` + LineCode string `json:"line_code"` + Note string `json:"note"` + NoteableID int `json:"noteable_id"` + NoteableType string `json:"noteable_type"` + OriginalPosition *NotePosition `json:"original_position"` + Position *NotePosition `json:"position"` + ProjectID int `json:"project_id"` + ResolvedAt string `json:"resolved_at"` + ResolvedByID string `json:"resolved_by_id"` + ResolvedByPush string `json:"resolved_by_push"` + StDiff *Diff `json:"st_diff"` + System bool `json:"system"` + Type string `json:"type"` + UpdatedAt string `json:"updated_at"` + UpdatedByID string `json:"updated_by_id"` + Description string `json:"description"` + URL string `json:"url"` } `json:"object_attributes"` Repository *Repository `json:"repository"` MergeRequest struct { @@ -614,6 +638,10 @@ type MergeEvent struct { Previous int `json:"previous"` Current int `json:"current"` } `json:"updated_by_id"` + MilestoneID struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"milestone_id"` } `json:"changes"` } @@ -716,6 +744,7 @@ type PipelineEvent struct { Tag bool `json:"tag"` SHA string `json:"sha"` BeforeSHA string `json:"before_sha"` + Source string `json:"source"` Status string `json:"status"` Stages []string `json:"stages"` CreatedAt string `json:"created_at"` @@ -832,3 +861,43 @@ type BuildEvent struct { } `json:"commit"` Repository *Repository `json:"repository"` } + +// DeploymentEvent represents a deployment event +// +// GitLab API docs: +// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#deployment-events +type DeploymentEvent struct { + ObjectKind string `json:"object_kind"` + Status string `json:"status"` + DeployableID int `json:"deployable_id"` + DeployableURL string `json:"deployable_url"` + Environment string `json:"environment"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL *string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + CIConfigPath string `json:"ci_config_path"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + } `json:"project"` + ShortSHA string `json:"short_sha"` + User struct { + Name string `json:"name"` + Username string `json:"username"` + AvatarURL string `json:"avatar_url"` + Email string `json:"email"` + } `json:"user"` + UserURL string `json:"user_url"` + CommitURL string `json:"commit_url"` + CommitTitle string `json:"commit_title"` +} diff --git a/vendor/github.com/xanzy/go-gitlab/events.go b/vendor/github.com/xanzy/go-gitlab/events.go index ed1160938586c..468d932fb3145 100644 --- a/vendor/github.com/xanzy/go-gitlab/events.go +++ b/vendor/github.com/xanzy/go-gitlab/events.go @@ -34,6 +34,7 @@ type EventsService struct { // GitLab API docs: // https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events type ContributionEvent struct { + ID int `json:"id"` Title string `json:"title"` ProjectID int `json:"project_id"` ActionName string `json:"action_name"` diff --git a/vendor/github.com/xanzy/go-gitlab/gitlab.go b/vendor/github.com/xanzy/go-gitlab/gitlab.go index f8e4ee22d6b96..5bab400503bb7 100644 --- a/vendor/github.com/xanzy/go-gitlab/gitlab.go +++ b/vendor/github.com/xanzy/go-gitlab/gitlab.go @@ -117,6 +117,7 @@ type Client struct { Epics *EpicsService Events *EventsService Features *FeaturesService + FreezePeriods *FreezePeriodsService GitIgnoreTemplates *GitIgnoreTemplatesService GroupBadges *GroupBadgesService GroupCluster *GroupClustersService @@ -280,6 +281,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) { c.Epics = &EpicsService{client: c} c.Events = &EventsService{client: c} c.Features = &FeaturesService{client: c} + c.FreezePeriods = &FreezePeriodsService{client: c} c.GitIgnoreTemplates = &GitIgnoreTemplatesService{client: c} c.GroupBadges = &GroupBadgesService{client: c} c.GroupCluster = &GroupClustersService{client: c} @@ -290,6 +292,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) { c.GroupVariables = &GroupVariablesService{client: c} c.Groups = &GroupsService{client: c} c.InstanceCluster = &InstanceClustersService{client: c} + c.InstanceVariables = &InstanceVariablesService{client: c} c.IssueLinks = &IssueLinksService{client: c} c.Issues = &IssuesService{client: c, timeStats: timeStats} c.IssuesStatistics = &IssuesStatisticsService{client: c} @@ -425,7 +428,7 @@ func (c *Client) configureLimiter() error { if v := resp.Header.Get(headerRateLimit); v != "" { if rateLimit, _ := strconv.ParseFloat(v, 64); rateLimit > 0 { // The rate limit is based on requests per minute, so for our limiter to - // work correctly we devide the limit by 60 to get the limit per second. + // work correctly we divide the limit by 60 to get the limit per second. rateLimit /= 60 // Configure the limit and burst using a split of 2/3 for the limit and // 1/3 for the burst. This enables clients to burst 1/3 of the allowed diff --git a/vendor/github.com/xanzy/go-gitlab/group_hooks.go b/vendor/github.com/xanzy/go-gitlab/group_hooks.go index 704232b90b199..fa2ac4f6e43e4 100644 --- a/vendor/github.com/xanzy/go-gitlab/group_hooks.go +++ b/vendor/github.com/xanzy/go-gitlab/group_hooks.go @@ -38,6 +38,7 @@ type GroupHook struct { JobEvents bool `json:"job_events"` PipelineEvents bool `json:"pipeline_events"` WikiPageEvents bool `json:"wiki_page_events"` + DeploymentEvents bool `json:"deployment_events"` EnableSSLVerification bool `json:"enable_ssl_verification"` CreatedAt *time.Time `json:"created_at"` } @@ -105,6 +106,7 @@ type AddGroupHookOptions struct { JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` } @@ -149,6 +151,7 @@ type EditGroupHookOptions struct { JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` } diff --git a/vendor/github.com/xanzy/go-gitlab/group_milestones.go b/vendor/github.com/xanzy/go-gitlab/group_milestones.go index b3249f7b2ba88..7c12552721a58 100644 --- a/vendor/github.com/xanzy/go-gitlab/group_milestones.go +++ b/vendor/github.com/xanzy/go-gitlab/group_milestones.go @@ -251,6 +251,10 @@ func (s *GroupMilestonesService) GetGroupMilestoneMergeRequests(gid interface{}, return mr, resp, err } +// BurndownChartEvent reprensents a burnout chart event +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/group_milestones.html#get-all-burndown-chart-events-for-a-single-milestone-starter type BurndownChartEvent struct { CreatedAt *time.Time `json:"created_at"` Weight *int `json:"weight"` diff --git a/vendor/github.com/xanzy/go-gitlab/groups.go b/vendor/github.com/xanzy/go-gitlab/groups.go index 2aae8653901e6..6a3f64f516d2a 100644 --- a/vendor/github.com/xanzy/go-gitlab/groups.go +++ b/vendor/github.com/xanzy/go-gitlab/groups.go @@ -75,6 +75,9 @@ type Group struct { CreatedAt *time.Time `json:"created_at"` } +// LDAPGroupLink represents a GitLab LDAP group link. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#ldap-group-links type LDAPGroupLink struct { CN string `json:"cn"` GroupAccess AccessLevelValue `json:"group_access"` @@ -263,6 +266,31 @@ func (s *GroupsService) DeleteGroup(gid interface{}, options ...RequestOptionFun return s.client.Do(req, nil) } +// RestoreGroup restores a previously deleted group +// +// GitLap API docs: +// https://docs.gitlab.com/ee/api/groups.html#restore-group-marked-for-deletion +func (s *GroupsService) RestoreGroup(gid interface{}, options ...RequestOptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/restore", pathEscape(group)) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + // SearchGroup get all groups that match your string in their name or path. // // GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#search-for-group @@ -338,7 +366,7 @@ func (s *GroupsService) ListGroupProjects(gid interface{}, opt *ListGroupProject // https://docs.gitlab.com/ce/api/groups.html#list-a-groups-s-subgroups type ListSubgroupsOptions ListGroupsOptions -// ListSubgroups gets a list of subgroups for a given project. +// ListSubgroups gets a list of subgroups for a given group. // // GitLab API docs: // https://docs.gitlab.com/ce/api/groups.html#list-a-groups-s-subgroups diff --git a/vendor/github.com/xanzy/go-gitlab/issue_links.go b/vendor/github.com/xanzy/go-gitlab/issue_links.go index 495793764ad59..ab8cfdf0c8dce 100644 --- a/vendor/github.com/xanzy/go-gitlab/issue_links.go +++ b/vendor/github.com/xanzy/go-gitlab/issue_links.go @@ -34,6 +34,7 @@ type IssueLinksService struct { type IssueLink struct { SourceIssue *Issue `json:"source_issue"` TargetIssue *Issue `json:"target_issue"` + LinkType string `json:"link_type"` } // ListIssueRelations gets a list of related issues of a given issue, @@ -70,6 +71,7 @@ func (s *IssueLinksService) ListIssueRelations(pid interface{}, issueIID int, op type CreateIssueLinkOptions struct { TargetProjectID *string `json:"target_project_id"` TargetIssueIID *string `json:"target_issue_iid"` + LinkType *string `json:"link_type"` } // CreateIssueLink creates a two-way relation between two issues. diff --git a/vendor/github.com/xanzy/go-gitlab/issues.go b/vendor/github.com/xanzy/go-gitlab/issues.go index ffd412eeb6847..a55bf08a00fcc 100644 --- a/vendor/github.com/xanzy/go-gitlab/issues.go +++ b/vendor/github.com/xanzy/go-gitlab/issues.go @@ -125,6 +125,7 @@ func (i Issue) String() string { return Stringify(i) } +// UnmarshalJSON implements the json.Unmarshaler interface. func (i *Issue) UnmarshalJSON(data []byte) error { type alias Issue diff --git a/vendor/github.com/xanzy/go-gitlab/jobs.go b/vendor/github.com/xanzy/go-gitlab/jobs.go index 0aaa5832a7e83..e6540cf1f3a15 100644 --- a/vendor/github.com/xanzy/go-gitlab/jobs.go +++ b/vendor/github.com/xanzy/go-gitlab/jobs.go @@ -19,7 +19,6 @@ package gitlab import ( "bytes" "fmt" - "io" "time" ) @@ -76,6 +75,29 @@ type Job struct { User *User `json:"user"` } +// Bridge represents a pipeline bridge. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/jobs.html#list-pipeline-bridges +type Bridge struct { + Commit *Commit `json:"commit"` + Coverage float64 `json:"coverage"` + AllowFailure bool `json:"allow_failure"` + CreatedAt *time.Time `json:"created_at"` + StartedAt *time.Time `json:"started_at"` + FinishedAt *time.Time `json:"finished_at"` + Duration float64 `json:"duration"` + ID int `json:"id"` + Name string `json:"name"` + Pipeline PipelineInfo `json:"pipeline"` + Ref string `json:"ref"` + Stage string `json:"stage"` + Status string `json:"status"` + Tag bool `json:"tag"` + WebURL string `json:"web_url"` + User *User `json:"user"` + DownstreamPipeline *PipelineInfo `json:"downstream_pipeline"` +} + // ListJobsOptions are options for two list apis type ListJobsOptions struct { ListOptions @@ -89,7 +111,7 @@ type ListJobsOptions struct { // // GitLab API docs: // https://docs.gitlab.com/ce/api/jobs.html#list-project-jobs -func (s *JobsService) ListProjectJobs(pid interface{}, opts *ListJobsOptions, options ...RequestOptionFunc) ([]Job, *Response, error) { +func (s *JobsService) ListProjectJobs(pid interface{}, opts *ListJobsOptions, options ...RequestOptionFunc) ([]*Job, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err @@ -101,7 +123,7 @@ func (s *JobsService) ListProjectJobs(pid interface{}, opts *ListJobsOptions, op return nil, nil, err } - var jobs []Job + var jobs []*Job resp, err := s.client.Do(req, &jobs) if err != nil { return nil, resp, err @@ -136,6 +158,32 @@ func (s *JobsService) ListPipelineJobs(pid interface{}, pipelineID int, opts *Li return jobs, resp, err } +// ListPipelineBridges gets a list of bridges for specific pipeline in a +// project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/jobs.html#list-pipeline-jobs +func (s *JobsService) ListPipelineBridges(pid interface{}, pipelineID int, opts *ListJobsOptions, options ...RequestOptionFunc) ([]*Bridge, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/bridges", pathEscape(project), pipelineID) + + req, err := s.client.NewRequest("GET", u, opts, options) + if err != nil { + return nil, nil, err + } + + var bridges []*Bridge + resp, err := s.client.Do(req, &bridges) + if err != nil { + return nil, resp, err + } + + return bridges, resp, err +} + // GetJob gets a single job of a project. // // GitLab API docs: @@ -165,7 +213,7 @@ func (s *JobsService) GetJob(pid interface{}, jobID int, options ...RequestOptio // // GitLab API docs: // https://docs.gitlab.com/ce/api/job_artifacts.html#get-job-artifacts -func (s *JobsService) GetJobArtifacts(pid interface{}, jobID int, options ...RequestOptionFunc) (io.Reader, *Response, error) { +func (s *JobsService) GetJobArtifacts(pid interface{}, jobID int, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err @@ -183,7 +231,7 @@ func (s *JobsService) GetJobArtifacts(pid interface{}, jobID int, options ...Req return nil, resp, err } - return artifactsBuf, resp, err + return bytes.NewReader(artifactsBuf.Bytes()), resp, err } // DownloadArtifactsFileOptions represents the available DownloadArtifactsFile() @@ -200,7 +248,7 @@ type DownloadArtifactsFileOptions struct { // // GitLab API docs: // https://docs.gitlab.com/ce/api/job_artifacts.html#download-the-artifacts-archive -func (s *JobsService) DownloadArtifactsFile(pid interface{}, refName string, opt *DownloadArtifactsFileOptions, options ...RequestOptionFunc) (io.Reader, *Response, error) { +func (s *JobsService) DownloadArtifactsFile(pid interface{}, refName string, opt *DownloadArtifactsFileOptions, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err @@ -218,7 +266,7 @@ func (s *JobsService) DownloadArtifactsFile(pid interface{}, refName string, opt return nil, resp, err } - return artifactsBuf, resp, err + return bytes.NewReader(artifactsBuf.Bytes()), resp, err } // DownloadSingleArtifactsFile download a file from the artifacts from the @@ -228,7 +276,7 @@ func (s *JobsService) DownloadArtifactsFile(pid interface{}, refName string, opt // // GitLab API docs: // https://docs.gitlab.com/ce/api/job_artifacts.html#download-a-single-artifact-file-by-job-id -func (s *JobsService) DownloadSingleArtifactsFile(pid interface{}, jobID int, artifactPath string, options ...RequestOptionFunc) (io.Reader, *Response, error) { +func (s *JobsService) DownloadSingleArtifactsFile(pid interface{}, jobID int, artifactPath string, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err @@ -252,14 +300,14 @@ func (s *JobsService) DownloadSingleArtifactsFile(pid interface{}, jobID int, ar return nil, resp, err } - return artifactBuf, resp, err + return bytes.NewReader(artifactBuf.Bytes()), resp, err } // GetTraceFile gets a trace of a specific job of a project // // GitLab API docs: // https://docs.gitlab.com/ce/api/jobs.html#get-a-trace-file -func (s *JobsService) GetTraceFile(pid interface{}, jobID int, options ...RequestOptionFunc) (io.Reader, *Response, error) { +func (s *JobsService) GetTraceFile(pid interface{}, jobID int, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err @@ -277,7 +325,7 @@ func (s *JobsService) GetTraceFile(pid interface{}, jobID int, options ...Reques return nil, resp, err } - return traceBuf, resp, err + return bytes.NewReader(traceBuf.Bytes()), resp, err } // CancelJob cancels a single job of a project. diff --git a/vendor/github.com/xanzy/go-gitlab/notes.go b/vendor/github.com/xanzy/go-gitlab/notes.go index b8d599e4cddf8..9eb4c59b6061c 100644 --- a/vendor/github.com/xanzy/go-gitlab/notes.go +++ b/vendor/github.com/xanzy/go-gitlab/notes.go @@ -70,18 +70,29 @@ type Note struct { // NotePosition represents the position attributes of a note. type NotePosition struct { - BaseSHA string `json:"base_sha"` - StartSHA string `json:"start_sha"` - HeadSHA string `json:"head_sha"` - PositionType string `json:"position_type"` - NewPath string `json:"new_path,omitempty"` - NewLine int `json:"new_line,omitempty"` - OldPath string `json:"old_path,omitempty"` - OldLine int `json:"old_line,omitempty"` - Width int `json:"width,omitempty"` - Height int `json:"height,omitempty"` - X int `json:"x,omitempty"` - Y int `json:"y,omitempty"` + BaseSHA string `json:"base_sha"` + StartSHA string `json:"start_sha"` + HeadSHA string `json:"head_sha"` + PositionType string `json:"position_type"` + NewPath string `json:"new_path,omitempty"` + NewLine int `json:"new_line,omitempty"` + OldPath string `json:"old_path,omitempty"` + OldLine int `json:"old_line,omitempty"` + LineRange *LineRange `json:"line_range"` +} + +// LineRange represents the range of a note. +type LineRange struct { + StartRange *LinePosition `json:"start"` + EndRange *LinePosition `json:"end"` +} + +// LinePosition represents a position in a line range. +type LinePosition struct { + LineCode string `json:"line_code"` + Type string `json:"type"` + OldLine int `json:"old_line"` + NewLine int `json:"new_line"` } func (n Note) String() string { diff --git a/vendor/github.com/xanzy/go-gitlab/pipelines.go b/vendor/github.com/xanzy/go-gitlab/pipelines.go index 5b893486fe456..4d2bd770eb3c6 100644 --- a/vendor/github.com/xanzy/go-gitlab/pipelines.go +++ b/vendor/github.com/xanzy/go-gitlab/pipelines.go @@ -105,10 +105,21 @@ type PipelineTestSuites struct { // PipelineTestCases contains test cases details. type PipelineTestCases struct { - Status string `json:"status"` - Name string `json:"name"` - Classname string `json:"classname"` - ExecutionTime float64 `json:"execution_time"` + Status string `json:"status"` + Name string `json:"name"` + Classname string `json:"classname"` + File string `json:"file"` + ExecutionTime float64 `json:"execution_time"` + SystemOutput string `json:"system_output"` + StackTrace string `json:"stack_trace"` + AttachmentURL string `json:"attachment_url"` + RecentFailures RecentFailures `json:"recent_failures"` +} + +// RecentFailures contains failures count for the project's default branch. +type RecentFailures struct { + Count int `json:"count"` + BaseBranch string `json:"base_branch"` } func (p PipelineTestReport) String() string { diff --git a/vendor/github.com/xanzy/go-gitlab/project_mirror.go b/vendor/github.com/xanzy/go-gitlab/project_mirror.go index aa7a1aa5d3723..e246a43c6fdd0 100644 --- a/vendor/github.com/xanzy/go-gitlab/project_mirror.go +++ b/vendor/github.com/xanzy/go-gitlab/project_mirror.go @@ -68,7 +68,6 @@ func (s *ProjectMirrorService) ListProjectMirror(pid interface{}, options ...Req } return pm, resp, err - } // AddProjectMirrorOptions contains the properties requires to create diff --git a/vendor/github.com/xanzy/go-gitlab/projects.go b/vendor/github.com/xanzy/go-gitlab/projects.go index 5d5ca8c386ab9..866380c2f4d39 100644 --- a/vendor/github.com/xanzy/go-gitlab/projects.go +++ b/vendor/github.com/xanzy/go-gitlab/projects.go @@ -77,6 +77,7 @@ type Project struct { StarCount int `json:"star_count"` RunnersToken string `json:"runners_token"` PublicBuilds bool `json:"public_builds"` + AllowMergeOnSkippedPipeline bool `json:"allow_merge_on_skipped_pipeline"` OnlyAllowMergeIfPipelineSucceeds bool `json:"only_allow_merge_if_pipeline_succeeds"` OnlyAllowMergeIfAllDiscussionsAreResolved bool `json:"only_allow_merge_if_all_discussions_are_resolved"` RemoveSourceBranchAfterMerge bool `json:"remove_source_branch_after_merge"` @@ -101,6 +102,7 @@ type Project struct { SnippetsAccessLevel AccessControlValue `json:"snippets_access_level"` PagesAccessLevel AccessControlValue `json:"pages_access_level"` AutocloseReferencedIssues bool `json:"autoclose_referenced_issues"` + CIForwardDeploymentEnabled bool `json:"ci_forward_deployment_enabled"` SharedWithGroups []struct { GroupID int `json:"group_id"` GroupName string `json:"group_name"` @@ -486,6 +488,7 @@ type CreateProjectOptions struct { Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"` PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"` + AllowMergeOnSkippedPipeline *bool `url:"allow_merge_on_skipped_pipeline,omitempty" json:"allow_merge_on_skipped_pipeline,omitempty"` OnlyAllowMergeIfPipelineSucceeds *bool `url:"only_allow_merge_if_pipeline_succeeds,omitempty" json:"only_allow_merge_if_pipeline_succeeds,omitempty"` OnlyAllowMergeIfAllDiscussionsAreResolved *bool `url:"only_allow_merge_if_all_discussions_are_resolved,omitempty" json:"only_allow_merge_if_all_discussions_are_resolved,omitempty"` MergeMethod *MergeMethodValue `url:"merge_method,omitempty" json:"merge_method,omitempty"` @@ -499,6 +502,7 @@ type CreateProjectOptions struct { AutoCancelPendingPipelines *string `url:"auto_cancel_pending_pipelines,omitempty" json:"auto_cancel_pending_pipelines,omitempty"` BuildCoverageRegex *string `url:"build_coverage_regex,omitempty" json:"build_coverage_regex,omitempty"` CIConfigPath *string `url:"ci_config_path,omitempty" json:"ci_config_path,omitempty"` + CIForwardDeploymentEnabled *bool `url:"ci_forward_deployment_enabled,omitempty" json:"ci_forward_deployment_enabled,omitempty"` AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` AutoDevopsDeployStrategy *string `url:"auto_devops_deploy_strategy,omitempty" json:"auto_devops_deploy_strategy,omitempty"` ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"` @@ -592,6 +596,7 @@ type EditProjectOptions struct { Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"` PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"` + AllowMergeOnSkippedPipeline *bool `url:"allow_merge_on_skipped_pipeline,omitempty" json:"allow_merge_on_skipped_pipeline,omitempty"` OnlyAllowMergeIfPipelineSucceeds *bool `url:"only_allow_merge_if_pipeline_succeeds,omitempty" json:"only_allow_merge_if_pipeline_succeeds,omitempty"` OnlyAllowMergeIfAllDiscussionsAreResolved *bool `url:"only_allow_merge_if_all_discussions_are_resolved,omitempty" json:"only_allow_merge_if_all_discussions_are_resolved,omitempty"` MergeMethod *MergeMethodValue `url:"merge_method,omitempty" json:"merge_method,omitempty"` @@ -604,6 +609,7 @@ type EditProjectOptions struct { AutoCancelPendingPipelines *string `url:"auto_cancel_pending_pipelines,omitempty" json:"auto_cancel_pending_pipelines,omitempty"` BuildCoverageRegex *string `url:"build_coverage_regex,omitempty" json:"build_coverage_regex,omitempty"` CIConfigPath *string `url:"ci_config_path,omitempty" json:"ci_config_path,omitempty"` + CIForwardDeploymentEnabled *bool `url:"ci_forward_deployment_enabled,omitempty" json:"ci_forward_deployment_enabled,omitempty"` CIDefaultGitDepth *int `url:"ci_default_git_depth,omitempty" json:"ci_default_git_depth,omitempty"` AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` AutoDevopsDeployStrategy *string `url:"auto_devops_deploy_strategy,omitempty" json:"auto_devops_deploy_strategy,omitempty"` @@ -886,6 +892,7 @@ type ProjectHook struct { JobEvents bool `json:"job_events"` PipelineEvents bool `json:"pipeline_events"` WikiPageEvents bool `json:"wiki_page_events"` + DeploymentEvents bool `json:"deployment_events"` EnableSSLVerification bool `json:"enable_ssl_verification"` CreatedAt *time.Time `json:"created_at"` } @@ -962,6 +969,7 @@ type AddProjectHookOptions struct { JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` } @@ -1008,6 +1016,7 @@ type EditProjectHookOptions struct { JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` } diff --git a/vendor/github.com/xanzy/go-gitlab/releases.go b/vendor/github.com/xanzy/go-gitlab/releases.go index 39df844c8084a..0891d39df9a83 100644 --- a/vendor/github.com/xanzy/go-gitlab/releases.go +++ b/vendor/github.com/xanzy/go-gitlab/releases.go @@ -124,7 +124,9 @@ type CreateReleaseOptions struct { TagName *string `url:"tag_name" json:"tag_name"` Description *string `url:"description" json:"description"` Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Milestones []string `url:"milestones,omitempty" json:"milestones,omitempty"` Assets *ReleaseAssets `url:"assets,omitempty" json:"assets,omitempty"` + ReleasedAt *time.Time `url:"released_at,omitempty" json:"released_at,omitempty"` } // CreateRelease creates a release. @@ -157,8 +159,10 @@ func (s *ReleasesService) CreateRelease(pid interface{}, opts *CreateReleaseOpti // GitLab API docs: // https://docs.gitlab.com/ce/api/releases/index.html#update-a-release type UpdateReleaseOptions struct { - Name *string `url:"name" json:"name"` - Description *string `url:"description" json:"description"` + Name *string `url:"name" json:"name"` + Description *string `url:"description" json:"description"` + Milestones []string `url:"milestones,omitempty" json:"milestones,omitempty"` + ReleasedAt *time.Time `url:"released_at,omitempty" json:"released_at,omitempty"` } // UpdateRelease updates a release. diff --git a/vendor/github.com/xanzy/go-gitlab/repository_files.go b/vendor/github.com/xanzy/go-gitlab/repository_files.go index cc954c27d77aa..fc0422c4f586e 100644 --- a/vendor/github.com/xanzy/go-gitlab/repository_files.go +++ b/vendor/github.com/xanzy/go-gitlab/repository_files.go @@ -260,6 +260,7 @@ func (r FileInfo) String() string { // https://docs.gitlab.com/ce/api/repository_files.html#create-new-file-in-repository type CreateFileOptions struct { Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"` Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` @@ -302,6 +303,7 @@ func (s *RepositoryFilesService) CreateFile(pid interface{}, fileName string, op // https://docs.gitlab.com/ce/api/repository_files.html#update-existing-file-in-repository type UpdateFileOptions struct { Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"` Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` diff --git a/vendor/github.com/xanzy/go-gitlab/runners.go b/vendor/github.com/xanzy/go-gitlab/runners.go index 96c23467bc28c..ee587d65a36e2 100644 --- a/vendor/github.com/xanzy/go-gitlab/runners.go +++ b/vendor/github.com/xanzy/go-gitlab/runners.go @@ -69,6 +69,7 @@ type RunnerDetails struct { Token string `json:"token"` Revision string `json:"revision"` TagList []string `json:"tag_list"` + RunUntagged bool `json:"run_untagged"` Version string `json:"version"` Locked bool `json:"locked"` AccessLevel string `json:"access_level"` @@ -380,14 +381,27 @@ func (s *RunnersService) ListGroupsRunners(gid interface{}, opt *ListGroupsRunne // GitLab API docs: // https://docs.gitlab.com/ce/api/runners.html#register-a-new-runner type RegisterNewRunnerOptions struct { - Token *string `url:"token" json:"token"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Info *string `url:"info,omitempty" json:"info,omitempty"` - Active *bool `url:"active,omitempty" json:"active,omitempty"` - Locked *bool `url:"locked,omitempty" json:"locked,omitempty"` - RunUntagged *bool `url:"run_untagged,omitempty" json:"run_untagged,omitempty"` - TagList []string `url:"tag_list[],omitempty" json:"tag_list,omitempty"` - MaximumTimeout *int `url:"maximum_timeout,omitempty" json:"maximum_timeout,omitempty"` + Token *string `url:"token" json:"token"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Info *RegisterNewRunnerInfoOptions `url:"info,omitempty" json:"info,omitempty"` + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Locked *bool `url:"locked,omitempty" json:"locked,omitempty"` + RunUntagged *bool `url:"run_untagged,omitempty" json:"run_untagged,omitempty"` + TagList []string `url:"tag_list[],omitempty" json:"tag_list,omitempty"` + MaximumTimeout *int `url:"maximum_timeout,omitempty" json:"maximum_timeout,omitempty"` +} + +// RegisterNewRunnerInfoOptions represents the info hashmap parameter in +// RegisterNewRunnerOptions. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/runners.html#register-a-new-runner +type RegisterNewRunnerInfoOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Version *string `url:"version,omitempty" json:"version,omitempty"` + Revision *string `url:"revision,omitempty" json:"revision,omitempty"` + Platform *string `url:"platform,omitempty" json:"platform,omitempty"` + Architecture *string `url:"architecture,omitempty" json:"architecture,omitempty"` } // RegisterNewRunner registers a new Runner for the instance. @@ -418,10 +432,10 @@ type DeleteRegisteredRunnerOptions struct { Token *string `url:"token" json:"token"` } -// DeleteRegisteredRunner registers a new Runner for the instance. +// DeleteRegisteredRunner deletes a Runner by Token. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#delete-a-registered-runner +// https://docs.gitlab.com/ce/api/runners.html#delete-a-runner-by-authentication-token func (s *RunnersService) DeleteRegisteredRunner(opt *DeleteRegisteredRunnerOptions, options ...RequestOptionFunc) (*Response, error) { req, err := s.client.NewRequest("DELETE", "runners", opt, options) if err != nil { @@ -431,6 +445,19 @@ func (s *RunnersService) DeleteRegisteredRunner(opt *DeleteRegisteredRunnerOptio return s.client.Do(req, nil) } +// DeleteRegisteredRunnerByID deletes a Runner by ID. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/runners.html#delete-a-runner-by-id +func (s *RunnersService) DeleteRegisteredRunnerByID(rid int, options ...RequestOptionFunc) (*Response, error) { + req, err := s.client.NewRequest("DELETE", fmt.Sprintf("runners/%d", rid), nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + // VerifyRegisteredRunnerOptions represents the available // VerifyRegisteredRunner() options. // diff --git a/vendor/github.com/xanzy/go-gitlab/services.go b/vendor/github.com/xanzy/go-gitlab/services.go index 0f36c4eb942ba..a7b5f754db9c3 100644 --- a/vendor/github.com/xanzy/go-gitlab/services.go +++ b/vendor/github.com/xanzy/go-gitlab/services.go @@ -52,6 +52,7 @@ type Service struct { PipelineEvents bool `json:"pipeline_events"` JobEvents bool `json:"job_events"` WikiPageEvents bool `json:"wiki_page_events"` + DeploymentEvents bool `json:"deployment_events"` } // ListServices gets a list of all active services. diff --git a/vendor/github.com/xanzy/go-gitlab/users.go b/vendor/github.com/xanzy/go-gitlab/users.go index 2dbed926c5438..3b8dc1b07a27d 100644 --- a/vendor/github.com/xanzy/go-gitlab/users.go +++ b/vendor/github.com/xanzy/go-gitlab/users.go @@ -54,40 +54,43 @@ type BasicUser struct { // // GitLab API docs: https://docs.gitlab.com/ee/api/users.html type User struct { - ID int `json:"id"` - Username string `json:"username"` - Email string `json:"email"` - Name string `json:"name"` - State string `json:"state"` - WebURL string `json:"web_url"` - CreatedAt *time.Time `json:"created_at"` - Bio string `json:"bio"` - Location string `json:"location"` - PublicEmail string `json:"public_email"` - Skype string `json:"skype"` - Linkedin string `json:"linkedin"` - Twitter string `json:"twitter"` - WebsiteURL string `json:"website_url"` - Organization string `json:"organization"` - ExternUID string `json:"extern_uid"` - Provider string `json:"provider"` - ThemeID int `json:"theme_id"` - LastActivityOn *ISOTime `json:"last_activity_on"` - ColorSchemeID int `json:"color_scheme_id"` - IsAdmin bool `json:"is_admin"` - AvatarURL string `json:"avatar_url"` - CanCreateGroup bool `json:"can_create_group"` - CanCreateProject bool `json:"can_create_project"` - ProjectsLimit int `json:"projects_limit"` - CurrentSignInAt *time.Time `json:"current_sign_in_at"` - LastSignInAt *time.Time `json:"last_sign_in_at"` - ConfirmedAt *time.Time `json:"confirmed_at"` - TwoFactorEnabled bool `json:"two_factor_enabled"` - Identities []*UserIdentity `json:"identities"` - External bool `json:"external"` - PrivateProfile bool `json:"private_profile"` - SharedRunnersMinutesLimit int `json:"shared_runners_minutes_limit"` - CustomAttributes []*CustomAttribute `json:"custom_attributes"` + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + WebURL string `json:"web_url"` + CreatedAt *time.Time `json:"created_at"` + Bio string `json:"bio"` + Location string `json:"location"` + PublicEmail string `json:"public_email"` + Skype string `json:"skype"` + Linkedin string `json:"linkedin"` + Twitter string `json:"twitter"` + WebsiteURL string `json:"website_url"` + Organization string `json:"organization"` + ExternUID string `json:"extern_uid"` + Provider string `json:"provider"` + ThemeID int `json:"theme_id"` + LastActivityOn *ISOTime `json:"last_activity_on"` + ColorSchemeID int `json:"color_scheme_id"` + IsAdmin bool `json:"is_admin"` + AvatarURL string `json:"avatar_url"` + CanCreateGroup bool `json:"can_create_group"` + CanCreateProject bool `json:"can_create_project"` + ProjectsLimit int `json:"projects_limit"` + CurrentSignInAt *time.Time `json:"current_sign_in_at"` + LastSignInAt *time.Time `json:"last_sign_in_at"` + ConfirmedAt *time.Time `json:"confirmed_at"` + TwoFactorEnabled bool `json:"two_factor_enabled"` + Note string `json:"note"` + Identities []*UserIdentity `json:"identities"` + External bool `json:"external"` + PrivateProfile bool `json:"private_profile"` + SharedRunnersMinutesLimit int `json:"shared_runners_minutes_limit"` + ExtraSharedRunnersMinutesLimit int `json:"extra_shared_runners_minutes_limit"` + UsingLicenseSeat bool `json:"using_license_seat"` + CustomAttributes []*CustomAttribute `json:"custom_attributes"` } // UserIdentity represents a user identity. @@ -101,8 +104,9 @@ type UserIdentity struct { // GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-users type ListUsersOptions struct { ListOptions - Active *bool `url:"active,omitempty" json:"active,omitempty"` - Blocked *bool `url:"blocked,omitempty" json:"blocked,omitempty"` + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Blocked *bool `url:"blocked,omitempty" json:"blocked,omitempty"` + ExcludeInternal *bool `url:"exclude_internal,omitempty" json:"exclude_internal,omitempty"` // The options below are only available for admins. Search *string `url:"search,omitempty" json:"search,omitempty"` @@ -362,8 +366,9 @@ func (s *UsersService) GetSSHKey(key int, options ...RequestOptionFunc) (*SSHKey // // GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#add-ssh-key type AddSSHKeyOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Key *string `url:"key,omitempty" json:"key,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + Key *string `url:"key,omitempty" json:"key,omitempty"` + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` } // AddSSHKey creates a new key owned by the currently authenticated user. @@ -937,10 +942,10 @@ func (s *UsersService) SetUserStatus(opt *UserStatusOptions, options ...RequestO // GitLab API docs: // https://docs.gitlab.com/ee/api/users.html#user-memberships-admin-only type UserMembership struct { - SourceID int `json:"source_id"` - SourceName string `json:"source_name"` - SourceType string `json:"source_type"` - AccessLevel string `json:"access_level"` + SourceID int `json:"source_id"` + SourceName string `json:"source_name"` + SourceType string `json:"source_type"` + AccessLevel AccessLevelValue `json:"access_level"` } // GetUserMembershipOptions represents the options available to query user memberships. diff --git a/vendor/github.com/xanzy/go-gitlab/validate.go b/vendor/github.com/xanzy/go-gitlab/validate.go index 099484ef1f21f..17ffb15e31da3 100644 --- a/vendor/github.com/xanzy/go-gitlab/validate.go +++ b/vendor/github.com/xanzy/go-gitlab/validate.go @@ -1,5 +1,7 @@ package gitlab +import "fmt" + // ValidateService handles communication with the validation related methods of // the GitLab API. // @@ -16,6 +18,17 @@ type LintResult struct { Errors []string `json:"errors"` } +// ProjectLintResult represents the linting results by project. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/lint.html#validate-a-projects-ci-configuration +type ProjectLintResult struct { + Valid bool `json:"valid"` + Errors []string `json:"errors"` + Warnings []string `json:"warnings"` + MergedYaml string `json:"merged_yaml"` +} + // Lint validates .gitlab-ci.yml content. // // GitLab API docs: https://docs.gitlab.com/ce/api/lint.html @@ -38,3 +51,70 @@ func (s *ValidateService) Lint(content string, options ...RequestOptionFunc) (*L return l, resp, nil } + +// ProjectNamespaceLintOptions represents the available ProjectNamespaceLint() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/lint.html#validate-a-ci-yaml-configuration-with-a-namespace +type ProjectNamespaceLintOptions struct { + Content *string `url:"content,omitempty" json:"content,omitempty"` + DryRun *bool `url:"dry_run,omitempty" json:"dry_run,omitempty"` +} + +// ProjectNamespaceLint validates .gitlab-ci.yml content by project. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/lint.html#validate-a-ci-yaml-configuration-with-a-namespace +func (s *ValidateService) ProjectNamespaceLint(pid interface{}, opt *ProjectNamespaceLintOptions, options ...RequestOptionFunc) (*ProjectLintResult, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/ci/lint", pathEscape(project)) + + req, err := s.client.NewRequest("POST", u, &opt, options) + if err != nil { + return nil, nil, err + } + + l := new(ProjectLintResult) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// ProjectLintOptions represents the available ProjectLint() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/lint.html#validate-a-projects-ci-configuration +type ProjectLintOptions struct { + DryRun *bool `url:"dry_run,omitempty" json:"dry_run,omitempty"` +} + +// ProjectLint validates .gitlab-ci.yml content by project. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/lint.html#validate-a-projects-ci-configuration +func (s *ValidateService) ProjectLint(pid interface{}, opt *ProjectLintOptions, options ...RequestOptionFunc) (*ProjectLintResult, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/ci/lint", pathEscape(project)) + + req, err := s.client.NewRequest("GET", u, &opt, options) + if err != nil { + return nil, nil, err + } + + l := new(ProjectLintResult) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} diff --git a/vendor/github.com/yuin/goldmark/README.md b/vendor/github.com/yuin/goldmark/README.md index 8cf7c5a0ebbab..7f6a93e8511f8 100644 --- a/vendor/github.com/yuin/goldmark/README.md +++ b/vendor/github.com/yuin/goldmark/README.md @@ -1,7 +1,7 @@ goldmark ========================================== -[![http://godoc.org/github.com/yuin/goldmark](https://godoc.org/github.com/yuin/goldmark?status.svg)](http://godoc.org/github.com/yuin/goldmark) +[![https://pkg.go.dev/github.com/yuin/goldmark](https://pkg.go.dev/badge/github.com/yuin/goldmark.svg)](https://pkg.go.dev/github.com/yuin/goldmark) [![https://github.com/yuin/goldmark/actions?query=workflow:test](https://github.com/yuin/goldmark/workflows/test/badge.svg?branch=master&event=push)](https://github.com/yuin/goldmark/actions?query=workflow:test) [![https://coveralls.io/github/yuin/goldmark](https://coveralls.io/repos/github/yuin/goldmark/badge.svg?branch=master)](https://coveralls.io/github/yuin/goldmark) [![https://goreportcard.com/report/github.com/yuin/goldmark](https://goreportcard.com/badge/github.com/yuin/goldmark)](https://goreportcard.com/report/github.com/yuin/goldmark) @@ -173,6 +173,7 @@ Parser and Renderer options - This extension enables Table, Strikethrough, Linkify and TaskList. - This extension does not filter tags defined in [6.11: Disallowed Raw HTML (extension)](https://github.github.com/gfm/#disallowed-raw-html-extension-). If you need to filter HTML tags, see [Security](#security). + - If you need to parse github emojis, you can use [goldmark-emoji](https://github.com/yuin/goldmark-emoji) extension. - `extension.DefinitionList` - [PHP Markdown Extra: Definition lists](https://michelf.ca/projects/php-markdown/extra/#def-list) - `extension.Footnote` @@ -286,6 +287,89 @@ markdown := goldmark.New( ) ``` +### Footnotes extension + +The Footnote extension implements [PHP Markdown Extra: Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes). + +This extension has some options: + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `extension.WithFootnoteIDPrefix` | `[]byte` | a prefix for the id attributes.| +| `extension.WithFootnoteIDPrefixFunction` | `func(gast.Node) []byte` | a function that determines the id attribute for given Node.| +| `extension.WithFootnoteLinkTitle` | `[]byte` | an optional title attribute for footnote links.| +| `extension.WithFootnoteBacklinkTitle` | `[]byte` | an optional title attribute for footnote backlinks. | +| `extension.WithFootnoteLinkClass` | `[]byte` | a class for footnote links. This defaults to `footnote-ref`. | +| `extension.WithFootnoteBacklinkClass` | `[]byte` | a class for footnote backlinks. This defaults to `footnote-backref`. | +| `extension.WithFootnoteBacklinkHTML` | `[]byte` | a class for footnote backlinks. This defaults to `↩︎`. | + +Some options can have special substitutions. Occurances of “^^” in the string will be replaced by the corresponding footnote number in the HTML output. Occurances of “%%” will be replaced by a number for the reference (footnotes can have multiple references). + +`extension.WithFootnoteIDPrefix` and `extension.WithFootnoteIDPrefixFunction` are useful if you have multiple Markdown documents displayed inside one HTML document to avoid footnote ids to clash each other. + +`extension.WithFootnoteIDPrefix` sets fixed id prefix, so you may write codes like the following: + +```go +for _, path := range files { + source := readAll(path) + prefix := getPrefix(path) + + markdown := goldmark.New( + goldmark.WithExtensions( + NewFootnote( + WithFootnoteIDPrefix([]byte(path)), + ), + ), + ) + var b bytes.Buffer + err := markdown.Convert(source, &b) + if err != nil { + t.Error(err.Error()) + } +} +``` + +`extension.WithFootnoteIDPrefixFunction` determines an id prefix by calling given function, so you may write codes like the following: + +```go +markdown := goldmark.New( + goldmark.WithExtensions( + NewFootnote( + WithFootnoteIDPrefixFunction(func(n gast.Node) []byte { + v, ok := n.OwnerDocument().Meta()["footnote-prefix"] + if ok { + return util.StringToReadOnlyBytes(v.(string)) + } + return nil + }), + ), + ), +) + +for _, path := range files { + source := readAll(path) + var b bytes.Buffer + + doc := markdown.Parser().Parse(text.NewReader(source)) + doc.Meta()["footnote-prefix"] = getPrefix(path) + err := markdown.Renderer().Render(&b, source, doc) +} +``` + +You can use [goldmark-meta](https://github.com/yuin/goldmark-meta) to define a id prefix in the markdown document: + + +```markdown +--- +title: document title +slug: article1 +footnote-prefix: article1 +--- + +# My article + +``` + Security -------------------- By default, goldmark does not render raw HTML or potentially-dangerous URLs. @@ -336,6 +420,8 @@ Extensions extension for the goldmark Markdown parser. - [goldmark-highlighting](https://github.com/yuin/goldmark-highlighting): A syntax-highlighting extension for the goldmark markdown parser. +- [goldmark-emoji](https://github.com/yuin/goldmark-emoji): An emoji + extension for the goldmark Markdown parser. - [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax): Mathjax support for the goldmark markdown parser goldmark internal(for extension developers) diff --git a/vendor/github.com/yuin/goldmark/ast/ast.go b/vendor/github.com/yuin/goldmark/ast/ast.go index 66059e94cc1c0..3719ebbd8d7da 100644 --- a/vendor/github.com/yuin/goldmark/ast/ast.go +++ b/vendor/github.com/yuin/goldmark/ast/ast.go @@ -45,11 +45,6 @@ type Attribute struct { Value interface{} } -var attrNameIDS = []byte("#") -var attrNameID = []byte("id") -var attrNameClassS = []byte(".") -var attrNameClass = []byte("class") - // A Node interface defines basic AST node functionalities. type Node interface { // Type returns a type of this node. @@ -116,6 +111,11 @@ type Node interface { // tail of the children. InsertAfter(self, v1, insertee Node) + // OwnerDocument returns this node's owner document. + // If this node is not a child of the Document node, OwnerDocument + // returns nil. + OwnerDocument() *Document + // Dump dumps an AST tree structure to stdout. // This function completely aimed for debugging. // level is a indent level. Implementer should indent informations with @@ -169,7 +169,7 @@ type Node interface { RemoveAttributes() } -// A BaseNode struct implements the Node interface. +// A BaseNode struct implements the Node interface partialliy. type BaseNode struct { firstChild Node lastChild Node @@ -358,6 +358,22 @@ func (n *BaseNode) InsertBefore(self, v1, insertee Node) { } } +// OwnerDocument implements Node.OwnerDocument +func (n *BaseNode) OwnerDocument() *Document { + d := n.Parent() + for { + p := d.Parent() + if p == nil { + if v, ok := d.(*Document); ok { + return v + } + break + } + d = p + } + return nil +} + // Text implements Node.Text . func (n *BaseNode) Text(source []byte) []byte { var buf bytes.Buffer diff --git a/vendor/github.com/yuin/goldmark/ast/block.go b/vendor/github.com/yuin/goldmark/ast/block.go index f5bca33fe944a..fc0b3c2e029ce 100644 --- a/vendor/github.com/yuin/goldmark/ast/block.go +++ b/vendor/github.com/yuin/goldmark/ast/block.go @@ -7,7 +7,7 @@ import ( textm "github.com/yuin/goldmark/text" ) -// A BaseBlock struct implements the Node interface. +// A BaseBlock struct implements the Node interface partialliy. type BaseBlock struct { BaseNode blankPreviousLines bool @@ -50,6 +50,8 @@ func (b *BaseBlock) SetLines(v *textm.Segments) { // A Document struct is a root node of Markdown text. type Document struct { BaseBlock + + meta map[string]interface{} } // KindDocument is a NodeKind of the Document node. @@ -70,10 +72,29 @@ func (n *Document) Kind() NodeKind { return KindDocument } +// OwnerDocument implements Node.OwnerDocument +func (n *Document) OwnerDocument() *Document { + return n +} + +// Meta returns metadata of this document. +func (n *Document) Meta() map[string]interface{} { + if n.meta == nil { + n.meta = map[string]interface{}{} + } + return n.meta +} + +// SetMeta sets given metadata to this document. +func (n *Document) SetMeta(meta map[string]interface{}) { + n.meta = meta +} + // NewDocument returns a new Document node. func NewDocument() *Document { return &Document{ BaseBlock: BaseBlock{}, + meta: nil, } } diff --git a/vendor/github.com/yuin/goldmark/ast/inline.go b/vendor/github.com/yuin/goldmark/ast/inline.go index 23dcad4bc9ada..b221695bd7049 100644 --- a/vendor/github.com/yuin/goldmark/ast/inline.go +++ b/vendor/github.com/yuin/goldmark/ast/inline.go @@ -8,7 +8,7 @@ import ( "github.com/yuin/goldmark/util" ) -// A BaseInline struct implements the Node interface. +// A BaseInline struct implements the Node interface partialliy. type BaseInline struct { BaseNode } diff --git a/vendor/github.com/yuin/goldmark/extension/ast/footnote.go b/vendor/github.com/yuin/goldmark/extension/ast/footnote.go index 835f8478b3e6b..dedbab4f8b0f9 100644 --- a/vendor/github.com/yuin/goldmark/extension/ast/footnote.go +++ b/vendor/github.com/yuin/goldmark/extension/ast/footnote.go @@ -2,6 +2,7 @@ package ast import ( "fmt" + gast "github.com/yuin/goldmark/ast" ) @@ -9,13 +10,15 @@ import ( // (PHP Markdown Extra) text. type FootnoteLink struct { gast.BaseInline - Index int + Index int + RefCount int } // Dump implements Node.Dump. func (n *FootnoteLink) Dump(source []byte, level int) { m := map[string]string{} m["Index"] = fmt.Sprintf("%v", n.Index) + m["RefCount"] = fmt.Sprintf("%v", n.RefCount) gast.DumpHelper(n, source, level, m, nil) } @@ -30,36 +33,40 @@ func (n *FootnoteLink) Kind() gast.NodeKind { // NewFootnoteLink returns a new FootnoteLink node. func NewFootnoteLink(index int) *FootnoteLink { return &FootnoteLink{ - Index: index, + Index: index, + RefCount: 0, } } -// A FootnoteBackLink struct represents a link to a footnote of Markdown +// A FootnoteBacklink struct represents a link to a footnote of Markdown // (PHP Markdown Extra) text. -type FootnoteBackLink struct { +type FootnoteBacklink struct { gast.BaseInline - Index int + Index int + RefCount int } // Dump implements Node.Dump. -func (n *FootnoteBackLink) Dump(source []byte, level int) { +func (n *FootnoteBacklink) Dump(source []byte, level int) { m := map[string]string{} m["Index"] = fmt.Sprintf("%v", n.Index) + m["RefCount"] = fmt.Sprintf("%v", n.RefCount) gast.DumpHelper(n, source, level, m, nil) } -// KindFootnoteBackLink is a NodeKind of the FootnoteBackLink node. -var KindFootnoteBackLink = gast.NewNodeKind("FootnoteBackLink") +// KindFootnoteBacklink is a NodeKind of the FootnoteBacklink node. +var KindFootnoteBacklink = gast.NewNodeKind("FootnoteBacklink") // Kind implements Node.Kind. -func (n *FootnoteBackLink) Kind() gast.NodeKind { - return KindFootnoteBackLink +func (n *FootnoteBacklink) Kind() gast.NodeKind { + return KindFootnoteBacklink } -// NewFootnoteBackLink returns a new FootnoteBackLink node. -func NewFootnoteBackLink(index int) *FootnoteBackLink { - return &FootnoteBackLink{ - Index: index, +// NewFootnoteBacklink returns a new FootnoteBacklink node. +func NewFootnoteBacklink(index int) *FootnoteBacklink { + return &FootnoteBacklink{ + Index: index, + RefCount: 0, } } diff --git a/vendor/github.com/yuin/goldmark/extension/footnote.go b/vendor/github.com/yuin/goldmark/extension/footnote.go index ede72db8787f6..62f5ee61c6866 100644 --- a/vendor/github.com/yuin/goldmark/extension/footnote.go +++ b/vendor/github.com/yuin/goldmark/extension/footnote.go @@ -2,6 +2,8 @@ package extension import ( "bytes" + "strconv" + "github.com/yuin/goldmark" gast "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/extension/ast" @@ -10,10 +12,10 @@ import ( "github.com/yuin/goldmark/renderer/html" "github.com/yuin/goldmark/text" "github.com/yuin/goldmark/util" - "strconv" ) var footnoteListKey = parser.NewContextKey() +var footnoteLinkListKey = parser.NewContextKey() type footnoteBlockParser struct { } @@ -164,7 +166,20 @@ func (s *footnoteParser) Parse(parent gast.Node, block text.Reader, pc parser.Co return nil } - return ast.NewFootnoteLink(index) + fnlink := ast.NewFootnoteLink(index) + var fnlist []*ast.FootnoteLink + if tmp := pc.Get(footnoteLinkListKey); tmp != nil { + fnlist = tmp.([]*ast.FootnoteLink) + } else { + fnlist = []*ast.FootnoteLink{} + pc.Set(footnoteLinkListKey, fnlist) + } + pc.Set(footnoteLinkListKey, append(fnlist, fnlink)) + if line[0] == '!' { + parent.AppendChild(parent, gast.NewTextSegment(text.NewSegment(segment.Start, segment.Start+1))) + } + + return fnlink } type footnoteASTTransformer struct { @@ -180,23 +195,46 @@ func NewFootnoteASTTransformer() parser.ASTTransformer { func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) { var list *ast.FootnoteList - if tlist := pc.Get(footnoteListKey); tlist != nil { - list = tlist.(*ast.FootnoteList) - } else { - return + var fnlist []*ast.FootnoteLink + if tmp := pc.Get(footnoteListKey); tmp != nil { + list = tmp.(*ast.FootnoteList) } + if tmp := pc.Get(footnoteLinkListKey); tmp != nil { + fnlist = tmp.([]*ast.FootnoteLink) + } + pc.Set(footnoteListKey, nil) + pc.Set(footnoteLinkListKey, nil) + + if list == nil { + return + } + + counter := map[int]int{} + if fnlist != nil { + for _, fnlink := range fnlist { + if fnlink.Index >= 0 { + counter[fnlink.Index]++ + } + } + for _, fnlink := range fnlist { + fnlink.RefCount = counter[fnlink.Index] + } + } for footnote := list.FirstChild(); footnote != nil; { var container gast.Node = footnote next := footnote.NextSibling() if fc := container.LastChild(); fc != nil && gast.IsParagraph(fc) { container = fc } - index := footnote.(*ast.Footnote).Index + fn := footnote.(*ast.Footnote) + index := fn.Index if index < 0 { list.RemoveChild(list, footnote) } else { - container.AppendChild(container, ast.NewFootnoteBackLink(index)) + backLink := ast.NewFootnoteBacklink(index) + backLink.RefCount = counter[index] + container.AppendChild(container, backLink) } footnote = next } @@ -214,19 +252,250 @@ func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Read node.AppendChild(node, list) } +// FootnoteConfig holds configuration values for the footnote extension. +// +// Link* and Backlink* configurations have some variables: +// Occurrances of “^^” in the string will be replaced by the +// corresponding footnote number in the HTML output. +// Occurrances of “%%” will be replaced by a number for the +// reference (footnotes can have multiple references). +type FootnoteConfig struct { + html.Config + + // IDPrefix is a prefix for the id attributes generated by footnotes. + IDPrefix []byte + + // IDPrefix is a function that determines the id attribute for given Node. + IDPrefixFunction func(gast.Node) []byte + + // LinkTitle is an optional title attribute for footnote links. + LinkTitle []byte + + // BacklinkTitle is an optional title attribute for footnote backlinks. + BacklinkTitle []byte + + // LinkClass is a class for footnote links. + LinkClass []byte + + // BacklinkClass is a class for footnote backlinks. + BacklinkClass []byte + + // BacklinkHTML is an HTML content for footnote backlinks. + BacklinkHTML []byte +} + +// FootnoteOption interface is a functional option interface for the extension. +type FootnoteOption interface { + renderer.Option + // SetFootnoteOption sets given option to the extension. + SetFootnoteOption(*FootnoteConfig) +} + +// NewFootnoteConfig returns a new Config with defaults. +func NewFootnoteConfig() FootnoteConfig { + return FootnoteConfig{ + Config: html.NewConfig(), + LinkTitle: []byte(""), + BacklinkTitle: []byte(""), + LinkClass: []byte("footnote-ref"), + BacklinkClass: []byte("footnote-backref"), + BacklinkHTML: []byte("↩︎"), + } +} + +// SetOption implements renderer.SetOptioner. +func (c *FootnoteConfig) SetOption(name renderer.OptionName, value interface{}) { + switch name { + case optFootnoteIDPrefixFunction: + c.IDPrefixFunction = value.(func(gast.Node) []byte) + case optFootnoteIDPrefix: + c.IDPrefix = value.([]byte) + case optFootnoteLinkTitle: + c.LinkTitle = value.([]byte) + case optFootnoteBacklinkTitle: + c.BacklinkTitle = value.([]byte) + case optFootnoteLinkClass: + c.LinkClass = value.([]byte) + case optFootnoteBacklinkClass: + c.BacklinkClass = value.([]byte) + case optFootnoteBacklinkHTML: + c.BacklinkHTML = value.([]byte) + default: + c.Config.SetOption(name, value) + } +} + +type withFootnoteHTMLOptions struct { + value []html.Option +} + +func (o *withFootnoteHTMLOptions) SetConfig(c *renderer.Config) { + if o.value != nil { + for _, v := range o.value { + v.(renderer.Option).SetConfig(c) + } + } +} + +func (o *withFootnoteHTMLOptions) SetFootnoteOption(c *FootnoteConfig) { + if o.value != nil { + for _, v := range o.value { + v.SetHTMLOption(&c.Config) + } + } +} + +// WithFootnoteHTMLOptions is functional option that wraps goldmark HTMLRenderer options. +func WithFootnoteHTMLOptions(opts ...html.Option) FootnoteOption { + return &withFootnoteHTMLOptions{opts} +} + +const optFootnoteIDPrefix renderer.OptionName = "FootnoteIDPrefix" + +type withFootnoteIDPrefix struct { + value []byte +} + +func (o *withFootnoteIDPrefix) SetConfig(c *renderer.Config) { + c.Options[optFootnoteIDPrefix] = o.value +} + +func (o *withFootnoteIDPrefix) SetFootnoteOption(c *FootnoteConfig) { + c.IDPrefix = o.value +} + +// WithFootnoteIDPrefix is a functional option that is a prefix for the id attributes generated by footnotes. +func WithFootnoteIDPrefix(a []byte) FootnoteOption { + return &withFootnoteIDPrefix{a} +} + +const optFootnoteIDPrefixFunction renderer.OptionName = "FootnoteIDPrefixFunction" + +type withFootnoteIDPrefixFunction struct { + value func(gast.Node) []byte +} + +func (o *withFootnoteIDPrefixFunction) SetConfig(c *renderer.Config) { + c.Options[optFootnoteIDPrefixFunction] = o.value +} + +func (o *withFootnoteIDPrefixFunction) SetFootnoteOption(c *FootnoteConfig) { + c.IDPrefixFunction = o.value +} + +// WithFootnoteIDPrefixFunction is a functional option that is a prefix for the id attributes generated by footnotes. +func WithFootnoteIDPrefixFunction(a func(gast.Node) []byte) FootnoteOption { + return &withFootnoteIDPrefixFunction{a} +} + +const optFootnoteLinkTitle renderer.OptionName = "FootnoteLinkTitle" + +type withFootnoteLinkTitle struct { + value []byte +} + +func (o *withFootnoteLinkTitle) SetConfig(c *renderer.Config) { + c.Options[optFootnoteLinkTitle] = o.value +} + +func (o *withFootnoteLinkTitle) SetFootnoteOption(c *FootnoteConfig) { + c.LinkTitle = o.value +} + +// WithFootnoteLinkTitle is a functional option that is an optional title attribute for footnote links. +func WithFootnoteLinkTitle(a []byte) FootnoteOption { + return &withFootnoteLinkTitle{a} +} + +const optFootnoteBacklinkTitle renderer.OptionName = "FootnoteBacklinkTitle" + +type withFootnoteBacklinkTitle struct { + value []byte +} + +func (o *withFootnoteBacklinkTitle) SetConfig(c *renderer.Config) { + c.Options[optFootnoteBacklinkTitle] = o.value +} + +func (o *withFootnoteBacklinkTitle) SetFootnoteOption(c *FootnoteConfig) { + c.BacklinkTitle = o.value +} + +// WithFootnoteBacklinkTitle is a functional option that is an optional title attribute for footnote backlinks. +func WithFootnoteBacklinkTitle(a []byte) FootnoteOption { + return &withFootnoteBacklinkTitle{a} +} + +const optFootnoteLinkClass renderer.OptionName = "FootnoteLinkClass" + +type withFootnoteLinkClass struct { + value []byte +} + +func (o *withFootnoteLinkClass) SetConfig(c *renderer.Config) { + c.Options[optFootnoteLinkClass] = o.value +} + +func (o *withFootnoteLinkClass) SetFootnoteOption(c *FootnoteConfig) { + c.LinkClass = o.value +} + +// WithFootnoteLinkClass is a functional option that is a class for footnote links. +func WithFootnoteLinkClass(a []byte) FootnoteOption { + return &withFootnoteLinkClass{a} +} + +const optFootnoteBacklinkClass renderer.OptionName = "FootnoteBacklinkClass" + +type withFootnoteBacklinkClass struct { + value []byte +} + +func (o *withFootnoteBacklinkClass) SetConfig(c *renderer.Config) { + c.Options[optFootnoteBacklinkClass] = o.value +} + +func (o *withFootnoteBacklinkClass) SetFootnoteOption(c *FootnoteConfig) { + c.BacklinkClass = o.value +} + +// WithFootnoteBacklinkClass is a functional option that is a class for footnote backlinks. +func WithFootnoteBacklinkClass(a []byte) FootnoteOption { + return &withFootnoteBacklinkClass{a} +} + +const optFootnoteBacklinkHTML renderer.OptionName = "FootnoteBacklinkHTML" + +type withFootnoteBacklinkHTML struct { + value []byte +} + +func (o *withFootnoteBacklinkHTML) SetConfig(c *renderer.Config) { + c.Options[optFootnoteBacklinkHTML] = o.value +} + +func (o *withFootnoteBacklinkHTML) SetFootnoteOption(c *FootnoteConfig) { + c.BacklinkHTML = o.value +} + +// WithFootnoteBacklinkHTML is an HTML content for footnote backlinks. +func WithFootnoteBacklinkHTML(a []byte) FootnoteOption { + return &withFootnoteBacklinkHTML{a} +} + // FootnoteHTMLRenderer is a renderer.NodeRenderer implementation that // renders FootnoteLink nodes. type FootnoteHTMLRenderer struct { - html.Config + FootnoteConfig } // NewFootnoteHTMLRenderer returns a new FootnoteHTMLRenderer. -func NewFootnoteHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { +func NewFootnoteHTMLRenderer(opts ...FootnoteOption) renderer.NodeRenderer { r := &FootnoteHTMLRenderer{ - Config: html.NewConfig(), + FootnoteConfig: NewFootnoteConfig(), } for _, opt := range opts { - opt.SetHTMLOption(&r.Config) + opt.SetFootnoteOption(&r.FootnoteConfig) } return r } @@ -234,7 +503,7 @@ func NewFootnoteHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { // RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs. func (r *FootnoteHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { reg.Register(ast.KindFootnoteLink, r.renderFootnoteLink) - reg.Register(ast.KindFootnoteBackLink, r.renderFootnoteBackLink) + reg.Register(ast.KindFootnoteBacklink, r.renderFootnoteBacklink) reg.Register(ast.KindFootnote, r.renderFootnote) reg.Register(ast.KindFootnoteList, r.renderFootnoteList) } @@ -243,25 +512,45 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt if entering { n := node.(*ast.FootnoteLink) is := strconv.Itoa(n.Index) - _, _ = w.WriteString(``) + _, _ = w.WriteString(`" class="`) + _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.LinkClass, + n.Index, n.RefCount)) + if len(r.FootnoteConfig.LinkTitle) > 0 { + _, _ = w.WriteString(`" title="`) + _, _ = w.Write(util.EscapeHTML(applyFootnoteTemplate(r.FootnoteConfig.LinkTitle, n.Index, n.RefCount))) + } + _, _ = w.WriteString(`" role="doc-noteref">`) + _, _ = w.WriteString(is) _, _ = w.WriteString(``) } return gast.WalkContinue, nil } -func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { +func (r *FootnoteHTMLRenderer) renderFootnoteBacklink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { if entering { - n := node.(*ast.FootnoteBackLink) + n := node.(*ast.FootnoteBacklink) is := strconv.Itoa(n.Index) - _, _ = w.WriteString(` `) - _, _ = w.WriteString("↩︎") + _, _ = w.WriteString(`" class="`) + _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkClass, n.Index, n.RefCount)) + if len(r.FootnoteConfig.BacklinkTitle) > 0 { + _, _ = w.WriteString(`" title="`) + _, _ = w.Write(util.EscapeHTML(applyFootnoteTemplate(r.FootnoteConfig.BacklinkTitle, n.Index, n.RefCount))) + } + _, _ = w.WriteString(`" role="doc-backlink">`) + _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkHTML, n.Index, n.RefCount)) _, _ = w.WriteString(``) } return gast.WalkContinue, nil @@ -271,7 +560,9 @@ func (r *FootnoteHTMLRenderer) renderFootnote(w util.BufWriter, source []byte, n n := node.(*ast.Footnote) is := strconv.Itoa(n.Index) if entering { - _, _ = w.WriteString(`
  • \^{}\[\]` + "`" + `]*)?`) +var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:[/#?][-a-zA-Z0-9@:%_\+.~#!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) -var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp):\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:(?:/|[#?])[-a-zA-Z0-9@:%_+.~#$!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`) +var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp)://[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?::\d+)?(?:[/#?][-a-zA-Z0-9@:%_+.~#$!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) // An LinkifyConfig struct is a data structure that holds configuration of the // Linkify extension. diff --git a/vendor/github.com/yuin/goldmark/extension/table.go b/vendor/github.com/yuin/goldmark/extension/table.go index f0e994e838b2e..c40bdefc5c813 100644 --- a/vendor/github.com/yuin/goldmark/extension/table.go +++ b/vendor/github.com/yuin/goldmark/extension/table.go @@ -15,6 +15,13 @@ import ( "github.com/yuin/goldmark/util" ) +var escapedPipeCellListKey = parser.NewContextKey() + +type escapedPipeCell struct { + Cell *ast.TableCell + Pos []int +} + // TableCellAlignMethod indicates how are table cells aligned in HTML format.indicates how are table cells aligned in HTML format. type TableCellAlignMethod int @@ -148,7 +155,7 @@ func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text. if alignments == nil { continue } - header := b.parseRow(lines.At(i-1), alignments, true, reader) + header := b.parseRow(lines.At(i-1), alignments, true, reader, pc) if header == nil || len(alignments) != header.ChildCount() { return } @@ -156,7 +163,7 @@ func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text. table.Alignments = alignments table.AppendChild(table, ast.NewTableHeader(header)) for j := i + 1; j < lines.Len(); j++ { - table.AppendChild(table, b.parseRow(lines.At(j), alignments, false, reader)) + table.AppendChild(table, b.parseRow(lines.At(j), alignments, false, reader, pc)) } node.Lines().SetSliced(0, i-1) node.Parent().InsertAfter(node.Parent(), node, table) @@ -170,7 +177,7 @@ func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text. } } -func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []ast.Alignment, isHeader bool, reader text.Reader) *ast.TableRow { +func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []ast.Alignment, isHeader bool, reader text.Reader, pc parser.Context) *ast.TableRow { source := reader.Source() line := segment.Value(source) pos := 0 @@ -194,18 +201,39 @@ func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments [] } else { alignment = alignments[i] } - closure := util.FindClosure(line[pos:], byte(0), '|', true, false) - if closure < 0 { - closure = len(line[pos:]) - } + + var escapedCell *escapedPipeCell node := ast.NewTableCell() - seg := text.NewSegment(segment.Start+pos, segment.Start+pos+closure) + node.Alignment = alignment + hasBacktick := false + closure := pos + for ; closure < limit; closure++ { + if line[closure] == '`' { + hasBacktick = true + } + if line[closure] == '|' { + if closure == 0 || line[closure-1] != '\\' { + break + } else if hasBacktick { + if escapedCell == nil { + escapedCell = &escapedPipeCell{node, []int{}} + escapedList := pc.ComputeIfAbsent(escapedPipeCellListKey, + func() interface{} { + return []*escapedPipeCell{} + }).([]*escapedPipeCell) + escapedList = append(escapedList, escapedCell) + pc.Set(escapedPipeCellListKey, escapedList) + } + escapedCell.Pos = append(escapedCell.Pos, segment.Start+closure-1) + } + } + } + seg := text.NewSegment(segment.Start+pos, segment.Start+closure) seg = seg.TrimLeftSpace(source) seg = seg.TrimRightSpace(source) node.Lines().Append(seg) - node.Alignment = alignment row.AppendChild(row, node) - pos += closure + 1 + pos = closure + 1 } for ; i < len(alignments); i++ { row.AppendChild(row, ast.NewTableCell()) @@ -243,6 +271,49 @@ func (b *tableParagraphTransformer) parseDelimiter(segment text.Segment, reader return alignments } +type tableASTTransformer struct { +} + +var defaultTableASTTransformer = &tableASTTransformer{} + +// NewTableASTTransformer returns a parser.ASTTransformer for tables. +func NewTableASTTransformer() parser.ASTTransformer { + return defaultTableASTTransformer +} + +func (a *tableASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) { + lst := pc.Get(escapedPipeCellListKey) + if lst == nil { + return + } + pc.Set(escapedPipeCellListKey, nil) + for _, v := range lst.([]*escapedPipeCell) { + _ = gast.Walk(v.Cell, func(n gast.Node, entering bool) (gast.WalkStatus, error) { + if n.Kind() != gast.KindCodeSpan { + return gast.WalkContinue, nil + } + c := n.FirstChild() + for c != nil { + next := c.NextSibling() + if c.Kind() == gast.KindText { + t := c.(*gast.Text) + for _, pos := range v.Pos { + if t.Segment.Start <= pos && t.Segment.Stop > pos { + n1 := gast.NewRawTextSegment(t.Segment.WithStop(pos)) + n2 := gast.NewRawTextSegment(t.Segment.WithStart(pos + 1)) + n.InsertAfter(n, c, n1) + n.InsertAfter(n, n1, n2) + n.RemoveChild(n, c) + } + } + } + c = next + } + return gast.WalkContinue, nil + }) + } +} + // TableHTMLRenderer is a renderer.NodeRenderer implementation that // renders Table nodes. type TableHTMLRenderer struct { @@ -419,7 +490,7 @@ func (r *TableHTMLRenderer) renderTableCell(w util.BufWriter, source []byte, nod cob.AppendByte(';') } style := fmt.Sprintf("text-align:%s", n.Alignment.String()) - cob.Append(util.StringToReadOnlyBytes(style)) + cob.AppendString(style) n.SetAttributeString("style", cob.Bytes()) } } @@ -454,9 +525,14 @@ func NewTable(opts ...TableOption) goldmark.Extender { } func (e *table) Extend(m goldmark.Markdown) { - m.Parser().AddOptions(parser.WithParagraphTransformers( - util.Prioritized(NewTableParagraphTransformer(), 200), - )) + m.Parser().AddOptions( + parser.WithParagraphTransformers( + util.Prioritized(NewTableParagraphTransformer(), 200), + ), + parser.WithASTTransformers( + util.Prioritized(defaultTableASTTransformer, 0), + ), + ) m.Renderer().AddOptions(renderer.WithNodeRenderers( util.Prioritized(NewTableHTMLRenderer(e.options...), 500), )) diff --git a/vendor/github.com/yuin/goldmark/go.mod b/vendor/github.com/yuin/goldmark/go.mod index a10efcad5288d..f76c1766fcb50 100644 --- a/vendor/github.com/yuin/goldmark/go.mod +++ b/vendor/github.com/yuin/goldmark/go.mod @@ -1,3 +1,3 @@ module github.com/yuin/goldmark -go 1.13 +go 1.15 diff --git a/vendor/github.com/yuin/goldmark/parser/link.go b/vendor/github.com/yuin/goldmark/parser/link.go index e7c6966f3def1..c36cce5d9000d 100644 --- a/vendor/github.com/yuin/goldmark/parser/link.go +++ b/vendor/github.com/yuin/goldmark/parser/link.go @@ -2,7 +2,6 @@ package parser import ( "fmt" - "regexp" "strings" "github.com/yuin/goldmark/ast" @@ -113,8 +112,6 @@ func (s *linkParser) Trigger() []byte { return []byte{'!', '[', ']'} } -var linkDestinationRegexp = regexp.MustCompile(`\s*([^\s].+)`) -var linkTitleRegexp = regexp.MustCompile(`\s+(\)|["'\(].+)`) var linkBottom = NewContextKey() func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node { @@ -293,20 +290,17 @@ func (s *linkParser) parseLink(parent ast.Node, last *linkLabelState, block text func parseLinkDestination(block text.Reader) ([]byte, bool) { block.SkipSpaces() line, _ := block.PeekLine() - buf := []byte{} if block.Peek() == '<' { i := 1 for i < len(line) { c := line[i] if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) { - buf = append(buf, '\\', line[i+1]) i += 2 continue } else if c == '>' { block.Advance(i + 1) return line[1:i], true } - buf = append(buf, c) i++ } return nil, false @@ -316,7 +310,6 @@ func parseLinkDestination(block text.Reader) ([]byte, bool) { for i < len(line) { c := line[i] if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) { - buf = append(buf, '\\', line[i+1]) i += 2 continue } else if c == '(' { @@ -329,7 +322,6 @@ func parseLinkDestination(block text.Reader) ([]byte, bool) { } else if util.IsSpace(c) { break } - buf = append(buf, c) i++ } block.Advance(i) diff --git a/vendor/github.com/yuin/goldmark/parser/parser.go b/vendor/github.com/yuin/goldmark/parser/parser.go index def13db66635f..e58b5ee936cb6 100644 --- a/vendor/github.com/yuin/goldmark/parser/parser.go +++ b/vendor/github.com/yuin/goldmark/parser/parser.go @@ -138,6 +138,9 @@ type Context interface { // Get returns a value associated with the given key. Get(ContextKey) interface{} + // ComputeIfAbsent computes a value if a value associated with the given key is absent and returns the value. + ComputeIfAbsent(ContextKey, func() interface{}) interface{} + // Set sets the given value to the context. Set(ContextKey, interface{}) @@ -252,6 +255,15 @@ func (p *parseContext) Get(key ContextKey) interface{} { return p.store[key] } +func (p *parseContext) ComputeIfAbsent(key ContextKey, f func() interface{}) interface{} { + v := p.store[key] + if v == nil { + v = f() + p.store[key] = v + } + return v +} + func (p *parseContext) Set(key ContextKey, value interface{}) { p.store[key] = value } diff --git a/vendor/github.com/yuin/goldmark/parser/raw_html.go b/vendor/github.com/yuin/goldmark/parser/raw_html.go index d7ba414ff21b3..7fd696cc2cefc 100644 --- a/vendor/github.com/yuin/goldmark/parser/raw_html.go +++ b/vendor/github.com/yuin/goldmark/parser/raw_html.go @@ -2,10 +2,11 @@ package parser import ( "bytes" + "regexp" + "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/text" "github.com/yuin/goldmark/util" - "regexp" ) type rawHTMLParser struct { @@ -67,8 +68,6 @@ func (s *rawHTMLParser) parseSingleLineRegexp(reg *regexp.Regexp, block text.Rea return node } -var dummyMatch = [][]byte{} - func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Reader, pc Context) ast.Node { sline, ssegment := block.Position() if block.Match(reg) { @@ -102,7 +101,3 @@ func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Read } return nil } - -func (s *rawHTMLParser) CloseBlock(parent ast.Node, pc Context) { - // nothing to do -} diff --git a/vendor/github.com/yuin/goldmark/util/util.go b/vendor/github.com/yuin/goldmark/util/util.go index fc1438dc19d98..3ec73f54f32f9 100644 --- a/vendor/github.com/yuin/goldmark/util/util.go +++ b/vendor/github.com/yuin/goldmark/util/util.go @@ -37,6 +37,12 @@ func (b *CopyOnWriteBuffer) Write(value []byte) { b.buffer = append(b.buffer, value...) } +// WriteString writes given string to the buffer. +// WriteString allocate new buffer and clears it at the first time. +func (b *CopyOnWriteBuffer) WriteString(value string) { + b.Write(StringToReadOnlyBytes(value)) +} + // Append appends given bytes to the buffer. // Append copy buffer at the first time. func (b *CopyOnWriteBuffer) Append(value []byte) { @@ -49,6 +55,12 @@ func (b *CopyOnWriteBuffer) Append(value []byte) { b.buffer = append(b.buffer, value...) } +// AppendString appends given string to the buffer. +// AppendString copy buffer at the first time. +func (b *CopyOnWriteBuffer) AppendString(value string) { + b.Append(StringToReadOnlyBytes(value)) +} + // WriteByte writes the given byte to the buffer. // WriteByte allocate new buffer and clears it at the first time. func (b *CopyOnWriteBuffer) WriteByte(c byte) { @@ -804,7 +816,7 @@ func IsPunct(c byte) bool { return punctTable[c] == 1 } -// IsPunct returns true if the given rune is a punctuation, otherwise false. +// IsPunctRune returns true if the given rune is a punctuation, otherwise false. func IsPunctRune(r rune) bool { return int32(r) <= 256 && IsPunct(byte(r)) || unicode.IsPunct(r) } @@ -814,7 +826,7 @@ func IsSpace(c byte) bool { return spaceTable[c] == 1 } -// IsSpace returns true if the given rune is a space, otherwise false. +// IsSpaceRune returns true if the given rune is a space, otherwise false. func IsSpaceRune(r rune) bool { return int32(r) <= 256 && IsSpace(byte(r)) || unicode.IsSpace(r) } diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go index 9eed911ac735e..8219748d0f6b4 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go @@ -78,6 +78,9 @@ func (bsc *ByteSliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, case bsontype.Null: val.Set(reflect.Zero(val.Type())) return vr.ReadNull() + case bsontype.Undefined: + val.Set(reflect.Zero(val.Type())) + return vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a []byte", vrType) } diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go index 52d2365a34513..a2e2d425a0f7d 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go @@ -24,6 +24,16 @@ import ( var defaultValueDecoders DefaultValueDecoders +func newDefaultStructCodec() *StructCodec { + codec, err := NewStructCodec(DefaultStructTagParser) + if err != nil { + // This function is called from the codec registration path, so errors can't be propagated. If there's an error + // constructing the StructCodec, we panic to avoid losing it. + panic(fmt.Errorf("error creating default StructCodec: %v", err)) + } + return codec +} + // DefaultValueDecoders is a namespace type for the default ValueDecoders used // when creating a registry. type DefaultValueDecoders struct{} @@ -77,7 +87,7 @@ func (dvd DefaultValueDecoders) RegisterDefaultDecoders(rb *RegistryBuilder) { RegisterDefaultDecoder(reflect.Map, defaultMapCodec). RegisterDefaultDecoder(reflect.Slice, defaultSliceCodec). RegisterDefaultDecoder(reflect.String, defaultStringCodec). - RegisterDefaultDecoder(reflect.Struct, defaultStructCodec). + RegisterDefaultDecoder(reflect.Struct, newDefaultStructCodec()). RegisterDefaultDecoder(reflect.Ptr, NewPointerCodec()). RegisterTypeMapEntry(bsontype.Double, tFloat64). RegisterTypeMapEntry(bsontype.String, tString). @@ -140,6 +150,10 @@ func (dvd DefaultValueDecoders) BooleanDecodeValue(dctx DecodeContext, vr bsonrw if err = vr.ReadNull(); err != nil { return err } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return err + } default: return fmt.Errorf("cannot decode %v into a boolean", vrType) } @@ -195,6 +209,10 @@ func (dvd DefaultValueDecoders) IntDecodeValue(dc DecodeContext, vr bsonrw.Value if err = vr.ReadNull(); err != nil { return err } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return err + } default: return fmt.Errorf("cannot decode %v into an integer type", vrType) } @@ -230,8 +248,8 @@ func (dvd DefaultValueDecoders) IntDecodeValue(dc DecodeContext, vr bsonrw.Value } // UintDecodeValue is the ValueDecoderFunc for uint types. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use UIntCodec.DecodeValue instead. +// +// Deprecated: UintDecodeValue is not registered by default. Use UintCodec.DecodeValue instead. func (dvd DefaultValueDecoders) UintDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { var i64 int64 var err error @@ -354,6 +372,10 @@ func (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.Val if err = vr.ReadNull(); err != nil { return err } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return err + } default: return fmt.Errorf("cannot decode %v into a float32 or float64 type", vrType) } @@ -373,8 +395,8 @@ func (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.Val } // StringDecodeValue is the ValueDecoderFunc for string types. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use StringCodec.DecodeValue instead. +// +// Deprecated: StringDecodeValue is not registered by default. Use StringCodec.DecodeValue instead. func (dvd DefaultValueDecoders) StringDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { var str string var err error @@ -409,6 +431,8 @@ func (DefaultValueDecoders) JavaScriptDecodeValue(dctx DecodeContext, vr bsonrw. js, err = vr.ReadJavascript() case bsontype.Null: err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a primitive.JavaScript", vrType) } @@ -452,6 +476,10 @@ func (DefaultValueDecoders) SymbolDecodeValue(dctx DecodeContext, vr bsonrw.Valu if err = vr.ReadNull(); err != nil { return err } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return err + } default: return fmt.Errorf("cannot decode %v into a primitive.Symbol", vrType) } @@ -474,6 +502,8 @@ func (DefaultValueDecoders) BinaryDecodeValue(dc DecodeContext, vr bsonrw.ValueR data, subtype, err = vr.ReadBinary() case bsontype.Null: err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a Binary", vrType) } @@ -536,6 +566,10 @@ func (dvd DefaultValueDecoders) ObjectIDDecodeValue(dc DecodeContext, vr bsonrw. if err = vr.ReadNull(); err != nil { return err } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return err + } default: return fmt.Errorf("cannot decode %v into an ObjectID", vrType) } @@ -557,6 +591,8 @@ func (DefaultValueDecoders) DateTimeDecodeValue(dc DecodeContext, vr bsonrw.Valu dt, err = vr.ReadDateTime() case bsontype.Null: err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a DateTime", vrType) } @@ -574,12 +610,21 @@ func (DefaultValueDecoders) NullDecodeValue(dc DecodeContext, vr bsonrw.ValueRea return ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: val} } - if vrType := vr.Type(); vrType != bsontype.Null { - return fmt.Errorf("cannot decode %v into a Null", vrType) + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Undefined: + err = vr.ReadUndefined() + case bsontype.Null: + err = vr.ReadNull() + default: + return fmt.Errorf("cannot decode %v into a Null", vr.Type()) } + if err != nil { + return err + } val.Set(reflect.ValueOf(primitive.Null{})) - return vr.ReadNull() + return nil } // RegexDecodeValue is the ValueDecoderFunc for Regex. @@ -595,6 +640,8 @@ func (DefaultValueDecoders) RegexDecodeValue(dc DecodeContext, vr bsonrw.ValueRe pattern, options, err = vr.ReadRegex() case bsontype.Null: err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a Regex", vrType) } @@ -620,6 +667,8 @@ func (DefaultValueDecoders) DBPointerDecodeValue(dc DecodeContext, vr bsonrw.Val ns, pointer, err = vr.ReadDBPointer() case bsontype.Null: err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a DBPointer", vrType) } @@ -644,6 +693,8 @@ func (DefaultValueDecoders) TimestampDecodeValue(dc DecodeContext, vr bsonrw.Val t, incr, err = vr.ReadTimestamp() case bsontype.Null: err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a Timestamp", vrType) } @@ -667,6 +718,8 @@ func (DefaultValueDecoders) MinKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueR err = vr.ReadMinKey() case bsontype.Null: err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a MinKey", vr.Type()) } @@ -690,6 +743,8 @@ func (DefaultValueDecoders) MaxKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueR err = vr.ReadMaxKey() case bsontype.Null: err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a MaxKey", vr.Type()) } @@ -714,6 +769,8 @@ func (dvd DefaultValueDecoders) Decimal128DecodeValue(dctx DecodeContext, vr bso d128, err = vr.ReadDecimal128() case bsontype.Null: err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a primitive.Decimal128", vr.Type()) } @@ -755,6 +812,11 @@ func (dvd DefaultValueDecoders) JSONNumberDecodeValue(dc DecodeContext, vr bsonr return err } val.SetString("") + case bsontype.Undefined: + if err := vr.ReadUndefined(); err != nil { + return err + } + val.SetString("") default: return fmt.Errorf("cannot decode %v into a json.Number", vrType) } @@ -787,14 +849,20 @@ func (dvd DefaultValueDecoders) URLDecodeValue(dc DecodeContext, vr bsonrw.Value } val.Set(reflect.ValueOf(url.URL{})) return nil + case bsontype.Undefined: + if err := vr.ReadUndefined(); err != nil { + return err + } + val.Set(reflect.ValueOf(url.URL{})) + return nil default: return fmt.Errorf("cannot decode %v into a *url.URL", vrType) } } // TimeDecodeValue is the ValueDecoderFunc for time.Time. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use Time.DecodeValue instead. +// +// Deprecated: TimeDecodeValue is not registered by default. Use TimeCodec.DecodeValue instead. func (dvd DefaultValueDecoders) TimeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { if vr.Type() != bsontype.DateTime { return fmt.Errorf("cannot decode %v into a time.Time", vr.Type()) @@ -814,8 +882,8 @@ func (dvd DefaultValueDecoders) TimeDecodeValue(dc DecodeContext, vr bsonrw.Valu } // ByteSliceDecodeValue is the ValueDecoderFunc for []byte. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use ByteSliceCodec.DecodeValue instead. +// +// Deprecated: ByteSliceDecodeValue is not registered by default. Use ByteSliceCodec.DecodeValue instead. func (dvd DefaultValueDecoders) ByteSliceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { if vr.Type() != bsontype.Binary && vr.Type() != bsontype.Null { return fmt.Errorf("cannot decode %v into a []byte", vr.Type()) @@ -843,8 +911,8 @@ func (dvd DefaultValueDecoders) ByteSliceDecodeValue(dc DecodeContext, vr bsonrw } // MapDecodeValue is the ValueDecoderFunc for map[string]* types. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use Map.DecodeValue instead. +// +// Deprecated: MapDecodeValue is not registered by default. Use MapCodec.DecodeValue instead. func (dvd DefaultValueDecoders) MapDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { if !val.CanSet() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String { return ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} @@ -935,6 +1003,9 @@ func (dvd DefaultValueDecoders) ArrayDecodeValue(dc DecodeContext, vr bsonrw.Val case bsontype.Null: val.Set(reflect.Zero(val.Type())) return vr.ReadNull() + case bsontype.Undefined: + val.Set(reflect.Zero(val.Type())) + return vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into an array", vrType) } @@ -964,8 +1035,8 @@ func (dvd DefaultValueDecoders) ArrayDecodeValue(dc DecodeContext, vr bsonrw.Val } // SliceDecodeValue is the ValueDecoderFunc for slice types. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use SliceCodec.DecodeValue instead. +// +// Deprecated: SliceDecodeValue is not registered by default. Use SliceCodec.DecodeValue instead. func (dvd DefaultValueDecoders) SliceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { if !val.CanSet() || val.Kind() != reflect.Slice { return ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} @@ -1075,8 +1146,8 @@ func (dvd DefaultValueDecoders) UnmarshalerDecodeValue(dc DecodeContext, vr bson } // EmptyInterfaceDecodeValue is the ValueDecoderFunc for interface{}. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use EmptyInterfaceCodec.DecodeValue instead. +// +// Deprecated: EmptyInterfaceDecodeValue is not registered by default. Use EmptyInterfaceCodec.DecodeValue instead. func (dvd DefaultValueDecoders) EmptyInterfaceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { if !val.CanSet() || val.Type() != tEmpty { return ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: val} @@ -1146,6 +1217,7 @@ func (dvd DefaultValueDecoders) decodeDefault(dc DecodeContext, vr bsonrw.ValueR return nil, err } + idx := 0 for { vr, err := ar.ReadValue() if err == bsonrw.ErrEOA { @@ -1159,9 +1231,10 @@ func (dvd DefaultValueDecoders) decodeDefault(dc DecodeContext, vr bsonrw.ValueR err = decoder.DecodeValue(dc, vr, elem) if err != nil { - return nil, err + return nil, newDecodeError(strconv.Itoa(idx), err) } elems = append(elems, elem) + idx++ } return elems, nil @@ -1200,6 +1273,12 @@ func (dvd DefaultValueDecoders) CodeWithScopeDecodeValue(dc DecodeContext, vr bs } val.Set(reflect.ValueOf(primitive.CodeWithScope{})) return nil + case bsontype.Undefined: + if err := vr.ReadUndefined(); err != nil { + return err + } + val.Set(reflect.ValueOf(primitive.CodeWithScope{})) + return nil default: return fmt.Errorf("cannot decode %v into a primitive.CodeWithScope", vrType) } @@ -1239,7 +1318,7 @@ func (DefaultValueDecoders) decodeElemsFromDocumentReader(dc DecodeContext, dr b val := reflect.New(tEmpty).Elem() err = decoder.DecodeValue(dc, vr, val) if err != nil { - return nil, err + return nil, newDecodeError(key, err) } elems = append(elems, reflect.ValueOf(primitive.E{Key: key, Value: val.Interface()})) diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go index 08078b304d270..01ddbbb672156 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go @@ -104,7 +104,7 @@ func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) { RegisterDefaultEncoder(reflect.Map, defaultMapCodec). RegisterDefaultEncoder(reflect.Slice, defaultSliceCodec). RegisterDefaultEncoder(reflect.String, defaultStringCodec). - RegisterDefaultEncoder(reflect.Struct, defaultStructCodec). + RegisterDefaultEncoder(reflect.Struct, newDefaultStructCodec()). RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec()). RegisterHookEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)). RegisterHookEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)). @@ -150,8 +150,8 @@ func (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.Value } // UintEncodeValue is the ValueEncoderFunc for uint types. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use UIntCodec.EncodeValue instead. +// +// Deprecated: UintEncodeValue is not registered by default. Use UintCodec.EncodeValue instead. func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { switch val.Kind() { case reflect.Uint8, reflect.Uint16: @@ -185,8 +185,8 @@ func (dve DefaultValueEncoders) FloatEncodeValue(ec EncodeContext, vw bsonrw.Val } // StringEncodeValue is the ValueEncoderFunc for string types. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use StringCodec.EncodeValue instead. +// +// Deprecated: StringEncodeValue is not registered by default. Use StringCodec.EncodeValue instead. func (dve DefaultValueEncoders) StringEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { if val.Kind() != reflect.String { return ValueEncoderError{ @@ -245,19 +245,20 @@ func (dve DefaultValueEncoders) URLEncodeValue(ec EncodeContext, vw bsonrw.Value } // TimeEncodeValue is the ValueEncoderFunc for time.TIme. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use TimeCodec.EncodeValue instead. +// +// Deprecated: TimeEncodeValue is not registered by default. Use TimeCodec.EncodeValue instead. func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { if !val.IsValid() || val.Type() != tTime { return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val} } tt := val.Interface().(time.Time) - return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6)) + dt := primitive.NewDateTimeFromTime(tt) + return vw.WriteDateTime(int64(dt)) } // ByteSliceEncodeValue is the ValueEncoderFunc for []byte. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use ByteSliceCodec.EncodeValue instead. +// +// Deprecated: ByteSliceEncodeValue is not registered by default. Use ByteSliceCodec.EncodeValue instead. func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { if !val.IsValid() || val.Type() != tByteSlice { return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val} @@ -269,8 +270,8 @@ func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw } // MapEncodeValue is the ValueEncoderFunc for map[string]* types. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use MapCodec.EncodeValue instead. +// +// Deprecated: MapEncodeValue is not registered by default. Use MapCodec.EncodeValue instead. func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { if !val.IsValid() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String { return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} @@ -419,8 +420,8 @@ func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.Val } // SliceEncodeValue is the ValueEncoderFunc for slice types. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use SliceCodec.EncodeValue instead. +// +// Deprecated: SliceEncodeValue is not registered by default. Use SliceCodec.EncodeValue instead. func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { if !val.IsValid() || val.Kind() != reflect.Slice { return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} @@ -501,8 +502,8 @@ func (dve DefaultValueEncoders) lookupElementEncoder(ec EncodeContext, origEncod } // EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}. -// This method is deprecated and does not have any stability guarantees. It may be removed in the -// future. Use EmptyInterfaceCodec.EncodeValue instead. +// +// Deprecated: EmptyInterfaceEncodeValue is not registered by default. Use EmptyInterfaceCodec.EncodeValue instead. func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { if !val.IsValid() || val.Type() != tEmpty { return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go index 85ae9c6a19e97..d641960c10209 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go @@ -20,12 +20,29 @@ var defaultMapCodec = NewMapCodec() // MapCodec is the Codec used for map values. type MapCodec struct { - DecodeZerosMap bool - EncodeNilAsEmpty bool + DecodeZerosMap bool + EncodeNilAsEmpty bool + EncodeKeysWithStringer bool } var _ ValueCodec = &MapCodec{} +// KeyMarshaler is the interface implemented by an object that can marshal itself into a string key. +// This applies to types used as map keys and is similar to encoding.TextMarshaler. +type KeyMarshaler interface { + MarshalKey() (key string, err error) +} + +// KeyUnmarshaler is the interface implemented by an object that can unmarshal a string representation +// of itself. This applies to types used as map keys and is similar to encoding.TextUnmarshaler. +// +// UnmarshalKey must be able to decode the form generated by MarshalKey. +// UnmarshalKey must copy the text if it wishes to retain the text +// after returning. +type KeyUnmarshaler interface { + UnmarshalKey(key string) error +} + // NewMapCodec returns a MapCodec with options opts. func NewMapCodec(opts ...*bsonoptions.MapCodecOptions) *MapCodec { mapOpt := bsonoptions.MergeMapCodecOptions(opts...) @@ -37,6 +54,9 @@ func NewMapCodec(opts ...*bsonoptions.MapCodecOptions) *MapCodec { if mapOpt.EncodeNilAsEmpty != nil { codec.EncodeNilAsEmpty = *mapOpt.EncodeNilAsEmpty } + if mapOpt.EncodeKeysWithStringer != nil { + codec.EncodeKeysWithStringer = *mapOpt.EncodeKeysWithStringer + } return &codec } @@ -79,7 +99,11 @@ func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, v keys := val.MapKeys() for _, key := range keys { - keyStr := fmt.Sprint(key) + keyStr, err := mc.encodeKey(key) + if err != nil { + return err + } + if collisionFn != nil && collisionFn(keyStr) { return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key) } @@ -129,6 +153,9 @@ func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val ref case bsontype.Null: val.Set(reflect.Zero(val.Type())) return vr.ReadNull() + case bsontype.Undefined: + val.Set(reflect.Zero(val.Type())) + return vr.ReadUndefined() default: return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type()) } @@ -157,7 +184,6 @@ func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val ref } keyType := val.Type().Key() - keyKind := keyType.Kind() for { key, vr, err := dr.ReadElement() @@ -168,29 +194,15 @@ func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val ref return err } - k := reflect.ValueOf(key) - if keyType != tString { - switch keyKind { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, - reflect.Float32, reflect.Float64: - parsed, err := strconv.ParseFloat(k.String(), 64) - if err != nil { - return fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %v", keyKind, err) - } - k = reflect.ValueOf(parsed) - case reflect.String: // if keyType wraps string - default: - return fmt.Errorf("BSON map must have string or decimal keys. Got:%v", val.Type()) - } - - k = k.Convert(keyType) + k, err := mc.decodeKey(key, keyType) + if err != nil { + return err } elem := reflect.New(eType).Elem() err = decoder.DecodeValue(dc, vr, elem) if err != nil { - return err + return newDecodeError(key, err) } val.SetMapIndex(k, elem) @@ -204,3 +216,82 @@ func clearMap(m reflect.Value) { m.SetMapIndex(k, none) } } + +func (mc *MapCodec) encodeKey(val reflect.Value) (string, error) { + if mc.EncodeKeysWithStringer { + return fmt.Sprint(val), nil + } + + // keys of any string type are used directly + if val.Kind() == reflect.String { + return val.String(), nil + } + // KeyMarshalers are marshaled + if km, ok := val.Interface().(KeyMarshaler); ok { + if val.Kind() == reflect.Ptr && val.IsNil() { + return "", nil + } + buf, err := km.MarshalKey() + if err == nil { + return buf, nil + } + return "", err + } + + switch val.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(val.Int(), 10), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(val.Uint(), 10), nil + } + return "", fmt.Errorf("unsupported key type: %v", val.Type()) +} + +var keyUnmarshalerType = reflect.TypeOf((*KeyUnmarshaler)(nil)).Elem() + +func (mc *MapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value, error) { + keyVal := reflect.ValueOf(key) + var err error + switch { + // First, if EncodeKeysWithStringer is not enabled, try to decode withKeyUnmarshaler + case !mc.EncodeKeysWithStringer && reflect.PtrTo(keyType).Implements(keyUnmarshalerType): + keyVal = reflect.New(keyType) + v := keyVal.Interface().(KeyUnmarshaler) + err = v.UnmarshalKey(key) + keyVal = keyVal.Elem() + // Otherwise, go to type specific behavior + default: + switch keyType.Kind() { + case reflect.String: + keyVal = reflect.ValueOf(key).Convert(keyType) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + s := string(key) + n, parseErr := strconv.ParseInt(s, 10, 64) + if parseErr != nil || reflect.Zero(keyType).OverflowInt(n) { + err = fmt.Errorf("failed to unmarshal number key %v", s) + } + keyVal = reflect.ValueOf(n).Convert(keyType) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + s := string(key) + n, parseErr := strconv.ParseUint(s, 10, 64) + if parseErr != nil || reflect.Zero(keyType).OverflowUint(n) { + err = fmt.Errorf("failed to unmarshal number key %v", s) + break + } + keyVal = reflect.ValueOf(n).Convert(keyType) + case reflect.Float32, reflect.Float64: + if mc.EncodeKeysWithStringer { + parsed, err := strconv.ParseFloat(key, 64) + if err != nil { + return keyVal, fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %v", keyType.Kind(), err) + } + keyVal = reflect.ValueOf(parsed) + break + } + fallthrough + default: + return keyVal, fmt.Errorf("unsupported key type: %v", keyType) + } + } + return keyVal, err +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go index 0d9502f214a57..616a3e701b753 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go @@ -14,11 +14,6 @@ import ( "go.mongodb.org/mongo-driver/bson/bsontype" ) -var defaultPointerCodec = &PointerCodec{ - ecache: make(map[reflect.Type]ValueEncoder), - dcache: make(map[reflect.Type]ValueDecoder), -} - var _ ValueEncoder = &PointerCodec{} var _ ValueDecoder = &PointerCodec{} @@ -83,6 +78,10 @@ func (pc *PointerCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val val.Set(reflect.Zero(val.Type())) return vr.ReadNull() } + if vr.Type() == bsontype.Undefined { + val.Set(reflect.Zero(val.Type())) + return vr.ReadUndefined() + } if val.IsNil() { val.Set(reflect.New(val.Type().Elem())) diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go index 02b63bbe46f8e..60abffb248366 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go @@ -187,8 +187,9 @@ func (rb *RegistryBuilder) RegisterHookDecoder(t reflect.Type, dec ValueDecoder) return rb } -// RegisterEncoder has been deprecated and will be removed in a future major version release. Use RegisterTypeEncoder -// or RegisterHookEncoder instead. +// RegisterEncoder registers the provided type and encoder pair. +// +// Deprecated: Use RegisterTypeEncoder or RegisterHookEncoder instead. func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder { if t == tEmpty { rb.typeEncoders[t] = enc @@ -210,8 +211,9 @@ func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *Re return rb } -// RegisterDecoder has been deprecated and will be removed in a future major version release. Use RegisterTypeDecoder -// or RegisterHookDecoder instead. +// RegisterDecoder registers the provided type and decoder pair. +// +// Deprecated: Use RegisterTypeDecoder or RegisterHookDecoder instead. func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder { if t == nil { rb.typeDecoders[nil] = dec diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go index f0282eb23b8d0..3c1b6b860ae4f 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go @@ -123,6 +123,9 @@ func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val r case bsontype.Null: val.Set(reflect.Zero(val.Type())) return vr.ReadNull() + case bsontype.Undefined: + val.Set(reflect.Zero(val.Type())) + return vr.ReadUndefined() case bsontype.Type(0), bsontype.EmbeddedDocument: if val.Type().Elem() != tE { return fmt.Errorf("cannot decode document into %s", val.Type()) @@ -149,8 +152,8 @@ func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val r } return nil case bsontype.String: - if val.Type().Elem() != tByte { - return fmt.Errorf("SliceDecodeValue can only decode a string into a byte array, got %v", vrType) + if sliceType := val.Type().Elem(); sliceType != tByte { + return fmt.Errorf("SliceDecodeValue can only decode a string into a byte array, got %v", sliceType) } str, err := vr.ReadString() if err != nil { diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go index c672cf5a68691..910f2049a4876 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go @@ -85,6 +85,10 @@ func (sc *StringCodec) DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, va if err = vr.ReadNull(); err != nil { return err } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return err + } default: return fmt.Errorf("cannot decode %v into a string type", vr.Type()) } diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go index 777cdfb69584f..9ce901782f7ed 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "reflect" + "sort" "strings" "sync" "time" @@ -19,9 +20,35 @@ import ( "go.mongodb.org/mongo-driver/bson/bsontype" ) -var defaultStructCodec = &StructCodec{ - cache: make(map[reflect.Type]*structDescription), - parser: DefaultStructTagParser, +// DecodeError represents an error that occurs when unmarshalling BSON bytes into a native Go type. +type DecodeError struct { + keys []string + wrapped error +} + +// Unwrap returns the underlying error +func (de *DecodeError) Unwrap() error { + return de.wrapped +} + +// Error implements the error interface. +func (de *DecodeError) Error() string { + // The keys are stored in reverse order because the de.keys slice is builtup while propagating the error up the + // stack of BSON keys, so we call de.Keys(), which reverses them. + keyPath := strings.Join(de.Keys(), ".") + return fmt.Sprintf("error decoding key %s: %v", keyPath, de.wrapped) +} + +// Keys returns the BSON key path that caused an error as a slice of strings. The keys in the slice are in top-down +// order. For example, if the document being unmarshalled was {a: {b: {c: 1}}} and the value for c was supposed to be +// a string, the keys slice will be ["a", "b", "c"]. +func (de *DecodeError) Keys() []string { + reversedKeys := make([]string, 0, len(de.keys)) + for idx := len(de.keys) - 1; idx >= 0; idx-- { + reversedKeys = append(reversedKeys, de.keys[idx]) + } + + return reversedKeys } // Zeroer allows custom struct types to implement a report of zero @@ -33,13 +60,14 @@ type Zeroer interface { // StructCodec is the Codec used for struct values. type StructCodec struct { - cache map[reflect.Type]*structDescription - l sync.RWMutex - parser StructTagParser - DecodeZeroStruct bool - DecodeDeepZeroInline bool - EncodeOmitDefaultStruct bool - AllowUnexportedFields bool + cache map[reflect.Type]*structDescription + l sync.RWMutex + parser StructTagParser + DecodeZeroStruct bool + DecodeDeepZeroInline bool + EncodeOmitDefaultStruct bool + AllowUnexportedFields bool + OverwriteDuplicatedInlinedFields bool } var _ ValueEncoder = &StructCodec{} @@ -67,6 +95,9 @@ func NewStructCodec(p StructTagParser, opts ...*bsonoptions.StructCodecOptions) if structOpt.EncodeOmitDefaultStruct != nil { codec.EncodeOmitDefaultStruct = *structOpt.EncodeOmitDefaultStruct } + if structOpt.OverwriteDuplicatedInlinedFields != nil { + codec.OverwriteDuplicatedInlinedFields = *structOpt.OverwriteDuplicatedInlinedFields + } if structOpt.AllowUnexportedFields != nil { codec.AllowUnexportedFields = *structOpt.AllowUnexportedFields } @@ -166,6 +197,19 @@ func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val r return dw.WriteDocumentEnd() } +func newDecodeError(key string, original error) error { + de, ok := original.(*DecodeError) + if !ok { + return &DecodeError{ + keys: []string{key}, + wrapped: original, + } + } + + de.keys = append(de.keys, key) + return de +} + // DecodeValue implements the Codec interface. // By default, map types in val will not be cleared. If a map has existing key/value pairs, it will be extended with the new ones from vr. // For slices, the decoder will set the length of the slice to zero and append all elements. The underlying array will not be cleared. @@ -181,6 +225,13 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r return err } + val.Set(reflect.Zero(val.Type())) + return nil + case bsontype.Undefined: + if err := vr.ReadUndefined(); err != nil { + return err + } + val.Set(reflect.Zero(val.Type())) return nil default: @@ -267,7 +318,8 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r } if !field.CanSet() { // Being settable is a super set of being addressable. - return fmt.Errorf("cannot decode element '%s' into field %v; it is not settable", name, field) + innerErr := fmt.Errorf("field %v is not settable", field) + return newDecodeError(fd.name, innerErr) } if field.Kind() == reflect.Ptr && field.IsNil() { field.Set(reflect.New(field.Type().Elem())) @@ -276,19 +328,19 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r dctx := DecodeContext{Registry: r.Registry, Truncate: fd.truncate || r.Truncate} if fd.decoder == nil { - return ErrNoDecoder{Type: field.Elem().Type()} + return newDecodeError(fd.name, ErrNoDecoder{Type: field.Elem().Type()}) } if decoder, ok := fd.decoder.(ValueDecoder); ok { err = decoder.DecodeValue(dctx, vr, field.Elem()) if err != nil { - return err + return newDecodeError(fd.name, err) } continue } err = fd.decoder.DecodeValue(dctx, vr, field) if err != nil { - return err + return newDecodeError(fd.name, err) } } @@ -350,7 +402,8 @@ type structDescription struct { } type fieldDescription struct { - name string + name string // BSON key name + fieldName string // struct field name idx int omitEmpty bool minSize bool @@ -360,6 +413,35 @@ type fieldDescription struct { decoder ValueDecoder } +type byIndex []fieldDescription + +func (bi byIndex) Len() int { return len(bi) } + +func (bi byIndex) Swap(i, j int) { bi[i], bi[j] = bi[j], bi[i] } + +func (bi byIndex) Less(i, j int) bool { + // If a field is inlined, its index in the top level struct is stored at inline[0] + iIdx, jIdx := bi[i].idx, bi[j].idx + if len(bi[i].inline) > 0 { + iIdx = bi[i].inline[0] + } + if len(bi[j].inline) > 0 { + jIdx = bi[j].inline[0] + } + if iIdx != jIdx { + return iIdx < jIdx + } + for k, biik := range bi[i].inline { + if k >= len(bi[j].inline) { + return false + } + if biik != bi[j].inline[k] { + return biik < bi[j].inline[k] + } + } + return len(bi[i].inline) < len(bi[j].inline) +} + func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescription, error) { // We need to analyze the struct, including getting the tags, collecting // information about inlining, and create a map of the field name to the field. @@ -377,6 +459,7 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr inlineMap: -1, } + var fields []fieldDescription for i := 0; i < numFields; i++ { sf := t.Field(i) if sf.PkgPath != "" && (!sc.AllowUnexportedFields || !sf.Anonymous) { @@ -394,7 +477,12 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr decoder = nil } - description := fieldDescription{idx: i, encoder: encoder, decoder: decoder} + description := fieldDescription{ + fieldName: sf.Name, + idx: i, + encoder: encoder, + decoder: decoder, + } stags, err := sc.parser.ParseStructTags(sf) if err != nil { @@ -431,31 +519,62 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr return nil, err } for _, fd := range inlinesf.fl { - if _, exists := sd.fm[fd.name]; exists { - return nil, fmt.Errorf("(struct %s) duplicated key %s", t.String(), fd.name) - } if fd.inline == nil { fd.inline = []int{i, fd.idx} } else { fd.inline = append([]int{i}, fd.inline...) } - sd.fm[fd.name] = fd - sd.fl = append(sd.fl, fd) + fields = append(fields, fd) + } default: return nil, fmt.Errorf("(struct %s) inline fields must be a struct, a struct pointer, or a map", t.String()) } continue } + fields = append(fields, description) + } - if _, exists := sd.fm[description.name]; exists { - return nil, fmt.Errorf("struct %s) duplicated key %s", t.String(), description.name) + // Sort fieldDescriptions by name and use dominance rules to determine which should be added for each name + sort.Slice(fields, func(i, j int) bool { + x := fields + // sort field by name, breaking ties with depth, then + // breaking ties with index sequence. + if x[i].name != x[j].name { + return x[i].name < x[j].name + } + if len(x[i].inline) != len(x[j].inline) { + return len(x[i].inline) < len(x[j].inline) + } + return byIndex(x).Less(i, j) + }) + + for advance, i := 0, 0; i < len(fields); i += advance { + // One iteration per name. + // Find the sequence of fields with the name of this first field. + fi := fields[i] + name := fi.name + for advance = 1; i+advance < len(fields); advance++ { + fj := fields[i+advance] + if fj.name != name { + break + } } - - sd.fm[description.name] = description - sd.fl = append(sd.fl, description) + if advance == 1 { // Only one field with this name + sd.fl = append(sd.fl, fi) + sd.fm[name] = fi + continue + } + dominant, ok := dominantField(fields[i : i+advance]) + if !ok || !sc.OverwriteDuplicatedInlinedFields { + return nil, fmt.Errorf("struct %s) duplicated key %s", t.String(), name) + } + sd.fl = append(sd.fl, dominant) + sd.fm[name] = dominant } + sort.Sort(byIndex(sd.fl)) + sc.l.Lock() sc.cache[t] = sd sc.l.Unlock() @@ -463,6 +582,22 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr return sd, nil } +// dominantField looks through the fields, all of which are known to +// have the same name, to find the single field that dominates the +// others using Go's inlining rules. If there are multiple top-level +// fields, the boolean will be false: This condition is an error in Go +// and we skip all the fields. +func dominantField(fields []fieldDescription) (fieldDescription, bool) { + // The fields are sorted in increasing index-length order, then by presence of tag. + // That means that the first field is the dominant one. We need only check + // for error cases: two fields at top level. + if len(fields) > 1 && + len(fields[0].inline) == len(fields[1].inline) { + return fieldDescription{}, false + } + return fields[0], true +} + func fieldByIndexErr(v reflect.Value, index []int) (result reflect.Value, err error) { defer func() { if recovered := recover(); recovered != nil { diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go index 6f1b724d19b01..a7df44db70bf6 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go @@ -14,6 +14,7 @@ import ( "go.mongodb.org/mongo-driver/bson/bsonoptions" "go.mongodb.org/mongo-driver/bson/bsonrw" "go.mongodb.org/mongo-driver/bson/bsontype" + "go.mongodb.org/mongo-driver/bson/primitive" ) const ( @@ -80,6 +81,10 @@ func (tc *TimeCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val re if err := vr.ReadNull(); err != nil { return err } + case bsontype.Undefined: + if err := vr.ReadUndefined(); err != nil { + return err + } default: return fmt.Errorf("cannot decode %v into a time.Time", vrType) } @@ -97,5 +102,6 @@ func (tc *TimeCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val re return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val} } tt := val.Interface().(time.Time) - return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6)) + dt := primitive.NewDateTimeFromTime(tt) + return vw.WriteDateTime(int64(dt)) } diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go index e0df05837486b..3c991264d1161 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go @@ -112,6 +112,10 @@ func (uic *UIntCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val r if err = vr.ReadNull(); err != nil { return err } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return err + } default: return fmt.Errorf("cannot decode %v into an integer type", vrType) } diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go index 1ac3e20088a31..7a6a880b88a0b 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go @@ -10,6 +10,12 @@ package bsonoptions type MapCodecOptions struct { DecodeZerosMap *bool // Specifies if the map should be zeroed before decoding into it. Defaults to false. EncodeNilAsEmpty *bool // Specifies if a nil map should encode as an empty document instead of null. Defaults to false. + // Specifies how keys should be handled. If false, the behavior matches encoding/json, where the encoding key type must + // either be a string, an integer type, or implement bsoncodec.KeyMarshaler and the decoding key type must either be a + // string, an integer type, or implement bsoncodec.KeyUnmarshaler. If true, keys are encoded with fmt.Sprint() and the + // encoding key type must be a string, an integer type, or a float. If true, the use of Stringer will override + // TextMarshaler/TextUnmarshaler. Defaults to false. + EncodeKeysWithStringer *bool } // MapCodec creates a new *MapCodecOptions @@ -23,12 +29,22 @@ func (t *MapCodecOptions) SetDecodeZerosMap(b bool) *MapCodecOptions { return t } -// SetEncodeNilAsEmpty specifies if a nil map should encode as an empty document instead of null. Defaults to false. +// SetEncodeNilAsEmpty specifies if a nil map should encode as an empty document instead of null. Defaults to false. func (t *MapCodecOptions) SetEncodeNilAsEmpty(b bool) *MapCodecOptions { t.EncodeNilAsEmpty = &b return t } +// SetEncodeKeysWithStringer specifies how keys should be handled. If false, the behavior matches encoding/json, where the +// encoding key type must either be a string, an integer type, or implement bsoncodec.KeyMarshaler and the decoding key +// type must either be a string, an integer type, or implement bsoncodec.KeyUnmarshaler. If true, keys are encoded with +// fmt.Sprint() and the encoding key type must be a string, an integer type, or a float. If true, the use of Stringer +// will override TextMarshaler/TextUnmarshaler. Defaults to false. +func (t *MapCodecOptions) SetEncodeKeysWithStringer(b bool) *MapCodecOptions { + t.EncodeKeysWithStringer = &b + return t +} + // MergeMapCodecOptions combines the given *MapCodecOptions into a single *MapCodecOptions in a last one wins fashion. func MergeMapCodecOptions(opts ...*MapCodecOptions) *MapCodecOptions { s := MapCodec() @@ -42,6 +58,9 @@ func MergeMapCodecOptions(opts ...*MapCodecOptions) *MapCodecOptions { if opt.EncodeNilAsEmpty != nil { s.EncodeNilAsEmpty = opt.EncodeNilAsEmpty } + if opt.EncodeKeysWithStringer != nil { + s.EncodeKeysWithStringer = opt.EncodeKeysWithStringer + } } return s diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go index ad32c7c382429..78d1dd8668608 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go @@ -6,12 +6,15 @@ package bsonoptions +var defaultOverwriteDuplicatedInlinedFields = true + // StructCodecOptions represents all possible options for struct encoding and decoding. type StructCodecOptions struct { - DecodeZeroStruct *bool // Specifies if structs should be zeroed before decoding into them. Defaults to false. - DecodeDeepZeroInline *bool // Specifies if structs should be recursively zeroed when a inline value is decoded. Defaults to false. - EncodeOmitDefaultStruct *bool // Specifies if default structs should be considered empty by omitempty. Defaults to false. - AllowUnexportedFields *bool // Specifies if unexported fields should be marshaled/unmarshaled. Defaults to false. + DecodeZeroStruct *bool // Specifies if structs should be zeroed before decoding into them. Defaults to false. + DecodeDeepZeroInline *bool // Specifies if structs should be recursively zeroed when a inline value is decoded. Defaults to false. + EncodeOmitDefaultStruct *bool // Specifies if default structs should be considered empty by omitempty. Defaults to false. + AllowUnexportedFields *bool // Specifies if unexported fields should be marshaled/unmarshaled. Defaults to false. + OverwriteDuplicatedInlinedFields *bool // Specifies if fields in inlined structs can be overwritten by higher level struct fields with the same key. Defaults to true. } // StructCodec creates a new *StructCodecOptions @@ -38,6 +41,15 @@ func (t *StructCodecOptions) SetEncodeOmitDefaultStruct(b bool) *StructCodecOpti return t } +// SetOverwriteDuplicatedInlinedFields specifies if inlined struct fields can be overwritten by higher level struct fields with the +// same bson key. When true and decoding, values will be written to the outermost struct with a matching key, and when +// encoding, keys will have the value of the top-most matching field. When false, decoding and encoding will error if +// there are duplicate keys after the struct is inlined. Defaults to true. +func (t *StructCodecOptions) SetOverwriteDuplicatedInlinedFields(b bool) *StructCodecOptions { + t.OverwriteDuplicatedInlinedFields = &b + return t +} + // SetAllowUnexportedFields specifies if unexported fields should be marshaled/unmarshaled. Defaults to false. func (t *StructCodecOptions) SetAllowUnexportedFields(b bool) *StructCodecOptions { t.AllowUnexportedFields = &b @@ -46,7 +58,9 @@ func (t *StructCodecOptions) SetAllowUnexportedFields(b bool) *StructCodecOption // MergeStructCodecOptions combines the given *StructCodecOptions into a single *StructCodecOptions in a last one wins fashion. func MergeStructCodecOptions(opts ...*StructCodecOptions) *StructCodecOptions { - s := StructCodec() + s := &StructCodecOptions{ + OverwriteDuplicatedInlinedFields: &defaultOverwriteDuplicatedInlinedFields, + } for _, opt := range opts { if opt == nil { continue @@ -61,6 +75,9 @@ func MergeStructCodecOptions(opts ...*StructCodecOptions) *StructCodecOptions { if opt.EncodeOmitDefaultStruct != nil { s.EncodeOmitDefaultStruct = opt.EncodeOmitDefaultStruct } + if opt.OverwriteDuplicatedInlinedFields != nil { + s.OverwriteDuplicatedInlinedFields = opt.OverwriteDuplicatedInlinedFields + } if opt.AllowUnexportedFields != nil { s.AllowUnexportedFields = opt.AllowUnexportedFields } diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go index 7e9612c07434e..7bcf662135afc 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go @@ -217,7 +217,7 @@ func parseDatetimeString(data string) (int64, error) { return 0, fmt.Errorf("invalid $date value string: %s", data) } - return t.Unix()*1e3 + int64(t.Nanosecond())/1e6, nil + return int64(primitive.NewDateTimeFromTime(t)), nil } func parseDatetimeObject(data *extJSONObject) (d int64, err error) { diff --git a/vendor/go.mongodb.org/mongo-driver/bson/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/doc.go index 2943f14ecace1..5f411b6251fab 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/doc.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/doc.go @@ -53,7 +53,7 @@ // 16. BSON min key unmarshals to an primitive.MinKey. // 17. BSON max key unmarshals to an primitive.MaxKey. // 18. BSON undefined unmarshals to a primitive.Undefined. -// 19. BSON null unmarshals to a primitive.Null. +// 19. BSON null unmarshals to nil. // 20. BSON DBPointer unmarshals to a primitive.DBPointer. // 21. BSON symbol unmarshals to a primitive.Symbol. // @@ -67,13 +67,13 @@ // 5. uint8 and uint16 marshal to a BSON int32. // 6. uint, uint32, and uint64 marshal to a BSON int32 if the value is between math.MinInt32 and math.MaxInt32, // inclusive, and BSON int64 otherwise. -// 7. BSON null values will unmarshal into the zero value of a field (e.g. unmarshalling a BSON null value into a string -// will yield the empty string.). +// 7. BSON null and undefined values will unmarshal into the zero value of a field (e.g. unmarshalling a BSON null or +// undefined value into a string will yield the empty string.). // // Structs // -// Structs can be marshalled/unmarshalled to/from BSON. When transforming structs to/from BSON, the following rules -// apply: +// Structs can be marshalled/unmarshalled to/from BSON or Extended JSON. When transforming structs to/from BSON or Extended +// JSON, the following rules apply: // // 1. Only exported fields in structs will be marshalled or unmarshalled. // @@ -89,7 +89,10 @@ // 5. When unmarshalling, a field of type interface{} will follow the D/M type mappings listed above. BSON documents // unmarshalled into an interface{} field will be unmarshalled as a D. // -// The following struct tags can be used to configure behavior: +// The encoding of each struct field can be customized by the "bson" struct tag. +// The tag gives the name of the field, possibly followed by a comma-separated list of options. +// The name may be empty in order to specify options without overriding the default field name. The following options can be used +// to configure behavior: // // 1. omitempty: If the omitempty struct tag is specified on a field, the field will not be marshalled if it is set to // the zero value. By default, a struct field is only considered empty if the field's type implements the Zeroer @@ -110,9 +113,10 @@ // pulled up one level and will become top-level fields rather than being fields in a nested document. For example, if a // map field named "Map" with value map[string]interface{}{"foo": "bar"} is inlined, the resulting document will be // {"foo": "bar"} instead of {"map": {"foo": "bar"}}. There can only be one inlined map field in a struct. If there are -// duplicated fields in the resulting document when an inlined field is marshalled, an error will be returned. This tag -// can be used with fields that are pointers to structs. If an inlined pointer field is nil, it will not be marshalled. -// For fields that are not maps or structs, this tag is ignored. +// duplicated fields in the resulting document when an inlined struct is marshalled, the inlined field will be overwritten. +// If there are duplicated fields in the resulting document when an inlined map is marshalled, an error will be returned. +// This tag can be used with fields that are pointers to structs. If an inlined pointer field is nil, it will not be +// marshalled. For fields that are not maps or structs, this tag is ignored. // // Marshalling and Unmarshalling // diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go index bd0c5d161a559..fdd90d89c9fdd 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go @@ -206,6 +206,11 @@ func (d Decimal128) IsInf() int { return -1 } +// IsZero returns true if d is the empty Decimal128. +func (d Decimal128) IsZero() bool { + return d.h == 0 && d.l == 0 +} + func divmod(h, l uint64, div uint32) (qh, ql uint64, rem uint32) { div64 := uint64(div) a := h >> 32 diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go index 41d1cf28864c9..a0eb5378cbf0c 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go @@ -93,11 +93,18 @@ func (id ObjectID) MarshalJSON() ([]byte, error) { return json.Marshal(id.Hex()) } -// UnmarshalJSON populates the byte slice with the ObjectID. If the byte slice is 64 bytes long, it +// UnmarshalJSON populates the byte slice with the ObjectID. If the byte slice is 24 bytes long, it // will be populated with the hex representation of the ObjectID. If the byte slice is twelve bytes -// long, it will be populated with the BSON representation of the ObjectID. Otherwise, it will -// return an error. +// long, it will be populated with the BSON representation of the ObjectID. This method also accepts empty strings and +// decodes them as NilObjectID. For any other inputs, an error will be returned. func (id *ObjectID) UnmarshalJSON(b []byte) error { + // Ignore "null" to keep parity with the standard library. Decoding a JSON null into a non-pointer ObjectID field + // will leave the field unchanged. For pointer values, encoding/json will set the pointer to nil and will not + // enter the UnmarshalJSON hook. + if string(b) == "null" { + return nil + } + var err error switch len(b) { case 12: @@ -125,6 +132,12 @@ func (id *ObjectID) UnmarshalJSON(b []byte) error { } } + // An empty string is not a valid ObjectID, but we treat it as a special value that decodes as NilObjectID. + if len(str) == 0 { + copy(id[:], NilObjectID[:]) + return nil + } + if len(str) != 24 { return fmt.Errorf("cannot unmarshal into an ObjectID, the length must be 24 but it is %d", len(str)) } diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go index f47f8df3c84ec..5420496b5708f 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go @@ -40,11 +40,32 @@ type Undefined struct{} // DateTime represents the BSON datetime value. type DateTime int64 +var _ json.Marshaler = DateTime(0) +var _ json.Unmarshaler = (*DateTime)(nil) + // MarshalJSON marshal to time type func (d DateTime) MarshalJSON() ([]byte, error) { return json.Marshal(d.Time()) } +// UnmarshalJSON creates a primitive.DateTime from a JSON string. +func (d *DateTime) UnmarshalJSON(data []byte) error { + // Ignore "null" to keep parity with the time.Time type and the standard library. Decoding "null" into a non-pointer + // DateTime field will leave the field unchanged. For pointer values, the encoding/json will set the pointer to nil + // and will not defer to the UnmarshalJSON hook. + if string(data) == "null" { + return nil + } + + var tempTime time.Time + if err := json.Unmarshal(data, &tempTime); err != nil { + return err + } + + *d = NewDateTimeFromTime(tempTime) + return nil +} + // Time returns the date as a time type. func (d DateTime) Time() time.Time { return time.Unix(int64(d)/1000, int64(d)%1000*1000000) @@ -52,7 +73,7 @@ func (d DateTime) Time() time.Time { // NewDateTimeFromTime creates a new DateTime from a Time. func NewDateTimeFromTime(t time.Time) DateTime { - return DateTime(t.UnixNano() / 1000000) + return DateTime(t.Unix()*1e3 + int64(t.Nanosecond())/1e6) } // Null represents the BSON null value. diff --git a/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go b/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go index d59afcfe5458d..bd4c05039894f 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go @@ -104,7 +104,9 @@ func (rv RawValue) UnmarshalWithContext(dc *bsoncodec.DecodeContext, val interfa } func convertFromCoreValue(v bsoncore.Value) RawValue { return RawValue{Type: v.Type, Value: v.Data} } -func convertToCoreValue(v RawValue) bsoncore.Value { return bsoncore.Value{Type: v.Type, Data: v.Value} } +func convertToCoreValue(v RawValue) bsoncore.Value { + return bsoncore.Value{Type: v.Type, Data: v.Value} +} // Validate ensures the value is a valid BSON value. func (rv RawValue) Validate() error { return convertToCoreValue(rv).Validate() } @@ -176,7 +178,9 @@ func (rv RawValue) ObjectID() primitive.ObjectID { return convertToCoreValue(rv) // ObjectIDOK is the same as ObjectID, except it returns a boolean instead of // panicking. -func (rv RawValue) ObjectIDOK() (primitive.ObjectID, bool) { return convertToCoreValue(rv).ObjectIDOK() } +func (rv RawValue) ObjectIDOK() (primitive.ObjectID, bool) { + return convertToCoreValue(rv).ObjectIDOK() +} // Boolean returns the boolean value the Value represents. It panics if the // value is a BSON type other than boolean. @@ -214,7 +218,9 @@ func (rv RawValue) RegexOK() (pattern, options string, ok bool) { // DBPointer returns the BSON dbpointer value the Value represents. It panics if the value is a BSON // type other than DBPointer. -func (rv RawValue) DBPointer() (string, primitive.ObjectID) { return convertToCoreValue(rv).DBPointer() } +func (rv RawValue) DBPointer() (string, primitive.ObjectID) { + return convertToCoreValue(rv).DBPointer() +} // DBPointerOK is the same as DBPoitner, except that it returns a boolean // instead of panicking. diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go index 2a20d2e075c08..f7997fbbb7459 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go +++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go @@ -39,11 +39,14 @@ import ( // EmptyDocumentLength is the length of a document that has been started/ended but has no elements. const EmptyDocumentLength = 5 +// nullTerminator is a string version of the 0 byte that is appended at the end of cstrings. +const nullTerminator = string(byte(0)) + // AppendType will append t to dst and return the extended buffer. func AppendType(dst []byte, t bsontype.Type) []byte { return append(dst, byte(t)) } // AppendKey will append key to dst and return the extended buffer. -func AppendKey(dst []byte, key string) []byte { return append(dst, key+string(0x00)...) } +func AppendKey(dst []byte, key string) []byte { return append(dst, key+nullTerminator...) } // AppendHeader will append Type t and key to dst and return the extended // buffer. @@ -427,7 +430,7 @@ func AppendNullElement(dst []byte, key string) []byte { return AppendHeader(dst, // AppendRegex will append pattern and options to dst and return the extended buffer. func AppendRegex(dst []byte, pattern, options string) []byte { - return append(dst, pattern+string(0x00)+options+string(0x00)...) + return append(dst, pattern+nullTerminator+options+nullTerminator...) } // AppendRegexElement will append a BSON regex element using key, pattern, and diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go index 91932fd1bebce..d397cde2995de 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go +++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go @@ -181,7 +181,8 @@ func (d Document) LookupErr(key ...string) (Value, error) { if !ok { return Value{}, NewInsufficientBytesError(d, rem) } - if elem.Key() != key[0] { + // We use `KeyBytes` rather than `Key` to avoid a needless string alloc. + if string(elem.KeyBytes()) != key[0] { continue } if len(key) > 1 { diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go new file mode 100644 index 0000000000000..0112832400bdd --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go @@ -0,0 +1,50 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_openbsd.go + +package socket + +type iovec struct { + Base *byte + Len uint64 +} + +type msghdr struct { + Name *byte + Namelen uint32 + Iov *iovec + Iovlen uint32 + Control *byte + Controllen uint32 + Flags int32 +} + +type cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type sockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type sockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +const ( + sizeofIovec = 0x10 + sizeofMsghdr = 0x30 + + sizeofSockaddrInet = 0x10 + sizeofSockaddrInet6 = 0x1c +) diff --git a/vendor/golang.org/x/net/publicsuffix/table.go b/vendor/golang.org/x/net/publicsuffix/table.go index ec2bde8cb2134..31a034c5debd9 100644 --- a/vendor/golang.org/x/net/publicsuffix/table.go +++ b/vendor/golang.org/x/net/publicsuffix/table.go @@ -2,7 +2,7 @@ package publicsuffix -const version = "publicsuffix.org's public_suffix_list.dat, git revision bdbe9dfd268d040fc826766b1d4e27dc4416fe73 (2020-08-10T09:26:55Z)" +const version = "publicsuffix.org's public_suffix_list.dat, git revision f9f612a3386dd9a1e4a1892722e3418549520b49 (2020-11-30T21:55:23Z)" const ( nodesBitsChildren = 10 @@ -23,492 +23,499 @@ const ( ) // numTLD is the number of top level domains. -const numTLD = 1518 +const numTLD = 1513 // Text is the combined text of all labels. const text = "9guacuiababia-goracleaningroks-theatree12hpalermomahachijolstere" + - "trosnubalsfjorddnslivelanddnss3-ap-south-1kappchizip6116-b-datai" + - "ji234lima-cityeatselinogradult3l3p0rtatamotors3-ap-northeast-133" + - "7birkenesoddtangenovaranzaninohekinannestadivttasvuotnakamuratak" + - "ahamalselvendrellimitediyukuhashimojindianapolis-a-bloggerbirthp" + - "lacebjarkoyurihonjournalistjohninomiyakonojorpelandnpanamatta-va" + - "rjjatjeldsundrangedalimoliseminebjerkreimdbamblebesbyglandroverh" + - "alla-speziaustevollaziobihirosakikamijimatsuzakibigawagrocerybni" + - "keisenbahnatuurwetenschappenaumburgdyniabogadobeaemcloud66bjugni" + - "eznord-frontierblackfridayusuharabloombergbauernirasakindianmark" + - "etingjesdalinkyard-cloudyclusterbloxcms3-website-us-west-2blueda" + - "gestangeologyusuisservehumourbmoattachments5yuulmemorialivornoce" + - "anographiquebmsakyotanabellunord-aurdalpha-myqnapcloudaccesscamb" + - "ridgeiseiyoichippubetsubetsugarugbydgoszczecinemagentositechnolo" + - "gyuzawabmweddingjovikariyameinforumzjampagexlombardynaliaskimits" + - "ubatamibugattiffanycateringebuildingladefinimakanegasakirabnrwed" + - "eploybomloabathsbcatholicaxiashorokanaiebondray-dnstracebonnishi" + - "azaindielddanuorrindigenaklodzkodairabookinghostedpictethnologyb" + - "oomlair-traffic-controlleyboschaefflerdalomzaporizhzhegurindustr" + - "iabostikarlsoybostonakijinsekikogentappsselfipanasonichernihivgu" + - "bsalangenishigocelotenkawabotanicalgardenishiharabotanicgardenis" + - "hiizunazukindustriesteamsterdamnserverbaniabotanynysagaeroclubme" + - "decincinnationwidealerbouncemerckmsdnipropetrovskjervoyagets-itj" + - "maxxxboxenapponazure-mobilebounty-fullensakerrypropertiesalondon" + - "etskarmoyboutiquebechernivtsiciliabozen-sudtirolondrinamsskogane" + - "infinitintelligencebozen-suedtirolorenskoglassassinationalherita" + - "gebplacedogawarabikomaezakirunorddalottebrandywinevalleybrasilia" + - "brindisibenikinderoybristoloseyouriparachutingleezebritishcolumb" + - "ialowiezaganishikatakinouebroadcastlebtimnetzlglitchattanooganor" + - "dlandrayddnsfreebox-osascoli-picenordre-landraydnsupdaternopilaw" + - "atchesaltdalottokonamegatakazakinternationalfirearmsaludrivefsni" + - "llfjordrobaknoluoktachikawakuyabukievennodesadoes-itvedestrandru" + - "dupontariobranconakaniikawatanagurabroadwaybroke-itjomeloyalisto" + - "ragebrokerbronnoysundurbanamexhibitionishikatsuragit-reposalvado" + - "rdalibabalena-devicesalzburgliwicebrothermesaverdealstahaugesund" + - "erseaportsinfolldalouvreisenishikawazukamisunagawabrowsersafetym" + - "arketsamegawabrumunddalowiczest-le-patronishimerabrunelastxfinit" + - "ybrusselsamnangerbruxellesampalacebryansklepparaglidinglobalasho" + - "vhachinohedmarkarpaczeladzparisor-fronishinomiyashironocparliame" + - "ntjxjavald-aostarnbergloboavistanbulsan-sudtirolpusercontentkmax" + - "xn--0trq7p7nnishinoomotegoddabrynewhollandurhamburglogowegroweib" + - "olognagareyamakeupowiathletajimabaridagawalbrzycharitydalaskanit" + - "tedallasalleangaviikaascolipicenodumemsettsupportksatxn--11b4c3d" + - "ynathomebuiltwithdarkaruizawabuskerudinewjerseybuzentsujiiebuzzw" + - "eirbwellbeingzonebzhitomirumalatvuopmicrolightingloppenzaolbia-t" + - "empio-olbiatempioolbialystokkepnogatagajobojintuitmparmattelekom" + - "munikationishinoshimatsuurabzzcolumbusheycommunexus-2community-p" + - "rochowicecomoarekecomparemarkerryhotelsaobernardocompute-1comput" + - "erhistoryofscience-fictioncomsecuritytacticsxn--12cfi8ixb8luxury" + - "condoshichinohealth-carereformitakeharaconferenceconstructioncon" + - "suladonnagatorodoyconsultanthropologyconsultingrondarcontactozsd" + - "eltajirittogliattis-a-chefashioncontagematsubaracontemporaryarte" + - "ducationalchikugodontexistmein-iservebeercontractorskenconventur" + - "eshinodearthruherecipescaravantaacookingchannelsdvrdnsdojoburgro" + - "ngausdaluzerncoolvivanovoldacooperativano-frankivskolefrakkestad" + - "yndns1copenhagencyclopedichitosetogakushimotoganewspapercoproduc" + - "tionsaogoncartoonartdecologiacorporationcorsicagliaricoharuovatm" + - "allorcadaquesaotomeldalcorvettemasekashiwazakiyosemitecosenzakop" + - "anelblagrarchaeologyeongbuk0cosidnsfor-better-thanawassamukawata" + - "rikuzentakatajimidorissagamiharacostumedicinaharimalopolskanland" + - "ynnsapporocouchpotatofriesardegnaroycouklugsmilegallocus-3counci" + - "lcouponsardiniacozoracq-acranbrookuwanalyticsarlcrdynservebbsarp" + - "sborgrossetouchihayaakasakawaharacreditcardynulvikasserversaille" + - "sarufutsunomiyawakasaikaitakofuefukihaboromskogroundhandlingrozn" + - "ycreditunioncremonashgabadaddjaguarqcxn--12co0c3b4evalleaostavan" + - "gercrewiencricketrzyncrimeast-kazakhstanangercrotonecrownipartsa" + - "sayamacrsvpartycruisesasebofageometre-experts-comptablesaskatche" + - "wancryptonomichigangwoncuisinellajollamericanexpressexyculturalc" + - "entertainmentrani-andria-barletta-trani-andriacuneocupcakecuriti" + - "backyardsassaris-a-conservativegarsheis-a-cpadualstackhero-netwo" + - "rkinggroupasadenarashinocurvalled-aostaverncymrussiacyonabarumet" + - "lifeinsurancecyouthachiojiyaitakanezawafetsundyroyrvikingrpassag" + - "ensaudafguidegreefhvalerfidoomdnsiskinkyotobetsulikes-piedmontic" + - "ellodingenfieldfigueresinstaginguitarsavonarusawafilateliafilege" + - "ar-audnedalnfilegear-deatnunusualpersonfilegear-gbizfilegear-ief" + - "ilegear-jpmorganfilegear-sgujoinvilleitungsenfilminamiechizenfin" + - "alfinancefineartsaxofinlandfinnoyfirebaseappassenger-association" + - "firenetranoyfirenzefirestonefirmdalegoldpoint2thisamitsukefishin" + - "golffanschoenbrunnfitjarvodkafjordvalledaostargetmyiphostre-tote" + - "ndofinternet-dnschokokekschokoladenfitnessettlementransportefjal" + - "erflesbergulenflickragerogerscholarshipschoolschulezajskasuyanai" + - "zunzenflightschulserverflirfloginlinefloraflorencefloridatsunanj" + - "oetsuwanouchikujogaszkolancashirecreationfloripaderbornfloristan" + - "ohatakaharuslivinghistoryflorokunohealthcareerschwarzgwangjunipe" + - "rflowerschweizfltransurlflynnhosting-clusterfndfor-ourfor-somedi" + - "zinhistorischesciencecentersciencehistoryfor-theaterforexrothach" + - "irogatakaokalmykiaforgotdnscientistordalforli-cesena-forlicesena" + - "forlillehammerfeste-ipatriaforsaleikangerforsandasuologoipavianc" + - "arrdfortalfortmissoulancasterfortworthadanorthwesternmutualfosne" + - "scjohnsonfotaruis-a-democratrapaniizafoxfordebianfozfredrikstadt" + - "vscrapper-sitefreeddnsgeekgalaxyfreedesktopensocialfreemasonryfr" + - "eesitexaskoyabearalvahkikuchikuseikarugalsaceofreetlscrappingunm" + - "anxn--1ctwolominamatarnobrzegyptianfreiburguovdageaidnusrcfastly" + - "lbananarepublicaseihicampobassociatest-iservecounterstrikehimeji" + - "itatebayashijonawatempresashibetsukuiiyamanouchikuhokuryugasakit" + - "auraustinnaval-d-aosta-valleyokosukanumazuryokoteastcoastaldefen" + - "ceatonsbergivingjemnes3-eu-central-1freseniuscountryestateofdela" + - "wareggio-calabriafribourgushikamifuranorth-kazakhstanfriuli-v-gi" + - "uliafriuli-ve-giuliafriuli-vegiuliafriuli-venezia-giuliafriuli-v" + - "eneziagiuliafriuli-vgiuliafriuliv-giuliafriulive-giuliafriuliveg" + - "iuliafriulivenezia-giuliafriuliveneziagiuliafriulivgiuliafrlfrog" + - "anscrysechocolatelemarkarumaifarsundyndns-homednsamsungmodelling" + - "mxn--12c1fe0bradescotlandyndns-iparochernigovernmentoyotaparsand" + - "nessjoenishiokoppegardyndns-mailubindalublindesnesandoyfrognfrol" + - "andfrom-akrehamnfrom-alfrom-arfrom-azfrom-capetownnews-stagingwi" + - "ddleksvikaszubyfrom-coffeedbackplaneapplinzis-a-designerfrom-ctr" + - "avelchannelfrom-dchofunatoriginstitutelevisionthewifiatoyotomiya" + - "zakinuyamashinatsukigatakashimarnardalucaniafrom-dedyn-berlincol" + - "nfrom-flanderserveirchonanbulsan-suedtiroluccarbonia-iglesias-ca" + - "rboniaiglesiascarboniafrom-gaulardalfrom-hichisochildrensgardenf" + - "rom-iafrom-idfrom-ilfrom-in-brbar0emmafann-arboretumbriamallamac" + - "eiobbcg12038from-kserveminecraftravelersinsurancefrom-kyowariasa" + - "hikawawiiheyakumoduminamifuranofrom-lanciafrom-mamurogawafrom-md" + - "from-meeresistancefrom-mifunefrom-mnfrom-modalenfrom-mservemp3fr" + - "om-mtnfrom-nctulangevagrigentomologyeonggiehtavuoatnabudapest-a-" + - "la-masion-riopretobamaceratabuseating-organichoseiroumuenchenish" + - "itosashimizunaminamibosogndalucernefrom-ndfrom-nefrom-nh-servebl" + - "ogsiteleafamilycompanyanagawafflecellclaimservep2pfizerfrom-njaw" + - "orznoticiasnesoddenmarkhangelskjakdnepropetrovskiervaapsteiermar" + - "katowicefrom-nminamiiserniafrom-nvallee-aosteroyfrom-nyfrom-ohku" + - "rafrom-oketogurafrom-orfrom-padovaksdalfrom-pratohmandalfrom-ris" + - "-a-doctorayfrom-schmidtre-gauldalfrom-sdfrom-tnfrom-txn--1lqs03n" + - "from-utsiracusaikisarazurecontainerdpolicefrom-val-daostavalleyf" + - "rom-vtrdfrom-wafrom-wiardwebhostingxn--1lqs71dfrom-wvallee-d-aos" + - "teigenfrom-wyfrosinonefrostalowa-wolawafroyahooguyfstcgroupgfogg" + - "iafujiiderafujikawaguchikonefujiminokamoenairguardiannakadomarin" + - "ebraskauniversitychyattorneyagawakembuchikumagayagawakkanaibetsu" + - "bamericanfamilydsclouderackmazerbaijan-mayen-rootaribeiraogashim" + - "adachicagoboatservepicservequakefujinomiyadattowebcampinashikimi" + - "nohostfoldnavyfujiokayamangonohejis-a-financialadvisor-aurdalfuj" + - "isatoshonairlinedre-eikerfujisawafujishiroishidakabiratoridefens" + - "eljordfujitsurugashimangyshlakasamatsudopaasiafujixeroxn--1qqw23" + - "afujiyoshidavvenjargap-northeast-3fukayabeatservesarcasmatartand" + - "designfukuchiyamadavvesiidappnodebalancertificationfukudomigawaf" + - "ukuis-a-geekatsushikabeeldengeluidfukumitsubishigakishiwadazaifu" + - "daigojomedio-campidano-mediocampidanomediofukuokazakisofukushima" + - "niwakuratextileirfjordfukuroishikarikaturindalfukusakisosakitaga" + - "wafukuyamagatakahatakaishimoichinosekigaharafunabashiriuchinadaf" + - "unagatakamatsukawafunahashikamiamakusatsumasendaisennangooglecod" + - "espotrentin-sud-tirolfundaciofunkfeuerfuoiskujukuriyamannore-og-" + - "uvdalfuosskoczowildlifedorainfracloudfrontdoorfurnitureggio-emil" + - "ia-romagnakasatsunairportland-4-salernoboribetsuckservicesevasto" + - "polefurubirafurudonostiaafurukawairtelebitbridgestonekobayashiks" + - "hacknetcimbar1fusodegaurafussaintlouis-a-anarchistoireggiocalabr" + - "iafutabayamaguchinomihachimanagementrentin-sudtirolfutboldlygoin" + - "gnowhere-for-morenakatombetsumitakagiizefuttsurugimperiafuturecm" + - "sevenassisicilyfuturehostingfuturemailingfvgfyresdalhangoutsyste" + - "mscloudhannanmokuizumodenakayamapartmentsharpharmacienshawaiijim" + - "aritimoldeloittemp-dnshellaspeziahannosegawahanyuzenhapmircloudh" + - "arstadharvestcelebrationhasamarburghasaminami-alpshimokawahashba" + - "nghasudahasura-appharmacyshimokitayamahasvikatsuyamarugame-hosty" + - "hostinghatogayaizuwakamatsubushikusakadogawahatoyamazakitakamiiz" + - "umisanofidelityhatsukaichikaiseiheijis-a-landscaperugiahattfjell" + - "dalhayashimamotobungotakadancehazuminobusells-for-utwentehelsink" + - "itakatakarazukaluganskygearapphdfcbankaufenhembygdsforbundhemnes" + - "himonitayanagithubusercontentrentin-suedtirolhemsedalhepforgeher" + - "okusslattuminamiizukaminoyamaxunjargaheroyhgtvalleeaosteinkjerus" + - "alembroideryhidorahigashiagatsumagoianiahigashichichibunkyonanao" + - "shimageandsoundandvisionrenderhigashihiroshimanehigashiizumozaki" + - "takyushuaiahigashikagawahigashikagurasoedahigashikawakitaaikitam" + - "ihamadahigashikurumeetrentino-a-adigehigashimatsushimarcheapigee" + - "lvinckautokeinotteroyhigashimatsuyamakitaakitadaitoigawahigashim" + - "urayamamotorcycleshimonosekikawahigashinarusells-itrentino-aadig" + - "ehigashinehigashiomitamamurausukitamotosumy-gatewayhigashiosakas" + - "ayamanakakogawahigashishirakawamatakasagopocznorfolkebibleirvika" + - "zoologyhigashisumiyoshikawaminamiaikitanakagusukumodernhigashits" + - "unoshiroomurahigashiurawa-mazowszexnetrentino-alto-adigehigashiy" + - "amatokoriyamanashiibahccavuotnagaraholtaleniwaizumiotsukumiyamaz" + - "onawsmpplanetariuminamimakis-a-lawyerhigashiyodogawahigashiyoshi" + - "nogaris-a-liberalhiraizumisatohnoshoooshikamaishimofusartshimosu" + - "walkis-a-libertarianhirakatashinagawahiranairtrafficplexus-1hira" + - "rahiratsukagawahirayakagehistorichouseshimotsukehitachiomiyagild" + - "eskaliszhitachiotagotembaixadahitraeumtgeradelmenhorstalbanshimo" + - "tsumahjartdalhjelmelandholeckochikushinonsenergyholidayhomegoods" + - "hinichinanhomeiphiladelphiaareadmyblogspotrentino-altoadigehomel" + - "inkitoolsztynsettlershinjournalismailillesandefjordhomelinuxn--2" + - "m4a15ehomeofficehomesecuritymacaparecidahomesecuritypchoshibuyac" + - "htsandvikcoromantovalle-d-aostatic-accessanfranciscofreakunemuro" + - "rangehirnrtoyotsukaidohtawaramotoineppueblockbustermezhomesensee" + - "ringhomeunixn--2scrj9choyodobashichikashukujitawarahondahongotpa" + - "ntheonsitehonjyoitakasakitashiobarahornindalhorsellsyourhomeftph" + - "ilatelyhorteneis-a-linux-useranishiaritabashikaoirminamiminowaho" + - "spitalhoteleshinjukumanowtvalleedaostehotmailhoyangerhoylandetro" + - "itskypehumanitieshinkamigotoyohashimototalhurdalhurumajis-a-llam" + - "arriottrentino-s-tirolhyllestadhyogoris-a-musicianhyugawarahyund" + - "aiwafuneis-very-evillageis-very-goodyearis-very-niceis-very-swee" + - "tpepperis-with-thebandownloadisleofmanaustdaljetztrentino-sudtir" + - "oljevnakershuscultureggioemiliaromagnamsosnowiechristiansburgret" + - "akanabeautysvardoesntexisteingeekasaokamikoaniikappuboliviajessh" + - "eimpertrixcdn77-ssldyndns-office-on-the-weberjewelryjewishartgal" + - "leryjfkfhappoujgorajlljls-sto1jmphotographysiojnjcloudjiffylkesb" + - "iblackbaudcdn77-securebungoonord-odaljoyentrentino-sued-tiroljoy" + - "okaichibajddarchitecturealtorlandjpnjprshirakokamiminershiranuka" + - "mitsuejurkosakaerodromegallupinbarclaycards3-sa-east-1koseis-a-p" + - "ainteractivegaskvollkosherbrookegawakoshimizumakizunokunimimatak" + - "ayamarylandkoshunantankharkivanylvenicekosugekotohiradomainsureg" + - "ruhostingkotourakouhokutamakis-a-patsfankounosupplieshiraois-a-p" + - "ersonaltrainerkouyamashikekouzushimashikis-a-photographerokuapph" + - "ilipsynology-diskstationkozagawakozakis-a-playershifteditchyouri" + - "phoenixn--30rr7ykozowinbarclays3-us-east-2kpnkppspdnshiraokamoga" + - "wakrasnikahokutokashikis-a-republicancerresearchaeologicaliforni" + - "akrasnodarkredstonekristiansandcatshiratakahagitlaborkristiansun" + - "dkrodsheradkrokstadelvaldaostarostwodzislawindmillkryminamioguni" + - "5kumatorinokumejimasoykumenantokigawakunisakis-a-rockstarachowic" + - "ekunitachiarailwaykunitomigusukumamotoyamashikokuchuokunneppubtl" + - "shishikuis-a-socialistdlibestadkunstsammlungkunstunddesignkuokgr" + - "oupilotshisognekurehabmerkurgankurobelaudibleasingleshisuifuette" + - "rtdasnetzkurogiminamiashigarakuroisoftwarezzokuromatsunais-a-sox" + - "fankurotakikawasakis-a-studentalkushirogawakustanais-a-teacherka" + - "ssyno-dshinshinotsurgerykusupplynxn--3bst00minamisanrikubetsurfa" + - "uskedsmokorsetagayaseralingenoamishirasatogokasells-for-lessauhe" + - "radynv6kutchanelkutnokuzumakis-a-techietis-a-nascarfankvafjordkv" + - "alsundkvamfamberkeleykvanangenkvinesdalkvinnheradkviteseidatingk" + - "vitsoykwpspectruminamitanekzmishimatsumaebashimodatemissileluxem" + - "bourgmisugitokuyamatsumotofukemitourismolanxesshitaramamitoyoake" + - "miuramiyazurewebsiteshikagamiishibukawamiyotamanomjondalenmlbfan" + - "montrealestatefarmequipmentrentinoa-adigemonza-brianzapposhizuku" + - "ishimogosenmonza-e-della-brianzaptokyotangotsukitahatakamoriokak" + - "egawamonzabrianzaramonzaebrianzamonzaedellabrianzamoonscaleforce" + - "mordoviamoriyamatsunomoriyoshiminamiawajikis-an-actormormonsterm" + - "oroyamatsusakahoginankokubunjis-an-actresshintokushimamortgagemo" + - "scowindowskrakowinnershizuokanagawamoseushistorymosjoenmoskenesh" + - "oppingmosshopwarendalenugmosvikhersonmoteginowaniihamatamakawaji" + - "mansionshoujis-an-anarchistoricalsocietymoviemovimientolgamozill" + - "a-iotrentinoaadigemtranbymuenstermuginozawaonsenmuikamiokameokam" + - "akurazakiwakunigamiharumukoebenhavnmulhouseoullensvanguardmunaka" + - "tanemuncienciamuosattemupimientakkoelnmurmanskhmelnitskiyamarumo" + - "rimachidamurotorcraftrentinoalto-adigemusashimurayamatsushigemus" + - "ashinoharamuseetrentinoaltoadigemuseumverenigingmusicargodaddyn-" + - "vpndnshowamutsuzawamy-vigorgemy-wanggouvichristmaseratiresangomu" + - "tashinainvestmentsanjotoyouramyactivedirectorymyasustor-elvdalmy" + - "cdmydattolocalhistorymyddnskingmydissentrentinos-tirolmydobisshi" + - "kis-an-artistgorymydroboehringerikemydshowtimelhusdecorativearts" + - "hriramlidlugolekadenagahamaroygardendoftheinternetlifyis-an-engi" + - "neeringmyeffectrentinostirolmyfastly-terrariuminamiuonumasudamyf" + - "irewallonieruchomoscienceandindustrynmyforuminamiyamashirokawana" + - "belembetsukubankharkovaomyfritzmyftpaccesshwiosienarutomobellevu" + - "elosangelesjabbottrentinosud-tirolmyhome-servermyjinomykolaivare" + - "servehalflifestylemymailermymediapchromedicaltanissettaishinomak" + - "inkobeardubaiduckdnsannanishiwakinzais-a-candidatemyokohamamatsu" + - "damypepinkhmelnytskyivaporcloudmypetsigdalmyphotoshibalatinogift" + - "silkhplaystation-cloudmypicturesimple-urlmypsxn--3ds443gmysecuri" + - "tycamerakermyshopblocksirdalmythic-beastsjcbnpparibaselburgmytis" + - "-a-bookkeeperspectakasugais-an-entertainermytuleaprendemasakikon" + - "aikawachinaganoharamcoachampionshiphoptobishimadridvagsoyermyvnc" + - "hungnamdalseidfjordyndns-picsannohelplfinancialukowhalingrimstad" + - "yndns-remotewdyndns-serverisignissandiegomywirepaircraftingvollo" + - "mbardiamondslupsklabudhabikinokawabarthadselectrentin-sued-tirol" + - "platformshangrilapyplatter-appioneerplatterpippugliaplazaplcube-" + - "serverplumbingoplurinacionalpodhalevangerpodlasiellaktyubinskipt" + - "veterinaireadthedocscappgafannefrankfurtrentinosudtirolpodzonepo" + - "hlpoivronpokerpokrovsknx-serversicherungpoliticarrierpolitiendap" + - "olkowicepoltavalle-aostathellewismillerpomorzeszowitdkomaganepon" + - "pesaro-urbino-pesarourbinopesaromasvuotnaritakurashikis-bytomari" + - "timekeepingponypordenonepornporsangerporsangugeporsgrunnanyokosh" + - "ibahikariwanumatamayufuelveruminanopoznanpraxis-a-bruinsfanprdpr" + - "eservationpresidioprgmrprimelbourneprincipeprivatizehealthinsura" + - "nceprofesionalprogressivenneslaskerrylogisticsnoasakakinokiaprom" + - "ombetsurgeonshalloffameiwamassa-carrara-massacarraramassabusines" + - "sebykleclerchurcharternidyndns-webhareidsbergentingripepropertyp" + - "rotectionprotonetrentinosued-tirolprudentialpruszkowithgoogleapi" + - "szprvcyberlevagangaviikanonjis-certifieducatorahimeshimamateramo" + - "baraprzeworskogptplusgardenpulawypupittsburghofficialpvhagakhana" + - "migawapvtrentinosuedtirolpwcircustomer-ociprianiigataitogitsulda" + - "luroypzqhagebostadqldqponiatowadaqslingqualifioappiwatequickconn" + - "ectrentinsud-tirolquicksytestingquipelementsokananiimihoboleslaw" + - "iecistrondheimmobilienissayokkaichiropractichernovtsyncloudyndns" + - "-at-homedepotenzamamidsundyndns-at-workisboringlugmbhartipscbgmi" + - "nakamichiharaqvcitadeliveryggeesusonosuzakanazawasuzukaneyamazoe" + - "suzukis-into-animegurownprovidersvalbardunloppacificitichirurgie" + - "ns-dentistes-en-francesvcivilaviationissedalutskashibatakatsukiy" + - "osatokamachintaifun-dnsaliasanokashiharasveiosvelvikommunalforbu" + - "ndsvizzerasvn-reposolutionsokndalswidnicasacamdvrcampinagrandebu" + - "ilderschlesischesomaswidnikkokonoeswiebodzin-butterswiftcoverswi" + - "noujscienceandhistoryswissmarterthanyousynology-dsomnarviikamisa" + - "tokaizukameyamatotakadatuscanytushuissier-justicetuvalle-daostat" + - "icsor-varangertuxfamilytwmailvestre-slidreportrevisohughesoovest" + - "re-totennishiawakuravestvagoyvevelstadvibo-valentiavibovalentiav" + - "ideovillasorocabalestrandabergamo-siemensncfdvinnicasadelamoneda" + - "pliernewportlligatritonvinnytsiavipsinaappixolinovirginiavirtual" + - "-userveftpizzavirtualservervirtualuservegame-servervirtueeldomei" + - "n-vigorlicevirtuelvisakegawaviterboknowsitallvivolkenkundenvixn-" + - "-3hcrj9civilisationisshinguccircleverappsantabarbaravlaanderenvl" + - "adikavkazimierz-dolnyvladimirvlogintoyonezawavminiservervologdan" + - "skomonowruzhgorodeovolvolkswagentsorreisahayakawakamiichikawamis" + - "atottoris-foundationvolyngdalvoorloperauniterois-into-carshintom" + - "ikasaharavossevangenvotevotingvotoyonowmcloudwmflabsortlandwnext" + - "directrogstadworldworse-thandawowithyoutuberspacekitagatargitpag" + - "efrontappkmpspbar2wpdevcloudwpenginepoweredwritesthisblogsytewro" + - "clawiwatsukiyonotairestaurantroandinosaurepbodynamic-dnsopotrent" + - "insudtirolwtcminnesotaketaketomisatokorozawawtfbsbxn--1ck2e1banz" + - "aicloudcontrolledekagaminombresciaustraliajudaicable-modemocraci" + - "abruzzoologicalvinklein-addrammenuorochesterimo-i-rana4u2-localh" + - "ostrowiec66wuozuwzmiuwajimaxn--45q11civilwarmiaxn--4gbriminingxn" + - "--4it168dxn--4it797kongsbergxn--4pvxs4allxn--54b7fta0cclanbibaid" + - "armeniaxn--55qw42gxn--55qx5dxn--5js045dxn--5rtp49cldmailovecolle" + - "gefantasyleaguernseyxn--5rtq34kongsvingerxn--5su34j936bgsgxn--5t" + - "zm5gxn--6btw5axn--6frz82gxn--6orx2rxn--6qq986b3xlxn--7t0a264clic" + - "20001wwwhoswhokksundyndns-wikirkenesantacruzsantafedjejuifmetace" + - "ntrumeteorappartis-a-catererxn--80adxhksorumincomcastresindevice" + - "nzaporizhzhiaxn--80ao21axn--80aqecdr1axn--80asehdbarefootballoon" + - "ingjerdrumckinseyolasiteu-1xn--80aswgxn--80augustowloclawekomoro" + - "tsukaminokawanishiaizubangexn--8ltr62koninjambylxn--8pvr4uxn--8y" + - "0a063axn--90a3academiamicaaarborteaches-yogasawaracingxn--90aero" + - "portalabamagasakishimabaraogakibichuoxn--90aishobarakawagoexn--9" + - "0azhytomyravendbargainstantcloudfunctionswedenvironmentalconserv" + - "ationfabricafederationionjukudoyamaintenanceu-2xn--9dbhblg6digit" + - "alxn--9dbq2axn--9et52uxn--9krt00axn--andy-iraxn--aroport-byaotsu" + - "rreyxn--asky-iraxn--aurskog-hland-jnbarreauction-webhopenairbusa" + - "ntiquest-a-la-maisondre-landroidiscourses3-us-gov-west-1xn--aver" + - "y-yuasakuhokkaidovre-eikerxn--b-5gaxn--b4w605ferdxn--balsan-sdti" + - "rol-nsbsoundcastronomy-routerxn--bck1b9a5dre4clickashiwaraxn--bd" + - "ddj-mrabdxn--bearalvhki-y4axn--berlevg-jxaxn--bhcavuotna-s4axn--" + - "bhccavuotna-k7axn--bidr-5nachikatsuuraxn--bievt-0qa2xn--bjarky-f" + - "yasakaiminatoyookaniepcexn--bjddar-ptarumizusawaxn--blt-elabourx" + - "n--bmlo-graingerxn--bod-2natalxn--bozen-sdtirol-2obanazawaxn--br" + - "nny-wuacademy-firewall-gatewayxn--brnnysund-m8accident-investiga" + - "tion-aptibleadpagest-mon-blogueurovision-k3southcarolinarvikomat" + - "sushimarylhurstjordalshalsenxn--brum-voagatromsakataobaomoriguch" + - "iharahkkeravjuegoshikijobservableusercontentrentoyonakagyokutoya" + - "kolobrzegersundxn--btsfjord-9zaxn--bulsan-sdtirol-nsbarrel-of-kn" + - "owledgeapplicationcloudappspotagerevistaples3-us-west-1xn--c1avg" + - "xn--c2br7gxn--c3s14mintereitrentino-suedtirolxn--cck2b3barrell-o" + - "f-knowledgestack12xn--cckwcxetdxn--cesena-forl-mcbremangerxn--ce" + - "senaforl-i8axn--cg4bkis-into-cartoonshinyoshitomiokamitondabayas" + - "hiogamagoriziaxn--ciqpnxn--clchc0ea0b2g2a9gcdxn--comunicaes-v6a2" + - "oxn--correios-e-telecomunicaes-ghc29axn--czr694barsycenterprises" + - "akimobetsuitainaioirasebastopologyeongnamegawakayamagazineat-url" + - "illyombolzano-altoadigeorgeorgiaustrheimatunduhrennesoyokozebina" + - "gisoccertmgrazimutheworkpccwebredirectmembers3-eu-west-1xn--czrs" + - "0tromsojamisonxn--czru2dxn--czrw28barsyonlinewhampshirealtysnes3" + - "-us-west-2xn--d1acj3bashkiriauthordalandeportenrivnebinordreisa-" + - "hockeynutazuerichardlikescandyn53utilitiesquare7xn--d1alfaromeox" + - "n--d1atrusteexn--d5qv7z876clinichiryukyuragifuchungbukharavennag" + - "asakindlecznagasukexn--davvenjrga-y4axn--djrs72d6uyxn--djty4kons" + - "kowolayangroupiemontexn--dnna-grajewolterskluwerxn--drbak-wuaxn-" + - "-dyry-iraxn--e1a4cliniquenoharaxn--eckvdtc9dxn--efvn9southwestfa" + - "lenxn--efvy88haibarakitahiroshimaoris-a-greenxn--ehqz56nxn--elqq" + - "16hair-surveillancexn--eveni-0qa01gaxn--f6qx53axn--fct429konsula" + - "trobeepilepsykkylvenetodayxn--fhbeiarnxn--finny-yuaxn--fiq228c5h" + - "sowaxn--fiq64basicservercelliguriautomotiveconomiastagemological" + - "lyngenflfanquanpachigasakihokumakogenebakkeshibechambagriculture" + - "nnebudejjuedischesapeakebayernufcfanavigationavoizumizakibmdevel" + - "opmentatsunobiramusementdllpages3-ap-southeast-2ix4432-balsan-su" + - "edtirolkuszczytnoipirangamvik-serverrankoshigayachimataikikugawa" + - "lesundd-dnshome-webserverdal-o-g-i-n4tatarantours3-ap-northeast-" + - "2xn--fiqs8speedpartnersolarssonxn--fiqz9sphinxn--3e0b707exn--fjo" + - "rd-lraxn--fjq720axn--fl-ziaxn--flor-jraxn--flw351exn--forl-cesen" + - "a-fcbsspjelkavikomforbarcelonagawalmartattoolforgemreviewsaitosh" + - "imayfirstockholmestrandgcahcesuoloans3-fips-us-gov-west-1xn--for" + - "lcesena-c8axn--fpcrj9c3dxn--frde-grandrapidspreadbettingxn--frna" + - "-woaraisaijosoyrorospydebergxn--frya-hraxn--fzc2c9e2clintonoshoe" + - "santamariakexn--fzys8d69uvgmailxn--g2xx48clothingdustdataiwanair" + - "forcebetsuikidsmynasushiobaragusabaejrietisalatinabenonicbcn-nor" + - "th-1xn--gckr3f0fbx-ostrowwlkpmgruexn--gecrj9cn-northwest-1xn--gg" + - "aviika-8ya47hakatanortonxn--gildeskl-g0axn--givuotna-8yasugivest" + - "bytemarkonyvelolipoppdalxn--gjvik-wuaxn--gk3at1exn--gls-elacaixa" + - "xn--gmq050is-into-gamessinazawaxn--gmqw5axn--h-2failxn--h1aeghak" + - "odatexn--h2breg3evenesrlxn--h2brj9c8cngriwataraidyndns-workshopi" + - "tsitevadsobetsumidatlantichitachinakagawashtenawdev-myqnapcloude" + - "itysfjordyndns-blogdnsamsclubartowfarmsteadyndns-freeboxosloftoy" + - "osatoyokawaxn--h3cuzk1discountyxn--hbmer-xqaxn--hcesuolo-7ya35ba" + - "silicataniautoscanadaeguambulancechirealmpmnavuotnapleskns3-eu-w" + - "est-2xn--hery-iraxn--hgebostad-g3axn--hkkinen-5waxn--hmmrfeasta-" + - "s4accident-prevention-rancherkasydneyxn--hnefoss-q1axn--hobl-ira" + - "xn--holtlen-hxaxn--hpmir-xqaxn--hxt814exn--hyanger-q1axn--hyland" + - "et-54axn--i1b6b1a6a2exn--imr513nxn--indery-fyasuokanoyaltakatori" + - "s-leetrentino-stirolxn--io0a7is-lostrodawaraxn--j1aefbxosavannah" + - "gaxn--j1amhakonexn--j6w193gxn--jlq480n2rgxn--jlq61u9w7basketball" + - "finanzgoraveroykengerdalces3-eu-west-3xn--jlster-byatominamidait" + - "omanchesterxn--jrpeland-54axn--jvr189misakis-a-therapistoiaxn--k" + - "7yn95exn--karmy-yuaxn--kbrq7oxn--kcrx77d1x4axn--kfjord-iuaxn--kl" + - "bu-woaxn--klt787dxn--kltp7dxn--kltx9axn--klty5xn--3oq18vl8pn36ax" + - "n--koluokta-7ya57hakubahcavuotnagaivuotnagaokakyotambabyenglandx" + - "n--kprw13dxn--kpry57dxn--kput3is-not-certifiedugit-pagespeedmobi" + - "lizeroticanonoichinomiyakexn--krager-gyatsukanraxn--kranghke-b0a" + - "xn--krdsherad-m8axn--krehamn-dxaxn--krjohka-hwab49jdevcloudnshir" + - "ahamatonbetsurnadalxn--ksnes-uuaxn--kvfjord-nxaxn--kvitsy-fyatsu" + - "shiroxn--kvnangen-k0axn--l-1fairwindsrvarggatrentinsued-tirolxn-" + - "-l1accentureklamborghinikolaeventstoregontrailroadxn--laheadju-7" + - "yawaraxn--langevg-jxaxn--lcvr32dxn--ldingen-q1axn--leagaviika-52" + - "batochiokinoshimaizuruhrhcloudiscoveryomitanobninskaracoldwarsza" + - "wavocatanzarowebspacebizenakanojohanamakinoharaukraanghkeymachin" + - "eustargardds3-ca-central-1xn--lesund-huaxn--lgbbat1ad8jdfastvps-" + - "serveronakanotoddenxn--lgrd-poacctrvaroyxn--lhppi-xqaxn--linds-p" + - "ramericanartrycloudflareplantationxn--lns-qlaquilanstorfjordxn--" + - "loabt-0qaxn--lrdal-sraxn--lrenskog-54axn--lt-liacnpyatigorskodje" + - "ffersonxn--lten-granexn--lury-iraxn--m3ch0j3axn--mely-iraxn--mer" + - "ker-kuaxn--mgb2ddestorjcphonefosshioyandexcloudxn--mgb9awbfedora" + - "peoplegnicapebretonamicrosoftbankasukabedzin-berlindasdaburxn--m" + - "gba3a3ejtrysiljanxn--mgba3a4f16axn--mgba3a4franamizuholdingstpet" + - "ersburgxn--mgba7c0bbn0axn--mgbaakc7dvfedoraprojectraniandriabarl" + - "ettatraniandriaxn--mgbaam7a8hakuis-a-gurustkannamilanotogawaxn--" + - "mgbab2bdxn--mgbah1a3hjkrdxn--mgbai9a5eva00batsfjordishakotanayor" + - "ovigovtaxihuanfshostrolekamishihoronobeauxartsandcrafts3-website" + - "-ap-northeast-1xn--mgbai9azgqp6jelasticbeanstalkddietnedalxn--mg" + - "bayh7gpaleoxn--mgbbh1a71exn--mgbc0a9azcgxn--mgbca7dzdoxn--mgberp" + - "4a5d4a87gxn--mgberp4a5d4arxn--mgbgu82axn--mgbi4ecexposedxn--mgbp" + - "l2fhskydivingxn--mgbqly7c0a67fbcnsantoandreamhostersanukis-a-cel" + - "ticsfanxn--mgbqly7cvafranziskanerimaringatlantakahashimamakiryuo" + - "hdattorelayxn--mgbt3dhdxn--mgbtf8flatangerxn--mgbtx2bauhausposts" + - "-and-telecommunications3-website-ap-southeast-1xn--mgbx4cd0abbvi" + - "eeexn--mix082feiraquarelleaseeklogesaveincloudynvpnplus-4xn--mix" + - "891fermochizukirovogradoyxn--mjndalen-64axn--mk0axin-dslgbtuneso" + - "r-odalxn--mk1bu44cntoystre-slidrettozawaxn--mkru45is-savedunetfl" + - "ixilxn--mlatvuopmi-s4axn--mli-tlarvikooris-a-nursembokukitchenxn" + - "--mlselv-iuaxn--moreke-juaxn--mori-qsakuragawaxn--mosjen-eyawata" + - "hamaxn--mot-tlavagiskexn--mre-og-romsdal-qqbuserveexchangexn--ms" + - "y-ula0hakusanagochijiwadell-ogliastraderxn--mtta-vrjjat-k7aflaks" + - "tadaokagakicks-assnasaarlandxn--muost-0qaxn--mxtq1misasaguris-an" + - "-accountantshinshiroxn--ngbc5azdxn--ngbe9e0axn--ngbrxn--3pxu8kom" + - "vuxn--32vp30haebaruericssongdalenviknakatsugawaxn--nit225kopervi" + - "khakassiaxn--nmesjevuemie-tcbalsan-sudtirollagdenesnaaseinet-fre" + - "akstreamswatch-and-clockerxn--nnx388axn--nodessakurais-slickazun" + - "ow-dnshiojirishirifujiedaxn--nqv7fs00emaxn--nry-yla5gxn--ntso0iq" + - "x3axn--ntsq17gxn--nttery-byaeservehttplantslzxn--nvuotna-hwaxn--" + - "nyqy26axn--o1acheltenham-radio-opencraftrainingxn--o3cw4haldenxn" + - "--o3cyx2axn--od0algorithmiasakuchinotsuchiurakawaxn--od0aq3benev" + - "entoeidskoguchikuzenhktcp4xn--ogbpf8flekkefjordxn--oppegrd-ixaxn" + - "--ostery-fyaxn--osyro-wuaxn--otu796dxn--p1acferraraxn--p1ais-ube" + - "rleetrentino-sud-tirolxn--pgbs0dhlxn--porsgu-sta26ferraris-a-cub" + - "icle-slavellinodeobjectsaves-the-whalessandria-trani-barletta-an" + - "driatranibarlettaandriaxn--pssu33lxn--pssy2uxn--q9jyb4collection" + - "xn--qcka1pmcdirxn--qqqt11misawaxn--qxa6axn--qxamuneuestudioxn--r" + - "ady-iraxn--rdal-poaxn--rde-ulavangenxn--rdy-0nabaris-very-badajo" + - "zxn--rennesy-v1axn--rhkkervju-01aferrerotikagoshimalvikasumigaur" + - "ayasudaxn--rholt-mragowoodsidemonmouthalsaitamatsukuris-a-hard-w" + - "orkersewilliamhillxn--rhqv96gxn--rht27zxn--rht3dxn--rht61exn--ri" + - "sa-5nativeamericanantiquestudynamisches-dnsolognexn--risr-iraxn-" + - "-rland-uuaxn--rlingen-mxaxn--rmskog-byaxn--rny31hammarfeastafric" + - "apitalonewmexicodyn-o-saurlandesharis-a-hunterxn--rovu88bentleyo" + - "nagoyavoues3-external-1xn--rros-granvindafjordxn--rskog-uuaxn--r" + - "st-0naturalhistorymuseumcenterxn--rsta-francaiseharaxn--rvc1e0am" + - "3exn--ryken-vuaxn--ryrvik-byaxn--s-1faithamurakamigoris-a-knight" + - "pointtohobby-sitexn--s9brj9colognewyorkshirecifedexeterxn--sandn" + - "essjen-ogbeppublishproxyzgorzeleccogjerstadotsuruokakamigaharaxa" + - "urskog-holandinggfarmerseine164-baltimore-og-romsdalipayboltates" + - "hinanomachimkentateyamaetnaamesjevuemielno-ipifonyaarpalmasfjord" + - "enaturhistorisches3-ap-southeast-1xn--sandy-yuaxn--sdtirol-n2axn" + - "--seral-lraxn--ses554gxn--sgne-graphoxn--42c2d9axn--skierv-utaza" + - "stuff-4-salexn--skjervy-v1axn--skjk-soaxn--sknit-yqaxn--sknland-" + - "fxaxn--slat-5naturalsciencesnaturellestufftoread-booksnesolundbe" + - "ckomakiyosunndalxn--slt-elabcieszynxn--smla-hraxn--smna-gratange" + - "ntlentapisa-geekoryokamikawanehonbetsurutaharaxn--snase-nraxn--s" + - "ndre-land-0cbeskidyn-ip24xn--snes-poaxn--snsa-roaxn--sr-aurdal-l" + - "8axn--sr-fron-q1axn--sr-odal-q1axn--sr-varanger-ggbestbuyshouses" + - "3-website-ap-southeast-2xn--srfold-byaxn--srreisa-q1axn--srum-gr" + - "atis-a-bulls-fanxn--stfold-9xaxn--stjrdal-s1axn--stjrdalshalsen-" + - "sqbetainaboxfusejnymemergencyahabaghdadiskussionsbereichaseljeep" + - "sondriodejaneirockartuzyonagunicommbankaragandaxn--stre-toten-zc" + - "bhzcasertairaumalborkarasjohkamikitayamatsurin-the-bandain-vpnca" + - "sinordkappalmspringsakerxn--t60b56axn--tckweatherchannelxn--tiq4" + - "9xqyjelenia-goraxn--tjme-hraxn--tn0agrinetbankosaigawaxn--tnsber" + - "g-q1axn--tor131oxn--trany-yuaxn--trentin-sd-tirol-rzbieidsvollim" + - "anowarudaxn--trentin-sdtirol-7vbrplsbxn--45br5cylxn--trentino-sd" + - "-tirol-c3bielawaltervistaipeigersundisrechtranakaiwamizawatchand" + - "clockarasjokarasuyamarshallstatebankarateu-3xn--trentino-sdtirol" + - "-szbiellaakesvuemielecceu-4xn--trentinosd-tirol-rzbieszczadygeya" + - "chiyodaejeonbukcoalvdalaheadjudygarlandivtasvuodnakamagayahikobi" + - "erzycevje-og-hornnes3-website-eu-west-1xn--trentinosdtirol-7vbie" + - "vat-band-campaniaxn--trentinsd-tirol-6vbifukagawashingtondclkara" + - "tsuginamikatagamilitaryoriikareliancextraspace-to-rentalstomakom" + - "aibaraxn--trentinsdtirol-nsbigv-infoodnetworkangerxn--trgstad-r1" + - "axn--trna-woaxn--troms-zuaxn--tysvr-vraxn--uc0atvestfoldxn--uc0a" + - "y4axn--uist22handsonyoursidellogliastradingxn--uisz3gxn--unjrga-" + - "rtashkentunkommunexn--unup4yxn--uuwu58axn--vads-jraxn--valle-aos" + - "te-ebbturystykanmakiwielunnerxn--valle-d-aoste-ehbodollstuttgart" + - "rentinsuedtirolxn--valleaoste-e7axn--valledaoste-ebbvacationsusa" + - "kis-gonexn--vard-jraxn--vegrshei-c0axn--vermgensberater-ctbihoro" + - "logyoshiokanzakiyokawaraxn--vermgensberatung-pwbikedaemoneyukinc" + - "heonhlfanhs3-website-sa-east-1xn--vestvgy-ixa6oxn--vg-yiabkhazia" + - "xn--vgan-qoaxn--vgsy-qoa0jeonnamerikawauexn--vgu402colonialwilli" + - "amsburgroks-thisayamanobeokakudamatsuexn--vhquvestnesorfoldxn--v" + - "ler-qoaxn--vre-eiker-k8axn--vrggt-xqadxn--vry-yla5gxn--vuq861bil" + - "baokinawashirosatochigiessensiositecnologiaxn--w4r85el8fhu5dnrax" + - "n--w4rs40lxn--wcvs22dxn--wgbh1coloradoplateaudioxn--wgbl6axn--xh" + - "q521billustrationredumbrellahppiacenzachpomorskienikonanporovnob" + - "serverxn--xkc2al3hye2axn--xkc2dl3a5ee0hangglidingxn--y9a3aquariu" + - "misconfusedxn--yer-znaturbruksgymnxn--yfro4i67oxn--ygarden-p1axn" + - "--ygbi2ammxn--45brj9civilizationiyodogawaxn--ystre-slidre-ujbioc" + - "eanographics3-website-us-east-1xn--zbx025dxn--zf0ao64axn--zf0avx" + - "lxn--zfr164birdartcenterprisecloudcontrolappleborkdalwaysdatabas" + - "eballangenkainanaerobatickets3-website-us-west-1xnbayxz" + "trosnubalsfjordd-dnshome-webserverdal-o-g-i-n4tatsunobihirosakik" + + "amijimatsuuragrocerybnikeisenbahnaturhistorisches3-ap-south-1bip" + + "almasfjordenikonanporovnocpalmspringsakerbirdartcenterprisecloud" + + "accesscambridgeiseiyoichippubetsubetsugarussiabirkenesoddtangeno" + + "varahkkeravjuegoshikilatironrenderbirthplacevje-og-hornnes3-webs" + + "ite-us-west-1bjarkoyukuhashimojin-the-bandain-vpncateringebuildi" + + "ngladegreextraspace-to-rentalstomakomaibarabjerkreimbamblebesbyg" + + "landroverhalla-speziaustevollaziobiramswatch-and-clockereviewsai" + + "toshimattelekommunikationatuurwetenschappengine164-baltimore-og-" + + "romsdalp1bjugnieznord-odalwaysdatabaseballangenkainanaejrietisal" + + "atinabenonicatholicaxiaskimitsubatamibugattiffanyaaarborteaches-" + + "yogasawara-rugbydgoszczecinemaceratabuseating-organicbcieszynino" + + "hekinannestadiyurihonjournalistjohninomiyakonojorpelandnpanamats" + + "uzakincheonirasakindianapolis-a-bloggerblackfridayusuharabloombe" + + "rgbauernishiazaindianmarketinglassassinationalheritagebloxcms3-w" + + "ebsite-us-west-2bluedagestangemologicallyngenishigoddabmoattachm" + + "ents5yusuisservehttpanasonichernivtsiciliabmsakyotanabellunord-f" + + "rontierbmwedeployuulmemsettlersalangenishiharabnrwegroweibologna" + + "gareyamakeupowiatmallorcafederation-webhopencraftrainingleezebom" + + "loabathsbchernovtsyncloudrangedalondrinamsskoganeindielddanuorri" + + "ndigenaklodzkodairabondigitaloceanographicsxboxenishiizunazukind" + + "owapblogsiteleafamilycompany-2bonnishikataketomisatomobellevuelo" + + "sangelesjabbottjeldsundray-dnstracebookinghosted-by-previderboom" + + "lair-traffic-controlleyuzawaboschaefflerdalorenskoglitcheltenham" + + "-radio-opensocialottebostikariyameiwamarugame-hostedpictetjmaxxx" + + "finitybostonakijinsekikogentappsalon-1botanicalgardenishikatsura" + + "git-reposaltdalottokonamegatakayamassa-carrara-massacarraramassa" + + "businessebykleclerchirurgiens-dentistes-en-francebotanicgardenis" + + "hikawazukamishihoronobeauxartsandcraftsaludrayddnsfreebox-osasco" + + "li-picenordlandraydnsupdaterbotanychiryukyuragifuchungbukharauma" + + "lborkarlsoybouncemerckmsdnipropetrovskjervoyageorgeorgiabounty-f" + + "ullensakerrypropertiesalvadordalibabalena-devicesalzburgliwicebo" + + "utiquebechitachinakagawatchandclockarmoybozen-sudtirolouvrehabme" + + "rbozen-suedtirolowiczest-le-patronishimerabplaceducatorahimeshim" + + "amateraholtalenishinomiyashironohtawaramotoineppueblockbusternii" + + "minamiawajikindustriabrandywinevalleybrasiliabrindisibenikimobet" + + "suitaipeigersundrivefsnillfjordrobaknoluoktachikawafflecellcube-" + + "serverbristoloseyouriparachutinglobalashovhachinohedmarkarpaczel" + + "adzlgloboavistanbulsan-sudtirolpusercontentjomeloyalistoragebrit" + + "ishcolumbialowiezaganishinoomotegomniweatherchannelubindalublind" + + "esnesamegawabroadcastlebtimnetzparaglidinglogoweirbroadwaybroke-" + + "itvedestrandrudupontariobranconakaniikawatanagurabrokerbronnoysu" + + "ndurbanamexhibitionishinoshimatsushigebrothermesaverdeatnulvikar" + + "uizawabrowsersafetymarketsamnangerbrumunddalucaniabrunelastxjava" + + "ld-aostarnbergloppenzaolbia-tempio-olbiatempioolbialystokkembuch" + + "ikumagayagawakayamagentositecnologiabrusselsampalacebruxellesams" + + "clubartowellbeingzonebryansklepparisor-fronishiokoppegardurhambu" + + "rglugsjcbnpparibaselburgmbhartipsselfiparliamentjxn--0trq7p7nnis" + + "hitosashimizunaminamibosogndaluccargodaddyn-o-saurlandesamsungmi" + + "nakamichiharabrynewhollandynathomebuiltwithdarkarumaifarmsteadyn" + + "dns-at-homedepotenzamamidsundyndns-at-workisboringmodellingmxn--" + + "11b4c3dyndns-blogdnsandnessjoenishiwakindustriesteamfamberkeleyb" + + "uskerudyndns-freeboxoslocus-4buzentsujiiebuzzwesteuropenairbusan" + + "tiquest-a-la-maisondre-landroidyndns-homednsandoybwestfalenissan" + + "diegomurabzhitomirumalatvuopmicrolightingretakamoriokakudamatsue" + + "bzzcompute-1computerhistoryofscience-fictioncomsecaaskoyabearalv" + + "ahkijobservableusercontentoyotsukaidocondoshichinohealth-careref" + + "ormitakeharaconferenceconstructionconsuladoesntexisteingeekashiw" + + "araconsultanthropologyconsultingrongausdalcontactoyouracontagema" + + "tsubaracontemporaryarteducationalchikugodogadollsapporocontracto" + + "rskenconventureshinodeartheworkpccwhoswhokksundyndns1cookingchan" + + "nelsdvrdnsdojoburgrossetouchihayaakasakawaharacoolcooperativano-" + + "frankivskolefrakkestadynnsardegnaroycopenhagencyclopedichonanbul" + + "san-suedtirolukowestus2coproductionsardiniacorporationcorsicanon" + + "oichinomiyakecorvettemp-dnsarlcosenzakopanelastycoffeedbackplane" + + "applinzinzais-a-candidatecosidnsfor-better-thanawatchesarpsborgr" + + "oundhandlingroznynysaintlouis-a-anarchistoireggio-emilia-romagna" + + "katombetsumitakagiizecostumedicinagatorodoycouchpotatofriesarufu" + + "tsunomiyawakasaikaitabashikaoizumizakis-a-caterercoukashiwazakiy" + + "okawaracouncilcouponsasayamayfirstockholmestrandynservebbsasebof" + + "ageologycozoracqcxn--12co0c3b4evalleaostavangercranbrookuwanalyt" + + "icsaskatchewancrdynuniversitycreditcardynv6creditunioncremonashg" + + "abadaddjaguarqhachiojiyaizuwakamatsubushikusakadogawacrewiencric" + + "ketrzyncrimeast-kazakhstanangercrotonexus-3crownipartsassaris-a-" + + "celticsfancrsvps-hostrolekagoshimalopolskanlandynvpnpluscountrye" + + "stateofdelawareclaimsaudacruisesauheradyroyrvikingrpartycryptono" + + "michigangwoncuisinellajollamericanexpressexyculturalcentertainme" + + "ntoystre-slidrettozawacuneocupcakecuritibaghdadcurvalled-aostave" + + "rncymrunjargacyonabarumetacentrumeteorappasadenarashinocyouthruh" + + "erecifedexeterferrarivneferrerotikakamigaharafetsundfguidell-ogl" + + "iastraderfhskydivinguitarsavonarusawafhvalerfidontexistmein-iser" + + "vebeerfieldfigueresinstagingujoinvilleirvikasserversaillesaxofil" + + "ateliafilegear-audnedalnfilegear-debianfilegear-gbizfilegear-ief" + + "ilegear-jpmorganfilegear-sg-1filminamifuranofinalfinancefinearts" + + "choenbrunnfinlandfinnoyfirebaseappassagenschokokekschokoladenfir" + + "enetrani-andria-barletta-trani-andriafirenzefirestonefirmdalegni" + + "capetownnews-stagingulenfishingoldpoint2thisamitsukefitjarvodkaf" + + "jordvagsoygardenflfanquanpachigasakievennodesabaerobaticketschol" + + "arshipschoolsztynsettsurgeonshalloffameldalfitnessettlementrania" + + "ndriabarlettatraniandriafjalerflesbergunmansionschulezajskasukab" + + "edzin-berlindasdaburflickragerogerschulserverflightschwarzgwangj" + + "uifminamiiserniaflirfloginlinefloraflorencefloridatsunanjoetsuwa" + + "nouchikujogaszkolancashirecipescaravantaarpassenger-associationf" + + "loripaderbornfloristanohatajiris-a-chefashionflorokunohealthcare" + + "erschweizflowersciencecentersciencehistoryfltranoyflynnhosting-c" + + "lusterfndfnwkasumigaurayasudafoodnetworkdalfor-ourfor-somedizinh" + + "istorischescientistordalfor-theaterforexrothachirogatakanabeauty" + + "sfjordforgotdnscjohnsonforli-cesena-forlicesenaforlikescandyn53f" + + "orsalegolffanscrapper-siteforsandasuoloftranslatefortalfortextil" + + "eikangerfortmissoulancasterfortworthadanorth-kazakhstanfosnescra" + + "ppinguovdageaidnunusualpersonfotaruis-a-conservativegarsheis-a-c" + + "padualstackasuyanaizuerichardlillesandefjordfoxafozfrancaisehara" + + "franziskanerimaringatlantakahamalvikaszubyfredrikstadtvscrysecur" + + "itytacticservehumourfreeddnsgeekgalaxyfreedesktopocznordreisa-ho" + + "ckeynutazurestaticappspotagerfreemasonryfreesitefreetlserveircho" + + "shibuyahabackyardsangomutashinainfinitintelligencefreiburgushika" + + "mifuranorfolkebibleitungsenfreseniusculturecreationfribourgwiddl" + + "eksvikatowicefriuli-v-giuliafriuli-ve-giuliafriuli-vegiuliafriul" + + "i-venezia-giuliafriuli-veneziagiuliafriuli-vgiuliafriuliv-giulia" + + "friulive-giuliafriulivegiuliafriulivenezia-giuliafriuliveneziagi" + + "uliafriulivgiuliafrlfroganserveminecraftransportefrognfrolandfro" + + "m-akrehamnfrom-alfrom-arfrom-azurewebsiteshikagamiishibukawalbrz" + + "ycharternopilawalesundfrom-capitalonewjerseyfrom-cogxn--1ctwolom" + + "inamatargitlaborfrom-ctransurlfrom-dchoyodobashichikashukujitawa" + + "ravennagasakinderoyfrom-dedyn-berlincolnfrom-flanderservemp3from" + + "-gaulardalfrom-hichisochildrensgardenfrom-iafrom-idfrom-ilfrom-i" + + "n-brbar1from-kservep2patriafrom-kyowariasahikawafrom-lanciafrom-" + + "mamurogawafrom-mdfrom-meeresistancefrom-mifunefrom-mnfrom-modale" + + "nfrom-mservepicservequakefrom-mtnfrom-nctulangevagrigentomologye" + + "onggiehtavuoatnabudapest-a-la-masion-rancherkasydneyfrom-ndfrom-" + + "nefrom-nh-serveblogspotrapaniizafrom-njservesarcasmatartanddesig" + + "nfrom-nminamiizukaminoyamaxunispacefrom-nvalledaostaobaomoriguch" + + "iharag-cloud-charitychyattorneyagawakepnogatagajobojis-a-cubicle" + + "-slavellinodeobjectservicesevastopolefrom-nyminamimakis-a-democr" + + "atravelchannelfrom-ohdattorelayfrom-oketogurafrom-orfrom-padovak" + + "sdalfrom-pratohmandalfrom-ris-a-designerfrom-schmidtre-gauldalfr" + + "om-sdfrom-tnfrom-txn--1lqs03nfrom-utsiracusagamiharafrom-val-dao" + + "stavalleyfrom-vtravelersinsurancefrom-wafrom-wiardwebredirectmee" + + "trdfrom-wvallee-aosteroyfrom-wyfrosinonefrostalowa-wolawafroyait" + + "akaharunzenfstcgroupaviancarrierfujiiderafujikawaguchikonefujimi" + + "nokamoenairguardiannakadomarinebraskaunicommbankatsushikabeelden" + + "geluidvallee-d-aosteigenfujinomiyadattowebcampinashikiminohostfo" + + "ldnavyfujiokayamangonohejis-a-doctorayfujisatoshonairlinedre-eik" + + "erfujisawafujishiroishidakabiratoridefenseljordfujitsurugashiman" + + "gyshlakasamatsudoomdnsiskinkyotobetsumidatlantichristiansburgrim" + + "stadyndns-mailutskashibatakatorinternationalfirearmsanjotlon-2fu" + + "jixeroxfordefinimakanegasakinkobierzycefujiyoshidavvenjargap-nor" + + "theast-3fukayabeatsevenassisicilyfukuchiyamadavvesiidappnodebala" + + "ncertificationfukudomigawafukuis-a-financialadvisor-aurdalfukumi" + + "tsubishigakirovogradoyfukuokazakiryuohkurafukuroishikarikaturind" + + "alfukusakisarazure-mobileirfjordfukuyamagatakahashimamakishiwada" + + "zaifudaigojomedio-campidano-mediocampidanomediofunabashiriuchina" + + "dafunagatakahatakaishimoichinosekigaharafunahashikamiamakusatsum" + + "asendaisennangooglecodespotrendhostingfundaciofunkfeuerfuoiskuju" + + "kuriyamaniwakuratefuosskoczowiiheyakumoduminamiminowafurnituregg" + + "io-calabriafurubirafurudonostiaafurukawairportland-4-salernobori" + + "betsucksharis-a-geekatsuyamarumorimachidafusodegaurafussaikisofu" + + "kushimannore-og-uvdalfutabayamaguchinomihachimanagementrentin-su" + + "d-tirolfutboldlygoingnowhere-for-morenakasatsunairtelebitbridges" + + "toneendoftheinternethnologyfuttsurugimperiafuturecmsharpfizerfut" + + "urehostingfuturemailingfvgfyresdalhangglidinghangoutsystemscloud" + + "hannanmokuizumodenakayamanxn--1lqs71dhannortonhanyuzenhapmirclou" + + "dplatform0harstadharvestcelebrationhasamaoris-a-hunterhasaminami" + + "-alpshimokawahashbanghasudahasura-appgfoggiahasvikautokeinotogaw" + + "ahatoyamazakitahiroshimapartmentshimokitayamahatsukaichikaiseihe" + + "ijis-a-knightpointtohobby-sitehattfjelldalhayashimamotobungotaka" + + "dancehazuminobusells-for-ustkanmakiwakunigamiharutwentehelsinkit" + + "akamiizumisanofidelitysvardonnakamuratajimidorittogliattis-a-lan" + + "dscaperugiahembygdsforbundhemneshimonitayanagitappharmacienshimo" + + "nosekikawahemsedalhepforgeherokussldheroyhgtvalleeaosteinkjerusa" + + "lembroideryhidorahigashiagatsumagoianiahigashichichibunkyonanaos" + + "himageandsoundandvisionthewifiatrentin-sued-tirolhigashihiroshim" + + "anehigashiizumozakitakatakaokaluganskygearappharmacyshimosuwalki" + + "s-a-lawyerhigashikagawahigashikagurasoedahigashikawakitaaikitaky" + + "ushuaiahigashikurumegurownproviderhigashimatsushimarburghigashim" + + "atsuyamakitaakitadaitoigawahigashimurayamamotorcycleshimotsukehi" + + "gashinarusells-itrentin-suedtirolhigashinehigashiomitamamurausuk" + + "itamihamadahigashiosakasayamanakakogawahigashishirakawamatakaraz" + + "ukamakurazakitamotosumy-gatewayhigashisumiyoshikawaminamiaikitan" + + "akagusukumodernhigashitsunosegawahigashiurawa-mazowszexnetrentin" + + "o-a-adigehigashiyamatokoriyamanashiibahccavuotnagaragusadocktera" + + "mo-siemenscaledogawarabikomaezakirunoipirangalsacentralus-2higas" + + "hiyodogawahigashiyoshinogaris-a-liberalhiraizumisatohnoshoooshik" + + "amaishimofusartshimotsumahirakatashinagawahiranairtrafficplexus-" + + "1hirarahiratsukaeruhirayakagehistorichouseshinichinanhitachiomiy" + + "agildeskaliszhitachiotagoppdalhitraeumtgeradeloittenrissagaerocl" + + "ubmedecincinnationwidealstahaugesunderseaportsinfolionetworkange" + + "rhjartdalhjelmelandholeckochikushinonsenergyholidayhomegoodshinj" + + "ournalismailillehammerfeste-iphdfcbankazoologyhomeiphiladelphiaa" + + "readmyblogsytehomelinkyard-cloudnshinjukumanowruzhgorodeohomelin" + + "uxn--1qqw23ahomeofficehomesecuritymacaparecidahomesecuritypchris" + + "tmaseratiresannanisshingucciprianidyndns-office-on-the-weberhome" + + "senseeringhomeunixn--2m4a15ehondahongotembaixadahonjyoitakasagot" + + "pantheonsitehornindalhorsellsyourhomeftphilatelyhortendofinterne" + + "t-dnshinkamigototalhospitalhoteleshinshinotsurgeryhotmailhoyange" + + "rhoylandetroitskypehumanitieshinshirohurdalhurumajis-a-libertari" + + "anhyllestadhyogoris-a-linux-usershintokushimahyugawarahyundaiwaf" + + "uneis-very-badajozis-a-nursembokukitchenis-very-evillageis-very-" + + "goodyearis-very-niceis-very-sweetpepperis-with-thebandovre-eiker" + + "isleofmanaustdaljenv-arubabizjeonnamerikawauejetztrentino-stirol" + + "jevnakershusdecorativeartshiranukamitondabayashiogamagoriziajewe" + + "lryjewishartgalleryjfkddiamondshiraois-a-painterhostsolutionshin" + + "tomikasaharajgorajlljls-sto1jls-sto2jls-sto3jmphonefosshiraokami" + + "tsuejnjaworznotairestaurantrentino-s-tiroljoyentrentino-sud-tiro" + + "ljoyokaichibajddarchitecturealtorlandjpnjprshiratakahagithubuser" + + "contentrentino-sudtiroljurkosaigawakosakaerodromegallupinbarclay" + + "cards3-sa-east-1koseis-a-photographerokuapphilipsynology-disksta" + + "tionkosherbrookegawakoshimizumakiyosemitekoshunantankhakassiakos" + + "ugekotohiradomainsureggioemiliaromagnamsosnowiechurchaseljedugit" + + "-pagespeedmobilizeroticahcesuoloansanokashiharakotourakouhokutam" + + "akiyosunndalkounosupplieshitaramakouyamashikekouzushimashikizuno" + + "kunimilitarykozagawakozakis-a-playershifteditchyouriphoenixn--2s" + + "crj9chromedicaltanissettaishinomakindlecznagasukekozowildlifesty" + + "lekpnkppspdnshizukuishimogosenkrasnikahokutokashikis-a-republica" + + "ncerresearchaeologicaliforniakrasnodarkredstonekristiansandcatsh" + + "izuokamogawakristiansundkrodsheradkrokstadelvaldaostarostwodzisl" + + "awilliamhillkryminamioguni5kumatorinowtvaporcloudkumejimasoykume" + + "nantokigawakunisakis-a-rockstarachowicekunitachiarailwaykunitomi" + + "gusukumamotoyamashikokuchuokunneppubtlshoppingkunstsammlungkunst" + + "unddesignkuokgrouphxn--32vp30haebaruericssongdalenviknakatsugawa" + + "kuregruhostingkurgankurobelaudibleasingleshopwarendalenugkurogim" + + "imatakatsukis-a-socialistdlibestadkuroisoftwarezzokuromatsunais-" + + "a-soxfankurotakikawasakis-a-studentalkushirogawakustanais-a-teac" + + "herkassyno-dshinyoshitomiokamisunagawakusupplynxn--3bst00minamis" + + "anrikubetsupportrentino-sued-tirolkutchanelveruminamitanekutnoku" + + "zumakis-a-techietis-a-llamarnardalkvafjordkvalsundkvamlidlugolek" + + "adenagahamaroyerkvanangenkvinesdalkvinnheradkviteseidatingkvitso" + + "ykwpspectruminamiuonumassivegridkzmisconfusedmishimasudamissilel" + + "uxembourgmisugitokorozawamitourismilevangermitoyoakemiuramiyazur" + + "econtainerdpolicemiyotamanomjondalenmlbfanmontrealestatefarmequi" + + "pmentrentino-suedtirolmonza-brianzapposhoujis-an-actresshioyande" + + "xcloudmonza-e-della-brianzaptokuyamatsumaebashimodatemonzabrianz" + + "aramonzaebrianzamonzaedellabrianzamoonscaleforcemordoviamoriyama" + + "tsumotofukemoriyoshiminamiashigaramormonstermoroyamatsunomortgag" + + "emoscowinbarclays3-us-east-2moseushistorymosjoenmoskeneshowamoss" + + "howtimelhusgardenmosvikharkovanylvenicemoteginowaniigatakamatsuk" + + "awamoviemovimientokyotangotsukisosakitagawamozilla-iotrentinoa-a" + + "digemtranbymuginozawaonsenmuikamiokameokameyamatotakadamukoebenh" + + "avnmulhouseoullensvanguardmunakatanemuncienciamuosattemupiemonte" + + "murmanskhersonmurotorcraftrentinoaadigemusashimurayamatsusakahog" + + "inankokubunjis-an-anarchistoricalsocietymusashinoharamuseetrenti" + + "noalto-adigemuseumverenigingmusicarrdmutsuzawamy-vigorgemy-wangg" + + "ouvicircustomer-ocimdbananarepublic66myactivedirectorymyasustor-" + + "elvdalmycdn77-sslattuminamiyamashirokawanabelembetsukubankharkiv" + + "alleedaostemycloudswitcheshwindmillmydattolocalhistorymyddnsking" + + "mydissentrentinoaltoadigemydobisshikis-an-artistgorymydroboehrin" + + "gerikemydsienarutolgamyeffectrentinos-tirolmyfastblogermyfirewal" + + "lonieruchomoscienceandindustrynmyforuminanomyfritzmyftpaccessigd" + + "almyhome-servermyjinomykolaivareservegame-servermymailermymediap" + + "cistrondheimmobilieniyodogawamyokohamamatsudamypepilotsilkhmelni" + + "tskiyamarylandmypetsimple-urlmyphotoshibalatinombresciamypicture" + + "sirdalmypsxn--3ds443gmysecuritycamerakermyshopblockslupskhmelnyt" + + "skyivaomythic-beastslzmytis-a-bookkeeperspectakashimaritimoldelt" + + "aiwanairforcebetsuikidsmynasushiobarackmazerbaijan-mayen-rootari" + + "beiraogashimadachicagoboatsmolapymntrentinostirolmytuleaprendema" + + "sakihokumakogenebakkeshibechambagriculturennebudejjuedischesapea" + + "kebayernrtrentinosud-tirolmyvncitadeliverydyndns-remotewdyndns-s" + + "erverisignmywireitrentinosudtirolpklabudhabikinokawabarthadselec" + + "trentin-sudtirolplantsnoasakakinokiaplatformshangrilanxessokanag" + + "awaplatter-appimientakinoueplatterpinkhplaystation-cloudplazaplc" + + "itichocolatelevisionissayokkaichiropractichitosetogakushimotogan" + + "ewportkmaxxn--12c1fe0bradescotlandyndns-iparmatta-varjjatksatxn-" + + "-12cfi8ixb8lucerneplumbingoplurinacionalpodhaleviracloudletsoknd" + + "alpodlasiellaktyubinskiptveterinaireadthedocscappgafannefrankfur" + + "trentinosued-tirolpodzonepohlpoivronpokerpokrovskmpspbar2politic" + + "artoonartdecologiapolitiendapolkowicepoltavalle-aostathellewismi" + + "llerpomorzeszowindowskrakowinnersolarssonponpesaro-urbino-pesaro" + + "urbinopesaromasvuotnaritakoelnponypordenonepornporsangerporsangu" + + "geporsgrunnanyokoshibahikariwanumatakkofuefukihaboromskogpoznanp" + + "raxis-a-bruinsfanprdpreservationpresidioprgmrprimetelemarknx-ser" + + "versicherungprincipeprivatizehealthinsuranceprofesionalprogressi" + + "venneslaskerrylogisticsolognepromombetsurfastvps-serveronakanoto" + + "ddenpropertyprotectionprotonetrentinosuedtirolprudentialpruszkow" + + "iosolundbeckomaganeprvcyberlevagangaviikanonjis-an-engineeringpr" + + "zeworskogpulawypupioneerpvhagakhanamigawapvtrentinsud-tirolpwciv" + + "ilaviationpzqldqotoyohashimotoolsomaqponiatowadaqslingqualifioap" + + "pippugliaquickconnectrentinsudtirolquicksytestingquipelementsomn" + + "arviikamisatokaizukamikitayamatsuris-an-entertainerqvcivilisatio" + + "nsveiosvelvikomforbarcelonagawalmartattoolforgebinagisoccertmgra" + + "zimuthatogayachimataiji234lima-cityeatselinogradultateshinanomac" + + "himkentateyamaetnaamesjevuemielno-ipifony-1svizzerasvn-reposor-v" + + "arangerswidnicasadelamonedapliernewmexicodyn-vpndnsorfoldswidnik" + + "kokonoeswiebodzin-butterswiftcoverswinoujscienceandhistoryswissm" + + "arterthanyousynology-dsorocabalestrandabergamoareketunkommunalfo" + + "rbundturystykaniepcetuscanytushuissier-justicetuvalle-daostatics" + + "oundcastronomy-routertuxfamilytwmailvestre-slidreplantationvestr" + + "e-totennishiawakuravestvagoyvevelstadvibo-valentiavibovalentiavi" + + "deovillasouthwest1-uslivinghistoryvinnicaseihicampobassociatest-" + + "iservecounterstrikevinnytsiavipsinaappittsburghofficialvirginiav" + + "irtual-userveexchangevirtualcloudvirtualservervirtualuserveftpiw" + + "atevirtueeldomein-vigorlicevirtuelvisakegawaviterboknowsitallviv" + + "olkenkundenvixn--3hcrj9clanbibaidarmeniavlaanderenvladikavkazimi" + + "erz-dolnyvladimirvlogintoyonezawavminiservervologdanskommunevolv" + + "olkswagentsowavolyngdalvoorloperauniterois-gonevossevangenvotevo" + + "tingvotoyonowiwatsukiyonoshiroomgwloclawekomorotsukagawawmcloudw" + + "mflabspeedpartnersoownextdirectrevisohughesorreisahayakawakamiic" + + "hikawamisatottoris-bytomaritimekeepingworldworse-thandawowitdkom" + + "onow-dnshisognewpdevcloudwpenginepoweredwritesthisblogwroclawith" + + "googleapiszwtcircleverappsphinxn--3e0b707ewtfauskedsmokorsetagay" + + "aseralingenoamishirasatogokasells-for-lessavannahgawuozuwzmiuwaj" + + "imaxn--45q11clic20001wwwfarsundyndns-webhareidsbergentingripexn-" + + "-4gbriminingxn--4it168dxn--4it797kongsbergxn--4pvxs4allxn--54b7f" + + "ta0cclicketcloudcontrolapplicationcloud66xn--55qw42gxn--55qx5dxn" + + "--5js045dxn--5rtp49clinichofunatoriginstitutemasekasaokamiminers" + + "andvikcoromantovalle-d-aostatic-accessanfranciscofreakunemuroran" + + "gecloudyclusterxn--5rtq34kongsvingerxn--5su34j936bgsgxn--5tzm5gx" + + "n--6btw5axn--6frz82gxn--6orx2rxn--6qq986b3xlxn--7t0a264cliniquen" + + "oharaxn--80adxhkspjelkavikomatsushimarylhurstjordalshalsenxn--80" + + "ao21axn--80aqecdr1axn--80asehdbarefootballooningjerdrumckinseyol" + + "asitebinordre-landiscoveryggeebizenakanojohanamakinoharaustinnau" + + "mburggfarmerseineastasiamuneues3-ap-southeast-2ix4432-balsan-sue" + + "dtirolkuszczytnord-aurdalipayboltatarantours3-ap-northeast-2xn--" + + "80aswgxn--80augustowithyoutuberspacekitagatargetmyiphosteurxn--8" + + "ltr62koninjambylxn--8pvr4uxn--8y0a063axn--90a3academiamicable-mo" + + "democraciaxn--90aeroportalabamagasakishimabaraogakibichuoxn--90a" + + "ishobarakawagoexn--90azhytomyravendbargainstantcloudfunctionsncf" + + "dishakotanavigationavoirmcpehimejibigawaustraliamusementdllpages" + + "3-ca-central-1xn--9dbhblg6dietritonxn--9dbq2axn--9et52uxn--9krt0" + + "0axn--andy-iraxn--aroport-byaotsurreyxn--asky-iraxn--aurskog-hla" + + "nd-jnbarreauctionfabricagliaricoharuhrxn--avery-yuasakuhokkaidop" + + "aaskvollxn--b-5gaxn--b4w605ferdxn--balsan-sdtirol-nsbspreadbetti" + + "ngxn--bck1b9a5dre4clintonoshoesantabarbaraxn--bdddj-mrabdxn--bea" + + "ralvhki-y4axn--berlevg-jxaxn--bhcavuotna-s4axn--bhccavuotna-k7ax" + + "n--bidr-5nachikatsuuraxn--bievt-0qa2xn--bjarky-fyasakaiminatoyoo" + + "kaneyamazoexn--bjddar-ptarnobrzegyptianxn--blt-elabourxn--bmlo-g" + + "raingerxn--bod-2natalxn--bozen-sdtirol-2obanazawaxn--brnny-wuaca" + + "demy-firewall-gatewayxn--brnnysund-m8accident-investigation-apti" + + "bleadpagesquare7xn--brum-voagatroandinosaurepaircraftingvollomba" + + "rdiademonmouthagebostadxn--btsfjord-9zaxn--bulsan-sdtirol-nsbarr" + + "el-of-knowledgeappleborkaracoldwarszawaustrheimatunduhrennesoyok" + + "osukanraukraanghkeymachineustargardds3-eu-central-1xn--c1avgxn--" + + "c2br7gxn--c3s14minnesotaketakazakis-a-therapistoiaxn--cck2b3barr" + + "ell-of-knowledgehirnufcfanavuotnapleskns3-us-gov-west-1xn--cckwc" + + "xetdxn--cesena-forl-mcbremangerxn--cesenaforl-i8axn--cg4bkis-int" + + "o-animeinforumzxn--ciqpnxn--clchc0ea0b2g2a9gcdxn--comunicaes-v6a" + + "2oxn--correios-e-telecomunicaes-ghc29axn--czr694barsycenterprise" + + "sakikuchikuseikarugamvik-serverrankoshigayachiyodaejeonbukcoalph" + + "a-myqnapcloud-fr1xn--czrs0trogstadxn--czru2dxn--czrw28barsyonlin" + + "ewhampshirealtydalvdalaskanittedallasalleangaviikaascolipicenodu" + + "members3-us-west-1xn--d1acj3bashkiriauthordalandgcapebretonamicr" + + "osoftbank12xn--d1alfaromeoxn--d1atromsakatamayufuelblagrarchaeol" + + "ogyeongbuk0xn--d5qv7z876clothingdustdataitogitsuldalvivanovoldax" + + "n--davvenjrga-y4axn--djrs72d6uyxn--djty4konskowolayangrouphotogr" + + "aphysioxn--dnna-grajewolterskluwerxn--drbak-wuaxn--dyry-iraxn--e" + + "1a4cn-northwest-1xn--eckvdtc9dxn--efvn9spydebergxn--efvy88haibar" + + "akitahatakanezawaxn--ehqz56nxn--elqq16hair-surveillancexn--eveni" + + "-0qa01gaxn--f6qx53axn--fct429konsulatrobeepilepsykkylvenetodayxn" + + "--fhbeiarnxn--finny-yuaxn--fiq228c5hsrlxn--fiq64basicservercelli" + + "guriautomotiveconomiasakuchinotsuchiurakawakuyabukikonaikawachin" + + "aganoharamcoachampionshiphoptobamadridnbloggerevistaples3-eu-wes" + + "t-1xn--fiqs8srvarggatrentinsuedtirolxn--fiqz9storegontrailroadxn" + + "--fjord-lraxn--fjq720axn--fl-ziaxn--flor-jraxn--flw351exn--forl-" + + "cesena-fcbsstorfjordxn--forlcesena-c8axn--fpcrj9c3dxn--frde-gran" + + "drapidstorjcloud-ver-jpchungnamdalseidfjordyndns-picsannohelplfi" + + "nancialuxuryxn--frna-woaraisaijosoyrorostpetersburgxn--frya-hrax" + + "n--fzc2c9e2cngriwataraidyndns-wikiraxn--fzys8d69uvgmailxn--g2xx4" + + "8cnpyatigorskodjeepsondriodejaneirockartuzyxn--gckr3f0fbsbxn--1c" + + "k2e1bar0emmafann-arboretumbriamallamaceiobbcg12038xn--gecrj9cnsa" + + "ntacruzsewhalingroks-thisayamanobeokalmykiaxn--ggaviika-8ya47hak" + + "atanorthwesternmutualxn--gildeskl-g0axn--givuotna-8yasugitpagefr" + + "ontappixolinoxn--gjvik-wuaxn--gk3at1exn--gls-elacaixaxn--gmq050i" + + "s-into-carshirahamatonbetsurnadalxn--gmqw5axn--h-2failxn--h1aegh" + + "akodatexn--h2breg3evenestreams1xn--h2brj9c8cntoyotaparsantafedje" + + "ffersonxn--h3cuzk1discountysnestudioxn--hbmer-xqaxn--hcesuolo-7y" + + "a35basilicataniautoscanadaeguambulancechirealmpmnaval-d-aosta-va" + + "lleyokoteastcoastaldefenceastus2xn--hery-iraxn--hgebostad-g3axn-" + + "-hkkinen-5waxn--hmmrfeasta-s4accident-prevention-k3studynamische" + + "s-dnsopotrentinsued-tirolxn--hnefoss-q1axn--hobl-iraxn--holtlen-" + + "hxaxn--hpmir-xqaxn--hxt814exn--hyanger-q1axn--hylandet-54axn--i1" + + "b6b1a6a2exn--imr513nxn--indery-fyasuokannamihoboleslawiecolognew" + + "spaperxn--io0a7is-into-cartoonshirakokaminokawanishiaizubangexn-" + + "-j1aefbx-ostrowiechoseiroumuenchenissedaluroyxn--j1amhakonexn--j" + + "6w193gxn--jlq480n2rgxn--jlq61u9w7basketballfinanzgorzeleccollect" + + "ionayorovigovtaxihuanfshostyhostingjerstadotsuruokakegawaveroyke" + + "ngerdalces3-eu-west-2xn--jlster-byatominamidaitomanchesterxn--jr" + + "peland-54axn--jvr189mintereisenxn--k7yn95exn--karmy-yuaxn--kbrq7" + + "oxn--kcrx77d1x4axn--kfjord-iuaxn--klbu-woaxn--klt787dxn--kltp7dx" + + "n--kltx9axn--klty5xn--3oq18vl8pn36axn--koluokta-7ya57hakubahcavu" + + "otnagaivuotnagaokakyotambabyenglandxn--kprw13dxn--kpry57dxn--kpu" + + "t3is-into-gamessinazawaxn--krager-gyatsukanoyaltakasugais-leetre" + + "ntino-aadigexn--kranghke-b0axn--krdsherad-m8axn--krehamn-dxaxn--" + + "krjohka-hwab49jdevcloudjiffylkesbiblackbaudcdn-edgestackhero-net" + + "workinggroupaashorokanaiexn--ksnes-uuaxn--kvfjord-nxaxn--kvitsy-" + + "fyatsushiroxn--kvnangen-k0axn--l-1fairwindstuff-4-salexn--l1acce" + + "ntureklamborghinikolaeventstufftoread-booksnesor-odalxn--laheadj" + + "u-7yawaraxn--langevg-jxaxn--lcvr32dxn--ldingen-q1axn--leagaviika" + + "-52batochiokinoshimaintenanceobninskaragandavocatanzarowbq-aursk" + + "og-holandingdyniajudaicadaquest-mon-blogueurovision-riopretobish" + + "imagazinekobayashikshacknetnedalaheadjudygarlanddnslivelanddnss3" + + "-ap-southeast-1xn--lesund-huaxn--lgbbat1ad8jdfastlylbanzaiclouda" + + "ppscbgivingjemnes3-fips-us-gov-west-1xn--lgrd-poacctromsojamison" + + "xn--lhppi-xqaxn--linds-pramericanartrusteexn--lns-qlaquilanstutt" + + "gartrentoyonakagyokutoyakolobrzegersundxn--loabt-0qaxn--lrdal-sr" + + "axn--lrenskog-54axn--lt-liacolonialwilliamsburgrondarxn--lten-gr" + + "anexn--lury-iraxn--m3ch0j3axn--mely-iraxn--merker-kuaxn--mgb2dde" + + "susakis-certifiedunetlifyis-a-musicianxn--mgb9awbfbxostrowwlkpmg" + + "ruexn--mgba3a3ejtrvaroyxn--mgba3a4f16axn--mgba3a4fra1-dexn--mgba" + + "7c0bbn0axn--mgbaakc7dvfedorainfracloudfrontdoorxn--mgbaam7a8haku" + + "is-a-greenxn--mgbab2bdxn--mgbah1a3hjkrdxn--mgbai9a5eva00batsfjor" + + "diskussionsbereichattanooganordeste-idcasertairanzanhktcmemergen" + + "cyahikobeardubaiduckdns3-us-west-2xn--mgbai9azgqp6jejuniperxn--m" + + "gbayh7gpaleoxn--mgbbh1a71exn--mgbc0a9azcgxn--mgbca7dzdoxn--mgber" + + "p4a5d4a87gxn--mgberp4a5d4arxn--mgbgu82axn--mgbi4ecexposedxn--mgb" + + "pl2fhappouxn--mgbqly7c0a67fbcoloradoplateaudiopsysantamariakexn-" + + "-mgbqly7cvafr-1xn--mgbt3dhdxn--mgbtf8flatangerxn--mgbtx2bauhausp" + + "osts-and-telecommunicationswedeniwaizumiotsukumiyamazonawsmpplan" + + "etariumemorialillyombolzano-altoadigeometre-experts-comptables3-" + + "website-ap-northeast-1xn--mgbx4cd0abbvieeexn--mix082fedorapeople" + + "gallodingenxn--mix891fedoraprojectozsdeportevadsobetsulikes-pied" + + "monticellocalzonexn--mjndalen-64axn--mk0axin-dslgbtrycloudflarep" + + "bodynamic-dnsortlandxn--mk1bu44columbusheyxn--mkru45is-lostre-to" + + "teneis-a-nascarfanxn--mlatvuopmi-s4axn--mli-tlarvikonyvelolipopu" + + "sinteractivegashisuifuettertdasnetzxn--mlselv-iuaxn--moreke-juax" + + "n--mori-qsakuragawaxn--mosjen-eyawatahamaxn--mot-tlavagiskexn--m" + + "re-og-romsdal-qqbuseranishiaritakurashikis-not-certifiedxn--msy-" + + "ula0hakusanagochijiwadellogliastradingxn--mtta-vrjjat-k7aflaksta" + + "daokagakicks-assnasaarlandxn--muost-0qaxn--mxtq1misakis-an-accou" + + "ntantshiojirishirifujiedaxn--ngbc5azdxn--ngbe9e0axn--ngbrxn--3px" + + "u8komvuxn--30rr7yxn--nit225kooris-a-personaltrainerxn--nmesjevue" + + "mie-tcbalsan-sudtirollagdenesnaaseinet-freaksusonoxn--nnx388axn-" + + "-nodessakurais-savedxn--nqv7fs00emaxn--nry-yla5gxn--ntso0iqx3axn" + + "--ntsq17gxn--nttery-byaeservehalflifeinsurancexn--nvuotna-hwaxn-" + + "-nyqy26axn--o1achernihivgubsuzakananiikappuboliviajessheimpertri" + + "xcdn77-secureggiocalabriaxn--o3cw4haldenxn--o3cyx2axn--od0algxn-" + + "-od0aq3beneventoeidskoguchikuzenvironmentalconservationionjukudo" + + "yamaizuruovat-band-campaniavoues3-eu-west-3utilities-1kappchizip" + + "6116-b-datacentermezgorabogadobeaemcloud-dealerimo-i-rana4u2-loc" + + "alhostrodawarabruzzoologicalvinklein-addrammenuorochestereport3l" + + "3p0rtashkentatamotors3-ap-northeast-1337xn--ogbpf8flekkefjordxn-" + + "-oppegrd-ixaxn--ostery-fyaxn--osyro-wuaxn--otu796dxn--p1acfeiraq" + + "uarelleaseeklogesaveincloudxn--p1ais-slickazteleportlligatrentin" + + "o-alto-adigexn--pgbs0dhlxn--porsgu-sta26fermochizukirkenesaves-t" + + "he-whalessandria-trani-barletta-andriatranibarlettaandriaxn--pss" + + "u33lxn--pssy2uxn--q9jyb4communewyorkshirebungoonordkappartintuit" + + "oyotomiyazakinuyamashinatsukigatakasakitauraxn--qcka1pmcdirxn--q" + + "qqt11misasaguris-an-actorxn--qxa6axn--qxamsterdamnserverbaniaxn-" + + "-rady-iraxn--rdal-poaxn--rde-ulavangenxn--rdy-0nabaris-uberleetr" + + "entino-altoadigexn--rennesy-v1axn--rhkkervju-01aferraraxn--rholt" + + "-mragowoodsidevelopmentrysiljanxn--rhqv96gxn--rht27zxn--rht3dxn-" + + "-rht61exn--risa-5nativeamericanantiquesuzukanazawaxn--risr-iraxn" + + "--rland-uuaxn--rlingen-mxaxn--rmskog-byaxn--rny31halsaitamatsuku" + + "ris-a-gurusrcfastly-terrariuminamiechizenxn--rovu88bentleyomitan" + + "observerxn--rros-granvindafjordxn--rskog-uuaxn--rst-0naturalhist" + + "orymuseumcenterxn--rsta-franamizuholdingsmall-webhostingxn--rvc1" + + "e0am3exn--ryken-vuaxn--ryrvik-byaxn--s-1faithammarfeastafricarbo" + + "nia-iglesias-carboniaiglesiascarboniaxn--s9brj9community-prochow" + + "icexn--sandnessjen-ogbeppublishproxyzjampagexlimanowarudaxarnetf" + + "lixilovecollegefantasyleaguernseyokozeatonsbergivestbytemarkanza" + + "kiwielunnerhcloudiscourses3-external-1xn--sandy-yuaxn--sdtirol-n" + + "2axn--seral-lraxn--ses554gxn--sgne-graphoxn--42c2d9axn--skierv-u" + + "tazasuzukis-foundationxn--skjervy-v1axn--skjk-soaxn--sknit-yqaxn" + + "--sknland-fxaxn--slat-5naturalsciencesnaturellesvalbardunloppaci" + + "ficivilizationxn--slt-elabcn-north-1xn--smla-hraxn--smna-gratang" + + "entlentapisa-geekopervikfh-muensterxn--snase-nraxn--sndre-land-0" + + "cbeskidyn-ip24xn--snes-poaxn--snsa-roaxn--sr-aurdal-l8axn--sr-fr" + + "on-q1axn--sr-odal-q1axn--sr-varanger-ggbestbuyshouses3-website-a" + + "p-southeast-1xn--srfold-byaxn--srreisa-q1axn--srum-gratis-a-bull" + + "s-fanxn--stfold-9xaxn--stjrdal-s1axn--stjrdalshalsen-sqbetainabo" + + "xfusejnyanagawaltervistaikikugawashingtondclk3xn--stre-toten-zcb" + + "hzcasinorddalimitedisrechtranaharimalselvendrellimoliseminempres" + + "ashibetsukuibmdivtasvuodnakaiwamizawaweddingjesdalivornoceanogra" + + "phiquemrxn--t60b56axn--tckwebspacexn--tiq49xqyjelasticbeanstalka" + + "zunotteroyxn--tjme-hraxn--tn0agrinetbankoryokamikawanehonbetsuru" + + "taharaxn--tnsberg-q1axn--tor131oxn--trany-yuaxn--trentin-sd-tiro" + + "l-rzbieidsvollombardynaliasnesoddenmarkhangelskjakdnepropetrovsk" + + "iervaapsteiermarkarasjohkamikoaniihamatamakawajimarriottcp4xn--t" + + "rentin-sdtirol-7vbrplsbxn--45br5cylxn--trentino-sd-tirol-c3biela" + + "washtenawdev-myqnapcloudcontrolledekagaminogifts3-website-ap-sou" + + "theast-2xn--trentino-sdtirol-szbiellaakesvuemielecceu-1xn--trent" + + "inosd-tirol-rzbieszczadygeyachts3-website-eu-west-1xn--trentinos" + + "dtirol-7vbievathletajimabaridagawakkanaibetsubamericanfamilydscl" + + "ouderacingjovikarasjokarasuyamarshallstatebankarateu-2xn--trenti" + + "nsd-tirol-6vbifukagawassamukawatarikuzentakatainaioirasebastopol" + + "ogyeongnamegawafaicloudineat-urlomzaporizhzheguriitatebayashijon" + + "awateu-3xn--trentinsdtirol-nsbigv-infolldalondonetskaratsuginami" + + "katagamilanoticias3-website-sa-east-1xn--trgstad-r1axn--trna-woa" + + "xn--troms-zuaxn--tysvr-vraxn--uc0atvestfoldxn--uc0ay4axn--uist22" + + "hamurakamigoris-a-hard-workershawaiijimarcheapigeelvinckaufenxn-" + + "-uisz3gxn--unjrga-rtarumizusawaxn--unup4yxn--uuwu58axn--vads-jra" + + "xn--valle-aoste-ebbtunesorumincomcastresindevicenzaporizhzhiaxn-" + + "-valle-d-aoste-ehbodoes-it1-eurxn--valleaoste-e7axn--valledaoste" + + "-ebbvacationsvcivilwarmiastagets-itmparochernigovernmentoyosatoy" + + "okawaxn--vard-jraxn--vegrshei-c0axn--vermgensberater-ctbihorolog" + + "yonagoyaxn--vermgensberatung-pwblogoipizzaxn--vestvgy-ixa6oxn--v" + + "g-yiabkhaziaxn--vgan-qoaxn--vgsy-qoa0jelenia-goraxn--vgu402comob" + + "araxn--vhquvestnesouthcarolinarvikomakiyosatokamachintaifun-dnsa" + + "liashishikuis-a-patsfanxn--vler-qoaxn--vre-eiker-k8axn--vrggt-xq" + + "adxn--vry-yla5gxn--vuq861bikedaemoneyonagunicloudivttasvuotnakam" + + "agayahooguyoriikarelianceu-4xn--w4r85el8fhu5dnraxn--w4rs40lxn--w" + + "cvs22dxn--wgbh1comparemarkerryhotelsantoandreamhostersanukinvest" + + "mentsaobernardownloadyndns-workshopitsitexasaogoncasacamdvrcampi" + + "nagrandebuilderschlesischesaotomelbournexn--wgbl6axn--xhq521bilb" + + "aokinawashirosatochigiessensiositechnologyoshiokanumazuryukiiyam" + + "anouchikuhokuryugasakitashiobaraxn--xkc2al3hye2axn--xkc2dl3a5ee0" + + "handsonyoursidelmenhorstalbanshellaspeziaxn--y9a3aquariumisawaxn" + + "--yer-znaturbruksgymnxn--yfro4i67oxn--ygarden-p1axn--ygbi2ammxn-" + + "-45brj9cldmailuzernxn--ystre-slidre-ujbillustrationredumbrellahp" + + "piacenzachpomorskienhlfanhs3-website-us-east-1xn--zbx025dxn--zf0" + + "ao64axn--zf0avxlxn--zfr164biocelotenkawaxnbayxz" // nodes is the list of nodes. Each node is represented as a uint32, which // encodes the node's children, wildcard bit and node type (as an index into @@ -528,1808 +535,1812 @@ const text = "9guacuiababia-goracleaningroks-theatree12hpalermomahachijolstere" // [15 bits] text index // [ 6 bits] text length var nodes = [...]uint32{ - 0x32f643, - 0x3b5c84, - 0x2f7846, - 0x2ed303, - 0x2ed306, - 0x391ec6, - 0x3ba683, - 0x242cc4, - 0x2089c7, - 0x2f7488, + 0x20bc43, + 0x25d9c4, + 0x2f8cc6, + 0x217243, + 0x217246, + 0x38e886, + 0x3bb603, + 0x2392c4, + 0x3a15c7, + 0x2f8908, 0x1a000c2, - 0x1f3c187, - 0x37b0c9, - 0x39a04a, - 0x39a04b, - 0x231983, - 0x234b85, - 0x2202642, - 0x280004, - 0x2f79c3, - 0x202645, - 0x2608c02, - 0x365e83, - 0x2a15d84, - 0x3b5585, - 0x2e12282, - 0x27520e, - 0x251a43, - 0x3adec6, - 0x3207d42, - 0x306e07, - 0x237306, - 0x3601f82, - 0x26d143, - 0x334e46, - 0x360f48, - 0x28e806, - 0x276804, + 0x1f3cf47, + 0x376f09, + 0x397eca, + 0x397ecb, + 0x23a2c3, + 0x23cf05, + 0x22070c2, + 0x2f5304, + 0x2f8e43, + 0x30eb85, + 0x260ad42, + 0x360f03, + 0x2a58bc4, + 0x30f345, + 0x2e13602, + 0x21638e, + 0x25c3c3, + 0x3b3dc6, + 0x3202302, + 0x3096c7, + 0x23fa86, + 0x3606a82, + 0x28e183, + 0x235e06, + 0x2f4148, + 0x295bc6, + 0x3c7c04, 0x3a00ac2, - 0x34cd89, - 0x222087, - 0x3b4c86, - 0x370f49, - 0x3c8608, - 0x354f84, - 0x25b9c6, - 0x3cdd86, - 0x3e029c2, - 0x2a7f06, - 0x24394f, - 0x27f04e, - 0x221684, - 0x2d4205, - 0x32f545, - 0x215589, - 0x23d909, - 0x335647, - 0x355246, - 0x203583, - 0x42272c2, - 0x22ce03, - 0x2937ca, - 0x4601ac3, - 0x3e1a45, - 0x239202, - 0x392449, - 0x4e03502, - 0x209784, - 0x2f4406, - 0x28fac5, - 0x3732c4, - 0x56263c4, - 0x233f03, - 0x233f04, - 0x5a02e42, - 0x385d04, - 0x5e83a84, - 0x25d6ca, + 0x34b449, + 0x220787, + 0x32e5c6, + 0x36ba09, + 0x3ce888, + 0x210944, + 0x2acb06, + 0x2076c6, + 0x3e02002, + 0x38cc46, + 0x24d68f, + 0x3cdb8e, + 0x22b1c4, + 0x234c85, + 0x330d45, + 0x3aaa09, + 0x247e89, + 0x236607, + 0x2584c6, + 0x267083, + 0x422d0c2, + 0x22d543, + 0x29b5ca, + 0x4609983, + 0x3403c5, + 0x30a8c2, + 0x3a4f89, + 0x4e03b42, + 0x207a04, + 0x354186, + 0x243885, + 0x36ebc4, + 0x5626e04, + 0x203b43, + 0x23c4c4, + 0x5a030c2, + 0x25b344, + 0x5f2d504, + 0x316d0a, 0x6200882, - 0x229547, - 0x27e508, - 0x7a07282, - 0x334a47, - 0x2ce984, - 0x2ce987, - 0x3dbac5, - 0x390e07, - 0x34b706, - 0x2a1184, - 0x36a285, - 0x257e87, - 0x8e07cc2, - 0x2a8083, - 0x9210642, - 0x3b3f43, - 0x96074c2, - 0x2173c5, - 0x9a00202, - 0x375d04, - 0x2ef285, - 0x2215c7, - 0x25d04e, - 0x2ba484, - 0x29a884, - 0x20ebc3, - 0x35c549, - 0x2c17cb, - 0x2c75c8, - 0x32cc48, - 0x3313c8, - 0x3e1f48, - 0x370d8a, - 0x390d07, - 0x356606, - 0x9e3de82, - 0x26f0c3, - 0x3d2103, - 0x3d3c84, - 0x26f103, - 0x361e43, - 0x1737f82, - 0xa206c02, - 0x284a05, - 0x2bc146, - 0x234944, - 0x3aee07, - 0x26bdc6, - 0x2cd644, - 0x3bdc87, - 0x20d483, - 0xa6d7f02, - 0xab0bf02, - 0xae7b6c2, - 0x30bcc6, - 0xb200282, - 0x2a4d45, - 0x3394c3, - 0x3d5bc4, - 0x2f9284, - 0x2f9285, - 0x3dff03, - 0xb64ac43, - 0xba05102, - 0x2093c5, - 0x2093cb, - 0x2b2a0b, - 0x204cc4, - 0x209849, - 0x20ae84, - 0xbe0b742, - 0x20c303, - 0x20e1c3, - 0xc207f42, - 0x2f2aca, - 0xc608a02, - 0x280285, - 0x2e858a, - 0x242644, - 0x210143, - 0x210a04, - 0x211943, - 0x211944, - 0x211947, - 0x212685, - 0x213086, - 0x213386, - 0x214683, - 0x218248, - 0x217143, - 0xca0cfc2, - 0x266308, - 0x28ea8b, - 0x2208c8, - 0x221106, - 0x222887, - 0x225048, - 0xda0aac2, - 0xde1c942, - 0x272d48, - 0x20f1c7, - 0x20f705, - 0x310f88, - 0xe302e48, - 0x2b0ec3, - 0x22bec4, - 0x391f42, - 0xe62c0c2, - 0xea06cc2, - 0xf22c442, - 0x22c443, - 0xf60cf02, - 0x316343, - 0x332284, - 0x214803, - 0x354f44, - 0x32430b, - 0x20cf03, - 0x2f2086, - 0x25d544, - 0x2c888e, - 0x377205, - 0x268a88, - 0x3adfc7, - 0x3adfca, - 0x231503, - 0x2355c7, - 0x2c1985, - 0x231504, - 0x253a06, - 0x253a07, - 0x31dd84, - 0xfb109c4, - 0x25d384, - 0x25d386, - 0x252684, - 0x3c2f86, - 0x20f4c3, - 0x20f4c8, - 0x210448, - 0x29a843, - 0x2f2a83, - 0x343c04, - 0x35c0c3, - 0x1020cdc2, - 0x106bd282, - 0x205083, - 0x243fc6, - 0x25bac3, - 0x274784, - 0x10a30c82, - 0x25ce43, - 0x316a83, - 0x214dc2, - 0x10e00d42, - 0x2d3286, - 0x235a07, - 0x229bc7, - 0x3c0d85, - 0x21cc84, - 0x2a0dc5, - 0x30f247, - 0x2e5a49, - 0x2ee886, - 0x3032c6, - 0x11602282, - 0x307a08, - 0x31a706, - 0x2b1bc5, - 0x30c3c7, - 0x30dcc4, - 0x30dcc5, - 0x11a02284, - 0x202288, - 0x11e09482, - 0x12200482, - 0x275946, + 0x3cd347, + 0x27b5c8, + 0x7a08502, + 0x336287, + 0x2d36c4, + 0x2d36c7, + 0x38aa45, + 0x38bf07, + 0x34a906, + 0x29ac84, + 0x3633c5, + 0x282507, + 0x920c142, + 0x38cdc3, + 0x960b4c2, + 0x3b5e03, + 0x9a08742, + 0x2691c5, + 0x9e00202, + 0x371604, + 0x387345, + 0x22b107, + 0x2e954e, + 0x206984, + 0x283b04, + 0x2079c3, + 0x30d489, + 0x2c4e4b, + 0x2e1248, + 0x32b788, + 0x3328c8, + 0x20a888, + 0xa36b84a, + 0x38be07, + 0x2f7086, + 0xa617282, + 0x35ca43, + 0x3d6443, + 0x3d8084, + 0x35ca83, + 0x3bb643, + 0x1738b82, + 0xaa04702, + 0x28a385, + 0x261e86, + 0x252084, + 0x3b0cc7, + 0x25b186, + 0x2d4704, + 0x3be9c7, + 0x204703, + 0xb2dc982, + 0xb728c42, + 0xba13982, + 0x230646, + 0xbe00282, + 0x26b385, + 0x33a0c3, + 0x3de644, + 0x2fd584, + 0x2fd585, + 0x3e9683, + 0xc253c43, + 0xc606342, + 0x20e9c5, + 0x20e9cb, + 0x223c8b, + 0x20e804, + 0x20ee49, + 0x210404, + 0xca10d82, + 0x211a83, + 0x2121c3, + 0xce02502, + 0x23020a, + 0xd20bd42, + 0x2f5585, + 0x2ece4a, + 0x246f44, + 0x213f43, + 0x2154c4, + 0x2178c3, + 0x2178c4, + 0x2178c7, + 0x218705, + 0x219546, + 0x21a186, + 0x2172c3, + 0x220f88, + 0x215b03, + 0xd604242, + 0x2fc548, + 0x295e4b, + 0x229c88, + 0x22ac46, + 0x22b987, + 0x22e908, + 0xee016c2, + 0xf2295c2, + 0x278408, + 0x20b947, + 0x206e85, + 0x3e2208, + 0xf61c008, + 0x26a0c3, + 0x235a44, + 0x38e902, + 0xfa36c42, + 0xfe07f42, + 0x10637242, + 0x237243, + 0x10a04182, + 0x312683, + 0x2135c4, + 0x210903, + 0x210904, + 0x3a264b, + 0x204183, + 0x2f27c6, + 0x284a84, + 0x2ccf8e, + 0x240ec5, + 0x257008, + 0x2716c7, + 0x2716ca, + 0x21b9c3, + 0x25d7c7, + 0x2c5005, + 0x239e44, + 0x25ef06, + 0x25ef07, + 0x3601c4, + 0x10f10344, + 0x3169c4, + 0x3169c6, + 0x25d4c4, + 0x3c2086, + 0x206c43, + 0x206c48, + 0x20b2c8, + 0x2b3843, + 0x2301c3, + 0x344544, + 0x357203, + 0x11604042, + 0x11aea202, + 0x217843, + 0x203c06, + 0x3796c3, + 0x2fd344, + 0x11efd0c2, + 0x343583, + 0x332f83, + 0x21cdc2, + 0x12200d42, + 0x2d7946, + 0x228b07, + 0x27b347, + 0x2c7cc5, + 0x386404, + 0x3d4a45, + 0x3dcc47, + 0x2b5ec9, + 0x2cb106, + 0x2c7bc6, + 0x1320c602, + 0x2b6688, + 0x321346, + 0x327b05, + 0x2f7787, + 0x2fafc4, + 0x2fafc5, + 0x1370e7c4, + 0x30e7c8, + 0x13a08d02, + 0x13e00482, + 0x24c3c6, 0x200488, - 0x337b45, - 0x34d686, - 0x350448, - 0x360a48, - 0x12608cc5, - 0x12a15e84, - 0x215e87, - 0x12e0a902, - 0x13361e82, - 0x14612402, - 0x2f4505, - 0x14e8af45, - 0x269506, - 0x327ec7, - 0x3b26c7, - 0x1522ea43, - 0x32bb87, - 0x3c17c8, - 0x2162ed49, - 0x2753c7, - 0x22f487, - 0x22fe88, - 0x230686, - 0x231006, - 0x231c4c, - 0x23294a, - 0x232d47, - 0x234a4b, - 0x235847, - 0x23584e, - 0x21a36344, - 0x236704, - 0x238a07, - 0x260b47, - 0x23d046, - 0x23d047, - 0x335887, - 0x226dc3, - 0x21e2c982, - 0x23e846, - 0x23e84a, - 0x24004b, - 0x241287, - 0x241d05, - 0x242183, - 0x2423c6, - 0x2423c7, - 0x2fa483, - 0x22200102, - 0x2435ca, - 0x2277c682, - 0x22b49682, - 0x22e40902, - 0x23237402, - 0x246ac5, - 0x247344, - 0x23e0da02, - 0x385d85, - 0x240643, - 0x299645, - 0x201ec4, - 0x21dd04, - 0x2d4e46, - 0x251dc6, - 0x2095c3, - 0x3cce44, - 0x37f243, - 0x24e0f982, - 0x216404, - 0x216406, - 0x222c05, - 0x2482c6, - 0x30c4c8, - 0x265e44, - 0x294208, - 0x232fc5, - 0x259508, - 0x2d0686, - 0x30e0c7, - 0x269c04, - 0x26269c06, - 0x26622383, - 0x3a47c3, - 0x2f7108, - 0x38bc44, - 0x26b32ec7, - 0x2e6946, - 0x2e6949, - 0x369588, - 0x37d748, - 0x389c84, - 0x204583, - 0x240702, - 0x2724e682, - 0x27626282, - 0x205c83, - 0x27a08b02, - 0x2fa404, - 0x2790c6, - 0x21a203, - 0x2c3d47, - 0x3b3a83, - 0x2ba548, - 0x21edc5, - 0x259f83, - 0x2ef205, - 0x2ef344, - 0x30d9c6, - 0x220006, - 0x221506, - 0x2f4c84, - 0x235c03, - 0x27e11702, - 0x282351c5, + 0x325105, + 0x3264c6, + 0x329dc8, + 0x34c608, + 0x14203ec5, + 0x16e2f004, + 0x2b0f87, + 0x1720fe82, + 0x1762e702, + 0x18a16542, + 0x354285, + 0x192904c5, + 0x241c06, + 0x3b6207, + 0x368e07, + 0x19616543, + 0x3d6787, + 0x283a08, + 0x273b4bc9, + 0x216547, + 0x3e03c7, + 0x238308, + 0x238b06, + 0x239946, + 0x23a58c, + 0x23b58a, + 0x23ba87, + 0x23cdcb, + 0x23dd47, + 0x23dd4e, + 0x2763eb84, + 0x23ec84, + 0x240d87, + 0x24be07, + 0x246386, + 0x246387, + 0x3b74c7, + 0x203643, + 0x27a13b02, + 0x248746, + 0x24874a, + 0x248acb, + 0x249f07, + 0x24aac5, + 0x24b283, + 0x24c646, + 0x24c647, + 0x2feac3, + 0x27e00102, + 0x24d30a, + 0x28378742, + 0x2863d842, + 0x28a47402, + 0x28e3fb82, + 0x24f085, + 0x24fdc4, + 0x29a0c542, + 0x25b3c5, + 0x231943, + 0x29d005, + 0x20a784, + 0x21e5c4, + 0x2d9d06, + 0x25cc06, + 0x20ebc3, + 0x3c1a44, + 0x341883, + 0x2aa03242, + 0x2b1504, + 0x3a1a46, + 0x2b1505, + 0x207106, + 0x2f7888, + 0x233d04, + 0x2b0ac8, + 0x2f3f05, + 0x27ce88, + 0x2d57c6, + 0x21c787, + 0x279ec4, + 0x2be79ec6, + 0x2c220a83, + 0x3a6543, + 0x2c05c8, + 0x334684, + 0x2c615587, + 0x280dc6, + 0x2e9b49, + 0x362488, + 0x32c448, + 0x333004, + 0x20d303, + 0x249182, + 0x2ce57f02, + 0x2d226cc2, + 0x20dd83, + 0x2d615fc2, + 0x2fea44, + 0x285786, + 0x23ca03, + 0x2c72c7, + 0x36ca43, + 0x3e1348, + 0x2253c5, + 0x267d03, + 0x3872c5, + 0x387404, + 0x3bad86, + 0x22a386, + 0x22b046, + 0x2580c4, + 0x23e103, + 0x2da15282, + 0x2de3d545, 0x200843, - 0x28a0da82, - 0x22f203, - 0x3233c5, - 0x28e33fc3, - 0x29633fc9, - 0x29a00942, - 0x2a20fc42, - 0x292845, - 0x2166c6, - 0x2ada86, - 0x2e9f08, - 0x2e9f0b, - 0x346d4b, - 0x3c0f85, - 0x2d8489, + 0x2e603e82, + 0x23a543, + 0x3ca805, + 0x2ea22bc3, + 0x2f23c589, + 0x2f600942, + 0x2fe05342, + 0x2973c5, + 0x21f406, + 0x2b2986, + 0x308cc8, + 0x308ccb, + 0x346d8b, + 0x35b445, + 0x2dcf09, 0x1600b42, - 0x39b4c8, - 0x209b44, - 0x2aa031c2, - 0x34ca03, - 0x2b260d06, - 0x2b600fc2, - 0x3619c8, - 0x2ba293c2, - 0x33d78a, - 0x2bedd983, - 0x2c77b706, - 0x397c88, - 0x242986, - 0x38dc47, - 0x243b47, - 0x3cd90a, - 0x2426c4, - 0x365c04, - 0x37a709, - 0x2cbb1905, - 0x275246, - 0x20f3c3, - 0x24e104, - 0x2ced8384, - 0x3b4447, - 0x2d233647, - 0x25ce84, - 0x3b2b85, - 0x2695c8, - 0x3a4c87, - 0x3a9847, - 0x2d60fa02, - 0x26acc4, - 0x2981c8, - 0x248604, - 0x24bb44, - 0x24bf45, - 0x24c087, - 0x2da81989, - 0x21eb04, - 0x24d4c9, - 0x24d708, - 0x24de84, - 0x24de87, - 0x2de4e483, - 0x24f8c7, - 0x2e201282, - 0x16be142, - 0x250386, - 0x251187, - 0x2515c4, - 0x252dc7, - 0x254047, - 0x254603, - 0x2ba882, - 0x20e782, - 0x32cd43, - 0x3ce884, - 0x3ce88b, - 0x2e72cd48, - 0x259a04, - 0x255d05, - 0x2576c7, - 0x20e785, - 0x31d28a, - 0x259943, - 0x2ea091c2, - 0x21d304, - 0x260909, - 0x264e43, - 0x264f07, - 0x28c949, - 0x2091c8, - 0x26f783, - 0x283187, - 0x283b89, - 0x26a503, - 0x28b544, - 0x28cb89, - 0x290cc6, - 0x2e9d03, - 0x207c82, - 0x23cc03, - 0x2bdf47, - 0x23cc05, - 0x2c15c6, - 0x296d84, - 0x365485, - 0x2844c3, - 0x2148c6, - 0x27eb43, - 0x209a42, - 0x24ac04, - 0x2ee08882, - 0x2f368483, - 0x2f6033c2, - 0x249f83, - 0x20dc44, - 0x303b07, - 0x348546, - 0x27cec2, - 0x2fa04d82, - 0x30c6c4, - 0x30211ac2, - 0x30621c42, - 0x2f0f04, - 0x2f0f05, - 0x363e85, - 0x260286, - 0x30a06d42, - 0x20f8c5, - 0x219a45, - 0x21bb43, - 0x225d86, - 0x227545, - 0x265d82, - 0x360685, - 0x30bc44, - 0x265d83, - 0x265fc3, - 0x30e08f42, - 0x2e4dc7, - 0x24d904, - 0x24d909, - 0x24e004, - 0x28adc3, - 0x2b9808, - 0x3128adc4, - 0x28adc6, - 0x2a49c3, - 0x256543, - 0x266a83, - 0x316fb9c2, - 0x308982, - 0x31a00642, - 0x33b208, - 0x3e0108, - 0x3bef86, - 0x351a05, - 0x303c85, - 0x207d87, - 0x31e46145, - 0x23ca82, - 0x3229cac2, - 0x32600042, - 0x27db48, - 0x31a645, - 0x2feac4, - 0x248205, - 0x2497c7, - 0x388944, - 0x2434c2, - 0x32a0b2c2, - 0x352084, - 0x228b07, - 0x292d07, - 0x390dc4, - 0x3d2c03, - 0x29a784, - 0x29a788, - 0x231346, - 0x25388a, - 0x2f5844, - 0x299e48, - 0x235384, - 0x222986, - 0x29ca84, - 0x2f4806, - 0x24dbc9, - 0x2abc07, - 0x213ec3, - 0x32e5b542, - 0x3a2503, - 0x20b942, - 0x33205742, - 0x34c006, - 0x386d08, - 0x2adc07, - 0x30b109, - 0x2addc9, - 0x2b0405, - 0x2b2d89, - 0x2b3cc5, - 0x2b4b05, - 0x2b5f88, - 0x33611b04, - 0x33a54747, - 0x22f843, - 0x2b6187, - 0x22f846, - 0x2b6987, - 0x2ab845, - 0x22f0c3, - 0x33e32702, - 0x210384, - 0x3422cb02, - 0x3460b5c2, - 0x314d06, - 0x27e485, - 0x2b8ec7, - 0x356e03, - 0x361dc4, - 0x21d783, - 0x355e03, - 0x34a09582, - 0x35208fc2, - 0x391fc4, - 0x32ae03, - 0x305545, - 0x3560f782, - 0x35e02182, - 0x305d46, - 0x2069c4, - 0x30a304, - 0x30a30a, - 0x366005c2, - 0x2160c3, - 0x21528a, - 0x219008, - 0x36a0e704, + 0x2d2908, + 0x20f144, + 0x30602bc2, + 0x33e203, + 0x30e4bfc6, + 0x31200fc2, + 0x20ae88, + 0x31613242, + 0x37aa4a, + 0x32239383, + 0x32b77546, + 0x318348, + 0x38db06, + 0x389c87, + 0x24d887, + 0x20724a, + 0x246fc4, + 0x360c84, + 0x376889, + 0x32fb3a05, + 0x2163c6, + 0x20bb43, + 0x263284, + 0x33232d44, + 0x32d187, + 0x3365e987, + 0x2edb44, + 0x250145, + 0x241cc8, + 0x250387, + 0x250607, + 0x33a18242, + 0x2a2704, + 0x29e388, + 0x251b04, + 0x254744, + 0x254b05, + 0x254c47, + 0x3468b8c9, + 0x2555c4, + 0x256b09, + 0x256d48, + 0x257604, + 0x257607, + 0x257d03, + 0x259ac7, + 0x34a01282, + 0x16c0502, + 0x25b506, + 0x25bb47, + 0x25c404, + 0x25e347, + 0x25f247, + 0x25fc83, + 0x34e5c082, + 0x239fc2, + 0x260743, + 0x260744, + 0x26074b, + 0x32b888, + 0x2891c4, + 0x2618c5, + 0x262fc7, + 0x2ee845, + 0x3b930a, + 0x266b03, + 0x3520eb02, + 0x21dc84, + 0x26b6c9, + 0x26f443, + 0x26f507, + 0x384989, + 0x211fc8, + 0x213bc3, + 0x286bc7, + 0x288f89, + 0x276a83, + 0x290984, + 0x291d49, + 0x2951c6, + 0x3825c3, + 0x204982, + 0x268803, + 0x2c0307, + 0x38f005, + 0x2c4c46, + 0x219a44, + 0x372285, + 0x289e43, + 0x21abc6, + 0x22e143, + 0x20c342, + 0x253c04, + 0x35634402, + 0x35a34403, + 0x35e04342, + 0x253283, + 0x21a604, + 0x323c87, + 0x21fb46, + 0x290942, + 0x3620e8c2, + 0x32c684, + 0x36a17a42, + 0x36e09ac2, + 0x3caac4, + 0x3caac5, + 0x3b6b85, + 0x37d146, + 0x37207042, + 0x207045, + 0x20f745, + 0x213dc3, + 0x2267c6, + 0x227105, + 0x2305c2, + 0x35ac85, + 0x2305c4, + 0x233c43, + 0x233e83, + 0x3760a302, + 0x2318c7, + 0x257784, + 0x257789, + 0x263184, + 0x290343, + 0x2bd008, + 0x37a90344, + 0x290346, + 0x2b05c3, + 0x262243, + 0x343b43, + 0x37f03e02, + 0x30ad42, + 0x38200642, + 0x33bfc8, + 0x2158c8, + 0x3bfcc6, + 0x385145, + 0x323e05, + 0x202347, + 0x386823c5, + 0x2038c2, + 0x38aa0a82, + 0x38e00042, + 0x2832c8, + 0x2b65c5, + 0x302f84, + 0x250d45, + 0x2514c7, + 0x3b0184, + 0x24d202, + 0x3923b502, + 0x350984, + 0x22fec7, + 0x297b47, + 0x38bec4, + 0x3d7403, + 0x2b3784, + 0x2b3788, + 0x239c86, + 0x25ed8a, + 0x358e44, + 0x29ddc8, + 0x24ffc4, + 0x22ba86, + 0x2a0a44, + 0x354586, + 0x257a49, + 0x221247, + 0x39d543, + 0x39605102, + 0x386d03, + 0x210f82, + 0x39a027c2, + 0x268f86, + 0x3b2848, + 0x2b2b07, + 0x2331c9, + 0x2b2cc9, + 0x2b5585, + 0x2b6f09, + 0x2b7705, + 0x2b8545, + 0x2b94c8, + 0x39e17a84, + 0x3a25fdc7, + 0x2b96c3, + 0x2b96c7, + 0x3e0786, + 0x2b9c87, + 0x2af945, + 0x2d0843, + 0x3a63b342, + 0x214184, + 0x3aa11402, + 0x3ae1ec82, + 0x31e946, + 0x27b545, + 0x2bbd87, + 0x3c32c3, + 0x20ccc4, + 0x21e103, + 0x2f6883, + 0x3b2042c2, + 0x3ba08e82, + 0x38e984, + 0x25c043, + 0x308985, + 0x3be05502, + 0x3c602102, + 0x222f86, + 0x2e9484, + 0x2f0284, + 0x2f028a, + 0x3ce005c2, + 0x20e103, + 0x23498a, + 0x26a7c8, + 0x3d2b1b84, 0x2005c3, - 0x36e0a2c3, - 0x26a749, - 0x247109, - 0x2c3e46, - 0x372191c3, - 0x2191c5, - 0x21e7cd, - 0x22db06, - 0x2e61cb, - 0x37607542, - 0x358448, - 0x3b20c202, - 0x3b603082, - 0x39e285, - 0x3ba04b82, - 0x2af7c7, - 0x205603, - 0x227708, - 0x3be022c2, - 0x25ef84, - 0x21fc83, - 0x354a05, - 0x240746, - 0x227104, - 0x2f2a43, - 0x384583, - 0x3c206142, - 0x3c0f04, - 0x2bab45, - 0x2bdb47, - 0x281403, - 0x2be4c3, - 0x1616fc2, - 0x2be783, - 0x2beb83, - 0x3c600e02, - 0x33f584, - 0x235e06, - 0x2e6503, - 0x2bf943, - 0x3ca4b202, - 0x24b208, - 0x2c0904, - 0x33f306, - 0x253e87, - 0x29a946, - 0x38bbc4, - 0x4ae03102, - 0x22f70b, - 0x30180e, - 0x217a8f, - 0x2be183, - 0x4b65a642, - 0x1641882, - 0x4ba03802, - 0x2563c3, - 0x20ee83, - 0x21b306, - 0x34e0c6, - 0x395dc7, - 0x3d2484, - 0x4be16802, - 0x4c21f2c2, - 0x2e2845, - 0x33dec7, - 0x2c2506, - 0x4c669782, - 0x3626c4, - 0x2c7a83, - 0x4ca06902, - 0x4cf78103, - 0x2c9284, - 0x2cde89, - 0x4d2d5182, - 0x4d60a342, - 0x248985, - 0x4dad5682, - 0x4de01582, - 0x364e47, - 0x37b34b, - 0x243905, - 0x258509, - 0x270906, - 0x4e201584, - 0x206d89, - 0x2d6a07, - 0x22a147, - 0x22c743, - 0x2f0d86, - 0x352f87, - 0x21df43, - 0x2a87c6, - 0x4ea29a82, - 0x4ee34242, - 0x2061c3, - 0x392605, - 0x303147, - 0x236d06, - 0x23cb85, - 0x24d884, - 0x2aad45, - 0x393dc4, - 0x4f201482, - 0x2e9184, - 0x247004, - 0x24700d, - 0x2ee249, - 0x22ca48, - 0x248c04, - 0x347fc5, - 0x204407, - 0x206504, - 0x26be87, - 0x267a45, - 0x4f60a284, - 0x2c6045, - 0x201484, - 0x253306, - 0x394fc5, - 0x4faa4c82, - 0x2758c3, - 0x357643, - 0x35d804, - 0x35d805, - 0x39d506, - 0x23ccc5, - 0x368e84, - 0x364343, - 0x4fe17e86, - 0x21a8c5, - 0x21e2c5, - 0x327dc4, - 0x2f58c3, - 0x2f58cc, - 0x502bdc42, - 0x50600e82, - 0x50a02702, - 0x21e1c3, - 0x21e1c4, - 0x50e0a682, - 0x3b9e88, - 0x2c1685, - 0x2d5ec4, - 0x230e86, - 0x51204202, - 0x5162d582, - 0x51a00c42, - 0x296545, - 0x2f4b46, - 0x265684, - 0x335386, - 0x229306, - 0x25bfc3, - 0x51e9068a, - 0x2815c5, - 0x293783, - 0x209f06, - 0x209f09, - 0x223fc7, - 0x2b7fc8, - 0x3c84c9, - 0x2e5bc8, - 0x22dd86, - 0x20eb83, - 0x52208c82, - 0x32d248, - 0x52606a02, - 0x52a0b982, - 0x215f83, - 0x2ee705, - 0x2a0484, - 0x300689, - 0x3c04c4, - 0x20bc08, - 0x5320b983, - 0x53724784, - 0x216708, - 0x246f47, - 0x53b49242, - 0x370242, - 0x32f4c5, - 0x385509, - 0x23cb03, - 0x31bb84, - 0x3424c4, - 0x204483, - 0x28698a, - 0x53f93b42, - 0x542101c2, - 0x2d7e83, - 0x396083, - 0x162dfc2, - 0x26e8c3, - 0x54615782, - 0x54a00bc2, - 0x54e17544, - 0x217546, - 0x271a44, - 0x27d983, - 0x289683, - 0x55200bc3, - 0x2403c6, - 0x3d5d85, - 0x2dbe07, - 0x2dbd46, - 0x2dcd88, - 0x2dcf86, - 0x202a04, - 0x2a21cb, - 0x2dfa03, - 0x2dfa05, - 0x20e982, - 0x365142, - 0x55646b42, - 0x55a0a942, - 0x216843, - 0x55e720c2, - 0x2720c3, - 0x2e0483, - 0x56603e42, - 0x56ae4806, - 0x258d46, - 0x56ee4942, - 0x5720e202, - 0x57666002, - 0x57a0cac2, - 0x57e0e882, - 0x58203882, - 0x20c543, - 0x3af006, - 0x5861e484, - 0x21620a, - 0x3b0106, - 0x281284, - 0x208143, - 0x59216102, - 0x203182, - 0x241c83, - 0x59617fc3, - 0x3c49c7, - 0x394ec7, - 0x5c245ec7, - 0x37efc7, - 0x228803, - 0x22880a, - 0x237bc4, - 0x31ef04, - 0x31ef0a, - 0x22eb85, - 0x5c60e742, - 0x250343, - 0x5ca00602, - 0x24dfc3, - 0x3a24c3, - 0x5d200582, - 0x3c1744, - 0x207f84, - 0x3dcc45, - 0x32e9c5, - 0x2f6786, - 0x30a546, - 0x5d63bec2, - 0x5da02542, - 0x301dc5, - 0x258a52, - 0x363486, - 0x291043, - 0x31c146, - 0x2b6585, - 0x1605cc2, - 0x65e0fec2, - 0x377b43, - 0x20fec3, - 0x39f483, - 0x66201102, - 0x20f443, - 0x666035c2, - 0x207583, - 0x3dcf88, - 0x269543, - 0x2b0286, - 0x3da087, - 0x34f0c6, - 0x34f0cb, - 0x2811c7, - 0x2f6f04, - 0x66e00c02, - 0x2c1505, - 0x67217f83, - 0x235fc3, - 0x332505, - 0x34a9c3, - 0x67b4a9c6, - 0x3d048a, - 0x2a98c3, - 0x2371c4, + 0x3d687643, + 0x326909, + 0x280609, + 0x2c73c6, + 0x3da43543, + 0x2887cd, + 0x3a8e86, + 0x3e0e8b, + 0x3de087c2, + 0x2ac948, + 0x42221082, + 0x42601e02, + 0x398285, + 0x42a02642, + 0x2b3187, + 0x202983, + 0x2272c8, + 0x42e06002, + 0x3a9984, + 0x22a003, + 0x3532c5, + 0x2491c6, + 0x22cf04, + 0x230183, + 0x44205b42, + 0x35b3c4, + 0x2beb45, + 0x2bff07, + 0x285203, + 0x2c1443, + 0x1619e82, + 0x2c1b03, + 0x2c2103, + 0x44600e02, + 0x239104, + 0x23e306, + 0x288d83, + 0x2c2a83, + 0x44a54202, + 0x254208, + 0x2c3a04, + 0x2052c6, + 0x387d07, + 0x3d4dc6, + 0x2c0544, + 0x52e025c2, + 0x3e064b, + 0x30624e, + 0x2201cf, + 0x3bc5c3, + 0x536687c2, + 0x161ee02, + 0x53a01f42, + 0x2f9843, + 0x20b603, + 0x2732c6, + 0x2cb846, + 0x2bc847, + 0x3b7004, + 0x53e1f542, + 0x542258c2, + 0x302645, + 0x32a647, + 0x2c6106, + 0x5463d782, + 0x382f04, + 0x2cc083, + 0x54a07bc2, + 0x54f73803, + 0x2cd984, + 0x2d2249, + 0x552da042, + 0x55611b82, + 0x2876c5, + 0x55ada802, + 0x56205542, + 0x35fb87, + 0x37718b, + 0x24d645, + 0x264489, + 0x275d46, + 0x56608004, + 0x208009, + 0x2f9cc7, + 0x349887, + 0x205543, + 0x2f1a46, + 0x351887, + 0x24c243, + 0x2a4106, + 0x56e1f002, + 0x57225e82, + 0x217443, + 0x3a5145, + 0x21c307, + 0x23f286, + 0x38ef85, + 0x263104, + 0x2aee85, + 0x390bc4, + 0x5760b402, + 0x2d8d84, + 0x2cbe44, + 0x39c84d, + 0x2cbe49, + 0x237848, + 0x262c84, + 0x38d345, + 0x3c2307, + 0x3c2bc4, + 0x273847, + 0x228f05, + 0x57ab4484, + 0x2c5b45, + 0x26e104, + 0x316546, + 0x3b6005, + 0x57e6b2c2, + 0x225e43, + 0x333e43, + 0x2c8784, + 0x2c8785, + 0x208c86, + 0x235585, + 0x263944, + 0x58392e03, + 0x587d1a86, + 0x219405, + 0x21b385, + 0x3b6104, + 0x2f93c3, + 0x358ecc, + 0x58ac0002, + 0x58e00e82, + 0x59209d42, + 0x21b283, + 0x21b284, + 0x59610442, + 0x308108, + 0x2c4d05, + 0x2dafc4, + 0x359186, + 0x59a205c2, + 0x59e109c2, + 0x5a200c42, + 0x2a3c05, + 0x354806, + 0x232c84, + 0x236346, + 0x213186, + 0x25aa03, + 0x5a694b4a, + 0x2853c5, + 0x29b583, + 0x20f546, + 0x5aa0f549, + 0x22c4c7, + 0x3c8c08, + 0x3ce749, + 0x2b6048, + 0x209146, + 0x207cc3, + 0x5af1de42, + 0x32bd88, + 0x5b256e02, + 0x5b601582, + 0x233243, + 0x2efe85, + 0x280f44, + 0x3e27c9, + 0x386e04, + 0x38d188, + 0x5be10fc3, + 0x5c3a2ac4, + 0x21f448, + 0x5c70df02, + 0x2cf1c2, + 0x330cc5, + 0x34af09, + 0x216443, + 0x31b884, + 0x36e504, + 0x20b683, + 0x28bf8a, + 0x5cb0f082, + 0x5ce13fc2, + 0x2dc903, + 0x3939c3, + 0x1609382, + 0x35c243, + 0x5d228882, + 0x5d600bc2, + 0x5da8d4c4, + 0x28d4c6, + 0x276e84, + 0x283103, + 0x28f583, + 0x5de00bc3, + 0x248e46, + 0x3de805, + 0x2e0947, + 0x2e0886, + 0x2e0e48, + 0x2e1046, + 0x2239c4, + 0x2a6a8b, + 0x2e30c3, + 0x2e30c5, + 0x2165c2, + 0x35fe82, + 0x5e24f102, + 0x5e603742, + 0x20a083, + 0x5ea77782, + 0x277783, + 0x2e4103, + 0x5f2093c2, + 0x5f6e8306, + 0x35e3c6, + 0x5fae8442, + 0x5fe12202, + 0x60233ec2, + 0x60ea9542, + 0x61345342, + 0x61602802, + 0x20b0c3, + 0x3da086, + 0x61a1b544, + 0x2b130a, + 0x3b1d46, + 0x285084, + 0x202703, + 0x62606c02, + 0x204cc2, + 0x26f843, + 0x62a296c3, + 0x3c5847, + 0x3b5f07, + 0x67e60847, + 0x341607, + 0x232403, + 0x23240a, + 0x257204, + 0x31e544, + 0x31e54a, + 0x24a905, + 0x6823a382, + 0x2583c3, + 0x68600602, + 0x257743, + 0x386cc3, + 0x68e00582, + 0x283984, + 0x202544, + 0x2032c5, + 0x3301c5, + 0x236e86, + 0x2fb4c6, + 0x6924ba82, + 0x69601cc2, + 0x2f97c5, + 0x35e0d2, + 0x298a06, + 0x291c43, + 0x2b4ac6, + 0x2cf8c5, + 0x1603442, + 0x71a056c2, + 0x341143, + 0x212bc3, + 0x29c403, + 0x71e01102, + 0x21e803, + 0x7222d4c2, + 0x201d03, + 0x3b1008, + 0x241c43, + 0x2b5406, + 0x3e3047, + 0x34dbc6, + 0x34dbcb, + 0x284fc7, + 0x33ee44, + 0x72a00c02, + 0x2c4b85, + 0x72e2f483, + 0x23b843, + 0x39fd45, + 0x348ec3, + 0x73748ec6, + 0x3e514a, + 0x2ade43, + 0x213a04, 0x2003c6, - 0x2b1fc6, - 0x67e3e083, - 0x273987, - 0x26a647, - 0x2a3e85, - 0x2b2346, - 0x21a903, - 0x6aa25fc3, - 0x6ae00a82, - 0x6b20e9c4, - 0x213b49, - 0x226685, - 0x266e44, - 0x35a3c8, - 0x241e85, - 0x6b642285, - 0x247e89, - 0x3b4d43, - 0x349604, - 0x6ba05b42, - 0x216a43, - 0x6be75c42, - 0x275c46, - 0x167ce82, - 0x6c20c182, - 0x296448, - 0x29a743, - 0x2c5f87, - 0x384605, - 0x2be805, - 0x2be80b, - 0x2f0b06, - 0x2bea06, - 0x2804c4, - 0x211c86, - 0x6c6f1608, - 0x287403, - 0x25be43, - 0x25be44, - 0x2f0184, - 0x2f8747, - 0x318245, - 0x6cb20202, - 0x6ce04fc2, - 0x6d604fc5, - 0x2c6a84, - 0x2f114b, - 0x2f9188, - 0x306444, - 0x6da2c8c2, - 0x6de2d782, - 0x3c2f03, - 0x2faf84, - 0x2fb245, - 0x2fbd47, - 0x6e2fe604, - 0x390ec4, - 0x6e616982, - 0x380fc9, - 0x2ffa45, - 0x243bc5, - 0x3005c5, - 0x6ea16983, - 0x237e84, - 0x237e8b, - 0x3010c4, - 0x30138b, - 0x301f05, - 0x217bca, - 0x303dc8, - 0x303fca, - 0x304883, - 0x30488a, - 0x6f213982, - 0x6f642c42, - 0x6fa0d403, - 0x6fede302, - 0x307643, - 0x702f8442, - 0x70739c42, - 0x308544, - 0x218386, - 0x3350c5, - 0x30c343, - 0x32fc06, - 0x3a0645, - 0x366b44, - 0x70a00902, - 0x2ae704, - 0x2d810a, - 0x2c0587, - 0x34ad46, - 0x235407, - 0x23e883, - 0x2c92c8, - 0x3dc44b, - 0x2ce445, - 0x223585, - 0x223586, - 0x342604, - 0x3cd748, - 0x2198c3, - 0x28b144, - 0x3cdc87, - 0x2f6b46, - 0x314a06, - 0x2c86ca, - 0x24d544, - 0x3214ca, - 0x70f5ccc6, - 0x35ccc7, - 0x255d87, - 0x2ab784, - 0x34c349, - 0x238cc5, - 0x2f8343, - 0x2201c3, - 0x7121b843, - 0x231704, - 0x71600682, - 0x266886, - 0x71acbc45, - 0x31c385, - 0x2505c6, - 0x2a6184, - 0x71e02b02, - 0x2421c4, - 0x7220d782, - 0x20d785, - 0x37d504, - 0x7361a6c3, - 0x73a08382, - 0x208383, - 0x34d886, - 0x73e07742, - 0x399508, - 0x223e44, - 0x223e46, - 0x396906, - 0x74257784, - 0x217e05, - 0x368548, - 0x265c07, - 0x2b1087, - 0x2b108f, - 0x2980c6, - 0x23c0c3, - 0x23db04, - 0x219b43, - 0x222ac4, - 0x24c404, - 0x74606c82, - 0x2bef83, - 0x337143, - 0x74a08502, - 0x20cec3, - 0x30be83, - 0x21270a, - 0x279407, - 0x25070c, - 0x74e509c6, - 0x250b46, - 0x253b87, - 0x752302c7, - 0x259009, - 0x75666444, - 0x75a0a1c2, - 0x75e02442, - 0x2c8a86, - 0x273784, - 0x2bf406, - 0x230748, - 0x3926c4, - 0x2f7a46, - 0x2ada45, - 0x7628dc88, - 0x2424c3, - 0x292005, - 0x3ab143, - 0x243cc3, - 0x243cc4, - 0x21d2c3, - 0x7664b642, - 0x76a04782, - 0x2f8209, - 0x293a05, - 0x293d84, - 0x294545, - 0x210f44, - 0x28eec7, - 0x35ff05, - 0x772ddf84, - 0x2ddf88, - 0x2df1c6, - 0x2e5144, - 0x2e8988, - 0x2e8fc7, - 0x7760ab02, - 0x2f1004, - 0x219c04, - 0x2ceb87, - 0x77a0ab04, - 0x2670c2, - 0x77e0ee42, - 0x20ee43, - 0x248884, - 0x29a503, - 0x2b7085, - 0x78201442, - 0x308885, - 0x23cac2, - 0x312645, - 0x23cac5, - 0x786010c2, - 0x316a04, - 0x78a018c2, - 0x349086, - 0x25ab46, - 0x385648, - 0x2cf888, - 0x314c84, - 0x35a585, - 0x310489, - 0x39b604, - 0x3d0444, - 0x2132c3, - 0x237c83, - 0x78f1fb05, - 0x24fd85, - 0x28b044, - 0x35eacd, - 0x25cdc2, - 0x366543, - 0x79201702, - 0x79600ec2, - 0x398fc5, - 0x341947, - 0x227344, - 0x3c86c9, - 0x2d8249, - 0x25fc83, - 0x27ccc8, - 0x35d1c9, - 0x220f47, - 0x79b7b845, - 0x39d086, - 0x3a7d46, - 0x3ac645, - 0x2ee345, - 0x79e06242, - 0x28db85, - 0x2c4b48, - 0x2d1686, - 0x7a22aa87, - 0x2d1ec4, - 0x2d1447, - 0x30d006, - 0x7a603c02, - 0x39d206, - 0x311cca, - 0x312545, - 0x7aa30ac2, - 0x7ae92ec2, - 0x36c7c6, - 0x7b292ec7, - 0x7b60d982, - 0x242c83, - 0x3c75c6, - 0x2d0744, - 0x33ec86, - 0x24eac6, - 0x20290a, - 0x359945, - 0x35c986, - 0x38a183, - 0x38a184, - 0x7ba1cc42, - 0x28f183, - 0x7be1e202, - 0x2fccc3, - 0x7c215504, - 0x20de04, - 0x7c60de0a, - 0x219243, - 0x239747, - 0x315146, - 0x3670c4, - 0x281142, - 0x2ac982, - 0x7ca007c2, - 0x22b3c3, - 0x255b47, + 0x327f06, + 0x73a0cb83, + 0x20cb87, + 0x326807, + 0x2a8485, + 0x239706, + 0x217303, + 0x76626a03, + 0x76a00a82, + 0x76ec8044, + 0x2114c9, + 0x22f7c5, + 0x361cc4, + 0x31e288, + 0x24ac45, + 0x7724ccc5, + 0x255849, + 0x32e683, + 0x23d7c4, + 0x77608402, + 0x21f783, + 0x77a96dc2, + 0x296dc6, + 0x169a902, + 0x77e15982, + 0x2a3b08, + 0x2b3743, + 0x2c5a87, + 0x2c1b85, + 0x2c5645, + 0x34de4b, + 0x2f17c6, + 0x34e046, + 0x277304, + 0x219d06, + 0x782f1e48, + 0x28e543, + 0x265043, + 0x265044, + 0x2fa884, + 0x309447, + 0x3da945, + 0x786f8842, + 0x78a059c2, + 0x792059c5, + 0x2ca784, + 0x2fa9cb, + 0x2fd488, + 0x24bd04, + 0x796376c2, + 0x79a06bc2, + 0x206bc3, + 0x2ff644, + 0x2ff905, + 0x300487, + 0x79f02ac4, + 0x38bfc4, + 0x7a2037c2, + 0x37e5c9, + 0x303fc5, + 0x24d905, + 0x304b45, + 0x7a61f6c3, + 0x240644, + 0x24064b, + 0x305b04, + 0x305dcb, + 0x306745, + 0x22030a, + 0x307108, + 0x30730a, + 0x307b83, + 0x307b8a, + 0x7ae1a782, + 0x7b24cec2, + 0x7b604683, + 0x7bad3b02, + 0x309ec3, + 0x7bef57c2, + 0x7c33a842, + 0x30a904, + 0x2210c6, + 0x236085, + 0x30ccc3, + 0x3ce106, + 0x219045, + 0x35a504, + 0x7c600902, + 0x2b4004, + 0x2dcb8a, + 0x2c3687, + 0x349246, + 0x25d607, + 0x248783, + 0x2cd9c8, + 0x3e7ccb, + 0x221e45, + 0x36e645, + 0x36e646, + 0x2f8384, + 0x3df448, + 0x205703, + 0x2075c4, + 0x2075c7, + 0x33ea86, + 0x3a2e06, + 0x2ccdca, + 0x256b84, + 0x2c244a, + 0x7ca08dc6, + 0x208dc7, + 0x261947, + 0x266584, + 0x266589, + 0x336705, + 0x2f9c43, + 0x22a543, + 0x7ce264c3, + 0x23a044, + 0x7d200682, + 0x3d8986, + 0x7d6d05c5, + 0x2b4d05, + 0x25b746, + 0x31d704, + 0x7da12742, + 0x24b2c4, + 0x7de04a02, + 0x20c2c5, + 0x336884, + 0x7f22ccc3, + 0x7f609742, + 0x209743, + 0x21e946, + 0x7fa01ec2, + 0x397488, + 0x22c344, + 0x22c346, + 0x394246, + 0x7fe63084, + 0x21a7c5, + 0x22ef08, + 0x231dc7, + 0x326fc7, + 0x326fcf, + 0x29e286, + 0x23cc03, + 0x241684, + 0x20f843, + 0x22bbc4, + 0x252e44, + 0x80207f02, + 0x3747c3, + 0x337cc3, + 0x80602b02, + 0x204143, + 0x37d083, + 0x21878a, + 0x27eb47, + 0x258ecc, + 0x80a59186, + 0x25abc6, + 0x25bcc7, + 0x80e38747, + 0x262389, + 0x812fc684, + 0x8160a0c2, + 0x81a01702, + 0x2cd186, + 0x20c984, + 0x39e1c6, + 0x267ec8, + 0x3a5204, + 0x2f8ec6, + 0x2b2945, + 0x81e7c4c8, + 0x24c743, + 0x28a485, + 0x35d1c3, + 0x24da03, + 0x24da04, + 0x21dc43, + 0x82254642, + 0x826014c2, + 0x2f9b09, + 0x296cc5, + 0x3d4744, + 0x3e5745, + 0x20f244, + 0x37b3c7, + 0x338685, + 0x82ed1984, + 0x2d1988, + 0x2dd986, + 0x2e1dc4, + 0x2e1fc8, + 0x83204ac2, + 0x2f0d84, + 0x20f904, + 0x2d38c7, + 0x83605fc4, + 0x2171c2, + 0x83a0b5c2, + 0x20b5c3, + 0x2875c4, + 0x2512c3, + 0x2ba385, + 0x83e35542, + 0x30ac45, + 0x279c42, + 0x311f85, + 0x2db805, + 0x842010c2, + 0x332f04, + 0x84602d82, + 0x30dd46, + 0x2192c6, + 0x34b048, + 0x2d49c8, + 0x31e8c4, + 0x301805, + 0x2c0d09, + 0x2d2a44, + 0x3e5104, + 0x21f203, + 0x207383, + 0x84a07385, + 0x26fac5, + 0x269544, + 0x337d4d, + 0x352902, + 0x352903, + 0x84e04102, + 0x85200ec2, + 0x396f45, + 0x354c47, + 0x22d144, + 0x3ce949, + 0x2dccc9, + 0x282303, + 0x282308, + 0x246809, + 0x227d47, + 0x85755b45, + 0x3615c6, + 0x362786, + 0x365cc5, + 0x2cbf45, + 0x85a01c42, + 0x2930c5, + 0x2c9448, + 0x2d6a06, + 0x85ed7247, + 0x306984, + 0x2b9ac7, + 0x3b9106, + 0x8624b302, + 0x208986, + 0x31160a, + 0x311e85, + 0x86615a82, + 0x86a14442, + 0x278b86, + 0x86e97d07, + 0x8720c4c2, + 0x20a803, + 0x2250c6, + 0x2d5884, + 0x27ac86, + 0x32fa86, + 0x3a32ca, + 0x32e805, + 0x30d8c6, + 0x36c343, + 0x36c344, + 0x87603bc2, + 0x321303, + 0x87a1b2c2, + 0x31fec3, + 0x87e34c04, + 0x2d8284, + 0x883e380a, + 0x209203, + 0x326ac7, + 0x315106, + 0x38fa84, + 0x236d42, + 0x2b0982, + 0x886007c2, + 0x232a43, + 0x261707, 0x2007c7, - 0x28e544, - 0x3e2587, - 0x2fbe46, - 0x20f307, - 0x30bdc4, - 0x2e5d45, - 0x218ac5, - 0x7ce05682, - 0x216f86, - 0x227043, - 0x227ec2, - 0x227ec6, - 0x7d21c882, - 0x7d62dc42, - 0x238f85, - 0x7da03d02, - 0x7de02a82, - 0x353545, - 0x2d9845, - 0x2af105, - 0x7e65aa03, - 0x279185, - 0x2f0bc7, - 0x2b7945, - 0x359b05, - 0x268b84, - 0x266cc6, - 0x3944c4, - 0x7ea008c2, - 0x7f798885, - 0x3d0907, - 0x3a09c8, - 0x269f86, - 0x269f8d, - 0x26f7c9, - 0x26f7d2, - 0x34d185, - 0x380843, - 0x7fa03b42, - 0x31f9c4, - 0x22db83, - 0x393e85, - 0x313785, - 0x7fe1fcc2, - 0x259fc3, - 0x8022b302, - 0x80a1cac2, - 0x80e00082, - 0x2ec2c5, - 0x213fc3, - 0x81208f02, - 0x81604642, - 0x3c1706, - 0x27e1ca, - 0x20c6c3, - 0x257c83, - 0x2f7343, - 0x832072c2, - 0x9161f702, - 0x91e07ac2, - 0x2034c2, - 0x3d3d09, - 0x2d4584, - 0x2e1c88, - 0x92305102, - 0x92a01502, - 0x2c2285, - 0x234e88, - 0x2f65c8, - 0x2fb70c, - 0x239683, - 0x92e13f42, - 0x9320e482, - 0x2bce06, - 0x315fc5, - 0x2e5583, - 0x247cc6, - 0x316106, - 0x253383, - 0x317803, - 0x317c46, - 0x319484, - 0x26aa06, - 0x236444, - 0x319b44, - 0x31ad0a, - 0x936bb102, - 0x24e605, - 0x31c58a, - 0x31c4c5, - 0x31e504, - 0x31e606, - 0x31e784, - 0x216d06, - 0x93a03c42, - 0x2ecf86, - 0x358f85, - 0x35c807, - 0x3c7386, - 0x253d84, - 0x2e5807, - 0x21dfc5, - 0x21dfc7, - 0x3c3a87, - 0x3c3a8e, - 0x280bc6, - 0x2bda05, - 0x20aa47, - 0x20e243, - 0x20e247, - 0x228f05, - 0x22bfc4, - 0x368842, - 0x32a1c7, - 0x241184, - 0x32a684, - 0x3ab1cb, - 0x21ab83, - 0x2dd0c7, - 0x21ab84, - 0x2dd3c7, - 0x3ae243, - 0x34f8cd, - 0x3aa588, - 0x93e45f84, - 0x366dc5, - 0x31f345, - 0x31f783, - 0x94223d42, - 0x322283, - 0x322b03, - 0x217104, - 0x283c85, - 0x224e87, - 0x38a206, - 0x393c43, - 0x22ad4b, - 0x322c8b, - 0x283d8b, - 0x2b32cb, - 0x2c718a, - 0x2d184b, - 0x2f1b4b, - 0x35ab4c, - 0x319f4b, - 0x374b91, - 0x39ad0a, - 0x3b794b, - 0x3c694c, - 0x3df28b, - 0x3256ca, - 0x325bca, - 0x326a4e, - 0x3271cb, - 0x32748a, - 0x328a51, - 0x328e8a, - 0x32938b, - 0x3298ce, - 0x32b70c, - 0x32c34b, - 0x32c60e, - 0x32c98c, - 0x32d6ca, - 0x32ee8c, - 0x9472f18a, - 0x32fd88, - 0x330949, - 0x33308a, - 0x33330a, - 0x33358b, - 0x3368ce, - 0x337751, - 0x341dc9, - 0x34200a, - 0x342b4b, - 0x34348d, - 0x34430a, - 0x3455d6, - 0x34694b, - 0x349e0a, - 0x34a38a, - 0x34b28b, - 0x34cc09, - 0x350249, - 0x3507cd, - 0x3510cb, - 0x352bcb, - 0x353689, - 0x353cce, - 0x35410a, - 0x35a04a, - 0x35a7ca, - 0x35b18b, - 0x35b9cb, - 0x35e2cd, - 0x35fa0d, - 0x360310, - 0x3607cb, - 0x36210c, - 0x36288b, - 0x36494b, - 0x36614e, - 0x36660b, - 0x36660d, - 0x36d70b, - 0x36e18f, - 0x36e54b, - 0x36f50a, - 0x36fb09, - 0x370089, - 0x94b7040b, - 0x3706ce, - 0x370a4e, - 0x3726cb, - 0x37374f, - 0x375fcb, - 0x37628b, - 0x37654a, - 0x37af49, - 0x37fa0f, - 0x3841cc, - 0x384bcc, - 0x385ece, - 0x38644f, - 0x38680e, - 0x3871d0, - 0x3875cf, - 0x3883ce, - 0x388f0c, - 0x389211, - 0x389652, - 0x38b3d1, - 0x38be8e, - 0x38c2cb, - 0x38c2ce, - 0x38c64f, - 0x38ca0e, - 0x38cd93, - 0x38d251, - 0x38d68c, - 0x38d98e, - 0x38de0c, - 0x38e353, - 0x38f1d0, - 0x3902cc, - 0x3905cc, - 0x390a8b, - 0x391bce, - 0x3920cb, - 0x392e4b, - 0x39418c, - 0x399a4a, - 0x39a50c, - 0x39a80c, - 0x39ab09, - 0x39d68b, - 0x39d948, - 0x39e649, - 0x39e64f, - 0x39ff0b, - 0x94fa0bca, - 0x3a268c, - 0x3a364b, - 0x3a3909, - 0x3a3cc8, - 0x3a458b, - 0x3a688a, - 0x3a6b0b, - 0x3a700c, - 0x3a77c9, - 0x3a7a08, - 0x3ab48b, - 0x3aeb8b, - 0x3b0d0e, - 0x3b244b, - 0x3b72cb, - 0x3c360b, - 0x3c38c9, - 0x3c3e0d, - 0x3d148a, - 0x3d4917, - 0x3d5618, - 0x3d8989, - 0x3d9ccb, - 0x3daad4, - 0x3dafcb, - 0x3db54a, - 0x3dbc0a, - 0x3dbe8b, - 0x3dd190, - 0x3dd591, - 0x3ddc4a, - 0x3de88d, - 0x3def8d, - 0x3e104b, - 0x217083, - 0x953b3583, - 0x2b0f46, - 0x27ca85, - 0x29c647, - 0x384906, - 0x1602342, - 0x2b3609, - 0x32fa04, - 0x2efcc8, - 0x21b783, - 0x31f907, - 0x230902, - 0x2b8f03, - 0x95603602, - 0x2d8d06, - 0x2da3c4, - 0x377084, - 0x201c43, - 0x95ed56c2, - 0x9622c344, - 0x34c287, - 0x9662bf82, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0x106b48, - 0x205803, + 0x292704, + 0x258d47, + 0x300586, + 0x20ba87, + 0x230744, + 0x2b61c5, + 0x221c45, + 0x88a0d782, + 0x219e46, + 0x230bc3, + 0x29d6c2, + 0x2fc146, + 0x88e12682, + 0x89213402, + 0x213405, + 0x8962bdc2, + 0x89a02a02, + 0x351e45, + 0x2e3405, + 0x30a705, + 0x8a268b83, + 0x285845, + 0x2f1887, + 0x2b9385, + 0x32e9c5, + 0x257104, + 0x361b46, + 0x24e044, + 0x8a6008c2, + 0x8b2510c5, + 0x3967c7, + 0x213c08, + 0x27d046, + 0x27d04d, + 0x2803c9, + 0x2803d2, + 0x37e8c5, + 0x383403, + 0x8b6091c2, + 0x32f684, + 0x3a8f03, + 0x3d64c5, + 0x3136c5, + 0x8ba2a042, + 0x267d43, + 0x8be32982, + 0x8c629742, + 0x8ca00082, + 0x2ead45, + 0x39d643, + 0x8ce04942, + 0x8d206502, + 0x283946, + 0x2484ca, + 0x201c83, + 0x2638c3, + 0x2f2d43, + 0x8ee04a42, + 0x9d666342, + 0x9de0e002, + 0x205002, + 0x3d8109, + 0x2d9444, + 0x2e5488, + 0x9e308542, + 0x9ea017c2, + 0x393285, + 0x23d208, + 0x2f8088, + 0x30500c, + 0x241403, + 0x9ee6dac2, + 0x9f208e42, + 0x39dbc6, + 0x315f85, + 0x2e8c43, + 0x24cb06, + 0x3160c6, + 0x251403, + 0x317703, + 0x317dc6, + 0x319884, + 0x2a2446, + 0x34cd04, + 0x319f44, + 0x31aa0a, + 0x9f603582, + 0x257e85, + 0x31bfca, + 0x31bf05, + 0x31ce84, + 0x31cf86, + 0x31d104, + 0x21fa46, + 0x9fa16ec2, + 0x216ec6, + 0x271385, + 0x30d747, + 0x3c1346, + 0x25bec4, + 0x2e8ec7, + 0x2089c5, + 0x242c07, + 0x228947, + 0x22894e, + 0x2849c6, + 0x2b6dc5, + 0x205f07, + 0x3c3947, + 0x212d85, + 0x229b84, + 0x3235c2, + 0x23d887, + 0x249e04, + 0x35a784, + 0x2cf04b, + 0x9fe246c3, + 0x301387, + 0x2246c4, + 0x301687, + 0x310883, + 0x34e54d, + 0x3ad188, + 0xa0233984, + 0x3e16c5, + 0x31f985, + 0x31fdc3, + 0xa0608f02, + 0x3212c3, + 0x321a83, + 0x215ac4, + 0x289085, + 0x219fc7, + 0x36c3c6, + 0x390a43, + 0x233f0b, + 0x35be8b, + 0x2b504b, + 0x2cae8b, + 0x3991ca, + 0x2d6bcb, + 0x2f228b, + 0x32178c, + 0x31a34b, + 0x370491, + 0x398e4a, + 0x3b8a4b, + 0x3c95cc, + 0x3e6f4b, + 0x3230ca, + 0x323f4a, + 0x324dce, + 0x325a4b, + 0x325d0a, + 0x328911, + 0x328d4a, + 0x32924b, + 0x32978e, + 0x32a14c, + 0x32ae8b, + 0x32b14e, + 0x32b4cc, + 0x32ef0a, + 0x33068c, + 0xa0b3098a, + 0x331288, + 0x331e49, + 0x3348ca, + 0x334b4a, + 0x334dcb, + 0x33744e, + 0x338091, + 0x341cc9, + 0x341f0a, + 0x342c8b, + 0x343dcd, + 0x344c4a, + 0x345616, + 0x34698b, + 0x34844a, + 0x34888a, + 0x34a48b, + 0x34b2c9, + 0x34eec9, + 0x34f44d, + 0x34fc0b, + 0x3514cb, + 0x351f89, + 0x3525ce, + 0x3529ca, + 0x3550ca, + 0x35590a, + 0x3562cb, + 0x356b0b, + 0x35798d, + 0x359fcd, + 0x35a910, + 0x35adcb, + 0x35bacc, + 0x35cc8b, + 0x35f68b, + 0x3611ce, + 0x3617cb, + 0x3617cd, + 0x36740b, + 0x367e8f, + 0x36824b, + 0x36918a, + 0x369f49, + 0x36ab49, + 0xa0f6aecb, + 0x36b18e, + 0x36b50e, + 0x36e28b, + 0x36f04f, + 0x3718cb, + 0x371b8b, + 0x371e4a, + 0x376d89, + 0x37c74f, + 0x381d4c, + 0x38298c, + 0x3830ce, + 0x3835cf, + 0x38398e, + 0x383e10, + 0x38420f, + 0x384bce, + 0x38528c, + 0x385591, + 0x3859d2, + 0x387891, + 0x387ece, + 0x38830b, + 0x38830e, + 0x38868f, + 0x388a4e, + 0x388dd3, + 0x389291, + 0x3896cc, + 0x3899ce, + 0x389e4c, + 0x38a293, + 0x38af50, + 0x38b3cc, + 0x38b6cc, + 0x38bb8b, + 0x38e58e, + 0x38ea8b, + 0x38f2cb, + 0x39150c, + 0x3979ca, + 0x39864c, + 0x39894c, + 0x398c49, + 0x39ac8b, + 0x39af48, + 0x39b509, + 0x39b50f, + 0x39cf4b, + 0xa139e64a, + 0x3a3a0c, + 0x3a49cb, + 0x3a4c89, + 0x3a56c8, + 0x3a630b, + 0x3a810a, + 0x3a838b, + 0x3a9b0c, + 0x3aa649, + 0x3aa888, + 0x3ad7cb, + 0x3b0a4b, + 0x3b2e0e, + 0x3b494b, + 0x3b83cb, + 0x3c420b, + 0x3c44c9, + 0x3c488d, + 0x3d57ca, + 0x3d9857, + 0x3da218, + 0x3dc0c9, + 0x3de3cb, + 0x3df714, + 0x3dfc0b, + 0x3e018a, + 0x3e2a0a, + 0x3e2c8b, + 0x3e4810, + 0x3e4c11, + 0x3e5a4a, + 0x3e654d, + 0x3e6c4d, + 0x3e940b, + 0x219f43, + 0xa17b5883, + 0x3cc686, + 0x3df0c5, + 0x27a587, + 0x2ddec6, + 0x164bf82, + 0x2729c9, + 0x20c004, + 0x2f0788, + 0x226403, + 0x32f5c7, + 0x247f82, + 0x2bbdc3, + 0xa1a0e042, + 0x2dd846, + 0x2defc4, + 0x2c8404, + 0x3a0f43, + 0xa22da842, + 0xa262f444, + 0x2664c7, + 0xa2a35b02, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x117bc8, + 0x20d903, 0x2000c2, - 0xae888, - 0x212402, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x5803, - 0x23e083, - 0x208503, - 0x33cb96, - 0x36c093, - 0x3e2409, - 0x215d88, - 0x2c1389, - 0x31c706, - 0x3520d0, - 0x212113, - 0x2f6c08, - 0x282247, - 0x28d487, - 0x2aaa8a, - 0x36a609, - 0x3573c9, - 0x24cd4b, - 0x34b706, - 0x32ce4a, - 0x221106, - 0x32f603, - 0x2e4d05, - 0x20f4c8, - 0x28598d, - 0x2f45cc, - 0x3033c7, - 0x30e60d, - 0x215e84, - 0x2319ca, - 0x23248a, - 0x23294a, - 0x212407, - 0x23ce87, - 0x2410c4, - 0x269c06, - 0x35d584, - 0x305988, - 0x3c0509, - 0x2e9f06, - 0x2e9f08, - 0x24400d, - 0x2d8489, - 0x397c88, - 0x243b47, - 0x33230a, - 0x251186, - 0x2ff544, - 0x225c07, - 0x266a8a, - 0x23fb8e, - 0x246145, - 0x3dd98b, - 0x22b109, - 0x247109, - 0x205447, - 0x20544a, - 0x2ceac7, - 0x301949, - 0x347c88, - 0x33284b, - 0x2ee705, - 0x22c90a, - 0x265dc9, - 0x3568ca, - 0x21b8cb, - 0x225b0b, - 0x24cad5, - 0x2ce085, - 0x243bc5, - 0x237e8a, - 0x2527ca, - 0x321a07, - 0x234fc3, - 0x2c8a08, - 0x2e32ca, - 0x223e46, - 0x256689, - 0x28dc88, - 0x2e5144, - 0x38e109, - 0x2cf888, - 0x2d05c7, - 0x398886, - 0x3d0907, - 0x2c51c7, - 0x2401c5, - 0x245f8c, - 0x366dc5, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x5803, - 0x23e083, - 0x212402, - 0x22ea43, - 0x217fc3, - 0x205803, - 0x23e083, - 0x22ea43, - 0x217fc3, - 0x5803, - 0x269543, - 0x23e083, - 0x1d1843, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x5803, - 0x23e083, - 0xae888, - 0x212402, - 0x22ea43, - 0x22ea47, - 0x8ecc4, - 0x217fc3, - 0x1b5c04, - 0x23e083, - 0x212402, - 0x204542, - 0x2f6e82, - 0x2022c2, - 0x202582, - 0x2f2402, - 0x96206, - 0x51709, - 0xe9bc7, - 0x481a6c3, - 0x8e8c7, - 0x154546, - 0xaa43, - 0x11eec5, + 0x793c8, + 0x216542, + 0x343b43, + 0x216443, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x202b03, + 0x33d956, + 0x365753, + 0x258bc9, + 0x2b0e88, + 0x2c4a09, + 0x31c146, + 0x3509d0, + 0x218053, + 0x33eb48, + 0x285c87, + 0x2929c7, + 0x2aebca, + 0x363749, + 0x333bc9, + 0x25dd0b, + 0x34a906, + 0x32b98a, + 0x22ac46, + 0x238c43, + 0x231805, + 0x206c48, + 0x28b04d, + 0x35434c, + 0x271047, + 0x309f4d, + 0x22f004, + 0x23a30a, + 0x23b0ca, + 0x23b58a, + 0x218347, + 0x2461c7, + 0x249d44, + 0x279ec6, + 0x34abc4, + 0x222bc8, + 0x386e49, + 0x209a46, + 0x308cc8, + 0x24dd4d, + 0x2dcf09, + 0x318348, + 0x24d887, + 0x21364a, + 0x25bb46, + 0x34bbc4, + 0x2298c7, + 0x3d8b8a, + 0x242f8e, + 0x2823c5, + 0x29788b, + 0x232789, + 0x280609, + 0x20d547, + 0x20d54a, + 0x2d3807, + 0x306389, + 0x37b048, + 0x37948b, + 0x2efe85, + 0x23770a, + 0x233c89, + 0x33324a, + 0x22654b, + 0x2297cb, + 0x25da95, + 0x2f0c45, + 0x24d905, + 0x24064a, + 0x26ba4a, + 0x390f47, + 0x23d343, + 0x2cd108, + 0x2e640a, + 0x22c346, + 0x261289, + 0x27c4c8, + 0x2e1dc4, + 0x2512c9, + 0x2d49c8, + 0x2d5707, + 0x2510c6, + 0x3967c7, + 0x399b07, + 0x248c45, + 0x37500c, + 0x3e16c5, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x216542, + 0x216543, + 0x2296c3, + 0x20d903, + 0x20cb83, + 0x216543, + 0x2296c3, + 0xd903, + 0x241c43, + 0x20cb83, + 0x1d5b83, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x793c8, + 0x216542, + 0x216543, + 0x3a8607, + 0x17b1c4, + 0x2296c3, + 0xbbc4, + 0x20cb83, + 0x19045, + 0x216542, + 0x2104c2, + 0x31d0c2, + 0x206002, + 0x205c02, + 0x2160c2, + 0x9a6c6, + 0x5c549, + 0x182487, + 0x1550e, + 0x99049, + 0x482ccc3, + 0x95c87, + 0x152e06, + 0x1643, + 0x11e505, 0xc1, - 0x522ea43, - 0x233fc3, - 0x280203, - 0x266a83, - 0x2191c3, - 0x23cb03, - 0x2e4c06, - 0x217fc3, - 0x23e083, - 0x234f43, - 0xae888, - 0x3b46c4, - 0x324547, - 0x201c83, - 0x39e284, - 0x2052c3, - 0x2054c3, - 0x266a83, - 0x178d87, + 0x5216543, + 0x222bc3, + 0x2f5503, + 0x343b43, + 0x243543, + 0x216443, + 0x2e8706, + 0x2296c3, + 0x20cb83, + 0x202883, + 0x793c8, + 0x209b84, + 0x3a2887, + 0x3a0f83, + 0x25e704, + 0x20d3c3, + 0x20d5c3, + 0x343b43, + 0xb46c7, 0x9c4, - 0x157bc3, - 0x2105, + 0x12db83, + 0x10e645, 0x66000c2, - 0x4ac43, - 0x6a12402, - 0x6e8b749, - 0x7091e09, - 0x923cd, - 0x9270d, - 0x2f6e82, - 0xe704, - 0x2149, + 0x53c43, + 0x6a16542, + 0x6e90b89, + 0x7096ac9, + 0x96f4d, + 0x9728d, + 0x31d0c2, + 0xb1b84, + 0x10e689, 0x2003c2, - 0x7623188, - 0x100ac4, - 0x320c03, - 0xae888, - 0x41184, - 0x140ea82, + 0x76b1a88, + 0x105504, + 0x320b43, + 0x793c8, + 0x49e04, + 0x1407242, 0x14005c2, - 0x140ea82, - 0x1519d46, - 0x230983, - 0x276243, - 0x7e2ea43, - 0x2319c4, - 0x8233fc3, - 0x8a66a83, - 0x209582, - 0x20e704, - 0x217fc3, - 0x3319c3, - 0x209282, - 0x23e083, - 0x2188c2, - 0x308483, - 0x207742, - 0x203b83, - 0x222403, - 0x207d02, - 0xae888, - 0x230983, - 0x210448, - 0x87319c3, - 0x209282, - 0x308483, - 0x207742, - 0x203b83, - 0x222403, - 0x207d02, - 0x2509c7, - 0x308483, - 0x207742, - 0x203b83, - 0x222403, - 0x207d02, - 0x22ea43, - 0x6c02, - 0xf4c3, - 0x31c2, - 0x293c2, - 0x4d82, - 0x8c82, - 0x72c2, - 0x43d42, - 0x24ac43, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x2191c3, - 0x23cb03, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x201b02, - 0x216983, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0x24ac43, - 0x212402, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x217fc3, - 0x23e083, - 0x37b845, - 0x21fcc2, + 0x1407242, + 0x151a146, + 0x23bb83, + 0x2cc803, + 0x7e16543, + 0x23a304, + 0x8622bc3, + 0x8f43b43, + 0x2042c2, + 0x2b1b84, + 0x2296c3, + 0x38c643, + 0x203c82, + 0x20cb83, + 0x221a42, + 0x30a303, + 0x201ec2, + 0x26a603, + 0x220b03, + 0x2089c2, + 0x793c8, + 0x82fdcc9, + 0x27b43, + 0x23bb83, + 0x20b2c8, + 0x8b8c643, + 0x203c82, + 0x30a303, + 0x201ec2, + 0x26a603, + 0x220b03, + 0x2089c2, + 0x259187, + 0x30a303, + 0x201ec2, + 0x26a603, + 0x220b03, + 0x2089c2, + 0x216543, + 0x4702, + 0x6c43, + 0x2bc2, + 0x13242, + 0xe8c2, + 0x11de42, + 0x4a42, + 0x4da82, + 0x253c43, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x243543, + 0x216443, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x204642, + 0x21f6c3, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x8503, + 0x2d4c2, + 0x253c43, + 0x216542, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x2296c3, + 0x20cb83, + 0x355b45, + 0x22a042, 0x2000c2, - 0xae888, - 0x1454408, - 0x7b64a, - 0x266a83, - 0x202881, + 0x793c8, + 0xaec0ad2, + 0x1472588, + 0x1b2b8a, + 0x3ec5, + 0x343b43, + 0x230d41, 0x2009c1, 0x200a01, - 0x201781, - 0x202101, - 0x20bac1, - 0x201d01, - 0x203001, - 0x230d41, + 0x202c41, + 0x201b41, + 0x211101, + 0x209c01, + 0x230e41, + 0x2fd181, 0x200001, 0x2000c1, 0x200201, - 0x146bc5, - 0xae888, + 0x146c05, + 0x793c8, 0x200101, 0x201381, 0x200501, @@ -2344,7257 +2355,7413 @@ var nodes = [...]uint32{ 0x200581, 0x2003c1, 0x200a81, - 0x20c241, + 0x2210c1, 0x200401, 0x200741, 0x2007c1, 0x200081, - 0x201501, - 0x207d01, - 0x20a8c1, - 0x202341, - 0x201c41, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x212402, - 0x22ea43, - 0x233fc3, + 0x2017c1, + 0x201641, + 0x207281, + 0x2024c1, + 0x208481, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x216542, + 0x216543, + 0x222bc3, 0x2003c2, - 0x23e083, - 0x1a083, - 0x178d87, - 0x7f3c7, - 0x36fc6, - 0x3a8ca, - 0x91248, - 0x54d88, - 0x55a47, - 0x6e8c6, - 0xec7c5, - 0x1b5a05, - 0x129783, - 0x13a06, - 0x134c46, - 0x24cd44, - 0x334907, - 0xae888, - 0x2e5904, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x12402, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x32f388, - 0x207d44, - 0x233f04, - 0x204cc4, - 0x2bcd07, - 0x2e21c7, - 0x22ea43, - 0x23670b, - 0x323dca, - 0x34b9c7, - 0x238548, - 0x354a88, - 0x233fc3, - 0x25e4c7, - 0x280203, - 0x211448, - 0x212e49, - 0x20e704, - 0x2191c3, - 0x23b948, - 0x23cb03, - 0x2dfb4a, - 0x2e4c06, - 0x3b0107, - 0x217fc3, - 0x323606, - 0x2760c8, - 0x23e083, - 0x257546, - 0x2f93cd, - 0x2fba08, - 0x3010cb, - 0x2b2946, - 0x341847, - 0x21ecc5, - 0x3da84a, - 0x22ac05, - 0x24fc8a, - 0x21fcc2, - 0x20aa43, - 0x32a684, + 0x20cb83, + 0x22a83, + 0xb46c7, + 0x1cdf07, + 0x32f46, + 0x4280a, + 0x95748, + 0x60c88, + 0x61607, + 0xbc3c4, + 0x15c246, + 0xeec85, + 0x10f7c5, + 0x129643, + 0x30846, + 0x13906, + 0x25dd04, + 0x336147, + 0x793c8, + 0x2e8fc4, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x16542, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x330b88, + 0x202304, + 0x23c4c4, + 0x20e804, + 0x39dac7, + 0x2e59c7, + 0x216543, + 0x23ec8b, + 0x33100a, + 0x38f947, + 0x300288, + 0x353348, + 0x222bc3, + 0x3c2e87, + 0x2f5503, + 0x214fc8, + 0x224309, + 0x2b1b84, + 0x243543, + 0x244688, + 0x216443, + 0x2e320a, + 0x2e8706, + 0x3b1d47, + 0x2296c3, + 0x2f1b46, + 0x3d2288, + 0x20cb83, + 0x275546, + 0x2fd6cd, + 0x2ffe48, + 0x305b0b, + 0x223bc6, + 0x354b47, + 0x21d985, + 0x22e68a, + 0x2fce05, + 0x26f9ca, + 0x22a042, + 0x201643, + 0x35a784, 0x200006, - 0x3ba683, - 0x2ae783, - 0x281bc3, - 0x207d43, - 0x323a43, - 0x2029c2, - 0x309b85, - 0x2b07c9, - 0x201ac3, - 0x240843, - 0x233f03, - 0x232283, + 0x3bb603, + 0x2b4083, + 0x28bb03, + 0x202303, + 0x37a403, + 0x202002, + 0x39d805, + 0x2b5949, + 0x209983, + 0x2492c3, + 0x203b43, + 0x216c43, 0x200201, - 0x39b3c7, - 0x2ec005, - 0x3c2003, - 0x2a4d43, - 0x3dff03, - 0x204cc4, - 0x356e43, - 0x227608, - 0x322bc3, - 0x310c4d, - 0x280c88, - 0x210606, - 0x28f1c3, - 0x366903, - 0x394443, - 0xce2ea43, - 0x233808, - 0x236704, - 0x23d3c3, - 0x241283, + 0x2d2807, + 0x2eaa85, + 0x3c1fc3, + 0x26b383, + 0x3e9683, + 0x20e804, + 0x3c3303, + 0x2271c8, + 0x35bdc3, + 0x3e1ecd, + 0x284a88, + 0x20b486, + 0x2e9443, + 0x35a2c3, + 0x361ac3, + 0xda16543, + 0x23bdc8, + 0x23ec84, + 0x247203, + 0x249f03, 0x200106, - 0x244e88, - 0x20f983, - 0x21fa43, - 0x2b6ec3, - 0x222383, - 0x3da883, - 0x22f203, - 0x233fc3, - 0x22d003, - 0x249203, - 0x24cbc3, - 0x28b003, - 0x28f143, - 0x20a003, + 0x24e888, + 0x266943, + 0x228fc3, + 0x2ba1c3, + 0x220a83, + 0x22e6c3, + 0x23a543, + 0x222bc3, + 0x22d743, + 0x255ec3, + 0x209a43, + 0x290583, + 0x325243, + 0x20ae83, + 0x232d43, + 0x3a4e85, + 0x25c504, + 0x25dfc7, + 0x25c082, + 0x260183, + 0x263c46, 0x265743, - 0x392345, - 0x2516c4, - 0x252a47, - 0x2ba882, - 0x254b03, - 0x258106, - 0x259243, - 0x259c43, - 0x27cc83, - 0x26f183, - 0x20b183, - 0x3b43c3, - 0x29d847, - 0xd266a83, - 0x2c3fc3, - 0x28f203, - 0x204903, - 0x20e703, - 0x2ed2c3, - 0x20e905, - 0x37fd83, - 0x24b709, + 0x266c03, + 0x2822c3, + 0x35cb03, + 0x21fb43, + 0x32d103, + 0x2a1807, + 0xe743b43, + 0x2d3103, + 0x207c83, + 0x20e443, + 0x26a7c3, + 0x217203, + 0x3b5945, + 0x37cac3, + 0x252749, 0x2012c3, - 0x313a83, - 0xd63cb83, - 0x2d5e43, - 0x204d03, - 0x218bc8, - 0x2b0706, - 0x26ef46, - 0x2ba8c6, - 0x38f887, - 0x205e03, - 0x215f83, - 0x23cb03, - 0x291346, - 0x20e982, - 0x2b8a83, - 0x33b645, - 0x217fc3, - 0x31da07, - 0x1605803, - 0x2760c3, - 0x212483, - 0x232383, - 0x235fc3, - 0x23e083, - 0x21d506, - 0x3b5d46, - 0x380703, - 0x2fa583, - 0x216983, - 0x250983, - 0x317883, - 0x306d43, - 0x308843, - 0x3a0645, - 0x235403, - 0x3b2a86, - 0x221d43, - 0x27fc88, - 0x2201c3, - 0x2201c9, - 0x273288, - 0x221e48, - 0x225645, - 0x36000a, - 0x38e84a, - 0x22f98b, - 0x238108, - 0x294983, - 0x2f2a03, - 0x393d83, - 0x39fa83, - 0x316248, - 0x37a903, - 0x38a184, - 0x21cc42, - 0x20de03, - 0x260e03, + 0x3139c3, + 0xea53203, + 0x2daf43, + 0x20e843, + 0x214808, + 0x2b5886, + 0x35c8c6, + 0x2be186, + 0x267347, + 0x202143, + 0x233243, + 0x216443, + 0x295846, + 0x2165c2, + 0x2e69c3, + 0x33c405, + 0x2296c3, + 0x31c887, + 0x160d903, + 0x29ae43, + 0x2183c3, + 0x23c9c3, + 0x23b843, + 0x20cb83, + 0x21de86, + 0x202fc6, + 0x37db83, + 0x29a8c3, + 0x21f6c3, + 0x259143, + 0x317783, + 0x309603, + 0x30ac03, + 0x219045, + 0x24c343, + 0x250046, + 0x21b103, + 0x2f4f88, + 0x22a543, + 0x22a549, + 0x37ad08, + 0x220548, + 0x22eac5, + 0x38ac4a, + 0x3e08ca, + 0x3e110b, + 0x3e1ac8, + 0x2aa6c3, + 0x230143, + 0x390b83, + 0x2f34c3, + 0x312588, + 0x355303, + 0x36c344, + 0x203bc2, + 0x22e683, + 0x24c0c3, 0x2007c3, - 0x22dc43, - 0x27b143, - 0x234f43, - 0x21fcc2, - 0x22b8c3, - 0x239683, - 0x319ec3, - 0x31b744, - 0x32a684, - 0x21cb03, - 0xae888, + 0x3d8883, + 0x281003, + 0x202883, + 0x22a042, + 0x2d3703, + 0x241403, + 0x31a2c3, + 0x31b444, + 0x35a784, + 0x227083, + 0x793c8, + 0xdf1854c, + 0xe2ac245, + 0xbb705, 0x2000c2, 0x200ac2, - 0x2029c2, - 0x201802, + 0x202002, + 0x202cc2, 0x200202, - 0x205082, - 0x249382, - 0x2031c2, + 0x202402, + 0x250cc2, + 0x202bc2, 0x200382, 0x200c42, - 0x349242, - 0x20a942, - 0x2720c2, + 0x30df02, + 0x203742, + 0x277782, 0x200a82, - 0x2f2402, - 0x205b42, - 0x211c82, - 0x216982, - 0x206002, - 0x205502, + 0x2160c2, + 0x208402, + 0x219d02, + 0x2037c2, + 0x2cb042, + 0x205d42, 0x200682, - 0x2113c2, + 0x214f42, + 0x212742, 0x202b02, - 0x208502, - 0x202442, - 0x207142, - 0x202a82, + 0x201702, + 0x203782, + 0x202a02, 0xc2, 0xac2, - 0x29c2, - 0x1802, + 0x2002, + 0x2cc2, 0x202, - 0x5082, - 0x49382, - 0x31c2, + 0x2402, + 0x50cc2, + 0x2bc2, 0x382, 0xc42, - 0x149242, - 0xa942, - 0x720c2, + 0x10df02, + 0x3742, + 0x77782, 0xa82, - 0xf2402, - 0x5b42, - 0x11c82, - 0x16982, - 0x6002, - 0x5502, + 0x160c2, + 0x8402, + 0x19d02, + 0x37c2, + 0xcb042, + 0x5d42, 0x682, - 0x113c2, + 0x14f42, + 0x12742, 0x2b02, - 0x8502, - 0x2442, - 0x7142, - 0x2a82, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x83c2, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x12402, - 0x212402, - 0x23e083, - 0xee2ea43, - 0x266a83, - 0x23cb03, - 0x1c0443, - 0x230242, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x5803, - 0x1c0443, - 0x23e083, - 0x3602, + 0x1702, + 0x3782, + 0x2a02, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x1642, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x16542, + 0x216542, + 0x20cb83, + 0x10216543, + 0x343b43, + 0x216443, + 0xeb2c7, + 0x7ca83, + 0x2386c2, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x30103, + 0x2296c3, + 0xd903, + 0x7ca83, + 0x20cb83, + 0xe042, 0x2001c2, - 0x1567b85, - 0x146bc5, - 0x210402, - 0xae888, - 0x12402, - 0x2359c2, - 0x206b02, - 0x208142, - 0x20e742, - 0x23bec2, - 0x1b5a05, - 0x201402, - 0x209282, + 0x15ca1c5, + 0x146c05, + 0x20cd42, + 0x793c8, + 0x16542, + 0x23dec2, + 0x204202, + 0x202702, + 0x23a382, + 0x24ba82, + 0x10f7c5, + 0x201482, + 0x203c82, 0x201102, - 0x2053c2, - 0x205b42, - 0x2408c2, - 0x20ee42, - 0x256382, - 0xfe72cc4, + 0x203382, + 0x208402, + 0x2473c2, + 0x20b5c2, + 0x21c282, + 0x11278384, 0x142, - 0x178d87, - 0x30a83, - 0x12808d, - 0xec849, - 0x118a0b, - 0xf0a88, - 0x5bd09, - 0x1145c6, - 0x266a83, - 0xae888, + 0xb46c7, + 0x15a43, + 0x1b63cd, + 0xeed09, + 0xef94b, + 0xf1748, + 0x64f09, + 0x114786, + 0x343b43, + 0x793c8, 0x9c4, - 0x157bc3, - 0x2105, - 0xae888, - 0xe7607, - 0x1104d007, - 0x56546, - 0x2149, - 0xa28e, - 0x14ca47, - 0x150e583, + 0x12db83, + 0x10e645, + 0x793c8, + 0xebe47, + 0x12455f47, + 0x12a5f244, + 0x62246, + 0x10e689, + 0xb448e, + 0x13e247, + 0x15d8303, + 0x12e0ad42, + 0x9989, + 0xa144, 0x2000c2, - 0x24cd44, - 0x212402, - 0x22ea43, - 0x204542, - 0x233fc3, - 0xfa03, + 0x25dd04, + 0x216542, + 0x216543, + 0x2104c2, + 0x222bc3, + 0x1a003, 0x200382, - 0x2e5904, - 0x2191c3, - 0x206a02, - 0x217fc3, - 0x3bec2, + 0x2e8fc4, + 0x243543, + 0x256e02, + 0x2296c3, + 0x4ba82, 0x2003c2, - 0x23e083, - 0x243bc6, - 0x333b4f, + 0x20cb83, + 0x24d906, + 0x33538f, 0x602, - 0x72a143, - 0x2f3c0a, - 0xae888, - 0x212402, - 0x280203, - 0x266a83, - 0x23cb03, - 0x5803, - 0x1522f06, - 0x1c4104, - 0xa288, - 0x140dbcb, - 0x156c4ca, - 0xf3289, - 0x15da64a, - 0x1513f07, - 0xaab4b, - 0x10d4c5, - 0xf0545, - 0x11d749, - 0x146bc5, - 0x178d87, - 0x1c4104, - 0xfe2c4, - 0x212402, - 0x22ea43, - 0x266a83, - 0x217fc3, + 0x723543, + 0x2f5dca, + 0x793c8, + 0x216542, + 0x2f5503, + 0x343b43, + 0x216443, + 0xd903, + 0x147b5e07, + 0x157cd06, + 0x13f046, + 0x14bc4b88, + 0x1db944, + 0x14ebe40a, + 0x15abe40d, + 0xb4488, + 0x142e44b, + 0x147888a, + 0x15c66b43, + 0xf3949, + 0x16104b48, + 0x1664c347, + 0x15e360a, + 0x1513e47, + 0xaec8b, + 0x16a9068c, + 0xa5545, + 0xcf9c5, + 0x11c5c9, + 0x1a0c84, + 0x117703, + 0x152be545, + 0x124443, + 0x15635c43, + 0x124443, + 0x1d7607, + 0x2bdc2, + 0x6502, + 0x6502, + 0x4182, + 0x6502, + 0x4a42, + 0xd42, + 0x3242, + 0x146c05, + 0xb46c7, + 0x1db944, + 0x102784, + 0x216542, + 0x216543, + 0x343b43, + 0x2296c3, 0x2000c2, 0x200c82, - 0x205102, - 0x1362ea43, - 0x23d542, - 0x233fc3, + 0x206342, + 0x17a16543, + 0x247382, + 0x222bc3, 0x201282, - 0x208882, - 0x266a83, - 0x23ca82, - 0x27b882, - 0x22c302, + 0x234402, + 0x343b43, + 0x2038c2, + 0x271cc2, + 0x22f402, 0x200cc2, - 0x295f42, + 0x29a402, 0x200802, 0x200d82, - 0x25b542, - 0x2295c2, - 0x205742, - 0x13150c, - 0x2be4c2, - 0x250d42, - 0x227082, - 0x24a282, - 0x23cb03, + 0x205102, + 0x2870c2, + 0x2027c2, + 0x132a0c, + 0x2c1442, + 0x25adc2, + 0x230c02, + 0x253582, + 0x216443, 0x200bc2, - 0x217fc3, - 0x209ec2, - 0x25c042, - 0x23e083, - 0x3081c2, - 0x208502, - 0x20a1c2, - 0x204782, + 0x2296c3, + 0x20f502, + 0x298642, + 0x20cb83, + 0x249342, + 0x202b02, + 0x20a0c2, + 0x2014c2, 0x2010c2, - 0x230ac2, - 0x205682, - 0x22b302, - 0x2270c2, - 0x32748a, - 0x36f50a, - 0x3a124a, - 0x3e2d42, - 0x208902, - 0x20e8c2, - 0x13aa7f09, - 0x13f61e8a, - 0x142fc47, - 0x142050c2, - 0x143a083, - 0x1742, - 0x161e8a, - 0x162b0e, - 0x241ec4, - 0x57fc5, - 0x14a2ea43, - 0x3dc03, - 0x233fc3, - 0x24d704, - 0x266a83, - 0x20e704, - 0x2191c3, - 0x13d289, - 0x157686, - 0x23cb03, - 0xf1584, - 0x1598c3, - 0x217fc3, - 0x2a7c5, - 0x205803, - 0x23e083, - 0x1466d84, - 0x235403, - 0x181584, - 0x20aa43, - 0xae888, - 0x154f043, - 0x12a086, - 0x146e844, - 0x1a45, - 0x14c80a, - 0x124d82, - 0x15408acd, - 0x1adec6, - 0x159a140b, - 0xc951, - 0x15ea7f09, - 0x1ac8, - 0x69908, - 0x1c9415c7, - 0x3502, - 0xa8087, - 0x221ce, - 0x146bcb, - 0x14a88b, - 0x1c008a, - 0x1683c7, - 0xae888, - 0x120d48, - 0xa807, - 0x1cc176cb, - 0x1a087, - 0xcfc2, - 0x2b20d, - 0x16a7c7, - 0xb1bca, - 0x1e174f, - 0x12308f, - 0x161e82, - 0x12402, - 0x8af48, - 0x1d10778c, - 0x1570a, - 0xe710a, - 0x19004a, - 0x80a88, - 0x1d208, - 0x5a488, - 0xe75c8, - 0x1388, - 0xf982, - 0x167c0f, - 0xc6d8b, - 0x10f508, - 0x35cc7, - 0x4878a, - 0xbc3cb, - 0x34449, - 0x48687, - 0x83986, - 0x1d108, - 0x18ea0c, - 0x161347, - 0x1ae40a, - 0xec88, - 0x10ae8e, - 0x10b64e, - 0x16820b, - 0x168a8b, - 0x658cb, - 0x66609, - 0x6754b, - 0xbd4cd, - 0xf548b, - 0xf5fcd, - 0xf634d, - 0x10360a, - 0x12a4cb, - 0x166c0b, - 0x3bfc5, - 0x1d58b810, - 0x13514f, - 0x72e8f, - 0x2470d, - 0x13d450, - 0x293c2, - 0x1da1f8c8, - 0x7f248, - 0xea790, - 0x17fe0e, - 0x1df22b85, - 0x4c84b, - 0x13c390, - 0x1d30a, - 0x168c49, - 0x680c7, - 0x68407, - 0x685c7, - 0x68947, - 0x69e07, - 0x6a2c7, - 0x6bb07, - 0x6c047, - 0x6d587, - 0x6d907, - 0x6dfc7, - 0x6e187, - 0x6e347, - 0x6e507, - 0x6f307, - 0x6fc47, - 0x70a87, - 0x70e47, - 0x71487, - 0x71747, - 0x71907, - 0x71c07, - 0x71f87, - 0x72187, - 0x748c7, - 0x74a87, - 0x74c47, - 0x75dc7, - 0x77207, - 0x776c7, - 0x77dc7, - 0x78087, - 0x78407, - 0x785c7, - 0x789c7, - 0x78e07, - 0x792c7, - 0x79847, - 0x79a07, - 0x79bc7, - 0x7a007, - 0x7aa87, - 0x7afc7, - 0x7b207, - 0x7b3c7, - 0x7bb87, - 0x7c187, - 0x9a42, - 0x5a58a, - 0x13808, - 0x1baf8c, - 0x4eb87, - 0x918c5, - 0x9b311, - 0x1bb46, - 0x104dca, - 0x8adca, - 0x56546, - 0xb3ecb, + 0x215a82, + 0x20d782, + 0x232982, + 0x22cec2, + 0x325d0a, + 0x36918a, + 0x39ecca, + 0x3e9b42, + 0x20cec2, + 0x2be702, + 0x17f8cc49, + 0x183bb68a, + 0x14380c7, + 0x18601682, + 0x1430483, + 0x2c02, + 0x1bb68a, + 0x14f0ce, + 0x21d684, + 0xe8805, + 0x18e16543, + 0x48383, + 0x222bc3, + 0x256d44, + 0x343b43, + 0x2b1b84, + 0x243543, + 0x13e049, + 0x133e86, + 0x216443, + 0xf1dc4, + 0x1b03, + 0x2296c3, + 0x149f05, + 0x20d903, + 0x20cb83, + 0x1561c04, + 0x24c343, + 0x114bc4, + 0x201643, + 0x793c8, + 0x154db43, + 0x123486, + 0x155c1c4, + 0x1a0d45, + 0x1a0a8a, + 0x130602, + 0x199a16cd, + 0x1b3dc6, + 0x147f11, + 0x19f8cc49, + 0x1a0dc8, + 0x42008, + 0x20869487, + 0x3b42, + 0x18cdc7, + 0x208ce, + 0x146c0b, + 0x148d8b, + 0x1c0dca, + 0x34347, + 0x793c8, + 0xb4188, + 0xfd87, + 0x20c1fe0b, + 0x22a87, + 0x4242, + 0x3288d, + 0x163907, + 0x127b0a, + 0x12510c, + 0x1252cf, + 0x1ca4cf, + 0x212eb34d, + 0x2e702, + 0x16542, + 0x904c8, + 0x214e91cc, + 0x1aab8a, + 0xeb94a, + 0x7d54a, + 0x84888, + 0x1db88, + 0x68608, + 0xebe08, + 0x17bbc8, + 0x3242, + 0x1ca24f, + 0xcaa8b, + 0x1dcf08, + 0x3e1c7, + 0x874ca, + 0x3aa4b, + 0x51b89, + 0x873c7, + 0x136f46, + 0x1da88, + 0x1e0a8c, + 0xf4547, + 0x31a0a, + 0x1c74c8, + 0x32f4e, + 0x3370e, + 0x3418b, + 0x3518b, + 0x3678b, + 0xfc849, + 0x880cb, + 0xb688d, + 0x158a8b, + 0xf7a8d, + 0xf7e0d, + 0x12378a, + 0x15a5cb, + 0x1e150b, + 0x3f545, + 0x219c4bd0, + 0x21c41a88, + 0x3610f, + 0x7854f, + 0x2254d, + 0x17a710, + 0x13242, + 0x22258908, + 0x1cdd88, + 0x1b0350, + 0x106a4e, + 0x2275bd85, + 0x555cb, + 0x13d150, + 0x1dc8a, + 0x35349, + 0x6ff47, + 0x70287, + 0x70447, + 0x71587, + 0x72407, + 0x72787, + 0x734c7, + 0x73a07, + 0x73f07, + 0x74287, + 0x74947, + 0x74b07, + 0x74cc7, + 0x74e87, + 0x75207, + 0x756c7, + 0x75ec7, + 0x76287, + 0x768c7, + 0x76b87, + 0x76d47, + 0x77047, + 0x77647, + 0x77847, + 0x78d07, + 0x78ec7, + 0x79087, + 0x79807, + 0x7a047, + 0x7a8c7, + 0x7d387, + 0x7d7c7, + 0x7db47, + 0x7dd07, + 0x7e107, + 0x7e547, + 0x7ea07, + 0x7ef87, + 0x7f147, + 0x7f307, + 0x7f747, + 0x7fd07, + 0x80247, + 0x80847, + 0x80a07, + 0x810c7, + 0x81607, + 0xc342, + 0x6870a, + 0x1a608, + 0x1bbfcc, + 0x12fb47, + 0x44405, + 0xc3d91, + 0x13dc6, + 0x12100a, + 0x9034a, + 0x62246, + 0xb7f4b, 0x642, - 0x31351, - 0xc5d89, - 0x9bf49, - 0x9d306, - 0x5b542, - 0x1b21ca, - 0xafcc9, - 0xb040f, - 0xb0a0e, - 0xb3108, - 0x11b08, - 0xb5c2, - 0x6ed89, - 0x1e3586c9, - 0xbd049, - 0xbd04c, - 0x8f90e, - 0x4b8c, - 0xf2f8f, - 0x1bf08e, - 0x12b40c, - 0x33449, - 0x45391, - 0x45948, - 0x1a4e12, - 0x593cd, - 0x69acd, - 0x78f8b, - 0x81855, - 0x860c9, - 0x1518ca, - 0x188809, - 0x1aad50, - 0x1ae8cb, - 0x9890f, - 0xa868b, - 0xa914c, - 0xaa110, - 0xb7dca, - 0xb894d, - 0xd3a0e, - 0x195a0a, - 0xc1e8c, - 0xc4e94, - 0xc5a11, - 0xc694b, - 0xc858f, - 0xcbb0d, - 0xcd20e, - 0xd048c, - 0xd0c8c, - 0xd370b, - 0x172a8e, - 0x199ed0, - 0xdba8b, - 0xdc74d, - 0xdf30f, - 0xe804c, - 0xe9d8e, - 0xf3651, - 0x10570c, - 0x1d4047, - 0x10d14d, - 0x11db8c, - 0x144550, - 0x16528d, - 0x16efc7, - 0x176790, - 0x19dd08, - 0x1a3e8b, - 0xba1cf, - 0x1bb208, - 0x14bf0d, - 0x1125d0, - 0x178c89, - 0x1e78b7c8, - 0x1eabf946, - 0xc0843, - 0x3ec49, - 0xc7405, - 0x6902, - 0x48c09, - 0x14c50a, - 0x1efa52c6, - 0x15a52cd, - 0x1f36a9c4, - 0x57d06, - 0x1b68a, - 0x27bcd, - 0x1f52b109, - 0x216c3, - 0x11bb8a, - 0xe6751, - 0xe6b89, - 0xe7087, - 0xe7d88, - 0xe8447, - 0x4ec48, - 0xcacb, - 0x1311c9, - 0xf1e10, - 0xf22cc, - 0x1faf270d, - 0xf3a88, - 0xf4ec5, - 0x147e08, - 0x19ce4a, - 0x18a347, - 0x2542, - 0x1ff3f5d5, - 0x13d08a, - 0x1320c9, - 0x9e588, - 0x6ab09, - 0x7cb45, - 0x11d88a, - 0x92e0f, - 0x10d54b, - 0x11ff4c, - 0x176cd2, - 0xe9c6, - 0x7ce85, - 0x117a48, - 0xf84cb, - 0xf1151, - 0x16acc7, - 0x4da0a, - 0x20300485, - 0x1b330c, - 0x139c43, - 0x197a86, - 0x408c2, - 0x1089cb, - 0x10948a, - 0x150980c, - 0x7f5c8, - 0xf6188, - 0x2069e606, - 0x17d5c7, - 0xd782, - 0x7742, - 0x1a55d0, - 0x65087, - 0x3074f, - 0x13a06, - 0xd2b8e, - 0x99a0b, - 0x3dd48, - 0x34809, - 0x5da12, - 0x197b4d, - 0x118088, - 0x1188c9, - 0xee00d, - 0x19f749, - 0xb48b, - 0x6c348, - 0x71d88, - 0x75a88, - 0x80389, - 0x8058a, - 0x84b0c, - 0x166eca, - 0xf17ca, - 0x1178c7, - 0x9a50a, - 0x1cda4d, - 0x45c51, - 0x20acd506, - 0x1b994b, - 0x12f80c, - 0x94388, - 0x149449, - 0x160b0d, - 0x68b90, - 0x1812cd, - 0x4642, - 0x4a68d, - 0x72c2, - 0x1f702, - 0x11780a, - 0x756ca, - 0x20e7b508, - 0x104cca, - 0x11f80b, - 0x10b8cc, - 0x12048a, - 0x12070f, - 0x120ace, - 0x171cd, - 0x211e2c05, - 0x12d408, - 0x3602, - 0x1422383, - 0x415505, - 0x45d884, - 0x16202c0e, - 0x16b59cce, - 0x1720180a, - 0x17b9184e, - 0x1835788e, - 0x18b7f38c, - 0x142fc47, - 0x142fc49, - 0x143a083, - 0x1926060c, - 0x19b49bc9, - 0x1a36af09, - 0x1ab71749, - 0x1742, - 0x2b51, - 0x159c11, - 0x174d, - 0x1b6451, - 0x1577d1, - 0x17f2cf, - 0x6054f, - 0x149b0c, - 0x16ae4c, - 0x17168c, - 0x1af28d, - 0x15d915, - 0xc1a8c, - 0xc778c, - 0x135a10, - 0x141acc, - 0x14af8c, - 0x18ad99, - 0x191599, - 0x1bdfd9, - 0x1cb4d4, - 0x1d6294, - 0x1e02d4, - 0x1e2714, - 0xa994, - 0x1b2c1b49, - 0x1b9e0589, - 0x1c2c7849, - 0x16645b49, - 0x1742, - 0x16e45b49, - 0x1742, - 0xa98a, - 0x1742, - 0x17645b49, - 0x1742, - 0xa98a, - 0x1742, - 0x17e45b49, - 0x1742, - 0x18645b49, - 0x1742, - 0x18e45b49, - 0x1742, - 0xa98a, - 0x1742, - 0x19645b49, - 0x1742, - 0xa98a, - 0x1742, - 0x19e45b49, - 0x1742, - 0x1a645b49, - 0x1742, - 0xa98a, - 0x1742, - 0x1ae45b49, - 0x1742, - 0xa98a, - 0x1742, - 0x1b645b49, - 0x1742, - 0x1be45b49, - 0x1742, - 0x1c645b49, - 0x1742, - 0xa98a, - 0x1742, + 0x39c91, + 0xc5889, + 0xa0689, + 0xa12c6, + 0x5102, + 0x9c50a, + 0xb4e49, + 0xb558f, + 0xb5b8e, + 0xb7288, + 0x22a17a92, + 0x19b88, + 0x22f2fd07, + 0x1ec82, + 0x15c709, + 0x15490a, + 0x23347589, + 0x19de09, + 0x19de0c, + 0x15f4b, + 0x436ce, + 0xe6cc, + 0xf364f, + 0x1bfdce, + 0x4594c, + 0x5e789, + 0x658d1, + 0x65e88, + 0x7bd12, + 0x7cd4d, + 0x7e6cd, + 0x8564b, + 0x8b795, + 0x932c9, + 0x18500a, + 0x1b0049, + 0x1d4350, + 0x99acb, + 0x9ee0f, + 0xa3fcb, + 0xad6cc, + 0xbac90, + 0xd844a, + 0x18264d, + 0x19210e, + 0xbc48a, + 0xc090c, + 0x1997d4, + 0xc5511, + 0xca64b, + 0xccc8f, + 0xd048d, + 0xd42ce, + 0xd55cc, + 0xd5dcc, + 0xd814b, + 0x14284e, + 0x197d50, + 0x1aa38b, + 0xddacd, + 0xe730f, + 0xec90c, + 0x108b4e, + 0x10c891, + 0x18214c, + 0x11ca07, + 0x144e8d, + 0x15ffcc, + 0x1693d0, + 0x17208d, + 0x172dc7, + 0x195a10, + 0x1a5888, + 0x1abd0b, + 0xbd9cf, + 0x1bc248, + 0x68e8d, + 0x111f10, + 0x174389, + 0x237c4b88, + 0x23ac2a86, + 0xc3943, + 0x52a89, + 0x54c9, + 0xcbc45, + 0x7bc2, + 0x18fd89, + 0x62c8a, + 0x23e7c1c6, + 0x147c1cd, + 0x24363b04, + 0x1da806, + 0x2630a, + 0x2778d, + 0x246da54b, + 0x2484f809, + 0x2b203, + 0x11b88a, + 0xe9951, + 0xe9d89, + 0xeb8c7, + 0xec648, + 0xecd07, + 0x12fc08, + 0x14808b, + 0x1326c9, + 0xf2550, + 0xf2a0c, + 0x24ef31cd, + 0xf5c48, + 0xf7685, + 0x1d0608, + 0x19a8ca, + 0x16c507, + 0x1cc2, + 0x25239155, + 0x13de4a, + 0x1363c9, + 0x5688, + 0xa2549, + 0x1df185, + 0x11c70a, + 0x97c4f, + 0xa55cb, + 0x15ee8c, + 0xc8052, + 0x1b5a06, + 0x9a905, + 0x15f148, + 0xfa0cb, + 0xfa9d1, + 0x143847, + 0x5788a, + 0x25704a05, + 0x1b560c, + 0x13a843, + 0x1953c6, + 0x473c2, + 0x10ad8b, + 0x10b8ca, + 0x150bc4c, + 0xf48c8, + 0xf7c48, + 0x25a05706, + 0x1b7287, + 0x4a02, + 0x1ec2, + 0x1a6e50, + 0x67dc7, + 0x67ecf, + 0x30846, + 0x12270e, + 0x9d3cb, + 0x46c88, + 0x51f49, + 0x117052, + 0x11820d, + 0x118d88, + 0xef809, + 0x19c60d, + 0x112c9, + 0x6824b, + 0x69d88, + 0x73d08, + 0x75388, + 0x771c9, + 0x773ca, + 0x799cc, + 0x1e17ca, + 0xf14ca, + 0x1177c7, + 0xa38ca, + 0x738d, + 0x174cd1, + 0x25ed45c6, + 0x17768b, + 0xbe0c, + 0x414c8, + 0x3d609, + 0x14c6cd, + 0x57110, + 0x190c8d, + 0x6502, + 0x6540d, + 0x4a42, + 0x66342, + 0x11770a, + 0x263d034a, + 0x25c4a, + 0x26680b48, + 0x120f0a, + 0x12f4cb, + 0x3398c, + 0x1203ca, + 0x2692064f, + 0x120a0e, + 0x26de9a05, + 0x12bf48, + 0xe042, + 0x1420a83, + 0x1a38e20e, + 0x1ab2eb8e, + 0x1b202cca, + 0x1bb7c04e, + 0x1c32d84e, + 0x1cb3408c, + 0x14380c7, + 0x14380c9, + 0x1430483, + 0x1d3419cc, + 0x1db54e89, + 0x1e36d309, + 0x1eba0889, + 0x2c02, + 0x1a3511, + 0x12ead1, + 0x2c0d, + 0x17bf91, + 0x12d791, + 0x133fcf, + 0x14190f, + 0x154dcc, + 0x16d24c, + 0x1a07cc, + 0x1b764d, + 0x17d415, + 0xc510c, + 0xe140c, + 0x1439d0, + 0x14a18c, + 0x18758c, + 0x18df59, + 0x1bed19, + 0x1cabd9, + 0x1cc7d4, + 0x1d2454, + 0x1e8694, + 0x5e54, + 0xff14, + 0x1f2c51c9, + 0x1f9e8949, + 0x202e14c9, + 0x1a666089, + 0x2c02, + 0x1ae66089, + 0x2c02, + 0x5e4a, + 0x2c02, + 0x1b666089, + 0x2c02, + 0x5e4a, + 0x2c02, + 0x1be66089, + 0x2c02, + 0x1c666089, + 0x2c02, + 0x1ce66089, + 0x2c02, + 0x5e4a, + 0x2c02, + 0x1d666089, + 0x2c02, + 0x5e4a, + 0x2c02, + 0x1de66089, + 0x2c02, + 0x1e666089, + 0x2c02, + 0x5e4a, + 0x2c02, + 0x1ee66089, + 0x2c02, + 0x5e4a, + 0x2c02, + 0x1f666089, + 0x2c02, + 0x1fe66089, + 0x2c02, + 0x20666089, + 0x2c02, + 0x5e4a, + 0x2c02, 0x1400401, - 0xc945, - 0x1c0084, - 0x144ce03, - 0x1426d83, - 0x14fa443, - 0x2c0e, - 0x159cce, - 0x8450e, - 0x180a, - 0x19184e, - 0x15788e, - 0x17f38c, - 0x6060c, - 0x149bc9, - 0x16af09, - 0x171749, - 0xc1b49, - 0x1e0589, - 0xc7849, - 0x135acd, - 0x141b89, - 0xac49, - 0x12d5c4, - 0x132ac4, - 0x1c8a04, - 0x1c95c4, - 0xaae04, - 0x2ec44, - 0x3cd84, - 0x192d44, - 0x13904, - 0xbec06, - 0x59504, - 0x158e7c3, - 0x149987, - 0x148574c, - 0x1ac3, - 0x293c2, - 0x107788, - 0xd1784, - 0x14386, - 0xd8a84, - 0x15aa06, - 0x16b82, - 0xa8c1, - 0x20e44, - 0xb1706, - 0x171c3, - 0x1ac3, - 0xa0e83, - 0x13d385, - 0x124dc2, - 0x124dc8, - 0xeb947, - 0x131247, - 0xf982, + 0x147f05, + 0x1c0dc4, + 0x8903, + 0x8502, + 0x54642, + 0x1419303, + 0x1403603, + 0x14fea83, + 0x18e20e, + 0x12eb8e, + 0x89e8e, + 0x2cca, + 0x17c04e, + 0x12d84e, + 0x13408c, + 0x1419cc, + 0x154e89, + 0x16d309, + 0x1a0889, + 0xc51c9, + 0x1e8949, + 0xe14c9, + 0x143a8d, + 0x6109, + 0x101c9, + 0x3d1c2, + 0x1cbcc4, + 0x1cec84, + 0x1d1104, + 0x1df604, + 0xaef44, + 0xacdc4, + 0x4a9c4, + 0x35644, + 0x1a704, + 0x136fc4, + 0x7b0c9, + 0x7b0cc, + 0x158286, + 0x15828e, + 0x7ce84, + 0x155cf03, + 0x14a007, + 0x148ae0c, + 0x9983, + 0x136fc4, + 0x13242, + 0xe91c8, + 0xd6b04, + 0x1e9706, + 0xdd5c4, + 0x121646, + 0x1f8c2, + 0x7281, + 0x27c44, + 0x69306, + 0x15b83, + 0x9983, + 0x71703, + 0xc7e43, + 0x14803, + 0xf7a03, + 0xc8045, + 0x5adc2, + 0x148a42, + 0x1a1e88, + 0xee7c7, + 0x132747, + 0x3242, 0x2000c2, - 0x212402, - 0x204542, - 0x20fa02, + 0x216542, + 0x2104c2, + 0x218242, 0x200382, 0x2003c2, - 0x207742, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e703, - 0x217fc3, - 0x23e083, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x217fc3, - 0x23e083, - 0x10303, - 0x266a83, - 0xe704, + 0x201ec2, + 0x216543, + 0x222bc3, + 0x343b43, + 0x26a7c3, + 0x2296c3, + 0x20cb83, + 0x793c8, + 0x216543, + 0x222bc3, + 0x2296c3, + 0x20cb83, + 0xb303, + 0x343b43, + 0xb1b84, 0x2000c2, - 0x24ac43, - 0x2362ea43, - 0x392747, - 0x266a83, - 0x21e1c3, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x226e0a, - 0x243bc5, - 0x216983, - 0x22dc42, - 0xae888, - 0x23adad8a, + 0x253c43, + 0x29216543, + 0x3a5287, + 0x343b43, + 0x21b283, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x23098a, + 0x24d905, + 0x21f6c3, + 0x213402, + 0x793c8, + 0x296df98a, 0xe01, - 0xae888, - 0x12402, - 0x137ac2, - 0x2432ae8b, - 0x2462e004, - 0x16a905, - 0x8cc5, - 0x107786, - 0x24a08cc5, - 0x54383, - 0x5cd83, + 0x793c8, + 0x16542, + 0x138402, + 0x29e4f58b, + 0x2a2093c4, + 0x163a45, + 0x1403ec5, + 0xe91c6, + 0x2a603ec5, + 0x5fa83, + 0x1b0243, 0x9c4, - 0x157bc3, - 0x2105, - 0x146bc5, - 0xae888, - 0x1a087, - 0x2ea43, - 0x2ed4d, - 0x2523a707, - 0x159146, - 0x25401645, - 0x1c0992, - 0x159207, - 0x1dbca, - 0x10ac8, - 0x1dac7, - 0x6bcca, - 0x1bc448, - 0xe4f07, - 0x1ac70f, - 0x36fc7, - 0x192b46, - 0x13c390, - 0xcee8f, - 0x21c49, - 0x57d84, - 0x259592ce, - 0x185a89, - 0x6e646, - 0x111a89, - 0x193c86, - 0x1c2e06, - 0x4f10c, - 0xbc5ca, - 0x345c7, - 0x17edca, - 0x1596c9, - 0xf8e8c, - 0x1c8ca, - 0x4b8ca, - 0x2149, - 0x57d06, - 0x3468a, - 0x118f4a, - 0xa3a4a, - 0x137509, - 0xe54c8, - 0xe5746, - 0xed88d, - 0x5130b, - 0xc7c05, - 0x25f5a28c, - 0x14ca47, - 0x110289, - 0xd1047, - 0xc6114, - 0x1129cb, - 0x10f34a, - 0x5d88a, - 0xac80d, - 0x151fa09, - 0x117e4c, - 0x1186cb, - 0x88c3, - 0x88c3, - 0x36fc6, - 0x88c3, - 0x107788, - 0x15c103, - 0x46604, - 0x54603, - 0x347c5, - 0x1475903, - 0x51709, - 0xf84cb, - 0x14e82c3, - 0x154546, - 0x15037c7, - 0x1aafc7, - 0x26d41489, - 0x17e86, - 0x4ac43, - 0xae888, - 0x12402, - 0x4d704, - 0x61083, - 0x17b845, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x233f03, - 0x22ea43, - 0x233fc3, - 0x280203, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0x2bd443, - 0x20aa43, - 0x233f03, - 0x24cd44, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x204ac3, - 0x28541585, - 0x142e6c3, - 0x22ea43, - 0x233fc3, - 0x20fa03, - 0x280203, - 0x266a83, - 0x20e704, - 0x3433c3, - 0x215f83, - 0x23cb03, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0x216983, - 0x29219f03, - 0x176bc9, - 0x12402, - 0x3c7603, - 0x29e2ea43, - 0x233fc3, - 0x249283, - 0x266a83, - 0x2220c3, - 0x215f83, - 0x23e083, - 0x3005c3, - 0x3cd604, - 0xae888, - 0x2a62ea43, - 0x233fc3, - 0x2b31c3, - 0x266a83, - 0x23cb03, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x2302c3, - 0xae888, - 0x2ae2ea43, - 0x233fc3, - 0x280203, - 0x205803, - 0x23e083, - 0xae888, - 0x142fc47, - 0x24ac43, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x146bc5, - 0x178d87, - 0xc634b, - 0xe6f84, - 0xc7c05, - 0x1454408, - 0x2c10d, - 0x2c242285, - 0x27c44, - 0x12402, - 0x10103, - 0x184485, - 0x30242, - 0x53c2, - 0x34b8c5, - 0xae888, - 0x88c2, - 0x1b2c3, - 0x16b88f, - 0x12402, - 0x1063c6, + 0x12db83, + 0x10e645, + 0x146c05, + 0x793c8, + 0x22a87, + 0x16543, + 0x1b4bcd, + 0x2ae42647, + 0x1386, + 0x2b17be85, + 0x186012, + 0x1447, + 0x1e48a, + 0x17588, + 0x1e387, + 0x7368a, + 0x1bd188, + 0x110a47, + 0x165d8f, + 0x3db87, + 0x4bb86, + 0x13d150, + 0x19350f, + 0x1b009, + 0x1da884, + 0x2b40150e, + 0x5b0c9, + 0x74fc6, + 0x1113c9, + 0x190a86, + 0x6ac6, + 0xb8e4c, + 0x3ac4a, + 0x51d07, + 0x14140a, + 0x1909, + 0x25e8c, + 0x2954a, + 0x6b44a, + 0x10e689, + 0x1da806, + 0x51dca, + 0x11934a, + 0xa954a, + 0x114309, + 0xe8b88, + 0xe8e06, + 0xef08d, + 0x5b88b, + 0xcc205, + 0x2bb1e14c, + 0x13e247, + 0x10fcc9, + 0xd6187, + 0xc5c14, + 0x11230b, + 0x1dcd4a, + 0x116eca, + 0xb080d, + 0x152f6c9, + 0x117fcc, + 0x118b8b, + 0x31a03, + 0x31a03, + 0x32f46, + 0x31a03, + 0xe91c8, + 0x157243, + 0x4ebc4, + 0x5fc83, + 0x14a9607, + 0x51f05, + 0x15186c3, + 0x5c549, + 0xc8045, + 0xfa0cb, + 0x14ecb83, + 0x152e06, + 0x1523947, + 0x1d45c7, + 0x2c97ce89, + 0x1d1a86, + 0x53c43, + 0x793c8, + 0x16542, + 0x56d44, + 0x43ac3, + 0x155b45, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x203b43, + 0x216543, + 0x222bc3, + 0x2f5503, + 0x343b43, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x2a0843, + 0x201643, + 0x203b43, + 0x25dd04, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x20e603, + 0x2192c3, + 0x213402, + 0x2e17cf85, + 0x1438003, + 0x216543, + 0x222bc3, + 0x21a003, + 0x2f5503, + 0x343b43, + 0x2b1b84, + 0x34b203, + 0x233243, + 0x216443, + 0x2296c3, + 0x7ca83, + 0x20cb83, + 0x21f6c3, + 0x2ee0fc03, + 0xc7f49, + 0x16542, + 0x225103, + 0x2fa16543, + 0x222bc3, + 0x252183, + 0x343b43, + 0x2207c3, + 0x233243, + 0x20cb83, + 0x2037c3, + 0x3df304, + 0x793c8, + 0x30216543, + 0x222bc3, + 0x2b7343, + 0x343b43, + 0x216443, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x238743, + 0x793c8, + 0x30a16543, + 0x222bc3, + 0x2f5503, + 0x20d903, + 0x20cb83, + 0x793c8, + 0x14380c7, + 0x253c43, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x146c05, + 0xb46c7, + 0xc5e4b, + 0x31a3ca06, + 0x31efdb4b, + 0xea184, + 0xcc205, + 0x1472588, + 0x2f20d, + 0x1c4b88, + 0x136fc4, + 0x3264ccc5, + 0x27804, + 0x16542, + 0x1a143, + 0x158185, + 0x386c2, + 0x34aac5, + 0x793c8, + 0x33e98f0d, + 0x343a11ca, + 0x24642, + 0x5483, + 0x164f4f, + 0x18242, + 0x7ce84, + 0x136fc4, + 0x16542, 0x2000c2, - 0x24ac43, - 0x22ea43, - 0x266a83, - 0x20e704, - 0x23cb03, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x216983, - 0x30242, - 0x32ff08, - 0x24cd44, - 0x37e046, - 0x3af146, - 0xae888, - 0x31a6c3, - 0x355c09, - 0x30ddd5, - 0x10dddf, - 0x22ea43, - 0x7fa87, - 0x242992, - 0x1623c6, - 0x16fd05, - 0x1d30a, - 0x168c49, - 0x24274f, - 0x2e5904, - 0x2bbf05, - 0x313850, - 0x215f87, - 0x205803, - 0x321388, - 0x134b86, - 0x293b0a, - 0x223144, - 0x2ffec3, - 0x22dc42, - 0x2fa00b, - 0x5803, - 0x182c04, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x5803, - 0x23e083, - 0x307183, - 0x212402, - 0x1c06c3, - 0x2a4c4, - 0x217fc3, - 0x23e083, - 0x2fc39fc5, - 0x1d5cc6, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x21e1c3, - 0x265dc3, - 0x23e083, - 0x4ac43, - 0x212402, - 0x22ea43, - 0x233fc3, - 0x217fc3, - 0x5803, - 0x23e083, - 0x17082, + 0x253c43, + 0x216543, + 0x343b43, + 0x2b1b84, + 0x216443, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x21f6c3, + 0x216543, + 0x222bc3, + 0x2296c3, + 0x20cb83, + 0x19045, + 0x331408, + 0x25dd04, + 0x379ac6, + 0x3a0686, + 0x793c8, + 0x2b6643, + 0x2f6689, + 0x21c495, + 0x1c49f, + 0x216543, + 0xf4d87, + 0x38db12, + 0x16a146, + 0x182c45, + 0x1dc8a, + 0x35349, + 0x38d8cf, + 0x2e8fc4, + 0x237a05, + 0x313790, + 0x2b1087, + 0x20d903, + 0x2c2308, + 0x13846, + 0x29fc4a, + 0x26fb04, + 0x304443, + 0x213402, + 0x2fe64b, + 0x222bc3, + 0x343b43, + 0xd903, + 0x15b044, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x309a43, + 0x216542, + 0x187003, + 0x149c04, + 0x2296c3, + 0x20cb83, + 0x364419c5, + 0x1de746, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x21b283, + 0x233c83, + 0x20cb83, + 0x53c43, + 0x216542, + 0x216543, + 0x222bc3, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x19f42, 0x2000c2, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x8cc5, - 0x1ac3, - 0x24cd44, - 0x22ea43, - 0x233fc3, - 0x217544, - 0x217fc3, - 0x23e083, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0x1357c9, - 0x4cc4, - 0x22ea43, - 0xf982, - 0x233fc3, - 0x280203, - 0x204903, - 0x23cb03, - 0x217fc3, - 0x5803, - 0x23e083, - 0x2a82, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x36a584, - 0x20e704, - 0x217fc3, - 0x23e083, - 0x20aa43, - 0x6c02, - 0x212402, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x2f4c43, - 0x160c3, - 0x1e1c3, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0x32748a, - 0x345389, - 0x36500b, - 0x3657ca, - 0x36f50a, - 0x37c54b, - 0x393a4a, - 0x399a4a, - 0x3a124a, - 0x3a1c4b, - 0x3c4709, - 0x3cf9ca, - 0x3cfe0b, - 0x3db28b, - 0x3e0d8a, - 0xcdc2, - 0x22ea43, - 0x233fc3, - 0x280203, - 0x23cb03, - 0x217fc3, - 0x5803, - 0x23e083, - 0xcc4b, - 0x17fe07, - 0x5af88, - 0xee144, - 0x1c4104, - 0x94dc8, - 0xea706, - 0xcc06, - 0x1a07c9, - 0xae888, - 0x22ea43, - 0x1d304, - 0x2680c4, - 0x201c02, - 0x21e484, - 0x202645, - 0x233f03, - 0x24cd44, - 0x22ea43, - 0x236704, - 0x233fc3, - 0x24d704, - 0x2e5904, - 0x20e704, - 0x215f83, - 0x217fc3, - 0x23e083, - 0x24a845, - 0x204ac3, - 0x216983, - 0x204343, - 0x2ddf84, - 0x32a004, - 0x23a185, - 0xae888, - 0x3b4e04, - 0x3c2f86, - 0x202284, - 0x212402, - 0x3770c7, - 0x3a9947, - 0x24bb44, - 0x20e785, - 0x365485, - 0x22f845, - 0x20e704, - 0x38f948, - 0x2523c6, - 0x3641c8, - 0x2836c5, - 0x2ee705, - 0x237bc4, - 0x23e083, - 0x300ac4, - 0x37b286, - 0x243cc3, - 0x2ddf84, - 0x24fd85, - 0x248b84, - 0x2a67c4, - 0x22dc42, - 0x232ec6, - 0x3b7ec6, - 0x315fc5, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x3ec5, + 0x63a09, + 0x9983, + 0x25dd04, + 0x216543, + 0x222bc3, + 0x28d4c4, + 0x2296c3, + 0x20cb83, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x7ca83, + 0x20cb83, + 0x1b7409, + 0xe804, + 0x216543, + 0x3242, + 0x222bc3, + 0x2f5503, + 0x20e443, + 0x216443, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x2a02, + 0x216543, + 0x222bc3, + 0x343b43, + 0x3636c4, + 0x2b1b84, + 0x2296c3, + 0x20cb83, + 0x201643, + 0x4702, + 0x216542, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x7ca83, + 0x20cb83, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x284103, + 0xe103, + 0x1b283, + 0x2296c3, + 0x7ca83, + 0x20cb83, + 0x38bc6, + 0x325d0a, + 0x3453c9, + 0x35fd4b, + 0x36084a, + 0x36918a, + 0x37860b, + 0x39084a, + 0x3979ca, + 0x39ecca, + 0x39ef4b, + 0x3c5589, + 0x3d368a, + 0x3d3acb, + 0x3dfecb, + 0x3e914a, + 0x4042, + 0x216543, + 0x222bc3, + 0x2f5503, + 0x216443, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x3ecb, + 0x106a47, + 0x69a08, + 0x19c744, + 0x1db944, + 0x98e48, + 0xedac6, + 0x1481c6, + 0x13a09, + 0x793c8, + 0x216543, + 0x1dc84, + 0x26ff44, + 0x215d42, + 0x21b544, + 0x30eb85, + 0x203b43, + 0x25dd04, + 0x216543, + 0x23ec84, + 0x222bc3, + 0x256d44, + 0x2e8fc4, + 0x2b1b84, + 0x233243, + 0x2296c3, + 0x20cb83, + 0x2655c5, + 0x20e603, + 0x21f6c3, + 0x27d683, + 0x2d1984, + 0x323404, + 0x34bd45, + 0x793c8, + 0x32e744, + 0x3c2086, + 0x30e7c4, + 0x216542, + 0x2c8447, + 0x250707, + 0x254744, + 0x2ee845, + 0x372285, + 0x2b96c5, + 0x2b1b84, + 0x267408, + 0x25d206, + 0x392c88, + 0x287105, + 0x2efe85, + 0x257204, + 0x20cb83, + 0x305504, + 0x3770c6, + 0x24da03, + 0x2d1984, + 0x26fac5, + 0x38fd04, + 0x2aacc4, + 0x213402, + 0x38f846, + 0x3b8fc6, + 0x315f85, 0x2000c2, - 0x24ac43, - 0x34e12402, - 0x21fa44, + 0x253c43, + 0xedc46, + 0x3b616542, + 0x231d44, + 0x63dc5, 0x200382, - 0x23cb03, - 0x20cac2, - 0x217fc3, + 0x216443, + 0x2a9542, + 0x2296c3, 0x2003c2, - 0x2fcf46, - 0x208503, - 0x20aa43, - 0xae888, - 0xae888, - 0x266a83, - 0x1c0443, + 0x301a46, + 0x202b03, + 0x1da785, + 0x201643, + 0x793c8, + 0x793c8, + 0x343b43, + 0x7ca83, 0x2000c2, - 0x35a12402, - 0x266a83, - 0x26e2c3, - 0x3433c3, - 0x22e004, - 0x217fc3, - 0x23e083, - 0xae888, + 0x3c216542, + 0x343b43, + 0x274c43, + 0x34b203, + 0x2093c4, + 0x2296c3, + 0x20cb83, + 0x793c8, 0x2000c2, - 0x36212402, - 0x22ea43, - 0x217fc3, - 0x5803, - 0x23e083, + 0x3ca16542, + 0x216543, + 0x2296c3, + 0xd903, + 0x20cb83, 0x682, - 0x203b42, - 0x21fcc2, - 0x21e1c3, - 0x2f8e43, + 0x2091c2, + 0x22a042, + 0x21b283, + 0x2faf43, 0x2000c2, - 0x146bc5, - 0xae888, - 0x178d87, - 0x212402, - 0x233fc3, - 0x24d704, - 0x2033c3, - 0x266a83, - 0x204903, - 0x23cb03, - 0x217fc3, - 0x213cc3, - 0x23e083, - 0x234fc3, - 0x140d13, - 0x142dd4, - 0x146bc5, - 0x178d87, - 0x1dbc9, - 0x110b86, - 0x121b4b, - 0x36fc6, - 0x54bc7, - 0xe786, + 0x146c05, + 0x793c8, + 0xb46c7, + 0x216542, + 0x222bc3, + 0x256d44, + 0x204f03, + 0x343b43, + 0x20e443, + 0x216443, + 0x2296c3, + 0x20b243, + 0x20cb83, + 0x23d343, + 0x1643, + 0x13ff13, + 0x142f14, + 0x146c05, + 0xb46c7, + 0x1e489, + 0x1e1e06, + 0x19108b, + 0x32f46, + 0x60ac7, + 0x145246, 0x649, - 0x1d818a, - 0x9110d, - 0x127d8c, - 0x1198ca, - 0x15d048, - 0x1b5a05, - 0x1dc08, - 0x13a06, - 0x1ce786, - 0x134c46, + 0x15d3ca, + 0x9560d, + 0x1b60cc, + 0x119cca, + 0x46688, + 0x10f7c5, + 0x1e4c8, + 0x30846, + 0x1d1806, + 0x13906, 0x602, - 0x2293c2, - 0x6f204, - 0xa0e86, - 0x1411d0, - 0x147a54e, - 0x1e46, - 0x696cc, - 0x37b22f0b, - 0x146bc5, - 0x15434b, - 0x37fce6c4, - 0x1c0247, - 0x23c91, - 0x11a7ca, - 0x22ea43, - 0x38285648, - 0x6bc45, - 0xf988, - 0x1ff44, - 0x14c705, - 0x38561cc6, - 0x9b306, - 0xc9b46, - 0x9620a, - 0x96ecc, - 0x1c2043, - 0x1c4104, - 0x38a120c4, - 0x51709, - 0x164347, - 0x1167ca, - 0x14dac89, + 0x213242, + 0x15cb84, + 0x1d4b06, + 0x1255d0, + 0x14dbf0e, + 0x1a1146, + 0x41dcc, + 0x3e37cd0b, + 0x146c05, + 0x152c0b, + 0x3e7d1744, + 0x1c0f87, + 0x2c191, + 0x12140a, + 0x216543, + 0x3ea8ad08, + 0x73605, + 0x89288, + 0x2a2c4, + 0x62e85, + 0x3ec0b186, + 0x1bc60b, + 0xc3d86, + 0x72206, + 0x9a6ca, + 0x16c5cc, + 0x1c2003, + 0x1db944, + 0x3f218004, + 0x5c549, + 0x192e07, + 0xac00a, + 0x14df889, 0x605, - 0x103583, - 0x38e35107, - 0x2a7c5, - 0x153d986, - 0x14731c6, - 0xb3f8c, - 0x104248, - 0x390408c3, - 0xfa24b, - 0x12bd4b, - 0x3964950c, - 0x140ba83, - 0xc96c8, - 0xfa4c5, - 0xc6c09, - 0xeca43, - 0x11fb08, - 0x141b5c6, - 0x8e8c7, - 0x39b60b09, - 0x99c87, - 0xf054a, - 0x3afc6788, - 0x11838d, - 0xff48, - 0x1ac3, - 0x1445009, - 0x3a643, - 0x36fc6, - 0x107788, - 0x13904, - 0x154c85, - 0x1492ec3, - 0x22387, - 0x39e22383, - 0x3a3c78c6, - 0x3a637e84, - 0x3ab09647, - 0x107784, - 0x107784, - 0x107784, - 0x107784, + 0xb6803, + 0x3f63d487, + 0x149f05, + 0x1565b86, + 0x157ac46, + 0x3fb92f4f, + 0xb800c, + 0x107588, + 0x3fc473c3, + 0x10a3c4, + 0xfe88b, + 0x1d694b, + 0x4025240c, + 0x14110c3, + 0xcddc8, + 0xfeb05, + 0xca909, + 0xeb643, + 0x12f7c8, + 0x1426246, + 0x95c87, + 0x4074c6c9, + 0x41a7a6c8, + 0x9dc07, + 0xcf9ca, + 0x41fc9408, + 0x11884d, + 0x12248, + 0x9983, + 0x146a249, + 0x14c203, + 0x32f46, + 0xe91c8, + 0x1a704, + 0x1d8645, + 0xfea83, + 0x1497d03, + 0x20a87, + 0x40a20a83, + 0x40fc2486, + 0x41240644, + 0x4170ba87, + 0xe91c4, + 0xe91c4, + 0xe91c4, + 0xe91c4, + 0x3ec5, + 0x1a18c8, + 0x148209, 0x41, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x23e083, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0x20cb83, 0x2000c2, - 0x212402, - 0x266a83, - 0x209582, - 0x217fc3, - 0x23e083, - 0x208503, - 0x38644f, - 0x38680e, - 0xae888, - 0x22ea43, - 0x44cc7, - 0x233fc3, - 0x266a83, - 0x2191c3, - 0x217fc3, - 0x23e083, - 0x1d84, - 0x157d04, - 0x1b4744, - 0x21afc3, - 0x324007, - 0x207d42, - 0x272549, + 0x216542, + 0x343b43, + 0x2042c2, + 0x2296c3, + 0x20cb83, + 0x202b03, + 0x3835cf, + 0x38398e, + 0x793c8, + 0x216543, + 0x4e6c7, + 0x222bc3, + 0x343b43, + 0x243543, + 0x2296c3, + 0x20cb83, + 0x1a1084, + 0x12dcc4, + 0x9c04, + 0x224503, + 0x3a2347, + 0x202302, + 0x277c09, 0x200ac2, - 0x3a58cb, - 0x2a6b8a, - 0x2aec89, + 0x3a714b, + 0x2e808a, + 0x2ec409, 0x200542, - 0x220306, - 0x244495, - 0x3a5a15, - 0x387d93, - 0x3a5f93, - 0x2272c2, - 0x2272c5, - 0x25f44c, - 0x27ad0b, - 0x277a05, - 0x201802, - 0x239202, - 0x381b06, - 0x203502, - 0x2cf9c6, - 0x21d58d, - 0x22a54c, - 0x38b884, + 0x22a686, + 0x256255, + 0x3a7295, + 0x259fd3, + 0x3a7813, + 0x22d0c2, + 0x22d0c5, + 0x363e0c, + 0x27ff8b, + 0x281405, + 0x202cc2, + 0x30a8c2, + 0x37ed06, + 0x203b42, + 0x2d4b06, + 0x21df0d, + 0x349c8c, + 0x3c4c44, 0x200882, - 0x222b02, - 0x3a51c8, + 0x205242, + 0x27c0c8, 0x200202, - 0x336d46, - 0x39c70f, - 0x357dd0, - 0x229804, - 0x244655, - 0x387f13, - 0x24c943, - 0x369f8a, - 0x20c5c7, - 0x3a1ec9, - 0x316687, - 0x30bf02, + 0x32dd86, + 0x39a18f, + 0x32dd90, + 0x3abc44, + 0x256415, + 0x25a153, + 0x20a883, + 0x3630ca, + 0x211d47, + 0x39f1c9, + 0x3129c7, + 0x328c42, 0x200282, - 0x3c90c6, - 0x204cc2, - 0xae888, - 0x207f42, - 0x208a02, - 0x228fc7, - 0x348187, - 0x348191, - 0x218885, - 0x21888e, - 0x2194cf, - 0x20cfc2, - 0x3236c7, - 0x21b008, - 0x20aac2, - 0x21c942, - 0x227846, - 0x22784f, - 0x26c690, - 0x22c442, - 0x20cf02, - 0x238b48, - 0x214803, - 0x261248, - 0x2eea8d, - 0x20cf03, - 0x3cc248, - 0x28734f, - 0x28770e, - 0x25d54a, - 0x26cb11, - 0x26cf90, - 0x30280d, - 0x302b4c, - 0x3c20c7, - 0x36a107, - 0x37e109, - 0x29a842, - 0x205082, - 0x256b8c, - 0x256e8b, + 0x3cb7c6, + 0x207dc2, + 0x793c8, + 0x202502, + 0x20bd42, + 0x212e47, + 0x38d507, + 0x38d511, + 0x221a05, + 0x221a0e, + 0x22204f, + 0x204242, + 0x2f1c07, + 0x224b48, + 0x2016c2, + 0x2295c2, + 0x227406, + 0x22740f, + 0x23ff50, + 0x237242, + 0x204182, + 0x336588, + 0x210903, + 0x2920c8, + 0x2cb30d, + 0x204183, + 0x3a04c8, + 0x28e48f, + 0x28e84e, + 0x316b8a, + 0x3b3ed1, + 0x3b4350, + 0x21b9cd, + 0x21bd0c, + 0x386987, + 0x363247, + 0x379b89, + 0x20cd02, + 0x202402, + 0x26274c, + 0x262a4b, 0x200d42, - 0x2d38c6, - 0x202282, + 0x2d8306, + 0x20c602, 0x200482, - 0x361e82, - 0x212402, - 0x22f244, - 0x239d87, - 0x22c982, - 0x240307, - 0x241b47, - 0x230a82, - 0x211d02, - 0x244b85, - 0x20da02, - 0x3985ce, - 0x3d068d, - 0x233fc3, - 0x28cf0e, - 0x2bb64d, - 0x35cc43, - 0x203142, - 0x28ac84, - 0x29a802, - 0x223ec2, - 0x3930c5, - 0x3a3b07, - 0x2481c2, - 0x20fa02, - 0x24d307, - 0x251a88, - 0x2ba882, - 0x27cf06, - 0x256a0c, - 0x256d4b, - 0x2091c2, - 0x261d4f, - 0x262110, - 0x26250f, - 0x2628d5, - 0x262e14, - 0x26330e, - 0x26368e, - 0x263a0f, - 0x263dce, - 0x264154, - 0x264653, - 0x264b0d, - 0x27c349, - 0x292a43, - 0x2033c2, - 0x2d2685, - 0x2033c6, + 0x22e702, + 0x216542, + 0x3dbec4, + 0x241787, + 0x213b02, + 0x248d87, + 0x24a7c7, + 0x215a42, + 0x219d82, + 0x24e585, + 0x20c542, + 0x250e0e, + 0x39654d, + 0x222bc3, + 0x243c8e, + 0x2c764d, + 0x3c4143, + 0x2026c2, + 0x2730c4, + 0x2b3802, + 0x213642, + 0x3a6a05, + 0x3acc07, + 0x250d02, + 0x218242, + 0x256947, + 0x25c8c8, + 0x25c082, + 0x29a986, + 0x2625cc, + 0x26290b, + 0x20eb02, + 0x26c34f, + 0x26c710, + 0x26cb0f, + 0x26ced5, + 0x26d414, + 0x26d90e, + 0x26dc8e, + 0x26e00f, + 0x26e3ce, + 0x26e754, + 0x26ec53, + 0x26f10d, + 0x2817c9, + 0x2975c3, + 0x204342, + 0x322205, + 0x204f06, 0x200382, - 0x3451c7, - 0x266a83, + 0x2bfd47, + 0x343b43, 0x200642, - 0x23e108, - 0x26cd51, - 0x26d190, - 0x202182, - 0x291c47, - 0x204b82, - 0x277507, - 0x206902, - 0x207089, - 0x381ac7, - 0x294648, - 0x361b06, - 0x207483, - 0x207485, - 0x234242, + 0x23e448, + 0x3b4111, + 0x3b4550, + 0x202102, + 0x296907, + 0x202642, + 0x25c247, + 0x207bc2, + 0x208309, + 0x37ecc7, + 0x3e5848, + 0x20afc6, + 0x208703, + 0x208705, + 0x225e82, 0x2004c2, - 0x3c94c5, - 0x3b3785, - 0x201482, - 0x219303, - 0x3546c7, - 0x20bdc7, - 0x204d02, - 0x249084, - 0x20eb03, - 0x2f6f89, - 0x20eb08, - 0x202702, - 0x20a682, - 0x26b947, - 0x26ca45, - 0x273508, - 0x2b1347, - 0x209f03, - 0x2a0d06, - 0x30268d, - 0x302a0c, - 0x305e06, - 0x206b02, - 0x208c82, - 0x20b982, - 0x2871cf, - 0x2875ce, - 0x365507, - 0x204482, - 0x388c05, - 0x388c06, - 0x215782, + 0x3cbbc5, + 0x36bd85, + 0x20b402, + 0x237843, + 0x352f87, + 0x3c3c47, + 0x203f02, + 0x38f0c4, + 0x271f43, + 0x33eec9, + 0x3c7348, + 0x209d42, + 0x210442, + 0x22cac7, + 0x231745, + 0x20c708, + 0x327287, + 0x20f543, + 0x3d4986, + 0x21b84d, + 0x21bbcc, + 0x223046, + 0x204202, + 0x31de42, + 0x201582, + 0x28e30f, + 0x28e70e, + 0x372307, + 0x202042, + 0x3d2185, + 0x3d2186, + 0x228882, 0x200bc2, - 0x293506, - 0x206583, - 0x206586, - 0x2d8a45, - 0x2d8a4d, - 0x2d92d5, - 0x2da14c, - 0x2da4cd, - 0x2da812, - 0x20a942, - 0x2720c2, - 0x203882, - 0x36ac46, - 0x204a46, - 0x202542, - 0x203446, + 0x298346, + 0x210783, + 0x3c2c46, + 0x2dd585, + 0x2dd58d, + 0x2de195, + 0x2ded4c, + 0x2df0cd, + 0x2df412, + 0x203742, + 0x277782, + 0x202802, + 0x3437c6, + 0x20e586, + 0x43296084, + 0x201cc2, + 0x204f86, 0x201102, - 0x324805, - 0x202582, - 0x398709, - 0x22ce4c, - 0x22d18b, + 0x3a2b45, + 0x205c02, + 0x250f49, + 0x22d58c, + 0x22d8cb, 0x2003c2, - 0x252e48, - 0x202a42, + 0x25e3c8, + 0x211c02, 0x200a82, - 0x278706, - 0x245ac5, + 0x27de46, + 0x266005, 0x200a87, - 0x22dcc5, - 0x257e45, - 0x201b42, - 0x21dcc2, - 0x205b42, - 0x298c07, - 0x2fd00d, - 0x2fd38c, - 0x235507, - 0x27ce82, - 0x211c82, - 0x3dc788, - 0x248d88, - 0x34f348, - 0x3bb1c4, - 0x372d07, - 0x36aa43, - 0x22d782, - 0x204ac2, - 0x2fe3c9, - 0x30b287, - 0x216982, - 0x278b05, - 0x242c42, - 0x20d402, - 0x2f8b83, - 0x2f8b86, - 0x306d42, - 0x308142, + 0x2fca45, + 0x2824c5, + 0x23d7c2, + 0x21e582, + 0x208402, + 0x29f107, + 0x301b0d, + 0x301e8c, + 0x25d707, + 0x29a902, + 0x219d02, + 0x3e8008, + 0x38ff08, + 0x2e5e08, + 0x3bc204, + 0x342ac7, + 0x363b83, + 0x206bc2, + 0x203482, + 0x302889, + 0x233347, + 0x2037c2, + 0x27e245, + 0x24cec2, + 0x204682, + 0x30b0c3, + 0x30b0c6, + 0x309602, + 0x30a282, 0x200402, - 0x3616c6, - 0x34de07, - 0x216782, + 0x2abc86, + 0x273007, + 0x213582, 0x200902, - 0x26108f, - 0x28cd4d, - 0x28fd0e, - 0x2bb4cc, - 0x208842, - 0x205302, - 0x361945, - 0x325d86, + 0x291f0f, + 0x243acd, + 0x39e2ce, + 0x2c74cc, + 0x20cbc2, + 0x202a82, + 0x20ae05, + 0x324106, 0x200b82, - 0x205502, + 0x205d42, 0x200682, - 0x28d0c4, - 0x2c14c4, - 0x389fc6, - 0x207742, - 0x28d807, - 0x23c643, - 0x23c648, - 0x23d1c8, - 0x245207, - 0x249946, - 0x20ab02, - 0x2186c3, - 0x2186c7, - 0x292246, - 0x2ecb85, - 0x27a1c8, - 0x2018c2, - 0x3c1007, - 0x207142, - 0x25cdc2, - 0x201702, - 0x219649, - 0x203c02, - 0x10acc8, - 0x201f42, - 0x235783, - 0x3599c7, + 0x243e44, + 0x2c4b44, + 0x36c186, + 0x201ec2, + 0x292d47, + 0x23f643, + 0x23f648, + 0x2408c8, + 0x24ad47, + 0x251646, + 0x204ac2, + 0x2118c3, + 0x2118c7, + 0x28a6c6, + 0x2ed245, + 0x27f908, + 0x202d82, + 0x35b4c7, + 0x203782, + 0x352902, + 0x204102, + 0x2221c9, + 0x24b302, + 0x14448, + 0x201b82, + 0x25d983, + 0x32e887, 0x200f02, - 0x22cfcc, - 0x22d2cb, - 0x305e86, - 0x3034c5, - 0x203d02, - 0x202a82, - 0x2cb146, - 0x20dd03, - 0x36a307, - 0x2b3f42, + 0x22d70c, + 0x22da0b, + 0x2abf06, + 0x223e85, + 0x43609d83, + 0x22bdc2, + 0x202a02, + 0x2cf7c6, + 0x209003, + 0x363447, + 0x211482, 0x2008c2, - 0x244315, - 0x3a5bd5, - 0x387c53, - 0x3a6113, - 0x2596c7, - 0x28b111, - 0x2908d0, - 0x2f7b92, - 0x29b711, - 0x2a0548, - 0x2a0550, - 0x2a2c8f, - 0x2a6953, - 0x2aea52, - 0x2b8190, - 0x36f14f, - 0x3a4112, - 0x2bac51, - 0x2bfa93, - 0x3426d2, - 0x2d868f, - 0x2e010e, - 0x2e3512, - 0x2e43d1, - 0x2e79cf, - 0x2ea38e, - 0x2ed451, - 0x2fa9d0, - 0x304412, - 0x307211, - 0x309090, - 0x321ecf, - 0x37ab11, - 0x3d2fd0, - 0x33fac6, - 0x314b47, - 0x2153c7, - 0x202402, - 0x288985, - 0x3135c7, - 0x21fcc2, - 0x208d82, - 0x22b8c5, - 0x208743, - 0x26ec86, - 0x2fd1cd, - 0x2fd50c, - 0x2034c2, - 0x25f2cb, - 0x27abca, - 0x22718a, - 0x2ca549, - 0x2fc34b, - 0x2b148d, - 0x313ccc, - 0x240cca, - 0x2466cc, - 0x24e88b, - 0x27784c, - 0x27bd0e, - 0x29cb4b, - 0x2b668c, - 0x2ec543, - 0x2edf06, - 0x3c6782, - 0x305102, - 0x25cb43, - 0x201502, - 0x204243, - 0x353446, - 0x262a87, - 0x2c3846, - 0x2158c8, - 0x354548, - 0x3800c6, - 0x20e482, - 0x31598d, - 0x315ccc, - 0x32bf07, - 0x319707, - 0x223542, - 0x216b82, - 0x203b02, - 0x284302, - 0x336c56, - 0x33b795, - 0x3407d6, - 0x3437d3, - 0x343e92, - 0x35bc93, - 0x35de52, - 0x3b6bcf, - 0x3c5758, - 0x3c6257, - 0x3c6c59, - 0x3c8b18, - 0x3c96d8, - 0x3cb9d7, - 0x3cc457, - 0x3ce196, - 0x3d1cd3, - 0x3d2755, - 0x3d33d2, - 0x3d3853, - 0x212402, - 0x217fc3, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x208503, + 0x2560d5, + 0x3a7455, + 0x259e93, + 0x3a7993, + 0x279587, + 0x294d91, + 0x2f9010, + 0x2a27d2, + 0x2a7411, + 0x2aae48, + 0x2aae50, + 0x372f4f, + 0x3a5e53, + 0x3abf92, + 0x2c2690, + 0x2bec4f, + 0x2c2bd2, + 0x2c4191, + 0x2d73d3, + 0x2dd112, + 0x2e3d4f, + 0x2e664e, + 0x2e7e92, + 0x2ec211, + 0x2ed70f, + 0x2f58ce, + 0x2f7251, + 0x2f8450, + 0x2ff012, + 0x307751, + 0x309ad0, + 0x30b50f, + 0x366211, + 0x355510, + 0x37f0c6, + 0x31e787, + 0x234ac7, + 0x201c02, + 0x28ce85, + 0x313507, + 0x22a042, + 0x203f82, + 0x3d0545, + 0x228183, + 0x35c606, + 0x301ccd, + 0x30200c, + 0x205002, + 0x363c8b, + 0x27fe4a, + 0x22cf8a, + 0x2ceb09, + 0x300a8b, + 0x3273cd, + 0x313c0c, + 0x2477ca, + 0x24ec8c, + 0x27aa4b, + 0x28124c, + 0x28418e, + 0x2a0b0b, + 0x2eafcc, + 0x2f3103, + 0x2ef706, + 0x3c9402, + 0x308542, + 0x2651c3, + 0x2017c2, + 0x23d203, + 0x351d46, + 0x26d087, + 0x2e2846, + 0x3aad48, + 0x352e08, + 0x306d06, + 0x208e42, + 0x31594d, + 0x315c8c, + 0x3d6b07, + 0x319b07, + 0x221e02, + 0x21f8c2, + 0x211842, + 0x289c82, + 0x3377d6, + 0x33c555, + 0x33f9d6, + 0x344113, + 0x3447d2, + 0x356dd3, + 0x357512, + 0x3b7ccf, + 0x3c6b58, + 0x3c8ed7, + 0x3c98d9, + 0x3cb218, + 0x3cbdd8, + 0x3cccd7, + 0x3ced97, + 0x3d1216, + 0x3d6013, + 0x3d6f55, + 0x3d77d2, + 0x3d7c53, + 0x30182, + 0x43a13a04, + 0x43fc4b88, + 0x3ec5, + 0x216542, + 0x2296c3, + 0x386c2, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x202b03, 0x2000c2, - 0x202642, - 0x3ce98545, - 0x3d25ef05, - 0x3d73ed86, - 0xae888, - 0x3dac0105, - 0x212402, - 0x204542, - 0x3de5de45, - 0x3e285fc5, - 0x3e687a87, - 0x3ea87dc9, - 0x3ef4da84, + 0x2070c2, + 0x44e9bcc5, + 0x4529b285, + 0x4567ad86, + 0x793c8, + 0x45ac3205, + 0x216542, + 0x2104c2, + 0x45f336c5, + 0x4628b685, + 0x4668c587, + 0x46a93f89, + 0x46e1eb44, 0x200382, 0x200642, - 0x3f25bf05, - 0x3f69e949, - 0x3fb36248, - 0x3feb87c5, - 0x403513c7, - 0x40623708, - 0x40b08c85, - 0x40e9f486, - 0x413a9a89, - 0x416dd6c8, - 0x41ad02c8, - 0x41e9ef8a, - 0x422ef084, - 0x426ad705, - 0x42acc788, - 0x42e48985, - 0x214882, - 0x4324bd03, - 0x436abe06, - 0x43a6af08, - 0x43ef4246, - 0x4434df48, - 0x447af006, - 0x44a463c4, - 0x44e03182, - 0x45707b87, - 0x45ab43c4, - 0x45e81487, - 0x463da087, + 0x4725a945, + 0x4769b3c9, + 0x47b36dc8, + 0x47ebb2c5, + 0x4834ff07, + 0x4861cf88, + 0x48b18f85, + 0x48e21486, + 0x4924b649, + 0x496f9ec8, + 0x49ad5408, + 0x49ea4e8a, + 0x4a387144, + 0x4a6b2605, + 0x4aad1108, + 0x4ae876c5, + 0x21ab82, + 0x4b2e3303, + 0x4b6aff46, + 0x4bba9148, + 0x4bf53fc6, + 0x4c273148, + 0x4c7da086, + 0x4ca4fb84, + 0x4ce04cc2, + 0x4d6e2c47, + 0x4dab7d44, + 0x4de85287, + 0x4e3e3047, 0x2003c2, - 0x466a3e85, - 0x46a15cc4, - 0x46faaa07, - 0x4723c0c7, - 0x4768aac6, - 0x47a86b45, - 0x47e9ea47, - 0x482dd548, - 0x487da407, - 0x48adcb49, - 0x48ed9845, - 0x4931d047, - 0x49697b86, - 0x27c4b, - 0x49b47b08, - 0x22800d, - 0x25c089, - 0x279d4b, - 0x27b8cb, - 0x2afecb, - 0x39b08b, + 0x4e6a8485, + 0x4ea7fa84, + 0x4efafd07, + 0x4f23cc07, + 0x4f690046, + 0x4fa8c145, + 0x4fea2f07, + 0x502cdf88, + 0x507e33c7, + 0x50abb909, + 0x50ee3405, + 0x5131f287, + 0x5169b0c6, + 0x2780b, + 0x51a2e2c8, + 0x230c4d, + 0x271d09, + 0x27f48b, + 0x29868b, + 0x2b744b, + 0x2d24cb, + 0x32430b, + 0x3245cb, + 0x324a89, 0x325f8b, 0x32624b, - 0x326709, - 0x32770b, - 0x3279cb, - 0x32850b, - 0x32910a, - 0x32964a, - 0x329c4c, - 0x32e6cb, - 0x32ec0a, - 0x34228a, - 0x34d34e, - 0x34e94e, - 0x34ecca, - 0x350b0a, - 0x351b4b, - 0x351e0b, - 0x35290b, - 0x372ecb, - 0x3734ca, - 0x37418b, - 0x37444a, - 0x3746ca, - 0x37494a, - 0x394a0b, - 0x39bbcb, - 0x39ed4e, - 0x39f0cb, - 0x3a65cb, - 0x3a73cb, - 0x3ab74a, - 0x3ab9c9, - 0x3abc0a, - 0x3ad9ca, - 0x3c514b, - 0x3d00cb, - 0x3d0aca, - 0x3d170b, - 0x3d7a4b, - 0x3e07cb, - 0x49e89188, - 0x4a290209, - 0x4a6a7249, - 0x4aaefcc8, - 0x35f145, - 0x204083, - 0x251f44, - 0x34e385, - 0x34d7c6, - 0x367645, - 0x28f384, - 0x3450c8, - 0x31f645, - 0x299784, - 0x203787, - 0x2a634a, - 0x37738a, - 0x365607, - 0x26b0c7, - 0x2e7ec7, - 0x288047, - 0x33a405, - 0x20e506, - 0x2f34c7, - 0x20fd84, - 0x3ba146, - 0x3ba046, - 0x3dccc5, - 0x389dc4, - 0x29ffc6, - 0x2a5407, - 0x2671c6, - 0x31a487, - 0x235e43, - 0x3a2246, - 0x238d85, - 0x287b87, - 0x26fe0a, - 0x237784, - 0x2219c8, - 0x39a2c9, - 0x2d6b87, - 0x3bba06, - 0x203f48, - 0x2f4989, - 0x3a2084, - 0x2d2a04, - 0x313005, - 0x21e388, - 0x2d6e47, - 0x2b7689, - 0x3690c8, - 0x31b8c6, - 0x266cc6, - 0x2a0b88, - 0x371c86, - 0x25ef05, - 0x28ab86, - 0x281f48, - 0x2870c6, - 0x255f0b, - 0x2be206, - 0x2a280d, - 0x205385, - 0x2b4286, - 0x21f585, - 0x2bc949, - 0x2e0cc7, - 0x3cd248, - 0x39dec6, - 0x2a1949, - 0x2c1246, - 0x26fd85, - 0x2a9606, - 0x2d5506, - 0x2db549, - 0x2c8186, - 0x2a6047, - 0x2d5bc5, - 0x208a43, - 0x22d805, - 0x395c07, - 0x25fac6, - 0x205289, - 0x33ed86, - 0x281686, - 0x226049, - 0x28a589, - 0x2aa947, - 0x207648, - 0x29b149, - 0x288608, - 0x3a7646, - 0x2e5285, - 0x27dd4a, - 0x281706, - 0x347446, - 0x2deb05, - 0x253708, - 0x2f5707, - 0x23114a, - 0x24df06, - 0x2e2785, - 0x3086c6, - 0x20d647, - 0x3bb8c7, - 0x21a3c5, - 0x26ff45, - 0x26c506, - 0x273b06, - 0x2b0d46, - 0x2ccc44, - 0x289b09, - 0x291a06, - 0x306f0a, - 0x30c148, - 0x31cd48, - 0x37738a, - 0x2ef805, - 0x2a5345, - 0x3cac88, - 0x2c7e88, - 0x2398c7, - 0x36ee86, - 0x339788, - 0x20ee87, - 0x27a408, - 0x2c6806, - 0x28bac8, - 0x29de06, - 0x283847, - 0x23b3c6, - 0x29ffc6, - 0x27438a, - 0x305f86, - 0x2e5289, - 0x2a7746, - 0x22910a, - 0x2463c9, - 0x2fd9c6, - 0x2c9144, - 0x2d274d, - 0x285e07, - 0x3325c6, - 0x2d0185, - 0x2c12c5, - 0x396906, - 0x2a9b89, - 0x2c09c7, - 0x282946, - 0x2ced06, - 0x28f409, - 0x288d84, - 0x23f644, - 0x3b53c8, - 0x237ac6, - 0x2a9708, - 0x322708, - 0x3a9f87, - 0x358b89, - 0x3c9f87, - 0x2bffca, - 0x2fee8f, - 0x2b230a, - 0x3e22c5, - 0x282185, - 0x21c3c5, - 0x229747, - 0x20d203, - 0x207848, - 0x355606, - 0x355709, - 0x2f3dc6, - 0x2db387, - 0x2a1709, - 0x3cd148, - 0x2debc7, - 0x325343, - 0x35f1c5, - 0x20d185, - 0x2cca8b, - 0x248a44, - 0x238344, - 0x27d506, - 0x325507, - 0x396e8a, - 0x24bd87, - 0x298787, - 0x285fc5, - 0x3d5c05, - 0x296ac9, - 0x29ffc6, - 0x24bc0d, - 0x273445, - 0x2c3c03, - 0x2059c3, - 0x3617c5, - 0x33a085, - 0x203f48, - 0x283287, - 0x23f3c6, - 0x2a6ec6, - 0x22bbc5, - 0x234287, - 0x25eb47, - 0x252287, - 0x2ad78a, - 0x3a2308, - 0x2ccc44, - 0x286e47, + 0x3283cb, + 0x328fca, + 0x32950a, + 0x329b0c, + 0x32fecb, + 0x33040a, + 0x34218a, + 0x34c2ce, + 0x34d44e, + 0x34d7ca, + 0x34f78a, + 0x35044b, + 0x35070b, + 0x35120b, + 0x36e7cb, + 0x36edca, + 0x36fa8b, + 0x36fd4a, + 0x36ffca, + 0x37024a, + 0x391a8b, + 0x39944b, + 0x39bc0e, + 0x39bf8b, + 0x3a7e4b, + 0x3a9ecb, + 0x3ada8a, + 0x3add09, + 0x3adf4a, + 0x3afa0a, + 0x3c654b, + 0x3d3d8b, + 0x3d4f4a, + 0x3d5a4b, + 0x3dbc4b, + 0x3e8b8b, + 0x51e8d908, + 0x522946c9, + 0x526ab689, + 0x52af0788, + 0x359645, + 0x20dec3, + 0x25cd84, + 0x2cbb05, + 0x21e886, + 0x221205, + 0x293a44, + 0x2bfc48, + 0x31fc85, + 0x29d144, + 0x20d007, + 0x2aa84a, + 0x24104a, + 0x372407, + 0x3a9307, + 0x2ec787, + 0x291247, + 0x313305, + 0x219686, + 0x372c47, + 0x35a804, + 0x2c9046, + 0x3dc846, + 0x203345, + 0x333144, + 0x2a80c6, + 0x2a9a07, + 0x22fa86, + 0x2b6407, + 0x23e343, + 0x39f546, + 0x3367c5, + 0x28c687, + 0x27588a, + 0x23e544, + 0x21ad88, + 0x2ba709, + 0x2c9607, + 0x3c6006, + 0x267608, + 0x37ae89, + 0x39f384, + 0x322584, + 0x30c2c5, + 0x21b448, + 0x2dbb47, + 0x30a449, + 0x3d8f48, + 0x31b5c6, + 0x361b46, + 0x2a5ac8, + 0x36d846, + 0x29b285, + 0x290106, + 0x285988, + 0x28e206, + 0x261acb, + 0x38a106, + 0x2a6f8d, + 0x20d485, + 0x2b7c06, + 0x21d045, + 0x3c8609, + 0x2e4747, + 0x3d2008, + 0x3c4f86, + 0x2a6209, + 0x2c48c6, + 0x275805, + 0x216b86, + 0x2d7cc6, + 0x2e02c9, + 0x2cc886, + 0x31d5c7, + 0x2dec05, + 0x20c043, + 0x261c45, + 0x2bc687, + 0x3640c6, + 0x20d389, + 0x27ad86, + 0x285486, + 0x226a89, + 0x28fb09, + 0x2aea87, + 0x201dc8, + 0x29f949, + 0x28cb08, + 0x3e5e06, + 0x2e8945, + 0x2834ca, + 0x285506, + 0x3cfc86, + 0x2e2b85, + 0x25ec08, + 0x358d07, + 0x239a8a, + 0x257686, + 0x303885, + 0x30aa86, + 0x2048c7, + 0x3c5ec7, + 0x2ac545, + 0x2759c5, + 0x23fdc6, + 0x36a446, + 0x269f46, + 0x2d15c4, + 0x28ebc9, + 0x2966c6, + 0x3097ca, + 0x232148, + 0x31ef88, + 0x24104a, + 0x2421c5, + 0x2a9945, + 0x3def48, + 0x2ce108, + 0x23ae87, + 0x288686, + 0x33a388, + 0x20b607, + 0x28d208, + 0x2ca506, + 0x290f08, + 0x2a1dc6, + 0x287287, + 0x29ea46, + 0x2a80c6, + 0x2313ca, + 0x3dbf46, + 0x2e8949, + 0x2abb86, + 0x212f8a, + 0x24fb89, + 0x3024c6, + 0x2cd844, + 0x3222cd, + 0x28b4c7, + 0x39fe06, + 0x2d52c5, + 0x2c4945, + 0x394246, + 0x2ae109, + 0x369787, + 0x286386, + 0x393386, + 0x293ac9, + 0x2e37c4, + 0x3025c4, + 0x30f188, + 0x2fbec6, + 0x2adc88, + 0x216b08, + 0x260507, + 0x30e2c9, + 0x347a47, + 0x2c30ca, + 0x30334f, + 0x2396ca, + 0x20ac05, + 0x285bc5, + 0x216945, + 0x3cd547, + 0x204483, + 0x201fc8, + 0x2f6086, + 0x2f6189, + 0x2f5f86, + 0x2e0c87, + 0x2a5fc9, + 0x3d1f08, + 0x3c87c7, + 0x322d43, + 0x3596c5, + 0x204405, + 0x2d140b, + 0x287784, + 0x300084, + 0x282c86, + 0x322f07, + 0x3947ca, + 0x3b0887, + 0x29bf07, + 0x28b685, + 0x3de685, + 0x2934c9, + 0x2a80c6, + 0x3b070d, + 0x354745, + 0x2c7183, + 0x20dac3, + 0x258b05, + 0x33ac85, + 0x267608, + 0x286cc7, + 0x245246, + 0x2ab306, + 0x235745, + 0x23c847, + 0x3e4107, + 0x25d0c7, + 0x2b268a, + 0x39f608, + 0x2d15c4, + 0x28df87, + 0x28a847, + 0x35df46, + 0x2a1447, + 0x2ea808, + 0x35d588, + 0x27a306, + 0x3a9548, + 0x2cc904, + 0x372c46, + 0x266286, + 0x246046, + 0x2025c6, + 0x214ac4, + 0x291306, + 0x2d3e46, + 0x2a5386, + 0x224006, + 0x20d986, + 0x2ea646, + 0x245148, + 0x2c6648, + 0x2e5688, + 0x221408, + 0x3deec6, + 0x20f1c5, + 0x27b9c6, + 0x2bb345, + 0x397087, + 0x246005, + 0x217943, + 0x26a545, + 0x23b844, + 0x20dac5, + 0x223a03, + 0x2c4707, + 0x3aa1c8, + 0x2b64c6, + 0x2d630d, + 0x285b86, + 0x2a4905, + 0x2221c3, + 0x2d0ac9, + 0x2e3946, + 0x2a34c6, + 0x29c484, + 0x239647, + 0x2f43c6, + 0x303ac5, + 0x244243, + 0x211184, + 0x28aa06, + 0x219784, + 0x3c11c8, + 0x2064c9, + 0x369d09, + 0x2ada8a, + 0x2495cd, + 0x23e8c7, + 0x206986, + 0x21e5c4, + 0x293f89, + 0x2924c8, + 0x294546, + 0x242b06, + 0x2a1447, + 0x2c3b06, + 0x223686, + 0x3d0c06, + 0x3e30ca, + 0x21cf88, + 0x234885, + 0x245749, + 0x270b0a, + 0x33b008, + 0x2a8cc8, + 0x2a3448, + 0x3e450c, + 0x3996c5, + 0x2ab588, + 0x2ca006, + 0x29dac6, + 0x2dab47, + 0x3b0785, + 0x290285, + 0x369bc9, + 0x210b07, + 0x2f6145, + 0x2286c7, + 0x20dac3, + 0x2dc505, + 0x229108, + 0x2cc507, + 0x2a8b89, + 0x2e1dc5, + 0x30a804, + 0x31dc08, + 0x2cb5c7, + 0x3c8988, + 0x22aa48, + 0x392005, + 0x353b46, + 0x2ab406, + 0x30c689, + 0x266387, + 0x2bbb86, + 0x2585c7, + 0x215103, + 0x21eb44, + 0x2e6fc5, + 0x23c984, + 0x2526c4, + 0x28db87, + 0x2743c7, + 0x286544, + 0x2a89d0, + 0x333847, + 0x3de685, + 0x25084c, + 0x22a804, + 0x2c1108, + 0x287189, + 0x2be9c6, + 0x32f908, + 0x27a484, + 0x282f88, + 0x23a086, + 0x231248, + 0x2a93c6, + 0x2d2d4b, + 0x331b85, + 0x2e6e48, + 0x21a484, + 0x28f78a, + 0x2a8b89, + 0x29e946, + 0x21b6c8, + 0x2657c5, + 0x2d00c4, + 0x2c1006, + 0x25cf88, + 0x28d908, + 0x3356c6, + 0x36c104, + 0x283446, + 0x347ac7, 0x285187, - 0x363306, - 0x29d487, - 0x2ebd88, - 0x3d8348, - 0x29c3c6, - 0x26b308, - 0x2c8204, - 0x2f34c6, - 0x250dc6, - 0x3d5486, - 0x208006, - 0x218e84, - 0x288106, - 0x2cf246, - 0x2a0386, - 0x24bc06, - 0x205886, - 0x2a7e46, - 0x23f2c8, - 0x2c2a48, - 0x2e1e88, - 0x367848, - 0x3cac06, - 0x210ec5, - 0x22d7c6, - 0x2b8845, - 0x399107, - 0x295d45, - 0x2119c3, - 0x2e5f45, - 0x235fc4, - 0x2059c5, - 0x202a43, - 0x3c4bc7, - 0x399d08, - 0x31a546, - 0x34490d, - 0x282146, - 0x29f945, - 0x219643, - 0x2cc149, - 0x288f06, - 0x23b1c6, - 0x3b2144, - 0x2b2287, - 0x3611c6, - 0x23f845, - 0x270483, - 0x20b344, - 0x285346, - 0x20e604, - 0x275548, - 0x204609, - 0x32e489, - 0x2a950a, - 0x29738d, - 0x23e587, - 0x3c2cc6, - 0x21dd04, - 0x287dc9, - 0x28e308, - 0x290086, - 0x23abc6, - 0x29d487, - 0x2c98c6, - 0x226c46, - 0x25dfc6, - 0x3da10a, - 0x223708, - 0x2ef705, - 0x356c09, - 0x2d75ca, - 0x30cd48, - 0x2a46c8, - 0x299fc8, - 0x2b45cc, - 0x395905, - 0x2a7148, - 0x2c2d46, - 0x2e1446, - 0x2d5707, - 0x24bc85, - 0x28ad05, - 0x32e349, - 0x214207, - 0x3556c5, - 0x2284c7, - 0x2059c3, - 0x2d7a85, - 0x224148, - 0x2d9047, - 0x2a4589, - 0x2e5145, - 0x311404, - 0x2ab1c8, - 0x2eed47, - 0x2ded88, - 0x2206c8, - 0x2b5285, - 0x21f746, - 0x2a6fc6, - 0x3c2909, - 0x250ec7, - 0x2b8cc6, - 0x355347, - 0x208683, - 0x34da84, - 0x2dc405, - 0x2343c4, - 0x24b684, - 0x38fc47, - 0x26da47, - 0x282b04, - 0x2a43d0, - 0x207bc7, - 0x3d5c05, - 0x3b3c8c, - 0x220484, - 0x31e048, - 0x283749, - 0x3d78c6, - 0x31fc48, - 0x27d804, - 0x27d808, - 0x231746, - 0x274208, - 0x2a38c6, - 0x39b90b, - 0x330685, - 0x2dc288, - 0x213684, - 0x28988a, - 0x2a4589, - 0x23b2c6, - 0x2c2f48, - 0x2592c5, - 0x2cb744, - 0x31df46, - 0x252148, - 0x289188, - 0x333e86, - 0x389f44, - 0x27dcc6, - 0x3ca007, - 0x281387, - 0x29d48f, - 0x346f07, - 0x2fda87, - 0x388ac5, - 0x377ac5, - 0x2aa609, - 0x2f7786, - 0x38fe85, - 0x28a887, - 0x2d5988, - 0x302545, - 0x23b3c6, - 0x30bf88, - 0x2f424a, - 0x37e648, - 0x293287, - 0x2ff2c6, - 0x356bc6, + 0x2a144f, + 0x346f47, + 0x395747, + 0x368945, + 0x3410c5, + 0x2ae749, + 0x2f8c06, + 0x28c7c5, + 0x28fe07, + 0x2de9c8, + 0x219805, + 0x29ea46, + 0x231f88, + 0x353fca, + 0x32c888, + 0x2980c7, + 0x303786, + 0x245706, 0x2003c3, - 0x20c483, - 0x2d7789, - 0x29afc9, - 0x2dca46, - 0x2e5145, - 0x2b4448, - 0x2c2f48, - 0x2a3508, - 0x25e04b, - 0x344b47, - 0x3211c9, - 0x29d708, - 0x3505c4, - 0x3d50c8, - 0x295909, - 0x2b8fc5, - 0x229647, - 0x34db05, - 0x289088, - 0x2983cb, - 0x29e790, - 0x2b3e05, - 0x2135cc, - 0x23f585, - 0x25e883, - 0x2b6486, - 0x2ce3c4, - 0x23b686, - 0x2a5407, - 0x203d44, - 0x243208, - 0x20770d, - 0x3224c5, - 0x23e5c4, - 0x2b5684, - 0x2b5689, + 0x211c03, + 0x270cc9, + 0x29f7c9, + 0x2bb806, + 0x2e1dc5, + 0x3a97c8, + 0x21b6c8, + 0x2a7d08, + 0x3d0c8b, + 0x2d6547, + 0x31d409, + 0x2a16c8, + 0x329f44, + 0x3e3a48, + 0x299dc9, + 0x2bbe85, + 0x3cd447, + 0x21ebc5, + 0x28d808, + 0x29bb4b, + 0x2a2c50, + 0x2b7845, + 0x21a3cc, + 0x245405, + 0x28b703, + 0x2b49c6, + 0x2d3004, + 0x27fb86, + 0x2a9a07, + 0x221404, + 0x24cf48, + 0x201e8d, + 0x342545, + 0x23e904, + 0x2b60c4, + 0x395489, + 0x2afa88, + 0x332047, + 0x23a108, + 0x28ec88, + 0x286685, + 0x3cd987, + 0x286607, + 0x2f6447, + 0x2759c9, + 0x3c3009, + 0x375346, + 0x21bf06, + 0x28fec6, + 0x31a6c5, + 0x3c7104, + 0x3cf306, + 0x3d9dc6, + 0x2866c8, + 0x20458b, + 0x2fba47, + 0x21e5c4, + 0x2f4306, + 0x2eab47, + 0x38c785, + 0x3a1b45, + 0x266844, + 0x3c2f86, + 0x3cf388, + 0x293f89, + 0x254986, + 0x2922c8, + 0x303b86, + 0x360fc8, + 0x3603cc, + 0x286546, + 0x2a45cd, + 0x2a4a4b, + 0x31d685, + 0x3e4247, + 0x2cc986, + 0x3c5d88, + 0x3753c9, + 0x21d3c8, + 0x3de685, + 0x2893c7, + 0x28cc08, + 0x3c3709, + 0x2f4046, + 0x26af8a, + 0x3c5b08, + 0x21d20b, + 0x2d668c, + 0x283088, + 0x28a286, + 0x22de48, + 0x353c47, + 0x224e49, + 0x29b2cd, + 0x2a7fc6, + 0x3dc948, + 0x2c6509, + 0x2d16c8, + 0x291008, + 0x2d4c8c, + 0x2d5947, + 0x2d7887, + 0x275805, + 0x2c9987, + 0x2de888, + 0x2c1086, + 0x25480c, + 0x306808, + 0x2e1708, + 0x3cf646, + 0x327e47, + 0x375544, + 0x221408, + 0x29594c, + 0x243f8c, + 0x20ac85, + 0x2033c7, + 0x36c086, + 0x327dc6, + 0x39d8c8, + 0x224dc4, + 0x22fa8b, + 0x292e8b, + 0x303786, + 0x201d07, + 0x208805, + 0x27d905, + 0x22fbc6, + 0x265785, + 0x287745, + 0x2e0107, + 0x223a09, + 0x36a604, + 0x247245, + 0x30b005, + 0x3477c8, + 0x3a89c5, + 0x2d7089, + 0x3982c7, + 0x3982cb, + 0x302206, + 0x244e89, + 0x333088, + 0x2931c5, + 0x2f6548, + 0x3c3048, + 0x283d07, + 0x2455c7, + 0x28dc09, + 0x231187, + 0x29a109, + 0x2b984c, + 0x2bb808, + 0x2bf649, + 0x2c0787, + 0x28ed49, + 0x38fbc7, + 0x2d6788, + 0x3c1585, + 0x372bc6, + 0x2d5308, + 0x2fa4c8, + 0x2709c9, + 0x287787, + 0x27e305, + 0x207789, + 0x31f546, + 0x29b0c4, + 0x37f506, + 0x3a8fc8, + 0x23bc07, + 0x204788, + 0x3a9609, + 0x353907, + 0x2a7e46, + 0x3e3d84, + 0x26a5c9, + 0x3cd808, + 0x3cf507, + 0x291846, + 0x2044c6, + 0x3cfc04, + 0x2f3b46, + 0x207843, + 0x331709, + 0x331b46, + 0x2b7e85, + 0x2ab306, + 0x224185, + 0x28d088, + 0x205387, + 0x3c2786, + 0x333706, + 0x31ef88, + 0x2ae8c7, + 0x2a8005, + 0x2a87c8, + 0x3d4188, + 0x3c5b08, + 0x2452c5, + 0x372c46, + 0x369ac9, + 0x30c504, + 0x22400b, + 0x22338b, + 0x234789, + 0x20dac3, + 0x263745, + 0x2b62c6, + 0x246508, + 0x2fb584, + 0x2b64c6, + 0x2b27c9, + 0x3201c5, + 0x2e0046, + 0x2cb5c6, + 0x21b6c4, + 0x2a8e4a, + 0x2b7dc8, + 0x2fa4c6, + 0x371545, + 0x201b87, + 0x33aec7, + 0x353b44, + 0x2235c7, + 0x245fc4, + 0x245fc6, + 0x202003, + 0x2759c5, + 0x2bdc85, + 0x347188, + 0x28e145, + 0x286289, + 0x221247, + 0x22124b, + 0x2afd4c, + 0x2b034a, + 0x34ff07, + 0x20ac43, + 0x284b88, + 0x302585, + 0x219885, + 0x359784, + 0x2d6686, + 0x287186, + 0x2f3b87, + 0x26030b, + 0x214ac4, + 0x368a84, + 0x2bf884, + 0x2dfe06, + 0x221404, + 0x21b548, + 0x359585, + 0x249c05, + 0x2a7c47, + 0x3e4349, + 0x33ac85, + 0x39424a, + 0x2deb09, + 0x2ae3ca, + 0x3e3209, + 0x31c284, + 0x393445, + 0x2c3c08, + 0x3afdcb, + 0x30c2c5, + 0x216c86, + 0x24a884, + 0x2867c6, + 0x353789, + 0x2eac47, + 0x27af48, + 0x249946, + 0x347a47, + 0x28d908, + 0x3780c6, + 0x3e3e04, + 0x3b2687, + 0x384f05, + 0x396107, + 0x221484, + 0x2cc906, + 0x3aea88, + 0x2a4c08, + 0x32a647, + 0x306e08, + 0x2a1e85, + 0x20d904, + 0x240f48, + 0x29ae44, + 0x2168c5, + 0x3ae984, + 0x20b707, + 0x296787, + 0x28ee88, + 0x322f46, + 0x28e0c5, + 0x286088, + 0x32ca88, + 0x2ad9c9, + 0x223686, + 0x239b08, + 0x28f60a, + 0x38c808, + 0x318f85, + 0x27bbc6, 0x2adfc8, - 0x330b47, - 0x2317c8, - 0x289bc8, - 0x282c45, - 0x27ee47, - 0x282bc7, - 0x3559c7, - 0x26ff49, - 0x25e649, - 0x210706, - 0x302d46, - 0x28a946, - 0x326e85, - 0x3c5d04, - 0x3cc9c6, - 0x3d4e86, - 0x282c88, - 0x20d30b, - 0x237647, - 0x21dd04, - 0x361106, - 0x2ec0c7, - 0x2a7a45, - 0x324a85, - 0x267c04, - 0x25e5c6, - 0x3cca48, - 0x287dc9, - 0x261846, - 0x28e108, - 0x23f906, - 0x365f48, - 0x37904c, - 0x282b06, - 0x29f60d, - 0x29fa8b, - 0x2a6105, - 0x25ec87, - 0x2c8286, - 0x3bb788, - 0x210789, - 0x38a7c8, - 0x3d5c05, - 0x20fac7, - 0x288708, - 0x3c7c49, - 0x360e46, - 0x26174a, - 0x3bb508, - 0x38a60b, - 0x22398c, - 0x27d908, - 0x284906, - 0x27e848, - 0x2f3ec7, - 0x347049, - 0x35150d, - 0x29fec6, - 0x30ef48, - 0x2c2909, - 0x2ccd48, - 0x28bbc8, - 0x2cfb4c, - 0x2d0807, - 0x2d31c7, - 0x26fd85, - 0x2c54c7, - 0x2d5848, - 0x31dfc6, - 0x2704cc, - 0x301fc8, - 0x2dd8c8, - 0x23ae06, - 0x2b1f07, - 0x210904, - 0x367848, - 0x28d20c, - 0x29144c, - 0x3e2345, - 0x3dcd47, - 0x389ec6, - 0x2b1e86, - 0x2bcb08, - 0x21b284, - 0x2671cb, - 0x28d94b, - 0x2ff2c6, - 0x207587, - 0x3572c5, - 0x2781c5, - 0x267306, - 0x259285, - 0x248a05, - 0x2d65c7, - 0x2b2789, - 0x273cc4, - 0x23d405, - 0x2f8ac5, - 0x358908, - 0x2bf505, - 0x2d1d09, - 0x39e2c7, - 0x39e2cb, - 0x2fd706, - 0x23f009, - 0x389d08, - 0x3ae7c5, - 0x355ac8, - 0x25e688, - 0x286407, - 0x2b5a87, - 0x38fcc9, - 0x274147, - 0x295c49, - 0x2d11cc, - 0x2dca48, - 0x2c0dc9, - 0x2c4d07, - 0x289c89, - 0x367207, - 0x223a88, - 0x358d45, - 0x2f3446, - 0x2d01c8, - 0x21c488, - 0x2d7489, - 0x248a47, - 0x278bc5, - 0x3cde49, - 0x2fde86, - 0x297b84, - 0x33ff06, - 0x26ad88, - 0x2e6587, - 0x20d508, - 0x26b3c9, - 0x3a1a87, - 0x2a3646, - 0x25ed44, - 0x2e5fc9, - 0x27ecc8, - 0x23acc7, - 0x2702c6, - 0x20d246, - 0x3473c4, - 0x26b5c6, - 0x205943, - 0x330209, - 0x330646, - 0x2a4905, - 0x2a6ec6, - 0x2db905, - 0x288b88, - 0x33f3c7, - 0x23bb46, - 0x25de86, - 0x31cd48, - 0x2aa787, - 0x29ff05, - 0x2a41c8, - 0x3b1b88, - 0x3bb508, - 0x23f445, - 0x2f34c6, - 0x32e249, - 0x3c2784, - 0x2db78b, - 0x22694b, - 0x2ef609, - 0x2059c3, - 0x257b05, - 0x2ef4c6, - 0x241f88, - 0x30a604, - 0x31a546, - 0x2ad8c9, - 0x2ce1c5, - 0x2d6506, - 0x2eed46, - 0x203f44, - 0x29a14a, - 0x2a4848, - 0x21c486, - 0x375c45, - 0x357147, - 0x33a2c7, - 0x21f744, - 0x226b87, - 0x2bffc4, - 0x369146, - 0x207883, - 0x26ff45, - 0x2ba485, - 0x25b688, - 0x287005, - 0x282849, - 0x2abc07, - 0x36768b, - 0x2abc0c, - 0x2ac20a, - 0x3513c7, - 0x203843, - 0x280d88, - 0x23f605, - 0x3025c5, - 0x35f284, - 0x223986, - 0x283746, - 0x26b607, - 0x3a9d8b, - 0x218e84, - 0x309d04, - 0x2d6784, - 0x2db206, - 0x203d44, - 0x21e488, - 0x35f085, - 0x21a245, - 0x2a3447, - 0x25ed89, - 0x33a085, - 0x39690a, - 0x2d5ac9, - 0x2aceca, - 0x3da249, - 0x354004, - 0x2cedc5, - 0x2c99c8, - 0x3aaacb, - 0x313005, - 0x2ecd46, - 0x241c04, - 0x282d86, - 0x3a1909, - 0x2ec1c7, - 0x33ef48, - 0x297706, - 0x3c9f87, - 0x289188, - 0x37c006, - 0x3d5e84, - 0x386b47, - 0x388705, - 0x398187, - 0x29f484, - 0x2c8206, - 0x30ca48, - 0x29fc48, - 0x33dec7, - 0x3801c8, - 0x29dec5, - 0x205804, - 0x377288, - 0x3802c4, - 0x21c345, - 0x30cc44, - 0x20ef87, - 0x291ac7, - 0x289dc8, - 0x2def06, - 0x286f85, - 0x282648, - 0x37e848, - 0x2a9449, - 0x226c46, - 0x2311c8, - 0x28970a, - 0x2a7ac8, - 0x308c85, - 0x22d9c6, - 0x2a9a48, - 0x20fb8a, - 0x265587, - 0x28e745, - 0x297d88, - 0x2b3a44, - 0x253786, - 0x2d3548, - 0x205886, - 0x33aa08, - 0x2d9e07, - 0x203686, - 0x2c9144, - 0x26a4c7, - 0x2c3304, - 0x3a18c7, - 0x23b00d, - 0x239945, - 0x2d8e4b, - 0x2916c6, - 0x252f48, - 0x2431c4, - 0x3c0706, - 0x285346, - 0x27eb87, - 0x29f2cd, - 0x305587, - 0x2c3b48, - 0x28bd45, - 0x296c88, - 0x2d6dc6, + 0x28948a, + 0x232b87, + 0x292905, 0x29df48, - 0x38ecc6, - 0x3b3a07, - 0x28a149, - 0x35fe07, - 0x290348, - 0x34c1c5, - 0x22bc48, - 0x2b1dc5, - 0x2d6d05, - 0x37d145, - 0x24dc03, - 0x208084, - 0x297f85, - 0x3a9a89, - 0x36ec46, - 0x2ebe88, - 0x2eefc5, - 0x2c5387, - 0x2e0fca, - 0x2d6449, - 0x2d540a, - 0x2e1f08, - 0x22830c, - 0x28a90d, - 0x314e43, - 0x33a908, - 0x20b305, - 0x2f4006, - 0x3ccfc6, - 0x2d2405, - 0x355449, - 0x348ec5, - 0x282648, - 0x258946, - 0x370286, - 0x2ab089, - 0x3b0b47, - 0x298686, - 0x2e0f48, - 0x3d5388, - 0x2efec7, - 0x2cf3ce, - 0x2d7005, - 0x3c7b45, - 0x205788, - 0x36f947, - 0x20d282, - 0x2cf804, - 0x23b58a, - 0x23ad88, - 0x25e7c6, - 0x2a1848, - 0x2a6fc6, - 0x25f708, - 0x2b8cc8, - 0x30b3c4, - 0x2c5745, - 0x602284, - 0x602284, - 0x602284, - 0x207783, - 0x20d0c6, - 0x282b06, - 0x2a5dcc, - 0x202503, - 0x2d75c6, - 0x207844, - 0x288e88, - 0x2ad705, - 0x23b686, - 0x2cc888, - 0x2e3246, - 0x23bac6, - 0x203d48, - 0x2dc487, - 0x273f09, - 0x3df7ca, - 0x26dbc4, - 0x295d45, - 0x2b7645, - 0x2d9a86, - 0x23e5c6, - 0x2a5b46, - 0x3d3f06, - 0x274044, - 0x27404b, - 0x266cc4, - 0x23f185, - 0x2b7cc5, - 0x3aa046, - 0x209648, - 0x28a7c7, - 0x3305c4, - 0x213c03, - 0x2b3545, - 0x33fdc7, - 0x28a6cb, - 0x25b587, - 0x2cc788, - 0x2c5887, - 0x2715c6, - 0x25c348, - 0x2cad4b, - 0x34e2c6, - 0x214a09, - 0x2caec5, - 0x325343, - 0x2d6506, - 0x2d9d08, - 0x215203, - 0x2a11c3, - 0x289186, - 0x2a6fc6, - 0x379eca, - 0x284945, - 0x28518b, - 0x2a6e0b, - 0x2163c3, + 0x272e04, + 0x25ec86, + 0x2d7f88, + 0x20d986, + 0x3d55c8, + 0x237bc7, + 0x20cf06, + 0x2cd844, + 0x326687, + 0x2c6a84, + 0x353747, + 0x3cf84d, + 0x234805, + 0x2cc30b, + 0x244206, + 0x25e4c8, + 0x24cf04, + 0x26a146, + 0x28aa06, + 0x22e187, + 0x2a428d, + 0x3089c7, + 0x2c70c8, + 0x294145, + 0x219948, + 0x2dbac6, + 0x2a1f08, + 0x3e0d46, + 0x36c9c7, + 0x2e2d89, + 0x338587, + 0x294808, + 0x269145, + 0x2357c8, + 0x327d05, + 0x2334c5, + 0x379205, + 0x20af03, + 0x202644, + 0x245745, + 0x24b649, + 0x372a06, + 0x2ea908, + 0x289685, + 0x2c9847, + 0x2a90ca, + 0x2dff89, + 0x2d7bca, + 0x2e5708, + 0x22850c, + 0x28fe8d, + 0x31e443, + 0x3d54c8, + 0x211145, + 0x353d86, + 0x3d1d86, + 0x321f85, + 0x2586c9, + 0x30db85, + 0x286088, + 0x2648c6, + 0x36ad46, + 0x2af1c9, + 0x266e47, + 0x29be06, + 0x2a9048, + 0x245f48, + 0x2f0987, + 0x2e050e, + 0x2dbd05, + 0x3c3605, + 0x20d888, + 0x3a21c7, + 0x204502, + 0x2d4944, + 0x27fa8a, + 0x3cf5c8, + 0x3c3186, + 0x2a6108, + 0x2ab406, + 0x340f48, + 0x2bbb88, + 0x233484, + 0x2c9c05, + 0x70e7c4, + 0x70e7c4, + 0x70e7c4, + 0x201f03, + 0x204346, + 0x286546, + 0x2aa3cc, + 0x20cf43, + 0x270b06, + 0x201fc4, + 0x2e38c8, + 0x2b2605, + 0x27fb86, + 0x2d1208, + 0x2e6386, + 0x3c2706, + 0x29e748, + 0x2e7047, + 0x230f49, + 0x2f04ca, + 0x274544, + 0x246005, + 0x30a405, + 0x2e3646, + 0x23e906, + 0x2aa146, + 0x382006, + 0x231084, + 0x23108b, + 0x239644, + 0x201c05, + 0x2bab85, + 0x2605c6, + 0x20ec48, + 0x28fd47, + 0x331ac4, + 0x211583, + 0x272905, + 0x37f3c7, + 0x28fc4b, + 0x347087, + 0x2d1108, + 0x2c9d47, + 0x276a06, + 0x271fc8, + 0x2cf3cb, + 0x2cba46, + 0x212949, + 0x2cf545, + 0x322d43, + 0x2e0046, + 0x237ac8, + 0x215ec3, + 0x29acc3, + 0x28d906, + 0x2ab406, + 0x37604a, + 0x28a2c5, + 0x28a84b, + 0x2ab24b, + 0x217e03, + 0x209b03, + 0x2c3044, + 0x2e4887, + 0x237b44, + 0x29b2c4, + 0x2c9e84, + 0x38cb08, + 0x371488, + 0x211b89, + 0x2e3488, + 0x3a0087, + 0x224006, + 0x2ea54f, + 0x2dbe46, + 0x2e4dc4, + 0x3712ca, + 0x37f2c7, + 0x2c6b86, + 0x29b109, + 0x211b05, + 0x3472c5, + 0x211c46, + 0x235903, + 0x272e49, + 0x21d106, + 0x3a93c9, + 0x3947c6, + 0x2759c5, + 0x20b085, + 0x202643, + 0x2e49c8, + 0x332207, + 0x2f6084, + 0x2e3748, + 0x29d844, + 0x31ff46, + 0x2b49c6, + 0x247dc6, + 0x2e6d09, + 0x219805, + 0x2a80c6, + 0x25c0c9, + 0x2db246, + 0x2ea646, + 0x3abbc6, + 0x209085, + 0x3ae986, + 0x36c9c4, + 0x3c1585, + 0x2d5304, + 0x2c8f46, + 0x354704, + 0x201c03, + 0x292585, + 0x23d308, + 0x35a407, + 0x2fb609, + 0x292808, + 0x2a5891, + 0x2cb64a, + 0x3036c7, + 0x237d06, + 0x201fc4, + 0x2d5408, + 0x293688, + 0x2a5a4a, + 0x2d6e4d, + 0x216b86, + 0x29e846, + 0x326746, + 0x2ac3c7, + 0x2c7185, + 0x30d607, + 0x201e85, + 0x398404, + 0x3c2d46, + 0x2884c7, + 0x272b4d, + 0x2adf07, + 0x2bfb48, + 0x286389, + 0x27bac6, + 0x2f3fc5, + 0x2e9284, + 0x3a90c6, + 0x353a46, + 0x3cf746, + 0x2a6988, + 0x22d503, + 0x21b783, + 0x32c105, + 0x322606, + 0x2bbb45, + 0x249b48, + 0x2a9bca, + 0x239084, + 0x2e38c8, + 0x2a3448, + 0x3a9947, + 0x37b249, + 0x2d0e08, + 0x294007, + 0x2d3fc6, + 0x20d98a, + 0x3a9148, + 0x31dac9, + 0x2afb48, + 0x222849, + 0x35d787, + 0x208f45, + 0x2ab806, + 0x2c0f08, + 0x281fc8, + 0x261d08, + 0x342688, + 0x201c05, + 0x200d04, + 0x23bec8, + 0x24a604, + 0x3e3004, + 0x2759c5, + 0x29d187, + 0x3e4109, + 0x22df87, + 0x226b05, + 0x282e86, + 0x370d46, + 0x20ed44, + 0x2af4c6, + 0x28ac84, + 0x3d4886, + 0x3e3ec6, + 0x215d06, + 0x3de685, + 0x249a07, + 0x20ac43, + 0x22bf49, + 0x31ed88, + 0x293e84, + 0x293e8d, + 0x2a4d08, + 0x3082c8, + 0x31da46, + 0x2e2e89, + 0x2dff89, + 0x353485, + 0x2a9cca, + 0x27cb0a, + 0x291a4c, + 0x291bc6, + 0x284786, + 0x2dc446, + 0x3a6ac9, + 0x353fc6, + 0x2ae906, + 0x30dc46, + 0x221408, + 0x306e06, + 0x2e43cb, + 0x29d305, + 0x249c05, + 0x285285, + 0x30ef06, + 0x20d943, + 0x247d46, + 0x2ade87, + 0x2d52c5, + 0x2f4ec5, + 0x2c4945, + 0x2f9646, + 0x336cc4, + 0x336cc6, + 0x2a3d09, + 0x30ed8c, + 0x398148, + 0x25cf04, + 0x39d6c6, + 0x244306, + 0x237ac8, + 0x21b6c8, + 0x30ec89, + 0x201b87, + 0x2fbc09, + 0x27d9c6, + 0x216b04, + 0x210484, + 0x28df04, + 0x28d908, + 0x3e3f4a, + 0x33ac06, + 0x368807, + 0x396387, + 0x244f85, + 0x2b9304, + 0x299d86, + 0x2c71c6, + 0x205483, + 0x31ebc7, + 0x22a948, + 0x3535ca, + 0x202148, + 0x273148, + 0x354745, + 0x237105, + 0x2fbb45, + 0x245346, + 0x246e46, + 0x316a45, + 0x331949, + 0x2b910c, + 0x34ca47, + 0x2a5ac8, + 0x282185, + 0x70e7c4, + 0x236b04, + 0x2cc644, + 0x3d0ac6, + 0x2ad28e, + 0x347347, + 0x2ac5c5, + 0x30c48c, + 0x29d707, + 0x288447, + 0x2c8989, + 0x21ae49, + 0x292905, + 0x31ed88, + 0x369ac9, + 0x3c59c5, + 0x2d5208, + 0x2c1f86, + 0x2411c6, + 0x24fb84, + 0x2aa648, 0x206743, - 0x2bff44, - 0x2e0e07, - 0x27d904, - 0x25ef44, - 0x2c2bc4, - 0x2a7dc8, - 0x375b88, - 0x20c409, - 0x2d98c8, - 0x37d3c7, - 0x24bc06, - 0x2ebacf, - 0x2d7146, - 0x2e15c4, - 0x3759ca, - 0x33fcc7, - 0x2c3406, - 0x297bc9, - 0x20c385, - 0x25b7c5, - 0x20c4c6, - 0x22bd83, - 0x2b3a89, - 0x223886, - 0x26b189, - 0x396e86, - 0x26ff45, - 0x361bc5, - 0x206643, - 0x3131c8, - 0x330d07, - 0x355604, - 0x288d08, - 0x2e11c4, - 0x31c046, - 0x2b6486, - 0x23d846, - 0x2dc149, - 0x302545, - 0x29ffc6, - 0x277389, - 0x2d6146, - 0x2a7e46, - 0x3a8b46, - 0x22e405, - 0x30cc46, - 0x3b3a04, - 0x358d45, - 0x21c484, - 0x2c45c6, - 0x273404, - 0x207a43, - 0x28e3c5, - 0x234f88, - 0x366a47, - 0x30a689, - 0x28e648, - 0x2a0951, - 0x2eedca, - 0x2ff207, - 0x3d8686, - 0x207844, + 0x203f44, + 0x272985, + 0x39b187, + 0x26a445, + 0x28f4c9, + 0x29b80d, + 0x2b2ec6, + 0x2115c4, + 0x288608, + 0x22384a, + 0x3e9847, + 0x2b0c45, + 0x203f83, + 0x2ab40e, + 0x2e4acc, + 0x33b107, + 0x2ad447, + 0x4d39a7c7, + 0x143386, + 0x27804, + 0x212fc3, + 0x354005, + 0x2cc645, + 0x2a64c8, + 0x2a3289, + 0x25ce06, + 0x237b44, + 0x303606, + 0x245d0b, + 0x2da2cc, + 0x257b47, + 0x2e4685, + 0x3d4088, + 0x2f0745, + 0x3712c7, + 0x2e2c47, + 0x2494c5, + 0x20d943, + 0x2abd84, + 0x288cc5, + 0x36a505, + 0x36a506, + 0x2a0088, + 0x2884c7, + 0x3d2086, + 0x3cfb06, + 0x379146, + 0x3dcac9, + 0x3cda87, + 0x25cc86, + 0x2da446, + 0x387046, + 0x2b7d05, + 0x218586, + 0x3b5545, + 0x3a8a48, + 0x29cdcb, + 0x2998c6, + 0x3963c4, + 0x222e09, + 0x221244, + 0x2c1f08, + 0x311007, + 0x290f04, 0x2d02c8, - 0x2e2e88, - 0x2a0b0a, - 0x2d1acd, - 0x2a9606, - 0x203e46, - 0x26a586, - 0x21a247, - 0x2c3c05, - 0x35c6c7, - 0x207705, - 0x39e404, - 0x206686, - 0x30ec47, - 0x2b378d, - 0x2a9987, - 0x344fc8, - 0x282949, - 0x22d8c6, - 0x360dc5, - 0x2393c4, - 0x26ae86, - 0x21f646, - 0x23af06, - 0x2a20c8, - 0x22cdc3, - 0x23e443, - 0x34bcc5, - 0x2d2a86, - 0x2b8c85, - 0x297908, - 0x2a55ca, - 0x33f504, - 0x288e88, - 0x299fc8, - 0x25ef47, - 0x28ed49, - 0x2cc488, - 0x287e47, - 0x2c2e46, - 0x20588a, - 0x26af08, - 0x32df09, - 0x2ae088, - 0x224a09, - 0x3d8547, - 0x35ce45, - 0x2a73c6, - 0x31de48, - 0x2530c8, - 0x2bbfc8, - 0x21e608, - 0x23f185, - 0x200d04, - 0x233908, - 0x241984, - 0x3da044, - 0x26ff45, - 0x2997c7, - 0x25eb49, - 0x27e987, - 0x2260c5, - 0x27d706, - 0x375446, - 0x209744, - 0x2ab3c6, - 0x2855c4, - 0x293ec6, - 0x25e906, - 0x215046, - 0x3d5c05, - 0x2977c7, - 0x203843, - 0x22b509, - 0x31cb48, - 0x287cc4, - 0x287ccd, - 0x29fd48, - 0x2fcd48, - 0x32de86, - 0x28a249, - 0x2d6449, - 0x3a1605, - 0x2a56ca, - 0x2a844a, - 0x2b5c8c, - 0x2b5e06, - 0x280986, - 0x2d79c6, - 0x393189, - 0x2f4246, - 0x223b06, - 0x348f86, - 0x367848, - 0x37e646, - 0x2e094b, - 0x299945, - 0x21a245, - 0x281485, - 0x3b5146, - 0x205843, - 0x23d7c6, - 0x2a9907, - 0x2d0185, - 0x27fbc5, - 0x2c12c5, - 0x301c46, - 0x336144, - 0x336146, - 0x2a9e49, - 0x3b4fcc, - 0x39e148, - 0x2520c4, - 0x30c946, - 0x2917c6, - 0x2d9d08, - 0x2c2f48, - 0x3b4ec9, - 0x357147, - 0x237809, - 0x278286, - 0x22c544, - 0x20af04, - 0x286dc4, - 0x289188, - 0x25e98a, - 0x33a006, - 0x36eb07, - 0x398407, - 0x23f105, - 0x2b7604, - 0x2958c6, - 0x2c3c46, - 0x21b2c3, - 0x31c987, - 0x2205c8, - 0x3a174a, - 0x22e4c8, - 0x34df48, - 0x273445, - 0x2a6205, - 0x237745, - 0x23f4c6, - 0x242546, - 0x25d405, - 0x330449, - 0x2b740c, - 0x307d87, - 0x2a0b88, - 0x251045, - 0x602284, - 0x267c84, - 0x2d9184, - 0x212d06, - 0x2a8d0e, - 0x25b847, - 0x21a445, - 0x3c270c, - 0x3d2347, - 0x30ebc7, - 0x30f7c9, - 0x221a89, - 0x28e745, - 0x31cb48, - 0x32e249, - 0x3bb3c5, + 0x2d6984, + 0x2b7d44, + 0x293dc5, + 0x342586, + 0x38ca47, + 0x235f03, + 0x2a7f05, + 0x34bb44, + 0x3c3646, + 0x353508, + 0x32c785, + 0x29ca89, + 0x207985, + 0x3ca8c8, + 0x326c47, + 0x331c48, + 0x2cff07, + 0x395809, + 0x291186, + 0x397c06, + 0x29fa84, + 0x223f45, + 0x3151cc, + 0x285287, + 0x285a87, + 0x23e548, + 0x2b2ec6, + 0x2addc4, + 0x37ddc4, + 0x28da89, + 0x2dc546, + 0x293547, + 0x27b884, + 0x2af5c6, + 0x3de9c5, + 0x2e2ac7, + 0x2e4346, + 0x26ae49, + 0x2d2747, + 0x2a1447, + 0x2af046, + 0x291785, + 0x28c108, + 0x21cf88, + 0x36db46, + 0x32c7c5, + 0x2d8fc6, + 0x20d083, + 0x2a6349, + 0x2a9ece, + 0x2cfc48, + 0x29d948, + 0x36d94b, + 0x29ccc6, + 0x396284, + 0x28fa84, + 0x2a9fca, + 0x21a2c7, + 0x25cd45, + 0x212949, + 0x2d3f05, + 0x3e3047, + 0x29e6c4, + 0x206647, + 0x216a08, + 0x2c96c6, + 0x2cca89, + 0x2d0f0a, + 0x21a246, + 0x2a4846, + 0x2bab05, + 0x39c545, + 0x3b0e47, + 0x24f388, + 0x3de908, + 0x233486, + 0x20b105, + 0x23e68e, + 0x2d15c4, + 0x2a6445, + 0x282809, + 0x2f8a08, + 0x298006, + 0x2a82cc, + 0x2a97d0, + 0x2acecf, + 0x2ae648, + 0x34ff07, + 0x3de685, + 0x245745, + 0x38c8c9, + 0x29e149, + 0x283546, + 0x30c347, + 0x39d7c5, + 0x23ae89, + 0x35dfc6, + 0x353e0d, + 0x28ddc9, + 0x29b2c4, + 0x2cf6c8, + 0x23bf89, + 0x33adc6, + 0x284d85, + 0x397c06, + 0x27ae09, + 0x27b708, + 0x20f1c5, + 0x28f704, + 0x2a848b, + 0x33ac85, + 0x246586, + 0x2901c6, + 0x259446, + 0x3d0e8b, + 0x29cb89, + 0x225005, + 0x396f87, + 0x2cb5c6, + 0x25e646, + 0x28f388, + 0x2d40c9, + 0x2bf90c, + 0x37f1c8, + 0x31d186, + 0x3356c3, + 0x38adc6, + 0x302505, + 0x28b388, + 0x20ab06, + 0x3c8888, + 0x3b0905, + 0x267305, + 0x326d88, + 0x3b6ec7, + 0x3d1cc7, + 0x2f3b87, + 0x32f908, + 0x350048, + 0x2f1086, + 0x2c8d87, + 0x21ea07, + 0x39558a, + 0x210843, + 0x30ef06, + 0x23e605, + 0x27fa84, + 0x286389, + 0x395784, + 0x2c96c4, + 0x2a9444, + 0x2ad44b, + 0x332147, + 0x23e8c5, + 0x2a1b88, + 0x282e86, + 0x282e88, + 0x28a206, + 0x298945, + 0x298b85, + 0x29a546, + 0x30e148, + 0x29b048, + 0x286546, + 0x2a19cf, + 0x2a5e10, + 0x20d485, + 0x20ac43, + 0x237405, + 0x31d348, + 0x29e049, + 0x3c5b08, + 0x30c148, + 0x25ae48, + 0x332207, + 0x282b49, + 0x3c8a88, + 0x2b3944, + 0x2a92c8, + 0x347889, + 0x2c9307, + 0x2bc7c4, + 0x22e048, + 0x2497ca, + 0x2ee946, + 0x216b86, + 0x223549, + 0x2a9a07, + 0x2e0b08, + 0x244808, + 0x3d01c8, + 0x2796c5, + 0x386605, + 0x249c05, + 0x2cc605, + 0x2c6347, + 0x20d945, + 0x2d52c5, + 0x386b86, + 0x3c5a47, + 0x3afd07, + 0x249ac6, + 0x2e5c45, + 0x246586, + 0x205405, + 0x2c1d88, + 0x2f9e44, + 0x2db2c6, + 0x351e44, 0x2d00c8, - 0x2c1006, - 0x377506, - 0x2463c4, - 0x294908, - 0x204883, - 0x20ccc4, - 0x2b35c5, - 0x39db87, - 0x2e5e45, - 0x2895c9, - 0x29664d, - 0x2af506, - 0x213c44, - 0x36ee08, - 0x2b25ca, - 0x2144c7, - 0x34bb05, - 0x20cd03, - 0x2a6fce, - 0x3132cc, - 0x30ce47, - 0x2a8ec7, - 0x4539cd47, - 0xb20c6, - 0x27c44, - 0x215d03, - 0x2f4285, - 0x2d9185, - 0x2a1c08, - 0x29edc9, - 0x251fc6, - 0x27d904, - 0x2ff146, - 0x2398cb, - 0x2eab4c, - 0x24dcc7, - 0x2e0c05, - 0x3b1a88, - 0x2efc85, - 0x3759c7, - 0x307b87, - 0x2475c5, - 0x205843, - 0x21fac4, - 0x2e6445, - 0x273bc5, - 0x273bc6, - 0x2a2608, - 0x30ec47, - 0x3cd2c6, - 0x3472c6, - 0x37d086, - 0x30f0c9, - 0x27ef47, - 0x251e46, - 0x2eacc6, - 0x3cae06, - 0x2b4385, - 0x20e046, - 0x3b3245, - 0x2bf588, - 0x29940b, - 0x295606, - 0x398444, - 0x305bc9, - 0x2abc04, - 0x2c0f88, - 0x3116c7, - 0x28bac4, - 0x2cb948, - 0x2d1604, - 0x2b43c4, - 0x27a345, - 0x322506, - 0x2a7d07, - 0x249b03, - 0x2a3705, - 0x2ff4c4, - 0x3c7b86, - 0x3a1688, - 0x37e545, - 0x2990c9, - 0x3513c5, - 0x323488, - 0x2bc807, - 0x330748, - 0x2cb587, - 0x2fdb49, - 0x287f86, - 0x372946, - 0x29b284, - 0x309c45, - 0x31520c, - 0x281487, - 0x282047, - 0x23e208, - 0x2af506, - 0x2a9844, - 0x34a144, - 0x38fb49, - 0x2d7ac6, - 0x296b47, - 0x27e7c4, - 0x2ab4c6, - 0x3c1685, - 0x2dea47, - 0x2e08c6, - 0x261609, - 0x39b307, - 0x29d487, - 0x2aaf06, - 0x270205, - 0x286b08, - 0x223708, - 0x371f86, - 0x37e585, - 0x2e93c6, - 0x203803, - 0x2a1a89, - 0x2a58ce, - 0x2cb2c8, - 0x2e12c8, - 0x371d8b, - 0x299306, - 0x398304, - 0x23bac4, - 0x2a59ca, - 0x2134c7, - 0x251f05, - 0x214a09, - 0x2cf305, - 0x3da087, - 0x232144, - 0x204787, - 0x322608, - 0x2d6c46, - 0x2c8389, - 0x2cc58a, - 0x213446, - 0x29f886, - 0x2b7c45, - 0x39f685, - 0x37d947, - 0x246d48, - 0x3c15c8, - 0x30b3c6, - 0x361c45, - 0x23e34e, - 0x2ccc44, - 0x2a1b85, - 0x27d089, - 0x2f7588, - 0x2931c6, - 0x2a3ccc, - 0x2a51d0, - 0x2a894f, - 0x2aa508, - 0x3513c7, - 0x3d5c05, - 0x297f85, - 0x2a7b89, - 0x297f89, - 0x27ddc6, - 0x313087, - 0x309b45, - 0x337c49, - 0x363386, - 0x2f408d, - 0x286c89, - 0x25ef44, - 0x2cb048, - 0x2339c9, - 0x33a1c6, - 0x280f85, - 0x372946, - 0x33ee09, - 0x27e648, - 0x210ec5, - 0x289804, - 0x2a3e8b, - 0x33a085, - 0x242006, - 0x28ac46, - 0x22a986, - 0x25e24b, - 0x2991c9, - 0x347205, - 0x399007, - 0x2eed46, - 0x233086, - 0x289488, - 0x30ed89, - 0x344d8c, - 0x33fbc8, - 0x31e806, - 0x333e83, - 0x360186, - 0x2b58c5, - 0x285cc8, - 0x3e21c6, - 0x2dec88, - 0x24be05, - 0x293f85, - 0x2c0b88, - 0x3d5247, - 0x3ccf07, - 0x26b607, - 0x31fc48, - 0x2d9b88, - 0x2e2d86, - 0x2c4407, - 0x34d947, - 0x2b578a, - 0x238643, - 0x3b5146, - 0x23e2c5, - 0x215cc4, - 0x282949, - 0x2fdac4, - 0x2cbd84, - 0x2a3944, - 0x2a8ecb, - 0x330c47, - 0x23e585, - 0x29dbc8, - 0x27d706, - 0x27d708, - 0x284886, - 0x294845, - 0x294b05, - 0x296086, - 0x2971c8, - 0x297b08, - 0x282b06, - 0x29da0f, - 0x2a1550, - 0x205385, - 0x203843, - 0x22c605, - 0x321108, - 0x297e89, - 0x3bb508, - 0x312e88, - 0x385808, - 0x330d07, - 0x27d3c9, - 0x2dee88, - 0x2a4f84, - 0x2a37c8, - 0x3589c9, - 0x2c4a07, - 0x395d44, - 0x27ea48, - 0x29758a, - 0x2ff746, - 0x2a9606, - 0x226b09, - 0x2a5407, - 0x2dbfc8, - 0x2321c8, - 0x347988, - 0x259805, - 0x21ce85, - 0x21a245, - 0x2d9145, - 0x2c2747, - 0x205845, - 0x2d0185, - 0x203546, - 0x3bb447, - 0x3aaa07, - 0x297886, - 0x2e2445, - 0x242006, - 0x280e45, - 0x2c7d08, - 0x309ac4, - 0x2d61c6, - 0x353544, - 0x2cb748, - 0x32288a, - 0x28328c, - 0x2a6505, - 0x21a306, - 0x344f46, - 0x348d86, - 0x31e884, - 0x3cd585, - 0x284147, - 0x2a5489, - 0x2db647, - 0x602284, - 0x602284, - 0x330ac5, - 0x2dfe04, - 0x2a328a, - 0x27d586, - 0x2c0b04, - 0x3dccc5, - 0x2c1d85, - 0x2c3b44, - 0x28a887, - 0x3cdfc7, - 0x2db208, - 0x2e94c8, - 0x210ec9, - 0x388d08, - 0x29048b, - 0x2a7cc4, - 0x233185, - 0x38ff05, - 0x26b589, - 0x30ed89, - 0x305ac8, - 0x368f48, - 0x2e6bc4, - 0x291805, - 0x204083, - 0x2d9a45, - 0x2a0046, - 0x29ec0c, - 0x21f546, - 0x280e86, - 0x293445, - 0x301cc8, - 0x2eadc6, - 0x3d8806, - 0x2a9606, - 0x22e24c, - 0x38ffc4, - 0x37d1ca, - 0x293388, - 0x29ea47, - 0x2ff3c6, - 0x252087, - 0x2fed45, - 0x2702c6, - 0x363d86, - 0x377987, - 0x2cc284, - 0x20f085, - 0x27d084, - 0x39e487, - 0x27d2c8, - 0x28080a, - 0x288587, - 0x2ac487, - 0x351347, - 0x2efdc9, - 0x29ec0a, - 0x22c503, - 0x366a05, - 0x215083, - 0x2c2c09, - 0x2d9f48, - 0x388ac7, - 0x3bb609, - 0x223806, - 0x358e08, - 0x3c4b45, - 0x37e94a, - 0x2079c9, - 0x29c289, - 0x2d5707, - 0x2e2f89, - 0x214f48, - 0x25f906, - 0x21a4c8, - 0x27ff07, - 0x274147, - 0x2d5ac7, - 0x2dd548, - 0x30c7c6, - 0x297345, - 0x284147, - 0x29f388, - 0x37d004, - 0x306dc4, - 0x298587, - 0x2b9047, - 0x32e0ca, - 0x25f886, - 0x3c82ca, - 0x2cf747, - 0x2cca07, - 0x20f144, - 0x295d04, - 0x2de946, - 0x361444, - 0x36144c, - 0x311605, - 0x21c2c9, - 0x2f0e84, - 0x2c3c05, - 0x2b2548, - 0x297bc5, - 0x396906, - 0x2980c4, - 0x2ab98a, - 0x384806, - 0x24774a, - 0x3da407, - 0x20d645, - 0x22bd85, - 0x23f14a, - 0x247685, - 0x2a7b46, - 0x241984, - 0x2c00c6, - 0x37da05, - 0x3e2286, - 0x33decc, - 0x2e3cca, - 0x2a8544, - 0x24bc06, - 0x2a5407, - 0x2e0844, - 0x367848, - 0x2ecc46, - 0x398289, - 0x2cd009, - 0x2dcb49, - 0x2db946, - 0x280006, - 0x21a607, - 0x330388, - 0x27fe09, - 0x330c47, - 0x29dd46, - 0x3ca007, - 0x26a445, - 0x2ccc44, - 0x21a1c7, - 0x34db05, - 0x28f645, + 0x2db3ca, + 0x286ccc, + 0x2aaa05, + 0x2ac486, + 0x2bfac6, + 0x3b6806, + 0x31d204, + 0x3df285, + 0x289ac7, + 0x2a9a89, + 0x2e03c7, + 0x70e7c4, + 0x70e7c4, + 0x331fc5, + 0x312a84, + 0x2a7a8a, + 0x282d06, + 0x3698c4, + 0x203345, + 0x2c5405, + 0x2c70c4, + 0x28fe07, + 0x207907, + 0x2dfe08, + 0x2d90c8, + 0x20f1c9, + 0x29ae48, + 0x29494b, + 0x239704, + 0x29eb45, + 0x28c845, + 0x2f3b09, + 0x2d40c9, + 0x222d08, + 0x3d8dc8, + 0x2605c4, + 0x244345, + 0x20dec3, + 0x2e3605, + 0x2a8146, + 0x2a30cc, + 0x21d006, + 0x284c86, + 0x298285, + 0x2f96c8, + 0x2dac86, + 0x237e86, + 0x216b86, + 0x22b48c, + 0x27d4c4, + 0x37928a, + 0x2981c8, + 0x2a2f07, + 0x34ba46, + 0x25cec7, + 0x303205, + 0x291846, + 0x35ecc6, + 0x3728c7, + 0x2d0c04, + 0x20b805, + 0x282804, + 0x398487, + 0x282a48, + 0x28460a, + 0x28ca87, + 0x2b7907, + 0x34fe87, + 0x2f0889, + 0x2a30ca, + 0x208fc3, + 0x35a3c5, + 0x215d43, + 0x2c9ec9, + 0x36cc48, + 0x368947, + 0x3c5c09, + 0x21d086, + 0x3c1648, + 0x2c4685, + 0x32cb8a, + 0x20df09, + 0x27a1c9, + 0x2dab47, + 0x293789, + 0x215c08, + 0x3e3c46, + 0x2ac648, + 0x2f5207, + 0x231187, + 0x2deb07, + 0x2cdf88, + 0x39ab06, + 0x249585, + 0x289ac7, + 0x2a4348, + 0x3790c4, + 0x309684, + 0x29bd07, + 0x2bbf07, + 0x36994a, + 0x3e3bc6, + 0x3ce54a, + 0x2d4887, + 0x2d1387, + 0x20b8c4, + 0x29a1c4, + 0x2e29c6, + 0x2f4644, + 0x2f464c, + 0x310f45, + 0x216849, + 0x3caa44, + 0x2c7185, + 0x2237c8, + 0x27a545, + 0x394246, + 0x29e284, + 0x2a6d0a, + 0x2dddc6, + 0x3501ca, + 0x3e33c7, + 0x2048c5, + 0x235905, + 0x244fca, + 0x281f05, + 0x2ada86, + 0x24a604, + 0x2c31c6, + 0x3b0f05, + 0x20abc6, + 0x32a64c, + 0x22b70a, + 0x27cc04, + 0x224006, + 0x2a9a07, + 0x2e42c4, + 0x221408, + 0x2ed306, + 0x396209, + 0x3dd0c9, + 0x2bb909, + 0x2241c6, + 0x2f5306, + 0x2ac787, + 0x331888, + 0x2f5109, + 0x332147, + 0x2a1d06, + 0x347ac7, + 0x326605, + 0x2d15c4, + 0x2ac347, + 0x21ebc5, + 0x293d05, 0x200cc7, - 0x247488, - 0x3b1a06, - 0x2a01cd, - 0x2a1e0f, - 0x2a6e0d, - 0x226104, - 0x235086, - 0x2e4088, - 0x348f45, - 0x2b5948, - 0x2862ca, - 0x25ef44, - 0x239b06, - 0x211787, - 0x218e87, - 0x2dc549, - 0x21a485, - 0x2c3b44, - 0x2c568a, - 0x2cc049, - 0x2e3087, - 0x30d406, - 0x33a1c6, - 0x291746, - 0x386c06, - 0x2e398f, - 0x2e3f49, - 0x37e646, - 0x38f786, - 0x32fa49, - 0x2c4507, - 0x220d03, - 0x22e3c6, - 0x20c483, - 0x2d22c8, - 0x2b0e07, - 0x2aa709, - 0x2b6308, - 0x3cd048, - 0x367346, - 0x21f489, - 0x307cc5, - 0x2a3504, - 0x35cf07, - 0x393205, - 0x226104, - 0x23e648, - 0x213784, - 0x2c4247, - 0x399c86, - 0x26c5c5, - 0x2ae088, - 0x33a08b, - 0x31d047, - 0x23f3c6, - 0x2d71c4, - 0x3aef86, - 0x26ff45, - 0x34db05, - 0x286889, - 0x28a489, - 0x274184, - 0x2741c5, - 0x24bc45, - 0x37e7c6, - 0x31cc48, - 0x2ce7c6, - 0x22040b, - 0x3d774a, - 0x2cb685, - 0x294b86, - 0x25b285, - 0x3c2205, - 0x256147, - 0x3b53c8, - 0x237804, - 0x385406, - 0x297b86, - 0x215107, - 0x325304, - 0x285346, - 0x229845, - 0x229849, - 0x280204, - 0x2b7789, - 0x282b06, - 0x2d08c8, - 0x24bc45, - 0x398505, - 0x3e2286, - 0x344c89, - 0x221a89, - 0x280f06, - 0x2f7688, - 0x296788, - 0x25b244, - 0x2c6604, - 0x2c6608, - 0x3326c8, - 0x237909, - 0x29ffc6, - 0x2a9606, - 0x33964d, - 0x31a546, - 0x378f09, - 0x201f45, - 0x20c4c6, - 0x347b08, - 0x336085, - 0x34d984, - 0x26ff45, - 0x289fc8, - 0x2a3049, - 0x27d144, - 0x2c8206, - 0x29c4ca, - 0x30cd48, - 0x32e249, - 0x270bca, - 0x3bb586, - 0x2a1fc8, - 0x375785, - 0x293608, - 0x2fedc5, - 0x2236c9, - 0x33bc49, - 0x21fb82, - 0x2caec5, - 0x277f06, - 0x282a47, - 0x215cc5, - 0x33eb86, - 0x319508, - 0x2af506, - 0x2c9889, - 0x282146, - 0x289308, - 0x24ef85, - 0x394886, - 0x3b3b08, - 0x289188, - 0x3d8448, - 0x31b948, - 0x20e044, - 0x21f783, - 0x2c9ac4, - 0x288786, - 0x26a484, - 0x2e1207, - 0x3d8709, - 0x2d6785, - 0x2321c6, - 0x22e3c6, - 0x2a244b, - 0x2c3346, - 0x273686, - 0x2d62c8, - 0x266cc6, - 0x20d443, - 0x20bb03, - 0x2ccc44, - 0x2310c5, - 0x23f747, - 0x27d2c8, - 0x27d2cf, - 0x28404b, - 0x31ca48, - 0x2c8286, - 0x31cd4e, - 0x23f583, - 0x23f6c4, - 0x2c32c5, - 0x2c39c6, - 0x2959cb, - 0x299886, - 0x30c009, - 0x26c5c5, - 0x249a48, - 0x209bc8, - 0x22194c, - 0x2a8f06, - 0x2d9a86, - 0x2e5145, - 0x290108, - 0x283285, - 0x3505c8, - 0x2a404a, - 0x2a7249, - 0x602284, + 0x249388, + 0x3d4006, + 0x2a51cd, + 0x2a66cf, + 0x2ab24d, + 0x223444, + 0x23d406, + 0x2e7b48, + 0x30dc05, + 0x245488, + 0x283bca, + 0x29b2c4, + 0x2c67c6, + 0x215307, + 0x214ac7, + 0x2e7109, + 0x2ac605, + 0x2c70c4, + 0x2c9b4a, + 0x2d09c9, + 0x293887, + 0x2a5486, + 0x33adc6, + 0x244286, + 0x3b2746, + 0x2e69cf, + 0x2e7a09, + 0x306e06, + 0x267246, + 0x20c049, + 0x2c8e87, + 0x201543, + 0x209046, + 0x211c03, + 0x321e48, + 0x26a007, + 0x2ae849, + 0x2b4848, + 0x3d1e08, + 0x2878c6, + 0x225a89, + 0x34c985, + 0x2a7d04, + 0x209007, + 0x3a6b45, + 0x223444, + 0x23e988, + 0x21a584, + 0x2c8bc7, + 0x3aa146, + 0x23fe85, + 0x2afb48, + 0x33ac8b, + 0x31f287, + 0x245246, + 0x2dbec4, + 0x3da006, + 0x2759c5, + 0x21ebc5, + 0x28be89, + 0x28fa09, + 0x2311c4, + 0x231205, + 0x224045, + 0x32ca06, + 0x31ee88, + 0x2d3506, + 0x22a78b, + 0x2be84a, + 0x2d0005, + 0x298c06, + 0x238d85, + 0x386ac5, + 0x2a35c7, + 0x30f188, + 0x29aec4, + 0x34ae06, + 0x29b0c6, + 0x215dc7, + 0x322d04, + 0x28aa06, + 0x3cd645, + 0x3cd649, + 0x2f5504, + 0x30a549, + 0x286546, + 0x2d5a08, + 0x224045, + 0x396485, + 0x20abc6, + 0x2bf809, + 0x21ae49, + 0x284d06, + 0x2f8b08, + 0x29b948, + 0x238d44, + 0x2ca304, + 0x2ca308, + 0x39ff08, + 0x2fbd09, + 0x2a80c6, + 0x216b86, + 0x33a24d, + 0x2b64c6, + 0x360289, + 0x30e485, + 0x211c46, + 0x22e2c8, + 0x336c05, + 0x21ea44, + 0x2759c5, + 0x28f088, + 0x2a7849, + 0x2828c4, + 0x2cc906, + 0x27a40a, + 0x33b008, + 0x369ac9, + 0x27600a, + 0x3c5b86, + 0x2a6888, + 0x371085, + 0x298448, + 0x303285, + 0x21cf49, + 0x33ca09, + 0x234702, + 0x2cf545, + 0x28c906, + 0x286487, + 0x2b0dc5, + 0x34b946, + 0x319908, + 0x2b2ec6, + 0x2c3ac9, + 0x285b86, + 0x28f208, + 0x2b8cc5, + 0x24e406, + 0x36cac8, + 0x28d908, + 0x35d688, + 0x31b648, + 0x218584, + 0x20c8c3, + 0x2c3d04, + 0x28cc86, + 0x326644, + 0x29d887, + 0x237d89, + 0x2db645, + 0x244806, + 0x209046, + 0x29fecb, + 0x2c6ac6, + 0x20c886, + 0x2de708, + 0x361b46, + 0x2046c3, + 0x212403, + 0x2d15c4, + 0x239a05, + 0x3039c7, + 0x282a48, + 0x282a4f, + 0x2899cb, + 0x31ec88, + 0x2cc986, + 0x31ef8e, + 0x20abc3, + 0x303944, + 0x2c6a45, + 0x2c6f46, + 0x299e8b, + 0x29d246, + 0x232009, + 0x23fe85, + 0x251748, + 0x20e288, + 0x21ad0c, + 0x2ad486, + 0x2e3646, + 0x2e1dc5, + 0x2945c8, + 0x286cc5, + 0x329f48, + 0x2a864a, + 0x2ab689, + 0x70e7c4, 0x2000c2, - 0x4b212402, + 0x53216542, 0x200382, - 0x20e704, - 0x20b982, - 0x217544, - 0x203182, - 0x5803, + 0x2b1b84, + 0x201582, + 0x28d4c4, + 0x204cc2, + 0xd903, 0x2003c2, - 0x208502, - 0xae888, - 0x4cc4, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x7542, - 0x4b202, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0x1fcc2, - 0x4642, - 0x72c2, - 0x24ac43, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x217fc3, - 0x23e083, - 0x219ac3, - 0x24cd44, - 0x22ea43, - 0x236704, - 0x233fc3, - 0x2e5904, - 0x266a83, - 0x215f87, - 0x23cb03, - 0x205803, - 0x321388, - 0x23e083, - 0x293b0b, - 0x2ffec3, - 0x243bc6, - 0x22dc42, - 0x2fa00b, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23e083, - 0x221d43, - 0x210cc3, + 0x202b02, + 0x793c8, + 0xe804, + 0x216543, + 0x222bc3, + 0x343b43, + 0x87c2, + 0x54202, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x2a042, + 0x6502, + 0x4a42, + 0x253c43, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x2296c3, + 0x20cb83, + 0x20f7c3, + 0x25dd04, + 0x216543, + 0x23ec84, + 0x222bc3, + 0x2e8fc4, + 0x343b43, + 0x2b1087, + 0x216443, + 0x20d903, + 0x2c2308, + 0x20cb83, + 0x29fc4b, + 0x304443, + 0x24d906, + 0x213402, + 0x2fe64b, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x20cb83, + 0x21b103, + 0x2072c3, 0x2000c2, - 0xae888, - 0x334f05, - 0x34db88, - 0x2f4fc8, - 0x212402, - 0x36a4c5, - 0x3ca147, - 0x2031c2, - 0x243407, + 0x793c8, + 0x235ec5, + 0x21ec48, + 0x3585c8, + 0x216542, + 0x363605, + 0x347c07, + 0x202bc2, + 0x24d147, 0x200382, - 0x253d47, - 0x23a489, - 0x272888, - 0x347809, - 0x210382, - 0x3d5f47, - 0x32ad04, - 0x3ca207, - 0x3d7647, - 0x25a642, - 0x23cb03, - 0x20a942, - 0x203182, + 0x25be87, + 0x34c049, + 0x277f48, + 0x3d0049, + 0x214182, + 0x20e107, + 0x387c84, + 0x347cc7, + 0x2be747, + 0x2687c2, + 0x216443, + 0x203742, + 0x204cc2, 0x2003c2, - 0x205b42, + 0x208402, 0x200902, - 0x208502, - 0x2e1a45, - 0x227885, - 0x12402, - 0x33fc3, - 0x22ea43, - 0x233fc3, - 0x27e883, - 0x266a83, - 0x204903, - 0x217fc3, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0xfe83, + 0x202b02, + 0x2e5245, + 0x227445, + 0x16542, + 0x22bc3, + 0x216543, + 0x222bc3, + 0x22de83, + 0x343b43, + 0x20e443, + 0x2296c3, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x158286, + 0x55fa5a4b, + 0x216443, + 0x2296c3, + 0x7ca83, + 0x20cb83, + 0x175285, + 0x12b83, 0x101, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x2191c3, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0x217c83, - 0x4e4b1706, - 0x22383, - 0xd7405, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x212402, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0x5242, - 0xae888, - 0x12f603, - 0x5803, - 0x1c0443, - 0x46d04, - 0x147b604, - 0xf0085, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x243543, + 0x2296c3, + 0x7ca83, + 0x20cb83, + 0x2203c3, + 0x56869306, + 0x20a83, + 0x70945, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x216542, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x7ca83, + 0x20cb83, + 0x6482, + 0x793c8, + 0x38c43, + 0xd903, + 0x7ca83, + 0x4f344, + 0x1480c44, + 0xf0b45, 0x2000c2, - 0x3993c4, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x247e03, - 0x22f845, - 0x2191c3, - 0x21e1c3, - 0x217fc3, - 0x24dfc3, - 0x23e083, - 0x208503, - 0x24cdc3, - 0x20aa43, + 0x397344, + 0x216543, + 0x222bc3, + 0x343b43, + 0x24cc43, + 0x2b96c5, + 0x243543, + 0x21b283, + 0x2296c3, + 0x257743, + 0x20cb83, + 0x202b03, + 0x2192c3, + 0x201643, + 0x11d783, 0x5c2, - 0x30242, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, + 0x386c2, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, 0x2000c2, - 0x24ac43, - 0x212402, - 0xf982, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x217fc3, - 0x23e083, - 0x208502, - 0xae888, - 0x266a83, - 0x1c0443, - 0xae888, - 0x1c0443, - 0x276243, - 0x22ea43, - 0x2319c4, - 0x233fc3, - 0x266a83, - 0x209582, - 0x23cb03, - 0x217fc3, - 0x5803, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x209582, - 0x215f83, - 0x217fc3, - 0x23e083, - 0x2f8e43, - 0x208503, + 0x253c43, + 0x216542, + 0x3242, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x2296c3, + 0x20cb83, + 0x202b02, + 0x793c8, + 0x343b43, + 0x7ca83, + 0x793c8, + 0x7ca83, + 0x2cc803, + 0x216543, + 0x23a304, + 0x222bc3, + 0x343b43, + 0x2042c2, + 0x216443, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2042c2, + 0x233243, + 0x2296c3, + 0x20cb83, + 0x2faf43, + 0x202b03, 0x2000c2, - 0x212402, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x243bc5, - 0x1375c6, - 0x24cd44, - 0x22dc42, + 0x216542, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x24d905, + 0x1143c6, + 0x6ff44, + 0x329c4, + 0x25dd04, + 0x213402, 0x882, - 0xae888, - 0xf982, - 0x4b202, - 0x2a82, + 0x793c8, + 0x3242, + 0x54202, + 0x2a02, 0x2000c2, - 0x146bc5, - 0x1ae08, - 0x125203, - 0x212402, - 0x3c904, - 0x52d16f86, - 0x1384, - 0xc634b, - 0x3a806, - 0x7f3c7, - 0x1431c9, - 0x233fc3, - 0x49e88, - 0x49e8b, - 0x4a30b, - 0x4a9cb, - 0x4ad0b, - 0x4afcb, - 0x4b40b, - 0x1cb86, - 0x266a83, - 0xf48c5, - 0x2044, - 0x20ef43, - 0x11b787, - 0xe88c4, - 0x722c4, - 0x217fc3, - 0x81006, - 0x1583c4, - 0x1c0443, - 0x23e083, - 0x300ac4, - 0x131247, - 0x1371c9, - 0xc6108, - 0x1a2584, - 0x1ca344, - 0x134c46, - 0xff48, - 0x1480c5, - 0x124e89, - 0xe783, - 0x146bc5, - 0x212402, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x205803, - 0x23e083, - 0x2ffec3, - 0x22dc42, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e703, - 0x21e484, - 0x217fc3, - 0x5803, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x2e5904, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x243bc6, - 0x233fc3, - 0x266a83, - 0xf443, - 0x1c0443, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x146bc5, - 0x7f3c7, - 0x15c3, - 0xe783, - 0xae888, - 0x266a83, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x612c3, - 0x217fc3, - 0x23e083, - 0x5622ea43, - 0x233fc3, - 0x217fc3, - 0x23e083, - 0xae888, + 0x146c05, + 0x24948, + 0xe9883, + 0x216542, + 0x45c44, + 0x5b910646, + 0x1db84, + 0xc5e4b, + 0x42746, + 0x1cdf07, + 0x174bc9, + 0x222bc3, + 0x53188, + 0x5318b, + 0x5360b, + 0x539cb, + 0x53d0b, + 0x53fcb, + 0x5440b, + 0x18c86, + 0x343b43, + 0x154645, + 0x10e584, + 0x20b6c3, + 0x11b487, + 0x133604, + 0xed184, + 0x77984, + 0x2296c3, + 0x84e06, + 0xac8c4, + 0x7ca83, + 0x20cb83, + 0x305504, + 0x132747, + 0x113fc9, + 0xc5c08, + 0x1c8dc4, + 0x147e04, + 0x179dc3, + 0x13906, + 0x12248, + 0x18d445, + 0x1a1f49, + 0x39fc3, + 0x13ea86, + 0x146c05, + 0x216542, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x20d903, + 0x20cb83, + 0x304443, + 0x213402, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x26a7c3, + 0x21b544, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x2e8fc4, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x24d906, + 0x222bc3, + 0x343b43, + 0x1e803, + 0x7ca83, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x146c05, + 0x1cdf07, + 0x69c3, + 0x39fc3, + 0x793c8, + 0x343b43, + 0x216543, + 0x222bc3, + 0x343b43, + 0x722c3, + 0x2296c3, + 0x20cb83, + 0x5ee16543, + 0x222bc3, + 0x2296c3, + 0x20cb83, + 0x793c8, 0x2000c2, - 0x212402, - 0x22ea43, - 0x266a83, - 0x217fc3, + 0x216542, + 0x216543, + 0x343b43, + 0x2296c3, 0x2003c2, - 0x23e083, - 0x33c187, - 0x355d4b, - 0x211843, - 0x27da88, - 0x330107, - 0x229dc6, - 0x2d42c5, - 0x36a609, + 0x20cb83, + 0x33cf47, + 0x2f67cb, + 0x2153c3, + 0x283208, + 0x331607, + 0x349506, + 0x234d45, + 0x363749, + 0x24d688, + 0x37e649, + 0x3ae5d0, + 0x37e64b, + 0x3aaa09, + 0x2069c3, + 0x2fed09, + 0x23b286, + 0x23b28c, + 0x235f88, + 0x3e5c48, + 0x35c449, + 0x2cd20e, + 0x34be0b, + 0x2c340c, + 0x203b43, + 0x279d4c, + 0x203b49, + 0x300187, + 0x23c4cc, + 0x2c024a, + 0x21d684, + 0x21d68d, + 0x279c08, + 0x20f7cd, + 0x28a5c6, + 0x25dd0b, + 0x314149, + 0x2674c7, + 0x32cdc6, + 0x3339c9, + 0x35310a, + 0x30a088, + 0x304044, + 0x2bc2c7, + 0x24ea07, + 0x202744, + 0x2208c4, + 0x209cc9, + 0x30d489, + 0x20a888, + 0x2303c5, + 0x2140c5, + 0x20f086, + 0x21d549, + 0x283e4d, + 0x216d88, + 0x20ef87, + 0x234dc8, + 0x25b186, + 0x3e11c4, + 0x26b385, + 0x3e2f06, + 0x3e7984, + 0x203a47, + 0x20588a, + 0x216784, + 0x21a186, + 0x21a989, + 0x21a98f, + 0x21cc4d, + 0x21e706, + 0x224550, + 0x224946, + 0x226187, + 0x227f07, + 0x227f0f, + 0x229309, + 0x22cc86, + 0x22e907, + 0x22e908, + 0x22ed09, + 0x206e88, + 0x317a87, + 0x20c903, + 0x391906, + 0x37a588, + 0x2cd4ca, + 0x204189, + 0x22cb43, + 0x363506, + 0x34ac4a, + 0x282647, + 0x2fffca, + 0x31034e, + 0x229446, + 0x3d6847, + 0x24b006, + 0x203c06, + 0x38640b, + 0x218d8a, + 0x2f6e0d, + 0x2f53c7, + 0x274588, + 0x274589, + 0x27458f, + 0x2fb78c, + 0x2fb0c9, + 0x287bce, + 0x2b118a, + 0x20c606, + 0x2e9106, + 0x30cd4c, + 0x3bb08c, + 0x3d8388, + 0x338487, + 0x208c45, + 0x347e84, + 0x36430e, + 0x3109c4, + 0x3406c7, + 0x36be4a, + 0x3806d4, + 0x38a70f, + 0x2280c8, + 0x3917c8, + 0x38c34d, + 0x38c34e, + 0x3b4bc9, + 0x238308, + 0x23830f, + 0x23c1cc, + 0x23c1cf, + 0x23d147, + 0x23f90a, + 0x240acb, + 0x241348, + 0x244547, + 0x24be0d, + 0x362546, + 0x21d846, + 0x247bc9, + 0x26bac8, + 0x24db08, + 0x24db0e, + 0x26b907, + 0x308585, + 0x24f085, + 0x220744, + 0x3497c6, + 0x20a788, + 0x3a2983, + 0x2bf30e, + 0x24c1c8, + 0x3e534b, + 0x3c7807, + 0x2332c5, + 0x279ec6, + 0x2ba1c7, + 0x33e8c8, + 0x32c449, + 0x23cb05, + 0x2925c8, + 0x22fe06, + 0x3b3cca, + 0x364209, + 0x23c589, + 0x23c58b, + 0x33b7c8, + 0x202609, + 0x230486, + 0x3c298a, + 0x2a104a, + 0x23fb0c, + 0x371707, + 0x277d4a, + 0x39f78b, + 0x39f799, + 0x351a48, + 0x24d985, + 0x24bfc6, + 0x296489, + 0x250206, + 0x22b24a, + 0x2163c6, + 0x232d44, + 0x2dce0d, + 0x32d187, + 0x232d49, + 0x252185, + 0x2522c8, + 0x252f49, + 0x254744, + 0x254e07, + 0x254e08, + 0x255287, + 0x273b48, + 0x25cac7, + 0x2dfac5, + 0x26420c, + 0x2646c9, + 0x3b930a, + 0x266cc9, + 0x2fee09, + 0x26700c, + 0x26974b, + 0x26ac88, + 0x26bcc8, + 0x26f504, + 0x290988, + 0x291d49, + 0x2c0307, + 0x21abc6, + 0x2a9607, + 0x3d4bc9, + 0x21070b, + 0x247047, + 0x21fc47, + 0x3e3507, + 0x20f744, + 0x20f745, + 0x2e8cc5, + 0x357f0b, + 0x30df44, + 0x3b6648, + 0x25974a, + 0x22fec7, + 0x3e5007, + 0x299452, + 0x3d4786, + 0x239c86, + 0x340ace, + 0x3e5786, + 0x29ddc8, + 0x29f2cf, + 0x20fb88, 0x243948, - 0x381049, - 0x3ac290, - 0x38104b, - 0x215589, - 0x2015c3, - 0x2fa6c9, - 0x232646, - 0x23264c, - 0x334fc8, - 0x3dde48, - 0x26eac9, - 0x2c8b0e, - 0x23a24b, - 0x2c030c, - 0x233f03, - 0x284e8c, - 0x3e13c9, - 0x238447, - 0x233f0c, - 0x2bde8a, - 0x241ec4, - 0x38aa8d, - 0x284d48, - 0x219acd, - 0x292146, - 0x24cd4b, - 0x337349, - 0x38fa07, - 0x25f0c6, - 0x323849, - 0x35484a, - 0x30e748, - 0x2ffac4, - 0x3a8e87, - 0x3c0807, - 0x208184, - 0x2221c4, - 0x3b4809, - 0x35c549, - 0x3e1f48, - 0x2f2c85, - 0x2102c5, - 0x209a86, - 0x38a949, - 0x28654d, - 0x2ece48, - 0x209987, - 0x2d4348, - 0x26bdc6, - 0x22fa44, - 0x2a4d45, - 0x3d9f46, - 0x3dc104, - 0x3e12c7, - 0x204e8a, - 0x210e04, - 0x213386, - 0x214689, - 0x21468f, - 0x214c4d, - 0x215ac6, - 0x21aa10, - 0x21ae06, - 0x21b507, - 0x21bcc7, - 0x21bccf, - 0x21c689, - 0x224c46, - 0x225047, - 0x225048, - 0x225449, - 0x20f708, - 0x306a07, - 0x22b743, - 0x22e8c6, - 0x239148, - 0x2c8dca, - 0x20cf09, - 0x243a83, - 0x36a3c6, - 0x38524a, - 0x2fbb87, - 0x23828a, - 0x316c8e, - 0x21c7c6, - 0x32bc47, - 0x38ef46, - 0x243fc6, - 0x21cc8b, - 0x3a038a, - 0x35638d, - 0x2800c7, - 0x26dc08, - 0x26dc09, - 0x26dc0f, - 0x30a80c, - 0x265209, - 0x2bbbce, - 0x21608a, - 0x20dac6, - 0x3076c6, - 0x31a1cc, - 0x3df50c, - 0x325908, - 0x35fd07, - 0x39d4c5, - 0x3ca3c4, - 0x25fd0e, - 0x3ae384, - 0x37dd87, - 0x3a6d8a, - 0x3d7cd4, - 0x3db78f, - 0x21be88, - 0x22e788, - 0x39124d, - 0x39124e, - 0x22ed49, - 0x22fe88, - 0x22fe8f, - 0x233c0c, - 0x233c0f, - 0x234dc7, - 0x23718a, - 0x23874b, - 0x2395c8, - 0x23b807, - 0x260b4d, - 0x369646, - 0x38ac46, - 0x23d649, - 0x252848, - 0x243dc8, - 0x243dce, - 0x2bb387, - 0x305145, - 0x246ac5, - 0x206484, - 0x22a086, - 0x3e1e48, - 0x324643, - 0x2e8c8e, - 0x260f08, - 0x2acacb, - 0x276407, - 0x30b205, - 0x269c06, - 0x2b6ec7, - 0x321848, - 0x37d749, - 0x3d2cc5, - 0x28e408, - 0x228a46, - 0x3addca, - 0x25fc09, - 0x233fc9, - 0x233fcb, - 0x25c6c8, - 0x208049, - 0x2f2d46, - 0x2041ca, - 0x29d08a, - 0x23738c, - 0x375e07, - 0x27268a, - 0x331b0b, - 0x331b19, - 0x353148, - 0x243c45, - 0x260d06, - 0x211d89, - 0x3b2c46, - 0x22170a, - 0x275246, - 0x2d8384, - 0x2d838d, - 0x3b4447, - 0x368889, - 0x249285, - 0x2493c8, - 0x249c49, - 0x24bb44, - 0x24c247, - 0x24c248, - 0x24c507, - 0x26c188, - 0x251c87, - 0x2daec5, - 0x25828c, - 0x258749, - 0x31d28a, - 0x3b09c9, - 0x2fa7c9, - 0x38f54c, - 0x25accb, - 0x25c8c8, - 0x261448, - 0x264f04, - 0x28b548, - 0x28cb89, - 0x2bdf47, - 0x2148c6, - 0x2a3b07, - 0x2a0f49, - 0x354d4b, - 0x20b187, - 0x348647, - 0x3da547, - 0x219a44, - 0x219a45, - 0x2e5605, - 0x35e84b, - 0x349284, - 0x328308, - 0x30234a, - 0x228b07, - 0x3d0347, - 0x295192, - 0x293dc6, - 0x231346, - 0x34890e, - 0x294586, - 0x299e48, - 0x29aacf, - 0x219e88, - 0x28fb88, - 0x2df5ca, - 0x2df5d1, - 0x2ab64e, - 0x2550ca, - 0x2550cc, - 0x230087, - 0x230090, - 0x3d4f08, - 0x2ab845, - 0x2b71ca, - 0x3dc14c, - 0x29e08d, - 0x204906, - 0x204907, - 0x20490c, - 0x209d8c, - 0x2191cc, - 0x2c204b, - 0x3923c4, - 0x226c84, - 0x2ba749, - 0x34a1c7, - 0x382f89, - 0x29cec9, - 0x2bdb47, - 0x2bdd06, - 0x2bdd09, - 0x2be103, - 0x2af60a, - 0x323a87, - 0x3ca70b, - 0x35620a, - 0x32ad84, - 0x3c88c6, - 0x288809, - 0x3612c4, - 0x2e164a, - 0x2e2845, - 0x2cd7c5, - 0x2cd7cd, - 0x2cdb0e, - 0x2c9c05, - 0x33ae46, - 0x2437c7, - 0x2525ca, - 0x3ae686, - 0x381c04, - 0x35a607, - 0x2fc70b, - 0x26be87, - 0x2699c4, - 0x253306, - 0x25330d, - 0x2e724c, - 0x217e86, - 0x2ed04a, - 0x223486, - 0x220dc8, - 0x274707, - 0x2d5eca, - 0x2361c6, - 0x27ffc3, - 0x2f4b46, - 0x238fc8, - 0x37204a, - 0x2df007, - 0x2df008, + 0x2e75ca, + 0x2e75d1, + 0x2af74e, + 0x20294a, + 0x20294c, + 0x238507, + 0x238510, + 0x3d9e48, + 0x2af945, + 0x2ba4ca, + 0x3e79cc, + 0x2a204d, + 0x20e446, + 0x20e447, + 0x20e44c, + 0x20f3cc, + 0x26a98c, + 0x39304b, + 0x3a4f04, + 0x205604, + 0x2be009, + 0x37de47, + 0x361f89, + 0x2a0e89, + 0x2bff07, + 0x2c00c6, + 0x2c00c9, + 0x2c04c3, + 0x2b2fca, + 0x37a447, + 0x37b94b, + 0x2f6c8a, 0x25bfc4, - 0x295707, - 0x2fdf08, - 0x293fc8, - 0x2c30c8, - 0x33e14a, - 0x2ee705, - 0x2ee987, - 0x254f13, - 0x271146, - 0x20bc08, - 0x222a49, - 0x2432c8, - 0x3673cb, - 0x3cd3c8, - 0x2cab84, - 0x2c0c86, - 0x325e06, - 0x322349, - 0x2d5d07, - 0x258388, - 0x2a5c46, + 0x3ceb46, + 0x28cd09, + 0x2f44c4, + 0x2e4e4a, + 0x302645, + 0x2d1b85, + 0x2d1b8d, + 0x2d1ece, + 0x2722c5, + 0x33bc06, + 0x24d507, + 0x25d40a, + 0x231c86, + 0x37ee04, + 0x301887, + 0x300e4b, + 0x273847, + 0x2420c4, + 0x316546, + 0x31654d, + 0x2eba8c, + 0x3d1a86, + 0x216f8a, + 0x221d46, + 0x227bc8, + 0x2fd2c7, + 0x2dafca, + 0x3e7346, + 0x28aa83, + 0x354806, + 0x213448, + 0x36dc0a, + 0x25aa07, + 0x25aa08, + 0x2985c4, + 0x2a5c47, + 0x31f5c8, + 0x2f3cc8, + 0x2f1188, + 0x32a8ca, + 0x2efe85, + 0x2cb207, + 0x260e13, + 0x276586, + 0x38d188, + 0x22bb49, + 0x24d008, + 0x28794b, + 0x2ca108, + 0x2eb7c4, + 0x326e86, + 0x324186, + 0x3423c9, + 0x2dae07, + 0x264308, + 0x2aa246, 0x200bc4, - 0x3d5d85, - 0x3aa788, - 0x248e8a, - 0x2d8008, - 0x2dcf86, - 0x2a21ca, - 0x273d48, - 0x2e0648, - 0x2e18c8, - 0x2e2106, - 0x2e4286, - 0x3b048c, - 0x2e4810, - 0x2b8a85, - 0x219c88, - 0x21e910, - 0x219c90, - 0x3ac10e, - 0x3b010e, - 0x3b0114, - 0x3b934f, - 0x3b9706, - 0x3b6051, - 0x208253, - 0x2086c8, - 0x25f245, - 0x27dfc8, - 0x3a7c45, - 0x34aacc, - 0x22b989, - 0x3ae1c9, - 0x317147, - 0x237bc9, - 0x3b2807, - 0x33a486, - 0x2a4b47, - 0x202cc5, - 0x20fec3, - 0x20f443, - 0x215bc4, - 0x3dff8d, - 0x20bf4f, + 0x3de805, + 0x33f188, + 0x39000a, + 0x2dca88, + 0x2e1046, + 0x2a6a8a, + 0x36a688, + 0x3bc6c8, + 0x2e50c8, + 0x2e5906, + 0x2e7d46, + 0x3b20cc, + 0x2e8310, + 0x2e8705, + 0x20f988, + 0x288910, + 0x20f990, + 0x3ae44e, + 0x3b1d4e, + 0x3b1d54, + 0x3ba5cf, + 0x3ba986, + 0x202811, + 0x209613, + 0x32cf48, + 0x363c05, + 0x283748, + 0x32d685, + 0x348fcc, + 0x2718c9, + 0x310809, + 0x2fbfc7, + 0x368f49, + 0x3a8747, + 0x313386, + 0x26b187, + 0x2649c5, + 0x212bc3, + 0x21e803, + 0x2433c4, + 0x21574d, + 0x3c3dcf, 0x200c05, - 0x34a9c6, - 0x2200c7, - 0x334d47, - 0x37b8c6, - 0x37b8cb, - 0x2ac3c5, - 0x259986, - 0x30db47, - 0x252b89, - 0x225706, - 0x38c185, - 0x3c324b, - 0x205d06, - 0x226685, - 0x246248, - 0x296448, - 0x2ae3cc, - 0x2ae3d0, - 0x2b4f89, - 0x2c7007, - 0x2be80b, - 0x2ce086, - 0x3068ca, - 0x2a81cb, - 0x38160a, - 0x39f946, - 0x2f8d05, - 0x330006, - 0x28d548, - 0x31720a, - 0x390edc, - 0x2fff8c, - 0x300288, - 0x243bc5, - 0x387ac7, - 0x25d246, - 0x2bcc85, - 0x218386, - 0x37ba88, - 0x2cc2c7, - 0x2c8a08, - 0x27120a, - 0x3c110c, - 0x3248c9, - 0x3c1387, - 0x28d0c4, - 0x246b86, - 0x28f70a, - 0x29cfc5, - 0x221e4c, - 0x222508, - 0x2f6848, - 0x2b1a0c, - 0x31aa0c, - 0x32a8c9, - 0x32ab07, - 0x242dcc, - 0x22ac84, - 0x36fe0a, - 0x31114c, - 0x24e1cb, - 0x24f60b, - 0x2509c6, - 0x2541c7, - 0x2302c7, - 0x2302cf, - 0x312111, - 0x2eb492, - 0x25538d, - 0x25538e, - 0x2556ce, - 0x3b9508, - 0x3b9512, - 0x266448, - 0x223087, - 0x24fa4a, - 0x2af348, - 0x294545, - 0x2c258a, - 0x21b187, - 0x2f1004, - 0x20ee43, - 0x236c45, - 0x2df847, - 0x3aca87, - 0x29e28e, - 0x33dacd, - 0x350d49, - 0x31fb05, - 0x35f4c3, - 0x34ca46, - 0x259ec5, - 0x2acd08, - 0x227349, - 0x260d45, - 0x260d4f, - 0x2c6447, - 0x2154c5, - 0x276dca, - 0x205646, - 0x35d1c9, - 0x386ecc, - 0x3d2dc9, - 0x20b386, - 0x30214c, - 0x333f86, - 0x310088, - 0x331a06, - 0x36c7c6, - 0x2c34c4, - 0x3222c3, - 0x20de0a, - 0x22de51, - 0x26a90a, - 0x25b105, - 0x288207, - 0x255b47, - 0x2e8a84, - 0x2fe00b, - 0x347688, - 0x2cb146, - 0x23e285, - 0x268b84, - 0x24fc89, + 0x348ec6, + 0x22a447, + 0x235d07, + 0x355bc6, + 0x355bcb, + 0x2b0505, + 0x289146, + 0x3baf07, + 0x25e109, + 0x22eb86, + 0x3881c5, + 0x20368b, + 0x20de06, + 0x22f7c5, + 0x24fa08, + 0x2a3b08, + 0x2b3ccc, + 0x2b3cd0, + 0x2b89c9, + 0x2cad07, + 0x34de4b, + 0x2f0c46, + 0x31794a, + 0x38cf0b, + 0x314c4a, + 0x2f9406, + 0x2fae05, + 0x331506, + 0x292a88, + 0x3a5c0a, + 0x38bfdc, + 0x30450c, + 0x304808, + 0x24d905, + 0x38f6c7, + 0x2cce46, + 0x39da45, + 0x2210c6, + 0x355d88, + 0x2d0c47, + 0x2cd108, + 0x27664a, + 0x35b5cc, + 0x3a2c09, + 0x35b847, + 0x243e44, + 0x204a06, + 0x2434ca, + 0x2a0f85, + 0x22054c, + 0x220c08, + 0x236f48, + 0x32794c, + 0x33878c, + 0x35cf89, + 0x361d87, + 0x24808c, + 0x2fce84, + 0x322a4a, + 0x3e23cc, + 0x254fcb, + 0x255c8b, + 0x259186, + 0x25f087, + 0x238747, + 0x23874f, + 0x311a51, + 0x2ee312, + 0x25f3cd, + 0x25f3ce, + 0x25f70e, + 0x3ba788, + 0x3ba792, + 0x2fc688, + 0x2b1987, + 0x259c4a, + 0x2125c8, + 0x3e5745, + 0x2c618a, + 0x224cc7, + 0x2f0d84, + 0x20b5c3, + 0x23f1c5, + 0x2e7847, + 0x306587, + 0x2a224e, + 0x3dc44d, + 0x316209, + 0x207385, + 0x34f9c3, + 0x33e246, + 0x267c45, + 0x3e5588, + 0x22d149, + 0x24c005, + 0x24c00f, + 0x2c5f47, + 0x234bc5, + 0x3c81ca, + 0x20d746, + 0x246809, + 0x3599cc, + 0x37eec9, + 0x2111c6, + 0x25954c, + 0x3357c6, + 0x30fac8, + 0x38c686, + 0x278b86, + 0x2c6c44, + 0x386d83, + 0x3e380a, + 0x209211, + 0x2fb28a, + 0x3e19c5, + 0x263e87, + 0x261707, + 0x2e20c4, + 0x31f6cb, + 0x3cfec8, + 0x2cf7c6, + 0x23e5c5, + 0x257104, + 0x26f9c9, 0x2008c4, - 0x2124c7, - 0x34d185, - 0x34d187, - 0x348b45, - 0x20bb83, - 0x222f48, - 0x27e1ca, - 0x249b03, - 0x334f4a, - 0x2a9d06, - 0x260acf, - 0x2bb309, - 0x2e8c10, - 0x3064c8, - 0x2dd9c9, - 0x29f107, - 0x25328f, - 0x3bb9c4, - 0x2e5984, - 0x21ac86, - 0x2356c6, - 0x23edca, - 0x247cc6, - 0x2b9447, - 0x317c48, - 0x317e47, - 0x3192c7, - 0x31ad0a, - 0x319bcb, - 0x358f85, - 0x2eb0c8, - 0x21a303, - 0x3ccbcc, - 0x39d24f, - 0x3c7e0d, - 0x258b87, - 0x350e89, - 0x2f5c87, - 0x28c3c8, - 0x3d7ecc, - 0x2caa88, - 0x366dc8, - 0x332bce, - 0x345b54, - 0x346064, - 0x365d0a, - 0x38188b, - 0x3b28c4, - 0x3b28c9, - 0x239b88, - 0x247385, - 0x32414a, + 0x218407, + 0x37e8c5, + 0x37e8c7, + 0x340d05, + 0x212483, + 0x2b1848, + 0x2484ca, + 0x235f03, + 0x235f0a, + 0x2ae286, + 0x24bd8f, + 0x26b889, + 0x2bf290, + 0x2e2248, + 0x2e1809, 0x2a5007, - 0x215d84, - 0x24ac43, - 0x22ea43, - 0x236704, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x2191c3, - 0x23cb03, - 0x2e4806, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x216983, + 0x3164cf, + 0x3c5fc4, + 0x2e9044, + 0x2247c6, + 0x25d8c6, + 0x252c0a, + 0x24cb06, + 0x2bcc47, + 0x317dc8, + 0x317fc7, + 0x3196c7, + 0x31aa0a, + 0x319fcb, + 0x271385, + 0x2edf48, + 0x20c183, + 0x3c17cc, + 0x2089cf, + 0x22158d, + 0x35e207, + 0x236c89, + 0x35d247, + 0x2cbd48, + 0x3808cc, + 0x2eb6c8, + 0x3e16c8, + 0x33438e, + 0x345b94, + 0x3460a4, + 0x360d8a, + 0x37ea8b, + 0x3a8804, + 0x3a8809, + 0x2c6848, + 0x24fe05, + 0x3a248a, + 0x2b39c7, + 0x258bc4, + 0x253c43, + 0x216543, + 0x23ec84, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x243543, + 0x216443, + 0x2e8306, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x21f6c3, 0x2000c2, - 0x24ac43, - 0x212402, - 0x22ea43, - 0x236704, - 0x233fc3, - 0x266a83, - 0x2191c3, - 0x2e4806, - 0x217fc3, - 0x23e083, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x280203, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x21e484, - 0x217fc3, - 0x23e083, + 0x253c43, + 0x216542, + 0x216543, + 0x23ec84, + 0x222bc3, + 0x343b43, + 0x243543, + 0x2e8306, + 0x2296c3, + 0x20cb83, + 0x793c8, + 0x216543, + 0x222bc3, + 0x2f5503, + 0x606296c3, + 0x7ca83, + 0x20cb83, + 0x60a01704, + 0xc1442, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x21b544, + 0x2296c3, + 0x20cb83, 0x2000c2, - 0x281bc3, - 0x212402, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0x20cf02, - 0x20cdc2, - 0x212402, - 0x22ea43, - 0x204302, + 0x28bb03, + 0x216542, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x204182, + 0x204042, + 0x216542, + 0x216543, + 0x2080c2, 0x2005c2, - 0x20e704, - 0x217544, - 0x266002, - 0x21e484, + 0x2b1b84, + 0x28d4c4, + 0x233ec2, + 0x21b544, 0x2003c2, - 0x23e083, - 0x216983, - 0x2509c6, - 0x21fcc2, - 0x2072c2, - 0x223d42, - 0x58a13d83, - 0x58e30083, - 0x56486, - 0x56486, - 0x24cd44, - 0x205803, - 0x8acd, - 0x1e1cca, - 0x1cc04c, - 0x173cc, - 0xd720d, - 0x6e784, - 0x8f284, - 0x120384, - 0x146bc5, - 0x8e9c9, - 0xbf04c, - 0x1683c7, - 0x11fc6, - 0x16588, - 0x1a087, - 0x20ac8, - 0x1bdd8a, - 0x1109c7, - 0x59abd285, - 0xbd289, - 0x59c35a0b, - 0x129f08, - 0xcc4b, - 0x141488, - 0x167e89, - 0x8c80a, - 0x1316ce, - 0xbec4a, - 0xa4cd, - 0x2ed4d, - 0x14430cb, - 0xe710a, - 0x1384, - 0x59ac6, - 0xf988, - 0x10f508, - 0x35cc7, - 0x1dbc5, - 0x1fb47, - 0x34449, - 0x161347, - 0xec88, - 0x2afc9, - 0x3ea84, - 0xd3085, - 0x737ce, - 0x1410c7, - 0x5a224d46, - 0x4efcd, - 0x7f248, - 0x5a65ce86, - 0x5b05ce88, - 0x57388, - 0x13c390, - 0x5460c, - 0x68787, - 0x693c7, - 0x707c7, - 0x77c07, - 0x9a42, - 0x16e07, - 0x1a054c, - 0x5d4c5, - 0xb4e07, - 0xae286, - 0xafcc9, - 0xb3108, - 0xb5c2, + 0x20cb83, + 0x21f6c3, + 0x259186, + 0x22a042, + 0x204a42, + 0x208f02, + 0x61e0fb83, + 0x62202943, + 0x62186, + 0x62186, + 0x25dd04, + 0x20d903, + 0x1a16cd, + 0xa60a, + 0x1a02cc, + 0x8d34c, + 0x62c691cf, + 0x7074d, + 0x15c104, + 0x75104, + 0xffd44, + 0x146c05, + 0x95d89, + 0x17488c, + 0x34347, + 0x17f06, + 0x1f2c8, + 0x22a87, + 0x29e88, + 0x1beaca, + 0x1e1c47, + 0x174ac9, + 0x632ea205, + 0xea209, + 0x6343df0b, + 0x123308, + 0x3ecb, + 0x17ce88, + 0x18484a, + 0x132bce, + 0x6397448a, + 0x12808d, + 0x1b4bcd, + 0x144ce0b, + 0xeb94a, + 0x1db84, + 0x53846, + 0x89288, + 0x1dcf08, + 0x3e1c7, + 0x1e485, + 0x63eabe08, + 0x1d74c7, + 0x51b89, + 0xf4547, + 0x1c74c8, + 0x32649, + 0x48404, + 0x48985, + 0xc9ce, + 0x1402c7, + 0x6462cd86, + 0xb8d0d, + 0x1cdd88, + 0xedb48, + 0x64b7cb46, + 0x6557cb48, + 0xb3588, + 0x13d150, + 0x5fc8c, + 0x70607, + 0x71b07, + 0x75c07, + 0x7c947, + 0xc342, + 0x1d8707, + 0x18f4c, + 0x116b05, + 0xb8847, + 0xb3b86, + 0xb4e49, + 0xb7288, + 0x1ec82, 0x5c2, - 0x193c86, - 0x1c2b0b, - 0x1c2e06, - 0x6f044, - 0x1b5ac7, - 0x33449, - 0x860c9, - 0x1bb208, - 0x4b202, - 0x199249, - 0x11a08, - 0xfb54a, - 0xe689, - 0x2a8c6, - 0xdac89, - 0xe7087, - 0xe77c9, - 0xea1c8, - 0xec607, - 0xee689, - 0xf1a45, - 0xf1e10, - 0x1d60c6, - 0x1b5a05, - 0x19dfc7, - 0xbd68d, - 0x41d85, - 0xfa5c6, - 0xfadc7, - 0x100ad8, - 0x7f5c8, - 0x14978a, - 0xd782, - 0x5b7928cb, - 0x4f3ca, - 0x5a04d, - 0x2442, - 0xd4d86, - 0x13a06, - 0xa2ac8, - 0xb2e8a, - 0x3dd48, - 0x74e49, - 0x118088, - 0x6f48e, - 0x75088, - 0x14ca47, - 0x5ba5cdc4, - 0xb170d, - 0x1095c5, - 0x2748, - 0x35288, - 0x1145c6, - 0x4642, - 0xcaf44, - 0xe5006, - 0x134c46, - 0x5bd8490b, - 0x3602, + 0x190a86, + 0x67cb, + 0x6ac6, + 0x15c9c4, + 0x10f887, + 0x5e789, + 0x932c9, + 0x1bc248, + 0x54202, + 0x1971c9, + 0x17988, + 0x104e4a, + 0x65ada54b, + 0x145149, + 0x12506, + 0xdf889, + 0xeb8c7, + 0xec009, + 0xed548, + 0xeeac7, + 0xefe09, + 0xf2185, + 0xf2550, + 0x1e84c6, + 0x10f7c5, + 0x120047, + 0xb6a4d, + 0x4ab45, + 0xfec06, + 0xff487, + 0x105518, + 0xf48c8, + 0x80d4a, + 0x4a02, + 0x663a540b, + 0x666df98a, + 0x55a4a, + 0x6334d, + 0x1702, + 0xd9c46, + 0x30846, + 0xa7248, + 0xb700a, + 0x46c88, + 0x79289, + 0x118d88, + 0x6f68e, + 0x16208, + 0x13e247, + 0x66bb0284, + 0x12764d, + 0x10ba05, + 0x1a2f48, + 0x4fec8, + 0x66eaf2c8, + 0x114786, + 0x6502, + 0xcf5c4, + 0x110b46, + 0x6724b348, + 0x13906, + 0x678ddecb, + 0xe042, + 0xacc09, + 0x12d408, + 0x164647, + 0x35b4a, + 0x40407, 0x401, 0x81, - 0xbe588, - 0x5bb87, - 0x93783, - 0x5aa37e84, - 0x5ae9c0c3, + 0x183c47, + 0x116348, + 0x642c1503, + 0x1616c4, + 0xc1508, + 0xc1708, + 0xc1908, + 0x69c07, + 0x9b583, + 0x64e40644, + 0x652a0803, 0xc1, - 0x25d86, + 0x267c6, 0xc1, 0x201, - 0x25d86, - 0x93783, - 0x18b7c8, - 0x4cdc3, - 0x27c44, - 0x20f47, - 0xaa47, - 0x1571585, - 0x4e584, - 0x149307, - 0x12402, - 0x241ec4, - 0x22ea43, - 0x24d704, - 0x20e704, - 0x217fc3, - 0x222905, - 0x217c83, - 0x235403, - 0x37b845, - 0x20aa43, - 0x1be83, - 0x5ce2ea43, - 0x233fc3, - 0x4d704, - 0x33c3, - 0x266a83, + 0x267c6, + 0x9b583, + 0x65f36fc4, + 0x18b2c4, + 0x1a845, + 0x88e45, + 0x10f9c4, + 0x16684, + 0x54644, + 0x1c4b88, + 0x1866cc, + 0xe01, + 0x192c3, + 0x27804, + 0x1c4b88, + 0x677c4b88, + 0x674c3, + 0x79943, + 0x27d47, + 0x5f07, + 0x156d145, + 0x57e04, + 0x10dfc7, + 0x16542, + 0x88e04, + 0x21d684, + 0x216543, + 0x256d44, + 0x2b1b84, + 0x2296c3, + 0x22ba05, + 0x2203c3, + 0x24c343, + 0x355b45, + 0x201643, + 0x1df83, + 0x68a16543, + 0x222bc3, + 0x56d44, + 0x4f03, + 0x343b43, 0x200181, - 0x1e1c3, - 0x23cb03, - 0x217544, - 0x21e484, - 0x217fc3, - 0x4dfc3, - 0x23e083, - 0x208503, - 0xae888, + 0x1b283, + 0x216443, + 0x28d4c4, + 0x21b544, + 0x2296c3, + 0x57743, + 0x20cb83, + 0x202b03, + 0x793c8, 0x2000c2, - 0x24ac43, - 0x212402, - 0x22ea43, - 0x233fc3, - 0x280203, + 0x253c43, + 0x216542, + 0x216543, + 0x222bc3, + 0x2f5503, 0x2005c2, - 0x20e704, - 0x2191c3, - 0x23cb03, - 0x217fc3, - 0x205803, - 0x23e083, - 0x20aa43, - 0x19d184, - 0xae888, - 0x10a087, - 0x12402, - 0x1aa705, - 0x5474f, - 0xf10c6, - 0x1454408, - 0x118cce, - 0x5de2a502, - 0x32f688, - 0x361886, - 0x24e706, - 0x39cb07, - 0x5e200c82, - 0x5e6bb188, - 0x21f28a, - 0x268208, + 0x2b1b84, + 0x243543, + 0x216443, + 0x2296c3, + 0x20d903, + 0x20cb83, + 0x201643, + 0x8904, + 0x793c8, + 0xf0007, + 0x16542, + 0x13f105, + 0x5fdcf, + 0xfa946, + 0x1472588, + 0x1190ce, + 0x69a0bc42, + 0x20bc88, + 0x20ad46, + 0x257f86, + 0x39a587, + 0x69e00c82, + 0x6a2bf108, + 0x22588a, + 0x270088, 0x200ac2, - 0x3ca549, - 0x358fc7, - 0x214846, - 0x222c89, - 0x2eeac4, - 0x3ca446, - 0x2e9104, - 0x2029c4, - 0x257b49, - 0x310e86, - 0x267c85, - 0x26b845, - 0x22f587, - 0x2de387, - 0x26b784, - 0x2d2486, - 0x301785, - 0x20ee05, - 0x25b1c5, - 0x2c2347, - 0x276245, - 0x24a0c9, - 0x37eb85, - 0x321984, - 0x3ae5c7, - 0x3b3fce, - 0x207289, - 0x3487c9, - 0x371246, - 0x2405c8, - 0x37554b, - 0x2a74cc, - 0x326f06, - 0x2c01c7, - 0x2f0d05, - 0x3163ca, - 0x3e2049, + 0x37b789, + 0x2713c7, + 0x21ab46, + 0x2b1589, + 0x2cb344, + 0x349406, + 0x2d8d04, + 0x223984, + 0x263789, + 0x3e2106, + 0x236b05, + 0x274145, + 0x3e04c7, + 0x2d3b87, + 0x2d8684, + 0x322006, + 0x3061c5, + 0x20b585, + 0x238cc5, + 0x337047, + 0x3c7645, + 0x2533c9, + 0x3411c5, + 0x33ea04, + 0x231bc7, + 0x379ece, + 0x208509, + 0x340989, + 0x36ce06, + 0x249048, + 0x370e4b, + 0x2ab90c, + 0x31a746, + 0x2c32c7, + 0x2f19c5, + 0x31270a, + 0x20a989, 0x201189, - 0x206a86, - 0x30d905, - 0x246e45, - 0x389a89, - 0x25b34b, - 0x2ef106, - 0x353806, - 0x209984, - 0x303a46, - 0x3051c8, - 0x3cbf46, - 0x267846, - 0x203048, - 0x205107, - 0x206809, - 0x208e85, - 0xae888, - 0x3d2c44, - 0x319844, - 0x210145, - 0x343c49, - 0x221287, - 0x22128b, - 0x22434a, - 0x228745, - 0x5ea087c2, - 0x3560c7, - 0x5ee2b748, - 0x206cc7, - 0x303085, - 0x35d60a, - 0x12402, - 0x28428b, - 0x28544a, - 0x24a546, - 0x20ffc3, - 0x21114d, - 0x3ca98c, - 0x203a8d, - 0x232105, - 0x3363c5, - 0x324687, - 0x206309, - 0x21f186, - 0x247b45, - 0x3401c8, - 0x2d4dc3, - 0x2f52c8, - 0x303948, - 0x3a2107, - 0x3c5d88, - 0x3c76c9, - 0x2ff5c7, - 0x3558c7, - 0x371408, - 0x38bcc4, - 0x38bcc7, - 0x292048, - 0x366406, - 0x3cb14f, - 0x265747, - 0x2d1f86, - 0x32ac45, - 0x223ec3, - 0x2479c7, - 0x38e083, - 0x24c6c6, - 0x24e486, - 0x24ff06, - 0x298ec5, - 0x26c183, - 0x398ec8, - 0x390849, - 0x3a290b, - 0x250088, - 0x251945, - 0x253645, - 0x5f2ba882, - 0x2a4c09, - 0x223307, - 0x259a05, - 0x257a47, - 0x258ec6, - 0x386ac5, - 0x259d0b, - 0x25c8c4, - 0x267dc5, - 0x267f07, - 0x27c586, - 0x27c9c5, - 0x28b987, - 0x28c147, - 0x2a9cc4, - 0x2bee4a, - 0x292b08, - 0x375809, - 0x25b985, - 0x3585c6, - 0x30538a, - 0x26d6c6, - 0x236047, - 0x272a0d, - 0x2abf09, - 0x397445, - 0x2603c7, - 0x32d088, - 0x3b38c8, - 0x20a107, - 0x20e3c6, - 0x22cc07, - 0x24d903, - 0x310e04, - 0x383405, - 0x3af807, - 0x3bae09, - 0x2f5e08, - 0x235f45, - 0x362784, - 0x250245, - 0x25ca8d, + 0x207d06, + 0x3bacc5, + 0x24f485, + 0x385e09, + 0x238e4b, + 0x3871c6, + 0x352106, + 0x20ef84, + 0x323bc6, + 0x308608, + 0x3cd246, + 0x228d06, + 0x204b88, + 0x206347, + 0x207ac9, + 0x20a245, + 0x793c8, + 0x3d7444, + 0x319c44, + 0x213f45, + 0x344589, + 0x22adc7, + 0x22adcb, + 0x22c88a, + 0x232345, + 0x6a606e82, + 0x2f6b47, + 0x6aa34fc8, + 0x207f47, + 0x21c245, + 0x2c858a, + 0x16542, + 0x289c0b, + 0x28ab0a, + 0x22bd06, + 0x2122c3, + 0x214ccd, + 0x3c338c, + 0x3dec0d, + 0x29e685, + 0x2bdd45, + 0x3a29c7, + 0x214609, + 0x225786, + 0x24c985, + 0x37f7c8, + 0x2d9c83, + 0x3588c8, + 0x323ac8, + 0x39f407, + 0x3c7188, + 0x2251c9, + 0x2d7a47, + 0x2f6347, + 0x36cfc8, + 0x37b644, + 0x37b647, + 0x28a4c8, + 0x361486, + 0x205acf, + 0x323607, + 0x321b06, + 0x361ec5, + 0x22c3c3, + 0x250b47, + 0x251243, + 0x255446, + 0x257d06, + 0x25a606, + 0x29c885, + 0x273b43, + 0x396e48, + 0x38b949, + 0x3a3c8b, + 0x25a788, + 0x25c785, + 0x25eb45, + 0x6ae5c082, + 0x26b249, + 0x3d1907, + 0x2891c5, + 0x263687, + 0x264dc6, + 0x3b2605, + 0x267a8b, + 0x26ac84, + 0x26fc45, + 0x26fd87, + 0x281a06, + 0x281e45, + 0x290dc7, + 0x291487, + 0x2ae244, + 0x37468a, + 0x297688, + 0x371109, + 0x2acac5, + 0x347486, + 0x3087ca, + 0x274046, + 0x23b8c7, + 0x2780cd, + 0x2b0049, + 0x394d85, + 0x37d287, + 0x32bbc8, + 0x36c888, + 0x3c3ac7, + 0x3ce246, + 0x22d347, + 0x257783, + 0x357f04, + 0x380f85, + 0x3b1447, + 0x3bbe49, + 0x287f08, + 0x23b7c5, + 0x382fc4, + 0x2574c5, + 0x26510d, 0x200cc2, - 0x2ce4c6, - 0x2f7986, - 0x30820a, - 0x3a0e06, - 0x3aa945, - 0x2e95c5, - 0x2e95c7, - 0x3adc0c, - 0x25720a, - 0x294d06, - 0x2e4185, - 0x303886, - 0x294fc7, - 0x296986, - 0x298dcc, - 0x222dc9, - 0x5f626207, - 0x29ae85, - 0x29ae86, - 0x29bb48, - 0x2ca185, - 0x2ac785, - 0x2ad148, - 0x2ad34a, - 0x5fa295c2, - 0x5fe0b942, - 0x309d85, - 0x26a483, - 0x32a308, - 0x210503, - 0x2ad5c4, - 0x35d30b, - 0x2a78c8, - 0x384648, - 0x6034b7c9, - 0x2b48c9, - 0x2b51c6, - 0x2b6b48, - 0x2b6d49, - 0x2b7a86, - 0x2b7c05, - 0x248486, - 0x2b8589, - 0x2cd607, - 0x394746, - 0x21b347, - 0x2014c7, - 0x213f04, - 0x6067f8c9, - 0x2bcec8, - 0x2bb088, + 0x221ec6, + 0x2f8e06, + 0x33f34a, + 0x39e886, + 0x3afc45, + 0x2d91c5, + 0x2d91c7, + 0x3b3b0c, + 0x2b340a, + 0x298d86, + 0x2e7c45, + 0x323a06, + 0x299287, + 0x29ab06, + 0x29c78c, + 0x2b16c9, + 0x6b226c47, + 0x29f685, + 0x29f686, + 0x2a0288, + 0x24c885, + 0x2b0785, + 0x2b2048, + 0x2b224a, + 0x6b6870c2, + 0x6ba10f82, + 0x368b05, + 0x317b83, + 0x23d9c8, + 0x20b383, + 0x2b24c4, + 0x24694b, + 0x2231c8, + 0x2c1bc8, + 0x6bf4a9c9, + 0x2b8309, + 0x2b8c06, + 0x2b9e48, + 0x2ba049, + 0x2ba946, + 0x2baac5, + 0x251986, + 0x2bb089, + 0x2d46c7, + 0x24e2c6, + 0x273307, + 0x37bd07, + 0x39d584, + 0x6c2f4bc9, + 0x39dc88, + 0x2bf008, 0x200e07, - 0x2d7c86, - 0x205a89, - 0x24e6c7, - 0x3c250a, - 0x3c8108, - 0x2131c7, - 0x2180c6, - 0x2a114a, - 0x32a708, - 0x2f7405, - 0x225a05, - 0x3d12c7, - 0x3264c9, - 0x32878b, - 0x39be48, - 0x37ec09, - 0x250487, - 0x2c94cc, - 0x2c9d4c, - 0x2ca04a, - 0x2ca2cc, - 0x2d3d88, - 0x2d3f88, - 0x2d4184, - 0x2d4549, - 0x2d4789, - 0x2d49ca, - 0x2d4c49, - 0x2d4fc7, - 0x3c91cc, - 0x3dc686, - 0x2723c8, - 0x26d786, - 0x3957c6, - 0x397347, - 0x3a8708, - 0x22a28b, - 0x206b87, - 0x257809, - 0x288349, - 0x2a4e07, - 0x2e9344, - 0x269087, - 0x39b786, - 0x2128c6, - 0x2ed205, - 0x2f9848, - 0x317044, - 0x317046, - 0x2570cb, - 0x2af909, - 0x385c06, - 0x267a49, - 0x210206, - 0x249088, - 0x20eb03, - 0x30da85, - 0x219849, - 0x214445, - 0x3b9e84, - 0x3d25c6, - 0x308005, - 0x20a686, - 0x31d587, - 0x355006, - 0x22c6cb, - 0x2040c7, - 0x3a9c46, - 0x278c86, - 0x22f646, - 0x26b749, - 0x3b5e0a, - 0x2cb445, - 0x205e0d, - 0x2ad446, - 0x239446, - 0x2e8b06, - 0x220d45, - 0x2f2107, - 0x30b4c7, - 0x2794ce, - 0x23cb03, - 0x2d7c49, - 0x324b49, - 0x22f2c7, - 0x271a47, - 0x2703c5, - 0x294145, - 0x60bb494f, - 0x2ddc07, - 0x2dddc8, - 0x2de184, - 0x2de646, - 0x60e46b42, - 0x2e2386, - 0x2e4806, - 0x3b564e, - 0x2f510a, - 0x2bb906, - 0x218d4a, - 0x203889, - 0x23c7c5, - 0x312d08, - 0x33dd86, - 0x2ba948, - 0x36aac8, - 0x28238b, - 0x39cc05, - 0x2762c8, - 0x20318c, - 0x302f47, - 0x24f986, - 0x30e908, - 0x229f48, - 0x6123bec2, - 0x20c70b, - 0x209089, - 0x2bf709, - 0x21a747, - 0x3c3088, - 0x6161cf48, - 0x21d84b, - 0x34bd89, - 0x28be0d, - 0x3802c8, - 0x2a1348, - 0x61a09282, - 0x228644, - 0x61e30242, - 0x3b9cc6, - 0x62200e42, - 0x2fd7ca, - 0x364486, - 0x267388, - 0x3cea88, - 0x3e1bc6, - 0x2c06c6, - 0x306246, - 0x2acc85, - 0x239dc4, - 0x62768e04, - 0x35f2c6, - 0x277a47, - 0x62a810c7, - 0x24ed8b, - 0x206ec9, - 0x33640a, - 0x2f4dc4, - 0x2e9708, - 0x39450d, - 0x2fe709, - 0x2fe948, - 0x2febc9, - 0x300ac4, - 0x266344, - 0x393505, - 0x33f0cb, - 0x2a7846, - 0x35f105, - 0x236dc9, - 0x2d2548, - 0x2aa9c4, - 0x316549, - 0x3c22c5, - 0x2de3c8, - 0x355f87, - 0x348bc8, - 0x288a06, - 0x20f5c7, - 0x2e8689, - 0x3c33c9, - 0x226705, - 0x23b4c5, - 0x62e13242, - 0x321744, - 0x232345, - 0x39ca06, - 0x33eac5, - 0x23fa07, - 0x35f3c5, - 0x27c5c4, - 0x371306, - 0x247bc7, - 0x238e46, - 0x30c645, - 0x214048, - 0x361a85, - 0x21e147, - 0x225209, - 0x2afa4a, - 0x266f07, - 0x266f0c, - 0x267c46, - 0x23df09, - 0x248085, - 0x2d2ec8, - 0x202443, - 0x2f2d05, - 0x3c0e45, - 0x282fc7, - 0x63201242, - 0x2f9b87, - 0x2f0906, - 0x3862c6, - 0x2f2586, - 0x229e86, - 0x23be08, - 0x27e105, - 0x2d2047, - 0x2d204d, - 0x20ee43, - 0x3dcb45, - 0x276b87, - 0x2f9ec8, - 0x276745, - 0x216bc8, - 0x382e86, - 0x29c107, - 0x2d6945, - 0x39cc86, - 0x399445, - 0x21ef4a, - 0x301b46, - 0x274587, - 0x2ce285, - 0x310687, - 0x35a584, - 0x3b9e06, - 0x312c45, - 0x33544b, - 0x39b609, - 0x281cca, - 0x226788, - 0x393f88, - 0x31408c, - 0x3d8d07, - 0x31c848, - 0x31ecc8, - 0x32b9c5, - 0x35c18a, - 0x35f4c9, - 0x63600ec2, - 0x20b086, - 0x260d44, - 0x2fc549, - 0x240e89, - 0x246907, - 0x27bfc7, - 0x29cd49, - 0x33e348, - 0x33e34f, - 0x22d606, - 0x2e6ccb, - 0x256845, - 0x256847, - 0x381cc9, - 0x21fe06, - 0x3164c7, - 0x2eb805, - 0x232004, - 0x307ec6, - 0x206244, - 0x3ba247, - 0x3792c8, - 0x63b0d808, - 0x30fa05, - 0x30fb47, - 0x3532c9, - 0x20c4c4, - 0x241948, - 0x63e653c8, - 0x2e8a84, - 0x2f6dc8, - 0x25f184, - 0x206109, - 0x220c85, - 0x6422dc42, - 0x22d645, - 0x2dfd45, - 0x2600c8, - 0x234c07, - 0x646008c2, - 0x3c7a85, - 0x2e04c6, - 0x24d186, - 0x321708, - 0x31f148, - 0x33ea86, - 0x34a046, - 0x30a149, - 0x386206, - 0x21fccb, - 0x229d05, - 0x2af286, - 0x368048, - 0x34ae46, - 0x2bc246, - 0x2178ca, - 0x2e1b0a, - 0x23eb45, - 0x29c787, - 0x27a146, - 0x64a034c2, - 0x276cc7, - 0x367145, - 0x305304, - 0x305305, - 0x2f4cc6, - 0x278807, - 0x21ac85, - 0x240f44, - 0x2c3708, - 0x2bc305, - 0x37a987, - 0x3808c5, - 0x21ee85, - 0x245744, - 0x245749, - 0x3015c8, - 0x359586, - 0x358846, - 0x363f06, - 0x64fcfc08, - 0x3d8b87, - 0x31474d, - 0x314f0c, - 0x315509, - 0x315749, - 0x65379942, - 0x3d7403, - 0x20e483, - 0x39b845, - 0x3af90a, - 0x33e946, - 0x2365c5, - 0x31e244, - 0x31e24b, - 0x33384c, - 0x33410c, - 0x334415, - 0x335e0d, - 0x337e8f, - 0x338252, - 0x3386cf, - 0x338a92, - 0x338f13, - 0x3393cd, - 0x33998d, - 0x339d0e, - 0x33a60e, - 0x33ac0c, - 0x33afcc, - 0x33b40b, - 0x33be8e, - 0x33c792, - 0x33e70c, - 0x3403d0, - 0x34e4d2, - 0x34f54c, - 0x34fc0d, - 0x34ff4c, - 0x3524d1, - 0x35398d, - 0x35ae4d, - 0x35b44a, - 0x35b6cc, - 0x35e60c, - 0x35ee0c, - 0x35f70c, - 0x362e93, - 0x363610, - 0x363a10, - 0x36460d, - 0x364c0c, - 0x365a49, - 0x3697cd, - 0x369b13, - 0x36b451, - 0x36bc53, - 0x36c94f, - 0x36cd0c, - 0x36d00f, - 0x36d3cd, - 0x36d9cf, - 0x36dd90, - 0x36e80e, - 0x37198e, - 0x3722d0, - 0x37318d, - 0x373b0e, - 0x373e8c, - 0x374fd3, - 0x37768e, - 0x377c10, - 0x378011, - 0x37844f, - 0x378813, - 0x3794cd, - 0x37980f, - 0x379bce, - 0x37a150, - 0x37a549, - 0x37bc90, - 0x37c18f, - 0x37c80f, - 0x37cbd2, - 0x37f68e, - 0x3804cd, - 0x380a0d, - 0x380d4d, - 0x381f0d, - 0x38224d, - 0x382590, - 0x38298b, - 0x3831cc, - 0x38354c, - 0x383b4c, - 0x383e4e, - 0x393650, - 0x395112, - 0x39558b, - 0x395f8e, - 0x39630e, - 0x396b8e, - 0x39710b, - 0x65797596, - 0x397e8d, - 0x398a14, - 0x39970d, - 0x39c255, - 0x39ea0d, - 0x39f38f, - 0x39fb4f, - 0x3a2bcf, - 0x3a2f8e, - 0x3a330d, - 0x3a4891, - 0x3a7ecc, - 0x3a81cc, - 0x3a84cb, - 0x3a890c, - 0x3a904f, - 0x3a9412, - 0x3aa1cd, - 0x3abe8c, - 0x3acc4c, - 0x3acf4d, - 0x3ad28f, - 0x3ad64e, - 0x3af5cc, - 0x3afb8d, - 0x3afecb, - 0x3b078c, - 0x3b108d, - 0x3b13ce, - 0x3b1749, - 0x3b2dd3, - 0x3b688d, - 0x3b6f8d, - 0x3b758c, - 0x3b7c0e, - 0x3b830f, - 0x3b86cc, - 0x3b89cd, - 0x3b8d0f, - 0x3b90cc, - 0x3ba40c, - 0x3ba8cc, - 0x3babcc, - 0x3bbb8d, - 0x3bbed2, - 0x3bc64c, - 0x3bc94c, - 0x3bcc51, - 0x3bd08f, - 0x3bd44f, - 0x3bd813, - 0x3be60e, - 0x3be98f, - 0x3bed4c, - 0x65bbf40e, - 0x3bf78f, - 0x3bfb56, - 0x3c1bd2, - 0x3c440c, - 0x3c4d8f, - 0x3c540d, - 0x3cec8f, - 0x3cf04c, - 0x3cf34d, - 0x3cf68d, - 0x3d0d4e, - 0x3d19cc, - 0x3d420c, - 0x3d4510, - 0x3d6791, - 0x3d6bcb, - 0x3d700c, - 0x3d730e, - 0x3d91d1, - 0x3d960e, - 0x3d998d, - 0x3de2cb, - 0x3debcf, - 0x3dfa54, - 0x23ca82, - 0x23ca82, - 0x203183, - 0x23ca82, - 0x203183, - 0x23ca82, + 0x2dc706, + 0x20db89, + 0x257f47, + 0x3c840a, + 0x3ce388, + 0x21f107, + 0x221886, + 0x29ac4a, + 0x3a6c88, + 0x2f8885, + 0x22f6c5, + 0x31bd47, + 0x324849, + 0x32864b, + 0x3bc408, + 0x341249, + 0x25b607, + 0x2cdbcc, + 0x2ce30c, + 0x2ce60a, + 0x2ce88c, + 0x2d8888, + 0x2d8a88, + 0x2d8c84, + 0x2d9409, + 0x2d9649, + 0x2d988a, + 0x2d9b09, + 0x2d9e87, + 0x3cb8cc, + 0x3e7f06, + 0x277a88, + 0x274106, + 0x392b46, + 0x394c87, + 0x3ab788, + 0x3499cb, + 0x207e07, + 0x263fc9, + 0x28d5c9, + 0x252907, + 0x24b5c4, + 0x26bfc7, + 0x2d2bc6, + 0x218946, + 0x217145, + 0x2db8c8, + 0x310704, + 0x310706, + 0x2b32cb, + 0x266749, + 0x25b246, + 0x228f09, + 0x214006, + 0x38f0c8, + 0x271f43, + 0x3bae45, + 0x218a89, + 0x3e97c5, + 0x308104, + 0x3b7146, + 0x36aa05, + 0x260006, + 0x31c407, + 0x2109c6, + 0x2374cb, + 0x3c2887, + 0x267786, + 0x27e3c6, + 0x3e0586, + 0x2d8649, + 0x20308a, + 0x2cfdc5, + 0x2fcb0d, + 0x2b2346, + 0x259946, + 0x2e2146, + 0x227b45, + 0x2f2847, + 0x233587, + 0x27ec0e, + 0x216443, + 0x2dc6c9, + 0x3a1c09, + 0x312b07, + 0x276e87, + 0x291945, + 0x2f3e45, + 0x6c609e0f, + 0x2e1a47, + 0x2e1c08, + 0x2e1f04, + 0x2e2446, + 0x6ca4f102, + 0x2e5b86, + 0x2e8306, + 0x30f40e, + 0x35870a, + 0x2c7906, + 0x21498a, + 0x20d109, + 0x23f7c5, + 0x30bfc8, + 0x3dc706, + 0x2be208, + 0x343648, + 0x285dcb, + 0x39a685, + 0x3c76c8, + 0x204ccc, + 0x21c107, + 0x259b86, + 0x36a848, + 0x349688, + 0x6ce4ba82, + 0x32e38b, + 0x211e89, + 0x20a449, + 0x3c2187, + 0x3a8bc8, + 0x6d21e1c8, + 0x32c1cb, + 0x268d09, + 0x29420d, + 0x306f08, + 0x3c5088, + 0x6d603c82, + 0x210c84, + 0x6da386c2, + 0x377a06, + 0x6de00e42, + 0x3022ca, + 0x2b0606, + 0x22fc48, + 0x2b1e48, + 0x260946, + 0x2c37c6, + 0x3090c6, + 0x3e5505, + 0x2417c4, + 0x6e235504, + 0x3597c6, + 0x281447, + 0x6e684ec7, + 0x391e0b, + 0x208149, + 0x2bdd8a, + 0x2d9304, + 0x258208, + 0x24e08d, + 0x302bc9, + 0x302e08, + 0x303089, + 0x305504, + 0x251104, + 0x28c445, + 0x20508b, + 0x223146, + 0x359605, + 0x23f349, + 0x3220c8, + 0x2aeb04, + 0x312889, + 0x21eec5, + 0x2d3bc8, + 0x2f6a07, + 0x340d88, + 0x28cf06, + 0x206d47, + 0x2ecf49, + 0x203809, + 0x22f845, + 0x2b0d05, + 0x6ea1f182, + 0x33e7c4, + 0x244985, + 0x39a486, + 0x34b885, + 0x303c87, + 0x3598c5, + 0x281a44, + 0x36cec6, + 0x24ca07, + 0x3a01c6, + 0x32c605, + 0x212788, + 0x20af45, + 0x21b207, + 0x22c649, + 0x26688a, + 0x2344c7, + 0x2344cc, + 0x236ac6, + 0x242d89, + 0x24c505, + 0x24c7c8, + 0x22ea03, + 0x230445, + 0x2c7d85, + 0x286a07, + 0x6ee01242, + 0x2fe1c7, + 0x2eef06, + 0x3ad646, + 0x2f2006, + 0x3495c6, + 0x24b9c8, + 0x283885, + 0x321bc7, + 0x321bcd, + 0x20b5c3, + 0x3e83c5, + 0x3c7f87, + 0x2fe508, + 0x3c7b45, + 0x21f908, + 0x35b2c6, + 0x2ea3c7, + 0x2f5685, + 0x39a706, + 0x3973c5, + 0x22554a, + 0x2f9546, + 0x2315c7, + 0x320285, + 0x2fdec7, + 0x301804, + 0x308086, + 0x30bf05, + 0x23640b, + 0x2d2a49, + 0x28bc0a, + 0x22f8c8, + 0x377b48, + 0x30fecc, + 0x310c87, + 0x31ea88, + 0x391308, + 0x3d65c5, + 0x32a40a, + 0x34f9c9, + 0x6f200ec2, + 0x210606, + 0x24c004, + 0x300c89, + 0x247989, + 0x24eec7, + 0x284447, + 0x2a0d09, + 0x32aac8, + 0x32aacf, + 0x22dd46, + 0x2e9ecb, + 0x261445, + 0x261447, + 0x3572c9, + 0x22a186, + 0x312807, + 0x2ee685, + 0x23a944, + 0x34cb86, + 0x2174c4, + 0x2c9147, + 0x360648, + 0x6f7babc8, + 0x30d045, + 0x30d187, + 0x351bc9, + 0x211c44, + 0x24a5c8, + 0x6fb04c88, + 0x2e20c4, + 0x33ed08, + 0x32ce84, + 0x217389, + 0x227a85, + 0x6fe13402, + 0x22dd85, + 0x2ed405, + 0x3b69c8, + 0x23cf87, + 0x702008c2, + 0x3c2645, + 0x2e4146, + 0x25fb06, + 0x33e788, + 0x348688, + 0x34b846, + 0x37dcc6, + 0x2f00c9, + 0x3ad586, + 0x22a04b, + 0x349345, + 0x259386, + 0x261f88, + 0x362646, + 0x29e506, + 0x22000a, + 0x2e530a, + 0x22be45, + 0x24f187, + 0x27f886, + 0x70605002, + 0x3c80c7, + 0x38fb05, + 0x308744, + 0x308745, + 0x258106, + 0x27df47, + 0x2247c5, + 0x247a44, + 0x2e2708, + 0x29e5c5, + 0x355387, + 0x383485, + 0x225485, + 0x265c84, + 0x265c89, + 0x306008, + 0x2017c6, + 0x347706, + 0x3b6c06, + 0x70bd38c8, + 0x3dc2c7, + 0x31490d, + 0x314ecc, + 0x3154c9, + 0x315709, + 0x70f75ac2, + 0x3db703, + 0x22bec3, + 0x2d2c85, + 0x3b154a, + 0x33e646, + 0x34ce85, + 0x31cbc4, + 0x31cbcb, + 0x33508c, + 0x33594c, + 0x335c55, + 0x33698d, + 0x338a8f, + 0x338e52, + 0x3392cf, + 0x339692, + 0x339b13, + 0x339fcd, + 0x33a58d, + 0x33a90e, + 0x33b2ce, + 0x33b9cc, + 0x33bd8c, + 0x33c1cb, + 0x33cc4e, + 0x33d552, + 0x33e40c, + 0x33f5d0, + 0x34cfd2, + 0x34e1cc, + 0x34e88d, + 0x34ebcc, + 0x350dd1, + 0x35228d, + 0x355f8d, + 0x35658a, + 0x35680c, + 0x357ccc, + 0x35930c, + 0x359ccc, + 0x35dad3, + 0x35e550, + 0x35e950, + 0x35f34d, + 0x35f94c, + 0x360ac9, + 0x36290d, + 0x362c53, + 0x364b11, + 0x365313, + 0x36664f, + 0x366a0c, + 0x366d0f, + 0x3670cd, + 0x3676cf, + 0x367a90, + 0x36850e, + 0x36d54e, + 0x36de90, + 0x36ea8d, + 0x36f40e, + 0x36f78c, + 0x3708d3, + 0x3725ce, + 0x373310, + 0x373711, + 0x373b4f, + 0x373f13, + 0x37564d, + 0x37598f, + 0x375d4e, + 0x3762d0, + 0x3766c9, + 0x377d50, + 0x37824f, + 0x3788cf, + 0x378c92, + 0x37c3ce, + 0x37d94d, + 0x37e00d, + 0x37e34d, + 0x37f9cd, + 0x37fd0d, + 0x380050, + 0x38044b, + 0x380d4c, + 0x3810cc, + 0x3816cc, + 0x3819ce, + 0x390450, + 0x392492, + 0x39290b, + 0x3938ce, + 0x393c4e, + 0x3944ce, + 0x394a4b, + 0x71394ed6, + 0x395e0d, + 0x396994, + 0x39768d, + 0x399cd5, + 0x39b8cd, + 0x39c24f, + 0x39cb8f, + 0x3a3f4f, + 0x3a430e, + 0x3a468d, + 0x3a6611, + 0x3aaf4c, + 0x3ab24c, + 0x3ab54b, + 0x3ab98c, + 0x3ac40f, + 0x3ac7d2, + 0x3acdcd, + 0x3ae1cc, + 0x3aec8c, + 0x3aef8d, + 0x3af2cf, + 0x3af68e, + 0x3b120c, + 0x3b17cd, + 0x3b1b0b, + 0x3b23cc, + 0x3b318d, + 0x3b34ce, + 0x3b3849, + 0x3b50d3, + 0x3b798d, + 0x3b808d, + 0x3b868c, + 0x3b8d0e, + 0x3b958f, + 0x3b994c, + 0x3b9c4d, + 0x3b9f8f, + 0x3ba34c, + 0x3bb38c, + 0x3bb90c, + 0x3bbc0c, + 0x3bc8cd, + 0x3bcc12, + 0x3bd38c, + 0x3bd68c, + 0x3bd991, + 0x3bddcf, + 0x3be18f, + 0x3be553, + 0x3bf34e, + 0x3bf6cf, + 0x3bfa8c, + 0x717c014e, + 0x3c04cf, + 0x3c0896, + 0x3c1b92, + 0x3c528c, + 0x3c618f, + 0x3c680d, + 0x3d294f, + 0x3d2d0c, + 0x3d300d, + 0x3d334d, + 0x3d51ce, + 0x3d5d0c, + 0x3d914c, + 0x3d9450, + 0x3daa91, + 0x3daecb, + 0x3db30c, + 0x3db60e, + 0x3dd8d1, + 0x3ddd0e, + 0x3de08d, + 0x3e5f8b, + 0x3e688f, + 0x3e74d4, + 0x2038c2, + 0x2038c2, + 0x204cc3, + 0x2038c2, + 0x204cc3, + 0x2038c2, 0x201082, - 0x2484c5, - 0x3d8ecc, - 0x23ca82, - 0x23ca82, + 0x2519c5, + 0x3dd5cc, + 0x2038c2, + 0x2038c2, 0x201082, - 0x23ca82, - 0x29c945, - 0x2afa45, - 0x23ca82, - 0x23ca82, - 0x208a02, - 0x29c945, - 0x336689, - 0x36b14c, - 0x23ca82, - 0x23ca82, - 0x23ca82, - 0x23ca82, - 0x2484c5, - 0x23ca82, - 0x23ca82, - 0x23ca82, - 0x23ca82, - 0x208a02, - 0x336689, - 0x23ca82, - 0x23ca82, - 0x23ca82, - 0x2afa45, - 0x23ca82, - 0x2afa45, - 0x36b14c, - 0x3d8ecc, - 0x24ac43, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x217fc3, - 0x23e083, - 0x1e14cf, - 0x1b4508, - 0x6704, - 0x5803, - 0x8efc8, - 0x1d1843, + 0x2038c2, + 0x2a0905, + 0x266885, + 0x2038c2, + 0x2038c2, + 0x20bd42, + 0x2a0905, + 0x337209, + 0x36480c, + 0x2038c2, + 0x2038c2, + 0x2038c2, + 0x2038c2, + 0x2519c5, + 0x2038c2, + 0x2038c2, + 0x2038c2, + 0x2038c2, + 0x20bd42, + 0x337209, + 0x2038c2, + 0x2038c2, + 0x2038c2, + 0x266885, + 0x2038c2, + 0x266885, + 0x36480c, + 0x3dd5cc, + 0x253c43, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x2296c3, + 0x20cb83, + 0x3c4f, + 0x12d248, + 0x6f7c4, + 0xd903, + 0x17b4c8, + 0x1d5b83, 0x2000c2, - 0x66a12402, - 0x241283, - 0x25a584, - 0x2033c3, - 0x38a0c4, - 0x231346, - 0x222743, - 0x3d2484, - 0x3517c5, - 0x23cb03, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0x226e0a, - 0x2509c6, - 0x39668c, - 0xae888, - 0x212402, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x215f83, - 0x2e4806, - 0x217fc3, - 0x23e083, - 0x216983, - 0xe783, - 0xaeec8, - 0x675dc3c5, - 0x49647, - 0x146bc5, - 0xcd89, - 0x8c02, - 0x1c73ca, - 0x683a7b85, - 0x146bc5, - 0x1683c7, - 0x74f88, - 0xb74e, - 0x90d92, - 0x123bcb, - 0x110ac6, - 0x686bd285, - 0x68abf28c, - 0x149147, - 0x178d87, - 0x127eca, - 0x3c290, - 0x1645, - 0xc634b, - 0x10f508, - 0x35cc7, - 0xbc3cb, - 0x34449, - 0x48687, - 0x161347, - 0xef347, - 0x35c06, - 0xec88, - 0x69036fc6, - 0x3dc87, - 0x176b06, - 0x4efcd, - 0xe9890, - 0x694293c2, - 0x7f248, - 0x8c550, - 0x184e8c, - 0x69b8794d, - 0x5a388, - 0x5a80b, - 0x71007, - 0x96d89, - 0x56546, - 0x9bd48, - 0x5b542, - 0x1b21ca, - 0x65a87, - 0xb4e07, - 0xafcc9, - 0xb3108, - 0xf48c5, - 0x193c86, - 0x1c2e06, - 0xffb4e, - 0xef90e, - 0x18ee0f, - 0x33449, - 0x860c9, - 0x1b1d4b, - 0xb538f, - 0xc470c, - 0xcfe0b, - 0x11d1c8, - 0x16f747, - 0x194c88, - 0x1a8c8b, - 0xb920c, - 0xb960c, - 0xb9a0c, - 0xb9d0d, - 0x1bb208, - 0x50d42, - 0x199249, - 0x15d048, - 0x1de00b, - 0xd7e86, - 0xdfe8b, - 0x13c2cb, - 0xeaf4a, - 0xec7c5, - 0xf1e10, - 0xf6a46, - 0x155146, - 0x1b5a05, - 0x19dfc7, - 0xe2608, - 0xfadc7, - 0xfb087, - 0x1416c7, - 0xccec6, - 0x1b9b0a, - 0xae70a, - 0x13a06, - 0xb4bcd, - 0x3dd48, - 0x118088, - 0x1188c9, - 0xc7c05, - 0x1b800c, - 0xb9f0b, - 0x15ca49, - 0x1d1204, - 0x114389, - 0x1145c6, - 0x156786, - 0x3c986, - 0x72c2, - 0x134c46, - 0x1496cb, - 0x11e987, - 0x11eb47, - 0x3602, - 0xd9785, - 0x2de44, + 0x72616542, + 0x249f03, + 0x23adc4, + 0x204f03, + 0x36c284, + 0x239c86, + 0x220e43, + 0x3b7004, + 0x2999c5, + 0x216443, + 0x2296c3, + 0x7ca83, + 0x20cb83, + 0x23098a, + 0x259186, + 0x393fcc, + 0x793c8, + 0x216542, + 0x216543, + 0x222bc3, + 0x343b43, + 0x233243, + 0x2e8306, + 0x2296c3, + 0x20cb83, + 0x21f6c3, + 0x39fc3, + 0xb4388, + 0x731e7c45, + 0x7c4c7, + 0xb1845, + 0x52547, + 0x146c05, + 0x4009, + 0xad42, + 0x1c138a, + 0x73f2d5c5, + 0x146c05, + 0x34347, + 0x16108, + 0x10d8e, + 0x95292, + 0x130e0b, + 0x1e1d46, + 0x742ea205, + 0x7479e04c, + 0x10de07, + 0xb46c7, + 0x1b620a, + 0x44ad0, + 0x17be85, + 0xc5e4b, + 0x1dcf08, + 0x3e1c7, + 0x3aa4b, + 0x51b89, + 0x873c7, + 0xf4547, + 0x187407, + 0x3e106, + 0x1c74c8, + 0x74c32f46, + 0x46bc7, + 0xc7e86, + 0xb8d0d, + 0x96110, + 0x75013242, + 0x1cdd88, + 0x184590, + 0x18ed0c, + 0x7578f54d, + 0x68508, + 0x6898b, + 0x76447, + 0x19a49, + 0x62246, + 0xa0488, + 0x5102, + 0x9c50a, + 0x36947, + 0xb8847, + 0xb4e49, + 0xb7288, + 0x154645, + 0x190a86, + 0x6ac6, + 0x1040ce, + 0x422ce, + 0x4aecf, + 0x5e789, + 0x932c9, + 0x9c08b, + 0xbb44f, + 0x1dd2cc, + 0xd4f4b, + 0x1b9248, + 0x191d07, + 0x19b308, + 0xbc0cb, + 0xbca0c, + 0xbce0c, + 0xbd20c, + 0xbd50d, + 0x1bc248, + 0x5adc2, + 0x1971c9, + 0x46688, + 0xda88b, + 0xdc906, + 0xe3acb, + 0x13d08b, + 0xeddca, + 0xeec85, + 0xf2550, + 0xf8286, + 0x583c6, + 0x10f7c5, + 0x120047, + 0xfa348, + 0xff487, + 0xff747, + 0x69587, + 0xd1846, + 0x17784a, + 0xb400a, + 0x30846, + 0xb860d, + 0x46c88, + 0x118d88, + 0xef809, + 0x1b2a09, + 0xcc205, + 0x176a8c, + 0xbd70b, + 0x10d989, + 0x112cc4, + 0x114549, + 0x114786, + 0x143506, + 0x4a42, + 0x13906, + 0x80c8b, + 0x11de07, + 0x11dfc7, + 0xe042, + 0xde645, + 0x9204, 0x101, - 0x506c3, - 0x68e6a646, - 0x9c0c3, + 0x5b843, + 0x74b26806, + 0xa0803, 0x382, - 0x2b104, + 0x1504, 0xac2, - 0x4cd44, + 0x5dd04, 0x882, - 0x7282, - 0x6c02, - 0x10bf02, - 0xcf02, - 0xbd282, + 0x8502, + 0x4702, + 0x128c42, + 0x4182, + 0xea202, 0xd42, - 0x161e82, - 0x37402, - 0xda02, - 0xf982, - 0x4e682, - 0x33fc3, + 0x2e702, + 0x3fb82, + 0xc542, + 0x3242, + 0x57f02, + 0x22bc3, 0x942, - 0x31c2, - 0xfa02, - 0x91c2, + 0x2bc2, + 0x18242, + 0xeb02, 0x642, - 0x32702, - 0xb5c2, - 0x8fc2, - 0xf782, + 0x3b342, + 0x1ec82, + 0x8e82, + 0x5502, 0x5c2, - 0x191c3, - 0x4b82, - 0x22c2, - 0x4b202, - 0x6902, - 0x2702, - 0xa682, - 0x4202, - 0x8c82, - 0xb982, - 0x193b42, - 0x720c2, - 0xcac2, - 0x17fc3, + 0x43543, + 0x2642, + 0x6002, + 0x54202, + 0x7bc2, + 0x9d42, + 0x10442, + 0x205c2, + 0x11de42, + 0x1582, + 0x10f082, + 0x77782, + 0xa9542, + 0x296c3, 0x602, - 0x3bec2, - 0x2542, - 0x35c2, - 0x26685, - 0x4fc2, - 0x42c42, - 0x3d583, + 0x4ba82, + 0x1cc2, + 0x2d4c2, + 0x2f7c5, + 0x59c2, + 0x4cec2, + 0x179e43, 0x682, - 0xd782, - 0x2442, - 0xab02, - 0xee42, + 0x4a02, + 0x1702, + 0x4ac2, + 0xb5c2, 0x8c2, - 0x4642, - 0x72c2, - 0x8cc5, - 0x69e01082, - 0x6a2e82c3, - 0x1ac3, - 0x6a601082, - 0x1ac3, - 0x7a807, - 0x2089c3, + 0x6502, + 0x4a42, + 0x3ec5, + 0x75a01082, + 0x75eecb83, + 0x9983, + 0x76201082, + 0x9983, + 0xdc1c7, + 0x215483, 0x2000c2, - 0x22ea43, - 0x233fc3, - 0x280203, + 0x216543, + 0x222bc3, + 0x2f5503, 0x2005c3, - 0x215f83, - 0x217fc3, - 0x205803, - 0x23e083, - 0x2bd443, - 0xc7c44, - 0x16acc5, - 0x105085, - 0x10103, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x280203, - 0x23cb03, - 0x217fc3, - 0x205803, - 0x1c0443, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x200181, - 0x23cb03, - 0x217fc3, - 0x24dfc3, - 0x23e083, - 0x2f44, - 0x24ac43, - 0x22ea43, - 0x233fc3, - 0x275243, - 0x280203, - 0x2d2a83, - 0x2381c3, - 0x2a49c3, + 0x233243, + 0x2296c3, + 0x20d903, + 0x20cb83, + 0x2a0843, + 0xcc244, + 0x143845, + 0x1084c5, + 0x1a143, + 0x793c8, + 0x216543, + 0x222bc3, + 0x2f5503, + 0x216443, + 0x2296c3, 0x20d903, - 0x266a83, - 0x20e704, - 0x217fc3, - 0x23e083, - 0x20aa43, - 0x207d44, - 0x25cc83, - 0x33f03, - 0x238f43, - 0x32dac8, - 0x2a1184, + 0x7ca83, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x200181, + 0x216443, + 0x2296c3, + 0x257743, + 0x20cb83, + 0x1a3904, + 0x253c43, + 0x216543, + 0x222bc3, + 0x2163c3, + 0x2f5503, + 0x322603, + 0x285483, + 0x2b05c3, + 0x205383, + 0x343b43, + 0x2b1b84, + 0x2296c3, + 0x20cb83, + 0x201643, + 0x202304, + 0x239843, + 0x3b43, + 0x2133c3, + 0x32f308, + 0x29ac84, 0x20020a, - 0x385986, - 0x1530c4, - 0x3bc307, - 0x21bfca, - 0x22d4c9, - 0x3c7247, - 0x3c9c8a, - 0x24ac43, - 0x309e0b, - 0x20d849, - 0x2fde05, - 0x3ba707, - 0x12402, - 0x22ea43, - 0x2264c7, - 0x224685, - 0x2e9209, - 0x233fc3, - 0x23a086, - 0x2d3383, - 0xf0983, - 0x11bf06, - 0x8886, - 0x226c7, - 0x228c86, - 0x30bf45, - 0x208f47, - 0x319107, - 0x6d266a83, - 0x34f787, - 0x23ca83, - 0x21df05, - 0x20e704, - 0x275f48, - 0x3c410c, - 0x2be385, - 0x2ac086, - 0x226387, - 0x3c1447, - 0x269207, - 0x277008, - 0x31b18f, - 0x22d705, - 0x241387, - 0x211647, - 0x3caf0a, - 0x340009, - 0x32e945, - 0x34ef0a, - 0xdd286, - 0xc8087, - 0x2d3405, - 0x2f83c4, - 0x3e1b06, - 0x14e1c6, - 0x385107, - 0x250c47, - 0x3c5f48, - 0x212a05, - 0x224586, - 0x168688, - 0x2677c5, - 0x67986, - 0x2f5b85, - 0x267704, - 0x3c2387, - 0x23bc4a, - 0x2a6688, - 0x25f986, - 0x15f83, - 0x2ee705, - 0x354bc6, - 0x3c9406, - 0x3b5906, - 0x23cb03, - 0x3aa447, - 0x2115c5, - 0x217fc3, - 0x2eb20d, - 0x205803, - 0x3c6048, - 0x215c44, - 0x27c885, - 0x2ad606, - 0x358146, - 0x2af187, - 0x2a4a07, - 0x28dfc5, - 0x23e083, - 0x36f847, - 0x38a449, - 0x325009, - 0x3624ca, - 0x201b42, - 0x21dec4, - 0x304f84, - 0x2f9707, - 0x2f9a48, - 0x2fbfc9, - 0x3dca09, - 0x2fc9c7, - 0x108589, - 0x229446, - 0xff8c6, - 0x300ac4, - 0x22efca, - 0x304b08, - 0x306109, - 0x3066c6, - 0x2c3cc5, - 0x2a6548, - 0x2d810a, - 0x204343, - 0x207ec6, - 0x2fcac7, - 0x30f6c5, - 0x3c0385, - 0x243cc3, - 0x2ddf84, - 0x2259c5, - 0x28c247, - 0x301705, - 0x2f72c6, - 0x121dc5, - 0x288d83, - 0x2bb9c9, - 0x27c64c, - 0x2cbd4c, - 0x37f088, - 0x2a9f87, - 0x310848, - 0x111507, - 0x31188a, - 0x311f4b, - 0x20d988, - 0x358248, - 0x2524c6, - 0x31fdc5, - 0x25c4ca, - 0x2e8305, - 0x22dc42, - 0x2d6807, - 0x269f86, - 0x37b205, - 0x3d2189, - 0x27e3c5, - 0x388a05, - 0x229a09, - 0x325a46, - 0x37de88, - 0x270103, - 0x228dc6, - 0x3d2506, - 0x32dc85, - 0x32dc89, - 0x2ca889, - 0x25c247, - 0x120f44, - 0x320f47, - 0x3dc909, - 0x21c1c5, - 0x39ec8, - 0x37e245, - 0x371145, - 0x3b3609, - 0x201802, - 0x366984, - 0x20d2c2, - 0x204b82, - 0x320245, - 0x352e48, - 0x2c7b45, - 0x2d5183, - 0x2d5185, - 0x2e2583, - 0x20e202, - 0x2b5bc4, - 0x273cc3, + 0x25afc6, + 0x1519c4, + 0x3bd047, + 0x22820a, + 0x22dc09, + 0x3c9ec7, + 0x3cc38a, + 0x253c43, + 0x368b8b, + 0x20c389, + 0x31f4c5, + 0x20cd87, + 0x16542, + 0x216543, + 0x226f07, + 0x2224c5, + 0x2d8e09, + 0x222bc3, + 0x34bc46, + 0x32a4c3, + 0xd2b03, + 0x11bc06, + 0x17a2c6, + 0x20dc7, + 0x229a46, + 0x231f45, + 0x20a307, + 0x319507, + 0x78f43b43, + 0x34e407, + 0x3b29c3, + 0x2712c5, + 0x2b1b84, + 0x2c2188, + 0x3db94c, + 0x2c1305, + 0x2b01c6, + 0x226dc7, + 0x35b907, + 0x2678c7, + 0x26c148, + 0x31ae8f, + 0x27b905, + 0x24a007, + 0x2151c7, + 0x28974a, + 0x37f609, + 0x330145, + 0x34da0a, + 0x101546, + 0xcc787, + 0x2d7e45, + 0x2f5744, + 0x340486, + 0xcb946, + 0x256ec7, + 0x25acc7, + 0x3b5b48, + 0x3d07c5, + 0x2223c6, + 0x2f048, + 0x228c85, + 0x28e46, + 0x240305, + 0x288284, + 0x21ef87, + 0x24b80a, + 0x2aab88, + 0x3e3cc6, + 0x33243, + 0x2efe85, + 0x3d8586, + 0x3cbb06, + 0x30f6c6, + 0x216443, + 0x3ad047, + 0x215145, + 0x2296c3, + 0x2ee08d, + 0x20d903, + 0x3b5c48, + 0x243444, + 0x281d05, + 0x2b2506, + 0x32e106, + 0x259287, + 0x268bc7, + 0x27c805, + 0x20cb83, + 0x3a20c7, + 0x24b489, + 0x36a249, + 0x382d0a, + 0x23d7c2, + 0x271284, + 0x3211c4, + 0x2fda07, + 0x2fe088, + 0x300709, + 0x3e8289, + 0x301107, + 0x10a949, + 0x2132c6, + 0x103e46, + 0x305504, + 0x3b4e4a, + 0x307e08, + 0x308f89, + 0x309246, + 0x2c7245, + 0x2aaa48, + 0x2dcb8a, + 0x27d683, + 0x202486, + 0x301207, + 0x2c8885, + 0x3c10c5, + 0x24da03, + 0x2d1984, + 0x22f685, + 0x291587, + 0x306145, + 0x2f2cc6, + 0x166105, + 0x2c79c3, + 0x2c79c9, + 0x281acc, + 0x2d06cc, + 0x3416c8, + 0x2a3e47, + 0x3101c8, + 0x110e47, + 0x3111ca, + 0x31188b, + 0x20c4c8, + 0x32e208, + 0x25d306, + 0x272145, + 0x33b5ca, + 0x2ecbc5, + 0x213402, + 0x2db6c7, + 0x27d046, + 0x377045, + 0x313149, + 0x27b485, + 0x1dea48, + 0x29d645, + 0x270e89, + 0x3d84c6, + 0x3407c8, + 0x31dd83, + 0x212c46, + 0x3b7086, + 0x31d845, + 0x31d849, + 0x2cee49, + 0x271ec7, + 0x120d84, + 0x320d87, + 0x3e8189, + 0x228405, + 0x418c8, + 0x379cc5, + 0x3a14c5, + 0x36bc09, + 0x202cc2, + 0x35a344, + 0x204542, + 0x202642, + 0x2ffc05, + 0x351748, + 0x2cc145, + 0x2da043, + 0x2da045, + 0x2e5d83, + 0x212202, + 0x333544, + 0x36a603, 0x200a82, - 0x2c1704, - 0x308c43, - 0x204ac2, - 0x2c7bc3, - 0x213984, - 0x306843, - 0x253cc4, - 0x207742, - 0x216883, - 0x218e43, - 0x2018c2, - 0x25cdc2, - 0x2ca6c9, - 0x208f02, - 0x291bc4, - 0x208742, - 0x3a9e44, - 0x229404, - 0x22aac4, - 0x2072c2, - 0x23d882, - 0x32aa83, - 0x26ac43, - 0x270184, - 0x2c7504, - 0x2ecac4, - 0x2fcc44, - 0x3210c3, - 0x35ce03, - 0x2dd204, - 0x3252c4, - 0x325406, - 0x226642, - 0x12402, - 0x41d83, - 0x212402, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x110c5, + 0x2c4d84, + 0x318f43, + 0x203482, + 0x269503, + 0x2307c4, + 0x3093c3, + 0x25be04, + 0x201ec2, + 0x21f5c3, + 0x214a83, + 0x202d82, + 0x352902, + 0x2cec89, + 0x204942, + 0x296884, + 0x21ef42, + 0x2603c4, + 0x213284, + 0x2d7284, + 0x204a42, + 0x247e02, + 0x35d143, + 0x2a2683, + 0x291704, + 0x2e1184, + 0x307fc4, + 0x31fe44, + 0x31d303, + 0x208f03, + 0x3014c4, + 0x322cc4, + 0x322e06, + 0x229782, + 0x16542, + 0x4ab43, + 0x216542, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x14c45, 0x2000c2, - 0x24ac43, - 0x22ea43, - 0x233fc3, - 0x203983, - 0x266a83, - 0x20e704, - 0x2ca984, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x216983, - 0x3010c4, - 0x32f643, - 0x2b0743, - 0x380784, - 0x37e046, - 0x20ebc3, - 0x146bc5, - 0x178d87, - 0x226dc3, - 0x6ee10c08, - 0x24cbc3, - 0x2c1183, - 0x21df43, - 0x215f83, - 0x3c7985, - 0x1ba6c3, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x210043, - 0x230743, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x2191c3, - 0x217fc3, - 0x2878c4, - 0x1c0443, - 0x23e083, - 0x25d244, - 0x146bc5, - 0x2ce8c5, - 0x178d87, - 0x212402, - 0x204542, + 0x253c43, + 0x216543, + 0x222bc3, + 0x206203, + 0x343b43, + 0x2b1b84, + 0x2cef44, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x21f6c3, + 0x305b04, + 0x20bc43, + 0x21bcc3, + 0x37dc04, + 0x379ac6, + 0x2079c3, + 0x146c05, + 0xb46c7, + 0x203643, + 0x7aa176c8, + 0x209a43, + 0x2c45c3, + 0x24c243, + 0x233243, + 0x3c2545, + 0xcd43, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x212343, + 0x203e43, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x243543, + 0x2296c3, + 0x28ea04, + 0x7ca83, + 0x20cb83, + 0x2cce44, + 0x146c05, + 0x2d3605, + 0xb46c7, + 0x216542, + 0x2104c2, 0x200382, - 0x203182, - 0x5803, + 0x204cc2, + 0xd903, 0x2003c2, - 0x157c44, - 0x22ea43, - 0x236704, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x21e484, - 0x217fc3, - 0x5803, - 0x23e083, - 0x208503, - 0x24cd44, - 0xae888, - 0x22ea43, - 0x205803, - 0x10103, - 0x126d84, - 0x241ec4, - 0xae888, - 0x22ea43, - 0x24d704, - 0x20e704, - 0x205803, - 0x209282, - 0x1c0443, - 0x23e083, - 0x235403, - 0xddf84, - 0x37b845, - 0x22dc42, - 0x32a143, - 0x2149, - 0xe7546, - 0x17e348, + 0x12dc04, + 0x216543, + 0x23ec84, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x21b544, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x202b03, + 0x25dd04, + 0x793c8, + 0x216543, + 0x20d903, + 0x1a143, + 0x11a5c4, + 0x21d684, + 0x793c8, + 0x16542, + 0x216543, + 0x256d44, + 0x2b1b84, + 0x20d903, + 0x203c82, + 0x7ca83, + 0x20cb83, + 0x24c343, + 0xd1984, + 0x355b45, + 0x213402, + 0x323543, + 0x10e689, + 0xebd86, + 0x1c4688, 0x2000c2, - 0xae888, - 0x212402, - 0x233fc3, - 0x266a83, + 0x793c8, + 0x216542, + 0x222bc3, + 0x343b43, 0x2005c2, - 0x5803, - 0x23e083, - 0xa882, + 0xd903, + 0x20cb83, + 0xfe02, 0x82, 0xc2, - 0x1c9e47, - 0x14b509, - 0x3043, - 0xae888, - 0x10bec3, - 0x72727c47, - 0x2ea43, - 0xaf88, - 0x33fc3, - 0x66a83, - 0x3fec6, - 0x191c3, - 0x56288, - 0xd0ac8, - 0x7dec6, - 0x729a7285, - 0x3cb03, - 0xdb008, - 0x3fa83, - 0x72cedbc6, - 0xf2ec5, - 0x124d04, - 0x341c7, - 0x17fc3, - 0x3443, - 0x3e083, - 0x1b02, - 0x182c8a, - 0x9c43, - 0x732c3f4c, - 0x120303, - 0x5d884, - 0x11af8b, - 0x11b548, - 0x95f42, - 0x17ff03, - 0x1454747, - 0x15b4247, - 0x14d5248, - 0x157ff03, - 0x18b7c8, - 0x156ecb, - 0x10382, - 0x131247, - 0x181584, + 0x1cc547, + 0x14a709, + 0x3a43, + 0x793c8, + 0x17d0c3, + 0x7e3e71c7, + 0x16543, + 0x10508, + 0x22bc3, + 0x143b43, + 0x432c6, + 0x43543, + 0x15d8c8, + 0xd5c08, + 0x1c1ac3, + 0x83646, + 0x7e5a9d85, + 0x16443, + 0x98e48, + 0xdfc08, + 0x103d03, + 0x7e8ef3c6, + 0xf3585, + 0x1a1dc4, + 0x3c787, + 0x296c3, + 0x4f83, + 0xcb83, + 0x4642, + 0x15b0ca, + 0xc205, + 0x7303, + 0x7eed308c, + 0xffcc3, + 0x10ba84, + 0x11ac8b, + 0x11b248, + 0x15d184, + 0x9a402, + 0x4b343, + 0x145fdc7, + 0x157a147, + 0x14da108, + 0x144b343, + 0x1c4b88, + 0x1ad30b, + 0x14182, + 0x132747, + 0x114bc4, 0x2000c2, - 0x212402, - 0x236704, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x215f83, - 0x217fc3, - 0x23e083, - 0x20d403, - 0x208503, - 0xe783, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, + 0x216542, + 0x23ec84, + 0x343b43, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x233243, + 0x2296c3, + 0x20cb83, + 0x204683, + 0x202b03, + 0x39fc3, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, 0x602, - 0x10103, - 0x66a83, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x215f83, - 0x217fc3, - 0x23e083, - 0x21fcc2, + 0x1a143, + 0x143b43, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x233243, + 0x2296c3, + 0x20cb83, + 0x22a042, 0x2000c1, 0x2000c2, 0x200201, - 0x337f82, - 0xae888, - 0x21aa05, + 0x338b82, + 0x793c8, + 0x224545, 0x200101, - 0x2ea43, - 0x319c4, + 0x16543, + 0x3a304, 0x201381, 0x200501, 0x201281, - 0x248442, - 0x38e084, - 0x248443, + 0x251242, + 0x251244, + 0x251943, 0x200041, 0x200801, 0x200181, + 0x18ab06, 0x200701, - 0x35c3c7, - 0x30fccf, - 0x39af46, + 0x30d307, + 0x312d8f, + 0x399086, 0x2004c1, - 0x326dc6, + 0x31a606, 0x200bc1, 0x200581, - 0x3de50e, + 0x3e61ce, 0x2003c1, - 0x23e083, + 0x20cb83, 0x200a81, - 0x32b305, - 0x201b02, - 0x243bc5, + 0x3a8d85, + 0x204642, + 0x24d905, 0x200401, 0x200741, 0x2007c1, - 0x22dc42, + 0x213402, 0x200081, - 0x207d01, - 0x20a8c1, - 0x202341, - 0x201c41, - 0x51709, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x217c83, - 0x22ea43, - 0x266a83, - 0x95e88, - 0x23cb03, - 0x217fc3, - 0x91043, - 0x23e083, - 0x76ef8008, - 0x1e0f83, - 0xff48, - 0x10402, - 0xb9c3, - 0x293c2, - 0x72c2, - 0x146bc5, - 0xae888, - 0x11fe87, - 0x5803, - 0x146bc5, - 0x175d84, - 0x7f448, - 0x46d04, - 0x17fe07, - 0x1c4104, - 0xd5e45, - 0x51709, - 0x1424c7, - 0x5aa4a, - 0x14f800a, - 0xae888, - 0x1c0443, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x233f03, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x2e5904, - 0x23e083, - 0x24a845, - 0x27e1c4, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20b982, - 0x217fc3, - 0x23e083, - 0x8503, - 0xaefca, - 0xea706, - 0x11fa04, - 0x1268c6, - 0x24ac43, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x217fc3, - 0x23e083, - 0x212402, - 0x22ea43, - 0x231f49, - 0x233fc3, - 0x2ac549, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x81004, - 0x5803, - 0x23e083, - 0x3008c8, - 0x239307, - 0x37b845, - 0xde248, - 0x1d6e08, - 0x1c9e47, - 0xf9cca, - 0x7650b, - 0x127007, - 0x40488, - 0x7f70a, - 0x25e48, - 0x14b509, - 0x25887, - 0x14dcc7, - 0x1b5208, - 0xaf88, - 0x4164f, - 0xa6845, - 0x148647, - 0x3fec6, - 0x36487, - 0x12ea86, - 0x56288, - 0x9a346, - 0x17dc87, - 0x1c1989, - 0x1cd6c7, - 0x19c009, - 0xc9049, - 0xce646, - 0xd0ac8, - 0xde505, - 0x8350a, - 0xdb008, - 0x3fa83, - 0xe2988, - 0x341c7, - 0x156b05, - 0x61950, - 0x3443, - 0x1c0443, - 0x17db07, - 0x2cd05, - 0xfb388, - 0x6db85, - 0x120303, - 0x1d1048, - 0xb2c06, - 0x33249, - 0xb6f47, - 0x240b, - 0x72344, - 0x113c44, - 0x11af8b, - 0x11b548, - 0x11be07, - 0x146bc5, - 0x22ea43, - 0x233fc3, - 0x280203, - 0x23e083, - 0x23e883, - 0x266a83, - 0x1c0443, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0x1b1e8b, + 0x201641, + 0x207281, + 0x2024c1, + 0x208481, + 0x5c549, + 0x793c8, + 0x216543, + 0x222bc3, + 0xac1c8, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x2203c3, + 0x2f43, + 0x216543, + 0x343b43, + 0x9a348, + 0x216443, + 0x2296c3, + 0x91c43, + 0x20cb83, + 0x82a99048, + 0x1e9343, + 0x12248, + 0xcd42, + 0x3c43, + 0x13242, + 0x4a42, + 0x146c05, + 0x793c8, + 0x9fb06, + 0x15edc7, + 0xd903, + 0x146c05, + 0x171684, + 0x1cdf88, + 0x4f344, + 0x106a47, + 0x60244, + 0xb1c0c, + 0x1db944, + 0xdaf45, + 0x5c549, + 0x16e507, + 0x28846, + 0x191ca, + 0x14f990a, + 0x793c8, + 0x7ca83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x203b43, + 0x793c8, + 0x216543, + 0x222bc3, + 0x2e8fc4, + 0x20cb83, + 0x2655c5, + 0x2484c4, + 0x216543, + 0x222bc3, + 0x343b43, + 0x201582, + 0x2296c3, + 0x20cb83, + 0x2b03, + 0xedac6, + 0x12f6c4, + 0x124c46, + 0x253c43, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2296c3, + 0x20cb83, + 0x216542, + 0x216543, + 0x23a889, + 0x222bc3, + 0x2b79c9, + 0x343b43, + 0x216443, + 0x2296c3, + 0x84e04, + 0xd903, + 0x20cb83, + 0x305308, + 0x3e2687, + 0x355b45, + 0xd3a48, + 0x1db108, + 0x1cc547, + 0xfe30a, + 0x1c790b, + 0x11a847, + 0x48f08, + 0xf4a0a, + 0x26888, + 0x14a709, + 0x2f547, + 0x1ed87, + 0x10efc8, + 0x10508, + 0x4a2cf, + 0xaad45, + 0x1fc47, + 0x432c6, + 0x14cd47, + 0x130286, + 0x15d8c8, + 0xa3706, + 0x1405c7, + 0x1798c9, + 0x1df3c7, + 0xc6d09, + 0xcd749, + 0xd3386, + 0xd5c08, + 0xd3d05, + 0x86f4a, + 0xdfc08, + 0x103d03, + 0xe6008, + 0x3c787, + 0x133485, + 0x649d0, + 0x4f83, + 0x7ca83, + 0x179747, + 0x2d445, + 0xffa48, + 0x74505, + 0xffcc3, + 0x1a3108, + 0x1a1386, + 0x9ec09, + 0xba247, + 0x10e94b, + 0x77a04, + 0x113b84, + 0x11ac8b, + 0x11b248, + 0x11bb07, + 0x146c05, + 0x216543, + 0x222bc3, + 0x2f5503, + 0x20cb83, + 0x248783, + 0x343b43, + 0x7ca83, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x9c1cb, 0x2000c2, - 0x212402, - 0x23e083, + 0x216542, + 0x20cb83, 0xd42, - 0xb982, - 0x83c2, - 0xae888, - 0x1357c9, - 0x18b7c8, - 0x12402, + 0x1582, + 0x1642, + 0x793c8, + 0x1b7409, + 0x1c4b88, + 0x16542, 0x2000c2, - 0x212402, + 0x216542, 0x200382, 0x2005c2, - 0x204482, - 0x217fc3, - 0x14a9c6, + 0x202042, + 0x2296c3, + 0x148ec6, 0x2003c2, - 0xddf84, + 0xd1984, 0x2000c2, - 0x24ac43, - 0x212402, - 0x22ea43, - 0x233fc3, + 0x253c43, + 0x216542, + 0x216543, + 0x222bc3, 0x200382, - 0x266a83, - 0x2191c3, - 0x23cb03, - 0x21e484, - 0x217fc3, - 0x213cc3, - 0x5803, - 0x23e083, - 0x25d884, - 0x20aa43, - 0x266a83, - 0x212402, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x205803, - 0x23e083, - 0x3c48c7, - 0x22ea43, - 0x282e87, - 0x394e06, - 0x208483, - 0x20fa03, - 0x266a83, - 0x204903, - 0x20e704, - 0x28f784, - 0x32bac6, - 0x208243, - 0x217fc3, - 0x23e083, - 0x24a845, - 0x2b21c4, - 0x3283c3, - 0x356703, - 0x2d6807, - 0x355f05, - 0x1d03, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x23cb03, - 0x217fc3, - 0x75504, - 0x23e083, - 0x16d43, - 0x7e308dcc, - 0x4e803, - 0x192c07, - 0xe6946, - 0x19dfc7, - 0x157585, - 0x222b02, - 0x23de83, - 0x20c5c3, - 0x24ac43, - 0x7ee2ea43, - 0x204302, - 0x233fc3, - 0x2033c3, - 0x266a83, - 0x20e704, - 0x3433c3, - 0x22d703, - 0x23cb03, - 0x21e484, - 0x7f216102, - 0x217fc3, - 0x23e083, - 0x204ac3, - 0x219243, - 0x218043, - 0x21fcc2, - 0x20aa43, - 0xae888, - 0x266a83, - 0x10103, - 0x215d84, - 0x24ac43, - 0x212402, - 0x22ea43, - 0x236704, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x2191c3, - 0x33f584, - 0x217544, - 0x2e4806, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x216983, - 0x269f86, - 0x3a9cb, - 0x36fc6, - 0xbd84a, - 0x11f48a, - 0xae888, - 0x215e84, - 0x8062ea43, - 0x37e504, - 0x233fc3, - 0x296d84, - 0x266a83, - 0x2f4c43, - 0x23cb03, - 0x217fc3, - 0x1c0443, - 0x23e083, - 0x54543, - 0x34a60b, - 0x3cf9ca, - 0x3e0a8c, - 0xee488, + 0x343b43, + 0x243543, + 0x216443, + 0x21b544, + 0x2296c3, + 0x20b243, + 0xd903, + 0x20cb83, + 0x30ba84, + 0x201643, + 0x343b43, + 0x216542, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0x20d903, + 0x20cb83, + 0x3c5747, + 0x216543, + 0x2868c7, + 0x3823c6, + 0x209843, + 0x21a003, + 0x343b43, + 0x20e443, + 0x2b1b84, + 0x243544, + 0x3d66c6, + 0x202803, + 0x2296c3, + 0x127f0b, + 0x20cb83, + 0x2655c5, + 0x2f7184, + 0x3b6703, + 0x343483, + 0x2db6c7, + 0x2f6985, + 0x1a1003, + 0x216543, + 0x222bc3, + 0x343b43, + 0x216443, + 0x2296c3, + 0x1c1184, + 0x20cb83, + 0x1fa83, + 0x89f0b24c, + 0x58083, + 0x4bc47, + 0x80dc6, + 0x120047, + 0x133d85, + 0x205242, + 0x246dc3, + 0x211d43, + 0x253c43, + 0x8aa16543, + 0x2080c2, + 0x222bc3, + 0x204f03, + 0x343b43, + 0x2b1b84, + 0x34b203, + 0x27b903, + 0x216443, + 0x21b544, + 0x8ae06c02, + 0x2296c3, + 0x20cb83, + 0x20e603, + 0x209203, + 0x2883c3, + 0x22a042, + 0x201643, + 0x793c8, + 0x343b43, + 0x1a143, + 0x258bc4, + 0x253c43, + 0x216542, + 0x216543, + 0x23ec84, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x243543, + 0x239104, + 0x28d4c4, + 0x2e8306, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x21f6c3, + 0x27d046, + 0x4290b, + 0x32f46, + 0xb6c0a, + 0x11faca, + 0x793c8, + 0x22f004, + 0x8c216543, + 0x32c744, + 0x222bc3, + 0x219a44, + 0x343b43, + 0x284103, + 0x216443, + 0x2296c3, + 0x7ca83, + 0x20cb83, + 0x31c03, + 0x348b0b, + 0x3d368a, + 0x3e8e4c, + 0xefc08, 0x2000c2, - 0x212402, + 0x216542, 0x200382, - 0x22f845, - 0x20e704, - 0x20b982, - 0x23cb03, - 0x217544, - 0x203182, + 0x2b96c5, + 0x2b1b84, + 0x201582, + 0x216443, + 0x28d4c4, + 0x204cc2, 0x2003c2, - 0x208502, - 0x21fcc2, - 0x4ac43, - 0xcdc2, - 0x2d0e89, - 0x36c648, - 0x266909, - 0x213d49, - 0x2184ca, - 0x30aaca, - 0x209482, - 0x361e82, - 0x12402, - 0x22ea43, - 0x22c982, - 0x241546, - 0x37c682, - 0x2013c2, - 0x27688e, - 0x2168ce, - 0x217f47, - 0x211c42, - 0x233fc3, - 0x266a83, - 0x20f342, + 0x202b02, + 0x22a042, + 0x53c43, + 0x4042, + 0x2d5fc9, + 0x278a08, + 0x3d8a09, + 0x39d3c9, + 0x2116ca, + 0x21424a, + 0x208d02, + 0x22e702, + 0x16542, + 0x216543, + 0x213b02, + 0x24a1c6, + 0x378742, + 0x47402, + 0x201442, + 0x3c7c8e, + 0x21f60e, + 0x3d1b47, + 0x219cc2, + 0x222bc3, + 0x343b43, + 0x20bac2, 0x2005c2, - 0xe703, - 0x23690f, - 0x241882, - 0x2c3587, - 0x2ec3c7, - 0x2de787, - 0x2e2b4c, - 0x2f024c, - 0x21f844, - 0x39334a, - 0x216802, - 0x206902, - 0x2cac84, + 0x6a7c3, + 0x23ee8f, + 0x21ee02, + 0x2eae47, + 0x2e2587, + 0x2e61c7, + 0x2f0e4c, + 0x2f2e0c, + 0x258884, + 0x28c28a, + 0x21f542, + 0x207bc2, + 0x2cf304, 0x200702, - 0x2c23c2, - 0x2f0484, - 0x214882, - 0x202702, - 0x1e1c3, - 0x29a3c7, - 0x30eac5, - 0x204202, - 0x236404, - 0x393b42, - 0x2edd48, - 0x217fc3, - 0x37b588, - 0x203242, - 0x21fa05, - 0x39da86, - 0x23e083, - 0x204fc2, - 0x2fc207, - 0x1b02, - 0x34bbc5, - 0x3dce85, - 0x20b502, - 0x206c82, - 0x34754a, - 0x28de4a, - 0x23cac2, - 0x2a39c4, + 0x2d8882, + 0x2f3044, + 0x21ab82, + 0x209d42, + 0x1b283, + 0x2a3787, + 0x288345, + 0x2205c2, + 0x319f04, + 0x30f082, + 0x2ef548, + 0x2296c3, + 0x3773c8, + 0x204d82, + 0x258a45, + 0x39b086, + 0x20cb83, + 0x2059c2, + 0x300947, + 0x4642, + 0x2504c5, + 0x203505, + 0x201782, + 0x207f02, + 0x3cfd8a, + 0x27c68a, + 0x279c42, + 0x2a94c4, 0x200f02, - 0x21dd88, - 0x207ac2, - 0x31c248, - 0x1501, - 0x316b47, - 0x3175c9, - 0x2bb102, - 0x31d505, - 0x36ed45, - 0x212acb, - 0x32c04c, - 0x22c488, - 0x331088, - 0x226642, - 0x2af242, + 0x271148, + 0x20e002, + 0x2b4bc8, + 0x17c1, + 0x316887, + 0x3174c9, + 0x203582, + 0x31c385, + 0x372b05, + 0x3d088b, + 0x3d6c4c, + 0x237288, + 0x332588, + 0x229782, + 0x259342, 0x2000c2, - 0xae888, - 0x212402, - 0x22ea43, + 0x793c8, + 0x216542, + 0x216543, 0x200382, - 0x203182, - 0x5803, + 0x204cc2, + 0xd903, 0x2003c2, - 0x23e083, - 0x208502, + 0x20cb83, + 0x202b02, 0x2000c2, - 0x146bc5, - 0x81a12402, - 0x108f04, - 0x37e05, - 0x82a66a83, - 0x21e1c3, - 0x20b982, - 0x217fc3, - 0x3d6203, - 0x82e3e083, - 0x2f8e43, - 0x27a906, - 0x1608503, - 0x146bc5, - 0x14a88b, - 0xae888, - 0x81f64008, - 0x68f47, - 0x822c6aca, - 0x74d87, - 0x1b5a05, - 0x82600f89, - 0x2c10d, - 0x3fcc2, - 0x11bb42, + 0x146c05, + 0x8d616542, + 0x10b384, + 0x405c5, + 0x8e743b43, + 0x21b283, + 0x201582, + 0x2296c3, + 0x3e8603, + 0x8ea0cb83, + 0x2faf43, + 0x2dc2c6, + 0xf57c5, + 0x1602b03, + 0x146c05, + 0x148d8b, + 0x793c8, + 0x8dbb6d08, + 0x6be87, + 0x8deca7ca, + 0x791c7, + 0x10f7c5, + 0x8e200f89, + 0x2f20d, + 0x430c2, + 0x11b842, 0xe01, - 0x107784, - 0xb018a, - 0x8dc87, - 0x10bb84, - 0x3ca03, - 0x3ca04, - 0x83603d82, - 0x83a00ac2, - 0x83e03502, - 0x84202e42, - 0x846074c2, - 0x84a0cf02, - 0x178d87, - 0x84e12402, - 0x85211d02, - 0x8561c782, - 0x85a0f982, - 0x2168c3, - 0x1ff44, - 0x28c543, - 0x85e12882, - 0x5a388, - 0x86207c82, - 0x4e007, - 0x1b77c7, - 0x86600042, - 0x86a00d82, - 0x86e00182, - 0x87209582, - 0x8760f782, - 0x87a005c2, - 0xfdd45, - 0x24dc03, - 0x3612c4, - 0x87e00702, - 0x8820a342, - 0x88601582, - 0x8d64b, - 0x88a00c42, - 0x89206a02, - 0x8960b982, - 0x89a04482, - 0x89e15782, - 0x8a200bc2, - 0x8a60a942, - 0x8aa720c2, - 0x8ae16102, - 0x8b201602, - 0x8b603182, - 0x8ba37282, - 0x8be05402, - 0x8c209ec2, - 0x1583c4, - 0x3169c3, - 0x8c634e42, - 0x8ca0f442, - 0x8ce03742, - 0x8d2006c2, - 0x8d6003c2, - 0x8da00a82, - 0xf8908, - 0x1b2007, - 0x8de16982, - 0x8e205302, - 0x8e608502, - 0x8ea0a1c2, - 0x1b800c, - 0x8ee03d02, - 0x8f224e42, - 0x8f601942, - 0x8fa034c2, - 0x8fe0e482, - 0x90203b02, - 0x90607d02, - 0x90a16382, - 0x90e7bcc2, - 0x9127c2c2, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x88f433c3, - 0x2220c3, - 0x3c7a04, - 0x266806, - 0x307183, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x26e9c9, - 0x20cdc2, - 0x3b3843, - 0x2c9343, - 0x260045, - 0x2033c3, - 0x3433c3, - 0x2220c3, - 0x2b8a83, - 0x20de03, - 0x3679c9, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x20cdc2, - 0x20cdc2, - 0x3433c3, - 0x2220c3, - 0x91a2ea43, - 0x233fc3, - 0x213f83, - 0x23cb03, - 0x217fc3, - 0x5803, - 0x23e083, - 0xae888, - 0x212402, - 0x22ea43, - 0x217fc3, - 0x23e083, - 0x6e842, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x924f6e82, - 0x23cb03, - 0x217fc3, - 0x5803, - 0x23e083, + 0xe91c4, + 0xb530a, + 0x7c4c7, + 0x30044, + 0x30083, + 0x30084, + 0x8f201f02, + 0x8f600ac2, + 0x8fa03b42, + 0x8fe030c2, + 0x90208742, + 0x90604182, + 0xb46c7, + 0x90a16542, + 0x90e19d82, + 0x9121d802, + 0x91603242, + 0x21f603, + 0x2a2c4, + 0x91aac1c8, + 0x213643, + 0x91e18902, + 0x68508, + 0x92204982, + 0x63187, + 0x1b88c7, + 0x92600042, + 0x92a00d82, + 0x92e00182, + 0x932042c2, + 0x93605502, + 0x93a005c2, + 0x11f405, + 0x20af03, + 0x2f44c4, + 0x93e00702, + 0x94211b82, + 0x94605542, + 0x92b8b, + 0x94a00c42, + 0x95256e02, + 0x95601582, + 0x95a02042, + 0x98e48, + 0x95e28882, + 0x96200bc2, + 0x96603742, + 0x96a77782, + 0x96e06c02, + 0x97205782, + 0x97604cc2, + 0x97a18f02, + 0x97e0d502, + 0x9820f502, + 0xac8c4, + 0x332ec3, + 0x9863d1c2, + 0x98a0bbc2, + 0x98e0cfc2, + 0x992006c2, + 0x996003c2, + 0x99a00a82, + 0xfa6c8, + 0x9c347, + 0x99e037c2, + 0x9a202a82, + 0x9a602b02, + 0x9aa0a0c2, + 0x176a8c, + 0x9ae2bdc2, + 0x9b22ce82, + 0x9b602e02, + 0x9ba05002, + 0x9be08e42, + 0x9c211842, + 0x9c6089c2, + 0x9ca13342, + 0x9ce81202, + 0x9d281742, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x207c3, + 0xd2443, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x94f4b203, + 0x2207c3, + 0x3c25c4, + 0x3d8906, + 0x309a43, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x35c349, + 0x204042, + 0x271c43, + 0x2cda43, + 0x3b6945, + 0x204f03, + 0x34b203, + 0x2207c3, + 0x2e69c3, + 0x22e683, + 0x3ca009, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x34b203, + 0x2207c3, + 0x204042, + 0x204042, + 0x34b203, + 0x2207c3, + 0x9da16543, + 0x222bc3, + 0x39d603, + 0x216443, + 0x2296c3, + 0xd903, + 0x20cb83, + 0x793c8, + 0x216542, + 0x216543, + 0x2296c3, + 0x20cb83, + 0x145842, + 0x216543, + 0x222bc3, + 0x343b43, + 0x9e51d0c2, + 0x216443, + 0x2296c3, + 0xd903, + 0x20cb83, 0x1381, - 0x241ec4, - 0x212402, - 0x22ea43, + 0x21d684, + 0x216542, + 0x216543, 0x200983, - 0x233fc3, - 0x24d704, - 0x280203, - 0x266a83, - 0x20e704, - 0x2191c3, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0x235403, - 0x37b845, - 0x20de03, - 0x20aa43, + 0x222bc3, + 0x256d44, + 0x2f5503, + 0x343b43, + 0x2b1b84, + 0x243543, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x24c343, + 0x355b45, + 0x22e683, + 0x201643, 0x882, - 0x5803, - 0x212402, - 0x22ea43, - 0x3433c3, - 0x217fc3, - 0x23e083, + 0xd903, + 0x216542, + 0x216543, + 0x34b203, + 0x2296c3, + 0x20cb83, 0x2000c2, - 0x24ac43, - 0xae888, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x231346, - 0x20e704, - 0x2191c3, - 0x21e484, - 0x217fc3, - 0x23e083, - 0x216983, - 0x4cc4, - 0x161e82, - 0x22ea43, - 0x22383, - 0x233fc3, - 0xb982, - 0x217fc3, - 0x23e083, - 0x30242, - 0x2a82, - 0x1481bc7, - 0x8cc7, - 0x22ea43, - 0x36fc6, - 0x233fc3, - 0x266a83, - 0xf07c6, - 0x217fc3, - 0x23e083, - 0x32d948, - 0x330ec9, - 0x341dc9, - 0x34cfc8, - 0x3a01c8, - 0x3a01c9, - 0x32748a, - 0x3657ca, - 0x399a4a, - 0x3a124a, - 0x3cf9ca, - 0x3db28b, - 0x26604d, - 0x230b0f, - 0x240950, - 0x3692cd, - 0x38384c, - 0x3a0f8b, - 0x74f88, - 0xf6cc8, - 0xbe1c5, - 0x148e8c7, - 0xd9785, + 0x253c43, + 0x793c8, + 0x216543, + 0x222bc3, + 0x343b43, + 0x239c86, + 0x2b1b84, + 0x243543, + 0x21b544, + 0x2296c3, + 0x20cb83, + 0x21f6c3, + 0xe804, + 0x2e702, + 0x216543, + 0x20a83, + 0x222bc3, + 0x1582, + 0x2296c3, + 0x20cb83, + 0x10e104, + 0x6ff44, + 0x2a02, + 0x148bb07, + 0x125887, + 0x216543, + 0x32f46, + 0x222bc3, + 0x343b43, + 0xf1386, + 0x2296c3, + 0x20cb83, + 0x32f188, + 0x3323c9, + 0x341cc9, + 0x34b688, + 0x39d208, + 0x39d209, + 0x325d0a, + 0x36084a, + 0x3979ca, + 0x39ecca, + 0x3d368a, + 0x3dfecb, + 0x2fc28d, + 0x2fcf4f, + 0x247450, + 0x3621cd, + 0x3813cc, + 0x39ea0b, + 0x16108, + 0x13ec08, + 0x18a0c5, + 0x190209, + 0x1495c87, + 0xde645, 0x2000c2, - 0x355d45, - 0x21e183, - 0x95a12402, - 0x233fc3, - 0x266a83, - 0x232b87, - 0x21df43, - 0x23cb03, - 0x217fc3, - 0x24dfc3, - 0x213cc3, - 0x210ec3, - 0x205803, - 0x23e083, - 0x2509c6, - 0x22dc42, - 0x20aa43, - 0xae888, + 0x2f67c5, + 0x209d03, + 0xa1e16542, + 0x222bc3, + 0x343b43, + 0x380b87, + 0x24c243, + 0x216443, + 0x2296c3, + 0x257743, + 0x20b243, + 0x20f1c3, + 0x20d903, + 0x20cb83, + 0x259186, + 0x213402, + 0x201643, + 0x793c8, 0x2000c2, - 0x24ac43, - 0x212402, - 0x22ea43, - 0x233fc3, - 0x266a83, - 0x20e704, - 0x23cb03, - 0x217fc3, - 0x23e083, - 0x208503, - 0x8cc7, - 0x10382, - 0x2144, - 0x1517446, + 0x253c43, + 0x216542, + 0x216543, + 0x222bc3, + 0x343b43, + 0x2b1b84, + 0x216443, + 0x2296c3, + 0x20cb83, + 0x202b03, + 0x125887, + 0x14182, + 0x10e684, + 0x1534746, 0x2000c2, - 0x212402, - 0x266a83, - 0x23cb03, - 0x23e083, + 0x216542, + 0x343b43, + 0x216443, + 0x20cb83, } // children is the list of nodes' children, the parent's wildcard bit and the @@ -9614,32 +9781,33 @@ var children = [...]uint32{ 0x40000000, 0x50000000, 0x60000000, - 0x17d05ee, - 0x17d45f4, - 0x17d85f5, - 0x17fc5f6, - 0x19545ff, - 0x196c655, - 0x198065b, - 0x1998660, - 0x19b8666, - 0x19d866e, - 0x19f0676, - 0x1a1067c, - 0x1a14684, - 0x1a3c685, - 0x1a4068f, - 0x1a58690, - 0x1a5c696, - 0x1a60697, - 0x1aa0698, - 0x1aa46a8, - 0x1aa86a9, - 0x21aac6aa, - 0x61ab46ab, - 0x21abc6ad, - 0x1b046af, - 0x1b086c1, + 0x17bc5e9, + 0x17c05ef, + 0x17c45f0, + 0x17e85f1, + 0x19405fa, + 0x1958650, + 0x196c656, + 0x198465b, + 0x19a4661, + 0x19c8669, + 0x19e0672, + 0x1a08678, + 0x1a0c682, + 0x1a34683, + 0x1a3868d, + 0x1a5068e, + 0x1a54694, + 0x1a58695, + 0x1a98696, + 0x1a9c6a6, + 0x1aa06a7, + 0x21aa46a8, + 0x61aac6a9, + 0x21ab46ab, + 0x1afc6ad, + 0x1b046bf, + 0x21b086c1, 0x1b2c6c2, 0x1b306cb, 0x1b446cc, @@ -9647,573 +9815,621 @@ var children = [...]uint32{ 0x1b686d2, 0x1b986da, 0x1bb46e6, - 0x1bdc6ed, - 0x1bec6f7, - 0x1bf06fb, - 0x1c886fc, - 0x1c9c722, - 0x1cb0727, - 0x1ce872c, - 0x1cf873a, - 0x1d0c73e, - 0x1d24743, - 0x1dc8749, - 0x1ffc772, - 0x20007ff, - 0x206c800, - 0x20d881b, - 0x20f0836, - 0x210483c, - 0x2108841, - 0x2110842, + 0x1bbc6ed, + 0x1be46ef, + 0x1bf86f9, + 0x21bfc6fe, + 0x1c006ff, + 0x1c98700, + 0x1cac726, + 0x1cc072b, + 0x1cfc730, + 0x1d0c73f, + 0x1d20743, + 0x1d38748, + 0x1ddc74e, + 0x2010777, + 0x2018804, + 0x2201c806, + 0x22020807, + 0x208c808, + 0x20f8823, + 0x211083e, 0x2124844, 0x2128849, - 0x214884a, - 0x2198852, - 0x219c866, - 0x221a0867, - 0x21c0868, + 0x213084a, + 0x214884c, + 0x214c852, + 0x2170853, + 0x21c085c, 0x21c4870, - 0x21c8871, - 0x21f0872, - 0x621f487c, - 0x223887d, - 0x223c88e, - 0x6224088f, - 0x225c890, - 0x228c897, - 0x229c8a3, - 0x22ac8a7, - 0x23608ab, - 0x23648d8, - 0x223748d9, - 0x223788dd, - 0x223808de, - 0x23d88e0, - 0x23dc8f6, - 0x23e08f7, - 0x29348f8, - 0x2938a4d, - 0x62940a4e, - 0x229e8a50, - 0x229eca7a, - 0x229f0a7b, - 0x229fca7c, - 0x22a00a7f, - 0x22a0ca80, - 0x22a10a83, - 0x22a14a84, - 0x22a18a85, - 0x22a1ca86, - 0x22a20a87, - 0x22a2ca88, - 0x22a30a8b, - 0x22a3ca8c, - 0x22a40a8f, - 0x22a44a90, - 0x22a48a91, - 0x22a54a92, - 0x22a58a95, - 0x22a64a96, - 0x22a68a99, - 0x22a6ca9a, - 0x22a70a9b, - 0x2a74a9c, - 0x22a78a9d, - 0x22a84a9e, - 0x22a88aa1, - 0x2a8caa2, - 0x2a94aa3, - 0x62aa0aa5, - 0x2ae4aa8, - 0x22b04ab9, + 0x221c8871, + 0x21e8872, + 0x21ec87a, + 0x21f087b, + 0x221c87c, + 0x62220887, + 0x22228888, + 0x2222c88a, + 0x227088b, + 0x227489c, + 0x6227889d, + 0x229489e, + 0x22e88a5, + 0x222ec8ba, + 0x222f08bb, + 0x222f88bc, + 0x222fc8be, + 0x223008bf, + 0x223048c0, + 0x230c8c1, + 0x23108c3, + 0x2231c8c4, + 0x223248c7, + 0x23348c9, + 0x23448cd, + 0x23f88d1, + 0x23fc8fe, + 0x2240c8ff, + 0x22410903, + 0x22418904, + 0x2470906, + 0x247491c, + 0x247891d, + 0x29ec91e, + 0x29f0a7b, + 0x22a98a7c, + 0x22a9caa6, + 0x22aa0aa7, + 0x22aacaa8, + 0x22ab0aab, + 0x22abcaac, + 0x22ac0aaf, + 0x22ac4ab0, + 0x22ac8ab1, + 0x22accab2, + 0x22ad0ab3, + 0x22adcab4, + 0x22ae0ab7, + 0x22aecab8, + 0x22af0abb, + 0x22af4abc, + 0x22af8abd, + 0x22b04abe, 0x22b08ac1, - 0x22b0cac2, - 0x22b10ac3, - 0x22b14ac4, - 0x22b1cac5, + 0x22b14ac2, + 0x22b18ac5, + 0x22b1cac6, 0x22b20ac7, 0x2b24ac8, - 0x22b44ac9, - 0x22b48ad1, - 0x22b4cad2, - 0x22b50ad3, - 0x22b54ad4, - 0x22b58ad5, - 0x2b60ad6, - 0x2b68ad8, - 0x2b6cada, - 0x2b88adb, - 0x2ba0ae2, + 0x22b28ac9, + 0x22b34aca, + 0x22b38acd, + 0x2b3cace, + 0x2b44acf, + 0x22b50ad1, + 0x62b5cad4, + 0x2ba0ad7, 0x2ba4ae8, - 0x2bb4ae9, - 0x2bc0aed, - 0x2bf4af0, - 0x2bfcafd, - 0x22c00aff, - 0x2c18b00, - 0x22c20b06, + 0x22bc4ae9, + 0x22bc8af1, + 0x22bccaf2, + 0x22bd4af3, + 0x22bdcaf5, + 0x22be0af7, + 0x22be4af8, + 0x22becaf9, + 0x22bf0afb, + 0x22bf4afc, + 0x2bf8afd, + 0x22c18afe, + 0x22c1cb06, + 0x22c20b07, 0x22c24b08, - 0x22c2cb09, - 0x2d28b0b, - 0x22d2cb4a, - 0x2d34b4b, - 0x2d38b4d, - 0x22d3cb4e, - 0x2d40b4f, - 0x2d68b50, - 0x2d6cb5a, - 0x2d70b5b, - 0x2d88b5c, - 0x2d9cb62, - 0x2dc4b67, - 0x2de4b71, - 0x2de8b79, - 0x62decb7a, - 0x2e20b7b, + 0x22c28b09, + 0x22c34b0a, + 0x22c38b0d, + 0x2c3cb0e, + 0x2c44b0f, + 0x2c4cb11, + 0x2c50b13, + 0x2c6cb14, + 0x2c84b1b, + 0x2c88b21, + 0x2c98b22, + 0x2ca4b26, + 0x2cd8b29, + 0x2ce0b36, + 0x22ce4b38, + 0x2cfcb39, + 0x22d04b3f, + 0x22d08b41, + 0x22d10b42, + 0x2e0cb44, + 0x22e10b83, + 0x2e18b84, + 0x2e1cb86, + 0x22e20b87, 0x2e24b88, - 0x22e28b89, - 0x2e2cb8a, - 0x2e54b8b, + 0x2e54b89, 0x2e58b95, - 0x2e7cb96, - 0x2e80b9f, - 0x2e94ba0, - 0x2e98ba5, - 0x2e9cba6, - 0x2ebcba7, - 0x2ed8baf, + 0x2e5cb96, + 0x2e74b97, + 0x2e88b9d, + 0x2eb0ba2, + 0x2ed8bac, 0x2edcbb6, - 0x22ee0bb7, - 0x2ee4bb8, - 0x2ee8bb9, - 0x2eecbba, - 0x2ef4bbb, - 0x2f08bbd, - 0x2f0cbc2, - 0x2f10bc3, - 0x2f38bc4, - 0x2f3cbce, - 0x2fb0bcf, - 0x2fb4bec, - 0x2fb8bed, - 0x2fd8bee, - 0x2ff0bf6, + 0x62ee0bb7, + 0x2f14bb8, + 0x2f18bc5, + 0x22f1cbc6, + 0x2f20bc7, + 0x2f48bc8, + 0x2f4cbd2, + 0x2f70bd3, + 0x2f74bdc, + 0x2f88bdd, + 0x2f8cbe2, + 0x2f90be3, + 0x2fb0be4, + 0x2fd4bec, + 0x22fd8bf5, + 0x22fdcbf6, + 0x2fe0bf7, + 0x22fe4bf8, + 0x2fe8bf9, + 0x2fecbfa, + 0x2ff0bfb, 0x2ff4bfc, - 0x3008bfd, - 0x3020c02, - 0x3040c08, - 0x3058c10, - 0x305cc16, - 0x3078c17, - 0x3094c1e, - 0x3098c25, - 0x30c4c26, - 0x30e4c31, - 0x3104c39, - 0x3168c41, - 0x3188c5a, - 0x31a8c62, - 0x31acc6a, - 0x31c4c6b, - 0x3208c71, - 0x3288c82, - 0x32b8ca2, - 0x32bccae, - 0x32c8caf, - 0x32e8cb2, - 0x32eccba, - 0x3310cbb, - 0x3318cc4, - 0x3354cc6, - 0x33a8cd5, - 0x33accea, - 0x33b0ceb, - 0x3494cec, - 0x2349cd25, - 0x234a0d27, - 0x234a4d28, - 0x34a8d29, - 0x234acd2a, - 0x234b0d2b, - 0x34b4d2c, - 0x234b8d2d, - 0x234c8d2e, - 0x234ccd32, - 0x234d0d33, - 0x234d4d34, - 0x234d8d35, - 0x234dcd36, - 0x34f4d37, - 0x3518d3d, - 0x3538d46, - 0x3ba4d4e, - 0x3bb0ee9, - 0x3bd0eec, - 0x3d90ef4, - 0x3e60f64, - 0x3ed0f98, - 0x3f28fb4, - 0x4010fca, - 0x4069004, - 0x40a501a, - 0x41a1029, - 0x426d068, - 0x430509b, - 0x43950c1, - 0x43f90e5, - 0x46310fe, - 0x46e918c, - 0x47b51ba, - 0x48011ed, - 0x4889200, - 0x48c5222, - 0x4915231, - 0x498d245, - 0x64991263, - 0x64995264, - 0x64999265, - 0x4a15266, - 0x4a71285, - 0x4aed29c, - 0x4b652bb, - 0x4be52d9, - 0x4c512f9, - 0x4d7d314, - 0x4dd535f, - 0x64dd9375, - 0x4e71376, - 0x4e7939c, - 0x24e7d39e, - 0x4f0539f, - 0x4f513c1, - 0x4fb93d4, - 0x50613ee, - 0x5129418, - 0x519144a, - 0x52a5464, - 0x652a94a9, - 0x652ad4aa, - 0x53094ab, - 0x53654c2, - 0x53f54d9, - 0x54714fd, - 0x54b551c, - 0x559952d, - 0x55cd566, - 0x562d573, - 0x56a158b, - 0x57295a8, - 0x57695ca, - 0x57d95da, - 0x657dd5f6, - 0x58055f7, - 0x5809601, - 0x5839602, - 0x585560e, - 0x5899615, - 0x58a9626, - 0x58c162a, - 0x5939630, - 0x594164e, - 0x595d650, - 0x5971657, - 0x598d65c, - 0x59b9663, - 0x59bd66e, - 0x59c566f, - 0x59d9671, - 0x59f9676, - 0x5a0967e, - 0x5a15682, - 0x5a51685, - 0x5a59694, - 0x5a6d696, - 0x5a9569b, - 0x5aa16a5, - 0x5aa96a8, - 0x5ad16aa, - 0x5af56b4, - 0x5b0d6bd, - 0x5b116c3, - 0x5b196c4, - 0x5b2d6c6, - 0x5bd56cb, - 0x5bd96f5, + 0x3010bfd, + 0x23014c04, + 0x2301cc05, + 0x3020c07, + 0x3048c08, + 0x305cc12, + 0x30d0c17, + 0x30dcc34, + 0x30e0c37, + 0x3100c38, + 0x3118c40, + 0x311cc46, + 0x3130c47, + 0x3148c4c, + 0x3168c52, + 0x3180c5a, + 0x3188c60, + 0x31a4c62, + 0x31c0c69, + 0x31c4c70, + 0x31f0c71, + 0x3210c7c, + 0x3230c84, + 0x3298c8c, + 0x32b8ca6, + 0x32d8cae, + 0x32dccb6, + 0x32f4cb7, + 0x3338cbd, + 0x33b8cce, + 0x33f4cee, + 0x33f8cfd, + 0x3404cfe, + 0x3424d01, + 0x3428d09, + 0x344cd0a, + 0x3454d13, + 0x3494d15, + 0x34e8d25, + 0x34ecd3a, + 0x34f0d3b, + 0x35e4d3c, + 0x235ecd79, + 0x235f0d7b, + 0x235f4d7c, + 0x35f8d7d, + 0x235fcd7e, + 0x23600d7f, + 0x23604d80, + 0x3608d81, + 0x2360cd82, + 0x2361cd83, + 0x23620d87, + 0x23624d88, + 0x23628d89, + 0x2362cd8a, + 0x23638d8b, + 0x2363cd8e, + 0x3654d8f, + 0x3678d95, + 0x3698d9e, + 0x3d0cda6, + 0x23d10f43, + 0x23d14f44, + 0x23d18f45, + 0x23d1cf46, + 0x3d2cf47, + 0x3d4cf4b, + 0x3f0cf53, + 0x3fdcfc3, + 0x404cff7, + 0x40a5013, + 0x418d029, + 0x41e5063, + 0x4221079, + 0x431d088, + 0x43e90c7, + 0x44810fa, + 0x4511120, + 0x4575144, + 0x47ad15d, + 0x48651eb, + 0x4931219, + 0x497d24c, + 0x4a0525f, + 0x4a41281, + 0x4a91290, + 0x4b092a4, + 0x64b0d2c2, + 0x64b112c3, + 0x64b152c4, + 0x4b912c5, + 0x4bed2e4, + 0x4c692fb, + 0x4ce131a, + 0x4d61338, + 0x4dcd358, + 0x4ef9373, + 0x4f513be, + 0x64f553d4, + 0x4fed3d5, + 0x4ff53fb, + 0x24ff93fd, + 0x50813fe, + 0x50cd420, + 0x5135433, + 0x51dd44d, + 0x52a5477, + 0x530d4a9, + 0x54214c3, + 0x65425508, + 0x65429509, + 0x548550a, + 0x54e1521, + 0x5571538, + 0x55ed55c, + 0x563157b, + 0x571558c, + 0x57495c5, + 0x57a95d2, + 0x581d5ea, + 0x58a5607, + 0x58e5629, + 0x5955639, + 0x65959655, + 0x5981656, + 0x5985660, + 0x59b5661, + 0x59d166d, + 0x5a15674, + 0x5a25685, + 0x5a3d689, + 0x5ab568f, + 0x5abd6ad, + 0x5ad96af, + 0x5aed6b6, + 0x5b116bb, + 0x25b156c4, + 0x5b416c5, + 0x5b456d0, + 0x5b4d6d1, + 0x5b616d3, + 0x5b816d8, + 0x5b916e0, + 0x5b9d6e4, + 0x5bd96e7, 0x5bdd6f6, - 0x5be16f7, - 0x5c056f8, - 0x5c29701, - 0x5c4570a, - 0x5c59711, - 0x5c6d716, - 0x5c7571b, - 0x5c7d71d, - 0x5c8571f, - 0x5c9d721, - 0x5cad727, - 0x5cb172b, - 0x5ccd72c, - 0x6555733, - 0x658d955, - 0x65b9963, - 0x65d596e, - 0x65f5975, - 0x661597d, - 0x6659985, - 0x6661996, - 0x26665998, - 0x26669999, - 0x667199a, - 0x687199c, - 0x26875a1c, - 0x6879a1d, - 0x2687da1e, - 0x2688da1f, - 0x26895a23, - 0x268a1a25, - 0x68a5a28, - 0x268a9a29, - 0x268b1a2a, - 0x68b9a2c, - 0x68c9a2e, - 0x68f1a32, - 0x692da3c, - 0x6931a4b, - 0x6969a4c, - 0x698da5a, - 0x74e5a63, - 0x74e9d39, - 0x74edd3a, - 0x274f1d3b, - 0x74f5d3c, - 0x274f9d3d, - 0x74fdd3e, - 0x27509d3f, - 0x750dd42, - 0x7511d43, - 0x27515d44, - 0x7519d45, - 0x27521d46, - 0x7525d48, - 0x7529d49, - 0x27539d4a, - 0x753dd4e, - 0x7541d4f, - 0x7545d50, - 0x7549d51, - 0x2754dd52, - 0x7551d53, - 0x7555d54, - 0x7559d55, - 0x755dd56, - 0x27565d57, - 0x7569d59, - 0x756dd5a, - 0x7571d5b, - 0x27575d5c, - 0x7579d5d, - 0x27581d5e, - 0x27585d60, - 0x75a1d61, - 0x75b9d68, - 0x75fdd6e, - 0x7601d7f, - 0x7625d80, - 0x7631d89, - 0x7635d8c, - 0x7639d8d, - 0x77fdd8e, - 0x27801dff, - 0x27809e00, - 0x2780de02, - 0x27811e03, - 0x7819e04, - 0x78f5e06, - 0x27901e3d, - 0x27905e40, - 0x27909e41, - 0x2790de42, - 0x7911e43, - 0x793de44, - 0x7949e4f, - 0x794de52, - 0x7971e53, - 0x797de5c, - 0x799de5f, - 0x79a1e67, - 0x79d9e68, - 0x7c89e76, - 0x7d45f22, - 0x7d49f51, - 0x7d4df52, - 0x7d61f53, - 0x7d65f58, - 0x7d99f59, - 0x7dd1f66, - 0x27dd5f74, - 0x7df1f75, - 0x7e19f7c, - 0x7e1df86, - 0x7e41f87, - 0x7e5df90, - 0x7e85f97, - 0x7e95fa1, - 0x7e99fa5, - 0x7e9dfa6, - 0x7ed5fa7, - 0x7ee1fb5, - 0x7f09fb8, - 0x7f95fc2, - 0x27f99fe5, - 0x7f9dfe6, - 0x7fadfe7, - 0x27fb1feb, - 0x7fc1fec, - 0x7fddff0, - 0x7ffdff7, - 0x8001fff, - 0x8016000, - 0x802a005, - 0x802e00a, - 0x803200b, - 0x803600c, - 0x805600d, - 0x80fe015, - 0x810203f, - 0x811e040, - 0x8146047, - 0x28156051, - 0x815a055, - 0x8166056, - 0x8192059, - 0x819a064, - 0x81ae066, - 0x81ce06b, - 0x81ea073, - 0x81fa07a, - 0x821207e, - 0x824a084, - 0x824e092, - 0x8322093, - 0x83260c8, - 0x833a0c9, - 0x83420ce, - 0x835a0d0, - 0x835e0d6, - 0x836a0d7, - 0x83760da, - 0x837a0dd, - 0x83820de, - 0x83860e0, - 0x83aa0e1, - 0x83ea0ea, - 0x83ee0fa, - 0x840e0fb, - 0x845e103, - 0x848e117, - 0x28492123, - 0x849a124, - 0x84f2126, - 0x84f613c, - 0x84fa13d, - 0x84fe13e, - 0x854213f, - 0x8552150, - 0x8592154, - 0x8596164, - 0x85c6165, - 0x870e171, - 0x87361c3, - 0x876e1cd, - 0x87961db, - 0x2879e1e5, - 0x287a21e7, - 0x287a61e8, - 0x87ae1e9, - 0x87ba1eb, - 0x88d61ee, - 0x88e2235, - 0x88ee238, - 0x88fa23b, - 0x890623e, - 0x8912241, - 0x891e244, - 0x892a247, - 0x893624a, - 0x894224d, - 0x894e250, - 0x895a253, - 0x8966256, - 0x8972259, - 0x897a25c, - 0x898625e, - 0x8992261, - 0x899e264, - 0x89aa267, - 0x89b626a, - 0x89c226d, - 0x89ce270, - 0x89da273, - 0x89e6276, - 0x89f2279, - 0x89fe27c, - 0x8a2a27f, - 0x8a3628a, - 0x8a4228d, - 0x8a4e290, - 0x8a5a293, - 0x8a66296, - 0x8a6e299, - 0x8a7a29b, - 0x8a8629e, - 0x8a922a1, - 0x8a9e2a4, - 0x8aaa2a7, - 0x8ab62aa, - 0x8ac22ad, - 0x8ace2b0, - 0x8ada2b3, - 0x8ae62b6, - 0x8af22b9, - 0x8afa2bc, - 0x8b062be, - 0x8b0e2c1, - 0x8b1a2c3, - 0x8b262c6, - 0x8b322c9, - 0x8b3e2cc, - 0x8b4a2cf, + 0x5be56f7, + 0x5bf96f9, + 0x5c216fe, + 0x5c2d708, + 0x5c3570b, + 0x5c5d70d, + 0x5c81717, + 0x5c99720, + 0x5c9d726, + 0x5ca5727, + 0x5cad729, + 0x5cc172b, + 0x5d71730, + 0x5d7575c, + 0x5d7d75d, + 0x5d8175f, + 0x5da5760, + 0x5dc9769, + 0x5de5772, + 0x5df9779, + 0x5e0d77e, + 0x5e15783, + 0x5e1d785, + 0x5e25787, + 0x5e3d789, + 0x5e4d78f, + 0x5e51793, + 0x5e6d794, + 0x66f579b, + 0x672d9bd, + 0x67599cb, + 0x67759d6, + 0x67799dd, + 0x2677d9de, + 0x679d9df, + 0x67bd9e7, + 0x68019ef, + 0x6809a00, + 0x2680da02, + 0x26811a03, + 0x6819a04, + 0x6a35a06, + 0x6a49a8d, + 0x26a4da92, + 0x6a51a93, + 0x6a59a94, + 0x26a5da96, + 0x26a61a97, + 0x26a6da98, + 0x26a7da9b, + 0x26a85a9f, + 0x26a91aa1, + 0x6a95aa4, + 0x26a99aa5, + 0x26ab1aa6, + 0x26ab9aac, + 0x26abdaae, + 0x26ac5aaf, + 0x26ac9ab1, + 0x26acdab2, + 0x26ad5ab3, + 0x6addab5, + 0x6af1ab7, + 0x6b19abc, + 0x6b55ac6, + 0x6b59ad5, + 0x6b91ad6, + 0x6bb5ae4, + 0x770daed, + 0x7711dc3, + 0x7715dc4, + 0x27719dc5, + 0x771ddc6, + 0x27721dc7, + 0x7725dc8, + 0x27731dc9, + 0x7735dcc, + 0x7739dcd, + 0x2773ddce, + 0x7741dcf, + 0x27749dd0, + 0x774ddd2, + 0x7751dd3, + 0x27761dd4, + 0x7765dd8, + 0x7769dd9, + 0x776ddda, + 0x7771ddb, + 0x27775ddc, + 0x7779ddd, + 0x777ddde, + 0x7781ddf, + 0x7785de0, + 0x2778dde1, + 0x7791de3, + 0x7795de4, + 0x7799de5, + 0x2779dde6, + 0x77a1de7, + 0x277a9de8, + 0x277addea, + 0x77c9deb, + 0x77e1df2, + 0x7825df8, + 0x7829e09, + 0x784de0a, + 0x7861e13, + 0x7865e18, + 0x7869e19, + 0x7a2de1a, + 0x27a31e8b, + 0x27a39e8c, + 0x27a3de8e, + 0x27a41e8f, + 0x7a49e90, + 0x7b25e92, + 0x27b31ec9, + 0x27b35ecc, + 0x27b39ecd, + 0x27b3dece, + 0x7b41ecf, + 0x7b6ded0, + 0x7b79edb, + 0x7b7dede, + 0x7ba1edf, + 0x7badee8, + 0x7bcdeeb, + 0x7bd1ef3, + 0x7c09ef4, + 0x7ebdf02, + 0x7f79faf, + 0x7f7dfde, + 0x7f81fdf, + 0x7f95fe0, + 0x7f99fe5, + 0x7fcdfe6, + 0x8005ff3, + 0x2800a001, + 0x8026002, + 0x804e009, + 0x8052013, + 0x8076014, + 0x809201d, + 0x80ba024, + 0x80ca02e, + 0x80ce032, + 0x80d2033, + 0x810e034, + 0x811a043, + 0x8142046, + 0x81de050, + 0x281e2077, + 0x81e6078, + 0x81f6079, + 0x281fa07d, + 0x820a07e, + 0x8226082, + 0x8246089, + 0x824a091, + 0x825e092, + 0x8272097, + 0x827609c, + 0x827a09d, + 0x827e09e, + 0x829e09f, + 0x834a0a7, + 0x834e0d2, + 0x836e0d3, + 0x839a0db, + 0x283aa0e6, + 0x83ae0ea, + 0x83be0eb, + 0x83f60ef, + 0x83fe0fd, + 0x84120ff, + 0x8432104, + 0x844e10c, + 0x845a113, + 0x8472116, + 0x84aa11c, + 0x84ae12a, + 0x858212b, + 0x8586160, + 0x859a161, + 0x85a2166, + 0x85ba168, + 0x85be16e, + 0x85ca16f, + 0x85d6172, + 0x85da175, + 0x85e2176, + 0x85e6178, + 0x860a179, + 0x864a182, + 0x864e192, + 0x866e193, + 0x86c219b, + 0x86f21b0, + 0x286f61bc, + 0x86fe1bd, + 0x87561bf, + 0x875a1d5, + 0x875e1d6, + 0x87621d7, + 0x87a61d8, + 0x87b61e9, + 0x87f61ed, + 0x87fa1fd, + 0x882a1fe, + 0x897620a, + 0x899e25d, + 0x89da267, + 0x8a02276, + 0x28a0a280, + 0x28a0e282, + 0x28a12283, + 0x8a1a284, + 0x8a26286, + 0x8b4a289, 0x8b562d2, 0x8b622d5, 0x8b6e2d8, - 0x8b722db, - 0x8b7e2dc, - 0x8b9a2df, - 0x8b9e2e6, - 0x8bae2e7, - 0x8bd22eb, - 0x8bd62f4, - 0x8c1a2f5, - 0x8c22306, - 0x8c36308, - 0x8c6a30d, - 0x8c8a31a, - 0x8c92322, - 0x8cb6324, - 0x8cce32d, - 0x8ce6333, - 0x8cfe339, - 0x8d1233f, - 0x28d5a344, - 0x8d5e356, - 0x8d8a357, - 0x8d9a362, - 0x8dae366, + 0x8b7a2db, + 0x8b862de, + 0x8b922e1, + 0x8b9e2e4, + 0x8baa2e7, + 0x8bb62ea, + 0x8bc22ed, + 0x28bc62f0, + 0x8bd22f1, + 0x8bde2f4, + 0x8bea2f7, + 0x8bf22fa, + 0x8bfe2fc, + 0x8c0a2ff, + 0x8c16302, + 0x8c22305, + 0x8c2e308, + 0x8c3a30b, + 0x8c4630e, + 0x8c52311, + 0x8c5e314, + 0x8c6a317, + 0x8c7631a, + 0x8ca231d, + 0x8cae328, + 0x8cba32b, + 0x8cc632e, + 0x8cd2331, + 0x8cde334, + 0x8ce6337, + 0x8cf2339, + 0x8cfe33c, + 0x8d0a33f, + 0x8d16342, + 0x8d22345, + 0x8d2e348, + 0x8d3a34b, + 0x8d4634e, + 0x8d52351, + 0x8d5e354, + 0x8d6a357, + 0x8d7235a, + 0x8d7e35c, + 0x8d8635f, + 0x8d92361, + 0x8d9e364, + 0x8daa367, + 0x8db636a, + 0x8dc236d, + 0x8dce370, + 0x8dda373, + 0x8de6376, + 0x8dea379, + 0x8df637a, + 0x8e1237d, + 0x8e16384, + 0x8e26385, + 0x8e4a389, + 0x8e4e392, + 0x8e92393, + 0x8e9a3a4, + 0x8eae3a6, + 0x8ee23ab, + 0x8f023b8, + 0x8f063c0, + 0x8f0e3c1, + 0x8f323c3, + 0x8f4a3cc, + 0x8f623d2, + 0x8f7a3d8, + 0x8f923de, + 0x28fda3e4, + 0x8fde3f6, + 0x900a3f7, + 0x901a402, + 0x902e406, } -// max children 601 (capacity 1023) -// max text offset 30901 (capacity 32767) +// max children 650 (capacity 1023) +// max text offset 31341 (capacity 32767) // max text length 36 (capacity 63) -// max hi 9067 (capacity 16383) -// max lo 9062 (capacity 16383) +// max hi 9227 (capacity 16383) +// max lo 9222 (capacity 16383) diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md index 8cfd6063e7299..1473e1296d09c 100644 --- a/vendor/golang.org/x/oauth2/README.md +++ b/vendor/golang.org/x/oauth2/README.md @@ -1,7 +1,7 @@ # OAuth2 for Go +[![Go Reference](https://pkg.go.dev/badge/golang.org/x/oauth2.svg)](https://pkg.go.dev/golang.org/x/oauth2) [![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2) -[![GoDoc](https://godoc.org/golang.org/x/oauth2?status.svg)](https://godoc.org/golang.org/x/oauth2) oauth2 package contains a client implementation for OAuth 2.0 spec. @@ -14,17 +14,17 @@ go get golang.org/x/oauth2 Or you can manually git clone the repository to `$(go env GOPATH)/src/golang.org/x/oauth2`. -See godoc for further documentation and examples. +See pkg.go.dev for further documentation and examples. -* [godoc.org/golang.org/x/oauth2](https://godoc.org/golang.org/x/oauth2) -* [godoc.org/golang.org/x/oauth2/google](https://godoc.org/golang.org/x/oauth2/google) +* [pkg.go.dev/golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) +* [pkg.go.dev/golang.org/x/oauth2/google](https://pkg.go.dev/golang.org/x/oauth2/google) ## Policy for new packages We no longer accept new provider-specific packages in this repo if all they do is add a single endpoint variable. If you just want to add a single endpoint, add it to the -[godoc.org/golang.org/x/oauth2/endpoints](https://godoc.org/golang.org/x/oauth2/endpoints) +[pkg.go.dev/golang.org/x/oauth2/endpoints](https://pkg.go.dev/golang.org/x/oauth2/endpoints) package. ## Report Issues / Send Patches diff --git a/vendor/golang.org/x/oauth2/google/google.go b/vendor/golang.org/x/oauth2/google/google.go index 81de32b360b27..2c8f1bd5ad78a 100644 --- a/vendor/golang.org/x/oauth2/google/google.go +++ b/vendor/golang.org/x/oauth2/google/google.go @@ -15,6 +15,7 @@ import ( "cloud.google.com/go/compute/metadata" "golang.org/x/oauth2" + "golang.org/x/oauth2/google/internal/externalaccount" "golang.org/x/oauth2/jwt" ) @@ -93,6 +94,7 @@ func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) { const ( serviceAccountKey = "service_account" userCredentialsKey = "authorized_user" + externalAccountKey = "external_account" ) // credentialsFile is the unmarshalled representation of a credentials file. @@ -111,6 +113,15 @@ type credentialsFile struct { ClientSecret string `json:"client_secret"` ClientID string `json:"client_id"` RefreshToken string `json:"refresh_token"` + + // External Account fields + Audience string `json:"audience"` + SubjectTokenType string `json:"subject_token_type"` + TokenURLExternal string `json:"token_url"` + TokenInfoURL string `json:"token_info_url"` + ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"` + CredentialSource externalaccount.CredentialSource `json:"credential_source"` + QuotaProjectID string `json:"quota_project_id"` } func (f *credentialsFile) jwtConfig(scopes []string) *jwt.Config { @@ -141,6 +152,20 @@ func (f *credentialsFile) tokenSource(ctx context.Context, scopes []string) (oau } tok := &oauth2.Token{RefreshToken: f.RefreshToken} return cfg.TokenSource(ctx, tok), nil + case externalAccountKey: + cfg := &externalaccount.Config{ + Audience: f.Audience, + SubjectTokenType: f.SubjectTokenType, + TokenURL: f.TokenURLExternal, + TokenInfoURL: f.TokenInfoURL, + ServiceAccountImpersonationURL: f.ServiceAccountImpersonationURL, + ClientSecret: f.ClientSecret, + ClientID: f.ClientID, + CredentialSource: f.CredentialSource, + QuotaProjectID: f.QuotaProjectID, + Scopes: scopes, + } + return cfg.TokenSource(ctx), nil case "": return nil, errors.New("missing 'type' field in credentials") default: diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go new file mode 100644 index 0000000000000..906d1fe9d3167 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go @@ -0,0 +1,230 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package externalaccount + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "path" + "sort" + "strings" + "time" +) + +// RequestSigner is a utility class to sign http requests using a AWS V4 signature. +type awsRequestSigner struct { + RegionName string + AwsSecurityCredentials map[string]string +} + +const ( +// AWS Signature Version 4 signing algorithm identifier. + awsAlgorithm = "AWS4-HMAC-SHA256" + +// The termination string for the AWS credential scope value as defined in +// https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html + awsRequestType = "aws4_request" + +// The AWS authorization header name for the security session token if available. + awsSecurityTokenHeader = "x-amz-security-token" + +// The AWS authorization header name for the auto-generated date. + awsDateHeader = "x-amz-date" + + awsTimeFormatLong = "20060102T150405Z" + awsTimeFormatShort = "20060102" +) + +func getSha256(input []byte) (string, error) { + hash := sha256.New() + if _, err := hash.Write(input); err != nil { + return "", err + } + return hex.EncodeToString(hash.Sum(nil)), nil +} + +func getHmacSha256(key, input []byte) ([]byte, error) { + hash := hmac.New(sha256.New, key) + if _, err := hash.Write(input); err != nil { + return nil, err + } + return hash.Sum(nil), nil +} + +func cloneRequest(r *http.Request) *http.Request { + r2 := new(http.Request) + *r2 = *r + if r.Header != nil { + r2.Header = make(http.Header, len(r.Header)) + + // Find total number of values. + headerCount := 0 + for _, headerValues := range r.Header { + headerCount += len(headerValues) + } + copiedHeaders := make([]string, headerCount) // shared backing array for headers' values + + for headerKey, headerValues := range r.Header { + headerCount = copy(copiedHeaders, headerValues) + r2.Header[headerKey] = copiedHeaders[:headerCount:headerCount] + copiedHeaders = copiedHeaders[headerCount:] + } + } + return r2 +} + +func canonicalPath(req *http.Request) string { + result := req.URL.EscapedPath() + if result == "" { + return "/" + } + return path.Clean(result) +} + +func canonicalQuery(req *http.Request) string { + queryValues := req.URL.Query() + for queryKey := range queryValues { + sort.Strings(queryValues[queryKey]) + } + return queryValues.Encode() +} + +func canonicalHeaders(req *http.Request) (string, string) { + // Header keys need to be sorted alphabetically. + var headers []string + lowerCaseHeaders := make(http.Header) + for k, v := range req.Header { + k := strings.ToLower(k) + if _, ok := lowerCaseHeaders[k]; ok { + // include additional values + lowerCaseHeaders[k] = append(lowerCaseHeaders[k], v...) + } else { + headers = append(headers, k) + lowerCaseHeaders[k] = v + } + } + sort.Strings(headers) + + var fullHeaders strings.Builder + for _, header := range headers { + headerValue := strings.Join(lowerCaseHeaders[header], ",") + fullHeaders.WriteString(header) + fullHeaders.WriteRune(':') + fullHeaders.WriteString(headerValue) + fullHeaders.WriteRune('\n') + } + + return strings.Join(headers, ";"), fullHeaders.String() +} + +func requestDataHash(req *http.Request) (string, error) { + var requestData []byte + if req.Body != nil { + requestBody, err := req.GetBody() + if err != nil { + return "", err + } + defer requestBody.Close() + + requestData, err = ioutil.ReadAll(io.LimitReader(requestBody, 1<<20)) + if err != nil { + return "", err + } + } + + return getSha256(requestData) +} + +func requestHost(req *http.Request) string { + if req.Host != "" { + return req.Host + } + return req.URL.Host +} + +func canonicalRequest(req *http.Request, canonicalHeaderColumns, canonicalHeaderData string) (string, error) { + dataHash, err := requestDataHash(req) + if err != nil { + return "", err + } + + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", req.Method, canonicalPath(req), canonicalQuery(req), canonicalHeaderData, canonicalHeaderColumns, dataHash), nil +} + +// SignRequest adds the appropriate headers to an http.Request +// or returns an error if something prevented this. +func (rs *awsRequestSigner) SignRequest(req *http.Request) error { + signedRequest := cloneRequest(req) + timestamp := now() + + signedRequest.Header.Add("host", requestHost(req)) + + if securityToken, ok := rs.AwsSecurityCredentials["security_token"]; ok { + signedRequest.Header.Add(awsSecurityTokenHeader, securityToken) + } + + if signedRequest.Header.Get("date") == "" { + signedRequest.Header.Add(awsDateHeader, timestamp.Format(awsTimeFormatLong)) + } + + authorizationCode, err := rs.generateAuthentication(signedRequest, timestamp) + if err != nil { + return err + } + signedRequest.Header.Set("Authorization", authorizationCode) + + req.Header = signedRequest.Header + return nil +} + +func (rs *awsRequestSigner) generateAuthentication(req *http.Request, timestamp time.Time) (string, error) { + secretAccessKey, ok := rs.AwsSecurityCredentials["secret_access_key"] + if !ok { + return "", errors.New("oauth2/google: missing secret_access_key header") + } + accessKeyId, ok := rs.AwsSecurityCredentials["access_key_id"] + if !ok { + return "", errors.New("oauth2/google: missing access_key_id header") + } + + canonicalHeaderColumns, canonicalHeaderData := canonicalHeaders(req) + + dateStamp := timestamp.Format(awsTimeFormatShort) + serviceName := "" + if splitHost := strings.Split(requestHost(req), "."); len(splitHost) > 0 { + serviceName = splitHost[0] + } + + credentialScope := fmt.Sprintf("%s/%s/%s/%s",dateStamp, rs.RegionName, serviceName, awsRequestType) + + requestString, err := canonicalRequest(req, canonicalHeaderColumns, canonicalHeaderData) + if err != nil { + return "", err + } + requestHash, err := getSha256([]byte(requestString)) + if err != nil{ + return "", err + } + + stringToSign := fmt.Sprintf("%s\n%s\n%s\n%s", awsAlgorithm, timestamp.Format(awsTimeFormatLong), credentialScope, requestHash) + + signingKey := []byte("AWS4" + secretAccessKey) + for _, signingInput := range []string{ + dateStamp, rs.RegionName, serviceName, awsRequestType, stringToSign, + } { + signingKey, err = getHmacSha256(signingKey, []byte(signingInput)) + if err != nil{ + return "", err + } + } + + return fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s", awsAlgorithm, accessKeyId, credentialScope, canonicalHeaderColumns, hex.EncodeToString(signingKey)), nil +} diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go new file mode 100644 index 0000000000000..deb9deb7308fb --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go @@ -0,0 +1,145 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package externalaccount + +import ( + "context" + "fmt" + "golang.org/x/oauth2" + "net/http" + "time" +) + +// now aliases time.Now for testing +var now = time.Now + +// Config stores the configuration for fetching tokens with external credentials. +type Config struct { + Audience string + SubjectTokenType string + TokenURL string + TokenInfoURL string + ServiceAccountImpersonationURL string + ClientSecret string + ClientID string + CredentialSource CredentialSource + QuotaProjectID string + Scopes []string +} + +// TokenSource Returns an external account TokenSource struct. This is to be called by package google to construct a google.Credentials. +func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource { + ts := tokenSource{ + ctx: ctx, + conf: c, + } + if c.ServiceAccountImpersonationURL == "" { + return oauth2.ReuseTokenSource(nil, ts) + } + scopes := c.Scopes + ts.conf.Scopes = []string{"https://www.googleapis.com/auth/cloud-platform"} + imp := impersonateTokenSource{ + ctx: ctx, + url: c.ServiceAccountImpersonationURL, + scopes: scopes, + ts: oauth2.ReuseTokenSource(nil, ts), + } + return oauth2.ReuseTokenSource(nil, imp) +} + +// Subject token file types. +const ( + fileTypeText = "text" + fileTypeJSON = "json" +) + +type format struct { + // Type is either "text" or "json". When not provided "text" type is assumed. + Type string `json:"type"` + // SubjectTokenFieldName is only required for JSON format. This would be "access_token" for azure. + SubjectTokenFieldName string `json:"subject_token_field_name"` +} + +// CredentialSource stores the information necessary to retrieve the credentials for the STS exchange. +type CredentialSource struct { + File string `json:"file"` + + URL string `json:"url"` + Headers map[string]string `json:"headers"` + + EnvironmentID string `json:"environment_id"` + RegionURL string `json:"region_url"` + RegionalCredVerificationURL string `json:"regional_cred_verification_url"` + CredVerificationURL string `json:"cred_verification_url"` + Format format `json:"format"` +} + +// parse determines the type of CredentialSource needed +func (c *Config) parse(ctx context.Context) baseCredentialSource { + if c.CredentialSource.File != "" { + return fileCredentialSource{File: c.CredentialSource.File, Format: c.CredentialSource.Format} + } else if c.CredentialSource.URL != "" { + return urlCredentialSource{URL: c.CredentialSource.URL, Format: c.CredentialSource.Format, ctx: ctx} + } + return nil +} + +type baseCredentialSource interface { + subjectToken() (string, error) +} + +// tokenSource is the source that handles external credentials. +type tokenSource struct { + ctx context.Context + conf *Config +} + +// Token allows tokenSource to conform to the oauth2.TokenSource interface. +func (ts tokenSource) Token() (*oauth2.Token, error) { + conf := ts.conf + + credSource := conf.parse(ts.ctx) + if credSource == nil { + return nil, fmt.Errorf("oauth2/google: unable to parse credential source") + } + subjectToken, err := credSource.subjectToken() + if err != nil { + return nil, err + } + stsRequest := STSTokenExchangeRequest{ + GrantType: "urn:ietf:params:oauth:grant-type:token-exchange", + Audience: conf.Audience, + Scope: conf.Scopes, + RequestedTokenType: "urn:ietf:params:oauth:token-type:access_token", + SubjectToken: subjectToken, + SubjectTokenType: conf.SubjectTokenType, + } + header := make(http.Header) + header.Add("Content-Type", "application/x-www-form-urlencoded") + clientAuth := ClientAuthentication{ + AuthStyle: oauth2.AuthStyleInHeader, + ClientID: conf.ClientID, + ClientSecret: conf.ClientSecret, + } + stsResp, err := ExchangeToken(ts.ctx, conf.TokenURL, &stsRequest, clientAuth, header, nil) + if err != nil { + return nil, err + } + + accessToken := &oauth2.Token{ + AccessToken: stsResp.AccessToken, + TokenType: stsResp.TokenType, + } + if stsResp.ExpiresIn < 0 { + return nil, fmt.Errorf("oauth2/google: got invalid expiry from security token service") + } else if stsResp.ExpiresIn >= 0 { + accessToken.Expiry = now().Add(time.Duration(stsResp.ExpiresIn) * time.Second) + } + + if stsResp.RefreshToken != "" { + accessToken.RefreshToken = stsResp.RefreshToken + } + return accessToken, nil +} diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/clientauth.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/clientauth.go new file mode 100644 index 0000000000000..0464724fd8ceb --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/clientauth.go @@ -0,0 +1,41 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package externalaccount + +import ( + "encoding/base64" + "golang.org/x/oauth2" + "net/http" + "net/url" +) + +// ClientAuthentication represents an OAuth client ID and secret and the mechanism for passing these credentials as stated in rfc6749#2.3.1. +type ClientAuthentication struct { + // AuthStyle can be either basic or request-body + AuthStyle oauth2.AuthStyle + ClientID string + ClientSecret string +} + +func (c *ClientAuthentication) InjectAuthentication(values url.Values, headers http.Header) { + if c.ClientID == "" || c.ClientSecret == "" || values == nil || headers == nil { + return + } + + switch c.AuthStyle { + case oauth2.AuthStyleInHeader: // AuthStyleInHeader corresponds to basic authentication as defined in rfc7617#2 + plainHeader := c.ClientID + ":" + c.ClientSecret + headers.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(plainHeader))) + case oauth2.AuthStyleInParams: // AuthStyleInParams corresponds to request-body authentication with ClientID and ClientSecret in the message body. + values.Set("client_id", c.ClientID) + values.Set("client_secret", c.ClientSecret) + case oauth2.AuthStyleAutoDetect: + values.Set("client_id", c.ClientID) + values.Set("client_secret", c.ClientSecret) + default: + values.Set("client_id", c.ClientID) + values.Set("client_secret", c.ClientSecret) + } +} diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/err.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/err.go new file mode 100644 index 0000000000000..233a78cef2aa5 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/err.go @@ -0,0 +1,18 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package externalaccount + +import "fmt" + +// Error for handling OAuth related error responses as stated in rfc6749#5.2. +type Error struct { + Code string + URI string + Description string +} + +func (err *Error) Error() string { + return fmt.Sprintf("got error code %s from %s: %s", err.Code, err.URI, err.Description) +} diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/filecredsource.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/filecredsource.go new file mode 100644 index 0000000000000..e953ddb473a7c --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/filecredsource.go @@ -0,0 +1,57 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package externalaccount + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "os" +) + +type fileCredentialSource struct { + File string + Format format +} + +func (cs fileCredentialSource) subjectToken() (string, error) { + tokenFile, err := os.Open(cs.File) + if err != nil { + return "", fmt.Errorf("oauth2/google: failed to open credential file %q", cs.File) + } + defer tokenFile.Close() + tokenBytes, err := ioutil.ReadAll(io.LimitReader(tokenFile, 1<<20)) + if err != nil { + return "", fmt.Errorf("oauth2/google: failed to read credential file: %v", err) + } + tokenBytes = bytes.TrimSpace(tokenBytes) + switch cs.Format.Type { + case "json": + jsonData := make(map[string]interface{}) + err = json.Unmarshal(tokenBytes, &jsonData) + if err != nil { + return "", fmt.Errorf("oauth2/google: failed to unmarshal subject token file: %v", err) + } + val, ok := jsonData[cs.Format.SubjectTokenFieldName] + if !ok { + return "", errors.New("oauth2/google: provided subject_token_field_name not found in credentials") + } + token, ok := val.(string) + if !ok { + return "", errors.New("oauth2/google: improperly formatted subject token") + } + return token, nil + case "text": + return string(tokenBytes), nil + case "": + return string(tokenBytes), nil + default: + return "", errors.New("oauth2/google: invalid credential_source file format type") + } + +} diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/impersonate.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/impersonate.go new file mode 100644 index 0000000000000..1d29c467f7bb6 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/impersonate.go @@ -0,0 +1,83 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package externalaccount + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "golang.org/x/oauth2" + "io" + "io/ioutil" + "net/http" + "time" +) + +// generateAccesstokenReq is used for service account impersonation +type generateAccessTokenReq struct { + Delegates []string `json:"delegates,omitempty"` + Lifetime string `json:"lifetime,omitempty"` + Scope []string `json:"scope,omitempty"` +} + +type impersonateTokenResponse struct { + AccessToken string `json:"accessToken"` + ExpireTime string `json:"expireTime"` +} + +type impersonateTokenSource struct { + ctx context.Context + ts oauth2.TokenSource + + url string + scopes []string +} + +// Token performs the exchange to get a temporary service account +func (its impersonateTokenSource) Token() (*oauth2.Token, error) { + reqBody := generateAccessTokenReq{ + Lifetime: "3600s", + Scope: its.scopes, + } + b, err := json.Marshal(reqBody) + if err != nil { + return nil, fmt.Errorf("oauth2/google: unable to marshal request: %v", err) + } + client := oauth2.NewClient(its.ctx, its.ts) + req, err := http.NewRequest("POST", its.url, bytes.NewReader(b)) + if err != nil { + return nil, fmt.Errorf("oauth2/google: unable to create impersonation request: %v", err) + } + req = req.WithContext(its.ctx) + req.Header.Set("Content-Type", "application/json") + + resp, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("oauth2/google: unable to generate access token: %v", err) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return nil, fmt.Errorf("oauth2/google: unable to read body: %v", err) + } + if c := resp.StatusCode; c < 200 || c > 299 { + return nil, fmt.Errorf("oauth2/google: status code %d: %s", c, body) + } + + var accessTokenResp impersonateTokenResponse + if err := json.Unmarshal(body, &accessTokenResp); err != nil { + return nil, fmt.Errorf("oauth2/google: unable to parse response: %v", err) + } + expiry, err := time.Parse(time.RFC3339, accessTokenResp.ExpireTime) + if err != nil { + return nil, fmt.Errorf("oauth2/google: unable to parse expiry: %v", err) + } + return &oauth2.Token{ + AccessToken: accessTokenResp.AccessToken, + Expiry: expiry, + TokenType: "Bearer", + }, nil +} diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go new file mode 100644 index 0000000000000..c7d85a3c20169 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go @@ -0,0 +1,98 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package externalaccount + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + + "golang.org/x/oauth2" +) + +// ExchangeToken performs an oauth2 token exchange with the provided endpoint. +// The first 4 fields are all mandatory. headers can be used to pass additional +// headers beyond the bare minimum required by the token exchange. options can +// be used to pass additional JSON-structured options to the remote server. +func ExchangeToken(ctx context.Context, endpoint string, request *STSTokenExchangeRequest, authentication ClientAuthentication, headers http.Header, options map[string]interface{}) (*STSTokenExchangeResponse, error) { + + client := oauth2.NewClient(ctx, nil) + + data := url.Values{} + data.Set("audience", request.Audience) + data.Set("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange") + data.Set("requested_token_type", "urn:ietf:params:oauth:token-type:access_token") + data.Set("subject_token_type", request.SubjectTokenType) + data.Set("subject_token", request.SubjectToken) + data.Set("scope", strings.Join(request.Scope, " ")) + opts, err := json.Marshal(options) + if err != nil { + return nil, fmt.Errorf("oauth2/google: failed to marshal additional options: %v", err) + } + data.Set("options", string(opts)) + + authentication.InjectAuthentication(data, headers) + encodedData := data.Encode() + + req, err := http.NewRequest("POST", endpoint, strings.NewReader(encodedData)) + if err != nil { + return nil, fmt.Errorf("oauth2/google: failed to properly build http request: %v", err) + + } + req = req.WithContext(ctx) + for key, list := range headers { + for _, val := range list { + req.Header.Add(key, val) + } + } + req.Header.Add("Content-Length", strconv.Itoa(len(encodedData))) + + resp, err := client.Do(req) + + if err != nil { + return nil, fmt.Errorf("oauth2/google: invalid response from Secure Token Server: %v", err) + } + defer resp.Body.Close() + + bodyJson := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)) + var stsResp STSTokenExchangeResponse + err = bodyJson.Decode(&stsResp) + if err != nil { + return nil, fmt.Errorf("oauth2/google: failed to unmarshal response body from Secure Token Server: %v", err) + + } + + return &stsResp, nil +} + +// STSTokenExchangeRequest contains fields necessary to make an oauth2 token exchange. +type STSTokenExchangeRequest struct { + ActingParty struct { + ActorToken string + ActorTokenType string + } + GrantType string + Resource string + Audience string + Scope []string + RequestedTokenType string + SubjectToken string + SubjectTokenType string +} + +// STSTokenExchangeResponse is used to decode the remote server response during an oauth2 token exchange. +type STSTokenExchangeResponse struct { + AccessToken string `json:"access_token"` + IssuedTokenType string `json:"issued_token_type"` + TokenType string `json:"token_type"` + ExpiresIn int `json:"expires_in"` + Scope string `json:"scope"` + RefreshToken string `json:"refresh_token"` +} diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/urlcredsource.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/urlcredsource.go new file mode 100644 index 0000000000000..b0d5d35e751ff --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/urlcredsource.go @@ -0,0 +1,71 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package externalaccount + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "golang.org/x/oauth2" + "io" + "io/ioutil" + "net/http" +) + +type urlCredentialSource struct { + URL string + Headers map[string]string + Format format + ctx context.Context +} + +func (cs urlCredentialSource) subjectToken() (string, error) { + client := oauth2.NewClient(cs.ctx, nil) + req, err := http.NewRequest("GET", cs.URL, nil) + if err != nil { + return "", fmt.Errorf("oauth2/google: HTTP request for URL-sourced credential failed: %v", err) + } + req = req.WithContext(cs.ctx) + + for key, val := range cs.Headers { + req.Header.Add(key, val) + } + resp, err := client.Do(req) + if err != nil { + return "", fmt.Errorf("oauth2/google: invalid response when retrieving subject token: %v", err) + } + defer resp.Body.Close() + + tokenBytes, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return "", fmt.Errorf("oauth2/google: invalid body in subject token URL query: %v", err) + } + + switch cs.Format.Type { + case "json": + jsonData := make(map[string]interface{}) + err = json.Unmarshal(tokenBytes, &jsonData) + if err != nil { + return "", fmt.Errorf("oauth2/google: failed to unmarshal subject token file: %v", err) + } + val, ok := jsonData[cs.Format.SubjectTokenFieldName] + if !ok { + return "", errors.New("oauth2/google: provided subject_token_field_name not found in credentials") + } + token, ok := val.(string) + if !ok { + return "", errors.New("oauth2/google: improperly formatted subject token") + } + return token, nil + case "text": + return string(tokenBytes), nil + case "": + return string(tokenBytes), nil + default: + return "", errors.New("oauth2/google: invalid credential_source file format type") + } + +} diff --git a/vendor/golang.org/x/sys/execabs/execabs.go b/vendor/golang.org/x/sys/execabs/execabs.go new file mode 100644 index 0000000000000..78192498db010 --- /dev/null +++ b/vendor/golang.org/x/sys/execabs/execabs.go @@ -0,0 +1,102 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package execabs is a drop-in replacement for os/exec +// that requires PATH lookups to find absolute paths. +// That is, execabs.Command("cmd") runs the same PATH lookup +// as exec.Command("cmd"), but if the result is a path +// which is relative, the Run and Start methods will report +// an error instead of running the executable. +// +// See https://blog.golang.org/path-security for more information +// about when it may be necessary or appropriate to use this package. +package execabs + +import ( + "context" + "fmt" + "os/exec" + "path/filepath" + "reflect" + "unsafe" +) + +// ErrNotFound is the error resulting if a path search failed to find an executable file. +// It is an alias for exec.ErrNotFound. +var ErrNotFound = exec.ErrNotFound + +// Cmd represents an external command being prepared or run. +// It is an alias for exec.Cmd. +type Cmd = exec.Cmd + +// Error is returned by LookPath when it fails to classify a file as an executable. +// It is an alias for exec.Error. +type Error = exec.Error + +// An ExitError reports an unsuccessful exit by a command. +// It is an alias for exec.ExitError. +type ExitError = exec.ExitError + +func relError(file, path string) error { + return fmt.Errorf("%s resolves to executable in current directory (.%c%s)", file, filepath.Separator, path) +} + +// LookPath searches for an executable named file in the directories +// named by the PATH environment variable. If file contains a slash, +// it is tried directly and the PATH is not consulted. The result will be +// an absolute path. +// +// LookPath differs from exec.LookPath in its handling of PATH lookups, +// which are used for file names without slashes. If exec.LookPath's +// PATH lookup would have returned an executable from the current directory, +// LookPath instead returns an error. +func LookPath(file string) (string, error) { + path, err := exec.LookPath(file) + if err != nil { + return "", err + } + if filepath.Base(file) == file && !filepath.IsAbs(path) { + return "", relError(file, path) + } + return path, nil +} + +func fixCmd(name string, cmd *exec.Cmd) { + if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) { + // exec.Command was called with a bare binary name and + // exec.LookPath returned a path which is not absolute. + // Set cmd.lookPathErr and clear cmd.Path so that it + // cannot be run. + lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer())) + if *lookPathErr == nil { + *lookPathErr = relError(name, cmd.Path) + } + cmd.Path = "" + } +} + +// CommandContext is like Command but includes a context. +// +// The provided context is used to kill the process (by calling os.Process.Kill) +// if the context becomes done before the command completes on its own. +func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd { + cmd := exec.CommandContext(ctx, name, arg...) + fixCmd(name, cmd) + return cmd + +} + +// Command returns the Cmd struct to execute the named program with the given arguments. +// See exec.Command for most details. +// +// Command differs from exec.Command in its handling of PATH lookups, +// which are used when the program name contains no slashes. +// If exec.Command would have returned an exec.Cmd configured to run an +// executable from the current directory, Command instead +// returns an exec.Cmd that will return an error from Start or Run. +func Command(name string, arg ...string) *exec.Cmd { + cmd := exec.Command(name, arg...) + fixCmd(name, cmd) + return cmd +} diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index d249919c30f07..0197df87276df 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -22,6 +22,7 @@ type HWND uintptr const ( InvalidHandle = ^Handle(0) + InvalidHWND = ^HWND(0) // Flags for DefineDosDevice. DDD_EXACT_MATCH_ON_REMOVE = 0x00000004 @@ -215,7 +216,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW //sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error) //sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW -//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32) = user32.GetWindowThreadProcessId +//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId //sys GetShellWindow() (shellWindow HWND) = user32.GetShellWindow //sys MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW //sys ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx @@ -264,19 +265,29 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect //sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile //sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW +//sys FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.FindFirstChangeNotificationW +//sys FindNextChangeNotification(handle Handle) (err error) +//sys FindCloseChangeNotification(handle Handle) (err error) //sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW -//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore +//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore //sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore -//sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore +//sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore //sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore //sys CertDeleteCertificateFromStore(certContext *CertContext) (err error) = crypt32.CertDeleteCertificateFromStore //sys CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext) = crypt32.CertDuplicateCertificateContext -//sys PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) = crypt32.PFXImportCertStore -//sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain -//sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain -//sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext -//sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext -//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy +//sys PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) = crypt32.PFXImportCertStore +//sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain +//sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain +//sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext +//sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext +//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy +//sys CertGetNameString(certContext *CertContext, nameType uint32, flags uint32, typePara unsafe.Pointer, name *uint16, size uint32) (chars uint32) = crypt32.CertGetNameStringW +//sys CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) = crypt32.CertFindExtension +//sys CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) = crypt32.CryptQueryObject +//sys CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) = crypt32.CryptDecodeObject +//sys CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptProtectData +//sys CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptUnprotectData +//sys WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) = wintrust.WinVerifyTrustEx //sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW //sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey //sys RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index b3bd0da42722a..fd4260762a8da 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -227,7 +227,7 @@ const ( ) const ( - // filters for ReadDirectoryChangesW + // filters for ReadDirectoryChangesW and FindFirstChangeNotificationW FILE_NOTIFY_CHANGE_FILE_NAME = 0x001 FILE_NOTIFY_CHANGE_DIR_NAME = 0x002 FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x004 @@ -427,6 +427,67 @@ const ( CERT_CLOSE_STORE_FORCE_FLAG = 0x00000001 CERT_CLOSE_STORE_CHECK_FLAG = 0x00000002 + /* CryptQueryObject object type */ + CERT_QUERY_OBJECT_FILE = 1 + CERT_QUERY_OBJECT_BLOB = 2 + + /* CryptQueryObject content type flags */ + CERT_QUERY_CONTENT_CERT = 1 + CERT_QUERY_CONTENT_CTL = 2 + CERT_QUERY_CONTENT_CRL = 3 + CERT_QUERY_CONTENT_SERIALIZED_STORE = 4 + CERT_QUERY_CONTENT_SERIALIZED_CERT = 5 + CERT_QUERY_CONTENT_SERIALIZED_CTL = 6 + CERT_QUERY_CONTENT_SERIALIZED_CRL = 7 + CERT_QUERY_CONTENT_PKCS7_SIGNED = 8 + CERT_QUERY_CONTENT_PKCS7_UNSIGNED = 9 + CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED = 10 + CERT_QUERY_CONTENT_PKCS10 = 11 + CERT_QUERY_CONTENT_PFX = 12 + CERT_QUERY_CONTENT_CERT_PAIR = 13 + CERT_QUERY_CONTENT_PFX_AND_LOAD = 14 + CERT_QUERY_CONTENT_FLAG_CERT = (1 << CERT_QUERY_CONTENT_CERT) + CERT_QUERY_CONTENT_FLAG_CTL = (1 << CERT_QUERY_CONTENT_CTL) + CERT_QUERY_CONTENT_FLAG_CRL = (1 << CERT_QUERY_CONTENT_CRL) + CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE = (1 << CERT_QUERY_CONTENT_SERIALIZED_STORE) + CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT = (1 << CERT_QUERY_CONTENT_SERIALIZED_CERT) + CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL = (1 << CERT_QUERY_CONTENT_SERIALIZED_CTL) + CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL = (1 << CERT_QUERY_CONTENT_SERIALIZED_CRL) + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED = (1 << CERT_QUERY_CONTENT_PKCS7_SIGNED) + CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED = (1 << CERT_QUERY_CONTENT_PKCS7_UNSIGNED) + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED = (1 << CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED) + CERT_QUERY_CONTENT_FLAG_PKCS10 = (1 << CERT_QUERY_CONTENT_PKCS10) + CERT_QUERY_CONTENT_FLAG_PFX = (1 << CERT_QUERY_CONTENT_PFX) + CERT_QUERY_CONTENT_FLAG_CERT_PAIR = (1 << CERT_QUERY_CONTENT_CERT_PAIR) + CERT_QUERY_CONTENT_FLAG_PFX_AND_LOAD = (1 << CERT_QUERY_CONTENT_PFX_AND_LOAD) + CERT_QUERY_CONTENT_FLAG_ALL = (CERT_QUERY_CONTENT_FLAG_CERT | CERT_QUERY_CONTENT_FLAG_CTL | CERT_QUERY_CONTENT_FLAG_CRL | CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE | CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT | CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL | CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL | CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED | CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED | CERT_QUERY_CONTENT_FLAG_PKCS10 | CERT_QUERY_CONTENT_FLAG_PFX | CERT_QUERY_CONTENT_FLAG_CERT_PAIR) + CERT_QUERY_CONTENT_FLAG_ALL_ISSUER_CERT = (CERT_QUERY_CONTENT_FLAG_CERT | CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE | CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT | CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED) + + /* CryptQueryObject format type flags */ + CERT_QUERY_FORMAT_BINARY = 1 + CERT_QUERY_FORMAT_BASE64_ENCODED = 2 + CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED = 3 + CERT_QUERY_FORMAT_FLAG_BINARY = (1 << CERT_QUERY_FORMAT_BINARY) + CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED = (1 << CERT_QUERY_FORMAT_BASE64_ENCODED) + CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED = (1 << CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED) + CERT_QUERY_FORMAT_FLAG_ALL = (CERT_QUERY_FORMAT_FLAG_BINARY | CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED | CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED) + + /* CertGetNameString name types */ + CERT_NAME_EMAIL_TYPE = 1 + CERT_NAME_RDN_TYPE = 2 + CERT_NAME_ATTR_TYPE = 3 + CERT_NAME_SIMPLE_DISPLAY_TYPE = 4 + CERT_NAME_FRIENDLY_DISPLAY_TYPE = 5 + CERT_NAME_DNS_TYPE = 6 + CERT_NAME_URL_TYPE = 7 + CERT_NAME_UPN_TYPE = 8 + + /* CertGetNameString flags */ + CERT_NAME_ISSUER_FLAG = 0x1 + CERT_NAME_DISABLE_IE4_UTF8_FLAG = 0x10000 + CERT_NAME_SEARCH_ALL_NAMES_FLAG = 0x2 + CERT_NAME_STR_ENABLE_PUNYCODE_FLAG = 0x00200000 + /* AuthType values for SSLExtraCertChainPolicyPara struct */ AUTHTYPE_CLIENT = 1 AUTHTYPE_SERVER = 2 @@ -437,6 +498,22 @@ const ( SECURITY_FLAG_IGNORE_WRONG_USAGE = 0x00000200 SECURITY_FLAG_IGNORE_CERT_CN_INVALID = 0x00001000 SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000 + + /* Flags for Crypt[Un]ProtectData */ + CRYPTPROTECT_UI_FORBIDDEN = 0x1 + CRYPTPROTECT_LOCAL_MACHINE = 0x4 + CRYPTPROTECT_CRED_SYNC = 0x8 + CRYPTPROTECT_AUDIT = 0x10 + CRYPTPROTECT_NO_RECOVERY = 0x20 + CRYPTPROTECT_VERIFY_PROTECTION = 0x40 + CRYPTPROTECT_CRED_REGENERATE = 0x80 + + /* Flags for CryptProtectPromptStruct */ + CRYPTPROTECT_PROMPT_ON_UNPROTECT = 1 + CRYPTPROTECT_PROMPT_ON_PROTECT = 2 + CRYPTPROTECT_PROMPT_RESERVED = 4 + CRYPTPROTECT_PROMPT_STRONG = 8 + CRYPTPROTECT_PROMPT_REQUIRE_STRONG = 16 ) const ( @@ -459,10 +536,58 @@ const ( REALTIME_PRIORITY_CLASS = 0x00000100 ) +/* wintrust.h constants for WinVerifyTrustEx */ +const ( + WTD_UI_ALL = 1 + WTD_UI_NONE = 2 + WTD_UI_NOBAD = 3 + WTD_UI_NOGOOD = 4 + + WTD_REVOKE_NONE = 0 + WTD_REVOKE_WHOLECHAIN = 1 + + WTD_CHOICE_FILE = 1 + WTD_CHOICE_CATALOG = 2 + WTD_CHOICE_BLOB = 3 + WTD_CHOICE_SIGNER = 4 + WTD_CHOICE_CERT = 5 + + WTD_STATEACTION_IGNORE = 0x00000000 + WTD_STATEACTION_VERIFY = 0x00000010 + WTD_STATEACTION_CLOSE = 0x00000002 + WTD_STATEACTION_AUTO_CACHE = 0x00000003 + WTD_STATEACTION_AUTO_CACHE_FLUSH = 0x00000004 + + WTD_USE_IE4_TRUST_FLAG = 0x1 + WTD_NO_IE4_CHAIN_FLAG = 0x2 + WTD_NO_POLICY_USAGE_FLAG = 0x4 + WTD_REVOCATION_CHECK_NONE = 0x10 + WTD_REVOCATION_CHECK_END_CERT = 0x20 + WTD_REVOCATION_CHECK_CHAIN = 0x40 + WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x80 + WTD_SAFER_FLAG = 0x100 + WTD_HASH_ONLY_FLAG = 0x200 + WTD_USE_DEFAULT_OSVER_CHECK = 0x400 + WTD_LIFETIME_SIGNING_FLAG = 0x800 + WTD_CACHE_ONLY_URL_RETRIEVAL = 0x1000 + WTD_DISABLE_MD2_MD4 = 0x2000 + WTD_MOTW = 0x4000 + + WTD_UICONTEXT_EXECUTE = 0 + WTD_UICONTEXT_INSTALL = 1 +) + var ( OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00") OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00") OID_SGC_NETSCAPE = []byte("2.16.840.1.113730.4.1\x00") + + WINTRUST_ACTION_GENERIC_VERIFY_V2 = GUID{ + Data1: 0xaac56b, + Data2: 0xcd44, + Data3: 0x11d0, + Data4: [8]byte{0x8c, 0xc2, 0x0, 0xc0, 0x4f, 0xc2, 0x95, 0xee}, + } ) // Pointer represents a pointer to an arbitrary Windows type. @@ -1051,7 +1176,57 @@ type MibIfRow struct { } type CertInfo struct { - // Not implemented + Version uint32 + SerialNumber CryptIntegerBlob + SignatureAlgorithm CryptAlgorithmIdentifier + Issuer CertNameBlob + NotBefore Filetime + NotAfter Filetime + Subject CertNameBlob + SubjectPublicKeyInfo CertPublicKeyInfo + IssuerUniqueId CryptBitBlob + SubjectUniqueId CryptBitBlob + CountExtensions uint32 + Extensions *CertExtension +} + +type CertExtension struct { + ObjId *byte + Critical int32 + Value CryptObjidBlob +} + +type CryptAlgorithmIdentifier struct { + ObjId *byte + Parameters CryptObjidBlob +} + +type CertPublicKeyInfo struct { + Algorithm CryptAlgorithmIdentifier + PublicKey CryptBitBlob +} + +type DataBlob struct { + Size uint32 + Data *byte +} +type CryptIntegerBlob DataBlob +type CryptUintBlob DataBlob +type CryptObjidBlob DataBlob +type CertNameBlob DataBlob +type CertRdnValueBlob DataBlob +type CertBlob DataBlob +type CrlBlob DataBlob +type CryptDataBlob DataBlob +type CryptHashBlob DataBlob +type CryptDigestBlob DataBlob +type CryptDerBlob DataBlob +type CryptAttrBlob DataBlob + +type CryptBitBlob struct { + Size uint32 + Data *byte + UnusedBits uint32 } type CertContext struct { @@ -1157,9 +1332,64 @@ type CertChainPolicyStatus struct { ExtraPolicyStatus Pointer } -type CryptDataBlob struct { - Size uint32 - Data *byte +type CertPolicyInfo struct { + Identifier *byte + CountQualifiers uint32 + Qualifiers *CertPolicyQualifierInfo +} + +type CertPoliciesInfo struct { + Count uint32 + PolicyInfos *CertPolicyInfo +} + +type CertPolicyQualifierInfo struct { + // Not implemented +} + +type CertStrongSignPara struct { + Size uint32 + InfoChoice uint32 + InfoOrSerializedInfoOrOID unsafe.Pointer +} + +type CryptProtectPromptStruct struct { + Size uint32 + PromptFlags uint32 + App HWND + Prompt *uint16 +} + +type WinTrustData struct { + Size uint32 + PolicyCallbackData uintptr + SIPClientData uintptr + UIChoice uint32 + RevocationChecks uint32 + UnionChoice uint32 + FileOrCatalogOrBlobOrSgnrOrCert unsafe.Pointer + StateAction uint32 + StateData Handle + URLReference *uint16 + ProvFlags uint32 + UIContext uint32 + SignatureSettings *WinTrustSignatureSettings +} + +type WinTrustFileInfo struct { + Size uint32 + FilePath *uint16 + File Handle + KnownSubject *GUID +} + +type WinTrustSignatureSettings struct { + Size uint32 + Index uint32 + Flags uint32 + SecondarySigs uint32 + VerifiedSigIndex uint32 + CryptoPolicy *CertStrongSignPara } const ( diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index cd5e8528cd799..c38c59d772c42 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -51,6 +51,7 @@ var ( modshell32 = NewLazySystemDLL("shell32.dll") moduser32 = NewLazySystemDLL("user32.dll") moduserenv = NewLazySystemDLL("userenv.dll") + modwintrust = NewLazySystemDLL("wintrust.dll") modws2_32 = NewLazySystemDLL("ws2_32.dll") modwtsapi32 = NewLazySystemDLL("wtsapi32.dll") @@ -145,12 +146,18 @@ var ( procCertDeleteCertificateFromStore = modcrypt32.NewProc("CertDeleteCertificateFromStore") procCertDuplicateCertificateContext = modcrypt32.NewProc("CertDuplicateCertificateContext") procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore") + procCertFindExtension = modcrypt32.NewProc("CertFindExtension") procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain") procCertFreeCertificateContext = modcrypt32.NewProc("CertFreeCertificateContext") procCertGetCertificateChain = modcrypt32.NewProc("CertGetCertificateChain") + procCertGetNameStringW = modcrypt32.NewProc("CertGetNameStringW") procCertOpenStore = modcrypt32.NewProc("CertOpenStore") procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy") + procCryptDecodeObject = modcrypt32.NewProc("CryptDecodeObject") + procCryptProtectData = modcrypt32.NewProc("CryptProtectData") + procCryptQueryObject = modcrypt32.NewProc("CryptQueryObject") + procCryptUnprotectData = modcrypt32.NewProc("CryptUnprotectData") procPFXImportCertStore = modcrypt32.NewProc("PFXImportCertStore") procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") @@ -183,9 +190,12 @@ var ( procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") procExitProcess = modkernel32.NewProc("ExitProcess") procFindClose = modkernel32.NewProc("FindClose") + procFindCloseChangeNotification = modkernel32.NewProc("FindCloseChangeNotification") + procFindFirstChangeNotificationW = modkernel32.NewProc("FindFirstChangeNotificationW") procFindFirstFileW = modkernel32.NewProc("FindFirstFileW") procFindFirstVolumeMountPointW = modkernel32.NewProc("FindFirstVolumeMountPointW") procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") + procFindNextChangeNotification = modkernel32.NewProc("FindNextChangeNotification") procFindNextFileW = modkernel32.NewProc("FindNextFileW") procFindNextVolumeMountPointW = modkernel32.NewProc("FindNextVolumeMountPointW") procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") @@ -347,6 +357,7 @@ var ( procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") + procWinVerifyTrustEx = modwintrust.NewProc("WinVerifyTrustEx") procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") procWSACleanup = modws2_32.NewProc("WSACleanup") @@ -1199,6 +1210,12 @@ func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (contex return } +func CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) { + r0, _, _ := syscall.Syscall(procCertFindExtension.Addr(), 3, uintptr(unsafe.Pointer(objId)), uintptr(countExtensions), uintptr(unsafe.Pointer(extensions))) + ret = (*CertExtension)(unsafe.Pointer(r0)) + return +} + func CertFreeCertificateChain(ctx *CertChainContext) { syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) return @@ -1220,6 +1237,12 @@ func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, a return } +func CertGetNameString(certContext *CertContext, nameType uint32, flags uint32, typePara unsafe.Pointer, name *uint16, size uint32) (chars uint32) { + r0, _, _ := syscall.Syscall6(procCertGetNameStringW.Addr(), 6, uintptr(unsafe.Pointer(certContext)), uintptr(nameType), uintptr(flags), uintptr(typePara), uintptr(unsafe.Pointer(name)), uintptr(size)) + chars = uint32(r0) + return +} + func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) { r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0) handle = Handle(r0) @@ -1246,6 +1269,38 @@ func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext return } +func CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procCryptDecodeObject.Addr(), 7, uintptr(encodingType), uintptr(unsafe.Pointer(structType)), uintptr(unsafe.Pointer(encodedBytes)), uintptr(lenEncodedBytes), uintptr(flags), uintptr(decoded), uintptr(unsafe.Pointer(decodedLen)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { + r1, _, e1 := syscall.Syscall9(procCryptProtectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) { + r1, _, e1 := syscall.Syscall12(procCryptQueryObject.Addr(), 11, uintptr(objectType), uintptr(object), uintptr(expectedContentTypeFlags), uintptr(expectedFormatTypeFlags), uintptr(flags), uintptr(unsafe.Pointer(msgAndCertEncodingType)), uintptr(unsafe.Pointer(contentType)), uintptr(unsafe.Pointer(formatType)), uintptr(unsafe.Pointer(certStore)), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(context)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { + r1, _, e1 := syscall.Syscall9(procCryptUnprotectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) { r0, _, e1 := syscall.Syscall(procPFXImportCertStore.Addr(), 3, uintptr(unsafe.Pointer(pfx)), uintptr(unsafe.Pointer(password)), uintptr(flags)) store = Handle(r0) @@ -1525,6 +1580,36 @@ func FindClose(handle Handle) (err error) { return } +func FindCloseChangeNotification(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindCloseChangeNotification.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(path) + if err != nil { + return + } + return _FindFirstChangeNotification(_p0, watchSubtree, notifyFilter) +} + +func _FindFirstChangeNotification(path *uint16, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) { + var _p1 uint32 + if watchSubtree { + _p1 = 1 + } + r0, _, e1 := syscall.Syscall(procFindFirstChangeNotificationW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(_p1), uintptr(notifyFilter)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) { r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0) handle = Handle(r0) @@ -1552,6 +1637,14 @@ func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, er return } +func FindNextChangeNotification(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextChangeNotification.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func findNextFile1(handle Handle, data *win32finddata1) (err error) { r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) if r1 == 0 { @@ -2904,9 +2997,12 @@ func GetShellWindow() (shellWindow HWND) { return } -func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32) { - r0, _, _ := syscall.Syscall(procGetWindowThreadProcessId.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(pid)), 0) +func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetWindowThreadProcessId.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(pid)), 0) tid = uint32(r0) + if tid == 0 { + err = errnoErr(e1) + } return } @@ -2947,6 +3043,14 @@ func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { return } +func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) { + r0, _, _ := syscall.Syscall(procWinVerifyTrustEx.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + func FreeAddrInfoW(addrinfo *AddrinfoW) { syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0) return diff --git a/vendor/golang.org/x/text/encoding/simplifiedchinese/hzgb2312.go b/vendor/golang.org/x/text/encoding/simplifiedchinese/hzgb2312.go index eb3157f0b20ef..e15b7bf6a7c78 100644 --- a/vendor/golang.org/x/text/encoding/simplifiedchinese/hzgb2312.go +++ b/vendor/golang.org/x/text/encoding/simplifiedchinese/hzgb2312.go @@ -57,7 +57,7 @@ loop: err = transform.ErrShortSrc break loop } - r = utf8.RuneError + r, size = utf8.RuneError, 1 goto write } size = 2 diff --git a/vendor/golang.org/x/text/internal/language/parse.go b/vendor/golang.org/x/text/internal/language/parse.go index 2be83e1da5420..a2fdad89db43e 100644 --- a/vendor/golang.org/x/text/internal/language/parse.go +++ b/vendor/golang.org/x/text/internal/language/parse.go @@ -133,14 +133,15 @@ func (s *scanner) resizeRange(oldStart, oldEnd, newSize int) { s.start = oldStart if end := oldStart + newSize; end != oldEnd { diff := end - oldEnd - if end < cap(s.b) { - b := make([]byte, len(s.b)+diff) + var b []byte + if n := len(s.b) + diff; n > cap(s.b) { + b = make([]byte, n) copy(b, s.b[:oldStart]) - copy(b[end:], s.b[oldEnd:]) - s.b = b } else { - s.b = append(s.b[end:], s.b[oldEnd:]...) + b = s.b[:n:n] } + copy(b[end:], s.b[oldEnd:]) + s.b = b s.next = end + (s.next - s.end) s.end = end } diff --git a/vendor/golang.org/x/text/unicode/bidi/bidi.go b/vendor/golang.org/x/text/unicode/bidi/bidi.go index e8edc54cc28d2..fd057601bd917 100644 --- a/vendor/golang.org/x/text/unicode/bidi/bidi.go +++ b/vendor/golang.org/x/text/unicode/bidi/bidi.go @@ -12,15 +12,14 @@ // and without notice. package bidi // import "golang.org/x/text/unicode/bidi" -// TODO: -// The following functionality would not be hard to implement, but hinges on -// the definition of a Segmenter interface. For now this is up to the user. -// - Iterate over paragraphs -// - Segmenter to iterate over runs directly from a given text. -// Also: +// TODO // - Transformer for reordering? // - Transformer (validator, really) for Bidi Rule. +import ( + "bytes" +) + // This API tries to avoid dealing with embedding levels for now. Under the hood // these will be computed, but the question is to which extent the user should // know they exist. We should at some point allow the user to specify an @@ -49,7 +48,9 @@ const ( Neutral ) -type options struct{} +type options struct { + defaultDirection Direction +} // An Option is an option for Bidi processing. type Option func(*options) @@ -66,12 +67,62 @@ type Option func(*options) // DefaultDirection sets the default direction for a Paragraph. The direction is // overridden if the text contains directional characters. func DefaultDirection(d Direction) Option { - panic("unimplemented") + return func(opts *options) { + opts.defaultDirection = d + } } // A Paragraph holds a single Paragraph for Bidi processing. type Paragraph struct { - // buffers + p []byte + o Ordering + opts []Option + types []Class + pairTypes []bracketType + pairValues []rune + runes []rune + options options +} + +// Initialize the p.pairTypes, p.pairValues and p.types from the input previously +// set by p.SetBytes() or p.SetString(). Also limit the input up to (and including) a paragraph +// separator (bidi class B). +// +// The function p.Order() needs these values to be set, so this preparation could be postponed. +// But since the SetBytes and SetStrings functions return the length of the input up to the paragraph +// separator, the whole input needs to be processed anyway and should not be done twice. +// +// The function has the same return values as SetBytes() / SetString() +func (p *Paragraph) prepareInput() (n int, err error) { + p.runes = bytes.Runes(p.p) + bytecount := 0 + // clear slices from previous SetString or SetBytes + p.pairTypes = nil + p.pairValues = nil + p.types = nil + + for _, r := range p.runes { + props, i := LookupRune(r) + bytecount += i + cls := props.Class() + if cls == B { + return bytecount, nil + } + p.types = append(p.types, cls) + if props.IsOpeningBracket() { + p.pairTypes = append(p.pairTypes, bpOpen) + p.pairValues = append(p.pairValues, r) + } else if props.IsBracket() { + // this must be a closing bracket, + // since IsOpeningBracket is not true + p.pairTypes = append(p.pairTypes, bpClose) + p.pairValues = append(p.pairValues, r) + } else { + p.pairTypes = append(p.pairTypes, bpNone) + p.pairValues = append(p.pairValues, 0) + } + } + return bytecount, nil } // SetBytes configures p for the given paragraph text. It replaces text @@ -80,70 +131,150 @@ type Paragraph struct { // consumed from b including this separator. Error may be non-nil if options are // given. func (p *Paragraph) SetBytes(b []byte, opts ...Option) (n int, err error) { - panic("unimplemented") + p.p = b + p.opts = opts + return p.prepareInput() } -// SetString configures p for the given paragraph text. It replaces text -// previously set by SetBytes or SetString. If b contains a paragraph separator +// SetString configures s for the given paragraph text. It replaces text +// previously set by SetBytes or SetString. If s contains a paragraph separator // it will only process the first paragraph and report the number of bytes -// consumed from b including this separator. Error may be non-nil if options are +// consumed from s including this separator. Error may be non-nil if options are // given. func (p *Paragraph) SetString(s string, opts ...Option) (n int, err error) { - panic("unimplemented") + p.p = []byte(s) + p.opts = opts + return p.prepareInput() } // IsLeftToRight reports whether the principle direction of rendering for this // paragraphs is left-to-right. If this returns false, the principle direction // of rendering is right-to-left. func (p *Paragraph) IsLeftToRight() bool { - panic("unimplemented") + return p.Direction() == LeftToRight } // Direction returns the direction of the text of this paragraph. // // The direction may be LeftToRight, RightToLeft, Mixed, or Neutral. func (p *Paragraph) Direction() Direction { - panic("unimplemented") + return p.o.Direction() } +// TODO: what happens if the position is > len(input)? This should return an error. + // RunAt reports the Run at the given position of the input text. // // This method can be used for computing line breaks on paragraphs. func (p *Paragraph) RunAt(pos int) Run { - panic("unimplemented") + c := 0 + runNumber := 0 + for i, r := range p.o.runes { + c += len(r) + if pos < c { + runNumber = i + } + } + return p.o.Run(runNumber) +} + +func calculateOrdering(levels []level, runes []rune) Ordering { + var curDir Direction + + prevDir := Neutral + prevI := 0 + + o := Ordering{} + // lvl = 0,2,4,...: left to right + // lvl = 1,3,5,...: right to left + for i, lvl := range levels { + if lvl%2 == 0 { + curDir = LeftToRight + } else { + curDir = RightToLeft + } + if curDir != prevDir { + if i > 0 { + o.runes = append(o.runes, runes[prevI:i]) + o.directions = append(o.directions, prevDir) + o.startpos = append(o.startpos, prevI) + } + prevI = i + prevDir = curDir + } + } + o.runes = append(o.runes, runes[prevI:]) + o.directions = append(o.directions, prevDir) + o.startpos = append(o.startpos, prevI) + return o } // Order computes the visual ordering of all the runs in a Paragraph. func (p *Paragraph) Order() (Ordering, error) { - panic("unimplemented") + if len(p.types) == 0 { + return Ordering{}, nil + } + + for _, fn := range p.opts { + fn(&p.options) + } + lvl := level(-1) + if p.options.defaultDirection == RightToLeft { + lvl = 1 + } + para, err := newParagraph(p.types, p.pairTypes, p.pairValues, lvl) + if err != nil { + return Ordering{}, err + } + + levels := para.getLevels([]int{len(p.types)}) + + p.o = calculateOrdering(levels, p.runes) + return p.o, nil } // Line computes the visual ordering of runs for a single line starting and // ending at the given positions in the original text. func (p *Paragraph) Line(start, end int) (Ordering, error) { - panic("unimplemented") + lineTypes := p.types[start:end] + para, err := newParagraph(lineTypes, p.pairTypes[start:end], p.pairValues[start:end], -1) + if err != nil { + return Ordering{}, err + } + levels := para.getLevels([]int{len(lineTypes)}) + o := calculateOrdering(levels, p.runes[start:end]) + return o, nil } // An Ordering holds the computed visual order of runs of a Paragraph. Calling // SetBytes or SetString on the originating Paragraph invalidates an Ordering. // The methods of an Ordering should only be called by one goroutine at a time. -type Ordering struct{} +type Ordering struct { + runes [][]rune + directions []Direction + startpos []int +} // Direction reports the directionality of the runs. // // The direction may be LeftToRight, RightToLeft, Mixed, or Neutral. func (o *Ordering) Direction() Direction { - panic("unimplemented") + return o.directions[0] } // NumRuns returns the number of runs. func (o *Ordering) NumRuns() int { - panic("unimplemented") + return len(o.runes) } // Run returns the ith run within the ordering. func (o *Ordering) Run(i int) Run { - panic("unimplemented") + r := Run{ + runes: o.runes[i], + direction: o.directions[i], + startpos: o.startpos[i], + } + return r } // TODO: perhaps with options. @@ -155,16 +286,19 @@ func (o *Ordering) Run(i int) Run { // A Run is a continuous sequence of characters of a single direction. type Run struct { + runes []rune + direction Direction + startpos int } // String returns the text of the run in its original order. func (r *Run) String() string { - panic("unimplemented") + return string(r.runes) } // Bytes returns the text of the run in its original order. func (r *Run) Bytes() []byte { - panic("unimplemented") + return []byte(r.String()) } // TODO: methods for @@ -174,25 +308,52 @@ func (r *Run) Bytes() []byte { // Direction reports the direction of the run. func (r *Run) Direction() Direction { - panic("unimplemented") + return r.direction } -// Position of the Run within the text passed to SetBytes or SetString of the +// Pos returns the position of the Run within the text passed to SetBytes or SetString of the // originating Paragraph value. func (r *Run) Pos() (start, end int) { - panic("unimplemented") + return r.startpos, r.startpos + len(r.runes) - 1 } // AppendReverse reverses the order of characters of in, appends them to out, // and returns the result. Modifiers will still follow the runes they modify. // Brackets are replaced with their counterparts. func AppendReverse(out, in []byte) []byte { - panic("unimplemented") + ret := make([]byte, len(in)+len(out)) + copy(ret, out) + inRunes := bytes.Runes(in) + + for i, r := range inRunes { + prop, _ := LookupRune(r) + if prop.IsBracket() { + inRunes[i] = prop.reverseBracket(r) + } + } + + for i, j := 0, len(inRunes)-1; i < j; i, j = i+1, j-1 { + inRunes[i], inRunes[j] = inRunes[j], inRunes[i] + } + copy(ret[len(out):], string(inRunes)) + + return ret } // ReverseString reverses the order of characters in s and returns a new string. // Modifiers will still follow the runes they modify. Brackets are replaced with // their counterparts. func ReverseString(s string) string { - panic("unimplemented") + input := []rune(s) + li := len(input) + ret := make([]rune, li) + for i, r := range input { + prop, _ := LookupRune(r) + if prop.IsBracket() { + ret[li-i-1] = prop.reverseBracket(r) + } else { + ret[li-i-1] = r + } + } + return string(ret) } diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go index 50deb6600a3c0..e4c0811016c2a 100644 --- a/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -4,7 +4,10 @@ package bidi -import "log" +import ( + "fmt" + "log" +) // This implementation is a port based on the reference implementation found at: // https://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/ @@ -97,13 +100,20 @@ type paragraph struct { // rune (suggested is the rune of the open bracket for opening and matching // close brackets, after normalization). The embedding levels are optional, but // may be supplied to encode embedding levels of styled text. -// -// TODO: return an error. -func newParagraph(types []Class, pairTypes []bracketType, pairValues []rune, levels level) *paragraph { - validateTypes(types) - validatePbTypes(pairTypes) - validatePbValues(pairValues, pairTypes) - validateParagraphEmbeddingLevel(levels) +func newParagraph(types []Class, pairTypes []bracketType, pairValues []rune, levels level) (*paragraph, error) { + var err error + if err = validateTypes(types); err != nil { + return nil, err + } + if err = validatePbTypes(pairTypes); err != nil { + return nil, err + } + if err = validatePbValues(pairValues, pairTypes); err != nil { + return nil, err + } + if err = validateParagraphEmbeddingLevel(levels); err != nil { + return nil, err + } p := ¶graph{ initialTypes: append([]Class(nil), types...), @@ -115,7 +125,7 @@ func newParagraph(types []Class, pairTypes []bracketType, pairValues []rune, lev resultTypes: append([]Class(nil), types...), } p.run() - return p + return p, nil } func (p *paragraph) Len() int { return len(p.initialTypes) } @@ -1001,58 +1011,61 @@ func typeForLevel(level level) Class { return R } -// TODO: change validation to not panic - -func validateTypes(types []Class) { +func validateTypes(types []Class) error { if len(types) == 0 { - log.Panic("types is null") + return fmt.Errorf("types is null") } for i, t := range types[:len(types)-1] { if t == B { - log.Panicf("B type before end of paragraph at index: %d", i) + return fmt.Errorf("B type before end of paragraph at index: %d", i) } } + return nil } -func validateParagraphEmbeddingLevel(embeddingLevel level) { +func validateParagraphEmbeddingLevel(embeddingLevel level) error { if embeddingLevel != implicitLevel && embeddingLevel != 0 && embeddingLevel != 1 { - log.Panicf("illegal paragraph embedding level: %d", embeddingLevel) + return fmt.Errorf("illegal paragraph embedding level: %d", embeddingLevel) } + return nil } -func validateLineBreaks(linebreaks []int, textLength int) { +func validateLineBreaks(linebreaks []int, textLength int) error { prev := 0 for i, next := range linebreaks { if next <= prev { - log.Panicf("bad linebreak: %d at index: %d", next, i) + return fmt.Errorf("bad linebreak: %d at index: %d", next, i) } prev = next } if prev != textLength { - log.Panicf("last linebreak was %d, want %d", prev, textLength) + return fmt.Errorf("last linebreak was %d, want %d", prev, textLength) } + return nil } -func validatePbTypes(pairTypes []bracketType) { +func validatePbTypes(pairTypes []bracketType) error { if len(pairTypes) == 0 { - log.Panic("pairTypes is null") + return fmt.Errorf("pairTypes is null") } for i, pt := range pairTypes { switch pt { case bpNone, bpOpen, bpClose: default: - log.Panicf("illegal pairType value at %d: %v", i, pairTypes[i]) + return fmt.Errorf("illegal pairType value at %d: %v", i, pairTypes[i]) } } + return nil } -func validatePbValues(pairValues []rune, pairTypes []bracketType) { +func validatePbValues(pairValues []rune, pairTypes []bracketType) error { if pairValues == nil { - log.Panic("pairValues is null") + return fmt.Errorf("pairValues is null") } if len(pairTypes) != len(pairValues) { - log.Panic("pairTypes is different length from pairValues") + return fmt.Errorf("pairTypes is different length from pairValues") } + return nil } diff --git a/vendor/golang.org/x/tools/go/analysis/analysis.go b/vendor/golang.org/x/tools/go/analysis/analysis.go index 8c3c2e7ab950f..d11505a165c86 100644 --- a/vendor/golang.org/x/tools/go/analysis/analysis.go +++ b/vendor/golang.org/x/tools/go/analysis/analysis.go @@ -1,3 +1,7 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package analysis import ( diff --git a/vendor/golang.org/x/tools/go/analysis/diagnostic.go b/vendor/golang.org/x/tools/go/analysis/diagnostic.go index 57eaf6faa2ac7..cd462a0cb5544 100644 --- a/vendor/golang.org/x/tools/go/analysis/diagnostic.go +++ b/vendor/golang.org/x/tools/go/analysis/diagnostic.go @@ -1,3 +1,7 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package analysis import "go/token" diff --git a/vendor/golang.org/x/tools/go/analysis/doc.go b/vendor/golang.org/x/tools/go/analysis/doc.go index 9fa3302dfbe99..94a3bd5d07cac 100644 --- a/vendor/golang.org/x/tools/go/analysis/doc.go +++ b/vendor/golang.org/x/tools/go/analysis/doc.go @@ -1,3 +1,7 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + /* Package analysis defines the interface between a modular static diff --git a/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/help.go b/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/help.go index c5a70f3b7d65a..ce92892c81769 100644 --- a/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/help.go +++ b/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/help.go @@ -1,3 +1,7 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package analysisflags import ( diff --git a/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go b/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go index 683b7e91d25e5..9051456e396ff 100644 --- a/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go +++ b/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go @@ -1,3 +1,7 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + // +build go1.12 package unitchecker diff --git a/vendor/golang.org/x/tools/go/analysis/validate.go b/vendor/golang.org/x/tools/go/analysis/validate.go index ad0e7276c915f..23e57bf02b66a 100644 --- a/vendor/golang.org/x/tools/go/analysis/validate.go +++ b/vendor/golang.org/x/tools/go/analysis/validate.go @@ -1,3 +1,7 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package analysis import ( diff --git a/vendor/golang.org/x/tools/go/ast/astutil/util.go b/vendor/golang.org/x/tools/go/ast/astutil/util.go index 7630629824af1..919d5305ab422 100644 --- a/vendor/golang.org/x/tools/go/ast/astutil/util.go +++ b/vendor/golang.org/x/tools/go/ast/astutil/util.go @@ -1,3 +1,7 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package astutil import "go/ast" diff --git a/vendor/golang.org/x/tools/go/buildutil/fakecontext.go b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go index 8b7f066739f1d..5fc672fd519c9 100644 --- a/vendor/golang.org/x/tools/go/buildutil/fakecontext.go +++ b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go @@ -1,3 +1,7 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package buildutil import ( diff --git a/vendor/golang.org/x/tools/go/buildutil/tags.go b/vendor/golang.org/x/tools/go/buildutil/tags.go index 486606f3768db..6da0ce4848e1a 100644 --- a/vendor/golang.org/x/tools/go/buildutil/tags.go +++ b/vendor/golang.org/x/tools/go/buildutil/tags.go @@ -1,3 +1,7 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package buildutil // This logic was copied from stringsFlag from $GOROOT/src/cmd/go/build.go. diff --git a/vendor/golang.org/x/tools/go/internal/cgo/cgo.go b/vendor/golang.org/x/tools/go/internal/cgo/cgo.go index 5db8b309676d5..9772504c97cfe 100644 --- a/vendor/golang.org/x/tools/go/internal/cgo/cgo.go +++ b/vendor/golang.org/x/tools/go/internal/cgo/cgo.go @@ -57,10 +57,10 @@ import ( "go/build" "go/parser" "go/token" + exec "golang.org/x/sys/execabs" "io/ioutil" "log" "os" - "os/exec" "path/filepath" "regexp" "strings" diff --git a/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go b/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go index b5bb95a63e505..7d94bbc1e5ff0 100644 --- a/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go +++ b/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go @@ -8,7 +8,7 @@ import ( "errors" "fmt" "go/build" - "os/exec" + exec "golang.org/x/sys/execabs" "strings" ) diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go index 35bc6a4127ac5..f4d73b23391fc 100644 --- a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go +++ b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go @@ -6,12 +6,9 @@ package packagesdriver import ( - "bytes" "context" - "encoding/json" "fmt" "go/types" - "os/exec" "strings" "golang.org/x/tools/internal/gocommand" @@ -19,67 +16,6 @@ import ( var debug = false -func GetSizes(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) { - // TODO(matloob): Clean this up. This code is mostly a copy of packages.findExternalDriver. - const toolPrefix = "GOPACKAGESDRIVER=" - tool := "" - for _, env := range env { - if val := strings.TrimPrefix(env, toolPrefix); val != env { - tool = val - } - } - - if tool == "" { - var err error - tool, err = exec.LookPath("gopackagesdriver") - if err != nil { - // We did not find the driver, so use "go list". - tool = "off" - } - } - - if tool == "off" { - inv := gocommand.Invocation{ - BuildFlags: buildFlags, - Env: env, - WorkingDir: dir, - } - return GetSizesGolist(ctx, inv, gocmdRunner) - } - - req, err := json.Marshal(struct { - Command string `json:"command"` - Env []string `json:"env"` - BuildFlags []string `json:"build_flags"` - }{ - Command: "sizes", - Env: env, - BuildFlags: buildFlags, - }) - if err != nil { - return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) - } - - buf := new(bytes.Buffer) - cmd := exec.CommandContext(ctx, tool) - cmd.Dir = dir - cmd.Env = env - cmd.Stdin = bytes.NewReader(req) - cmd.Stdout = buf - cmd.Stderr = new(bytes.Buffer) - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) - } - var response struct { - // Sizes, if not nil, is the types.Sizes to use when type checking. - Sizes *types.StdSizes - } - if err := json.Unmarshal(buf.Bytes(), &response); err != nil { - return nil, err - } - return response.Sizes, nil -} - func GetSizesGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (types.Sizes, error) { inv.Verb = "list" inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"} diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go index 8c8473fd0bd26..7242a0a7d2bef 100644 --- a/vendor/golang.org/x/tools/go/packages/external.go +++ b/vendor/golang.org/x/tools/go/packages/external.go @@ -12,8 +12,8 @@ import ( "bytes" "encoding/json" "fmt" + exec "golang.org/x/sys/execabs" "os" - "os/exec" "strings" ) @@ -89,7 +89,7 @@ func findExternalDriver(cfg *Config) driver { return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) } if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" { - fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd, words...), stderr) + fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr) } var response driverResponse diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go index 787783cd9f53f..ec417ba830e1f 100644 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -10,9 +10,10 @@ import ( "encoding/json" "fmt" "go/types" + exec "golang.org/x/sys/execabs" + "io/ioutil" "log" "os" - "os/exec" "path" "path/filepath" "reflect" @@ -208,56 +209,58 @@ extractQueries: } } - modifiedPkgs, needPkgs, err := state.processGolistOverlay(response) - if err != nil { - return nil, err - } + // Only use go/packages' overlay processing if we're using a Go version + // below 1.16. Otherwise, go list handles it. + if goVersion, err := state.getGoVersion(); err == nil && goVersion < 16 { + modifiedPkgs, needPkgs, err := state.processGolistOverlay(response) + if err != nil { + return nil, err + } - var containsCandidates []string - if len(containFiles) > 0 { - containsCandidates = append(containsCandidates, modifiedPkgs...) - containsCandidates = append(containsCandidates, needPkgs...) - } - if err := state.addNeededOverlayPackages(response, needPkgs); err != nil { - return nil, err - } - // Check candidate packages for containFiles. - if len(containFiles) > 0 { - for _, id := range containsCandidates { - pkg, ok := response.seenPackages[id] - if !ok { - response.addPackage(&Package{ - ID: id, - Errors: []Error{ - { + var containsCandidates []string + if len(containFiles) > 0 { + containsCandidates = append(containsCandidates, modifiedPkgs...) + containsCandidates = append(containsCandidates, needPkgs...) + } + if err := state.addNeededOverlayPackages(response, needPkgs); err != nil { + return nil, err + } + // Check candidate packages for containFiles. + if len(containFiles) > 0 { + for _, id := range containsCandidates { + pkg, ok := response.seenPackages[id] + if !ok { + response.addPackage(&Package{ + ID: id, + Errors: []Error{{ Kind: ListError, Msg: fmt.Sprintf("package %s expected but not seen", id), - }, - }, - }) - continue - } - for _, f := range containFiles { - for _, g := range pkg.GoFiles { - if sameFile(f, g) { - response.addRoot(id) + }}, + }) + continue + } + for _, f := range containFiles { + for _, g := range pkg.GoFiles { + if sameFile(f, g) { + response.addRoot(id) + } } } } } - } - // Add root for any package that matches a pattern. This applies only to - // packages that are modified by overlays, since they are not added as - // roots automatically. - for _, pattern := range restPatterns { - match := matchPattern(pattern) - for _, pkgID := range modifiedPkgs { - pkg, ok := response.seenPackages[pkgID] - if !ok { - continue - } - if match(pkg.PkgPath) { - response.addRoot(pkg.ID) + // Add root for any package that matches a pattern. This applies only to + // packages that are modified by overlays, since they are not added as + // roots automatically. + for _, pattern := range restPatterns { + match := matchPattern(pattern) + for _, pkgID := range modifiedPkgs { + pkg, ok := response.seenPackages[pkgID] + if !ok { + continue + } + if match(pkg.PkgPath) { + response.addRoot(pkg.ID) + } } } } @@ -824,6 +827,7 @@ func (state *golistState) cfgInvocation() gocommand.Invocation { BuildFlags: cfg.BuildFlags, ModFile: cfg.modFile, ModFlag: cfg.modFlag, + CleanEnv: cfg.Env != nil, Env: cfg.Env, Logf: cfg.Logf, WorkingDir: cfg.Dir, @@ -835,6 +839,26 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, cfg := state.cfg inv := state.cfgInvocation() + + // For Go versions 1.16 and above, `go list` accepts overlays directly via + // the -overlay flag. Set it, if it's available. + // + // The check for "list" is not necessarily required, but we should avoid + // getting the go version if possible. + if verb == "list" { + goVersion, err := state.getGoVersion() + if err != nil { + return nil, err + } + if goVersion >= 16 { + filename, cleanup, err := state.writeOverlays() + if err != nil { + return nil, err + } + defer cleanup() + inv.Overlay = filename + } + } inv.Verb = verb inv.Args = args gocmdRunner := cfg.gocmdRunner @@ -878,8 +902,13 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) && !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r) } + // golang/go#36770: Handle case where cmd/go prints module download messages before the error. + msg := stderr.String() + for strings.HasPrefix(msg, "go: downloading") { + msg = msg[strings.IndexRune(msg, '\n')+1:] + } if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") { - msg := stderr.String()[len("# "):] + msg := msg[len("# "):] if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") { return stdout, nil } @@ -976,6 +1005,67 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, return stdout, nil } +// OverlayJSON is the format overlay files are expected to be in. +// The Replace map maps from overlaid paths to replacement paths: +// the Go command will forward all reads trying to open +// each overlaid path to its replacement path, or consider the overlaid +// path not to exist if the replacement path is empty. +// +// From golang/go#39958. +type OverlayJSON struct { + Replace map[string]string `json:"replace,omitempty"` +} + +// writeOverlays writes out files for go list's -overlay flag, as described +// above. +func (state *golistState) writeOverlays() (filename string, cleanup func(), err error) { + // Do nothing if there are no overlays in the config. + if len(state.cfg.Overlay) == 0 { + return "", func() {}, nil + } + dir, err := ioutil.TempDir("", "gopackages-*") + if err != nil { + return "", nil, err + } + // The caller must clean up this directory, unless this function returns an + // error. + cleanup = func() { + os.RemoveAll(dir) + } + defer func() { + if err != nil { + cleanup() + } + }() + overlays := map[string]string{} + for k, v := range state.cfg.Overlay { + // Create a unique filename for the overlaid files, to avoid + // creating nested directories. + noSeparator := strings.Join(strings.Split(filepath.ToSlash(k), "/"), "") + f, err := ioutil.TempFile(dir, fmt.Sprintf("*-%s", noSeparator)) + if err != nil { + return "", func() {}, err + } + if _, err := f.Write(v); err != nil { + return "", func() {}, err + } + if err := f.Close(); err != nil { + return "", func() {}, err + } + overlays[k] = f.Name() + } + b, err := json.Marshal(OverlayJSON{Replace: overlays}) + if err != nil { + return "", func() {}, err + } + // Write out the overlay file that contains the filepath mappings. + filename = filepath.Join(dir, "overlay.json") + if err := ioutil.WriteFile(filename, b, 0665); err != nil { + return "", func() {}, err + } + return filename, cleanup, nil +} + func containsGoFile(s []string) bool { for _, f := range s { if strings.HasSuffix(f, ".go") { @@ -985,17 +1075,22 @@ func containsGoFile(s []string) bool { return false } -func cmdDebugStr(cmd *exec.Cmd, args ...string) string { +func cmdDebugStr(cmd *exec.Cmd) string { env := make(map[string]string) for _, kv := range cmd.Env { - split := strings.Split(kv, "=") + split := strings.SplitN(kv, "=", 2) k, v := split[0], split[1] env[k] = v } - var quotedArgs []string - for _, arg := range args { - quotedArgs = append(quotedArgs, strconv.Quote(arg)) - } - return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v PWD=%v go %s", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["PWD"], strings.Join(quotedArgs, " ")) + var args []string + for _, arg := range cmd.Args { + quoted := strconv.Quote(arg) + if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { + args = append(args, quoted) + } else { + args = append(args, arg) + } + } + return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) } diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go index de2c1dc579323..9576b472f9cc5 100644 --- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go +++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go @@ -9,7 +9,6 @@ import ( "fmt" "go/parser" "go/token" - "log" "os" "path/filepath" "regexp" @@ -35,9 +34,12 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif // This is an approximation of import path to id. This can be // wrong for tests, vendored packages, and a number of other cases. havePkgs[pkg.PkgPath] = pkg.ID - x := commonDir(pkg.GoFiles) - if x != "" { - pkgOfDir[x] = append(pkgOfDir[x], pkg) + dir, err := commonDir(pkg.GoFiles) + if err != nil { + return nil, nil, err + } + if dir != "" { + pkgOfDir[dir] = append(pkgOfDir[dir], pkg) } } @@ -441,20 +443,21 @@ func extractPackageName(filename string, contents []byte) (string, bool) { return f.Name.Name, true } -func commonDir(a []string) string { +// commonDir returns the directory that all files are in, "" if files is empty, +// or an error if they aren't in the same directory. +func commonDir(files []string) (string, error) { seen := make(map[string]bool) - x := append([]string{}, a...) - for _, f := range x { + for _, f := range files { seen[filepath.Dir(f)] = true } if len(seen) > 1 { - log.Fatalf("commonDir saw %v for %v", seen, x) + return "", fmt.Errorf("files (%v) are in more than one directory: %v", files, seen) } for k := range seen { - // len(seen) == 1 - return k + // seen has only one element; return it. + return k, nil } - return "" // no files + return "", nil // no files } // It is possible that the files in the disk directory dir have a different package diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go index b13cb081fcbe5..a1dcc40b7270d 100644 --- a/vendor/golang.org/x/tools/go/packages/visit.go +++ b/vendor/golang.org/x/tools/go/packages/visit.go @@ -1,3 +1,7 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package packages import ( diff --git a/vendor/golang.org/x/tools/imports/forward.go b/vendor/golang.org/x/tools/imports/forward.go index a4e40adba0d31..8be18a66b3c25 100644 --- a/vendor/golang.org/x/tools/imports/forward.go +++ b/vendor/golang.org/x/tools/imports/forward.go @@ -1,3 +1,7 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + // Package imports implements a Go pretty-printer (like package "go/format") // that also adds or removes import statements as necessary. package imports // import "golang.org/x/tools/imports" diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go index e37b494915072..a6cf0e64a4b17 100644 --- a/vendor/golang.org/x/tools/internal/event/core/event.go +++ b/vendor/golang.org/x/tools/internal/event/core/event.go @@ -12,7 +12,7 @@ import ( "golang.org/x/tools/internal/event/label" ) -// Event holds the information about an event of note that ocurred. +// Event holds the information about an event of note that occurred. type Event struct { at time.Time diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go index b5c061b0125d5..8659a0c5da67a 100644 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go +++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go @@ -9,10 +9,11 @@ import ( "bytes" "context" "fmt" + exec "golang.org/x/sys/execabs" "io" "os" - "os/exec" "regexp" + "strconv" "strings" "sync" "time" @@ -132,6 +133,10 @@ type Invocation struct { BuildFlags []string ModFlag string ModFile string + Overlay string + // If CleanEnv is set, the invocation will run only with the environment + // in Env, not starting with os.Environ. + CleanEnv bool Env []string WorkingDir string Logf func(format string, args ...interface{}) @@ -171,6 +176,11 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { goArgs = append(goArgs, "-mod="+i.ModFlag) } } + appendOverlayFlag := func() { + if i.Overlay != "" { + goArgs = append(goArgs, "-overlay="+i.Overlay) + } + } switch i.Verb { case "env", "version": @@ -189,6 +199,7 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { goArgs = append(goArgs, i.BuildFlags...) appendModFile() appendModFlag() + appendOverlayFlag() goArgs = append(goArgs, i.Args...) } cmd := exec.Command("go", goArgs...) @@ -200,7 +211,10 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { // The Go stdlib has a special feature where if the cwd and the PWD are the // same node then it trusts the PWD, so by setting it in the env for the child // process we fix up all the paths returned by the go command. - cmd.Env = append(os.Environ(), i.Env...) + if !i.CleanEnv { + cmd.Env = os.Environ() + } + cmd.Env = append(cmd.Env, i.Env...) if i.WorkingDir != "" { cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir) cmd.Dir = i.WorkingDir @@ -241,10 +255,19 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) error { func cmdDebugStr(cmd *exec.Cmd) string { env := make(map[string]string) for _, kv := range cmd.Env { - split := strings.Split(kv, "=") + split := strings.SplitN(kv, "=", 2) k, v := split[0], split[1] env[k] = v } - return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v go %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], cmd.Args) + var args []string + for _, arg := range cmd.Args { + quoted := strconv.Quote(arg) + if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { + args = append(args, quoted) + } else { + args = append(args, arg) + } + } + return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) } diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go index 60d45ac0e64d0..0cebac6e66886 100644 --- a/vendor/golang.org/x/tools/internal/gocommand/version.go +++ b/vendor/golang.org/x/tools/internal/gocommand/version.go @@ -16,9 +16,20 @@ func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { inv.Verb = "list" inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`} inv.Env = append(append([]string{}, inv.Env...), "GO111MODULE=off") - // Unset any unneeded flags. + // Unset any unneeded flags, and remove them from BuildFlags, if they're + // present. inv.ModFile = "" inv.ModFlag = "" + var buildFlags []string + for _, flag := range inv.BuildFlags { + // Flags can be prefixed by one or two dashes. + f := strings.TrimPrefix(strings.TrimPrefix(flag, "-"), "-") + if strings.HasPrefix(f, "mod=") || strings.HasPrefix(f, "modfile=") { + continue + } + buildFlags = append(buildFlags, flag) + } + inv.BuildFlags = buildFlags stdoutBytes, err := r.Run(ctx, inv) if err != nil { return 0, err diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go index 8a83613c5728f..65e0b94b17302 100644 --- a/vendor/golang.org/x/tools/internal/imports/mod.go +++ b/vendor/golang.org/x/tools/internal/imports/mod.go @@ -1,3 +1,7 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package imports import ( @@ -82,13 +86,22 @@ func (r *ModuleResolver) init() error { r.modsByDir = []*gocommand.ModuleJSON{mainMod, r.dummyVendorMod} } else { // Vendor mode is off, so run go list -m ... to find everything. - r.initAllMods() + err := r.initAllMods() + // We expect an error when running outside of a module with + // GO111MODULE=on. Other errors are fatal. + if err != nil && !strings.Contains(err.Error(), "working directory is not part of a module") { + return err + } } if gmc := r.env.Env["GOMODCACHE"]; gmc != "" { r.moduleCacheDir = gmc } else { - r.moduleCacheDir = filepath.Join(filepath.SplitList(goenv["GOPATH"])[0], "/pkg/mod") + gopaths := filepath.SplitList(goenv["GOPATH"]) + if len(gopaths) == 0 { + return fmt.Errorf("empty GOPATH") + } + r.moduleCacheDir = filepath.Join(gopaths[0], "/pkg/mod") } sort.Slice(r.modsByModPath, func(i, j int) bool { @@ -153,7 +166,7 @@ func (r *ModuleResolver) init() error { } func (r *ModuleResolver) initAllMods() error { - stdout, err := r.env.invokeGo(context.TODO(), "list", "-m", "-json", "...") + stdout, err := r.env.invokeGo(context.TODO(), "list", "-m", "-e", "-json", "...") if err != nil { return err } @@ -347,10 +360,11 @@ func (r *ModuleResolver) modInfo(dir string) (modDir string, modName string) { } if r.dirInModuleCache(dir) { - matches := modCacheRegexp.FindStringSubmatch(dir) - index := strings.Index(dir, matches[1]+"@"+matches[2]) - modDir := filepath.Join(dir[:index], matches[1]+"@"+matches[2]) - return modDir, readModName(filepath.Join(modDir, "go.mod")) + if matches := modCacheRegexp.FindStringSubmatch(dir); len(matches) == 3 { + index := strings.Index(dir, matches[1]+"@"+matches[2]) + modDir := filepath.Join(dir[:index], matches[1]+"@"+matches[2]) + return modDir, readModName(filepath.Join(modDir, "go.mod")) + } } for { if info, ok := r.cacheLoad(dir); ok { diff --git a/vendor/golang.org/x/tools/internal/imports/mod_cache.go b/vendor/golang.org/x/tools/internal/imports/mod_cache.go index 5b4f03accddc2..18dada495ca8a 100644 --- a/vendor/golang.org/x/tools/internal/imports/mod_cache.go +++ b/vendor/golang.org/x/tools/internal/imports/mod_cache.go @@ -1,3 +1,7 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package imports import ( diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go index 1335a5eed8a9d..d4ec6f9715e06 100644 --- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go +++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go @@ -1,3 +1,7 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + // Package packagesinternal exposes internal-only fields from go/packages. package packagesinternal diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go new file mode 100644 index 0000000000000..65473eb226d41 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go @@ -0,0 +1,1358 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typesinternal + +//go:generate stringer -type=ErrorCode + +type ErrorCode int + +// This file defines the error codes that can be produced during type-checking. +// Collectively, these codes provide an identifier that may be used to +// implement special handling for certain types of errors. +// +// Error codes should be fine-grained enough that the exact nature of the error +// can be easily determined, but coarse enough that they are not an +// implementation detail of the type checking algorithm. As a rule-of-thumb, +// errors should be considered equivalent if there is a theoretical refactoring +// of the type checker in which they are emitted in exactly one place. For +// example, the type checker emits different error messages for "too many +// arguments" and "too few arguments", but one can imagine an alternative type +// checker where this check instead just emits a single "wrong number of +// arguments", so these errors should have the same code. +// +// Error code names should be as brief as possible while retaining accuracy and +// distinctiveness. In most cases names should start with an adjective +// describing the nature of the error (e.g. "invalid", "unused", "misplaced"), +// and end with a noun identifying the relevant language object. For example, +// "DuplicateDecl" or "InvalidSliceExpr". For brevity, naming follows the +// convention that "bad" implies a problem with syntax, and "invalid" implies a +// problem with types. + +const ( + _ ErrorCode = iota + + // Test is reserved for errors that only apply while in self-test mode. + Test + + /* package names */ + + // BlankPkgName occurs when a package name is the blank identifier "_". + // + // Per the spec: + // "The PackageName must not be the blank identifier." + BlankPkgName + + // MismatchedPkgName occurs when a file's package name doesn't match the + // package name already established by other files. + MismatchedPkgName + + // InvalidPkgUse occurs when a package identifier is used outside of a + // selector expression. + // + // Example: + // import "fmt" + // + // var _ = fmt + InvalidPkgUse + + /* imports */ + + // BadImportPath occurs when an import path is not valid. + BadImportPath + + // BrokenImport occurs when importing a package fails. + // + // Example: + // import "amissingpackage" + BrokenImport + + // ImportCRenamed occurs when the special import "C" is renamed. "C" is a + // pseudo-package, and must not be renamed. + // + // Example: + // import _ "C" + ImportCRenamed + + // UnusedImport occurs when an import is unused. + // + // Example: + // import "fmt" + // + // func main() {} + UnusedImport + + /* initialization */ + + // InvalidInitCycle occurs when an invalid cycle is detected within the + // initialization graph. + // + // Example: + // var x int = f() + // + // func f() int { return x } + InvalidInitCycle + + /* decls */ + + // DuplicateDecl occurs when an identifier is declared multiple times. + // + // Example: + // var x = 1 + // var x = 2 + DuplicateDecl + + // InvalidDeclCycle occurs when a declaration cycle is not valid. + // + // Example: + // import "unsafe" + // + // type T struct { + // a [n]int + // } + // + // var n = unsafe.Sizeof(T{}) + InvalidDeclCycle + + // InvalidTypeCycle occurs when a cycle in type definitions results in a + // type that is not well-defined. + // + // Example: + // import "unsafe" + // + // type T [unsafe.Sizeof(T{})]int + InvalidTypeCycle + + /* decls > const */ + + // InvalidConstInit occurs when a const declaration has a non-constant + // initializer. + // + // Example: + // var x int + // const _ = x + InvalidConstInit + + // InvalidConstVal occurs when a const value cannot be converted to its + // target type. + // + // TODO(findleyr): this error code and example are not very clear. Consider + // removing it. + // + // Example: + // const _ = 1 << "hello" + InvalidConstVal + + // InvalidConstType occurs when the underlying type in a const declaration + // is not a valid constant type. + // + // Example: + // const c *int = 4 + InvalidConstType + + /* decls > var (+ other variable assignment codes) */ + + // UntypedNil occurs when the predeclared (untyped) value nil is used to + // initialize a variable declared without an explicit type. + // + // Example: + // var x = nil + UntypedNil + + // WrongAssignCount occurs when the number of values on the right-hand side + // of an assignment or or initialization expression does not match the number + // of variables on the left-hand side. + // + // Example: + // var x = 1, 2 + WrongAssignCount + + // UnassignableOperand occurs when the left-hand side of an assignment is + // not assignable. + // + // Example: + // func f() { + // const c = 1 + // c = 2 + // } + UnassignableOperand + + // NoNewVar occurs when a short variable declaration (':=') does not declare + // new variables. + // + // Example: + // func f() { + // x := 1 + // x := 2 + // } + NoNewVar + + // MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does + // not have single-valued left-hand or right-hand side. + // + // Per the spec: + // "In assignment operations, both the left- and right-hand expression lists + // must contain exactly one single-valued expression" + // + // Example: + // func f() int { + // x, y := 1, 2 + // x, y += 1 + // return x + y + // } + MultiValAssignOp + + // InvalidIfaceAssign occurs when a value of type T is used as an + // interface, but T does not implement a method of the expected interface. + // + // Example: + // type I interface { + // f() + // } + // + // type T int + // + // var x I = T(1) + InvalidIfaceAssign + + // InvalidChanAssign occurs when a chan assignment is invalid. + // + // Per the spec, a value x is assignable to a channel type T if: + // "x is a bidirectional channel value, T is a channel type, x's type V and + // T have identical element types, and at least one of V or T is not a + // defined type." + // + // Example: + // type T1 chan int + // type T2 chan int + // + // var x T1 + // // Invalid assignment because both types are named + // var _ T2 = x + InvalidChanAssign + + // IncompatibleAssign occurs when the type of the right-hand side expression + // in an assignment cannot be assigned to the type of the variable being + // assigned. + // + // Example: + // var x []int + // var _ int = x + IncompatibleAssign + + // UnaddressableFieldAssign occurs when trying to assign to a struct field + // in a map value. + // + // Example: + // func f() { + // m := make(map[string]struct{i int}) + // m["foo"].i = 42 + // } + UnaddressableFieldAssign + + /* decls > type (+ other type expression codes) */ + + // NotAType occurs when the identifier used as the underlying type in a type + // declaration or the right-hand side of a type alias does not denote a type. + // + // Example: + // var S = 2 + // + // type T S + NotAType + + // InvalidArrayLen occurs when an array length is not a constant value. + // + // Example: + // var n = 3 + // var _ = [n]int{} + InvalidArrayLen + + // BlankIfaceMethod occurs when a method name is '_'. + // + // Per the spec: + // "The name of each explicitly specified method must be unique and not + // blank." + // + // Example: + // type T interface { + // _(int) + // } + BlankIfaceMethod + + // IncomparableMapKey occurs when a map key type does not support the == and + // != operators. + // + // Per the spec: + // "The comparison operators == and != must be fully defined for operands of + // the key type; thus the key type must not be a function, map, or slice." + // + // Example: + // var x map[T]int + // + // type T []int + IncomparableMapKey + + // InvalidIfaceEmbed occurs when a non-interface type is embedded in an + // interface. + // + // Example: + // type T struct {} + // + // func (T) m() + // + // type I interface { + // T + // } + InvalidIfaceEmbed + + // InvalidPtrEmbed occurs when an embedded field is of the pointer form *T, + // and T itself is itself a pointer, an unsafe.Pointer, or an interface. + // + // Per the spec: + // "An embedded field must be specified as a type name T or as a pointer to + // a non-interface type name *T, and T itself may not be a pointer type." + // + // Example: + // type T *int + // + // type S struct { + // *T + // } + InvalidPtrEmbed + + /* decls > func and method */ + + // BadRecv occurs when a method declaration does not have exactly one + // receiver parameter. + // + // Example: + // func () _() {} + BadRecv + + // InvalidRecv occurs when a receiver type expression is not of the form T + // or *T, or T is a pointer type. + // + // Example: + // type T struct {} + // + // func (**T) m() {} + InvalidRecv + + // DuplicateFieldAndMethod occurs when an identifier appears as both a field + // and method name. + // + // Example: + // type T struct { + // m int + // } + // + // func (T) m() {} + DuplicateFieldAndMethod + + // DuplicateMethod occurs when two methods on the same receiver type have + // the same name. + // + // Example: + // type T struct {} + // func (T) m() {} + // func (T) m(i int) int { return i } + DuplicateMethod + + /* decls > special */ + + // InvalidBlank occurs when a blank identifier is used as a value or type. + // + // Per the spec: + // "The blank identifier may appear as an operand only on the left-hand side + // of an assignment." + // + // Example: + // var x = _ + InvalidBlank + + // InvalidIota occurs when the predeclared identifier iota is used outside + // of a constant declaration. + // + // Example: + // var x = iota + InvalidIota + + // MissingInitBody occurs when an init function is missing its body. + // + // Example: + // func init() + MissingInitBody + + // InvalidInitSig occurs when an init function declares parameters or + // results. + // + // Example: + // func init() int { return 1 } + InvalidInitSig + + // InvalidInitDecl occurs when init is declared as anything other than a + // function. + // + // Example: + // var init = 1 + InvalidInitDecl + + // InvalidMainDecl occurs when main is declared as anything other than a + // function, in a main package. + InvalidMainDecl + + /* exprs */ + + // TooManyValues occurs when a function returns too many values for the + // expression context in which it is used. + // + // Example: + // func ReturnTwo() (int, int) { + // return 1, 2 + // } + // + // var x = ReturnTwo() + TooManyValues + + // NotAnExpr occurs when a type expression is used where a value expression + // is expected. + // + // Example: + // type T struct {} + // + // func f() { + // T + // } + NotAnExpr + + /* exprs > const */ + + // TruncatedFloat occurs when a float constant is truncated to an integer + // value. + // + // Example: + // var _ int = 98.6 + TruncatedFloat + + // NumericOverflow occurs when a numeric constant overflows its target type. + // + // Example: + // var x int8 = 1000 + NumericOverflow + + /* exprs > operation */ + + // UndefinedOp occurs when an operator is not defined for the type(s) used + // in an operation. + // + // Example: + // var c = "a" - "b" + UndefinedOp + + // MismatchedTypes occurs when operand types are incompatible in a binary + // operation. + // + // Example: + // var a = "hello" + // var b = 1 + // var c = a - b + MismatchedTypes + + // DivByZero occurs when a division operation is provable at compile + // time to be a division by zero. + // + // Example: + // const divisor = 0 + // var x int = 1/divisor + DivByZero + + // NonNumericIncDec occurs when an increment or decrement operator is + // applied to a non-numeric value. + // + // Example: + // func f() { + // var c = "c" + // c++ + // } + NonNumericIncDec + + /* exprs > ptr */ + + // UnaddressableOperand occurs when the & operator is applied to an + // unaddressable expression. + // + // Example: + // var x = &1 + UnaddressableOperand + + // InvalidIndirection occurs when a non-pointer value is indirected via the + // '*' operator. + // + // Example: + // var x int + // var y = *x + InvalidIndirection + + /* exprs > [] */ + + // NonIndexableOperand occurs when an index operation is applied to a value + // that cannot be indexed. + // + // Example: + // var x = 1 + // var y = x[1] + NonIndexableOperand + + // InvalidIndex occurs when an index argument is not of integer type, + // negative, or out-of-bounds. + // + // Example: + // var s = [...]int{1,2,3} + // var x = s[5] + // + // Example: + // var s = []int{1,2,3} + // var _ = s[-1] + // + // Example: + // var s = []int{1,2,3} + // var i string + // var _ = s[i] + InvalidIndex + + // SwappedSliceIndices occurs when constant indices in a slice expression + // are decreasing in value. + // + // Example: + // var _ = []int{1,2,3}[2:1] + SwappedSliceIndices + + /* operators > slice */ + + // NonSliceableOperand occurs when a slice operation is applied to a value + // whose type is not sliceable, or is unaddressable. + // + // Example: + // var x = [...]int{1, 2, 3}[:1] + // + // Example: + // var x = 1 + // var y = 1[:1] + NonSliceableOperand + + // InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is + // applied to a string. + // + // Example: + // var s = "hello" + // var x = s[1:2:3] + InvalidSliceExpr + + /* exprs > shift */ + + // InvalidShiftCount occurs when the right-hand side of a shift operation is + // either non-integer, negative, or too large. + // + // Example: + // var ( + // x string + // y int = 1 << x + // ) + InvalidShiftCount + + // InvalidShiftOperand occurs when the shifted operand is not an integer. + // + // Example: + // var s = "hello" + // var x = s << 2 + InvalidShiftOperand + + /* exprs > chan */ + + // InvalidReceive occurs when there is a channel receive from a value that + // is either not a channel, or is a send-only channel. + // + // Example: + // func f() { + // var x = 1 + // <-x + // } + InvalidReceive + + // InvalidSend occurs when there is a channel send to a value that is not a + // channel, or is a receive-only channel. + // + // Example: + // func f() { + // var x = 1 + // x <- "hello!" + // } + InvalidSend + + /* exprs > literal */ + + // DuplicateLitKey occurs when an index is duplicated in a slice, array, or + // map literal. + // + // Example: + // var _ = []int{0:1, 0:2} + // + // Example: + // var _ = map[string]int{"a": 1, "a": 2} + DuplicateLitKey + + // MissingLitKey occurs when a map literal is missing a key expression. + // + // Example: + // var _ = map[string]int{1} + MissingLitKey + + // InvalidLitIndex occurs when the key in a key-value element of a slice or + // array literal is not an integer constant. + // + // Example: + // var i = 0 + // var x = []string{i: "world"} + InvalidLitIndex + + // OversizeArrayLit occurs when an array literal exceeds its length. + // + // Example: + // var _ = [2]int{1,2,3} + OversizeArrayLit + + // MixedStructLit occurs when a struct literal contains a mix of positional + // and named elements. + // + // Example: + // var _ = struct{i, j int}{i: 1, 2} + MixedStructLit + + // InvalidStructLit occurs when a positional struct literal has an incorrect + // number of values. + // + // Example: + // var _ = struct{i, j int}{1,2,3} + InvalidStructLit + + // MissingLitField occurs when a struct literal refers to a field that does + // not exist on the struct type. + // + // Example: + // var _ = struct{i int}{j: 2} + MissingLitField + + // DuplicateLitField occurs when a struct literal contains duplicated + // fields. + // + // Example: + // var _ = struct{i int}{i: 1, i: 2} + DuplicateLitField + + // UnexportedLitField occurs when a positional struct literal implicitly + // assigns an unexported field of an imported type. + UnexportedLitField + + // InvalidLitField occurs when a field name is not a valid identifier. + // + // Example: + // var _ = struct{i int}{1: 1} + InvalidLitField + + // UntypedLit occurs when a composite literal omits a required type + // identifier. + // + // Example: + // type outer struct{ + // inner struct { i int } + // } + // + // var _ = outer{inner: {1}} + UntypedLit + + // InvalidLit occurs when a composite literal expression does not match its + // type. + // + // Example: + // type P *struct{ + // x int + // } + // var _ = P {} + InvalidLit + + /* exprs > selector */ + + // AmbiguousSelector occurs when a selector is ambiguous. + // + // Example: + // type E1 struct { i int } + // type E2 struct { i int } + // type T struct { E1; E2 } + // + // var x T + // var _ = x.i + AmbiguousSelector + + // UndeclaredImportedName occurs when a package-qualified identifier is + // undeclared by the imported package. + // + // Example: + // import "go/types" + // + // var _ = types.NotAnActualIdentifier + UndeclaredImportedName + + // UnexportedName occurs when a selector refers to an unexported identifier + // of an imported package. + // + // Example: + // import "reflect" + // + // type _ reflect.flag + UnexportedName + + // UndeclaredName occurs when an identifier is not declared in the current + // scope. + // + // Example: + // var x T + UndeclaredName + + // MissingFieldOrMethod occurs when a selector references a field or method + // that does not exist. + // + // Example: + // type T struct {} + // + // var x = T{}.f + MissingFieldOrMethod + + /* exprs > ... */ + + // BadDotDotDotSyntax occurs when a "..." occurs in a context where it is + // not valid. + // + // Example: + // var _ = map[int][...]int{0: {}} + BadDotDotDotSyntax + + // NonVariadicDotDotDot occurs when a "..." is used on the final argument to + // a non-variadic function. + // + // Example: + // func printArgs(s []string) { + // for _, a := range s { + // println(a) + // } + // } + // + // func f() { + // s := []string{"a", "b", "c"} + // printArgs(s...) + // } + NonVariadicDotDotDot + + // MisplacedDotDotDot occurs when a "..." is used somewhere other than the + // final argument to a function call. + // + // Example: + // func printArgs(args ...int) { + // for _, a := range args { + // println(a) + // } + // } + // + // func f() { + // a := []int{1,2,3} + // printArgs(0, a...) + // } + MisplacedDotDotDot + + // InvalidDotDotDotOperand occurs when a "..." operator is applied to a + // single-valued operand. + // + // Example: + // func printArgs(args ...int) { + // for _, a := range args { + // println(a) + // } + // } + // + // func f() { + // a := 1 + // printArgs(a...) + // } + // + // Example: + // func args() (int, int) { + // return 1, 2 + // } + // + // func printArgs(args ...int) { + // for _, a := range args { + // println(a) + // } + // } + // + // func g() { + // printArgs(args()...) + // } + InvalidDotDotDotOperand + + // InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in + // function. + // + // Example: + // var s = []int{1, 2, 3} + // var l = len(s...) + InvalidDotDotDot + + /* exprs > built-in */ + + // UncalledBuiltin occurs when a built-in function is used as a + // function-valued expression, instead of being called. + // + // Per the spec: + // "The built-in functions do not have standard Go types, so they can only + // appear in call expressions; they cannot be used as function values." + // + // Example: + // var _ = copy + UncalledBuiltin + + // InvalidAppend occurs when append is called with a first argument that is + // not a slice. + // + // Example: + // var _ = append(1, 2) + InvalidAppend + + // InvalidCap occurs when an argument to the cap built-in function is not of + // supported type. + // + // See https://golang.org/ref/spec#Lengthand_capacity for information on + // which underlying types are supported as arguments to cap and len. + // + // Example: + // var s = 2 + // var x = cap(s) + InvalidCap + + // InvalidClose occurs when close(...) is called with an argument that is + // not of channel type, or that is a receive-only channel. + // + // Example: + // func f() { + // var x int + // close(x) + // } + InvalidClose + + // InvalidCopy occurs when the arguments are not of slice type or do not + // have compatible type. + // + // See https://golang.org/ref/spec#Appendingand_copying_slices for more + // information on the type requirements for the copy built-in. + // + // Example: + // func f() { + // var x []int + // y := []int64{1,2,3} + // copy(x, y) + // } + InvalidCopy + + // InvalidComplex occurs when the complex built-in function is called with + // arguments with incompatible types. + // + // Example: + // var _ = complex(float32(1), float64(2)) + InvalidComplex + + // InvalidDelete occurs when the delete built-in function is called with a + // first argument that is not a map. + // + // Example: + // func f() { + // m := "hello" + // delete(m, "e") + // } + InvalidDelete + + // InvalidImag occurs when the imag built-in function is called with an + // argument that does not have complex type. + // + // Example: + // var _ = imag(int(1)) + InvalidImag + + // InvalidLen occurs when an argument to the len built-in function is not of + // supported type. + // + // See https://golang.org/ref/spec#Lengthand_capacity for information on + // which underlying types are supported as arguments to cap and len. + // + // Example: + // var s = 2 + // var x = len(s) + InvalidLen + + // SwappedMakeArgs occurs when make is called with three arguments, and its + // length argument is larger than its capacity argument. + // + // Example: + // var x = make([]int, 3, 2) + SwappedMakeArgs + + // InvalidMake occurs when make is called with an unsupported type argument. + // + // See https://golang.org/ref/spec#Makingslices_maps_and_channels for + // information on the types that may be created using make. + // + // Example: + // var x = make(int) + InvalidMake + + // InvalidReal occurs when the real built-in function is called with an + // argument that does not have complex type. + // + // Example: + // var _ = real(int(1)) + InvalidReal + + /* exprs > assertion */ + + // InvalidAssert occurs when a type assertion is applied to a + // value that is not of interface type. + // + // Example: + // var x = 1 + // var _ = x.(float64) + InvalidAssert + + // ImpossibleAssert occurs for a type assertion x.(T) when the value x of + // interface cannot have dynamic type T, due to a missing or mismatching + // method on T. + // + // Example: + // type T int + // + // func (t *T) m() int { return int(*t) } + // + // type I interface { m() int } + // + // var x I + // var _ = x.(T) + ImpossibleAssert + + /* exprs > conversion */ + + // InvalidConversion occurs when the argument type cannot be converted to the + // target. + // + // See https://golang.org/ref/spec#Conversions for the rules of + // convertibility. + // + // Example: + // var x float64 + // var _ = string(x) + InvalidConversion + + // InvalidUntypedConversion occurs when an there is no valid implicit + // conversion from an untyped value satisfying the type constraints of the + // context in which it is used. + // + // Example: + // var _ = 1 + "" + InvalidUntypedConversion + + /* offsetof */ + + // BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument + // that is not a selector expression. + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Offsetof(x) + BadOffsetofSyntax + + // InvalidOffsetof occurs when unsafe.Offsetof is called with a method + // selector, rather than a field selector, or when the field is embedded via + // a pointer. + // + // Per the spec: + // + // "If f is an embedded field, it must be reachable without pointer + // indirections through fields of the struct. " + // + // Example: + // import "unsafe" + // + // type T struct { f int } + // type S struct { *T } + // var s S + // var _ = unsafe.Offsetof(s.f) + // + // Example: + // import "unsafe" + // + // type S struct{} + // + // func (S) m() {} + // + // var s S + // var _ = unsafe.Offsetof(s.m) + InvalidOffsetof + + /* control flow > scope */ + + // UnusedExpr occurs when a side-effect free expression is used as a + // statement. Such a statement has no effect. + // + // Example: + // func f(i int) { + // i*i + // } + UnusedExpr + + // UnusedVar occurs when a variable is declared but unused. + // + // Example: + // func f() { + // x := 1 + // } + UnusedVar + + // MissingReturn occurs when a function with results is missing a return + // statement. + // + // Example: + // func f() int {} + MissingReturn + + // WrongResultCount occurs when a return statement returns an incorrect + // number of values. + // + // Example: + // func ReturnOne() int { + // return 1, 2 + // } + WrongResultCount + + // OutOfScopeResult occurs when the name of a value implicitly returned by + // an empty return statement is shadowed in a nested scope. + // + // Example: + // func factor(n int) (i int) { + // for i := 2; i < n; i++ { + // if n%i == 0 { + // return + // } + // } + // return 0 + // } + OutOfScopeResult + + /* control flow > if */ + + // InvalidCond occurs when an if condition is not a boolean expression. + // + // Example: + // func checkReturn(i int) { + // if i { + // panic("non-zero return") + // } + // } + InvalidCond + + /* control flow > for */ + + // InvalidPostDecl occurs when there is a declaration in a for-loop post + // statement. + // + // Example: + // func f() { + // for i := 0; i < 10; j := 0 {} + // } + InvalidPostDecl + + // InvalidChanRange occurs when a send-only channel used in a range + // expression. + // + // Example: + // func sum(c chan<- int) { + // s := 0 + // for i := range c { + // s += i + // } + // } + InvalidChanRange + + // InvalidIterVar occurs when two iteration variables are used while ranging + // over a channel. + // + // Example: + // func f(c chan int) { + // for k, v := range c { + // println(k, v) + // } + // } + InvalidIterVar + + // InvalidRangeExpr occurs when the type of a range expression is not array, + // slice, string, map, or channel. + // + // Example: + // func f(i int) { + // for j := range i { + // println(j) + // } + // } + InvalidRangeExpr + + /* control flow > switch */ + + // MisplacedBreak occurs when a break statement is not within a for, switch, + // or select statement of the innermost function definition. + // + // Example: + // func f() { + // break + // } + MisplacedBreak + + // MisplacedContinue occurs when a continue statement is not within a for + // loop of the innermost function definition. + // + // Example: + // func sumeven(n int) int { + // proceed := func() { + // continue + // } + // sum := 0 + // for i := 1; i <= n; i++ { + // if i % 2 != 0 { + // proceed() + // } + // sum += i + // } + // return sum + // } + MisplacedContinue + + // MisplacedFallthrough occurs when a fallthrough statement is not within an + // expression switch. + // + // Example: + // func typename(i interface{}) string { + // switch i.(type) { + // case int64: + // fallthrough + // case int: + // return "int" + // } + // return "unsupported" + // } + MisplacedFallthrough + + // DuplicateCase occurs when a type or expression switch has duplicate + // cases. + // + // Example: + // func printInt(i int) { + // switch i { + // case 1: + // println("one") + // case 1: + // println("One") + // } + // } + DuplicateCase + + // DuplicateDefault occurs when a type or expression switch has multiple + // default clauses. + // + // Example: + // func printInt(i int) { + // switch i { + // case 1: + // println("one") + // default: + // println("One") + // default: + // println("1") + // } + // } + DuplicateDefault + + // BadTypeKeyword occurs when a .(type) expression is used anywhere other + // than a type switch. + // + // Example: + // type I interface { + // m() + // } + // var t I + // var _ = t.(type) + BadTypeKeyword + + // InvalidTypeSwitch occurs when .(type) is used on an expression that is + // not of interface type. + // + // Example: + // func f(i int) { + // switch x := i.(type) {} + // } + InvalidTypeSwitch + + /* control flow > select */ + + // InvalidSelectCase occurs when a select case is not a channel send or + // receive. + // + // Example: + // func checkChan(c <-chan int) bool { + // select { + // case c: + // return true + // default: + // return false + // } + // } + InvalidSelectCase + + /* control flow > labels and jumps */ + + // UndeclaredLabel occurs when an undeclared label is jumped to. + // + // Example: + // func f() { + // goto L + // } + UndeclaredLabel + + // DuplicateLabel occurs when a label is declared more than once. + // + // Example: + // func f() int { + // L: + // L: + // return 1 + // } + DuplicateLabel + + // MisplacedLabel occurs when a break or continue label is not on a for, + // switch, or select statement. + // + // Example: + // func f() { + // L: + // a := []int{1,2,3} + // for _, e := range a { + // if e > 10 { + // break L + // } + // println(a) + // } + // } + MisplacedLabel + + // UnusedLabel occurs when a label is declared but not used. + // + // Example: + // func f() { + // L: + // } + UnusedLabel + + // JumpOverDecl occurs when a label jumps over a variable declaration. + // + // Example: + // func f() int { + // goto L + // x := 2 + // L: + // x++ + // return x + // } + JumpOverDecl + + // JumpIntoBlock occurs when a forward jump goes to a label inside a nested + // block. + // + // Example: + // func f(x int) { + // goto L + // if x > 0 { + // L: + // print("inside block") + // } + // } + JumpIntoBlock + + /* control flow > calls */ + + // InvalidMethodExpr occurs when a pointer method is called but the argument + // is not addressable. + // + // Example: + // type T struct {} + // + // func (*T) m() int { return 1 } + // + // var _ = T.m(T{}) + InvalidMethodExpr + + // WrongArgCount occurs when too few or too many arguments are passed by a + // function call. + // + // Example: + // func f(i int) {} + // var x = f() + WrongArgCount + + // InvalidCall occurs when an expression is called that is not of function + // type. + // + // Example: + // var x = "x" + // var y = x() + InvalidCall + + /* control flow > suspended */ + + // UnusedResults occurs when a restricted expression-only built-in function + // is suspended via go or defer. Such a suspension discards the results of + // these side-effect free built-in functions, and therefore is ineffectual. + // + // Example: + // func f(a []int) int { + // defer len(a) + // return i + // } + UnusedResults + + // InvalidDefer occurs when a deferred expression is not a function call, + // for example if the expression is a type conversion. + // + // Example: + // func f(i int) int { + // defer int32(i) + // return i + // } + InvalidDefer + + // InvalidGo occurs when a go expression is not a function call, for example + // if the expression is a type conversion. + // + // Example: + // func f(i int) int { + // go int32(i) + // return i + // } + InvalidGo +) diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go new file mode 100644 index 0000000000000..97f3ec891fa61 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go @@ -0,0 +1,152 @@ +// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT. + +package typesinternal + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Test-1] + _ = x[BlankPkgName-2] + _ = x[MismatchedPkgName-3] + _ = x[InvalidPkgUse-4] + _ = x[BadImportPath-5] + _ = x[BrokenImport-6] + _ = x[ImportCRenamed-7] + _ = x[UnusedImport-8] + _ = x[InvalidInitCycle-9] + _ = x[DuplicateDecl-10] + _ = x[InvalidDeclCycle-11] + _ = x[InvalidTypeCycle-12] + _ = x[InvalidConstInit-13] + _ = x[InvalidConstVal-14] + _ = x[InvalidConstType-15] + _ = x[UntypedNil-16] + _ = x[WrongAssignCount-17] + _ = x[UnassignableOperand-18] + _ = x[NoNewVar-19] + _ = x[MultiValAssignOp-20] + _ = x[InvalidIfaceAssign-21] + _ = x[InvalidChanAssign-22] + _ = x[IncompatibleAssign-23] + _ = x[UnaddressableFieldAssign-24] + _ = x[NotAType-25] + _ = x[InvalidArrayLen-26] + _ = x[BlankIfaceMethod-27] + _ = x[IncomparableMapKey-28] + _ = x[InvalidIfaceEmbed-29] + _ = x[InvalidPtrEmbed-30] + _ = x[BadRecv-31] + _ = x[InvalidRecv-32] + _ = x[DuplicateFieldAndMethod-33] + _ = x[DuplicateMethod-34] + _ = x[InvalidBlank-35] + _ = x[InvalidIota-36] + _ = x[MissingInitBody-37] + _ = x[InvalidInitSig-38] + _ = x[InvalidInitDecl-39] + _ = x[InvalidMainDecl-40] + _ = x[TooManyValues-41] + _ = x[NotAnExpr-42] + _ = x[TruncatedFloat-43] + _ = x[NumericOverflow-44] + _ = x[UndefinedOp-45] + _ = x[MismatchedTypes-46] + _ = x[DivByZero-47] + _ = x[NonNumericIncDec-48] + _ = x[UnaddressableOperand-49] + _ = x[InvalidIndirection-50] + _ = x[NonIndexableOperand-51] + _ = x[InvalidIndex-52] + _ = x[SwappedSliceIndices-53] + _ = x[NonSliceableOperand-54] + _ = x[InvalidSliceExpr-55] + _ = x[InvalidShiftCount-56] + _ = x[InvalidShiftOperand-57] + _ = x[InvalidReceive-58] + _ = x[InvalidSend-59] + _ = x[DuplicateLitKey-60] + _ = x[MissingLitKey-61] + _ = x[InvalidLitIndex-62] + _ = x[OversizeArrayLit-63] + _ = x[MixedStructLit-64] + _ = x[InvalidStructLit-65] + _ = x[MissingLitField-66] + _ = x[DuplicateLitField-67] + _ = x[UnexportedLitField-68] + _ = x[InvalidLitField-69] + _ = x[UntypedLit-70] + _ = x[InvalidLit-71] + _ = x[AmbiguousSelector-72] + _ = x[UndeclaredImportedName-73] + _ = x[UnexportedName-74] + _ = x[UndeclaredName-75] + _ = x[MissingFieldOrMethod-76] + _ = x[BadDotDotDotSyntax-77] + _ = x[NonVariadicDotDotDot-78] + _ = x[MisplacedDotDotDot-79] + _ = x[InvalidDotDotDotOperand-80] + _ = x[InvalidDotDotDot-81] + _ = x[UncalledBuiltin-82] + _ = x[InvalidAppend-83] + _ = x[InvalidCap-84] + _ = x[InvalidClose-85] + _ = x[InvalidCopy-86] + _ = x[InvalidComplex-87] + _ = x[InvalidDelete-88] + _ = x[InvalidImag-89] + _ = x[InvalidLen-90] + _ = x[SwappedMakeArgs-91] + _ = x[InvalidMake-92] + _ = x[InvalidReal-93] + _ = x[InvalidAssert-94] + _ = x[ImpossibleAssert-95] + _ = x[InvalidConversion-96] + _ = x[InvalidUntypedConversion-97] + _ = x[BadOffsetofSyntax-98] + _ = x[InvalidOffsetof-99] + _ = x[UnusedExpr-100] + _ = x[UnusedVar-101] + _ = x[MissingReturn-102] + _ = x[WrongResultCount-103] + _ = x[OutOfScopeResult-104] + _ = x[InvalidCond-105] + _ = x[InvalidPostDecl-106] + _ = x[InvalidChanRange-107] + _ = x[InvalidIterVar-108] + _ = x[InvalidRangeExpr-109] + _ = x[MisplacedBreak-110] + _ = x[MisplacedContinue-111] + _ = x[MisplacedFallthrough-112] + _ = x[DuplicateCase-113] + _ = x[DuplicateDefault-114] + _ = x[BadTypeKeyword-115] + _ = x[InvalidTypeSwitch-116] + _ = x[InvalidSelectCase-117] + _ = x[UndeclaredLabel-118] + _ = x[DuplicateLabel-119] + _ = x[MisplacedLabel-120] + _ = x[UnusedLabel-121] + _ = x[JumpOverDecl-122] + _ = x[JumpIntoBlock-123] + _ = x[InvalidMethodExpr-124] + _ = x[WrongArgCount-125] + _ = x[InvalidCall-126] + _ = x[UnusedResults-127] + _ = x[InvalidDefer-128] + _ = x[InvalidGo-129] +} + +const _ErrorCode_name = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGo" + +var _ErrorCode_index = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 215, 231, 250, 258, 274, 292, 309, 327, 351, 359, 374, 390, 408, 425, 440, 447, 458, 481, 496, 508, 519, 534, 548, 563, 578, 591, 600, 614, 629, 640, 655, 664, 680, 700, 718, 737, 749, 768, 787, 803, 820, 839, 853, 864, 879, 892, 907, 923, 937, 953, 968, 985, 1003, 1018, 1028, 1038, 1055, 1077, 1091, 1105, 1125, 1143, 1163, 1181, 1204, 1220, 1235, 1248, 1258, 1270, 1281, 1295, 1308, 1319, 1329, 1344, 1355, 1366, 1379, 1395, 1412, 1436, 1453, 1468, 1478, 1487, 1500, 1516, 1532, 1543, 1558, 1574, 1588, 1604, 1618, 1635, 1655, 1668, 1684, 1698, 1715, 1732, 1747, 1761, 1775, 1786, 1798, 1811, 1828, 1841, 1852, 1865, 1877, 1886} + +func (i ErrorCode) String() string { + i -= 1 + if i < 0 || i >= ErrorCode(len(_ErrorCode_index)-1) { + return "ErrorCode(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _ErrorCode_name[_ErrorCode_index[i]:_ErrorCode_index[i+1]] +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go index a5bb408e2f1b3..c3e1a397dbf82 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Package typesinternal provides access to internal go/types APIs that are not +// yet exported. package typesinternal import ( + "go/token" "go/types" "reflect" "unsafe" @@ -26,3 +29,17 @@ func SetUsesCgo(conf *types.Config) bool { return true } + +func ReadGo116ErrorData(terr types.Error) (ErrorCode, token.Pos, token.Pos, bool) { + var data [3]int + // By coincidence all of these fields are ints, which simplifies things. + v := reflect.ValueOf(terr) + for i, name := range []string{"go116code", "go116start", "go116end"} { + f := v.FieldByName(name) + if !f.IsValid() { + return 0, 0, 0, false + } + data[i] = int(f.Int()) + } + return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true +} diff --git a/vendor/gopkg.in/yaml.v2/.travis.yml b/vendor/gopkg.in/yaml.v2/.travis.yml index 055480b9ef8e0..7348c50c0c3d7 100644 --- a/vendor/gopkg.in/yaml.v2/.travis.yml +++ b/vendor/gopkg.in/yaml.v2/.travis.yml @@ -11,6 +11,7 @@ go: - "1.11.x" - "1.12.x" - "1.13.x" + - "1.14.x" - "tip" go_import_path: gopkg.in/yaml.v2 diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go index d2c2308f1f4f8..acf71402cf31a 100644 --- a/vendor/gopkg.in/yaml.v2/apic.go +++ b/vendor/gopkg.in/yaml.v2/apic.go @@ -79,6 +79,8 @@ func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) { parser.encoding = encoding } +var disableLineWrapping = false + // Create a new emitter object. func yaml_emitter_initialize(emitter *yaml_emitter_t) { *emitter = yaml_emitter_t{ @@ -86,7 +88,9 @@ func yaml_emitter_initialize(emitter *yaml_emitter_t) { raw_buffer: make([]byte, 0, output_raw_buffer_size), states: make([]yaml_emitter_state_t, 0, initial_stack_size), events: make([]yaml_event_t, 0, initial_queue_size), - best_width: -1, + } + if disableLineWrapping { + emitter.best_width = -1 } } diff --git a/vendor/gopkg.in/yaml.v2/go.mod b/vendor/gopkg.in/yaml.v2/go.mod index 1934e87694502..2cbb85aeacd79 100644 --- a/vendor/gopkg.in/yaml.v2/go.mod +++ b/vendor/gopkg.in/yaml.v2/go.mod @@ -1,5 +1,5 @@ -module "gopkg.in/yaml.v2" +module gopkg.in/yaml.v2 -require ( - "gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405 -) +go 1.15 + +require gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 diff --git a/vendor/gopkg.in/yaml.v2/yaml.go b/vendor/gopkg.in/yaml.v2/yaml.go index 89650e293ac72..30813884c0679 100644 --- a/vendor/gopkg.in/yaml.v2/yaml.go +++ b/vendor/gopkg.in/yaml.v2/yaml.go @@ -175,7 +175,7 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) { // Zero valued structs will be omitted if all their public // fields are zero, unless they implement an IsZero // method (see the IsZeroer interface type), in which -// case the field will be included if that method returns true. +// case the field will be excluded if IsZero returns true. // // flow Marshal using a flow style (useful for structs, // sequences and maps). @@ -464,3 +464,15 @@ func isZero(v reflect.Value) bool { } return false } + +// FutureLineWrap globally disables line wrapping when encoding long strings. +// This is a temporary and thus deprecated method introduced to faciliate +// migration towards v3, which offers more control of line lengths on +// individual encodings, and has a default matching the behavior introduced +// by this function. +// +// The default formatting of v2 was erroneously changed in v2.3.0 and reverted +// in v2.4.0, at which point this function was introduced to help migration. +func FutureLineWrap() { + disableLineWrapping = true +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 618e397f40ca3..0f8d6944a9ec8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -4,7 +4,7 @@ cloud.google.com/go/compute/metadata ## explicit code.gitea.io/gitea-vet code.gitea.io/gitea-vet/checks -# code.gitea.io/sdk/gitea v0.13.1 +# code.gitea.io/sdk/gitea v0.13.2 ## explicit code.gitea.io/sdk/gitea # gitea.com/go-chi/binding v0.0.0-20210113025129-03f1d313373c @@ -83,7 +83,7 @@ github.com/andybalholm/cascadia # github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be ## explicit github.com/anmitsu/go-shlex -# github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 +# github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef github.com/asaskevich/govalidator # github.com/aymerick/douceur v0.2.0 github.com/aymerick/douceur/css @@ -152,7 +152,8 @@ github.com/blevesearch/zapx/v13 github.com/blevesearch/zapx/v14 # github.com/blevesearch/zapx/v15 v15.1.10 github.com/blevesearch/zapx/v15 -# github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc +# github.com/boombuler/barcode v1.0.1 +## explicit github.com/boombuler/barcode github.com/boombuler/barcode/qr github.com/boombuler/barcode/utils @@ -222,10 +223,12 @@ github.com/emirpasic/gods/utils # github.com/ethantkoenig/rupture v1.0.0 ## explicit github.com/ethantkoenig/rupture -# github.com/fatih/color v1.9.0 +# github.com/fatih/color v1.10.0 github.com/fatih/color # github.com/fatih/structtag v1.2.0 github.com/fatih/structtag +# github.com/felixge/httpsnoop v1.0.1 +github.com/felixge/httpsnoop # github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify # github.com/gliderlabs/ssh v0.3.1 @@ -314,21 +317,21 @@ github.com/go-git/go-git/v5/utils/merkletrie/noder # github.com/go-ldap/ldap/v3 v3.2.4 ## explicit github.com/go-ldap/ldap/v3 -# github.com/go-openapi/analysis v0.19.10 +# github.com/go-openapi/analysis v0.19.16 github.com/go-openapi/analysis github.com/go-openapi/analysis/internal -# github.com/go-openapi/errors v0.19.6 +# github.com/go-openapi/errors v0.19.9 github.com/go-openapi/errors # github.com/go-openapi/inflect v0.19.0 github.com/go-openapi/inflect -# github.com/go-openapi/jsonpointer v0.19.3 +# github.com/go-openapi/jsonpointer v0.19.5 github.com/go-openapi/jsonpointer -# github.com/go-openapi/jsonreference v0.19.4 +# github.com/go-openapi/jsonreference v0.19.5 github.com/go-openapi/jsonreference -# github.com/go-openapi/loads v0.19.5 +# github.com/go-openapi/loads v0.20.0 github.com/go-openapi/loads github.com/go-openapi/loads/fmts -# github.com/go-openapi/runtime v0.19.20 +# github.com/go-openapi/runtime v0.19.26 github.com/go-openapi/runtime github.com/go-openapi/runtime/logger github.com/go-openapi/runtime/middleware @@ -336,13 +339,13 @@ github.com/go-openapi/runtime/middleware/denco github.com/go-openapi/runtime/middleware/header github.com/go-openapi/runtime/middleware/untyped github.com/go-openapi/runtime/security -# github.com/go-openapi/spec v0.19.8 +# github.com/go-openapi/spec v0.20.1 github.com/go-openapi/spec -# github.com/go-openapi/strfmt v0.19.5 +# github.com/go-openapi/strfmt v0.20.0 github.com/go-openapi/strfmt -# github.com/go-openapi/swag v0.19.9 +# github.com/go-openapi/swag v0.19.13 github.com/go-openapi/swag -# github.com/go-openapi/validate v0.19.10 +# github.com/go-openapi/validate v0.20.1 github.com/go-openapi/validate # github.com/go-redis/redis/v7 v7.4.0 ## explicit @@ -358,7 +361,7 @@ github.com/go-redis/redis/v7/internal/util github.com/go-sql-driver/mysql # github.com/go-stack/stack v1.8.0 github.com/go-stack/stack -# github.com/go-swagger/go-swagger v0.25.0 +# github.com/go-swagger/go-swagger v0.26.0 ## explicit github.com/go-swagger/go-swagger/cmd/swagger github.com/go-swagger/go-swagger/cmd/swagger/commands @@ -405,7 +408,7 @@ github.com/golang/snappy github.com/google/go-github/v32/github # github.com/google/go-querystring v1.0.0 github.com/google/go-querystring/query -# github.com/google/uuid v1.1.2 +# github.com/google/uuid v1.2.0 ## explicit github.com/google/uuid # github.com/gorilla/context v1.1.1 @@ -413,7 +416,7 @@ github.com/google/uuid github.com/gorilla/context # github.com/gorilla/css v1.0.0 github.com/gorilla/css/scanner -# github.com/gorilla/handlers v1.4.2 +# github.com/gorilla/handlers v1.5.1 github.com/gorilla/handlers # github.com/gorilla/mux v1.7.3 github.com/gorilla/mux @@ -482,7 +485,7 @@ github.com/keybase/go-crypto/openpgp/errors github.com/keybase/go-crypto/openpgp/packet github.com/keybase/go-crypto/openpgp/s2k github.com/keybase/go-crypto/rsa -# github.com/klauspost/compress v1.11.3 +# github.com/klauspost/compress v1.11.7 ## explicit github.com/klauspost/compress/flate github.com/klauspost/compress/fse @@ -496,7 +499,7 @@ github.com/klauspost/cpuid # github.com/klauspost/pgzip v1.2.5 ## explicit github.com/klauspost/pgzip -# github.com/kr/pretty v0.2.0 +# github.com/kr/pretty v0.2.1 github.com/kr/pretty # github.com/kr/text v0.2.0 github.com/kr/text @@ -504,7 +507,7 @@ github.com/kr/text ## explicit github.com/lafriks/xormstore github.com/lafriks/xormstore/util -# github.com/lib/pq v1.8.1-0.20200908161135-083382b7e6fc +# github.com/lib/pq v1.9.0 ## explicit github.com/lib/pq github.com/lib/pq/oid @@ -514,14 +517,14 @@ github.com/libdns/libdns # github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 ## explicit github.com/lunny/dingtalk_webhook -# github.com/magiconair/properties v1.8.1 +# github.com/magiconair/properties v1.8.4 github.com/magiconair/properties # github.com/mailru/easyjson v0.7.6 github.com/mailru/easyjson github.com/mailru/easyjson/buffer github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jwriter -# github.com/markbates/goth v1.65.0 +# github.com/markbates/goth v1.66.1 ## explicit github.com/markbates/goth github.com/markbates/goth/gothic @@ -538,16 +541,15 @@ github.com/markbates/goth/providers/nextcloud github.com/markbates/goth/providers/openidConnect github.com/markbates/goth/providers/twitter github.com/markbates/goth/providers/yandex -# github.com/mattn/go-colorable v0.1.7 -## explicit +# github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-colorable # github.com/mattn/go-isatty v0.0.12 ## explicit github.com/mattn/go-isatty -# github.com/mattn/go-runewidth v0.0.9 +# github.com/mattn/go-runewidth v0.0.10 ## explicit github.com/mattn/go-runewidth -# github.com/mattn/go-sqlite3 v1.14.4 +# github.com/mattn/go-sqlite3 v1.14.6 ## explicit github.com/mattn/go-sqlite3 # github.com/matttproud/golang_protobuf_extensions v1.0.1 @@ -555,7 +557,7 @@ github.com/matttproud/golang_protobuf_extensions/pbutil # github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 ## explicit github.com/mgechev/dots -# github.com/mgechev/revive v1.0.3-0.20200921231451-246eac737dc7 +# github.com/mgechev/revive v1.0.3 ## explicit github.com/mgechev/revive/formatter github.com/mgechev/revive/lint @@ -571,9 +573,10 @@ github.com/mholt/archiver/v3 github.com/microcosm-cc/bluemonday # github.com/miekg/dns v1.1.30 github.com/miekg/dns -# github.com/minio/md5-simd v1.1.0 +# github.com/minio/md5-simd v1.1.1 +## explicit github.com/minio/md5-simd -# github.com/minio/minio-go/v7 v7.0.6 +# github.com/minio/minio-go/v7 v7.0.7 ## explicit github.com/minio/minio-go/v7 github.com/minio/minio-go/v7/pkg/credentials @@ -591,7 +594,7 @@ github.com/minio/sha256-simd # github.com/mitchellh/go-homedir v1.1.0 ## explicit github.com/mitchellh/go-homedir -# github.com/mitchellh/mapstructure v1.3.2 +# github.com/mitchellh/mapstructure v1.4.1 github.com/mitchellh/mapstructure # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd github.com/modern-go/concurrent @@ -607,7 +610,7 @@ github.com/msteinert/pam # github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 ## explicit github.com/nfnt/resize -# github.com/niklasfasching/go-org v1.3.2 +# github.com/niklasfasching/go-org v1.4.0 ## explicit github.com/niklasfasching/go-org/org # github.com/nwaples/rardecode v1.1.0 @@ -617,7 +620,7 @@ github.com/olekukonko/tablewriter # github.com/oliamb/cutter v0.2.2 ## explicit github.com/oliamb/cutter -# github.com/olivere/elastic/v7 v7.0.21 +# github.com/olivere/elastic/v7 v7.0.22 ## explicit github.com/olivere/elastic/v7 github.com/olivere/elastic/v7/config @@ -639,7 +642,7 @@ github.com/pierrec/lz4/v4/internal/xxh32 github.com/pkg/errors # github.com/pmezard/go-difflib v1.0.0 github.com/pmezard/go-difflib/difflib -# github.com/pquerna/otp v1.2.0 +# github.com/pquerna/otp v1.3.0 ## explicit github.com/pquerna/otp github.com/pquerna/otp/hotp @@ -663,6 +666,9 @@ github.com/prometheus/procfs/internal/util ## explicit github.com/quasoft/websspi github.com/quasoft/websspi/secctx +# github.com/rivo/uniseg v0.2.0 +## explicit +github.com/rivo/uniseg # github.com/rs/xid v1.2.1 github.com/rs/xid # github.com/russross/blackfriday/v2 v2.0.1 @@ -678,7 +684,7 @@ github.com/shurcooL/sanitized_anchor_name # github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 ## explicit github.com/shurcooL/vfsgen -# github.com/spf13/afero v1.3.2 +# github.com/spf13/afero v1.4.1 github.com/spf13/afero github.com/spf13/afero/mem # github.com/spf13/cast v1.3.1 @@ -688,7 +694,6 @@ github.com/spf13/jwalterweatherman # github.com/spf13/pflag v1.0.5 github.com/spf13/pflag # github.com/spf13/viper v1.7.1 -## explicit github.com/spf13/viper # github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf ## explicit @@ -747,7 +752,7 @@ github.com/urfave/cli # github.com/willf/bitset v1.1.11 ## explicit github.com/willf/bitset -# github.com/xanzy/go-gitlab v0.39.0 +# github.com/xanzy/go-gitlab v0.42.0 ## explicit github.com/xanzy/go-gitlab # github.com/xanzy/ssh-agent v0.2.1 @@ -757,7 +762,7 @@ github.com/xi2/xz # github.com/yohcop/openid-go v1.0.0 ## explicit github.com/yohcop/openid-go -# github.com/yuin/goldmark v1.2.1 +# github.com/yuin/goldmark v1.3.1 ## explicit github.com/yuin/goldmark github.com/yuin/goldmark/ast @@ -782,7 +787,7 @@ go.jolheiser.com/hcaptcha # go.jolheiser.com/pwn v0.0.3 ## explicit go.jolheiser.com/pwn -# go.mongodb.org/mongo-driver v1.3.5 +# go.mongodb.org/mongo-driver v1.4.4 go.mongodb.org/mongo-driver/bson go.mongodb.org/mongo-driver/bson/bsoncodec go.mongodb.org/mongo-driver/bson/bsonoptions @@ -801,7 +806,7 @@ go.uber.org/zap/internal/bufferpool go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore -# golang.org/x/crypto v0.0.0-20201217014255-9d1352758620 +# golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad ## explicit golang.org/x/crypto/argon2 golang.org/x/crypto/bcrypt @@ -831,7 +836,7 @@ golang.org/x/crypto/ssh/knownhosts # golang.org/x/mod v0.3.0 golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 +# golang.org/x/net v0.0.0-20210119194325-5f4716e94777 ## explicit golang.org/x/net/bpf golang.org/x/net/context @@ -848,22 +853,24 @@ golang.org/x/net/ipv4 golang.org/x/net/ipv6 golang.org/x/net/proxy golang.org/x/net/publicsuffix -# golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 +# golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013 ## explicit golang.org/x/oauth2 golang.org/x/oauth2/google +golang.org/x/oauth2/google/internal/externalaccount golang.org/x/oauth2/internal golang.org/x/oauth2/jws golang.org/x/oauth2/jwt -# golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 +# golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c ## explicit golang.org/x/sys/cpu +golang.org/x/sys/execabs golang.org/x/sys/internal/unsafeheader golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/svc golang.org/x/sys/windows/svc/debug -# golang.org/x/text v0.3.4 +# golang.org/x/text v0.3.5 ## explicit golang.org/x/text/encoding golang.org/x/text/encoding/charmap @@ -886,10 +893,10 @@ golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm golang.org/x/text/width -# golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e +# golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 ## explicit golang.org/x/time/rate -# golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9 +# golang.org/x/tools v0.1.0 ## explicit golang.org/x/tools/cover golang.org/x/tools/go/analysis @@ -973,7 +980,7 @@ gopkg.in/gomail.v2 gopkg.in/ini.v1 # gopkg.in/warnings.v0 v0.1.2 gopkg.in/warnings.v0 -# gopkg.in/yaml.v2 v2.3.0 +# gopkg.in/yaml.v2 v2.4.0 ## explicit gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 From 99b7af6fc89687ee74ca938b9a3f07bf8acc79dd Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Thu, 28 Jan 2021 19:08:11 +0100 Subject: [PATCH 24/24] Add some Unit-Tests (#14500) * fix url * modules/auth/pa: coverage: 40#.0% * modules/base coverage: 67.6% -> 89.9% * modules/cache coverage: 0% -> 12.0% * modules/convert coverage: 27.1% -> 29.7% --- modules/auth/pam/pam_test.go | 20 ++++ modules/base/natural_sort_test.go | 4 +- modules/base/tool.go | 2 +- modules/base/tool_test.go | 99 ++++++++++++++++++-- modules/cache/cache_test.go | 151 ++++++++++++++++++++++++++++++ modules/convert/utils_test.go | 39 ++++++++ 6 files changed, 306 insertions(+), 9 deletions(-) create mode 100644 modules/auth/pam/pam_test.go create mode 100644 modules/cache/cache_test.go create mode 100644 modules/convert/utils_test.go diff --git a/modules/auth/pam/pam_test.go b/modules/auth/pam/pam_test.go new file mode 100644 index 0000000000000..eafc9bc3dba4b --- /dev/null +++ b/modules/auth/pam/pam_test.go @@ -0,0 +1,20 @@ +// +build pam + +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package pam + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPamAuth(t *testing.T) { + result, err := Auth("gitea", "user1", "false-pwd") + assert.Error(t, err) + assert.EqualValues(t, "Authentication failure", err.Error()) + assert.Len(t, result, 0) +} diff --git a/modules/base/natural_sort_test.go b/modules/base/natural_sort_test.go index b8d45e4ec096f..2faa5acf38298 100644 --- a/modules/base/natural_sort_test.go +++ b/modules/base/natural_sort_test.go @@ -17,8 +17,8 @@ func TestNaturalSortLess(t *testing.T) { test("v1.20.0", "v1.2.0", false) test("v1.20.0", "v1.29.0", true) test("v1.20.0", "v1.20.0", false) - test("abc", "bcd", "abc" < "bcd") + test("abc", "bcd", true) test("a-1-a", "a-1-b", true) test("2", "12", true) - test("a", "ab", "a" < "ab") + test("a", "ab", true) } diff --git a/modules/base/tool.go b/modules/base/tool.go index 53339d6449568..d721d47e9d773 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -270,7 +270,7 @@ func Int64sContains(intsSlice []int64, a int64) bool { } // IsLetter reports whether the rune is a letter (category L). -// https://github.com/golang/go/blob/master/src/go/scanner/scanner.go#L257 +// https://github.com/golang/go/blob/c3b4918/src/go/scanner/scanner.go#L342 func IsLetter(ch rune) bool { return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) } diff --git a/modules/base/tool_test.go b/modules/base/tool_test.go index a2a989b31f85c..b6baeb8c3ce70 100644 --- a/modules/base/tool_test.go +++ b/modules/base/tool_test.go @@ -5,7 +5,10 @@ package base import ( + "encoding/base64" + "os" "testing" + "time" "github.com/stretchr/testify/assert" ) @@ -53,11 +56,48 @@ func TestBasicAuthDecode(t *testing.T) { func TestBasicAuthEncode(t *testing.T) { assert.Equal(t, "Zm9vOmJhcg==", BasicAuthEncode("foo", "bar")) + assert.Equal(t, "MjM6IjotLS0t", BasicAuthEncode("23:\"", "----")) } -// TODO: Test PBKDF2() -// TODO: Test VerifyTimeLimitCode() -// TODO: Test CreateTimeLimitCode() +func TestVerifyTimeLimitCode(t *testing.T) { + tc := []struct { + data string + minutes int + code string + valid bool + }{{ + data: "data", + minutes: 2, + code: testCreateTimeLimitCode(t, "data", 2), + valid: true, + }, { + data: "abc123-ß", + minutes: 1, + code: testCreateTimeLimitCode(t, "abc123-ß", 1), + valid: true, + }, { + data: "data", + minutes: 2, + code: "2021012723240000005928251dac409d2c33a6eb82c63410aaad569bed", + valid: false, + }} + for _, test := range tc { + actualValid := VerifyTimeLimitCode(test.data, test.minutes, test.code) + assert.Equal(t, test.valid, actualValid, "data: '%s' code: '%s' should be valid: %t", test.data, test.code, test.valid) + } +} + +func testCreateTimeLimitCode(t *testing.T, data string, m int) string { + result0 := CreateTimeLimitCode(data, m, nil) + result1 := CreateTimeLimitCode(data, m, time.Now().Format("200601021504")) + result2 := CreateTimeLimitCode(data, m, time.Unix(time.Now().Unix()+int64(time.Minute)*int64(m), 0).Format("200601021504")) + + assert.Equal(t, result0, result1) + assert.NotEqual(t, result0, result2) + + assert.True(t, len(result0) != 0) + return result0 +} func TestFileSize(t *testing.T) { var size int64 = 512 @@ -76,6 +116,12 @@ func TestFileSize(t *testing.T) { assert.Equal(t, "2.0 EiB", FileSize(size)) } +func TestPrettyNumber(t *testing.T) { + assert.Equal(t, "23,342,432", PrettyNumber(23342432)) + assert.Equal(t, "0", PrettyNumber(0)) + assert.Equal(t, "-100,000", PrettyNumber(-100000)) +} + func TestSubtract(t *testing.T) { toFloat64 := func(n interface{}) float64 { switch v := n.(type) { @@ -168,6 +214,13 @@ func TestInt64sToMap(t *testing.T) { ) } +func TestInt64sContains(t *testing.T) { + assert.Equal(t, map[int64]bool{}, Int64sToMap([]int64{})) + assert.Equal(t, true, Int64sContains([]int64{6, 44324, 4324, 32, 1, 2323}, 1)) + assert.Equal(t, true, Int64sContains([]int64{2323}, 2323)) + assert.Equal(t, false, Int64sContains([]int64{6, 44324, 4324, 32, 1, 2323}, 232)) +} + func TestIsLetter(t *testing.T) { assert.True(t, IsLetter('a')) assert.True(t, IsLetter('e')) @@ -181,6 +234,8 @@ func TestIsLetter(t *testing.T) { assert.False(t, IsLetter('-')) assert.False(t, IsLetter('1')) assert.False(t, IsLetter('$')) + assert.False(t, IsLetter(0x00)) + assert.False(t, IsLetter(0x93)) } func TestDetectContentTypeLongerThanSniffLen(t *testing.T) { @@ -197,11 +252,19 @@ Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment -->`))) } +// IsRepresentableAsText + func TestIsTextFile(t *testing.T) { assert.True(t, IsTextFile([]byte{})) assert.True(t, IsTextFile([]byte("lorem ipsum"))) } +func TestIsImageFile(t *testing.T) { + png, _ := base64.StdEncoding.DecodeString("iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAG0lEQVQYlWN4+vTpf3SMDTAMBYXYBLFpHgoKAeiOf0SGE9kbAAAAAElFTkSuQmCC") + assert.True(t, IsImageFile(png)) + assert.False(t, IsImageFile([]byte("plain text"))) +} + func TestIsSVGImageFile(t *testing.T) { assert.True(t, IsSVGImageFile([]byte(""))) assert.True(t, IsSVGImageFile([]byte(" "))) @@ -248,6 +311,33 @@ func TestIsSVGImageFile(t *testing.T) { `))) } +func TestIsPDFFile(t *testing.T) { + pdf, _ := base64.StdEncoding.DecodeString("JVBERi0xLjYKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nF3NPwsCMQwF8D2f4s2CNYk1baF0EHRwOwg4iJt/NsFb/PpevUE4Mjwe") + assert.True(t, IsPDFFile(pdf)) + assert.False(t, IsPDFFile([]byte("plain text"))) +} + +func TestIsVideoFile(t *testing.T) { + mp4, _ := base64.StdEncoding.DecodeString("AAAAGGZ0eXBtcDQyAAAAAGlzb21tcDQyAAEI721vb3YAAABsbXZoZAAAAADaBlwX2gZcFwAAA+gA") + assert.True(t, IsVideoFile(mp4)) + assert.False(t, IsVideoFile([]byte("plain text"))) +} + +func TestIsAudioFile(t *testing.T) { + mp3, _ := base64.StdEncoding.DecodeString("SUQzBAAAAAABAFRYWFgAAAASAAADbWFqb3JfYnJhbmQAbXA0MgBUWFhYAAAAEQAAA21pbm9yX3Zl") + assert.True(t, IsAudioFile(mp3)) + assert.False(t, IsAudioFile([]byte("plain text"))) +} + +// TODO: Test EntryIcon + +func TestSetupGiteaRoot(t *testing.T) { + _ = os.Setenv("GITEA_ROOT", "test") + assert.EqualValues(t, "test", SetupGiteaRoot()) + _ = os.Setenv("GITEA_ROOT", "") + assert.NotEqual(t, "test", SetupGiteaRoot()) +} + func TestFormatNumberSI(t *testing.T) { assert.Equal(t, "125", FormatNumberSI(int(125))) assert.Equal(t, "1.3k", FormatNumberSI(int64(1317))) @@ -255,6 +345,3 @@ func TestFormatNumberSI(t *testing.T) { assert.Equal(t, "45.7G", FormatNumberSI(45721317675)) assert.Equal(t, "", FormatNumberSI("test")) } - -// TODO: IsImageFile(), currently no idea how to test -// TODO: IsPDFFile(), currently no idea how to test diff --git a/modules/cache/cache_test.go b/modules/cache/cache_test.go new file mode 100644 index 0000000000000..92be69252dd58 --- /dev/null +++ b/modules/cache/cache_test.go @@ -0,0 +1,151 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package cache + +import ( + "fmt" + "testing" + "time" + + "code.gitea.io/gitea/modules/setting" + + "github.com/stretchr/testify/assert" +) + +func createTestCache() { + conn, _ = newCache(setting.Cache{ + Adapter: "memory", + TTL: time.Minute, + }) +} + +func TestNewContext(t *testing.T) { + assert.NoError(t, NewContext()) + + setting.CacheService.Cache = setting.Cache{Enabled: true, Adapter: "redis", Conn: "some random string"} + con, err := newCache(setting.Cache{ + Adapter: "rand", + Conn: "false conf", + Interval: 100, + }) + assert.Error(t, err) + assert.Nil(t, con) +} + +func TestGetCache(t *testing.T) { + createTestCache() + + assert.NotNil(t, GetCache()) +} + +func TestGetString(t *testing.T) { + createTestCache() + + data, err := GetString("key", func() (string, error) { + return "", fmt.Errorf("some error") + }) + assert.Error(t, err) + assert.Equal(t, "", data) + + data, err = GetString("key", func() (string, error) { + return "", nil + }) + assert.NoError(t, err) + assert.Equal(t, "", data) + + // data, err = GetString("key", func() (string, error) { + // return "some data", nil + // }) + // assert.NoError(t, err) + // assert.Equal(t, "", data) + // Remove("key") + + data, err = GetString("key", func() (string, error) { + return "some data", nil + }) + assert.NoError(t, err) + assert.Equal(t, "some data", data) + + // data, err = GetString("key", func() (string, error) { + // return "", fmt.Errorf("some error") + // }) + // assert.NoError(t, err) + // assert.Equal(t, "some data", data) + + // TODO: uncommented code works in IDE but not with go test +} + +func TestGetInt(t *testing.T) { + createTestCache() + + data, err := GetInt("key", func() (int, error) { + return 0, fmt.Errorf("some error") + }) + assert.Error(t, err) + assert.Equal(t, 0, data) + + data, err = GetInt("key", func() (int, error) { + return 0, nil + }) + assert.NoError(t, err) + assert.Equal(t, 0, data) + + // data, err = GetInt("key", func() (int, error) { + // return 100, nil + // }) + // assert.NoError(t, err) + // assert.Equal(t, 0, data) + // Remove("key") + + data, err = GetInt("key", func() (int, error) { + return 100, nil + }) + assert.NoError(t, err) + assert.Equal(t, 100, data) + + // data, err = GetInt("key", func() (int, error) { + // return 0, fmt.Errorf("some error") + // }) + // assert.NoError(t, err) + // assert.Equal(t, 100, data) + + // TODO: uncommented code works in IDE but not with go test +} +func TestGetInt64(t *testing.T) { + createTestCache() + + data, err := GetInt64("key", func() (int64, error) { + return 0, fmt.Errorf("some error") + }) + assert.Error(t, err) + assert.EqualValues(t, 0, data) + + data, err = GetInt64("key", func() (int64, error) { + return 0, nil + }) + assert.NoError(t, err) + assert.EqualValues(t, 0, data) + + // data, err = GetInt64("key", func() (int64, error) { + // return 100, nil + // }) + // assert.NoError(t, err) + // assert.EqualValues(t, 0, data) + // Remove("key") + + data, err = GetInt64("key", func() (int64, error) { + return 100, nil + }) + assert.NoError(t, err) + assert.EqualValues(t, 100, data) + + // data, err = GetInt64("key", func() (int, error) { + // return 0, fmt.Errorf("some error") + // }) + // assert.NoError(t, err) + // assert.EqualValues(t, 100, data) + + // TODO: uncommented code works in IDE but not with go test +} diff --git a/modules/convert/utils_test.go b/modules/convert/utils_test.go new file mode 100644 index 0000000000000..bd59299c01bd3 --- /dev/null +++ b/modules/convert/utils_test.go @@ -0,0 +1,39 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package convert + +import ( + "testing" + + _ "github.com/mattn/go-sqlite3" + "github.com/stretchr/testify/assert" +) + +func TestToCorrectPageSize(t *testing.T) { + assert.EqualValues(t, 30, ToCorrectPageSize(0)) + assert.EqualValues(t, 30, ToCorrectPageSize(-10)) + assert.EqualValues(t, 20, ToCorrectPageSize(20)) + assert.EqualValues(t, 50, ToCorrectPageSize(100)) +} + +func TestToGitServiceType(t *testing.T) { + tc := []struct { + typ string + enum int + }{{ + typ: "github", enum: 2, + }, { + typ: "gitea", enum: 3, + }, { + typ: "gitlab", enum: 4, + }, { + typ: "gogs", enum: 5, + }, { + typ: "trash", enum: 1, + }} + for _, test := range tc { + assert.EqualValues(t, test.enum, ToGitServiceType(test.typ)) + } +}