text:
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
  <string name="accept_location">Ulož polohu</string>
  <string name="accuracy">Přesnost</string>
  <string name="activity_not_found">Nenalezena žádná aktivita k řešení: %s</string>
  <string name="add_another">Přidat skupinu</string>
  <string name="add_another_repeat">Přidat další \"%s\" skupinu?</string>
  <string name="add_more">Přidat další</string>
  <string name="add_repeat">Pridat další \"%s\" skupinu?</string>
  <string name="add_repeat_no">Nepřidávat</string>
  <string name="advance">přejít k\nnásledující\notázce</string>
  <string name="altitude">Nadmořská výška</string>
  <string name="audio_file_error">Nebyl vybrán žádný audio soubor</string>
  <string name="audio_file_invalid">Soubor: %s není platný audio soubor.</string>
  <string name="backup">zpět k\npředchozí\notázce</string>
  <string name="barcode_scanner_error">Scanner čárových kódů není instalován!</string>
  <string name="cancel">Zrušit</string>
  <string name="cancel_loading_form">Zrušit</string>
  <string name="cancel_location">Zrušit</string>
  <string name="cannot_edit_completed_form">Dotazník, který byl označen za kompletní už nejde editovat. Může být zakódovaný.</string>
  <string name="capture_audio">Nahrát zvuk</string>
  <string name="capture_image">Udělat fotku</string>
  <string name="capture_video">Nahrát video</string>
  <string name="change_language">Změnit jazyk</string>
  <string name="change_password">Heslo do ODK</string>
  <string name="change_protocol_settings_default">Nastavení platformy</string>
  <string name="change_username">Uživatelské jméno do ODK</string>
  <string name="clearanswer_confirm">Odstranit odpověď na \"%s\"?</string>
  <string name="clear_answer">Odstranit odpověď</string>
  <string name="clear_answer_ask">Odstranit tuto odpověď?</string>
  <string name="clear_answer_no">Zrušit</string>
  <string name="completed_data">Hotovo (%s)</string>
  <string name="data">Uložené dotazníky</string>
  <string name="data_saved_error">Uložení dotazníku selhalo!</string>
  <string name="data_saved_ok">Dotazník úspěšně uložen!</string>
  <string name="save_point_error">Chyba při ukládání bodu obnovení: %s</string>
  <string name="default_completed">Ukládání dotazníku</string>
  <string name="default_completed_summary">Vždy uložit dotazník jako dokončený</string>
  <string name="delete_confirm">Smazat \"%s\" dotazník(ů)</string>
  <string name="delete_file">Smazat označené</string>
  <string name="delete_no">Nemazat</string>
  <string name="delete_repeat">Odstranit skupinu</string>
  <string name="delete_repeat_ask">Odstranit tuto skupinu?</string>
  <string name="delete_repeat_confirm">Odstranit skupinu \"%s\" a všechny její podskupiny?</string>
  <string name="delete_repeat_no">Zrušit</string>
  <string name="delete_yes">Smazat dotazníky</string>
  <string name="discard_answer">Smazat odpověď</string>
  <string name="discard_group">Odstranit skupinu</string>
  <string name="download">Stáhnout vybrané</string>
  <string name="download_forms_result">Stáhnout výsledky</string>
  <string name="downloading_data">Připojuji se k serveru</string>
  <string name="do_not_change">Zrušit</string>
  <string name="do_not_exit">Zrušit</string>
  <string name="do_not_save">Ignorovat změny</string>
  <string name="entering_repeat">Přidat skupinu</string>
  <string name="entering_repeat_ask">Přidat novou skupinu?</string>
  <string name="enter_data">Vyplnit dotazník</string>
  <string name="enter_data_button">Vyplnit dotazník</string>
  <string name="error_occured">Vyskytla se chyba</string>
  <string name="error_attaching_binary_file">Při vkládání médií: %s nastala chyba</string>
  <string name="fetching_file">Stahuji %1$s.\n\nForm %2$s z %3$s dotazníků.</string>
  <string name="file_deleted_error">%1$s z %2$s vybraných dotazníků se nepodařilo smazat!</string>
  <string name="file_deleted_ok">%s dotazníků úspěšně smazáno!</string>
  <string name="file_delete_in_progress">Mazání dotazníku už probíhá!</string>
  <string name="file_invalid">Soubor: %s není platný.</string>
  <string name="file_missing">Soubor: %s chybí.</string>
  <string name="finished_disk_scan">Prohledávání dokončeno. Všechny dotazníky načteny.</string>
  <string name="forms">Dotazníky k vyplnění</string>
  <string name="getting_location">Načítám pozici</string>
  <string name="get_barcode">Získat čárový kód</string>
  <string name="get_forms">Získat dotazník k vyplnění</string>
  <string name="get_location">Uložit pozici</string>
  <string name="provider_disabled_error">Nástroje pro získání polohy jsou zakázané!</string>
  <string name="invalid_answer_error">Tato odpověď je neplatná!</string>
  <string name="jump_to_beginning">Přejít na začátek</string>
  <string name="jump_to_end">Přejít na konec</string>
  <string name="jump_to_previous">Přejít nahoru</string>
  <string name="latitude">Zeměpisná šířka</string>
  <string name="leave_repeat_yes">Nepřidávat</string>
  <string name="leaving_repeat_ask">Přidat další skupinu?</string>
  <string name="list_failed_with_error">Výpis dotazníku selhal. %s.</string>
  <string name="loading_form">Načítám dotazník</string>
  <string name="load_remote_form_error">Chyba při načítání seznamu dotazníků</string>
  <string name="location_provider_accuracy">Používám %1$s. Přesnost: %2$s m.</string>
  <string name="location_accuracy">Přesnost: %1$s m</string>
  <string name="longitude">Zeměpisná délka</string>
  <string name="main_menu">Hlavní nabídka</string>
  <string name="main_menu_details">Pro snazší sběr dat...</string>
  <string name="manage_files">Smazat uložený dotazník</string>
  <string name="mark_finished">Označit dotazník jako dokončený</string>
  <string name="noselect_error">Nevybral/a jste žádný dotazník!</string>
  <string name="no_connection">Není k dispozici připojení k internetu!</string>
  <string name="no_items_display">Není co zobrazit.</string>
  <string name="no_items_display_forms">Není co zobrazit.\n\nZkuste stáhnout a vyplnit dotazník.</string>
  <string name="no_items_display_instances">
Není co zobrazit.\n\nZkuste před odesláním označit dotazníky jako dokončené.</string>
  <string name="ok">OK</string>
  <string name="parse_error">Dotazník nejde načíst.</string>
  <string name="parse_legacy_formlist_failed">Server neposkytnul seznam dostupných dotazníků kompatibilní s Aggregate 0.9.x. : %s</string>
  <string name="parse_openrosa_formlist_failed">Server neposkytnul seznam dostupných dotazníků kompatibilní se standartem OpenRosa 1.0: %s</string>
  <string name="password">Heslo</string>
  <string name="play_audio">Přehrát zvuk</string>
  <string name="play_video">Přehrát video</string>
  <string name="please_wait">Prosím chvilku počkejte.</string>
  <string name="please_wait_long">Prosím čekejte. Může to trvat několik minut.</string>
  <string name="quit_application">Konec %s</string>
  <string name="quit_entry">Uložit dotazník a skončit</string>
  <string name="refresh">Obnovit</string>
  <string name="replace_barcode">Změnit čárový kód</string>
  <string name="replace_location">Změnit polohu</string>
  <string name="required_answer_error">Tato odpověď je povinná!</string>
  <string name="review_data">Editovat uložený dotazník</string>
  <string name="review_data_button">Editovat uložený dotazník (%s)</string>
  <string name="saved_data">Nekompletní (%s)</string>
  <string name="save_all_answers">Uložit dotazník</string>
  <string name="save_enter_data_description">Jste na konci %s.</string>
  <string name="saving_form">Ukládám dotazník</string>
  <string name="sending_items">Odesílám %1$s z %2$s dotazník(ů)</string>
  <string name="send_data">Odeslat dokončený dotazník</string>
  <string name="send_data_button">Odeslat dokončený dotazník (%s)</string>
  <string name="send_selected_data">Odeslat vybrané</string>
  <string name="server_auth_credentials">Zadejte prosím uživatelské jméno a heslo pro server:\n%s</string>
  <string name="server_requires_auth">Server vyžaduje přihlášení</string>
  <string name="server_url">URL</string>
  <string name="server_preferences">Nastavení serveru</string>
  <string name="toggle_selected">O(d)značit všechny</string>
  <string name="trigger">OK. Pokračujte prosím.</string>
  <string name="uploading_data">Odesílám dotazník</string>
  <string name="url_error">Neplatné URL!</string>
  <string name="username">Uživatelské jméno</string>
  <string name="view_hierarchy">Přejít k otázce</string>
  <string name="general_preferences">Obecná nastavení</string>
  <string name="click_to_web">Klepnutím přejděte na http://opendatakit.org</string>
  <string name="client">Uživatelské rozhraní</string>
  <string name="show_splash">Zobrazit úvodní obrazovku</string>
  <string name="show_splash_summary">Zobrazit při startu aplikace</string>
  <string name="splash_path">Vyberte úvodní obrázek</string>
  <string name="default_splash_path">Výchozí obrazovka ODK</string>
  <string name="select_another_image">Vybrat další obrázek</string>
  <string name="use_odk_default">Použít výchozí obrázek</string>
  <string name="change_splash_path">Změnit obrázek</string>
  <string name="show_location">Ukázat pozici</string>
  <string name="keep_changes">Uložit změny</string>
  <string name="go_to_location">Přejít na pozici</string>
  <string name="change_formlist_url">Cesta k seznamu dotazníků (přidat k URL)</string>
  <string name="protocol">Platforma</string>
  <string name="change_protocol">Platforma</string>
  <string name="change_submission_url">Cesta pro odeslání (přidat k URL)</string>
  <string name="formlist_url">Cesta k seznamu dotazníků</string>
  <string name="submission_url">Cesta pro odeslání</string>
  <string name="font_size">Velikost písma</string>
  <string name="change_font_size">Velikost písma</string>
  <string name="form_scan_starting">Vyhledávám dotazníky...</string>
  <string name="access_error">Chyba při přístupu k %s:</string>
  <string name="manifest_server_error">Odpověď manifestu nehlásí verzi OpenRosa - špatný server?</string>
  <string name="root_element_error">Kořenový prvek není <manifest\> — místo toho předán %s</string>
  <string name="root_namespace_error">Jmenný prostor kořenového prvku není správný: %s</string>
  <string name="manifest_tag_error">Na vstupu manifestu %s chybí jeden nebo více tagů: filename, hash nebo downloadUrl</string>
  <string name="form_download_progress">%1$s. Stahuji mediální soubory: %2$s z %3$s</string>
  <string name="file_fetch_failed">Chyba: %2$s (%3$s) na %1$s</string>
  <string name="fetching_manifest">%s. Stahuji manifest </string>
  <string name="success">Úspěch</string>
  <string name="no_forms_uploaded">Žádný dotazník nebyl nahrán.</string>
  <string name="upload_results">Výsledky nahrávání</string>
  <string name="xform_parse_error">Chyba pársování XForm. %1$s chybí element %2$s</string>
  <string name="choose_sound">Vyberte zvuk</string>
  <string name="choose_video">Vyberte video</string>
  <string name="choose_image">Vyberte obrázek</string>
  <string name="selected">Vybráno:</string>
  <string name="select_answer">Zvolte odpověď</string>
  <string name="save_form_as">Pojmenujte tento dotazník</string>
  <string name="save_as_error">Uložené jméno nesmí být prázdné!</string>
  <string name="edit_prompt">Editovat otázku</string>
  <string name="selected_google_account_text">Účet Google</string>
  <string name="server_platform_odk_aggregate">ODK Aggregate</string>
  <string name="server_platform_other">Jiný</string>
  <string name="font_size_extra_large">Extra velký</string>
  <string name="font_size_large">Velký</string>
  <string name="font_size_medium">Střední</string>
  <string name="font_size_small">Malý</string>
  <string name="font_size_extra_small">Extra malý</string>
  <string name="change_view">Změnit pohled</string>
  <string name="show_sent_and_unsent_forms">Zobrazit odeslané a neodeslané dotazníky</string>
  <string name="show_unsent_forms">Zobrazit neodeslané dotazníky</string>
  <string name="added_on_date_at_time">\'Přidáno\' EEE, dd MMM, yyyy \'v\' HH:mm</string>
  <!--http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html-->
  <string name="saved_on_date_at_time">\'Uloženo\' EEE, dd MMM, yyyy \'v\' HH:mm</string>
  <!--http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html-->
  <string name="finalized_on_date_at_time">\'Dokončeno\' EEE, dd MMM, yyyy \'v\' HH:mm</string>
  <!--http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html-->
  <string name="sent_on_date_at_time">\'Odesláno\' EEE, dd MMM, yyyy \'v\' HH:mm</string>
  <!--http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html-->
  <string name="sending_failed_on_date_at_time">\'Odesílání selhalo\' EEE, dd MMM, yyyy \'v\' HH:mm</string>
  <!--http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html-->
  <string name="version">Verze:</string>
  <string name="parent_form_not_present">Tento uložený dotazník nelze editovat, protože jeho předloha chybí nebo byla smazána.\n\n ID dotazníku: %1$s</string>
  <string name="launch_app">Spustit</string>
  <string name="no_app">Požadovaná aplikace chybí. Zadejte prosím údaje ručně.</string>
  <string name="select_one">Zvolte jednu odpověď</string>
  <string name="savepoint_used">Neuložené změny obnoveny z bodu obnovy!</string>
  <string name="save_and_close">Uložit a zavřít</string>
  <string name="sign_button">Získat podpis</string>
  <string name="markup_image">Markup Image</string>
  <string name="draw_image">Sketch Image</string>
  <string name="reset_image">Resetovat</string>
  <string name="set_color">Nastavit barvu</string>
  <string name="select_drawing_color">Vybrat barvu čáry</string>
  <string name="user_access_main_menu">Dostupné v hlavní nabídce:</string>
  <string name="user_access_preferences">V nastavení lze měnit:</string>
  <string name="change_server">Platforma</string>
  <string name="change_username_default">Uživatelské jméno</string>
  <string name="admin_preferences">Administrátorská nastavení</string>
  <string name="admin_access_settings">Klepněte pro administrátorský přístup do Nastavení</string>
  <string name="user_access_form_entry">Dostupné při vyplňování dotazníku:</string>
  <string name="save_mid">Uložit dotazník</string>
  <string name="enter_new_password">Zadejte nové heslo</string>
  <string name="verify_new_password">Zadejte nové heslo znovu</string>
  <string name="admin_password_changed">Administrátorské heslo úspěšně změněno</string>
  <string name="admin_password_disabled">Administrátorské heslo vypnuto</string>
  <string name="admin_password_mismatch">Hesla se neshodují!</string>
  <string name="admin_password_incorrect">Heslo není správné!</string>
  <string name="enter_admin_password">Zadejte administrátorské heslo</string>
  <string name="found_in_menu">Zobrazit v menu při vyplňování dotazníku</string>
  <string name="autosend">Odeslat automaticky</string>
  <string name="autosend_wifi">...přes Wi-Fi</string>
  <string name="autosend_wifi_summary">Odeslat automaticky jakmile bude Wi-Fi k dispozici</string>
  <string name="autosend_network">...přes datové připojení</string>
  <string name="autosend_network_summary">Odeslat automaticky jakmile bude datové připojení k dispozici</string>
  <string name="found_in_main">Zobrazit v Hlavní nabídce</string>
  <string name="found_in_settings">Zobrazit v Obecném nastavení</string>
  <string name="found_at_end">Zobrazit na konci vyplňování dotazníku</string>
  <string name="no_account">Žádný účet</string>
  <string name="save_preferences">Uložit nastavení na Disk</string>
  <string name="form_forward">Další</string>
  <string name="form_backward">Předchozí</string>
  <string name="navigation">Navigace</string>
  <string name="swipe_navigation">Pohybem prstu do strany (swipe)</string>
  <string name="buttons_navigation">Pomocí tlačítek se šipkami</string>
  <string name="swipe_buttons_navigation">Pomocí swipu a tlačítek</string>
  <string name="swipe_instructions">Jste na začátku dotazníku %s. Pro posun vpřed a zpět přejeďte prstem po obrazovce tak, jak vidíte níže.</string>
  <string name="buttons_instructions">Jste na začátku dotazníku %s. Pro posun vpřed a zpět stiskněte tlačítka se šipkami zobrazená níže</string>
  <string name="swipe_buttons_instructions">Jste na začátku dotazníku %s. Pro pohyb vpřed a zpět přejeďte prstem po obrazovce nebo stiskněte tlačítka se šipkami</string>
  <string name="launch_printer">Tisknout</string>
  <string name="no_printer">Vybraná tiskárna není nainstalována. Nejdříve ji nainstalujte.</string>
  <string name="constraint_behavior">Ověření správnosti odpovědi</string>
  <string name="constraint_behavior_on_swipe">Ověření při přechodu na další otázku</string>
  <string name="constraint_behavior_on_finalize">Provést validaci až při dokončení</string>
  <string name="view_change_location">Prohlédnout nebo změnit polohu</string>
  <string name="open_url">Otevřít URL</string>
  <string name="get_bearing">Zaznamenat orientaci</string>
  <string name="replace_bearing">Nahradit orientaci</string>
  <string name="getting_bearing">Nahrávám orientaci</string>
  <string name="accept_bearing">Zaznamenat orientaci</string>
  <string name="sdcard_unmounted">Nemohu přistoupit na SD kartu. Možná jste připojeni přes USB (Současný stav: %s)</string>
  <string name="ext_file_no_data_error">Soubor neobsahuje žádná data!</string>
  <string name="ext_conflicting_columns_error">Sloupce %s souhlasí!</string>
  <string name="ext_sortBy_numeric_error">Sloupec pro řazení smí obsahovat jen číselné hodnoty. Problematická hodnota je \'%s\'.</string>
  <string name="ext_search_wrong_arguments_error">Chyba zadání ve funkci search() : Funkce potřebuje 1, 4 nebo 6 parametrů</string>
  <string name="ext_search_wrong_function_error">Chyba zadání ve funkci search() : Neznámá funkce \'%s\'.</string>
  <string name="ext_search_bad_function_error">Chyba zadání ve funkci search() : \'%s\' není funkce.</string>
  <string name="ext_search_return_error">Vyhledávání vrátilo objekt typu \'%s\'.</string>
  <string name="ext_import_generic_error">Nemohu importovat data z %1$s. Důvod: %2$s</string>
  <string name="ext_import_progress_message">Nahrávám data z \'%1$s\', počkejte prosím... %2$s</string>
  <string name="ext_import_cancelled_message">Načtení dat přerušeno!</string>
  <string name="ext_import_finalizing_message">Dokončuji nahraná data...</string>
  <string name="ext_import_completed_message">Načtení dat dokončeno!</string>
  <string name="ext_not_initialized_error">ExternalDataManager nebyl spuštěn.</string>
  <string name="ext_import_csv_missing_error">Externí data pro %1$s nebyla importována. Možná jste zapomněl/a přidat k dotazníku soubor %2$s.csv?</string>
  <string name="ext_search_generic_error">Chyba zadání ve funkci search() : %s</string>
  <string name="ext_assign_value_error">Nemohu přidělit hodnotu k \'%s\'.</string>
  <string name="fs_delete_media_path_if_file_error">Nemohu vymazat \'%s\'. Vymažte soubor ručně a stáhněte dotazník znovu.</string>
  <string name="fs_create_media_folder_error">Nemohu vytvořit adresář pro mediální soubory \'%s\'.</string>
  <string name="fs_file_copy_error">Nezdařilo se nakopírovat \'%1$s\' přes \'%2$s\'. Důvod: %3$s </string>
  <string name="survey_internal_error">Vnitřní chyba: přechod k otázce selhal.</string>
  <string name="survey_multiple_forms_error">Stáhli jste dva různé formuláře se shodným ID a verzí. Možná jste nahráli stejný dotazník dvakrát nebo na jiné servery. Každopádně, jeden byste měli smazat.</string>
  <string name="survey_loading_reading_form_message">Načítám nastavení dotazníku...</string>
  <string name="survey_loading_reading_data_message">Načítám data dotazníků...</string>
  <string name="survey_loading_reading_csv_message">Načítám CSV soubory...</string>
  <string name="survey_saving_validating_message">Ověřuji odpovědi...</string>
  <string name="survey_saving_collecting_message">Sbírám data...</string>
  <string name="survey_saving_saving_message">Ukládám na SD kartu...</string>
  <string name="survey_saving_finalizing_message">Dokončuji ukládání na SD kartu...</string>
  <string name="survey_saving_encrypting_message">Šifruji data...</string>
  <string name="high_resolution_summary">Povolit vysoké rozlišení videonahrávek</string>
  <string name="high_resolution">Vysoké rozlišení videa</string>
  <string name="google_drive">Google Drive</string>
  <string name="go_drive">Můj disk</string>
  <string name="go_shared">Sdíleno se mnou</string>
  <string name="modified_on_date_at_time">\'Upraveno v \' EEE, dd MMM, yyyy \'v\' HH:mm</string>
  <string name="protocol_settings">Konfigurovat nastavení platformy</string>
  <string name="aggregate_preferences">Nastavení ODK Aggregate</string>
  <string name="other_preferences">Ostatní nastavení platformy</string>
  <string name="drive_get_file">Získávám %1$s a mediální soubory</string>
  <string name="no_google_account">Není vybrán žádný účet Google!</string>
  <string name="invalid_oauth">Neplatný kód OAuth 2</string>
  <string name="picasa_upload_error">Chyba při nahrávání fotografie - Fotografie není k dispozici : %1$s</string>
  <string name="odk_auth_auth_fail">Chyba autorizace ODK pro automatické odesílání dat, ujistěte se, že Vaše nastavení je správné</string>
  <string name="odk_auto_note">ODK - výsledek automatického odeslání</string>
  <string name="notification_error">Chyba při zobrazení oznámení</string>
  <string name="delete_after_send">Vymazat po odeslání</string>
  <string name="delete_after_send_summary">Vymaže dokončené dotazníky a média po odeslání na server</string>
  <string name="change_server_url">URL Serveru</string>
  <string name="no_blank_search">Vyhledávací pole nemůže být prázdné</string>
  <string name="default_google_sheets_url"></string>
</resources>


text:
<template name="loading">

        <link href="css/loading.css" rel="stylesheet">

 Loading....

</template>

redpajama_set_name: RedPajamaGithub


text:
//
//  EYCNCityService.h
//  Pods
//
//  Created by Enix Yu on 29/5/2017.
//
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

typedef void (^EYCNCityServiceCompletion)(NSArray * _Nullable cities, NSError * _Nullable error);

@interface EYCNCityService : NSObject

/// 高德web api Domain,默认为:http://restapi.amap.com
@property (nonatomic, copy, nullable) NSString *apiDomain;

/// 高德获取行政区域web api URI, 默认为: /v3/config/district
@property (nonatomic, copy, nullable) NSString *apiURI;

/**
 * @brief 初始化Service
 * @param key: 高德web API Key,详情请查看:http://developer.amap.com/api/webservice/summary/
 * @return: Service 实例
 */
- (instancetype)initWithAPIKey:(NSString *)key;

/**
 * @brief 请求中国行政区域数据
 * @param completion: 请求完成回调
 */
- (void)requestCNCitiesWithCompletion:(EYCNCityServiceCompletion)completion;

@end

NS_ASSUME_NONNULL_END


text:
package env

import (
	"github.com/spf13/cobra"

	"github.com/nanobox-io/nanobox/processors/server"
	"github.com/nanobox-io/nanobox/util/display"
)

var (

	// ServerCmd ...
	ServerCmd = &cobra.Command{
		Hidden: true,
		Use:    "server",
		Short:  "Server control",
		Long:   ``,
	}

	// ServerStartCmd ...
	ServerStartCmd = &cobra.Command{
		Hidden: true,
		Use:    "start",
		Short:  "Start the server",
		Long:   ``,
		Run:    serverStartFn,
	}

	// ServerStopCmd ...
	ServerStopCmd = &cobra.Command{
		Hidden: true,
		Use:    "stop",
		Short:  "Stop the server",
		Long:   ``,
		Run:    serverStopFn,
	}

	// ServerTeadownCmd ...
	ServerTeadownCmd = &cobra.Command{
		Hidden: true,
		Use:    "teardown",
		Short:  "Teardown the server",
		Long:   ``,
		Run:    serverTeardownFn,
	}
)

//
func init() {
	ServerCmd.AddCommand(ServerStartCmd)
	ServerCmd.AddCommand(ServerStopCmd)
	ServerCmd.AddCommand(ServerTeadownCmd)
}

func serverStartFn(ccmd *cobra.Command, args []string) {
	display.CommandErr(server.Setup())
}

func serverStopFn(ccmd *cobra.Command, args []string) {

	display.CommandErr(server.Stop())
}

func serverTeardownFn(ccmd *cobra.Command, args []string) {

	display.CommandErr(server.Teardown())
}


text:
title: Violence reduction playbook
date: 2016-12-07 08:00:00 -05:00
categories:
- Criminal justice
position: 5
layout: research-article
main: article
description: Finding the right policy is the first step to curbing crime. We break
  down several popular options.
lead: Finding the right policy is the first step to curbing crime. We break down several
  popular options.
image:
  file: "/media/violence-reduction-playbook.jpg"
  alt: Window with bullet holes
author:
- Peter Hagemeyer
- David Morton
further reading:
- title: What Works in Reducing Community Violence
  url: https://www.usaid.gov/sites/default/files/USAID-2016-What-Works-in-Reducing-Community-Violence-Final-Report.pdf
  description: A report from the United States Agency for International Development
    looks at over 1,400 studies to identify what policies and strategies reduce community
    violence.
- title: National Gang Center Program Matrix
  url: https://www.nationalgangcenter.gov/SPT/Program-Matrix
  description: Matrix comparing a large collection of youth and gang crime prevention
    practices.
- title: Crime Solutions Database
  url: https://www.crimesolutions.gov/Programs.aspx
  description: The National Institute of Justice database includes crime programs,
    best practices, and efficacy and evidence ratings.
- title: Desistance and the Feared Self
  url: http://scholarlycommons.law.northwestern.edu/cgi/viewcontent.cgi?article=7339&context=jclc
  description: Ray Paternoster and Shawn Bushway examine why people commit crimes
    and what may make them stop.
- title: Reducing Group Related Violent Crime through Focused Deterrence
  url: http://www.smartpolicinginitiative.com/sites/all/files/resources/Reducing%20Group%20Related%20Violent%20Crime%20through%20Focused%20Deterrence%20in%20High%20Point%20NC.pdf
  description: Researchers look at the stages of focused deterrence as it was implemented  in
    High Point, North Carolina.
about: The Metro Ideas Project examined eight anti-crime policies, reviewed external
  research and interviewed national experts for the violence reduction playbook.
---

Combating violence is one of the most complex and visible challenges cities face. Policy is an important tool to curbing crime, but choosing the right strategy revolves around many questions:

What has worked in other cities? How expensive is implementation? Is a place-based approach better than a people-based approach? What stakeholder partners are needed? How well does a policy balance community safety with that community's values?

The Metro Ideas Project created a rubric comparing eight anti-crime policies. Our violence reduction playbook reflects existing research and interviews with criminal justice experts across the U.S.

      Policy
      Overview

      Focused deterrence
      Focuses resources on a few individuals believed to be responsible for high levels of crime

      Cure Violence
      Treats violence as a public health issue through a network of volunteers, mediators and city officials

      Disorder policing
      Identifies and commits resources to high crime areas

      School-based programs
      Uses schools and education programs to tackle root causes of violence

      Prison programs
      Aims to curbs recidivism through prisoner education and counseling

      Minimum sentencing laws
      Assumes that severity of punishment deters crime

      Civil gang injunctions
      Uses civil nuisance abatements to prevent gangs from congregating in specific areas

## Focused deterrence

Focused deterrence is a suite of crime reduction actions with a common goal: find the most violent offenders and stop them. Beginning with Boston's Operation Ceasefire in the 1990s, focused deterrence strategies promote intelligence-based, responsive policing and lifelines for those affected by violence.

It utilizes police intelligence to identify the small percentage of people who commit disproportionately high levels of crime. These individuals are then brought together into call-in meetings. During a call-in, law enforcement informs offenders they will be prosecuted to the full extent of the law, often with judicial priority for any offense, if they do not stop violent activities. The speech is followed up by a community member asking for a stop to the violence. This method has grown over the past two decades, and it continues to lead the charge of smart policing policy.

      Type
      Judiciary, social

      District attorney
      Support needed to prioritize cases

      Police
      Identify worst offenders, gather evidence, follow up with threats and community policing

      Political
      Executive support to get community backing and budget appropriation for staff

      Community
      Local leaders attend call-ins, aid reconciliation and provide support for rehabilitated offenders

      Resources
      Time and space for call-ins, staff for custom notifications, dedicated director for support services

      Long-term
      Services provided for offenders trying to straighten out. Cessation of support programs leads to relapse.

      Test cities
      Boston, Cincinnati, Chicago, Indianapolis and High Point, North Carolina

      Efficacy
      Medium to highly significant results when followed. Efficacy depends on buy-in and implementation. Considered to be one of the most consistent police-based measures

## Cure Violence

Cure Violence started in Chicago. Dr. Gary Slutkin realized there were similarities between violence and contagious diseases. By treating violence as a public health issue, the strategy attempts to address those at risk and treat those affected through a network of volunteers, mediators and city officials. When violence is treated in this way, they argue, it creates a societal change among the affected area and reverses an epidemic of violent crime.

      Type
      Social, public health

      District attorney
      NA

      Police
      Provide team members' safety, help in organization, and alerting network of crime

      Political
      Provides publicity, support and budget appropriations

      Community
      Provides business support, staff members and information about potential conflicts

      Resources
      Extensive manpower for mediations and street team involvement

      Long-term
      Long-term support system. Shootings rose significantly in Chicago when program ceased

      Test cities
      Chicago, Baltimore and New York City

      Efficacy
      Apparent medium to high efficacy. 41–73% drop in shootings and killings in Chicago in implementation areas. 56% reduction in killings in Baltimore in implementation areas

## Disorder policing

Disorder policing (aka hot-spot policing) uses data to identify and commit more resources to high crime areas. These efforts are directed toward reducing open crimes like drug dealing and public intoxication, as well as improving parts of high-crime areas that may be neglected — like poor street lighting, run-down buildings and abandoned vehicles.

This method can also include more aggressive enforcement measures, including vehicle searches and stop-and-frisk. The category applies to a broad spectrum of measures, but it is universally understood that best practices are based on data-driven resource allocation, neighborhood revitalization and protection for those in the neighborhood. Stop-and-frisk and other overly aggressive tactics have a history of encouraging racial profiling and police violence and are not recommended.

      Type
      Executive

      District attorney
      Prosecution support

      Police
      Identify "hot spot" crime areas and add higher police presence. Crackdown on open crime and public nuisances. Report abandoned buildings and crime evidence

      Political
      Initiation and support. Creation and funding for smart policing programs. Create teams to clean up streets, renovate or demolish abandoned buildings

      Community
      Often alienated by constant police presence. High possibility of harassment. Responsible for calling in crimes and abandoned property. Potential positive effects of neighborhood focus

      Resources
      Involves smarter allocation of police. Data gathering tools and staff may require additional funding. Significant investment to clean up dilapidated areas

      Long-term
      Continued responsiveness to changes in high crime areas

      Test cities
      Hundreds of cities in U.S.

      Efficacy
      Modest effects. Problem-oriented approach more effective than zero-tolerance. Police harassment has the potential to alienate those who are supposed to be protected. Neighborhood clean-up efforts can be beneficial

## School-based programs

School-based programs attempt to address root causes of violence before it happens. While other strategies share similar goals, school-based programs encourage positive conflict resolution skills and students to stay in school. They teach that violence is not a problem-solving tool and the value of an education.

      Type
      Educational, psychological

      District attorney
      NA

      Police
      Limited involvement outside of classroom visits

      Political
      Executive and school system to fund school programs

      Community
      Counselors or teachers instruct in empathy training, impulse control and anger management. Guide children through positive conflict resolution. Parents involved in take home material

      Resources
      Cost of materials and training for teachers

      Long-term
      Continuing program to watch changes in community

      Test cities
      Present in many U.S. schools

      Efficacy
      Potential strong efficacy. Social competence improved, reduction in aggressive and violent behaviors. Chicago program produced 50% reduction in violent crime and 35% reduction in overall crime in participating group. Cognitive behavioral therapy also considered highly effective

## Prison programs

Prison-based programs attempt to reduce the likelihood of recidivism. While numbers vary widely between studies, 30 to 60 percent of prisoners will go back to jail. Earning a GED diploma or other high school equivalency are one common tactic. Some prisons partner with community colleges for secondary degrees or provide industrial certification and vocational classes. Some prisons also offer counseling and cognitive behavioral therapy.

      Type
      Educational

      District attorney
      NA

      Police
      NA

      Political
      Enacting educational prison programs, counseling and cognitive-behavioral therapy services

      Community
      Able to utilize educated labor force, sense of rebuilding and gaining rather than losing members to cyclical incarceration

      Resources
      Estimated cost of education is comparatively lower than costs incurred by recidivism

      Long-term
      NA

      Test cities
      Widespread implementation

      Efficacy
      Education has been proven to reduce recidivism. In a San Francisco trial, inmates who participated had 46.3% lower recidivism rates for violent crimes and spent 42.6 percent less time in custody. Cognitive behavioral therapy also considered highly effective

## Minimum sentencing laws

Mandatory minimum sentencing laws have existed in the U.S. since the 18th century. Today there is an extensive rubric of penalties for hundreds of crimes. The foundational philosophy behind minimum sentencing is deterrence theory, which assumes a consideration of potential benefits versus potential costs and the likelihood of being caught by every person who commits a crime.

Experts debate whether deterrence theory works, but it informs the thinking behind minimum sentencing. It assumes that the worse the punishment, the less likely a crime will be committed. While credited with an increase in the U.S. prison population, there has also been a large national decrease in crime since the 1980s.

      Type
      Legislative

      District attorney
      Not necessary, but prosecutors exercise substantial sway over sentencing

      Police
      Not necessary. Can be used as policing tool

      Political
      Legislature passes guidelines

      Community
      Long-term loss of community members. Worst offenders sometimes removed for long periods

      Resources
      Large monetary commitment to care for prisoners

      Long-term
      None. Lack of support for recently freed inmates causes high recidivism rates

      Test cities
      Nationwide

      Efficacy
      Although some crime rates have dropped since implementation, it's impossible to isolate effects. Widely believed to contribute to cycle of crime and breakdown of communities

## Civil gang injunctions

[Civil gang injunctions](/blog/a-survey-of-civil-gang-injunctions/) originated in California in the '80s. They are a legal tool to create a civil nuisance abatement against gangs in a prescribed area. They list gangs and gang members within a specific geographic area and prohibit them from associating with each other or committing crimes. While popular on the West Coast and in some parts of the South, they have mixed results due to the large differences in how gangs operate.

      Type
      Judicial

      District attorney
      Needed to draft injunction

      Police
      Must provide records, evidence, statistics, gang member information, proven activities and define safety zone

      Political
      Provides support for enactment

      Community
      Mostly negative community effects. Makes minor interactions with gang member a crime. Community has potential to pressure gangs into good behavior

      Resources
      Manpower for research

      Long-term
      Continued gathering of evidence and tracking of gang activity

      Test cities
      Implemented in many U.S. cities

      Efficacy
      Some studies indicate reduced crime and frequency of 911 calls and gang activity. Others show no change in crime. Major issues are crime relocation, changing gang culture and constitutionality. Regarded by some as 1st Amendment infringement


text:
<?php

defined('_JEXEC') or die;

/**
 * Installer Update Controller
 *
 * @since  1.6
 */
class InstallerControllerUpdate extends JControllerLegacy
{
	/**
	 * Update a set of extensions.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public function update()
	{
		// Check for request forgeries.
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		/** @var InstallerModelUpdate $model */
		$model = $this->getModel('update');
		$uid   = $this->input->get('cid', array(), 'array');

		JArrayHelper::toInteger($uid, array());

		// Get the minimum stability.
		$component     = JComponentHelper::getComponent('com_installer');
		$params        = $component->params;
		$minimum_stability = $params->get('minimum_stability', JUpdater::STABILITY_STABLE, 'int');

		$model->update($uid, $minimum_stability);

		if ($model->getState('result', false))
		{
			$cache = JFactory::getCache('mod_menu');
			$cache->clean();
		}

		$app          = JFactory::getApplication();
		$redirect_url = $app->getUserState('com_installer.redirect_url');

		// Don't redirect to an external URL.
		if (!JUri::isInternal($redirect_url))
		{
			$redirect_url = '';
		}

		if (empty($redirect_url))
		{
			$redirect_url = JRoute::_('index.php?option=com_installer&view=update', false);
		}
		else
		{
			// Wipe out the user state when we're going to redirect.
			$app->setUserState('com_installer.redirect_url', '');
			$app->setUserState('com_installer.message', '');
			$app->setUserState('com_installer.extension_message', '');
		}

		$this->setRedirect($redirect_url);
	}

	/**
	 * Find new updates.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public function find()
	{
		(JSession::checkToken() or JSession::checkToken('get')) or jexit(JText::_('JINVALID_TOKEN'));

		// Get the caching duration.
		$component     = JComponentHelper::getComponent('com_installer');
		$params        = $component->params;
		$cache_timeout = $params->get('cachetimeout', 6, 'int');
		$cache_timeout = 3600 * $cache_timeout;

		// Get the minimum stability.
		$minimum_stability = $params->get('minimum_stability', JUpdater::STABILITY_STABLE, 'int');

		// Find updates.
		/** @var InstallerModelUpdate $model */
		$model = $this->getModel('update');

		$disabledUpdateSites = $model->getDisabledUpdateSites();

		if ($disabledUpdateSites)
		{
			$updateSitesUrl = JRoute::_('index.php?option=com_installer&view=updatesites');
			$this->setMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATE_SITES_COUNT_CHECK', $updateSitesUrl), 'warning');
		}

		$model->findUpdates(0, $cache_timeout, $minimum_stability);
		$this->setRedirect(JRoute::_('index.php?option=com_installer&view=update', false));
	}

	/**
	 * Purges updates.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public function purge()
	{
		// Check for request forgeries.
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$model = $this->getModel('update');
		$model->purge();

		/**
		 * We no longer need to enable update sites in Joomla! 3.4 as we now allow the users to manage update sites
		 * themselves.
		 * $model->enableSites();
		 */

		$this->setRedirect(JRoute::_('index.php?option=com_installer&view=update', false), $model->_message);
	}

	/**
	 * Fetch and report updates in JSON format, for AJAX requests
	 *
	 * @return void
	 *
	 * @since 2.5
	 */
	public function ajax()
	{
		$app = JFactory::getApplication();

		if (!JSession::checkToken('get'))
		{
			$app->setHeader('status', 403, true);
			$app->sendHeaders();
			echo JText::_('JINVALID_TOKEN');
			$app->close();
		}

		$eid               = $this->input->getInt('eid', 0);
		$skip              = $this->input->get('skip', array(), 'array');
		$cache_timeout     = $this->input->getInt('cache_timeout', 0);
		$minimum_stability = $this->input->getInt('minimum_stability', -1);

		$component     = JComponentHelper::getComponent('com_installer');
		$params        = $component->params;

		if ($cache_timeout == 0)
		{
			$cache_timeout = $params->get('cachetimeout', 6, 'int');
			$cache_timeout = 3600 * $cache_timeout;
		}

		if ($minimum_stability < 0)
		{
			$minimum_stability = $params->get('minimum_stability', JUpdater::STABILITY_STABLE, 'int');
		}

		/** @var InstallerModelUpdate $model */
		$model = $this->getModel('update');
		$model->findUpdates($eid, $cache_timeout, $minimum_stability);

		$model->setState('list.start', 0);
		$model->setState('list.limit', 0);

		if ($eid != 0)
		{
			$model->setState('filter.extension_id', $eid);
		}

		$updates = $model->getItems();

		if (!empty($skip))
		{
			$unfiltered_updates = $updates;
			$updates            = array();

			foreach ($unfiltered_updates as $update)
			{
				if (!in_array($update->extension_id, $skip))
				{
					$updates[] = $update;
				}
			}
		}

		echo json_encode($updates);

		$app->close();
	}
}


text:
package com.dianping.cat.report.page.problem.transform;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.dianping.cat.Cat;
import com.dianping.cat.Constants;
import com.dianping.cat.consumer.GraphTrendUtil;
import com.dianping.cat.consumer.problem.model.entity.Entity;
import com.dianping.cat.consumer.problem.model.entity.GraphTrend;
import com.dianping.cat.consumer.problem.model.entity.Machine;
import com.dianping.cat.consumer.problem.model.entity.ProblemReport;
import com.dianping.cat.consumer.problem.model.transform.BaseVisitor;
import com.dianping.cat.helper.TimeHelper;
import com.dianping.cat.report.graph.LineChart;
import com.dianping.cat.report.page.problem.Model;
import com.dianping.cat.report.page.problem.Payload;

public class ProblemTrendGraphBuilder {
	private int m_duration = 1;

	private LineChart buildLineChart(Date start, Date end, long step, int size) {
		LineChart item = new LineChart();

		item.setStart(start);
		item.setSize(size);
		item.setStep(step);
		item.setSubTitles(buildSubTitles(start, end));
		return item;
	}

	private String buildSubTitle(Date start, Date end) {
		SimpleDateFormat from = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat to = new SimpleDateFormat("MM-dd");
		StringBuilder sb = new StringBuilder();

		sb.append(from.format(start)).append("~").append(to.format(end));
		return sb.toString();
	}

	private List<String> buildSubTitles(Date start, Date end) {
		List<String> subTitles = new ArrayList<String>();

		subTitles.add(buildSubTitle(start, end));
		return subTitles;
	}

	public void buildTrendGraph(Model model, Payload payload, ProblemReport report) {
		String name = payload.getStatus();
		Date start = payload.getHistoryStartDate();
		Date end = payload.getHistoryEndDate();
		String reportType = payload.getReportType();
		String ip = payload.getIpAddress();
		String type = payload.getType();

		double[] data = getDatas(report, ip, type, name);

		ReportType queryType = ReportType.findByName(reportType);
		long step = queryType.getStep() * m_duration;
		int size = (int) ((start.getTime() - end.getTime()) / step);

		LineChart fail = buildLineChart(start, end, step, size);

		fail.setTitle(queryType.getFailTitle());
		fail.addValue(data);

		model.setErrorsTrend(fail.getJsonString());
	}

	private double[] getDatas(ProblemReport report, String ip, String type, String status) {
		ProblemReportVisitor visitor = new ProblemReportVisitor(ip, type, status);
		visitor.visitProblemReport(report);

		return visitor.getDatas();
	}

	public enum ReportType {

		DAY("day", TimeHelper.ONE_MINUTE) {
			@Override
			String getFailTitle() {
				return "错误量 (count/min)";
			}
		},

		WEEK("week", TimeHelper.ONE_DAY) {
			@Override
			String getFailTitle() {
				return "错误量 (count/day)";
			}
		},

		MONTH("month", TimeHelper.ONE_DAY) {
			@Override
			String getFailTitle() {
				return "错误量 (count/day)";
			}

		};

		private String m_name;

		private long m_step;

		private ReportType(String name, long step) {
			m_name = name;
			m_step = step;
		}

		public static ReportType findByName(String name) {
			for (ReportType type : ReportType.values()) {
				if (type.getName().equalsIgnoreCase(name)) {
					return type;
				}
			}
			throw new RuntimeException("Error graph query type");
		}

		abstract String getFailTitle();

		public String getName() {
			return m_name;
		}

		public long getStep() {
			return m_step;
		}
	}

	public class ProblemReportVisitor extends BaseVisitor {

		double[] m_fails;

		private String m_ip;

		private String m_type;

		private String m_status;

		public ProblemReportVisitor(String ip, String type, String status) {
			m_ip = ip;
			m_type = type;
			m_status = status;
		}

		public double[] getDatas() {
			return m_fails;
		}

		private double[] parseToDouble(String str) {
			if (str != null && str.length() > 0) {
				String[] strs = str.split(GraphTrendUtil.GRAPH_SPLITTER);
				double[] result = new double[strs.length];

				for (int i = 0; i < strs.length; i++) {
					try {
						result[i] = Double.parseDouble(strs[i]);
					} catch (Exception e) {
						result[i] = 0.0;
						Cat.logError(e);
					}
				}
				return result;
			} else {
				return null;
			}
		}

		private void resolveGraphTrend(GraphTrend graph) {
			if (graph != null) {
				m_duration = graph.getDuration();
				double[] tmp = parseToDouble(graph.getFails());

				if (m_fails == null) {
					m_fails = new double[tmp.length];
				}

				for (int i = 0; i < m_fails.length; i++) {
					m_fails[i] += tmp[i];
				}
			}
		}

		@Override
		public void visitMachine(Machine machine) {
			if (Constants.ALL.equalsIgnoreCase(m_ip)) {
				super.visitMachine(machine);
			} else {
				if (machine.getIp().equalsIgnoreCase(m_ip)) {
					super.visitMachine(machine);
				}
			}
		}

		@Override
		public void visitEntity(Entity entity) {
			if (m_status == null || m_status.length() == 0) {
				if (entity.getType().equalsIgnoreCase(m_type)) {
					GraphTrend graphTrend = entity.getGraphTrend();
					resolveGraphTrend(graphTrend);
				}
			} else {
				if (entity.getType().equalsIgnoreCase(m_type) && entity.getStatus().equalsIgnoreCase(m_status)) {
					GraphTrend graphTrend = entity.getGraphTrend();
					resolveGraphTrend(graphTrend);
				}
			}
		}
	}
}


text:
[mypy](http://mypy-lang.org/) is a compile-time static type checker
for Python, allowing optional, gradual typing of Python code.  Zulip
is using mypy's Python 2 compatible syntax for type annotations, which
means that type annotations are written inside comments that start
with `# type: `.  Here's a brief example of the mypy syntax we're
using in Zulip:

```
user_dict = {} # type: Dict[str, UserProfile]

def get_user_profile_by_email(email):
    # type: (str) -> UserProfile
    ... # Actual code of the function here
```

You can learn more about it at:

* [The mypy cheat
  sheet](https://github.com/python/mypy/blob/master/docs/source/cheat_sheet.rst)
  is the best resource for quickly understanding how to write the PEP
  484 type annotations used by mypy correctly.

* The [Python 2 type annotation syntax spec in PEP
  484](https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code)

* [Using mypy with Python 2 code](http://mypy.readthedocs.io/en/latest/python2.html)

The mypy type checker is run automatically as part of Zulip's Travis
CI testing process in the 'static-analysis' build.

## `type_debug.py`

`zerver/lib/type_debug.py` has a useful decorator `print_types`.  It
prints the types of the parameters of the decorated function and the
return type whenever that function is called.  This can help find out
what parameter types a function is supposed to accept, or if
parameters with the wrong types are being passed to a function.

Here is an example using the interactive console:

```
>>> from zerver.lib.type_debug import print_types
>>>
>>> @print_types
... def func(x, y):
...     return x + y
...
>>> func(1.0, 2)
func(float, int) -> float
3.0
>>> func('a', 'b')
func(str, str) -> str
'ab'
>>> func((1, 2), (3,))
func((int, int), (int,)) -> (int, int, int)
(1, 2, 3)
>>> func([1, 2, 3], [4, 5, 6, 7])
func([int, ...], [int, ...]) -> [int, ...]
[1, 2, 3, 4, 5, 6, 7]
```

`print_all` prints the type of the first item of lists.  So `[int, ...]` represents
a list whose first element's type is `int`.  Types of all items are not printed
because a list can have many elements, which would make the output too large.

Similarly in dicts, one key's type and the corresponding value's type are printed.
So `{1: 'a', 2: 'b', 3: 'c'}` will be printed as `{int: str, ...}`.

## Zulip goals

Zulip is hoping to reach 100% of the codebase annotated with mypy
static types, and then enforce that it stays that way.  Our current
coverage is shown in
[Coveralls](https://coveralls.io/github/zulip/zulip).

## Installing mypy

If you installed Zulip's development environment correctly, mypy
should already be installed inside the Python 3 virtualenv at
`zulip-py3-venv` (mypy only supports Python 3).  If it isn't installed
(e.g. because you haven't reprovisioned recently), you can run
`tools/install-mypy` to install it.

## Running mypy on Zulip's code locally

To run mypy on Zulip's python code, run the command:

    tools/run-mypy

It will output errors in the same style as a compiler would.  For
example, if your code has a type error like this:

```
foo = 1
foo = '1'
```

you'll get an error like this:

```
test.py: note: In function "test":
test.py:200: error: Incompatible types in assignment (expression has type "str", variable has type "int")
```

If you need help interpreting or debugging mypy errors, please feel
free to mention @sharmaeklavya2 or @timabbott on your pull request (or
email zulip-devel@googlegroups.com) to get help; we'd love to both
build a great troubleshooting guide in this doc and also help
contribute improvements to error messages upstream.

Since mypy is a new tool under rapid development and occasionally
makes breaking changes, Zulip is using a pinned version of mypy from
its [git repository](https://github.com/python/mypy) rather than
tracking the (older) latest mypy release on PyPI.

## Excluded files

Since several Python files in Zulip's code don't pass mypy's checks
(even for unannotated code) right now, a list of files to be excluded
from the check for CI is present in `tools/run-mypy`.

To run mypy on all Python files, ignoring the exclude list, you can
pass the `--all` option to `tools/run-mypy`.

    tools/run-mypy --all

If you type annotate some of those files so that they pass without
errors, please remove them from the exclude list.

## Mypy is there to find bugs in Zulip before they impact users

For the purposes of Zulip development, you can treat `mypy` like a
much more powerful linter that can catch a wide range of bugs.  If,
after running `tools/run-mypy` on your Zulip branch, you get mypy
errors, it's important to get to the bottom of the issue, not just do
something quick to silence the warnings.  Possible explanations include:

* A bug in any new type annotations you added.
* A bug in the existing type annotations.
* A bug in Zulip!
* Some Zulip code is correct but confusingly reuses variables with
  different types.
* A bug in mypy (though this is increasingly rare as mypy is now
  fairly mature as a project).

Each explanation has its own solution, but in every case the result
should be solving the mypy warning in a way that makes the Zulip
codebase better.  If you need help understanding an issue, please feel
free to mention @sharmaeklavya2 or @timabbott on the relevant pull
request or issue on GitHub.

If you think you have found a bug in Zulip or mypy, inform the zulip
developers by opening an issue on [Zulip's GitHub
repository](https://github.com/zulip/zulip/issues) or posting on
[zulip-devel](https://groups.google.com/d/forum/zulip-devel).  If it's
indeed a mypy bug, we can help with reporting it upstream.

## Annotating strings

In Python 3, strings can have non-ASCII characters without any problems.
Such characters are required to support languages which use non-latin
scripts like Japanese and Hindi.  They are also needed to support special
characters like mathematical symbols, musical symbols, etc.
In Python 2, however, `str` generally doesn't work well with non-ASCII
characters.  That's why `unicode` was introduced in Python 2.

But there are problems with the `unicode` and `str` system.  Implicit
conversions between `str` and `unicode` use the `ascii` codec, which
fails on strings containing non-ASCII characters.  Such errors are hard
to detect by people who always write in English.  To minimize such
implicit conversions, we should have a strict separation between `str`
and `unicode` in Python 2.  It might seem that using `unicode` everywhere
will solve all problems, but unfortunately it doesn't.  This is because
some parts of the standard library and the Python language (like keyword
argument unpacking) insist that parameters passed to them are `str`.

To make our code work correctly in Python 2, we have to identify strings
which contain data which could come from non-ASCII sources like stream
names, people's names, domain names, content of messages, emails, etc.
These strings should be `unicode`.  We also have to identify strings
which should be `str` like Exception names, attribute names, parameter
names, etc.

Mypy can help with this.  We just have to annotate each string as either
`str` or `unicode` and mypy's static type checking will tell us if we
are incorrectly mixing the two.  However, `unicode` is not defined in
Python 3.  We want our code to be Python 3 compatible in the future.
This can be achieved using 'six', a Python 2 and 3 compatibility library.

`six.text_type` is defined as `str` in Python 3 and as `unicode` in
Python 2.  We'll be using `text_type` (instead of `unicode`) and `str`
to annotate strings in Zulip's code.  We follow the style of doing
`from six import text_type` and using `text_type` for annotation instead
of doing `import six` and using `six.text_type` for annotation, because
`text_type` is used so extensively for type annotations that we don't
need to be that verbose.

Sometimes you'll find that you have to convert strings from one type to
another.  `zerver/lib/str_utils.py` has utility functions to help with that.
It also has documentation (in docstrings) which explains the right way
to use them.


text:
/*global defineSuite*/
defineSuite([
        'Core/defined'
    ], function(
        defined) {
    'use strict';

    it('works for defined value', function() {
        expect(defined(0)).toEqual(true);
    });

    it('works for null value', function() {
        expect(defined(null)).toEqual(false);
    });

    it('works for undefined value', function() {
        expect(defined(undefined)).toEqual(false);
    });
});


text:
/***
  Routes controller, of sorts
  All routes logic and management goes here
***/

var _   = require('underscore'),
    redis = require('redis');

// return cache value if available
var get = function(cache, key, callback) {

  // no cache options
  if (!cache) {
    return callback(null, null);
  }

  var client = redis.createClient(cache.port, cache.host);

  console.log('getting', key);
  client.get(key, function(err, data) {
    return callback(err, JSON.parse(data));
  });

}

// set cache value
var set = function(cache, key, value) {

  // no cache options
  if (!cache) {
    return false;
  }

  var client = redis.createClient(cache.port, cache.host);
  console.log('setting', key, JSON.stringify(value));
  client.set(key, JSON.stringify(value), function(err, data) {});

}

// delete a value
var del = function(key) {

  // no cache options
  if (!cache) {
    return false;
  }

  var client = redis.createClient(cache.port, cache.host);
  console.log('deleting', key);
  client.del(key);

}

// parse the cache options
var parseOptsCache = function(c) {

  if (!c) return false;

  if (c !== true && !c.match(/redis/)) return false;

  if (c !== true && !_.isString(c)) return false;

  // default cache values
  var cache = {
    type: 'redis',
    host: 'localhost',
    port: 6379
  };

  // return defaults if true is passed in
  if (c === true) return cache;

  // get bits
  var bits = c.split("://");

  if (bits.length == 2) {

    // only support redis for now
    if (bits[0] != 'redis') return false;

    cache.type = bits[0];
    cache.host = bits[1].split(":")[0];
    cache.port = (_.isNumber(bits[1].split(":")[1])?bits[1].split(":")[1]:6379);

    return cache;

  }

  // not a valid value
  else {
    return false;
  }

}

module.exports = {
  get: get,
  set: set,
  del: del,
  parseOptsCache: parseOptsCache
}


text:
namespace cc {

class PixelTest::PixelTestRendererClient
    : public RendererClient, public OutputSurfaceClient {
 public:
  explicit PixelTestRendererClient(gfx::Rect device_viewport)
      : device_viewport_(device_viewport) {}

  // RendererClient implementation.
  virtual gfx::Rect DeviceViewport() const OVERRIDE {
    return device_viewport_;
  }
  virtual float DeviceScaleFactor() const OVERRIDE {
    return 1.f;
  }
  virtual const LayerTreeSettings& Settings() const OVERRIDE {
    return settings_;
  }
  virtual void SetFullRootLayerDamage() OVERRIDE {}
  virtual void SetManagedMemoryPolicy(
      const ManagedMemoryPolicy& policy) OVERRIDE {}
  virtual void EnforceManagedMemoryPolicy(
      const ManagedMemoryPolicy& policy) OVERRIDE {}
  virtual bool HasImplThread() const OVERRIDE { return false; }
  virtual bool ShouldClearRootRenderPass() const OVERRIDE { return true; }
  virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const
      OVERRIDE {
    return CompositorFrameMetadata();
  }
  virtual bool AllowPartialSwap() const OVERRIDE {
    return true;
  }
  virtual int TopBorder() const OVERRIDE { return 0; }

  // OutputSurfaceClient implementation.
  virtual bool DeferredInitialize(
      scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE {
    return false;
  }
  virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) OVERRIDE {}
  virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {}
  virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE {}
  virtual void DidLoseOutputSurface() OVERRIDE {}
  virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
                                          gfx::Rect viewport) OVERRIDE {
    device_viewport_ = viewport;
  }

 private:
  gfx::Rect device_viewport_;
  LayerTreeSettings settings_;
};

PixelTest::PixelTest()
    : device_viewport_size_(gfx::Size(200, 200)),
      fake_client_(
          new PixelTestRendererClient(gfx::Rect(device_viewport_size_))) {}

PixelTest::~PixelTest() {}

bool PixelTest::RunPixelTest(RenderPassList* pass_list,
                             const base::FilePath& ref_file,
                             const PixelComparator& comparator) {
  return RunPixelTestWithReadbackTarget(pass_list,
                                        pass_list->back(),
                                        ref_file,
                                        comparator);
}

bool PixelTest::RunPixelTestWithReadbackTarget(
    RenderPassList* pass_list,
    RenderPass* target,
    const base::FilePath& ref_file,
    const PixelComparator& comparator) {
  base::RunLoop run_loop;

  target->copy_requests.push_back(CopyOutputRequest::CreateBitmapRequest(
      base::Bind(&PixelTest::ReadbackResult,
                 base::Unretained(this),
                 run_loop.QuitClosure())));

  renderer_->DecideRenderPassAllocationsForFrame(*pass_list);
  renderer_->DrawFrame(pass_list);

  // Wait for the readback to complete.
  resource_provider_->Finish();
  run_loop.Run();

  return PixelsMatchReference(ref_file, comparator);
}

void PixelTest::ReadbackResult(base::Closure quit_run_loop,
                               scoped_ptr<CopyOutputResult> result) {
  ASSERT_TRUE(result->HasBitmap());
  result_bitmap_ = result->TakeBitmap().Pass();
  quit_run_loop.Run();
}

bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file,
                                     const PixelComparator& comparator) {
  base::FilePath test_data_dir;
  if (!PathService::Get(cc::DIR_TEST_DATA, &test_data_dir))
    return false;

  // If this is false, we didn't set up a readback on a render pass.
  if (!result_bitmap_)
    return false;

  // To rebaseline:
  // return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true);

  return MatchesPNGFile(*result_bitmap_,
                        test_data_dir.Append(ref_file),
                        comparator);
}

void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) {
  CHECK(fake_client_);
  CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL));

  using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
  scoped_ptr<WebKit::WebGraphicsContext3D> context3d(
      WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext(
          WebKit::WebGraphicsContext3D::Attributes()));
  output_surface_.reset(new PixelTestOutputSurface(
      context3d.PassAs<WebKit::WebGraphicsContext3D>()));
  output_surface_->BindToClient(fake_client_.get());

  resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
  renderer_ = GLRenderer::Create(fake_client_.get(),
                                 output_surface_.get(),
                                 resource_provider_.get(),
                                 0,
                                 use_skia_gpu_backend).PassAs<DirectRenderer>();

  scoped_refptr<webkit::gpu::ContextProviderInProcess> offscreen_contexts =
      webkit::gpu::ContextProviderInProcess::Create();
  ASSERT_TRUE(offscreen_contexts->BindToCurrentThread());
  resource_provider_->set_offscreen_context_provider(offscreen_contexts);
}

void PixelTest::ForceExpandedViewport(gfx::Size surface_expansion,
                                      gfx::Vector2d viewport_offset) {
  static_cast<PixelTestOutputSurface*>(output_surface_.get())
      ->set_surface_expansion_size(surface_expansion);
  static_cast<PixelTestOutputSurface*>(output_surface_.get())
      ->set_viewport_offset(viewport_offset);
  SoftwareOutputDevice* device = output_surface_->software_device();
  if (device) {
    static_cast<PixelTestSoftwareOutputDevice*>(device)
        ->set_surface_expansion_size(surface_expansion);
  }
}

void PixelTest::SetUpSoftwareRenderer() {
  CHECK(fake_client_);

  scoped_ptr<SoftwareOutputDevice> device(new PixelTestSoftwareOutputDevice());
  output_surface_.reset(new PixelTestOutputSurface(device.Pass()));
  output_surface_->BindToClient(fake_client_.get());
  resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
  renderer_ = SoftwareRenderer::Create(
      fake_client_.get(),
      output_surface_.get(),
      resource_provider_.get()).PassAs<DirectRenderer>();
}

}  // namespace cc


text:
<?php
use app\components\object_block\ObjectBlock;

print ObjectBlock::widget(['model' => $model]);


text:
#include "tensorflow/core/kernels/cwise_ops_common.h"

namespace tensorflow {
REGISTER2(UnaryOp, CPU, "Tan", functor::tan, float, double);
#if GOOGLE_CUDA
REGISTER2(UnaryOp, GPU, "Tan", functor::tan, float, double);
#endif
}  // namespace tensorflow


text:
* Make sure stylesheet is built.

```
npm run build
```

* On `master`, update `package.json` with new version number. Follow [semver](http://semver.org/).

```json
  "version": "63.12.0",
```

* Commit with message "Bump version".

```
git commit -m "Bump version"
```

* Add git tag.

```
git tag 63.12.0
```

* Push to GitHub.

```
git push
git push --tags
```

* Publish to npm.

```
npm publish --access=public
```


text:
from random import choice

from bencode import bencode, fmt_bdecode
from typevalidator import validate, OPTIONAL_KEY
from plugins import Plugin, get_plugin_by_type
from support import debug, die, warning
from proximateprotocol import PLUGIN_TYPE_FETCHER, PLUGIN_TYPE_TCP_FETCHER, \
     PLUGIN_TYPE_COMMUNITY, PLUGIN_TYPE_SCHEDULER, TP_FETCH_TIMEOUT, \
     PLUGIN_TYPE_UDP_FETCHER

RETIREMENT_CYCLE = 5
FETCH_TIMEOUT_STEPS = TP_FETCH_TIMEOUT // RETIREMENT_CYCLE

community = None
fetcher = None

pendingreqs = {}

class Request:
    def __init__(self, rid, payload, callback, ctx, retries):
        self.rid = rid
        self.payload = payload
        self.callback = callback
        self.ctx = ctx
        self.retries = retries
        # +1 because timeout cycle is out of sync with creating the request
        self.ttl = FETCH_TIMEOUT_STEPS + 1
        self.userreplies = {}

    def call(self, user, reply):
        if self.callback != None and self.userreplies.has_key(user) == False:
            self.callback(user, reply, self.ctx)
            self.userreplies[user] = None

        fetcher.get_pending(user, self.rid, pop=True)

    def check_timeout(self, user):
        self.ttl -= 1
        if self.ttl <= 0:
            self.call(user, None)
            return False
        return True

    def retry(self):
        failure = (self.retries > 0)
        self.retries -= 1
        return failure

class Special_Reply:
    pass

class Fetcher_Plugin(Plugin):
    POSTPONE_REPLY = Special_Reply()
    SILENT_COMMUNITY_ERROR = Special_Reply()

    decodespec = {'rid': int, OPTIONAL_KEY('v'): int, 't': str, 'rt': str, 'c': str}

    def __init__(self):
        self.register_plugin(PLUGIN_TYPE_FETCHER)
        self.handlers = {}
        self.handlername = {}
        self.rid = 0

    def close_ip_connections(self, msg):
        for queuelist in fetchqueues.values():
            for fq in queuelist:
                fq.close(msg)

    def decode(self, payload):
        d = fmt_bdecode(self.decodespec, payload)
        if d == None:
            warning('Invalid fetcher payload: %s\n' % payload)
        return d

    def encode(self, msg, rid, rt):
        if type(msg) != dict:
            warning('fetcher: message must be a dictionary: %s\n' %(str(msg)), printstack=True)
            return None
        msg.setdefault('v', 0)
        msg.setdefault('t', '')
        msg['rid'] = rid
        msg['rt'] = rt
        return bencode(msg)

    def fetch(self, user, rtype, request, callback, ctx=None, retries=0, ack=True):
        """ Tries to fetch data from an user.

            user: user to fetch from
            rtype: type of the request, an arbitrary string
            request: message (dictionary) to send to the counter side
            callback: function to be called after data is fetched.
                      gets the return value of the counterparty's
                      handling function and the context as parameters.
                      This parameter can be None.
            ctx: context of the request, an arbitrary object
            retries: number of retries
            ack: If True, reply is expected and a lost message is (possibly)
                 retransmitted according.
        """
        assert(retries >= 0)

        request.setdefault('c', '')

        rid = self.obtain_rid(ack)

        payload = self.encode(request, rid, rtype)
        if payload == None:
            return False

        self.log('fetcher.fetch', user, request, payload)

        req = Request(rid, payload, callback, ctx, retries)

        success = self.backend.send_request(user, req)

        # Add request to the pending queue, unless it is a no-ack request.
        # The request is removed from the queue when req.call() is called.
        if success and rid >= 0:
            self.set_pending([user], req)

        return success

    def fetch_community(self, com, rtype, request, callback, ctx=None, retries=0, ack=True):
        """ Send fetch to every user in given community.

            Because users in communities can appear and disappear at
            any time, we take snapshot of currently active users.
        """

        request['c'] = com.get('name')
        return self.backend.fetch_community(com, rtype, request, callback, ctx=ctx, retries=retries, ack=ack)

    def is_fetch_community_efficient(self):
        return self.backend.efficient_fetch_community

    def log(self, name, user, request, payload):
        d = {'rid': request['rid'],
             'rt': request['rt'],
             't': request.get('t', ''),
             'nfields': len(request),
             'nbytes': len(payload),
            }
        c = request.get('c')
        if c != None:
            d['c'] = c
        if user != None:
            d['uid'] = user.get('uid')

    def fetch_queue_retirement(self, t, ctx):
        for (user, ureqs) in pendingreqs.items():
            for req in ureqs.values():
                req.check_timeout(user)
            if len(ureqs) == 0:
                # Cleanup unused queues to avoid re-scanning in the future
                pendingreqs.pop(user)
        return True

    def obtain_rid(self, ack):
        if ack:
            rid = self.rid
            self.rid += 1
        else:
            rid = -1 # No reply for the request
        return rid

    def ready(self):
        global community, fetcher
        fetcher = self
        community = get_plugin_by_type(PLUGIN_TYPE_COMMUNITY)

        for p in [PLUGIN_TYPE_UDP_FETCHER, PLUGIN_TYPE_TCP_FETCHER]:
            self.backend = get_plugin_by_type(p)
            if self.backend != None and self.backend.functional():
                break

        sch = get_plugin_by_type(PLUGIN_TYPE_SCHEDULER)
        sch.call_periodic(RETIREMENT_CYCLE * sch.SECOND, self.fetch_queue_retirement)

    def register_handler(self, rtype, handler, handlername):
        """ Register a slave handler that replies to the master.
            Handler will be called with the ip address and the payload
            of the message from master when a message with the
            corresponding rtype is received.
            Handlername is used for debugging purposes. """

        if self.handlers.has_key(rtype):
            die('Fetch handler for rtype %s already registered\n' %(rtype))
        self.handlers[rtype] = handler
        self.handlername[rtype] = handlername

    def handle_msg(self, user, msg):
        if len(msg['rt']) == 0:
            # Act as a master
            self.handle_reply(user, msg)
        else:
            # Act as a slave
            self.call_slave_handler(user, msg)

    def call_slave_handler(self, user, request):
        """ Fetch slave: handle incoming fetch request, call slavehandler """

        reply = None
        slavehandler = self.handlers.get(request['rt'])
        cname = request.get('c')
        if len(cname) > 0 and cname not in community.get_myself().get('communities'):
            return
        if slavehandler != None:
            reply = slavehandler(user, request)
        if request['rid'] < 0:
            return
        if reply == self.POSTPONE_REPLY:
            return
        if reply == self.SILENT_COMMUNITY_ERROR and len(cname) > 0:
            return
        if reply == None:
            warning('fetch slave returned None for %s:%s\n' % (request['rt'], request['t']))
        self.send_reply(user, request['rid'], reply)

    def handle_reply(self, user, reply):
        req = self.get_pending(user, reply['rid'])
        if req == None:
            warning('fetch master: invalid rid (%d) from %s\n' % (reply['rid'], user.tag()))
            return

        d = {'rid': reply['rid'],
             'nfields': len(reply),
             'nbytes': len(bencode(reply)),
             'rs': reply.get('rs', 'x'),
             'uid': user.get('uid'),
            }

        if reply.has_key('rs'):
            reply = None
        req.call(user, reply)

    def send_reply(self, user, rid, reply):
        """ Send reply to a fetch request. Can be a postponed reply.

            user: user to send the reply to
            rid: the request ID this reply belongs to
            reply: reply message to send to the master

            Reply value of None means an error occured.
        """

        if reply == None:
            reply = {'rs': ''}
        reply['c'] = ''
        payload = self.encode(reply, rid, '')
        if payload == None:
            return

        self.backend.send_reply(user, rid, payload)

    def get_pending(self, user, rid, pop=False):
        ureqs = pendingreqs.get(user)
        if ureqs != None:
            if pop:
                req = ureqs.pop(rid, None)
            else:
                req = ureqs.get(rid)
        else:
            req = None
        return req

    def set_pending(self, users, req):
        for user in users:
            ureqs = pendingreqs.setdefault(user, {})
            ureqs[req.rid] = req

def init(options):
    Fetcher_Plugin()


text:
module Forwardable
  # Version of +forwardable.rb+
  FORWARDABLE_VERSION = "1.1.0"

  FILE_REGEXP = %r"#{Regexp.quote(__FILE__)}"

  @debug = nil
  class << self
    # If true, <tt>__FILE__</tt> will remain in the backtrace in the event an
    # Exception is raised.
    attr_accessor :debug
  end

  # Takes a hash as its argument.  The key is a symbol or an array of
  # symbols.  These symbols correspond to method names.  The value is
  # the accessor to which the methods will be delegated.
  #
  # :call-seq:
  #    delegate method => accessor
  #    delegate [method, method, ...] => accessor
  #
  def instance_delegate(hash)
    hash.each{ |methods, accessor|
      methods = [methods] unless methods.respond_to?(:each)
      methods.each{ |method|
        def_instance_delegator(accessor, method)
      }
    }
  end

  #
  # Shortcut for defining multiple delegator methods, but with no
  # provision for using a different name.  The following two code
  # samples have the same effect:
  #
  #   def_delegators :@records, :size, :<<, :map
  #
  #   def_delegator :@records, :size
  #   def_delegator :@records, :<<
  #   def_delegator :@records, :map
  #
  def def_instance_delegators(accessor, *methods)
    methods.delete("__send__")
    methods.delete("__id__")
    for method in methods
      def_instance_delegator(accessor, method)
    end
  end

  # Define +method+ as delegator instance method with an optional
  # alias name +ali+. Method calls to +ali+ will be delegated to
  # +accessor.method+.
  #
  #   class MyQueue
  #     extend Forwardable
  #     attr_reader :queue
  #     def initialize
  #       @queue = []
  #     end
  #
  #     def_delegator :@queue, :push, :mypush
  #   end
  #
  #   q = MyQueue.new
  #   q.mypush 42
  #   q.queue    #=> [42]
  #   q.push 23  #=> NoMethodError
  #
  def def_instance_delegator(accessor, method, ali = method)
    line_no = __LINE__; str = %{
      def #{ali}(*args, &block)
        begin
          #{accessor}.__send__(:#{method}, *args, &block)
        rescue ::Exception
          $@.delete_if{|s| ::Forwardable::FILE_REGEXP =~ s} unless ::Forwardable::debug
          ::Kernel::raise
        end
      end
    }
    # If it's not a class or module, it's an instance
    begin
      module_eval(str, __FILE__, line_no)
    rescue
      instance_eval(str, __FILE__, line_no)
    end

  end

  alias delegate instance_delegate
  alias def_delegators def_instance_delegators
  alias def_delegator def_instance_delegator
end

# SingleForwardable can be used to setup delegation at the object level as well.
#
#    printer = String.new
#    printer.extend SingleForwardable        # prepare object for delegation
#    printer.def_delegator "STDOUT", "puts"  # add delegation for STDOUT.puts()
#    printer.puts "Howdy!"
#
# Also, SingleForwardable can be used to set up delegation for a Class or Module.
#
#   class Implementation
#     def self.service
#       puts "serviced!"
#     end
#   end
#
#   module Facade
#     extend SingleForwardable
#     def_delegator :Implementation, :service
#   end
#
#   Facade.service #=> serviced!
#
# If you want to use both Forwardable and SingleForwardable, you can
# use methods def_instance_delegator and def_single_delegator, etc.
module SingleForwardable
  # Takes a hash as its argument.  The key is a symbol or an array of
  # symbols.  These symbols correspond to method names.  The value is
  # the accessor to which the methods will be delegated.
  #
  # :call-seq:
  #    delegate method => accessor
  #    delegate [method, method, ...] => accessor
  #
  def single_delegate(hash)
    hash.each{ |methods, accessor|
      methods = [methods] unless methods.respond_to?(:each)
      methods.each{ |method|
        def_single_delegator(accessor, method)
      }
    }
  end

  #
  # Shortcut for defining multiple delegator methods, but with no
  # provision for using a different name.  The following two code
  # samples have the same effect:
  #
  #   def_delegators :@records, :size, :<<, :map
  #
  #   def_delegator :@records, :size
  #   def_delegator :@records, :<<
  #   def_delegator :@records, :map
  #
  def def_single_delegators(accessor, *methods)
    methods.delete("__send__")
    methods.delete("__id__")
    for method in methods
      def_single_delegator(accessor, method)
    end
  end

  # :call-seq:
  #   def_single_delegator(accessor, method, new_name=method)
  #
  # Defines a method _method_ which delegates to _accessor_ (i.e. it calls
  # the method of the same name in _accessor_).  If _new_name_ is
  # provided, it is used as the name for the delegate method.
  def def_single_delegator(accessor, method, ali = method)
    str = %{
      def #{ali}(*args, &block)
        begin
          #{accessor}.__send__(:#{method}, *args, &block)
        rescue ::Exception
          $@.delete_if{|s| ::Forwardable::FILE_REGEXP =~ s} unless ::Forwardable::debug
          ::Kernel::raise
        end
      end
    }

    instance_eval(str, __FILE__, __LINE__)
  end

  alias delegate single_delegate
  alias def_delegators def_single_delegators
  alias def_delegator def_single_delegator
end


text:
satgals
=======

code related to looking for satellite galaxies