diff --git a/babel.cfg b/babel.cfg new file mode 100644 index 00000000..d8f381e8 --- /dev/null +++ b/babel.cfg @@ -0,0 +1,5 @@ +[python: **.py] +[jinja2: **/templates/**.html] +[jinja2: **/templates/**.jinja2] +extensions=jinja2.ext.autoescape,jinja2.ext.with_ +silent=false diff --git a/ci/conda_requirements.txt b/ci/conda_requirements.txt index f3531a40..2dc7b04b 100644 --- a/ci/conda_requirements.txt +++ b/ci/conda_requirements.txt @@ -5,3 +5,4 @@ pycryptodome redis-py redis pytest +flask-babel diff --git a/messages.pot b/messages.pot new file mode 100644 index 00000000..19a1625d --- /dev/null +++ b/messages.pot @@ -0,0 +1,999 @@ +# Translations template for PROJECT. +# Copyright (C) 2021 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2021. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2021-05-11 13:19-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.9.1\n" + +#: microsetta_interface/implementation.py:379 +msgid "Unable to validate the kit name; please reload the page." +msgstr "" + +#: microsetta_interface/implementation.py:398 +msgid "" +"The provided kit id is not valid or has already been used; please re-" +"check your entry." +msgstr "" + +#: microsetta_interface/implementation.py:1014 +msgid "Blood (skin prick)" +msgstr "" + +#: microsetta_interface/implementation.py:1015 +msgid "Saliva" +msgstr "" + +#: microsetta_interface/implementation.py:1016 +msgid "Stool" +msgstr "" + +#: microsetta_interface/implementation.py:1017 +msgid "Mouth" +msgstr "" + +#: microsetta_interface/implementation.py:1018 +msgid "Nares" +msgstr "" + +#: microsetta_interface/implementation.py:1019 +msgid "Nasal mucus" +msgstr "" + +#: microsetta_interface/implementation.py:1020 +msgid "Right hand" +msgstr "" + +#: microsetta_interface/implementation.py:1021 +msgid "Left hand" +msgstr "" + +#: microsetta_interface/implementation.py:1022 +msgid "Forehead" +msgstr "" + +#: microsetta_interface/implementation.py:1023 +msgid "Torso" +msgstr "" + +#: microsetta_interface/implementation.py:1024 +msgid "Right leg" +msgstr "" + +#: microsetta_interface/implementation.py:1025 +msgid "Left leg" +msgstr "" + +#: microsetta_interface/implementation.py:1026 +msgid "Vaginal mucus" +msgstr "" + +#: microsetta_interface/implementation.py:1027 +msgid "Tears" +msgstr "" + +#: microsetta_interface/implementation.py:1028 +msgid "Ear wax" +msgstr "" + +#: microsetta_interface/implementation.py:1029 +msgid "Hair" +msgstr "" + +#: microsetta_interface/implementation.py:1030 +msgid "Fur" +msgstr "" + +#: microsetta_interface/implementation.py:1257 +msgid "Unable to validate Activation Code at this time" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:2 +#: microsetta_interface/templates/account_overview.jinja2:47 +msgid "Account Details" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:91 +msgid "City" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:92 +msgid "State" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:93 +msgid "Zip Code" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:114 +msgid "Profile" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:116 +#: microsetta_interface/templates/account_details.jinja2:120 +#: microsetta_interface/templates/sitebase.jinja2:76 +#: microsetta_interface/templates/sitebase.jinja2:78 +msgid "Profile Details" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:124 +#: microsetta_interface/templates/admin_activation_codes.jinja2:6 +#: microsetta_interface/templates/admin_activation_codes.jinja2:16 +#: microsetta_interface/templates/admin_activation_codes.jinja2:27 +#: microsetta_interface/templates/admin_home.jinja2:11 +#: microsetta_interface/templates/sitebase.jinja2:124 +msgid "Email" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:129 +msgid "First Name" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:133 +msgid "Last Name" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:138 +msgid "Note to non-US/GB users" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:138 +msgid "" +"We are working on support for additional countries and expect to have " +"that available soon." +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:141 +msgid "United States" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:142 +msgid "United Kingdom" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:146 +msgid "Street Address" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:168 +msgid "Activation Info" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:172 +msgid "Kit ID" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:175 +msgid "OR" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:177 +#: microsetta_interface/templates/admin_activation_codes.jinja2:11 +msgid "Activation Code" +msgstr "" + +#: microsetta_interface/templates/account_details.jinja2:184 +#: microsetta_interface/templates/account_details.jinja2:186 +msgid "Save Profile" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:2 +#: microsetta_interface/templates/account_overview.jinja2:44 +#: microsetta_interface/templates/sample.jinja2:112 +#: microsetta_interface/templates/sample_results.jinja2:107 +#: microsetta_interface/templates/source.jinja2:140 +msgid "Account" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:53 +msgid "View Account Details" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:58 +msgid "Sources" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:62 +msgid "" +"You have now set up your profile for your account! Please proceed to " +"identify your source." +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:66 +msgid "" +"Choose a source to assign samples to by clicking on a name, listed in " +"blue below:" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:71 +msgid "Name" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:74 +msgid "Source type" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:95 +msgid "What is the Source of Your Sample?" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:103 +msgid "" +"Our lab needs to know what type of sample(s) you are submitting (a.k.a. " +"the “source”). Add a new source and assign samples to it so we can " +"perform the correct analysis in our laboratory." +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:108 +msgid "" +"If you have multiple sources, you may add one source at a time. You can " +"return to this page after you finish registering the first one." +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:114 +msgid "Human Source" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:116 +#: microsetta_interface/templates/account_overview.jinja2:118 +#: microsetta_interface/templates/account_overview.jinja2:139 +msgid "Collect sample(s) from" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:116 +msgid "yourself" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:116 +#: microsetta_interface/templates/account_overview.jinja2:118 +#: microsetta_interface/templates/account_overview.jinja2:139 +msgid "(e.g. fecal, saliva, skin, etc.)" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:118 +msgid "someone else" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:121 +#: microsetta_interface/templates/account_overview.jinja2:131 +#: microsetta_interface/templates/account_overview.jinja2:144 +msgid "Select" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:126 +msgid "Environmental Source" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:128 +msgid "Collect sample(s) from a" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:128 +msgid "surface" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:128 +msgid "(e.g. kitchen counter, backyard soil, food, etc.)" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:136 +msgid "Animal Source" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:139 +msgid "your pet" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:139 +msgid "or an" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:139 +msgid "animal" +msgstr "" + +#: microsetta_interface/templates/account_overview.jinja2:141 +msgid "Animal sources are currently unavailable." +msgstr "" + +#: microsetta_interface/templates/admin_activation_codes.jinja2:2 +msgid "Admin Activation Codes" +msgstr "" + +#: microsetta_interface/templates/admin_activation_codes.jinja2:13 +msgid "Search" +msgstr "" + +#: microsetta_interface/templates/admin_activation_codes.jinja2:18 +msgid "Generate" +msgstr "" + +#: microsetta_interface/templates/admin_activation_codes.jinja2:19 +msgid "Generate + Send Email" +msgstr "" + +#: microsetta_interface/templates/admin_activation_codes.jinja2:21 +#: microsetta_interface/templates/admin_home.jinja2:5 +msgid "Search Results" +msgstr "" + +#: microsetta_interface/templates/admin_activation_codes.jinja2:30 +msgid "Code" +msgstr "" + +#: microsetta_interface/templates/admin_activation_codes.jinja2:33 +msgid "Activated" +msgstr "" + +#: microsetta_interface/templates/admin_activation_codes.jinja2:54 +#: microsetta_interface/templates/admin_home.jinja2:34 +msgid "No accounts found" +msgstr "" + +#: microsetta_interface/templates/admin_home.jinja2:2 +msgid "ADMINISTRATOR MODE" +msgstr "" + +#: microsetta_interface/templates/admin_home.jinja2:14 +msgid "Account ID" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:2 +msgid "ADMINISTRATOR SYSTEM PANEL" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:14 +#: microsetta_interface/templates/admin_system_panel.jinja2:36 +msgid "Set System Message" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:21 +msgid "System Message" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:25 +msgid "primary" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:26 +msgid "secondary" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:27 +msgid "success" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:28 +msgid "danger" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:29 +msgid "warning" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:30 +msgid "info" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:31 +msgid "light" +msgstr "" + +#: microsetta_interface/templates/admin_system_panel.jinja2:32 +msgid "dark" +msgstr "" + +#: microsetta_interface/templates/create_nonhuman_source.jinja2:2 +msgid "Create Non-human Source" +msgstr "" + +#: microsetta_interface/templates/create_nonhuman_source.jinja2:8 +msgid "Creating Source..." +msgstr "" + +#: microsetta_interface/templates/create_nonhuman_source.jinja2:20 +msgid "Environment description (optional)" +msgstr "" + +#: microsetta_interface/templates/create_nonhuman_source.jinja2:23 +msgid "Create Source" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:2 +msgid "Awaiting Email Confirmation" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:20 +msgid "Check your email inbox" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:21 +msgid "" +"To complete your verification, click on the link in the email AuthRocket " +"has sent to" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:25 +msgid "Waiting for you to confirm" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:28 +msgid "Please check both your spam and inbox" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:29 +msgid "AuthRocket is our authentication service" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:30 +msgid "Email wrong or didn't receive an email?" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:30 +msgid "Go to your AuthRocket Profile" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:30 +msgid "to update your email or resend a verification email" +msgstr "" + +#: microsetta_interface/templates/email_confirmation.jinja2:33 +msgid "You can close this browser tab!" +msgstr "" + +#: microsetta_interface/templates/embedded_pdf.jinja2:24 +msgid "" +"This report is generated by a third party without information regarding " +"age, height or weight." +msgstr "" + +#: microsetta_interface/templates/emperor.jinja2:2 +#: microsetta_interface/templates/emperor.jinja2:65 +#: microsetta_interface/templates/sitebase.jinja2:45 +msgid "Emperor Playground" +msgstr "" + +#: microsetta_interface/templates/emperor.jinja2:68 +msgid "PCOA URL" +msgstr "" + +#: microsetta_interface/templates/emperor.jinja2:73 +msgid "Go!" +msgstr "" + +#: microsetta_interface/templates/error.jinja2:2 +msgid "Error Page" +msgstr "" + +#: microsetta_interface/templates/error.jinja2:10 +msgid "" +"An error seemed to have occurred (see below). It is most likely our " +"fault. We are actively modifying our infrastructure to support COVID-19 " +"research, and we're still in the process of handling the different type " +"of scenarios that can happen on a website. We apologize for any " +"inconvenience." +msgstr "" + +#: microsetta_interface/templates/error.jinja2:13 +msgid "If you have any concerns, please email us at" +msgstr "" + +#: microsetta_interface/templates/error.jinja2:13 +msgid "and please note the error below" +msgstr "" + +#: microsetta_interface/templates/error.jinja2:15 +msgid "Error" +msgstr "" + +#: microsetta_interface/templates/home.jinja2:2 +#: microsetta_interface/templates/sitebase.jinja2:101 +msgid "Home" +msgstr "" + +#: microsetta_interface/templates/home.jinja2:22 +#: microsetta_interface/templates/home.jinja2:29 +#: microsetta_interface/templates/home.jinja2:30 +#: microsetta_interface/templates/home.jinja2:31 +msgid "en_us" +msgstr "" + +#: microsetta_interface/templates/home.jinja2:34 +msgid "Welcome!" +msgstr "" + +#: microsetta_interface/templates/home.jinja2:38 +msgid "SIGN UP" +msgstr "" + +#: microsetta_interface/templates/home.jinja2:42 +msgid "Already have an account?" +msgstr "" + +#: microsetta_interface/templates/home.jinja2:43 +msgid "Welcome back!" +msgstr "" + +#: microsetta_interface/templates/home.jinja2:43 +msgid "LOG IN" +msgstr "" + +#: microsetta_interface/templates/new_participant.jinja2:2 +#: microsetta_interface/templates/new_participant.jinja2:129 +msgid "Consent" +msgstr "" + +#: microsetta_interface/templates/new_participant.jinja2:107 +#: microsetta_interface/templates/new_participant.jinja2:108 +#: microsetta_interface/templates/new_participant.jinja2:109 +#: microsetta_interface/templates/new_participant.jinja2:110 +msgid "Saving..." +msgstr "" + +#: microsetta_interface/templates/new_participant.jinja2:164 +#: microsetta_interface/templates/new_participant.jinja2:204 +#: microsetta_interface/templates/new_participant.jinja2:238 +#: microsetta_interface/templates/new_participant.jinja2:259 +msgid "I Accept" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:2 +msgid "Optional Sample Surveys" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:9 +msgid "Your diet can provide researchers valuable information" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:12 +msgid "Would you like to take our additional survey, the" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:12 +#: microsetta_interface/templates/source.jinja2:194 +msgid "Food Frequency Questionnaire" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:12 +msgid "FFQ" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:12 +msgid "" +"By completing the questionnaire, you can enhance information about your " +"sample, which will power more insightful research!" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:13 +msgid "Note" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:13 +msgid "" +"If you took multiple samples within a short time frame, you only need to " +"take the FFQ for one such sample" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:16 +msgid "Approx time: 30 minutes" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:20 +msgid "Take FFQ" +msgstr "" + +#: microsetta_interface/templates/post_sample_questionnaire.jinja2:23 +msgid "Back to Samples" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:2 +#: microsetta_interface/templates/sample.jinja2:114 +msgid "Sample Information" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:42 +msgid "Required Format: MM/DD/YYYY" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:113 +#: microsetta_interface/templates/sample_results.jinja2:108 +msgid "Source" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:122 +msgid "Sample Recorded, Editing is Locked" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:126 +#: microsetta_interface/templates/source.jinja2:155 +msgid "Barcode" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:133 +msgid "Date" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:141 +msgid "Time" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:155 +msgid "Guidelines for site identification" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:156 +msgid "If collecting a" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:156 +msgid "BLOOD" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:156 +msgid "sample, please select Blood (skin prick)" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:157 +msgid "" +"For all swabs, please select the site as precisely as possible from the " +"options available" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:163 +msgid "Site sampled" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:167 +msgid "Select a sample type" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:183 +msgid "Notes" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:185 +msgid "(Optional) Is there else about this sample that you would like to add?" +msgstr "" + +#: microsetta_interface/templates/sample.jinja2:188 +msgid "Update" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:2 +msgid "Sample Results" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:109 +#: microsetta_interface/templates/source.jinja2:165 +msgid "Results" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:120 +msgid "What is in your sample?" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:122 +msgid "" +"The table below shows the relative abundances of all of the organisms we " +"observed in your sample. To produce this, we took the DNA sequences from " +"your sample, and compared them against publicly available annotated " +"reference databases. In some cases, a sequence may uniquely match a " +"database record, in other cases a sequence may match may different " +"records. To handle the uncertainty that can arise, we rely on a well used" +" and publicly available microbiome software package called QIIME 2. The exact " +"approach taken is highlighted in the main tutorial on feature-classification" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:127 +msgid "Relative Abundance" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:128 +msgid "Kingdom" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:129 +msgid "Phylum" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:130 +msgid "Class" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:131 +msgid "Order" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:132 +msgid "Family" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:133 +msgid "Genus" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:141 +msgid "Alpha Diversity" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:143 +msgid "" +"Here, we're providing a measure of the diversity of your sample, and how " +"it compares to the diversities of all of the same type of samples in The " +"Microsetta Initiative. There are many ways to calculate diversity. For " +"instance, you could compute a diversity value by counting the number of " +"unique organisms observed (i.e., the sample \"richness\"). Or, you might " +"be interested in weighting the calculation by the relative abundance of " +"the organisms (i.e., the sample \"evenness\"). The metric we're computing" +" here is called Faith's Phylogenetic Diversity (originally defined here). Faith's Phylogenetic Diversity computes the" +" \"richness\" of your sample as the amount of evolutionary breadth " +"represented by your sample. The way we compute alpha diversity is also " +"through QIIME 2, and" +" more information on it can be found in the alpha and beta diversity sections of the QIIME" +" 2 tutorial" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:148 +msgid "Beta Diversity" +msgstr "" + +#: microsetta_interface/templates/sample_results.jinja2:150 +msgid "" +"Here we display how your sample fits in among the other samples of The " +"Microsetta Initiative in terms of shared microbes. There are many ways to" +" calculate beta diversity, differing in how to weight the distance " +"between any two microbes. We take evolutionary distance into account with" +" the metric displayed here, known as Unweighted Unifrac. You can find an " +"overview of this metric here or better understand its derivation here. This computation is performed with QIIME 2, and more " +"information on it can be found in the alpha and beta diversity sections of the QIIME" +" 2 tutorial" +msgstr "" + +#: microsetta_interface/templates/sitebase.jinja2:5 +msgid "Microsetta" +msgstr "" + +#: microsetta_interface/templates/sitebase.jinja2:43 +msgid "Administrator Toolbar" +msgstr "" + +#: microsetta_interface/templates/sitebase.jinja2:44 +msgid "System Panel" +msgstr "" + +#: microsetta_interface/templates/sitebase.jinja2:46 +#: microsetta_interface/templates/sitebase.jinja2:80 +msgid "Log Out" +msgstr "" + +#: microsetta_interface/templates/sitebase.jinja2:47 +msgid "Activation Codes" +msgstr "" + +#: microsetta_interface/templates/sitebase.jinja2:50 +msgid "Find Account" +msgstr "" + +#: microsetta_interface/templates/sitebase.jinja2:82 +msgid "Log In" +msgstr "" + +#: microsetta_interface/templates/sitebase.jinja2:83 +msgid "Sign Up" +msgstr "" + +#: microsetta_interface/templates/sitebase.jinja2:122 +msgid "FAQs" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:2 +msgid "Account Samples" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:84 +msgid "Do you really want to remove this sample from this source?" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:85 +msgid "Doing so will remove any collection info saved for this sample and will" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:86 +msgid "unlink it from all surveys." +msgstr "" + +#: microsetta_interface/templates/source.jinja2:91 +msgid "You are deleting source" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:91 +msgid "and all surveys associated with it!" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:92 +msgid "" +"This operation cannot be undone. Are you sure you want to delete this " +"source?" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:100 +msgid "View" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:146 +msgid "It looks like some samples do not have collection information recorded." +msgstr "" + +#: microsetta_interface/templates/source.jinja2:150 +msgid "Samples (click on a barcode to provide collection information)" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:158 +msgid "Collection date" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:162 +msgid "Sample type" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:168 +msgid "Sample-specific survey" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:192 +msgid "View Top Food Report" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:198 +msgid "This sample has been received and cannot be removed." +msgstr "" + +#: microsetta_interface/templates/source.jinja2:200 +msgid "Remove" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:210 +msgid "Do I need to take more than one Food Frequency Questionnaire (FFQ)" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:211 +msgid "" +"If you are taking all of your samples at the same time, you will only " +"need to complete one. If you are collecting samples over time (e.g., once" +" per week), then please consider taking an FFQ per time point. The FFQs " +"provide valuable dietary research data for the project, so researchers " +"can better understand the relationship between the food you eat and your " +"microbes." +msgstr "" + +#: microsetta_interface/templates/source.jinja2:219 +msgid "" +"The kit ID used to create your account has unclaimed samples. To claim " +"samples from this kit, please click \"List samples\". To claim samples " +"from another kit ID, please enter it here and then click \"List Samples\"" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:222 +msgid "To add samples, please enter a kit ID here" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:226 +msgid "List Samples" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:231 +msgid "Select all samples that should be associated with this source" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:237 +msgid "Claim Selected Samples" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:244 +msgid "Surveys taken" +msgstr "" + +#: microsetta_interface/templates/source.jinja2:270 +msgid "" +"Sources with one or more samples assigned cannot be deleted. All samples" +" above must be removed prior to deleting this source." +msgstr "" + +#: microsetta_interface/templates/source.jinja2:272 +msgid "Delete Source" +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:2 +#: microsetta_interface/templates/survey.jinja2:114 +msgid "Participant Survey" +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:117 +msgid "Progress" +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:124 +msgid "Previous Section" +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:125 +msgid "Next Section" +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:144 +msgid "Submit Survey" +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:150 +msgid "" +"Please note: Once you've submitted this survey, you'll be unable to edit " +"your answers." +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:150 +msgid "" +"If you'd like to review or change any of your responses, please press the" +" Cancel button. Otherwise, press OK to submit your responses." +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:150 +msgid "This warning will only appear once." +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:172 +#: microsetta_interface/templates/survey.jinja2:192 +msgid "Step" +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:172 +#: microsetta_interface/templates/survey.jinja2:192 +msgid "of" +msgstr "" + +#: microsetta_interface/templates/survey.jinja2:172 +#: microsetta_interface/templates/survey.jinja2:192 +msgid "Complete" +msgstr "" + +#: microsetta_interface/templates/update_email.jinja2:2 +msgid "Email Update" +msgstr "" + +#: microsetta_interface/templates/update_email.jinja2:12 +msgid "" +"It appears that the email we have for your account is not the same as the" +" email you logged in with. Would you like us to update your email in our" +" records?" +msgstr "" + +#: microsetta_interface/templates/update_email.jinja2:18 +msgid "No, skip and continue" +msgstr "" + +#: microsetta_interface/templates/update_email.jinja2:21 +msgid "Yes, update and continue" +msgstr "" diff --git a/microsetta_interface/implementation.py b/microsetta_interface/implementation.py index 39585d44..9eb1971c 100644 --- a/microsetta_interface/implementation.py +++ b/microsetta_interface/implementation.py @@ -1,5 +1,8 @@ + import flask -from flask import render_template, session, redirect, make_response +import flask_babel +from flask_babel import gettext +from flask import render_template, session, redirect, make_response, request import jwt import requests from requests.auth import AuthBase @@ -8,6 +11,9 @@ from datetime import datetime import base64 import functools +from microsetta_interface.model_i18n import translate_source, \ + translate_sample, translate_survey_template, EN_US_KEY, LANGUAGES, \ + ES_MX_KEY # Authrocket uses RS256 public keys, so you can validate anywhere and safely # store the key in code. Obviously using this mechanism, we'd have to push code @@ -37,6 +43,7 @@ class Source: TOKEN_KEY_NAME = 'token' ADMIN_MODE_KEY = 'admin_mode' LOGIN_INFO_KEY = 'login_info' +LANG_KEY = "language" HOME_URL = "/home" HELP_EMAIL = "microsetta@ucsd.edu" @@ -56,6 +63,7 @@ class Source: ACCT_ADDR_STATE_KEY = "state" ACCT_ADDR_POST_CODE_KEY = "post_code" ACCT_ADDR_COUNTRY_CODE_KEY = "country_code" +ACCT_LANG_KEY = "language" # States NEEDS_REROUTE = "NeedsReroute" @@ -72,6 +80,14 @@ class Source: # in some way, as well as any special handling for external surveys. VIOSCREEN_ID = 10001 + +SYSTEM_MSG_DICTIONARY = { + "going_down": { + EN_US_KEY: "The system is going down at ", + ES_MX_KEY: "El sistema se apaga a las " + } + } + client_state = RedisCache() @@ -82,9 +98,21 @@ def _render_with_defaults(template_name, **context): defaults["login_info"] = session.get(LOGIN_INFO_KEY, None) defaults["admin_mode"] = admin_mode - msg, style = client_state.get(RedisCache.SYSTEM_BANNER, (None, None)) + msg, style, hours, minutes = client_state.get(RedisCache.SYSTEM_BANNER, + (None, None, None, None)) + + today = datetime.today() + if hours is None: + sys_msg_dt = datetime(today.year, today.month, today.day) + else: + sys_msg_dt = datetime(today.year, today.month, today.day, int(hours), + int(minutes)) + defaults["system_msg_text"] = msg defaults["system_msg_style"] = style + defaults["system_msg_time"] = flask_babel.format_datetime(sys_msg_dt, + 'h:mm a') + defaults["system_msg_dictionary"] = SYSTEM_MSG_DICTIONARY endpoint = SERVER_CONFIG["endpoint"] public_endpoint = SERVER_CONFIG["public_api_endpoint"] @@ -93,6 +121,9 @@ def _render_with_defaults(template_name, **context): defaults["authrocket_url"] = authrocket_url defaults["public_endpoint"] = public_endpoint + defaults["EN_US_KEY"] = EN_US_KEY + defaults["languages"] = LANGUAGES + defaults.update(context) return render_template(template_name, **defaults) @@ -373,8 +404,9 @@ def _refresh_state_and_route_to_sink(account_id=None, source_id=None): def _get_kit(kit_name): - unable_to_validate_msg = "Unable to validate the kit name; please " \ - "reload the page." + unable_to_validate_msg = gettext( + "Unable to validate the kit name; please " + "reload the page.") error_msg = None response = None @@ -390,8 +422,11 @@ def _get_kit(kit_name): params=ApiRequest.build_params({KIT_NAME_KEY: kit_name})) if response.status_code == 404: - error_msg = ("The provided kit id is not valid or has " - "already been used; please re-check your entry.") + error_msg = \ + gettext( + "The provided kit id is not valid or has " + "already been used; please re-check your entry." + ) elif response.status_code > 200: error_msg = unable_to_validate_msg except: # noqa @@ -433,12 +468,6 @@ def get_show_error_page(error_msg): return output -# FAQ display does not require any prereqs, so this method doesn't check any -def get_show_faq(): - output = _render_with_defaults('faq.jinja2') - return output - - def get_home(): email_verified = False accts_output = None @@ -503,6 +532,7 @@ def get_authrocket_callback(token, redirect_uri=None): "account_id": primary['account_id'], "email": primary['email'] } + session[LANG_KEY] = primary["language"] else: session[ADMIN_MODE_KEY] = False session[LOGIN_INFO_KEY] = { @@ -525,6 +555,9 @@ def get_logout(): @prerequisite([NEEDS_ACCOUNT]) def get_create_account(): email, _ = _parse_jwt(session[TOKEN_KEY_NAME]) + + browser_lang = request.accept_languages.best_match( + [LANGUAGES[lang].value for lang in LANGUAGES], default=LANGUAGES[EN_US_KEY].value) # TODO: Need to support other countries # and not default to US and California default_account_values = { @@ -537,7 +570,8 @@ def get_create_account(): ACCT_ADDR_STATE_KEY: 'CA', ACCT_ADDR_POST_CODE_KEY: '', ACCT_ADDR_COUNTRY_CODE_KEY: 'US' - } + }, + ACCT_LANG_KEY: browser_lang } return _render_with_defaults('account_details.jinja2', @@ -561,6 +595,7 @@ def post_create_account(*, body=None): ACCT_ADDR_POST_CODE_KEY: body['post_code'], ACCT_ADDR_COUNTRY_CODE_KEY: body['country_code'] }, + ACCT_LANG_KEY: body[LANG_KEY], KIT_NAME_KEY: kit_name, ACTIVATION_CODE_KEY: body["code"] } @@ -575,6 +610,7 @@ def post_create_account(*, body=None): "account_id": new_acct_id, "email": accts_output["email"] } + session[LANG_KEY] = accts_output['language'] return _refresh_state_and_route_to_sink(new_acct_id) @@ -624,6 +660,12 @@ def get_account(*, account_id=None): if has_error: return sources + # Update their language preferences cookie whenever they load this page. + # So if changed from another browser/tab/computer, + # going home will reset language + session[LANG_KEY] = account["language"] + + sources = [translate_source(s) for s in sources] return _render_with_defaults('account_overview.jinja2', account=account, sources=sources) @@ -652,7 +694,8 @@ def post_account_details(*, account_id=None, body=None): ACCT_ADDR_STATE_KEY: body['state'], ACCT_ADDR_POST_CODE_KEY: body['post_code'], ACCT_ADDR_COUNTRY_CODE_KEY: body['country_code'] - } + }, + ACCT_LANG_KEY: body['language'] } do_return, acct_output, _ = ApiRequest.put('/accounts/%s' % @@ -664,6 +707,7 @@ def post_account_details(*, account_id=None, body=None): "account_id": acct_output["account_id"], "email": acct_output["email"] } + session[LANG_KEY] = acct_output["language"] return _refresh_state_and_route_to_sink(account_id) @@ -929,12 +973,20 @@ def get_source(*, account_id=None, source_id=None): needs_assignment = True else: dt = datetime.fromisoformat(sample['sample_datetime']) - sample['sample_datetime'] = dt.strftime("%b-%d-%Y %-I:%M %p") + # rebase=True - show in user's locale, rebase=False, UTC (I think?) + sample['sample_datetime'] = flask_babel.format_datetime( + dt, + format=None, # Use babel default (short/medium/long/full) + rebase=False) needs_assignment = any([sample['sample_datetime'] is None for sample in samples_output]) is_human = source_output['source_type'] == Source.SOURCE_TYPE_HUMAN + + samples_output = [translate_sample(s) for s in samples_output] + per_source = [translate_survey_template(s) for s in per_source] + return _render_with_defaults('source.jinja2', account_id=account_id, source_id=source_id, @@ -995,15 +1047,39 @@ def get_update_sample(*, account_id=None, source_id=None, sample_id=None): "Nares", "Nasal mucus", "Right hand", "Left hand", "Forehead", "Torso", "Right leg", "Left leg", "Vaginal mucus", "Tears", "Ear wax", "Hair", "Fur"] + # babel scraping doesn't understand anything but constant strings. + # do not collapse this into a for loop unless you can verify + # that the POT file is correctly updated. + sample_site_translations = [ + gettext("Blood (skin prick)"), + gettext("Saliva"), + gettext("Stool"), + gettext("Mouth"), + gettext("Nares"), + gettext("Nasal mucus"), + gettext("Right hand"), + gettext("Left hand"), + gettext("Forehead"), + gettext("Torso"), + gettext("Right leg"), + gettext("Left leg"), + gettext("Vaginal mucus"), + gettext("Tears"), + gettext("Ear wax"), + gettext("Hair"), + gettext("Fur") + ] elif is_environmental: # Environment settings sample_sites = [None] + sample_site_translations = [None] else: raise BadRequest("Sources of type %s are not supported at this time" % source_output['source_type']) if sample_output['sample_datetime'] is not None: dt = datetime.fromisoformat(sample_output['sample_datetime']) + # TODO: This might need some flask_babel calls, hmm... sample_output['date'] = dt.strftime("%m/%d/%Y") sample_output['time'] = dt.strftime("%-I:%M %p") else: @@ -1016,6 +1092,7 @@ def get_update_sample(*, account_id=None, source_id=None, sample_id=None): source_name=source_output['source_name'], sample=sample_output, sample_sites=sample_sites, + sample_sites_text=sample_site_translations, is_environmental=is_environmental) @@ -1026,7 +1103,7 @@ def post_update_sample(*, account_id=None, source_id=None, sample_id=None): for x in flask.request.form: model[x] = flask.request.form[x] - date = model.pop('sample_date') + date = model.pop('sample_date_normalized') time = model.pop('sample_time') date_and_time = date + " " + time sample_datetime = datetime.strptime(date_and_time, "%m/%d/%Y %I:%M %p") @@ -1124,17 +1201,18 @@ def get_sample_results_experimental(): 'sample_remove_locked': False, 'sample_site': 'Stool', 'source_id': 'NA'} - return _render_with_defaults('new_results_page.jinja2', - account_id='NA', - source_id='NA', - sample=sample_output, - source_name='NA', - taxonomy=SERVER_CONFIG["taxonomy_resource"], - alpha_metric=SERVER_CONFIG["alpha_metric"], - beta_metric=SERVER_CONFIG["beta_metric"], - barcode_prefix=SERVER_CONFIG["barcode_prefix"], - show_breadcrumbs=False - ) + return _render_with_defaults( + 'new_results_page.jinja2', + account_id='NA', + source_id='NA', + sample=sample_output, + source_name='NA', + taxonomy=SERVER_CONFIG["taxonomy_resource"], + alpha_metric=SERVER_CONFIG["alpha_metric"], + beta_metric=SERVER_CONFIG["beta_metric"], + barcode_prefix=SERVER_CONFIG["barcode_prefix"], + show_breadcrumbs=False + ) @prerequisite([SOURCE_PREREQS_MET]) @@ -1220,7 +1298,7 @@ def get_ajax_check_activation_code(code, email): params=ApiRequest.build_params({"email": email, "code": code})) if response.status_code != 200: # Damn, couldn't properly communicate to backend server... - return "Unable to validate Activation Code at this time" + return gettext("Unable to validate Activation Code at this time") result_data = response.json() result = True if result_data["can_activate"] else result_data["error"] return flask.jsonify(result) @@ -1363,21 +1441,42 @@ def get_system_message(): def post_system_message(body): + # TODO: Localizing system messages means + # a dropdown instead of free text. if not session.get(ADMIN_MODE_KEY, False): raise Unauthorized() text = body.get("system_msg_text") style = body.get("system_msg_style") + hours = body.get("system_msg_hours") + minutes = body.get("system_msg_minutes") if text is None or len(text) == 0: text = None style = None + hours = None + minutes = None - client_state[RedisCache.SYSTEM_BANNER] = (text, style) + client_state[RedisCache.SYSTEM_BANNER] = (text, style, hours, minutes) return _render_with_defaults('admin_system_panel.jinja2') +def session_locale(): + # Based on snippet from https://flask-babel.tkte.ch/ + if LANG_KEY in session: + return session[LANG_KEY] + + # Awful. Can't resolve languages when inside unit tests, + # so have to pick a default + if not flask.has_request_context(): + return LANGUAGES[EN_US_KEY].value + + # TODO: We update this as we add support for new languages + return request.accept_languages.best_match( + [LANGUAGES[lang].value for lang in LANGUAGES]) + + class BearerAuth(AuthBase): def __init__(self, token): self.token = token @@ -1389,14 +1488,12 @@ def __call__(self, r): class ApiRequest: API_URL = SERVER_CONFIG["private_api_endpoint"] - DEFAULT_PARAMS = {'language_tag': 'en-US'} CAfile = SERVER_CONFIG["CAfile"] @classmethod def build_params(cls, params): all_params = {} - for key in ApiRequest.DEFAULT_PARAMS: - all_params[key] = ApiRequest.DEFAULT_PARAMS[key] + all_params["language_tag"] = session_locale() if params: for key in params: all_params[key] = params[key] diff --git a/microsetta_interface/model_i18n.py b/microsetta_interface/model_i18n.py new file mode 100644 index 00000000..210b5847 --- /dev/null +++ b/microsetta_interface/model_i18n.py @@ -0,0 +1,89 @@ +from collections import namedtuple + +from flask_babel import gettext +import copy + + +EN_US_KEY = "en_us" +ES_MX_KEY = "es_mx" + +Lang = namedtuple('Lang', ['value', 'display_text']) +LANGUAGES = { + EN_US_KEY: Lang("en_US", "English"), + ES_MX_KEY: Lang("es_MX", "Español") +} + + +def translate_sample(sample): + i18n_sample = copy.deepcopy(sample) + i18n_sample["sample_site"] = gettext(sample["sample_site"]) + if i18n_sample["sample_site"] is None: + i18n_sample["sample_site"] = "" + if i18n_sample["sample_datetime"] is None: + i18n_sample["sample_datetime"] = "" + return i18n_sample + + +def translate_source(source): + i18n_source = copy.deepcopy(source) + i18n_source["source_type"] = gettext(source["source_type"]) + return i18n_source + + +def translate_survey_template(survey_template): + i18n_survey_template = copy.deepcopy(survey_template) + i18n_survey_template["survey_template_title"] = \ + gettext(survey_template["survey_template_title"]) + return i18n_survey_template + + +def declare_enum_values(): + # There are a few enum fields in the private api + # model object types that need to be translated + # We define those enum values here so that babel + # picks them up for translation. + + # Sample.sample_site + # sample_site: + # enum: ["Blood (skin prick)", "Saliva", "Ear wax", "Forehead", + # "Fur", "Hair", "Left hand", "Left leg", "Mouth", "Nares", + # "Nasal mucus", "Right hand", "Right leg", "Stool", "Tears", + # "Torso", "Vaginal mucus", null] + gettext("Blood (skin prick)") + gettext("Saliva") + gettext("Ear wax") + gettext("Forehead") + gettext("Fur") + gettext("Hair") + gettext("Left hand") + gettext("Left leg") + gettext("Mouth") + gettext("Nares") + gettext("Nasal mucus") + gettext("Right hand") + gettext("Right leg") + gettext("Stool") + gettext("Tears") + gettext("Torso") + gettext("Vaginal mucus") + + # Source.source_site: + # source_type: + # enum: [human, animal, environmental] + gettext("human") + gettext("animal") + gettext("environmental") + + # SurveyTemplate.survey_template_title: + # Not defined in the microsetta-private-api yaml at the moment + # Taken from survey_template_repo.py + gettext("Primary Questionnaire") + gettext("Pet Information") + gettext("Fermented Foods Questionnaire") + gettext("Surfer Questionnaire") + gettext("Personal Microbiome Information") + gettext("COVID-19 Questionnaire") + gettext("Vioscreen Food Frequency Questionnaire") + + # Ensure that EN_US_KEY is added to the POT file + gettext("en_us") diff --git a/microsetta_interface/redis_cache.py b/microsetta_interface/redis_cache.py index 3b1966bc..f315889a 100644 --- a/microsetta_interface/redis_cache.py +++ b/microsetta_interface/redis_cache.py @@ -3,7 +3,7 @@ class RedisCache: - # System Banner Format: ["Blah blah blah", "primary"] + # System Banner Format: ["Blah blah blah", "primary", "hours", "minutes"] SYSTEM_BANNER = "system_banner" def __init__(self): diff --git a/microsetta_interface/routes.yaml b/microsetta_interface/routes.yaml index cc879047..6afec18e 100644 --- a/microsetta_interface/routes.yaml +++ b/microsetta_interface/routes.yaml @@ -31,19 +31,6 @@ paths: schema: type: string - '/view_faq': - get: - operationId: microsetta_interface.implementation.get_show_faq - tags: - - General - responses: - '200': - description: Display of FAQ page - content: - text/html: - schema: - type: string - '/error': get: operationId: microsetta_interface.implementation.get_show_error_page diff --git a/microsetta_interface/server.py b/microsetta_interface/server.py index b2bde869..06a5e621 100644 --- a/microsetta_interface/server.py +++ b/microsetta_interface/server.py @@ -3,10 +3,13 @@ import logging from microsetta_interface.config_manager import SERVER_CONFIG -from flask import jsonify +from flask import jsonify, g from werkzeug.utils import redirect import connexion +from flask_babel import Babel + +from microsetta_interface.implementation import session_locale # https://stackoverflow.com/a/37842465 @@ -51,11 +54,28 @@ def build_app(): app.app.logger.handlers = gunicorn_logger.handlers app.app.logger.setLevel(gunicorn_logger.level) + app.app.config['BABEL_DEFAULT_TIMEZONE'] = 'UTC' + app.app.config['BABEL_TRANSLATION_DIRECTORIES'] = './translations' + @app.route('/americangut/static/') def reroute_americangut(filename): # This is dumb as rocks, but it fixes static images referenced in # surveys without a schema change. return redirect('/static/' + filename) + + global babel + babel = Babel(app.app) + + @babel.localeselector + def get_locale(): + return session_locale() + + @babel.timezoneselector + def get_timezone(): + user = getattr(g, 'user', None) + if user is not None: + return user.timezone + return app @@ -74,6 +94,7 @@ def run(app): ) +babel = None app = build_app() diff --git a/microsetta_interface/static/img/bristol_stool.jpg b/microsetta_interface/static/img/bristol_stool.jpg deleted file mode 100644 index ce3e149f..00000000 Binary files a/microsetta_interface/static/img/bristol_stool.jpg and /dev/null differ diff --git a/microsetta_interface/static/img/choose_sample_example.png b/microsetta_interface/static/img/choose_sample_example.png deleted file mode 100644 index 22a6d4fc..00000000 Binary files a/microsetta_interface/static/img/choose_sample_example.png and /dev/null differ diff --git a/microsetta_interface/static/img/choose_source_example.png b/microsetta_interface/static/img/choose_source_example.png deleted file mode 100644 index 15324fcf..00000000 Binary files a/microsetta_interface/static/img/choose_source_example.png and /dev/null differ diff --git a/microsetta_interface/static/img/create_account_example.png b/microsetta_interface/static/img/create_account_example.png deleted file mode 100644 index 834e6ccb..00000000 Binary files a/microsetta_interface/static/img/create_account_example.png and /dev/null differ diff --git a/microsetta_interface/static/img/en_us/bristol_stool.jpg b/microsetta_interface/static/img/en_us/bristol_stool.jpg new file mode 100644 index 00000000..5764ffa9 Binary files /dev/null and b/microsetta_interface/static/img/en_us/bristol_stool.jpg differ diff --git a/microsetta_interface/static/img/hero-home-4-xl.jpeg b/microsetta_interface/static/img/en_us/hero-home-4-xl.jpeg similarity index 100% rename from microsetta_interface/static/img/hero-home-4-xl.jpeg rename to microsetta_interface/static/img/en_us/hero-home-4-xl.jpeg diff --git a/microsetta_interface/static/img/en_us/how-it-works.png b/microsetta_interface/static/img/en_us/how-it-works.png new file mode 100644 index 00000000..c14fa7d9 Binary files /dev/null and b/microsetta_interface/static/img/en_us/how-it-works.png differ diff --git a/microsetta_interface/static/img/how-it-works.svg b/microsetta_interface/static/img/en_us/how-it-works.svg similarity index 100% rename from microsetta_interface/static/img/how-it-works.svg rename to microsetta_interface/static/img/en_us/how-it-works.svg diff --git a/microsetta_interface/static/img/the-microsetta-initiative-logo-rgb-1.png b/microsetta_interface/static/img/en_us/the-microsetta-initiative-logo-rgb-1.png similarity index 100% rename from microsetta_interface/static/img/the-microsetta-initiative-logo-rgb-1.png rename to microsetta_interface/static/img/en_us/the-microsetta-initiative-logo-rgb-1.png diff --git a/microsetta_interface/static/img/the-microsetta-initiative-logo-rgb-1@2x.png b/microsetta_interface/static/img/en_us/the-microsetta-initiative-logo-rgb-1@2x.png similarity index 100% rename from microsetta_interface/static/img/the-microsetta-initiative-logo-rgb-1@2x.png rename to microsetta_interface/static/img/en_us/the-microsetta-initiative-logo-rgb-1@2x.png diff --git a/microsetta_interface/static/img/the-microsetta-initiative-logo-rgb-1@3x.png b/microsetta_interface/static/img/en_us/the-microsetta-initiative-logo-rgb-1@3x.png similarity index 100% rename from microsetta_interface/static/img/the-microsetta-initiative-logo-rgb-1@3x.png rename to microsetta_interface/static/img/en_us/the-microsetta-initiative-logo-rgb-1@3x.png diff --git a/microsetta_interface/static/img/es_mx/bristol_stool.jpg b/microsetta_interface/static/img/es_mx/bristol_stool.jpg new file mode 100644 index 00000000..181d07c4 Binary files /dev/null and b/microsetta_interface/static/img/es_mx/bristol_stool.jpg differ diff --git a/microsetta_interface/static/img/es_mx/hero-home-4-xl.jpeg b/microsetta_interface/static/img/es_mx/hero-home-4-xl.jpeg new file mode 100644 index 00000000..97d4e764 Binary files /dev/null and b/microsetta_interface/static/img/es_mx/hero-home-4-xl.jpeg differ diff --git a/microsetta_interface/static/img/es_mx/how-it-works.png b/microsetta_interface/static/img/es_mx/how-it-works.png new file mode 100644 index 00000000..f646105f Binary files /dev/null and b/microsetta_interface/static/img/es_mx/how-it-works.png differ diff --git a/microsetta_interface/static/img/es_mx/how-it-works.svg b/microsetta_interface/static/img/es_mx/how-it-works.svg new file mode 100644 index 00000000..511195d0 --- /dev/null +++ b/microsetta_interface/static/img/es_mx/how-it-works.svg @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/microsetta_interface/static/img/es_mx/the-microsetta-initiative-logo-rgb-1.png b/microsetta_interface/static/img/es_mx/the-microsetta-initiative-logo-rgb-1.png new file mode 100644 index 00000000..82863b18 Binary files /dev/null and b/microsetta_interface/static/img/es_mx/the-microsetta-initiative-logo-rgb-1.png differ diff --git a/microsetta_interface/static/img/es_mx/the-microsetta-initiative-logo-rgb-1@2x.png b/microsetta_interface/static/img/es_mx/the-microsetta-initiative-logo-rgb-1@2x.png new file mode 100644 index 00000000..5f0e50d9 Binary files /dev/null and b/microsetta_interface/static/img/es_mx/the-microsetta-initiative-logo-rgb-1@2x.png differ diff --git a/microsetta_interface/static/img/es_mx/the-microsetta-initiative-logo-rgb-1@3x.png b/microsetta_interface/static/img/es_mx/the-microsetta-initiative-logo-rgb-1@3x.png new file mode 100644 index 00000000..a20350f2 Binary files /dev/null and b/microsetta_interface/static/img/es_mx/the-microsetta-initiative-logo-rgb-1@3x.png differ diff --git a/microsetta_interface/static/img/old_registration_no_password.jpg b/microsetta_interface/static/img/old_registration_no_password.jpg deleted file mode 100644 index 8344323d..00000000 Binary files a/microsetta_interface/static/img/old_registration_no_password.jpg and /dev/null differ diff --git a/microsetta_interface/static/img/old_registration_password.jpg b/microsetta_interface/static/img/old_registration_password.jpg deleted file mode 100644 index 2c2daa32..00000000 Binary files a/microsetta_interface/static/img/old_registration_password.jpg and /dev/null differ diff --git a/microsetta_interface/static/img/signup_example.png b/microsetta_interface/static/img/signup_example.png deleted file mode 100644 index d0b61519..00000000 Binary files a/microsetta_interface/static/img/signup_example.png and /dev/null differ diff --git a/microsetta_interface/static/vendor/DataTables/en_us.json b/microsetta_interface/static/vendor/DataTables/en_us.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/microsetta_interface/static/vendor/DataTables/en_us.json @@ -0,0 +1 @@ +{} diff --git a/microsetta_interface/static/vendor/DataTables/es_mx.json b/microsetta_interface/static/vendor/DataTables/es_mx.json new file mode 100644 index 00000000..14273b0b --- /dev/null +++ b/microsetta_interface/static/vendor/DataTables/es_mx.json @@ -0,0 +1,137 @@ +{ + "aria": { + "sortAscending": "Activar para ordenar la columna de manera ascendente", + "sortDescending": "Activar para ordenar la columna de manera descendente" + }, + "autoFill": { + "cancel": "Cancelar", + "fill": "Rellene todas las celdas con %d<\\\/i><\/i>", + "fillHorizontal": "Rellenar celdas horizontalmente", + "fillVertical": "Rellenar celdas verticalmentemente" + }, + "buttons": { + "collection": "Colección", + "colvis": "Visibilidad", + "colvisRestore": "Restaurar visibilidad", + "copy": "Copiar", + "copyKeys": "Presione ctrl o u2318 + C para copiar los datos de la tabla al portapapeles del sistema.

Para cancelar, haga clic en este mensaje o presione escape.", + "copySuccess": { + "1": "Copiada 1 fila al portapapeles", + "_": "Copiadas %d fila al portapapeles" + }, + "copyTitle": "Copiar al portapapeles", + "csv": "CSV", + "excel": "Excel", + "pageLength": { + "-1": "Mostrar todas las filas", + "1": "Mostrar 1 fila", + "_": "Mostrar %d filas" + }, + "pdf": "PDF", + "print": "Imprimir" + }, + "emptyTable": "No se encontraron resultados", + "info": "Mostrando registros del _START_ al _END_ de un total de _TOTAL_ registros", + "infoEmpty": "Mostrando registros del 0 al 0 de un total de 0 registros", + "infoFiltered": "(filtrado de un total de _MAX_ registros)", + "infoThousands": ",", + "lengthMenu": "Mostrar _MENU_ registros", + "loadingRecords": "Cargando...", + "paginate": { + "first": "Primero", + "last": "Último", + "next": "Siguiente", + "previous": "Anterior" + }, + "processing": "Procesando...", + "search": "Buscar:", + "searchBuilder": { + "add": "Añadir condición", + "button": { + "0": "Constructor de búsqueda", + "_": "Constructor de búsqueda (%d)" + }, + "clearAll": "Borrar todo", + "condition": "Condición", + "data": "Data", + "deleteTitle": "Eliminar regla de filtrado", + "leftTitle": "Criterios anulados", + "logicAnd": "Y", + "logicOr": "O", + "rightTitle": "Criterios de sangría", + "title": { + "0": "Constructor de búsqueda", + "_": "Constructor de búsqueda (%d)" + }, + "value": "Valor" + }, + "searchPanes": { + "clearMessage": "Borrar todo", + "collapse": { + "0": "Paneles de búsqueda", + "_": "Paneles de búsqueda (%d)" + }, + "count": "{total}", + "countFiltered": "{shown} ({total}", + "emptyPanes": "Sin paneles de búsqueda", + "loadMessage": "Cargando paneles de búsqueda", + "title": "Filtros Activos - %d" + }, + "select": { + "1": "%d fila seleccionada", + "_": "%d filas seleccionadas", + "cells": { + "1": "1 celda seleccionada", + "_": "$d celdas seleccionadas" + }, + "columns": { + "1": "1 columna seleccionada", + "_": "%d columnas seleccionadas" + } + }, + "thousands": ",", + "zeroRecords": "No se encontraron resultados", + "datetime": { + "previous": "Anterior", + "next": "Proximo", + "hours": "Horas", + "minutes": "Minutos", + "seconds": "Segundos", + "unknown": "-", + "amPm": [ + "am", + "pm" + ] + }, + "editor": { + "close": "Cerrar", + "create": { + "button": "Nuevo", + "title": "Crear Nuevo Registro", + "submit": "Crear" + }, + "edit": { + "button": "Editar", + "title": "Editar Registro", + "submit": "Actualizar" + }, + "remove": { + "button": "Eliminar", + "title": "Eliminar Registro", + "submit": "Eliminar", + "confirm": { + "_": "¿Está seguro que desea eliminar %d filas?", + "1": "¿Está seguro que desea eliminar 1 fila?" + } + }, + "error": { + "system": "Ha ocurrido un error en el sistema (Más información<\\\\\\\/a>).<\\\/a><\/a>" + }, + "multi": { + "title": "Múltiples Valores", + "info": "Los elementos seleccionados contienen diferentes valores para este registro. Para editar y establecer todos los elementos de este registro con el mismo valor, hacer click o tap aquí, de lo contrario conservarán sus valores individuales.", + "restore": "Deshacer Cambios", + "noMulti": "Este registro puede ser editado individualmente, pero no como parte de un grupo." + } + } +} diff --git a/microsetta_interface/static/vendor/jquery-ui-i18n/README.txt b/microsetta_interface/static/vendor/jquery-ui-i18n/README.txt new file mode 100644 index 00000000..3d67beee --- /dev/null +++ b/microsetta_interface/static/vendor/jquery-ui-i18n/README.txt @@ -0,0 +1,3 @@ +Grab datepicker translation files from +https://github.com/jquery/jquery-ui/tree/main/ui/i18n + diff --git a/microsetta_interface/static/vendor/jquery-ui-i18n/datepicker-es.js b/microsetta_interface/static/vendor/jquery-ui-i18n/datepicker-es.js new file mode 100644 index 00000000..607150dc --- /dev/null +++ b/microsetta_interface/static/vendor/jquery-ui-i18n/datepicker-es.js @@ -0,0 +1,37 @@ +/* Inicialización en español para la extensión 'UI date picker' para jQuery. */ +/* Traducido por Vester (xvester@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + + datepicker.regional.es = { + closeText: "Cerrar", + prevText: "<Ant", + nextText: "Sig>", + currentText: "Hoy", + monthNames: [ "enero","febrero","marzo","abril","mayo","junio", + "julio","agosto","septiembre","octubre","noviembre","diciembre" ], + monthNamesShort: [ "ene","feb","mar","abr","may","jun", + "jul","ago","sep","oct","nov","dic" ], + dayNames: [ "domingo","lunes","martes","miércoles","jueves","viernes","sábado" ], + dayNamesShort: [ "dom","lun","mar","mié","jue","vie","sáb" ], + dayNamesMin: [ "D","L","M","X","J","V","S" ], + weekHeader: "Sm", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; + datepicker.setDefaults( datepicker.regional.es ); + + return datepicker.regional.es; + +} ) ); \ No newline at end of file diff --git a/microsetta_interface/static/vendor/vue-form-generator-2.3.4/vfg.js b/microsetta_interface/static/vendor/vue-form-generator-2.3.4/vfg.js index cd654b6f..e4f7cc30 100644 --- a/microsetta_interface/static/vendor/vue-form-generator-2.3.4/vfg.js +++ b/microsetta_interface/static/vendor/vue-form-generator-2.3.4/vfg.js @@ -4,4 +4,7 @@ * Released under the MIT License. */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.VueFormGenerator=e():t.VueFormGenerator=e()}("undefined"!=typeof self?self:this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=113)}([function(t,e,n){"use strict";function r(t,e,n,r,i,o,u,a){t=t||{};var c=typeof t.default;"object"!==c&&"function"!==c||(t=t.default);var s="function"==typeof t?t.options:t;e&&(s.render=e,s.staticRenderFns=n,s._compiled=!0),r&&(s.functional=!0),o&&(s._scopeId=o);var l;if(u?(l=function(t){t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,t||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),i&&i.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(u)},s._ssrRegister=l):i&&(l=a?function(){i.call(this,this.$root.$options.shadowRoot)}:i),l)if(s.functional){s._injectStyles=l;var f=s.render;s.render=function(t,e){return l.call(e),f(t,e)}}else{var d=s.beforeCreate;s.beforeCreate=d?[].concat(d,l):[l]}return{exports:t,options:s}}e.a=r},function(t,e,n){"use strict";function r(t){return m()(t)?null!=O.default[t]?O.default[t]:(console.warn("'"+t+"' is not a validator function!"),null):t}function i(t,e,n){var r=w()(n.context,"schema.attributes",{}),i=e.value||"input";m()(i)&&(r=w()(r,i)||r),b()(r,function(e,n){t.setAttribute(n,e)})}Object.defineProperty(e,"__esModule",{value:!0});var o=n(50),u=n.n(o),a=n(199),c=n.n(a),s=n(207),l=n.n(s),f=n(83),d=n.n(f),h=n(2),p=n.n(h),v=n(45),m=n.n(v),g=n(5),_=n.n(g),y=n(23),b=n.n(y),x=n(8),w=n.n(x),O=n(85),j=n(28);e.default={props:["vfg","model","schema","formOptions","disabled"],data:function(){return{errors:[],debouncedValidateFunc:null,debouncedFormatFunc:null}},directives:{attributes:{bind:i,updated:i,componentUpdated:i}},computed:{value:{cache:!1,get:function(){var t=void 0;return t=_()(w()(this.schema,"get"))?this.schema.get(this.model):w()(this.model,this.schema.model),this.formatValueToField(t)},set:function(t){var e=this.value;t=this.formatValueToModel(t),_()(t)?t(t,e):this.updateModelValue(t,e)}}},methods:{validate:function(t){var e=this;this.clearValidationErrors();var n=w()(this.formOptions,"validateAsync",!1),i=[];if(this.schema.validator&&!0!==this.schema.readonly&&!0!==this.disabled){var o=[];p()(this.schema.validator)?b()(this.schema.validator,function(t){o.push(r(t).bind(e))}):o.push(r(this.schema.validator).bind(this)),b()(o,function(t){if(n)i.push(t(e.value,e.schema,e.model));else{var r=t(e.value,e.schema,e.model);r&&_()(r.then)?r.then(function(t){t&&(e.errors=e.errors.concat(t));var n=0===e.errors.length;e.$emit("validated",n,e.errors,e)}):r&&(i=i.concat(r))}})}var a=function(n){var r=[];b()(c()(n),function(t){p()(t)&&t.length>0?r=r.concat(t):m()(t)&&r.push(t)}),_()(e.schema.onValidated)&&e.schema.onValidated.call(e,e.model,r,e.schema);var i=0===r.length;return t||e.$emit("validated",i,r,e),e.errors=r,r};return n?u.a.all(i).then(a):a(i)},debouncedValidate:function(){_()(this.debouncedValidateFunc)||(this.debouncedValidateFunc=d()(this.validate.bind(this),w()(this.schema,"validateDebounceTime",w()(this.formOptions,"validateDebounceTime",500)))),this.debouncedValidateFunc()},updateModelValue:function(t,e){var n=!1;_()(this.schema.set)?(this.schema.set(this.model,t),n=!0):this.schema.model&&(this.setModelValueByPath(this.schema.model,t),n=!0),n&&(this.$emit("model-updated",t,this.schema.model),_()(this.schema.onChanged)&&this.schema.onChanged.call(this,this.model,t,e,this.schema),!0===w()(this.formOptions,"validateAfterChanged",!1)&&(w()(this.schema,"validateDebounceTime",w()(this.formOptions,"validateDebounceTime",0))>0?this.debouncedValidate():this.validate()))},clearValidationErrors:function(){this.errors.splice(0)},setModelValueByPath:function(t,e){var n=t.replace(/\[(\w+)\]/g,".$1");n=n.replace(/^\./,"");for(var r=this.model,i=n.split("."),o=0,u=i.length;o1&&void 0!==arguments[1]&&arguments[1],n=w()(this.formOptions,"fieldIdPrefix","");return Object(j.slugifyFormID)(t,n)+(e?"-"+l()():"")},getFieldClasses:function(){return w()(this.schema,"fieldClasses",[])},formatValueToField:function(t){return t},formatValueToModel:function(t){return t}}}},function(t,e){var n=Array.isArray;t.exports=n},function(t,e){var n=t.exports={version:"2.5.1"};"number"==typeof __e&&(__e=n)},function(t,e,n){var r=n(56)("wks"),i=n(57),o=n(6).Symbol,u="function"==typeof o;(t.exports=function(t){return r[t]||(r[t]=u&&o[t]||(u?o:i)("Symbol."+t))}).store=r},function(t,e,n){function r(t){if(!o(t))return!1;var e=i(t);return e==a||e==c||e==u||e==s}var i=n(43),o=n(7),u="[object AsyncFunction]",a="[object Function]",c="[object GeneratorFunction]",s="[object Proxy]";t.exports=r},function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e){function n(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}t.exports=n},function(t,e,n){function r(t,e,n){var r=null==t?void 0:i(t,e);return void 0===r?n:r}var i=n(151);t.exports=r},function(t,e,n){var r=n(17);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,e,n){var r=n(216),i=n(46),o=n(221),u=n(75),a=Object.prototype,c=a.hasOwnProperty,s=r(function(t,e){t=Object(t);var n=-1,r=e.length,s=r>2?e[2]:void 0;for(s&&o(e[0],e[1],s)&&(r=1);++n1&&void 0!==arguments[1]?arguments[1]:{};return d()(t.fields,function(n){void 0===m()(e,n.model)&&void 0!==n.default&&(u()(n.default)?p()(e,n.model,n.default(n,t,e)):l()(n.default)||c()(n.default)?p()(e,n.model,i()(n.default)):p()(e,n.model,n.default))}),e},_=function(t){var e=[];return d()(t.fields,function(t){!0===t.multi&&e.push(t)}),e},y=function(t,e){var n={},r=_(t);return d()(r,function(t){var r=void 0,i=!0,o=t.model;d()(e,function(t){var e=m()(t,o);i?(r=e,i=!1):r!==e&&(r=void 0)}),p()(n,o,r)}),n},b=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return void 0!==t.id?e+t.id:e+(t.inputName||t.label||t.model||"").toString().trim().toLowerCase().replace(/ |_/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"").replace(/([^a-zA-Z0-9-]+)/g,"")},x=function(){return(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"").toString().trim().replace(/ /g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"").replace(/([^a-zA-Z0-9-_\/.\/:]+)/g,"")}},function(t,e,n){function r(t,e){for(var n=t.length;n--;)if(i(t[n][0],e))return n;return-1}var i=n(46);t.exports=r},function(t,e,n){function r(t,e,n,r){var u=!n;n||(n={});for(var a=-1,c=e.length;++a=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})})},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e,n){var r=n(17),i=n(6).document,o=r(i)&&r(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,e,n){var r=n(125),i=n(58);t.exports=Object.keys||function(t){return r(t,i)}},function(t,e,n){var r=n(54),i=n(33);t.exports=function(t){return r(i(t))}},function(t,e,n){var r=n(56)("keys"),i=n(57);t.exports=function(t){return r[t]||(r[t]=i(t))}},function(t,e,n){var r=n(16).f,i=n(21),o=n(4)("toStringTag");t.exports=function(t,e,n){t&&!i(t=n?t:t.prototype,o)&&r(t,o,{configurable:!0,value:e})}},function(t,e,n){var r=n(33);t.exports=function(t){return Object(r(t))}},function(t,e,n){n(129);for(var r=n(6),i=n(12),o=n(14),u=n(4)("toStringTag"),a="CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,TextTrackList,TouchList".split(","),c=0;c3?0:(t-t%10!=10)*t%10]}};var b={D:function(t){return t.getDate()},DD:function(t){return a(t.getDate())},Do:function(t,e){return e.DoFn(t.getDate())},d:function(t){return t.getDay()},dd:function(t){return a(t.getDay())},ddd:function(t,e){return e.dayNamesShort[t.getDay()]},dddd:function(t,e){return e.dayNames[t.getDay()]},M:function(t){return t.getMonth()+1},MM:function(t){return a(t.getMonth()+1)},MMM:function(t,e){return e.monthNamesShort[t.getMonth()]},MMMM:function(t,e){return e.monthNames[t.getMonth()]},YY:function(t){return String(t.getFullYear()).substr(2)},YYYY:function(t){return a(t.getFullYear(),4)},h:function(t){return t.getHours()%12||12},hh:function(t){return a(t.getHours()%12||12)},H:function(t){return t.getHours()},HH:function(t){return a(t.getHours())},m:function(t){return t.getMinutes()},mm:function(t){return a(t.getMinutes())},s:function(t){return t.getSeconds()},ss:function(t){return a(t.getSeconds())},S:function(t){return Math.round(t.getMilliseconds()/100)},SS:function(t){return a(Math.round(t.getMilliseconds()/10),2)},SSS:function(t){return a(t.getMilliseconds(),3)},a:function(t,e){return t.getHours()<12?e.amPm[0]:e.amPm[1]},A:function(t,e){return t.getHours()<12?e.amPm[0].toUpperCase():e.amPm[1].toUpperCase()},ZZ:function(t){var e=t.getTimezoneOffset();return(e>0?"-":"+")+a(100*Math.floor(Math.abs(e)/60)+Math.abs(e)%60,4)}},x={D:[l,function(t,e){t.day=e}],Do:[new RegExp(l.source+h.source),function(t,e){t.day=parseInt(e,10)}],M:[l,function(t,e){t.month=e-1}],YY:[l,function(t,e){var n=new Date,r=+(""+n.getFullYear()).substr(0,2);t.year=""+(e>68?r-1:r)+e}],h:[l,function(t,e){t.hour=e}],m:[l,function(t,e){t.minute=e}],s:[l,function(t,e){t.second=e}],YYYY:[d,function(t,e){t.year=e}],S:[/\d/,function(t,e){t.millisecond=100*e}],SS:[/\d{2}/,function(t,e){t.millisecond=10*e}],SSS:[f,function(t,e){t.millisecond=e}],d:[l,v],ddd:[h,v],MMM:[h,u("monthNamesShort")],MMMM:[h,u("monthNames")],a:[h,function(t,e,n){var r=e.toLowerCase();r===n.amPm[0]?t.isPm=!1:r===n.amPm[1]&&(t.isPm=!0)}],ZZ:[/([\+\-]\d\d:?\d\d|Z)/,function(t,e){"Z"===e&&(e="+00:00");var n,r=(e+"").match(/([\+\-]|\d\d)/gi);r&&(n=60*r[1]+parseInt(r[2],10),t.timezoneOffset="+"===r[0]?n:-n)}]};x.dd=x.d,x.dddd=x.ddd,x.DD=x.D,x.mm=x.m,x.hh=x.H=x.HH=x.h,x.MM=x.M,x.ss=x.s,x.A=x.a,c.masks={default:"ddd MMM DD YYYY HH:mm:ss",shortDate:"M/D/YY",mediumDate:"MMM D, YYYY",longDate:"MMMM D, YYYY",fullDate:"dddd, MMMM D, YYYY",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"},c.format=function(t,e,n){var r=n||c.i18n;if("number"==typeof t&&(t=new Date(t)),"[object Date]"!==Object.prototype.toString.call(t)||isNaN(t.getTime()))throw new Error("Invalid Date in fecha.format");e=c.masks[e]||e||c.masks.default;var i=[];return e=e.replace(p,function(t,e){return i.push(e),"??"}),e=e.replace(s,function(e){return e in b?b[e](t,r):e.slice(1,e.length-1)}),e.replace(/\?\?/g,function(){return i.shift()})},c.parse=function(t,e,n){var r=n||c.i18n;if("string"!=typeof e)throw new Error("Invalid format in fecha.parse");if(e=c.masks[e]||e,t.length>1e3)return!1;var i=!0,o={};if(e.replace(s,function(e){if(x[e]){var n=x[e],u=t.search(n[0]);~u?t.replace(n[0],function(e){return n[1](o,e,r),t=t.substr(u+e.length),e}):i=!1}return x[e]?"":e.slice(1,e.length-1)}),!i)return!1;var u=new Date;!0===o.isPm&&null!=o.hour&&12!=+o.hour?o.hour=+o.hour+12:!1===o.isPm&&12==+o.hour&&(o.hour=0);var a;return null!=o.timezoneOffset?(o.minute=+(o.minute||0)-+o.timezoneOffset,a=new Date(Date.UTC(o.year||u.getFullYear(),o.month||0,o.day||1,o.hour||0,o.minute||0,o.second||0,o.millisecond||0))):a=new Date(o.year||u.getFullYear(),o.month||0,o.day||1,o.hour||0,o.minute||0,o.second||0,o.millisecond||0),a},void 0!==t&&t.exports?t.exports=c:void 0!==(r=function(){return c}.call(e,n,e,t))&&(t.exports=r)}()},function(t,e,n){"use strict";var r=n(50),i=n.n(r),o=n(2),u=n.n(o),a=n(15),c=n.n(a),s=n(5),l=n.n(s),f=n(23),d=n.n(f),h=n(8),p=n.n(h),v=n(70),m=n(163);e.a={name:"formGenerator",components:{formGroup:m.a},mixins:[v.a],props:{schema:Object,model:Object,options:{type:Object,default:function(){return{validateAfterLoad:!1,validateAfterChanged:!1,fieldIdPrefix:"",validateAsync:!1,validationErrorClass:"error",validationSuccessClass:""}}},multiple:{type:Boolean,default:!1},isNewModel:{type:Boolean,default:!1},tag:{type:String,default:"fieldset",validator:function(t){return t.length>0}}},data:function(){return{vfg:this,errors:[]}},computed:{fields:function(){var t=this,e=[];return this.schema&&this.schema.fields&&d()(this.schema.fields,function(n){t.multiple&&!0!==n.multi||e.push(n)}),e},groups:function(){var t=[];return this.schema&&this.schema.groups&&d()(this.schema.groups.slice(0),function(e){t.push(e)}),t}},watch:{model:function(t,e){var n=this;e!==t&&null!=t&&this.$nextTick(function(){!0===n.options.validateAfterLoad&&!0!==n.isNewModel?n.validate():n.clearValidationErrors()})}},mounted:function(){var t=this;this.$nextTick(function(){t.model&&(!0===t.options.validateAfterLoad&&!0!==t.isNewModel?t.validate():t.clearValidationErrors())})},methods:{fieldVisible:function(t){return l()(t.visible)?t.visible.call(this,this.model,t,this):!!c()(t.visible)||t.visible},onFieldValidated:function(t,e,n){var r=this;this.errors=this.errors.filter(function(t){return t.field!==n.schema}),!t&&e&&e.length>0&&d()(e,function(t){r.errors.push({field:n.schema,error:t})});var i=0===this.errors.length;this.$emit("validated",i,this.errors,this)},onModelUpdated:function(t,e){this.$emit("model-updated",t,e)},validate:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;null===e&&(e=p()(this.options,"validateAsync",!1)),this.clearValidationErrors();var n=[],r=[];d()(this.$children,function(t){l()(t.validate)&&(n.push(t.$refs.child),r.push(t.validate(!0)))});var o=function(r){var i=[];d()(r,function(t,e){u()(t)&&t.length>0&&d()(t,function(t){i.push({field:n[e].schema,error:t})})}),t.errors=i;var o=0===i.length;return t.$emit("validated",o,i,t),e?i:o};return e?i.a.all(r).then(o):o(r)},clearValidationErrors:function(){this.errors.splice(0),d()(this.$children,function(t){t.clearValidationErrors()})}}}},function(t,e,n){t.exports={default:n(116),__esModule:!0}},function(t,e,n){"use strict";var r=n(52),i=n(11),o=n(121),u=n(12),a=n(21),c=n(14),s=n(122),l=n(38),f=n(128),d=n(4)("iterator"),h=!([].keys&&"next"in[].keys()),p=function(){return this};t.exports=function(t,e,n,v,m,g,_){s(n,e,v);var y,b,x,w=function(t){if(!h&&t in S)return S[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},O=e+" Iterator",j="values"==m,k=!1,S=t.prototype,C=S[d]||S["@@iterator"]||m&&S[m],M=C||w(m),T=m?j?w("entries"):M:void 0,I="Array"==e?S.entries||C:C;if(I&&(x=f(I.call(new t)))!==Object.prototype&&x.next&&(l(x,O,!0),r||a(x,d)||u(x,d,p)),j&&C&&"values"!==C.name&&(k=!0,M=function(){return C.call(this)}),r&&!_||!h&&!k&&S[d]||u(S,d,M),c[e]=M,c[O]=p,m)if(y={values:j?M:w("values"),keys:g?M:w("keys"),entries:T},_)for(b in y)b in S||o(S,b,y[b]);else i(i.P+i.F*(h||k),e,y);return y}},function(t,e){t.exports=!0},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){var r=n(22);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},function(t,e,n){var r=n(32),i=Math.min;t.exports=function(t){return t>0?i(r(t),9007199254740991):0}},function(t,e,n){var r=n(6),i=r["__core-js_shared__"]||(r["__core-js_shared__"]={});t.exports=function(t){return i[t]||(i[t]={})}},function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,n){var r=n(6).document;t.exports=r&&r.documentElement},function(t,e,n){var r=n(41),i=n(4)("iterator"),o=n(14);t.exports=n(3).getIteratorMethod=function(t){if(void 0!=t)return t[i]||t["@@iterator"]||o[r(t)]}},function(t,e,n){var r=n(9),i=n(19),o=n(4)("species");t.exports=function(t,e){var n,u=r(t).constructor;return void 0===u||void 0==(n=r(u)[o])?e:i(n)}},function(t,e,n){var r,i,o,u=n(18),a=n(137),c=n(59),s=n(34),l=n(6),f=l.process,d=l.setImmediate,h=l.clearImmediate,p=l.MessageChannel,v=l.Dispatch,m=0,g={},_=function(){var t=+this;if(g.hasOwnProperty(t)){var e=g[t];delete g[t],e()}},y=function(t){_.call(t.data)};d&&h||(d=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return g[++m]=function(){a("function"==typeof t?t:Function(t),e)},r(m),m},h=function(t){delete g[t]},"process"==n(22)(f)?r=function(t){f.nextTick(u(_,t,1))}:v&&v.now?r=function(t){v.now(u(_,t,1))}:p?(i=new p,o=i.port2,i.port1.onmessage=y,r=u(o.postMessage,o,1)):l.addEventListener&&"function"==typeof postMessage&&!l.importScripts?(r=function(t){l.postMessage(t+"","*")},l.addEventListener("message",y,!1)):r="onreadystatechange"in s("script")?function(t){c.appendChild(s("script")).onreadystatechange=function(){c.removeChild(this),_.call(t)}}:function(t){setTimeout(u(_,t,1),0)}),t.exports={set:d,clear:h}},function(t,e){t.exports=function(t){try{return{e:!1,v:t()}}catch(t){return{e:!0,v:t}}}},function(t,e,n){var r=n(9),i=n(17),o=n(42);t.exports=function(t,e){if(r(t),i(e)&&e.constructor===t)return e;var n=o.f(t);return(0,n.resolve)(e),n.promise}},function(t,e){function n(t,e){for(var n=-1,r=null==t?0:t.length;++n0,r=(e={},i()(e,m()(this.options,"validationErrorClass","error"),n),i()(e,m()(this.options,"validationSuccessClass","valid"),!n),i()(e,"disabled",this.fieldDisabled(t)),i()(e,"readonly",this.fieldReadonly(t)),i()(e,"featured",this.fieldFeatured(t)),i()(e,"required",this.fieldRequired(t)),e);return l()(t.styleClasses)?p()(t.styleClasses,function(t){return r[t]=!0}):c()(t.styleClasses)&&(r[t.styleClasses]=!0),d()(t.type)||(r["field-"+t.type]=!0),r},fieldErrors:function(t){return this.errors.filter(function(e){return e.field===t}).map(function(t){return t.error})},fieldDisabled:function(t){return u()(t.disabled)?t.disabled.call(this,this.model,t,this):!d()(t.disabled)&&t.disabled},fieldReadonly:function(t){return u()(t.readonly)?t.readonly.call(this,this.model,t,this):!d()(t.readonly)&&t.readonly},fieldFeatured:function(t){return u()(t.featured)?t.featured.call(this,this.model,t,this):!d()(t.featured)&&t.featured},fieldRequired:function(t){return u()(t.required)?t.required.call(this,this.model,t,this):!d()(t.required)&&t.required}}}},function(t,e){function n(t){return null!=t&&"object"==typeof t}t.exports=n},function(t,e,n){"use strict";var r=n(5),i=n.n(r),o=n(15),u=n.n(o),a=n(8),c=n.n(a),s=n(28),l=n(70),f=n(80),d=n.n(f);e.a={name:"form-group",components:d.a,mixins:[l.a],props:{vfg:{type:Object,required:!0},model:Object,options:{type:Object},field:{type:Object,required:!0},errors:{type:Array,default:function(){return[]}}},methods:{fieldTypeHasLabel:function(t){if(u()(t.label))return!1;switch("input"===t.type?t.inputType:t.type){case"button":case"submit":case"reset":return!1;default:return!0}},getFieldID:function(t){var e=c()(this.options,"fieldIdPrefix","");return Object(s.slugifyFormID)(t,e)},getFieldType:function(t){return"field-"+t.type},getButtonType:function(t){return c()(t,"type","button")},onFieldValidated:function(t,e,n){this.$emit("validated",t,e,n)},buttonVisibility:function(t){return t.buttons&&t.buttons.length>0},buttonClickHandler:function(t,e,n){return t.onclick.call(this,this.model,e,n,this)},fieldHint:function(t){return i()(t.hint)?t.hint.call(this,this.model,t,this):t.hint},fieldErrors:function(t){return this.errors.filter(function(e){return e.field===t}).map(function(t){return t.error})},onModelUpdated:function(t,e){this.$emit("model-updated",t,e)},validate:function(t){return this.$refs.child.validate(t)},clearValidationErrors:function(){if(this.$refs.child)return this.$refs.child.clearValidationErrors()}}}},function(t,e,n){function r(t,e,n,E,D,F){var $,N=e&k,L=e&S,R=e&C;if(n&&($=D?n(t,E,D,F):n(t)),void 0!==$)return $;if(!w(t))return t;var V=y(t);if(V){if($=m(t),!N)return l(t,$)}else{var z=v(t),U=z==T||z==I;if(b(t))return s(t,N);if(z==P||z==M||U&&!D){if($=L||U?{}:_(t),!N)return L?d(t,c($,t)):f(t,a($,t))}else{if(!A[z])return D?t:{};$=g(t,z,N)}}F||(F=new i);var Y=F.get(t);if(Y)return Y;if(F.set(t,$),O(t))return t.forEach(function(i){$.add(r(i,e,n,i,t,F))}),$;if(x(t))return t.forEach(function(i,o){$.set(o,r(i,e,n,o,t,F))}),$;var q=R?L?p:h:L?keysIn:j,B=V?void 0:q(t);return o(B||t,function(i,o){B&&(o=i,i=t[o]),u($,o,r(i,e,n,o,t,F))}),$}var i=n(166),o=n(65),u=n(47),a=n(174),c=n(175),s=n(176),l=n(177),f=n(178),d=n(180),h=n(182),p=n(183),v=n(77),m=n(184),g=n(185),_=n(186),y=n(2),b=n(79),x=n(189),w=n(7),O=n(190),j=n(24),k=1,S=2,C=4,M="[object Arguments]",T="[object Function]",I="[object GeneratorFunction]",P="[object Object]",A={};A[M]=A["[object Array]"]=A["[object ArrayBuffer]"]=A["[object DataView]"]=A["[object Boolean]"]=A["[object Date]"]=A["[object Float32Array]"]=A["[object Float64Array]"]=A["[object Int8Array]"]=A["[object Int16Array]"]=A["[object Int32Array]"]=A["[object Map]"]=A["[object Number]"]=A[P]=A["[object RegExp]"]=A["[object Set]"]=A["[object String]"]=A["[object Symbol]"]=A["[object Uint8Array]"]=A["[object Uint8ClampedArray]"]=A["[object Uint16Array]"]=A["[object Uint32Array]"]=!0,A["[object Error]"]=A[T]=A["[object WeakMap]"]=!1,t.exports=r},function(t,e,n){function r(t,e,n){"__proto__"==e&&i?i(t,e,{configurable:!0,enumerable:!0,value:n,writable:!0}):t[e]=n}var i=n(172);t.exports=r},function(t,e){function n(t){var e=[];if(null!=t)for(var n in Object(t))e.push(n);return e}t.exports=n},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}},function(t,e){function n(t){return i.call(t)}var r=Object.prototype,i=r.toString;t.exports=n},function(t,e){function n(){return!1}t.exports=n},function(t,e){function n(){return!1}t.exports=n},function(t,e,n){var r=n(195).forEach,i={},o=n(196);r(o.keys(),function(t){var e=t.replace(/^\.\//,"").replace(/\.vue/,"");i[e]=o(t).default});var u=n(256);r(u.keys(),function(t){var e=t.replace(/^\.\//,"").replace(/\.vue/,"");i[e]=u(t).default}),t.exports=i},function(t,e,n){"use strict";var r=n(1);e.a={mixins:[r.default]}},function(t,e){function n(t,e,n){for(var r=n-1,i=t.length;++r=e||n<0||S&&r>=b}function h(){var t=o();if(d(t))return p(t);w=setTimeout(h,f(t))}function p(t){return w=void 0,C&&_?r(t):(_=y=void 0,x)}function v(){void 0!==w&&clearTimeout(w),j=0,_=O=y=w=void 0}function m(){return void 0===w?x:p(o())}function g(){var t=o(),n=d(t);if(_=arguments,y=this,O=t,n){if(void 0===w)return l(O);if(S)return w=setTimeout(h,e),r(O)}return void 0===w&&(w=setTimeout(h,e)),x}var _,y,b,x,w,O,j=0,k=!1,S=!1,C=!0;if("function"!=typeof t)throw new TypeError(a);return e=u(e)||0,i(n)&&(k=!!n.leading,S="maxWait"in n,b=S?c(u(n.maxWait)||0,e):b,C="trailing"in n?!!n.trailing:C),g.cancel=v,g.flush=m,g}var i=n(7),o=n(208),u=n(84),a="Expected a function",c=Math.max,s=Math.min;t.exports=r},function(t,e,n){function r(t){if("number"==typeof t)return t;if(o(t))return u;if(i(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=i(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(a,"");var n=s.test(t);return n||l.test(t)?f(t.slice(2),n?2:8):c.test(t)?u:+t}var i=n(7),o=n(26),u=NaN,a=/^\s+|\s+$/g,c=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,l=/^0o[0-7]+$/i,f=parseInt;t.exports=r},function(t,e,n){"use strict";function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k;return b()(t)||""===t?e?[i(n.fieldIsRequired)]:[]:null}function i(t){if(null!=t&&arguments.length>1)for(var e=1;e3&&void 0!==arguments[3]?arguments[3]:k;return r(t,e.required,i)},number:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);if(null!=u)return u;var a=[];return c()(t)?(!b()(e.min)&&te.max&&a.push(i(o.numberTooBig,e.max))):a.push(i(o.invalidNumber)),a},integer:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);if(null!=u)return u;var a=S.number(t,e,n,o);return m()(t)||a.push(i(o.invalidInteger)),a},double:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);return null!=u?u:!_()(t)||isNaN(t)?[i(o.invalidNumber)]:void 0},string:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);if(null!=u)return u;var a=[];return p()(t)?(!b()(e.min)&&t.lengthe.max&&a.push(i(o.textTooBig,t.length,e.max))):a.push(i(o.thisNotText)),a},array:function(t,e,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k;if(e.required){if(!d()(t))return[i(r.thisNotArray)];if(0===t.length)return[i(r.fieldIsRequired)]}if(!b()(t)){if(!b()(e.min)&&t.lengthe.max)return[i(r.selectMaxItems,e.max)]}},date:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);if(null!=u)return u;var a=new Date(t);if(isNaN(a.getDate()))return[i(o.invalidDate)];var c=[];if(!b()(e.min)){var s=new Date(e.min);a.valueOf()l.valueOf()&&c.push(i(o.dateIsLate,j.a.format(a),j.a.format(l)))}return c},regexp:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);if(null!=u)return u;if(!b()(e.pattern)){if(!new RegExp(e.pattern).test(t))return[i(o.invalidFormat)]}},email:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);return null!=u?u:/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(t)?void 0:[i(o.invalidEmail)]},url:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);return null!=u?u:/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/g.test(t)?void 0:[i(o.invalidURL)]},creditCard:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);if(null!=u)return u;var a=/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,c=t.replace(/[^0-9]+/g,"");if(!a.test(c))return[i(o.invalidCard)];for(var s=0,l=void 0,f=void 0,d=void 0,h=c.length-1;h>=0;h--)l=c.substring(h,h+1),f=parseInt(l,10),d?(f*=2,s+=f>=10?f%10+1:f):s+=f,d=!d;return s%10==0&&c?void 0:[i(o.invalidCardNumber)]},alpha:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);return null!=u?u:/^[a-zA-Z]*$/.test(t)?void 0:[i(o.invalidTextContainNumber)]},alphaNumeric:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k,u=r(t,e.required,o);return null!=u?u:/^[a-zA-Z0-9]*$/.test(t)?void 0:[i(o.invalidTextContainSpec)]}};u()(S).forEach(function(t){var e=S[t];l()(e)&&(e.locale=function(t){return function(n,r,i){return e(n,r,i,w()(t,k))}})}),e.default=S},function(t,e,n){function r(t){var e=i(t),n=e%1;return e===e?n?e-n:e:0}var i=n(215);t.exports=r},function(t,e,n){function r(t){return"number"==typeof t||o(t)&&i(t)==u}var i=n(43),o=n(71),u="[object Number]";t.exports=r},function(t,e,n){"use strict";var r=n(225),i=n.n(r),o=n(15),u=n.n(o),a=n(7),c=n.n(a),s=n(1),l=n(28);e.a={mixins:[s.default],data:function(){return{comboExpanded:!1}},computed:{items:function(){var t=this.schema.values;return"function"==typeof t?t.apply(this,[this.model,this.schema]):t},selectedCount:function(){return this.value?this.value.length:0}},methods:{getInputName:function(t){return this.schema&&this.schema.inputName&&this.schema.inputName.length>0?Object(l.slugify)(this.schema.inputName+"_"+this.getItemValue(t)):Object(l.slugify)(this.getItemValue(t))},getItemValue:function(t){if(c()(t)){if(void 0!==this.schema.checklistOptions&&void 0!==this.schema.checklistOptions.value)return t[this.schema.checklistOptions.value];if(void 0!==t.value)return t.value;throw"`value` is not defined. If you want to use another key name, add a `value` property under `checklistOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/checklist.html#checklist-field-with-object-values"}return t},getItemName:function(t){if(c()(t)){if(void 0!==this.schema.checklistOptions&&void 0!==this.schema.checklistOptions.name)return t[this.schema.checklistOptions.name];if(void 0!==t.name)return t.name;throw"`name` is not defined. If you want to use another key name, add a `name` property under `checklistOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/checklist.html#checklist-field-with-object-values"}return t},isItemChecked:function(t){return this.value&&-1!==this.value.indexOf(this.getItemValue(t))},onChanged:function(t,e){if(!u()(this.value)&&Array.isArray(this.value)||(this.value=[]),t.target.checked){var n=i()(this.value);n.push(this.getItemValue(e)),this.value=n}else{var r=i()(this.value);r.splice(this.value.indexOf(this.getItemValue(e)),1),this.value=r}},onExpandCombo:function(){this.comboExpanded=!this.comboExpanded}}}},function(t,e,n){"use strict";var r=n(87),i=n.n(r),o=n(5),u=n.n(o),a=n(8),c=n.n(a),s=n(83),l=n.n(s),f=n(1),d=n(48),h=n.n(d),p={date:"YYYY-MM-DD",datetime:"YYYY-MM-DD HH:mm:ss","datetime-local":"YYYY-MM-DDTHH:mm:ss"};e.a={mixins:[f.default],computed:{inputType:function(){return this.schema&&"datetime"===this.schema.inputType?"datetime-local":this.schema.inputType}},methods:{formatValueToModel:function(t){var e=this;if(null!=t)switch(this.schema.inputType.toLowerCase()){case"date":case"datetime":case"datetime-local":case"number":case"range":return function(n,r){e.debouncedFormatFunc(t,r)}}return t},formatValueToField:function(t){switch(this.schema.inputType.toLowerCase()){case"date":case"datetime":case"datetime-local":return this.formatDatetimeValueToField(t)}return t},formatDatetimeToModel:function(t,e){var n=p[this.schema.inputType.toLowerCase()],r=h.a.parse(t,n);!1!==r&&(t=this.schema.format?h.a.format(r,this.schema.format):r.valueOf()),this.updateModelValue(t,e)},formatDatetimeValueToField:function(t){if(null===t||void 0===t)return null;var e=p[this.schema.inputType.toLowerCase()],n=t;return i()(t)||(n=h.a.parse(t,e)),!1!==n?h.a.format(n,e):t},formatNumberToModel:function(t,e){i()(t)||(t=NaN),this.updateModelValue(t,e)},onInput:function(t){var e=t.target.value;switch(this.schema.inputType.toLowerCase()){case"number":case"range":i()(parseFloat(t.target.value))&&(e=parseFloat(t.target.value))}this.value=e},onBlur:function(){u()(this.debouncedFormatFunc)&&this.debouncedFormatFunc.flush()}},mounted:function(){var t=this;switch(this.schema.inputType.toLowerCase()){case"number":case"range":this.debouncedFormatFunc=l()(function(e,n){t.formatNumberToModel(e,n)},parseInt(c()(this.schema,"debounceFormatTimeout",1e3)),{trailing:!0,leading:!1});break;case"date":case"datetime":case"datetime-local":this.debouncedFormatFunc=l()(function(e,n){t.formatDatetimeToModel(e,n)},parseInt(c()(this.schema,"debounceFormatTimeout",1e3)),{trailing:!0,leading:!1})}},created:function(){"file"===this.schema.inputType.toLowerCase()&&console.warn("The 'file' type in input field is deprecated. Use 'file' field instead.")}}},function(t,e,n){"use strict";var r=n(1);e.a={mixins:[r.default]}},function(t,e,n){"use strict";var r=n(8),i=n.n(r),o=n(5),u=n.n(o),a=n(7),c=n.n(a),s=n(1);e.a={mixins:[s.default],computed:{items:function(){var t=this.schema.values;return"function"==typeof t?t.apply(this,[this.model,this.schema]):t},id:function(){return this.schema.model}},methods:{getItemValue:function(t){if(c()(t)){if(void 0!==this.schema.radiosOptions&&void 0!==this.schema.radiosOptions.value)return t[this.schema.radiosOptions.value];if(void 0!==t.value)return t.value;throw"`value` is not defined. If you want to use another key name, add a `value` property under `radiosOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/radios.html#radios-field-with-object-values"}return t},getItemName:function(t){if(c()(t)){if(void 0!==this.schema.radiosOptions&&void 0!==this.schema.radiosOptions.name)return t[this.schema.radiosOptions.name];if(void 0!==t.name)return t.name;throw"`name` is not defined. If you want to use another key name, add a `name` property under `radiosOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/radios.html#radios-field-with-object-values"}return t},getItemCssClasses:function(t){return{"is-checked":this.isItemChecked(t),"is-disabled":this.isItemDisabled(t)}},onSelection:function(t){this.value=this.getItemValue(t)},isItemChecked:function(t){return this.getItemValue(t)===this.value},isItemDisabled:function(t){if(this.disabled)return!0;var e=i()(t,"disabled",!1);return u()(e)?e(this.model):e}}}},function(t,e,n){"use strict";var r=n(238),i=n.n(r),o=n(15),u=n.n(o),a=n(7),c=n.n(a),s=n(1);e.a={mixins:[s.default],computed:{selectOptions:function(){return this.schema.selectOptions||{}},items:function(){var t=this.schema.values;return"function"==typeof t?this.groupValues(t.apply(this,[this.model,this.schema])):this.groupValues(t)}},methods:{formatValueToField:function(t){return u()(t)?null:t},groupValues:function(t){var e=[],n={};return t.forEach(function(t){n=null,t.group&&c()(t)?(n=i()(e,function(e){return e.group===t.group}),n?n.ops.push({id:t.id,name:t.name}):(n={group:"",ops:[]},n.group=t.group,n.ops.push({id:t.id,name:t.name}),e.push(n))):e.push(t)}),e},getGroupName:function(t){if(t&&t.group)return t.group;throw"Group name is missing! https://icebob.gitbooks.io/vueformgenerator/content/fields/select.html#select-field-with-object-items"},getItemValue:function(t){if(c()(t)){if(void 0!==this.schema.selectOptions&&void 0!==this.schema.selectOptions.value)return t[this.schema.selectOptions.value];if(void 0!==t.id)return t.id;throw"`id` is not defined. If you want to use another key name, add a `value` property under `selectOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/select.html#select-field-with-object-items"}return t},getItemName:function(t){if(c()(t)){if(void 0!==this.schema.selectOptions&&void 0!==this.schema.selectOptions.name)return t[this.schema.selectOptions.name];if(void 0!==t.name)return t.name;throw"`name` is not defined. If you want to use another key name, add a `name` property under `selectOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/select.html#select-field-with-object-items"}return t}}}},function(t,e){function n(t){return t}t.exports=n},function(t,e,n){"use strict";var r=n(245),i=n.n(r),o=n(5),u=n.n(o),a=n(8),c=n.n(a),s=n(1);e.a={mixins:[s.default],methods:{onClick:function(t){var e=this;if(!0===this.schema.validateBeforeSubmit){t.preventDefault();var n=c()(this.formOptions,"validateAsync",!1),r=this.vfg.validate(),o=function(r){n&&!i()(r)||!n&&!r?u()(e.schema.onValidationError)&&e.schema.onValidationError(e.model,e.schema,r,t):u()(e.schema.onSubmit)&&e.schema.onSubmit(e.model,e.schema,t)};r&&u()(r.then)?r.then(o):o(r)}else u()(this.schema.onSubmit)&&this.schema.onSubmit(this.model,this.schema,t)}}}},function(t,e,n){"use strict";var r=n(1);e.a={mixins:[r.default]}},function(t,e,n){"use strict";var r=n(5),i=n.n(r),o=n(1);e.a={mixins:[o.default],methods:{onChange:function(t){i()(this.schema.onChanged)&&this.schema.onChanged.call(this,this.model,this.schema,t,this)}}}},function(t,e,n){"use strict";var r=n(10),i=n.n(r),o=n(1);e.a={mixins:[o.default],data:function(){return{cleave:null}},mounted:function(){this.$nextTick(function(){var t=this;window.Cleave?(this.cleave=new window.Cleave(this.$el,i()(this.schema.cleaveOptions||{},{creditCard:!1,phone:!1,phoneRegionCode:"AU",date:!1,datePattern:["d","m","Y"],numeral:!1,numeralThousandsGroupStyle:"thousand",numeralDecimalScale:2,numeralDecimalMark:".",blocks:[],delimiter:" ",prefix:null,numericOnly:!1,uppercase:!1,lowercase:!1,maxLength:0})),this.cleave.properties&&this.cleave.properties.hasOwnProperty("result")?this.$watch("cleave.properties.result",function(){t.value=t.cleave.properties.result}):this.$el.addEventListener("input",this.inputChange)):console.warn("Cleave is missing. Please download from https://github.com/nosir/cleave.js/ and load the script in the HTML head section!")})},methods:{inputChange:function(){this.value=this.$el.value}},beforeDestroy:function(){this.cleave&&(this.cleave.destroy(),this.$el.removeEventListener("input",this.inputChange))}}},function(t,e,n){"use strict";var r=n(99),i=n.n(r),o=n(10),u=n.n(o),a=n(1),c=n(100);e.a={mixins:[a.default],methods:i()({getDateFormat:function(){return this.schema.dateTimePickerOptions&&this.schema.dateTimePickerOptions.format?this.schema.dateTimePickerOptions.format:"YYYY-MM-DD HH:mm:ss"}},c.a),mounted:function(){this.$nextTick(function(){var t=this;if(window.$&&window.$.fn.datetimepicker){var e=this.$el.querySelector(".form-control");$(this.$el).datetimepicker(u()(this.schema.dateTimePickerOptions||{},{format:"YYYY-MM-DD HH:mm:ss"})).on("dp.change",function(){t.value=e.value})}else console.warn("Bootstrap datetimepicker library is missing. Please download from https://eonasdan.github.io/bootstrap-datetimepicker/ and load the script and CSS in the HTML head section!")})},beforeDestroy:function(){window.$&&window.$.fn.datetimepicker&&$(this.$el).data("DateTimePicker").destroy()}}},function(t,e,n){"use strict";e.__esModule=!0;var r=n(262),i=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default=i.default||function(t){for(var e=1;e":this.value},set:function(t){t&&0===t.indexOf("http")&&(this.value=t)}}},watch:{model:function(){var t=this.$el.querySelector("input.file");t&&(t.value="")}},methods:{remove:function(){this.value=""},fileChanged:function(t){var e=this,n=new FileReader;n.onload=function(t){e.value=t.target.result},t.target.files&&t.target.files.length>0&&n.readAsDataURL(t.target.files[0])}}}},function(t,e,n){"use strict";var r=n(1);e.a={mixins:[r.default],mounted:function(){this.$nextTick(function(){window.$&&window.$.fn.mask?$(this.$el).unmask().mask(this.schema.mask,this.schema.maskOptions):console.warn("JQuery MaskedInput library is missing. Please download from https://github.com/digitalBush/jquery.maskedinput and load the script in the HTML head section!")})},beforeDestroy:function(){window.$&&window.$.fn.mask&&$(this.$el).unmask()}}},function(t,e,n){"use strict";var r=n(10),i=n.n(r),o=n(2),u=n.n(o),a=n(1);e.a={mixins:[a.default],data:function(){return{slider:null}},watch:{model:function(){window.noUiSlider&&this.slider&&this.slider.noUiSlider&&this.slider.noUiSlider.set(this.value)}},computed:{containPips:function(){return this.schema.noUiSliderOptions&&void 0!==this.schema.noUiSliderOptions.pips},containTooltip:function(){return this.schema.noUiSliderOptions&&this.schema.noUiSliderOptions.tooltips}},methods:{onChange:function(t){u()(t)?this.value=[parseFloat(t[0]),parseFloat(t[1])]:this.value=parseFloat(t)},formatValueToField:function(t){null!==this.slider&&void 0!==this.slider.noUiSlider&&this.slider.noUiSlider.set(t)},formatValueToModel:function(t){if(void 0!==this.slider.noUiSlider)return t instanceof Array?[Number(t[0]),Number(t[1])]:Number(t)},getStartValue:function(){return null!=this.value?this.value:void 0!==this.schema.noUiSliderOptions&&this.schema.noUiSliderOptions.double?[this.schema.min,this.schema.min]:this.schema.min}},mounted:function(){var t=this;this.$nextTick(function(){window.noUiSlider?(t.slider=t.$el,window.noUiSlider.create(t.slider,i()(t.schema.noUiSliderOptions||{},{start:t.getStartValue(),range:{min:t.schema.min,max:t.schema.max}})),t.slider.noUiSlider.on("change",t.onChange.bind(t))):console.warn("noUiSlider is missing. Please download from https://github.com/leongersen/noUiSlider and load the script and CSS in the HTML head section!")})},beforeDestroy:function(){this.slider&&this.slider.noUiSlider.off("change")}}},function(t,e,n){"use strict";var r=n(99),i=n.n(r),o=n(8),u=n.n(o),a=n(10),c=n.n(a),s=n(1),l=n(100);e.a={mixins:[s.default],data:function(){return{picker:null,options:null}},methods:i()({getDateFormat:function(){return u()(this.schema,"pikadayOptions.format","YYYY-MM-DD")}},l.a,{initialize:function(t){var e=this;this.picker&&this.picker.destroy&&this.picker.destroy(),this.$nextTick(function(){window.Pikaday?(e.options=c()({},t,{field:e.$el,onSelect:function(){e.value=e.picker.toString()}}),e.picker=new window.Pikaday(e.options)):console.warn("Pikaday is missing. Please download from https://github.com/dbushell/Pikaday/ and load the script and CSS in the HTML head section!")})}}),mounted:function(){this.initialize(u()(this.schema,"pikadayOptions",{}))},beforeDestroy:function(){this.picker&&this.picker.destroy()}}},function(t,e,n){"use strict";var r=n(285),i=n.n(r),o=n(2),u=n.n(o),a=n(10),c=n.n(a),s=n(1);e.a={mixins:[s.default],data:function(){return{slider:null}},watch:{model:function(){if(window.$&&window.$.fn.ionRangeSlider){var t=void 0,e=void 0;if(u()(this.value)){var n=i()(this.value,2);t=n[0],e=n[1]}else t=this.value;this.slider&&this.slider.update({from:t,to:e})}}},mounted:function(){this.$nextTick(function(){if(window.$&&window.$.fn.ionRangeSlider){var t=void 0,e=void 0;if(u()(this.value)){var n=i()(this.value,2);t=n[0],e=n[1]}else t=this.value;var r=this;$(this.$el).ionRangeSlider(c()(this.schema.rangeSliderOptions||{},{type:"single",grid:!0,hide_min_max:!0,from:t,to:e,onChange:function(t){"double"===r.slider.options.type?r.value=[t.from,t.to]:r.value=t.from}})),this.slider=$(this.$el).data("ionRangeSlider")}else console.warn("ion.rangeSlider library is missing. Please download from https://github.com/IonDen/ion.rangeSlider and load the script and CSS in the HTML head section!")})},beforeDestroy:function(){this.slider&&this.slider.destroy()}}},function(t,e,n){t.exports={default:n(289),__esModule:!0}},function(t,e,n){"use strict";var r=n(7),i=n.n(r),o=n(1);e.a={mixins:[o.default],computed:{items:function(){var t=this.schema.values;return"function"==typeof t?t.apply(this,[this.model,this.schema]):t}},methods:{getItemValue:function(t){if(i()(t)){if(void 0!==this.schema.selectOptions&&void 0!==this.schema.selectOptions.value)return t[this.schema.selectOptions.value];if(void 0!==t.id)return t.id;throw"`id` is not defined. If you want to use another key name, add a `value` property under `selectOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/select.html#select-field-with-object-items"}return t},getItemName:function(t){if(i()(t)){if(void 0!==this.schema.selectOptions&&void 0!==this.schema.selectOptions.name)return t[this.schema.selectOptions.name];if(void 0!==t.name)return t.name;throw"`name` is not defined. If you want to use another key name, add a `name` property under `selectOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/select.html#select-field-with-object-items"}return t}},watch:{model:function(){$.fn.selectpicker&&$(this.$el).selectpicker("refresh")}},mounted:function(){this.$nextTick(function(){$.fn.selectpicker?$(this.$el).selectpicker("destroy").selectpicker(this.schema.selectOptions):console.warn("Bootstrap-select library is missing. Please download from https://silviomoreto.github.io/bootstrap-select/ and load the script and CSS in the HTML head section!")})},beforeDestroy:function(){$.fn.selectpicker&&$(this.$el).selectpicker("destroy")}}},function(t,e,n){"use strict";var r=n(10),i=n.n(r),o=n(1);e.a={mixins:[o.default],data:function(){return{picker:null}},watch:{model:function(){window.$&&window.$.fn.spectrum&&this.picker.spectrum("set",this.value)},disabled:function(t){t?this.picker.spectrum("disable"):this.picker.spectrum("enable")}},mounted:function(){this.$nextTick(function(){var t=this;window.$&&window.$.fn.spectrum?(this.picker=$(this.$el).spectrum("destroy").spectrum(i()(this.schema.colorOptions||{},{showInput:!0,showAlpha:!0,disabled:this.schema.disabled,allowEmpty:!this.schema.required,preferredFormat:"hex",change:function(e){t.value=e?e.toString():null}})),this.picker.spectrum("set",this.value)):console.warn("Spectrum color library is missing. Please download from http://bgrins.github.io/spectrum/ and load the script and CSS in the HTML head section!")})},beforeDestroy:function(){this.picker&&this.picker.spectrum("destroy")}}},function(t,e,n){"use strict";var r=n(107),i=n.n(r),o=n(10),u=n.n(o),a=n(1);e.a={mixins:[a.default],computed:{mapLink:function(){if(this.value){var t=void 0,e=void 0,n=u()(this.schema.staticMapOptions||{},{lat:"lat",lng:"lng",zoom:8,sizeX:640,sizeY:640});t=this.value[n.lat],e=this.value[n.lng];var r="http://maps.googleapis.com/maps/api/staticmap?center="+t+","+e+"&zoom="+n.zoom+"&size="+n.sizeX+"x"+n.sizeY,o=["scale","format","maptype","language","region","markers","path","visible","style","key","signature"],a=!0,c=!1,s=void 0;try{for(var l,f=i()(o);!(a=(l=f.next()).done);a=!0){var d=l.value;void 0!==n[d]&&(r+="&"+d+"="+n[d])}}catch(t){c=!0,s=t}finally{try{!a&&f.return&&f.return()}finally{if(c)throw s}}if(t&&e)return r}}}}},function(t,e,n){"use strict";var r=n(1);e.a={mixins:[r.default],methods:{formatValueToField:function(t){return null!=t&&this.schema.valueOn?t===this.schema.valueOn:t},formatValueToModel:function(t){return null!=t&&this.schema.valueOn?t?this.schema.valueOn:this.schema.valueOff:t}}}},function(t,e,n){"use strict";var r=n(1);e.a={mixins:[r.default],computed:{selectOptions:function(){return this.schema.selectOptions||{}},options:function(){var t=this.schema.values;return"function"==typeof t?t.apply(this,[this.model,this.schema]):t},customLabel:function(){return void 0!==this.schema.selectOptions&&void 0!==this.schema.selectOptions.customLabel&&"function"==typeof this.schema.selectOptions.customLabel?this.schema.selectOptions.customLabel:void 0}},methods:{updateSelected:function(t){this.value=t},addTag:function(t,e){var n=this.selectOptions.onNewTag;"function"==typeof n&&n(t,e,this.options,this.value)},onSearchChange:function(t,e){var n=this.selectOptions.onSearch;"function"==typeof n&&n(t,e,this.options)},onSelect:function(){},onRemove:function(){},onOpen:function(){},onClose:function(){}},created:function(){this.$root.$options.components.multiselect||console.error("'vue-multiselect' is missing. Please download from https://github.com/monterail/vue-multiselect and register the component globally!")}}},function(t,e,n){var r=n(114).default,i=n(28),o=n(85).default,u=n(80).default,a=n(1).default,c=function(e,n){if(e.component("VueFormGenerator",t.exports.component),n&&n.validators)for(var r in n.validators)({}).hasOwnProperty.call(n.validators,r)&&(o[r]=n.validators[r])};t.exports={component:r,schema:i,validators:o,abstractField:a,fieldComponents:u,install:c}},function(t,e,n){"use strict";function r(t){n(115)}Object.defineProperty(e,"__esModule",{value:!0});var i=n(49),o=n(307),u=n(0),a=r,c=Object(u.a)(i.a,o.a,o.b,!1,a,null,null);e.default=c.exports},function(t,e){},function(t,e,n){n(117),n(31),n(40),n(132),n(142),n(143),t.exports=n(3).Promise},function(t,e){},function(t,e,n){var r=n(32),i=n(33);t.exports=function(t){return function(e,n){var o,u,a=String(i(e)),c=r(n),s=a.length;return c<0||c>=s?t?"":void 0:(o=a.charCodeAt(c),o<55296||o>56319||c+1===s||(u=a.charCodeAt(c+1))<56320||u>57343?t?a.charAt(c):o:t?a.slice(c,c+2):u-56320+(o-55296<<10)+65536)}}},function(t,e,n){t.exports=!n(13)&&!n(20)(function(){return 7!=Object.defineProperty(n(34)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){var r=n(17);t.exports=function(t,e){if(!r(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!r(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){t.exports=n(12)},function(t,e,n){"use strict";var r=n(123),i=n(53),o=n(38),u={};n(12)(u,n(4)("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(u,{next:i(1,n)}),o(t,e+" Iterator")}},function(t,e,n){var r=n(9),i=n(124),o=n(58),u=n(37)("IE_PROTO"),a=function(){},c=function(){var t,e=n(34)("iframe"),r=o.length;for(e.style.display="none",n(59).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(" @@ -27,6 +27,7 @@ city: "required", state: "required", post_code: "required", + language: "required", {% if CREATE_ACCT %} kit_name: { required: "#code:blank", @@ -86,11 +87,37 @@ } } } + else if (code === "MX") { + $("#city_label").text("{{ _('City') }}*"); + $("#state_label").text("{{ _('State') }}*"); + $("#post_code_label").text("{{ _('Zip Code') }}*"); + $("#state").empty(); + + for (var country of COUNTRIES_LIST) + { + if (country.country !== "Mexico") + continue; + + for (var state of country.states) + { + var option = $('') + .attr("value", state) + .text(state); + + // We don't really have state codes for other + // countries... + if (state == start_code) + option.attr('selected','selected'); + + $("#state").append(option); + } + } + } else { - $("#city_label").text("City/Ciudad*"); - $("#state_label").text("State/Estado*"); - $("#post_code_label").text("Zip Code/Codigo Postal*"); + $("#city_label").text("{{ _('City') }}*"); + $("#state_label").text("{{ _('State') }}*"); + $("#post_code_label").text("{{ _('Zip Code') }}*"); $("#state").empty(); for (var state of US_STATES) @@ -111,40 +138,39 @@ {% endblock %} {% block breadcrumb %} {% if not CREATE_ACCT %} - + {% endif %} - + {% endblock %} {% block content %}
-
Profile Details
+
{{ _('Profile Details') }}
- +
- +
- +
-

- Note to non-US/GB users: We are working on support for additional countries and - expect to have that available soon. -

- + + +
- +
@@ -163,28 +189,39 @@
+
+ +
+ +
{% if CREATE_ACCT %}
- Activation Info + {{ _('Activation Info') }}
- +
-
-OR-
+
-{{ _('OR') }}-
- +
{% endif %} {% if CREATE_ACCT %} - + {% else %} - + {% endif %}
diff --git a/microsetta_interface/templates/account_overview.jinja2 b/microsetta_interface/templates/account_overview.jinja2 index aae7bfe0..ab539884 100644 --- a/microsetta_interface/templates/account_overview.jinja2 +++ b/microsetta_interface/templates/account_overview.jinja2 @@ -1,5 +1,5 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Account" %} +{% set page_title = _("Account") %} {% set show_breadcrumbs = True %} {% block head %} @@ -41,37 +41,37 @@ {% endblock %} {% block breadcrumb %} - + {% endblock %} {% block content %} -

Account Details

+

{{ _('Account Details') }}

{{account.first_name |e}} {{account.last_name |e}}
{{account.email |e}}
- View Account Details + {{ _('View Account Details') }}

-

Sources

+

{{ _('Sources') }}

{% if sources|length == 0 %} {% endif %} {% if sources|length > 0 %} - Choose a source to assign samples to by clicking on a name, listed in blue below: + {{ _('Choose a source to assign samples to by clicking on a name, listed in blue below:') }}

- Name + {{ _('Name') }}
- Source type + {{ _('Source type') }}
{% for source in sources %} @@ -92,7 +92,7 @@ {% endif %}

-

What is the Source of Your Sample?

+

{{ _('What is the Source of Your Sample?') }}


@@ -100,48 +100,48 @@
-

Our lab needs to know what type of sample(s) you are submitting (a.k.a. the “source”). Add a new source and assign samples to it so we can perform the correct analysis in our laboratory.

+

{{ _('Our lab needs to know what type of sample(s) you are submitting (a.k.a. the “source”). Add a new source and assign samples to it so we can perform the correct analysis in our laboratory.') }}

-

If you have multiple sources, you may add one source at a time. You can return to this page after you finish registering the first one.

+

{{ _('If you have multiple sources, you may add one source at a time. You can return to this page after you finish registering the first one.') }}

... -
Human Source
+
{{ _('Human Source') }}
- Collect sample(s) from yourself (e.g. fecal, saliva, skin, etc.) + {{ _('Collect sample(s) from') }} {{ _('yourself') }} {{ _('(e.g. fecal, saliva, skin, etc.)') }}
- Collect sample(s) from someone else (fecal, saliva, skin, etc.) + {{ _('Collect sample(s) from') }} {{ _('someone else') }} {{ _('(e.g. fecal, saliva, skin, etc.)') }}
... -
Environmental Source
+
{{ _('Environmental Source') }}
- Collect sample(s) from a surface (e.g. kitchen counter, backyard soil, food, etc.) + {{ _('Collect sample(s) from a') }} {{ _('surface') }} {{ _('(e.g. kitchen counter, backyard soil, food, etc.)') }}
... -
Animal Source
+
{{ _('Animal Source') }}
- Collect sample(s) from your pet or an animal (e.g. fecal, oral, skin, etc.) + {{ _('Collect sample(s) from') }} {{ _('your pet') }} {{ _('or an') }} {{ _('animal') }} {{ _('(e.g. fecal, saliva, skin, etc.)') }}
-
Animal sources are currently unavailable.
+
{{ _('Animal sources are currently unavailable.') }}
diff --git a/microsetta_interface/templates/admin_activation_codes.jinja2 b/microsetta_interface/templates/admin_activation_codes.jinja2 index 8c8837b8..b0dd2cc1 100644 --- a/microsetta_interface/templates/admin_activation_codes.jinja2 +++ b/microsetta_interface/templates/admin_activation_codes.jinja2 @@ -1,36 +1,36 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Admin Activation Codes" %} +{% set page_title = _("Admin Activation Codes") %} {% set show_breadcrumbs = False %} {% block content %}
- + - +
- + - +
- + - - + +
-

Search Results

+

{{ _('Search Results') }}

{% if diagnostics is not none and diagnostics|length > 0 %}
- Email + {{ _('Email') }}
- Code + {{ _('Code') }}
- Activated + {{ _('Activated') }}
{% for row in diagnostics %} @@ -43,7 +43,7 @@ {{ row.code|e }}
- {{ row.activated|e }} + {{ row.activated|e }}
@@ -51,7 +51,7 @@


{% else %} - No accounts found + {{ _('No accounts found') }} {% endif %}
{% endblock %} diff --git a/microsetta_interface/templates/admin_home.jinja2 b/microsetta_interface/templates/admin_home.jinja2 index 252a73b5..63732742 100644 --- a/microsetta_interface/templates/admin_home.jinja2 +++ b/microsetta_interface/templates/admin_home.jinja2 @@ -1,17 +1,17 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "ADMINISTRATOR MODE" %} +{% set page_title = _("ADMINISTRATOR MODE") %} {% set show_breadcrumbs = False %} {% block content %} -

Search Results

+

{{ _('Search Results') }}

{% if accounts|length > 0 %}
- Email + {{ _('Email') }}
- Account ID + {{ _('Account ID') }}
{% for account in accounts %} @@ -31,7 +31,7 @@


{% else %} - No accounts found + {{ _('No accounts found') }} {% endif %}
{% endblock %} diff --git a/microsetta_interface/templates/admin_system_panel.jinja2 b/microsetta_interface/templates/admin_system_panel.jinja2 index 6819463e..79737530 100644 --- a/microsetta_interface/templates/admin_system_panel.jinja2 +++ b/microsetta_interface/templates/admin_system_panel.jinja2 @@ -1,38 +1,69 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "ADMINISTRATOR SYSTEM PANEL" %} +{% set page_title = _("ADMINISTRATOR SYSTEM PANEL") %} {% set show_breadcrumbs = False %} {% block head %} {% endblock %} {% block content %} -

Set System Message

+

{{ _('Set System Message') }}

- +
- + System Message Class: + + + + + + + + +
+ System Message Text: +
+ Shutdown Time Hours:
+ Shutdown Time Minutes:
- +
{% endblock %} diff --git a/microsetta_interface/templates/create_nonhuman_source.jinja2 b/microsetta_interface/templates/create_nonhuman_source.jinja2 index 281c480f..91b256c4 100644 --- a/microsetta_interface/templates/create_nonhuman_source.jinja2 +++ b/microsetta_interface/templates/create_nonhuman_source.jinja2 @@ -1,11 +1,11 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Create Non-human Source" %} +{% set page_title = _("Create Non-human Source") %} {% set show_breadcrumbs = True %} {% block head %} {% endblock %} @@ -13,14 +13,14 @@
- +
- +
- +
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/microsetta_interface/templates/email_confirmation.jinja2 b/microsetta_interface/templates/email_confirmation.jinja2 index 7bc5b7e4..46edf5fc 100644 --- a/microsetta_interface/templates/email_confirmation.jinja2 +++ b/microsetta_interface/templates/email_confirmation.jinja2 @@ -1,5 +1,5 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Awaiting Email Confirmation" %} +{% set page_title = _("Awaiting Email Confirmation") %} {% set show_breadcrumbs = False %} {% block head %} @@ -17,21 +17,21 @@ {% block content %}
-

Check your email inbox.

-

To complete your verification, click on the link in the email AuthRocket has sent to {{ login_info.email }}.


+

{{ _('Check your email inbox') }}.

+

{{ _('To complete your verification, click on the link in the email AuthRocket has sent to') }} {{ login_info.email }}.




-

Waiting for you to confirm

+

{{ _('Waiting for you to confirm') }}


    -
  • Please check both your spam and inbox
  • -
  • AuthRocket is our authentication service
  • -
  • Email wrong or didn't receive an email? Go to your AuthRocket Profile → to update your email or resend a verification email.
  • +
  • {{ _('Please check both your spam and inbox') }}
  • +
  • {{ _('AuthRocket is our authentication service') }}
  • +
  • {{ _('Email wrong or didn\'t receive an email?') }} {{ _('Go to your AuthRocket Profile') }} → {{ _('to update your email or resend a verification email') }}.

- You can close this browser tab! After email verification, a new tab will automatically open, and you will proceed with filling out your profile details. + {{ _('You can close this browser tab!') }} {{ _('After email verification, a new tab will automatically open, and you will proceed with filling out your profile details') }}.

  
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/microsetta_interface/templates/embedded_pdf.jinja2 b/microsetta_interface/templates/embedded_pdf.jinja2 index 03d2002a..490fd008 100644 --- a/microsetta_interface/templates/embedded_pdf.jinja2 +++ b/microsetta_interface/templates/embedded_pdf.jinja2 @@ -21,7 +21,7 @@ html, body, embed { {% block content %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/microsetta_interface/templates/emperor.jinja2 b/microsetta_interface/templates/emperor.jinja2 index cac7d5b0..b8c494c3 100644 --- a/microsetta_interface/templates/emperor.jinja2 +++ b/microsetta_interface/templates/emperor.jinja2 @@ -1,5 +1,5 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Emperor Playground" %} +{% set page_title = _("Emperor Playground") %} {% set show_breadcrumbs = False %} {% set show_logout = True %} {% block head %} @@ -62,15 +62,15 @@ {% endblock %} {% block content %} -

Emperor Playground

+

{{ _('Emperor Playground') }}

- +
- +
diff --git a/microsetta_interface/templates/error.jinja2 b/microsetta_interface/templates/error.jinja2 index 983c9a44..003493f7 100644 --- a/microsetta_interface/templates/error.jinja2 +++ b/microsetta_interface/templates/error.jinja2 @@ -1,5 +1,5 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Error Page" %} +{% set page_title = _("Error Page") %} {% set show_breadcrumbs = True %} {% block head %} {% endblock %} @@ -7,16 +7,12 @@ {% endblock %} {% block content %}

- An error seemed to have occurred (see below). It is most likely our fault. - We are actively modifying our infrastructure to support COVID-19 research, - and we’re still in the process of handling the different type of scenarios - that can happen on a website. We apologize for any inconvenience. + {{ _('An error seemed to have occurred (see below). It is most likely our fault. We are actively modifying our infrastructure to support COVID-19 research, and we\'re still in the process of handling the different type of scenarios that can happen on a website. We apologize for any inconvenience.') }}

- If you have any concerns, please email us at microsetta@ucsd.edu - and please note the error below. + {{ _('If you have any concerns, please email us at') }} microsetta@ucsd.edu {{ _('and please note the error below') }}.

-Error: +{{ _('Error') }}:
{{ error_msg }}
{% endblock %} diff --git a/microsetta_interface/templates/faq.jinja2 b/microsetta_interface/templates/faq.jinja2 deleted file mode 100644 index 9c1cb6a3..00000000 --- a/microsetta_interface/templates/faq.jinja2 +++ /dev/null @@ -1,326 +0,0 @@ -{% extends "sitebase.jinja2" %} -{% set page_title = "Frequently Asked Questions" %} -{% set show_breadcrumbs = False %} -{% set disable_faq = True %} -{% block head %} - - -{% endblock %} -{% block content %} -

FAQ

-
-

- Thank you in advance for your patience and support during this period. If you have any further inquiries after - reviewing the questions below, please contact us at - microsetta@ucsd.edu. -
-
- Last Updated: June 1th, 2020 -

-
- -
-

-

- The Microsetta Initiative (TMI) is an extension of the American Gut - and British Gut Projects with the specific aims of being globally - inclusive and accommodating a broader range of microbiome sample - types. The American Gut and British Gut Project both still - operate through The Microsetta Initiative as regional projects, - making TMI the central hub for providing kits to participants and - hosting the participant website. -

-
-
-
-
- -
-

-

- For New Participants: -
- If you have an American Gut/Microsetta kit, live in the U.S., and have not registered the kit yet: -
- - Sign Up - to create a login using your email and a password of your choice. -
- -
- After, you will be prompted to click on the “Create New Account” button to fill out your personal - information and kit ID. Please use the kit ID provided on your registration card found in your kit. -
- -
- For existing participants: -
- If you previously had a participant account through the American/British Gut (microbio.me): -
- - Sign Up - to create a login using the email address you previously used when registering with either project. - In order to proceed, you will need to re-confirm your email address. -
-
- If your existing account associated with your email address had a single human source, you will be able - to log in and proceed in the process. If your existing account has multiple human sources (e.g., - multiple family members), you will be presented with a page indicating that we do not yet support this - account type. -
-
- We are working hard to migrate all American and British Gut kits to be compatible with the recent - infrastructure changes necessary for our COVID-19 response. We apologize for this temporary - inconvenience. -
-
- If you have a British Gut kit and have not registered the kit yet: -
- - Sign Up - to create a login using your email and a password of your choice. -
-
- Unfortunately, at this time, our website does not support non-U.S. addresses. We apologize for the - inconvenience and request that you check back at a later time. -
-
-

-
-
-
-
- -
-

-

- If you have previously received results from American Gut/British Gut: -
- We will work on making your results accessible through our participant website once we have migrated all - American/British Gut accounts to be compatible with the new database. -
-
- If there is an urgent need for your results, please email - microsetta@ucsd.edu, - providing your kit ID or barcode number. -
-
- If you have not yet received results from American/British Gut: -
- It typically takes 2-3 months from the time we receive a sample - for results to be produced. However, we are adapting our - infrastructure right now to better support COVID-19 research, - so the timings may change. Please contact microsetta@ucsd.edu, - providing your kit ID and/or barcode number so we may assist - you further. -

-
-
-
-
- -
-

-

If you are able to login and assign your sample(s), then yes. If your account is not presently - migrated, then please wait to send samples in. The sample assignment process is essential in order for - us to verify we have ethical consent to handle the sample. -
-
- If you have already taken a sample, please send it back as soon as possible, ideally within 48 hours, - using the materials provided in the kit. Our American and British Gut laboratories are still operating - and can store it to preserve your sample quality. -

-
-
-
-
- -
-

-

- In response to COVID-19, USPS deliveries have been reduced to our laboratory that runs from - UC San Diego. We are working closely with UC San Diego Shipping and Logistics to ensure samples are - delivered with minimal delay. All British Gut samples will be held at their site until they have - resumed normal operations, and they are able to bulk ship samples back to us. Due to these delays, - there may also be a longer waiting period for notifications regarding when your sample has been - received by our lab. Any samples we receive are placed in temperature-controlled freezers to ensure - sample quality is maintained. -
-
- If your sample has been sent via FedEx (new Microsetta kits), transit times from impacted areas might be - increased, but sample quality won’t be affected. -

-

-
-
-
- - -
- -
-

-

- Questions on the Online Process/Participant Website -
- Where is the kit ID? Or, I get a message that my kit ID is invalid or already in use when trying to register. -
- The kit ID is located on the kit registration card, found in the slot for Step 2 in your kit (please see the image below): -
- -
- IMPORTANT: If your registration card contains a "Password", as displayed in the image above, please the associated password. This is for our old website that is no longer online. -
-
- If you are unable to locate your kit ID or your registration - card, please email microsetta@ucsd.edu and provide one of the - barcode numbers found on your collection materials, such as the - number found on the sticky label on the silver specimen bag - (the barcode number would start with leading zeros) -
-
- What should I use for my password? -
- The password is your choice, but must be at least 8 characters - long. Some kits may have a password printed on the registration - card, please do not use that as your password as it’s for a - deprecated website that is no longer online. -
-
- I’m having trouble logging in my sample information/assigning my sample. -
-

    -
  1. Log into https://microsetta.ucsd.edu
  2. -
  3. Click on your account. This will say your email address, i.e. ("_____’s account") - Note: this will say "Create New Account" if a - consent form has not been completed. If a consent is - needed, you will be directed to the consent page, - followed by the questionnaires. -
  4. -
  5. Once you have completed Step 2, click on your name in the source list (example below).
  6. -
    - -
    -
  7. Next, you will need to add in your kit ID (“To add your - samples, please enter a kit ID here:”). The kit ID can be - found on the registration card inside your kit. If you have - done this already, skip to step 6. Please select the barcodes that you would like to - associate to your source.
  8. -
  9. The barcodes selected will show up under - the sample listing (see below image). To update your - collection date and the sample type, click on the barcode - number (colored as blue text).
  10. -
    - -
-
- Questions on Sample Collection -
- I did not get enough blood on the swabs. What can I do? -
- If at least one swab was saturated with blood: Proceed with sending your sample back to us; we will still be able to utilize it for analysis. -
- If neither swab was saturated with blood and your lancet is used: Contact us at microsetta@ucsd.edu, stating that you need a new lancet and provide your mailing address. -
-
- How do I use the two tubes provided in the kit? Which is my saliva swab? -
- Each tube provided in your kit is meant to be used for taking either a fecal and saliva sample (i.e. one sample type per tube). For the fecal sample, you will take the swabs, collect a sample, and place the swabs in the tube. For the saliva sample, you will spit inside the tube. Check the instruction brochure for detailed steps. -
-
- Why is there an extra set of swabs? -
- Please only use one set of swabs to take your fecal sample. The additional set was a packaging error and does not need to be used. -
-
- How do I take 2mL of saliva? -
- As the tubes do not currently have a mark for 2mL, please estimate this by filling up the tube about less than halfway with your saliva. -
-
- I took a different sample type than what was requested. -
- If only one of your samples was the incorrect sample type, - please proceed with sending them back. While we may not - process your sample immediately, there will be follow-ups as - part of the project, so we will collect additional samples at a - later point in time. -
-
- Where is the FedEx shipping label for pickup? -
- For CTS participants: If your Microsetta kit DID NOT contain a shipping label, please - visit this website and provide the requested information to - schedule your kit pick-up: https://microsetta.ucsd.edu/pickup. - FedEx will handle providing the proper labels when picking up - your kit. -
- If your Microsetta kit DID contain a shipping label, please - schedule a FedEx pickup by calling 1-800-463-3339, or drop off - your box with a FedEx center. -
-
- For LIBR participants: The shipping label should be pre-affixed - to the box. Please schedule a FedEx pickup by calling - 1-800-463-3339, or drop off your box with a FedEx center. -

-

-
-
-
- -
-{% endblock %} diff --git a/microsetta_interface/templates/home.jinja2 b/microsetta_interface/templates/home.jinja2 index 214601be..706292d0 100644 --- a/microsetta_interface/templates/home.jinja2 +++ b/microsetta_interface/templates/home.jinja2 @@ -1,5 +1,5 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Home" %} +{% set page_title = _("Home") %} {% set show_breadcrumbs = False %} {% set hide_footer = True %} @@ -19,32 +19,32 @@ {% block content %}
- +
- +
-

Welcome!

+

{{ _('Welcome!') }}

- Already have an account?
- Welcome back! LOG IN + {{ _('Already have an account?') }}
+ {{ _('Welcome back!') }} {{ _('LOG IN') }}
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/microsetta_interface/templates/new_participant.jinja2 b/microsetta_interface/templates/new_participant.jinja2 index 745f090c..c6b01242 100644 --- a/microsetta_interface/templates/new_participant.jinja2 +++ b/microsetta_interface/templates/new_participant.jinja2 @@ -1,5 +1,5 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Consent" %} +{% set page_title = _("Consent") %} {% set show_breadcrumbs = True %} {% block head %} @@ -104,10 +104,10 @@ $("#7-12-div").hide(); $("#13-17-div").hide(); $("#18-plus-div").hide(); - disableInputOnSubmit("#0-6-form", "#0-6-submit_button", "Saving..."); - disableInputOnSubmit("#7-12-form", "#7-12-submit_button", "Saving..."); - disableInputOnSubmit("#13-17-form", "#13-17-submit_button", "Saving..."); - disableInputOnSubmit("#18-form", "#18-submit_button", "Saving..."); + disableInputOnSubmit("#0-6-form", "#0-6-submit_button", "{{ _('Saving...') }}"); + disableInputOnSubmit("#7-12-form", "#7-12-submit_button", "{{ _('Saving...') }}"); + disableInputOnSubmit("#13-17-form", "#13-17-submit_button", "{{ _('Saving...') }}"); + disableInputOnSubmit("#18-form", "#18-submit_button", "{{ _('Saving...') }}"); }); {% endblock %} {% block breadcrumb %} - + {% endblock %} {% block content%}

{{ tl['ADD_HUMAN_TITLE'] |e}}

@@ -150,7 +150,7 @@ @@ -194,14 +194,14 @@ - +
{{ tl['PARTICIPANT_PARENT_1'] |e}}: *
{{ tl['PARTICIPANT_PARENT_2'] |e}}: *
{{ tl['PARTICIPANT_DECEASED_PARENTS'] |e}}:
@@ -228,14 +228,14 @@ - +
{{ tl['PARTICIPANT_PARENT_1'] |e}}: *
{{ tl['PARTICIPANT_PARENT_2'] |e}}: *
{{ tl['PARTICIPANT_DECEASED_PARENTS'] |e}}:
@@ -248,7 +248,7 @@ diff --git a/microsetta_interface/templates/new_results_page.jinja2 b/microsetta_interface/templates/new_results_page.jinja2 index cf61a39e..629111a2 100644 --- a/microsetta_interface/templates/new_results_page.jinja2 +++ b/microsetta_interface/templates/new_results_page.jinja2 @@ -1,5 +1,5 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Sample Results" %} +{% set page_title = _("Sample Results") %} {% set show_breadcrumbs = show_breadcrumbs %} {% block head %} @@ -149,6 +149,7 @@ } .scatter-bg { + background-image: url('/static/img/scatter.png'); background: url('/static/img/scatter.png'); background-position: top 400px left 0px; background-size: 220px; @@ -211,6 +212,29 @@ + + + {% endblock %} {% block breadcrumb %} - + {% endblock %} {% block content %} {% if needs_assignment %} {% endif %} {% if samples|length > 0 %} - Samples (click on a barcode to provide collection information): + {{ _('Samples (click on a barcode to provide collection information)') }}:
- Barcode + {{ _('Barcode') }}
- Collection date + {{ _('Collection date') }}
{% if is_human %}
- Sample type + {{ _('Sample type') }}
- Results + {{ _('Results') }}
- Sample-specific survey + {{ _('Sample-specific survey') }}
{% endif %}
@@ -189,15 +189,15 @@
{% if sample.ffq and sample.ffq_status == 3 %} - View Top Food Report + {{ _('View Top Food Report') }} {% else %} - Food Frequency Questionnaire + {{ _('Food Frequency Questionnaire') }} {% endif %}
{% endif %} -
+
- +
@@ -207,11 +207,8 @@ {% endif %} {% if samples|length > 1 and is_human %}
- Do I need to take more than one Food Frequency Questionnaire (FFQ)? - If you are taking all of your samples at the same time, you will only need to complete one. - If you are collecting samples over time (e.g., once per week), then please consider taking an FFQ per - time point. The FFQs provide valuable dietary research data for the project, so researchers can better - understand the relationship between the food you eat and your microbes. + {{ _('Do I need to take more than one Food Frequency Questionnaire (FFQ)') }}? + {{ _('If you are taking all of your samples at the same time, you will only need to complete one. If you are collecting samples over time (e.g., once per week), then please consider taking an FFQ per time point. The FFQs provide valuable dietary research data for the project, so researchers can better understand the relationship between the food you eat and your microbes.') }} {% endif %} {% if samples|length > 0 %}
@@ -219,32 +216,32 @@
{% if claim_kit_name_hint is not none %} - + {% else %} - + {% endif %}
- +

- Select all samples that should be associated with this source + {{ _('Select all samples that should be associated with this source') }}

- +
{% if surveys|length > 0 %}
-

Surveys taken:

+

{{ _('Surveys taken') }}:

{% for survey in surveys %} @@ -270,9 +267,9 @@
-
+
- +
diff --git a/microsetta_interface/templates/survey.jinja2 b/microsetta_interface/templates/survey.jinja2 index adfc4970..0edf3554 100644 --- a/microsetta_interface/templates/survey.jinja2 +++ b/microsetta_interface/templates/survey.jinja2 @@ -1,11 +1,20 @@ {% extends "sitebase.jinja2" %} -{% set page_title = "Participant Survey" %} +{% set page_title = _("Participant Survey") %} {% set show_breadcrumbs = True %} {% block head %} +