aboutsummaryrefslogtreecommitdiff
path: root/gn2/wqflask/templates
diff options
context:
space:
mode:
authorAlexander_Kabui2024-01-02 13:21:07 +0300
committerAlexander_Kabui2024-01-02 13:21:07 +0300
commit70c4201b332e0e2c0d958428086512f291469b87 (patch)
treeaea4fac8782c110fc233c589c3f0f7bd34bada6c /gn2/wqflask/templates
parent5092eb42f062b1695c4e39619f0bd74a876cfac2 (diff)
parent965ce5114d585624d5edb082c710b83d83a3be40 (diff)
downloadgenenetwork2-70c4201b332e0e2c0d958428086512f291469b87.tar.gz
merge changes
Diffstat (limited to 'gn2/wqflask/templates')
-rw-r--r--gn2/wqflask/templates/admin/change_resource_owner.html114
-rw-r--r--gn2/wqflask/templates/admin/create_group.html84
-rw-r--r--gn2/wqflask/templates/admin/group_manager.html147
-rw-r--r--gn2/wqflask/templates/admin/ind_user_manager.html111
-rw-r--r--gn2/wqflask/templates/admin/manage_resource.html124
-rw-r--r--gn2/wqflask/templates/admin/manage_user.html79
-rw-r--r--gn2/wqflask/templates/admin/search_for_groups.html134
-rw-r--r--gn2/wqflask/templates/admin/set_group_privileges.html102
-rw-r--r--gn2/wqflask/templates/admin/user_manager.html41
-rw-r--r--gn2/wqflask/templates/admin/view_group.html270
-rw-r--r--gn2/wqflask/templates/authorisation_error.html19
-rw-r--r--gn2/wqflask/templates/base.html397
-rw-r--r--gn2/wqflask/templates/base_macro.html28
-rw-r--r--gn2/wqflask/templates/blogs.html12
-rw-r--r--gn2/wqflask/templates/blogs_list.html52
-rw-r--r--gn2/wqflask/templates/bnw_page.html7
-rw-r--r--gn2/wqflask/templates/case_attributes.html415
-rw-r--r--gn2/wqflask/templates/collections/add.html86
-rw-r--r--gn2/wqflask/templates/collections/add_anonymous.html21
-rw-r--r--gn2/wqflask/templates/collections/list.html189
-rw-r--r--gn2/wqflask/templates/collections/not_logged_in.html23
-rw-r--r--gn2/wqflask/templates/collections/remove.html48
-rw-r--r--gn2/wqflask/templates/collections/view.html483
-rw-r--r--gn2/wqflask/templates/collections/view_anonymous.html143
-rw-r--r--gn2/wqflask/templates/comparison_bar_chart.html38
-rw-r--r--gn2/wqflask/templates/corr_scatterplot.html364
-rw-r--r--gn2/wqflask/templates/correlation_error_page.html23
-rw-r--r--gn2/wqflask/templates/correlation_matrix.html203
-rw-r--r--gn2/wqflask/templates/correlation_page.html550
-rw-r--r--gn2/wqflask/templates/credits.html58
-rw-r--r--gn2/wqflask/templates/ctl_results.html77
-rw-r--r--gn2/wqflask/templates/ctl_setup.html70
-rw-r--r--gn2/wqflask/templates/data_sharing.html262
-rw-r--r--gn2/wqflask/templates/dataset.html107
-rw-r--r--gn2/wqflask/templates/display_diffs.html95
-rw-r--r--gn2/wqflask/templates/display_files.html131
-rw-r--r--gn2/wqflask/templates/docedit.html31
-rw-r--r--gn2/wqflask/templates/docs.html17
-rw-r--r--gn2/wqflask/templates/edit_case_attributes.html104
-rw-r--r--gn2/wqflask/templates/edit_history.html56
-rw-r--r--gn2/wqflask/templates/edit_phenotype.html279
-rw-r--r--gn2/wqflask/templates/edit_probeset.html282
-rw-r--r--gn2/wqflask/templates/email/forgot_password.txt5
-rw-r--r--gn2/wqflask/templates/empty_collection.html15
-rw-r--r--gn2/wqflask/templates/environment.html160
-rw-r--r--gn2/wqflask/templates/error.html61
-rw-r--r--gn2/wqflask/templates/facilities.html24
-rw-r--r--gn2/wqflask/templates/generif.html101
-rw-r--r--gn2/wqflask/templates/geneweaver_page.html35
-rw-r--r--gn2/wqflask/templates/genotype.html87
-rw-r--r--gn2/wqflask/templates/glossary.html23
-rw-r--r--gn2/wqflask/templates/gn3_ctl_results.html101
-rw-r--r--gn2/wqflask/templates/gn3_wgcna_results.html192
-rw-r--r--gn2/wqflask/templates/gnqa.html84
-rw-r--r--gn2/wqflask/templates/gnqa_answer.html174
-rw-r--r--gn2/wqflask/templates/gsearch_gene.html267
-rw-r--r--gn2/wqflask/templates/gsearch_pheno.html238
-rw-r--r--gn2/wqflask/templates/heatmap.html44
-rwxr-xr-xgn2/wqflask/templates/index_page.html397
-rw-r--r--gn2/wqflask/templates/info_page.html92
-rw-r--r--gn2/wqflask/templates/jobs/debug.html42
-rw-r--r--gn2/wqflask/templates/jobs/no-such-job.html13
-rw-r--r--gn2/wqflask/templates/jupyter_notebooks.html28
-rw-r--r--gn2/wqflask/templates/links.html24
-rw-r--r--gn2/wqflask/templates/list_case_attribute_diffs.html59
-rw-r--r--gn2/wqflask/templates/list_case_attribute_diffs_error.html37
-rw-r--r--gn2/wqflask/templates/loading.html133
-rw-r--r--gn2/wqflask/templates/loading_corrs.html28
-rw-r--r--gn2/wqflask/templates/mapping_error.html36
-rw-r--r--gn2/wqflask/templates/mapping_results.html698
-rw-r--r--gn2/wqflask/templates/marker_regression.html119
-rw-r--r--gn2/wqflask/templates/metadata/dataset.html157
-rw-r--r--gn2/wqflask/templates/network_graph.html152
-rw-r--r--gn2/wqflask/templates/new_security/forgot_password.html52
-rw-r--r--gn2/wqflask/templates/new_security/forgot_password_step2.html25
-rw-r--r--gn2/wqflask/templates/new_security/login_user.html119
-rw-r--r--gn2/wqflask/templates/new_security/not_authenticated.html11
-rw-r--r--gn2/wqflask/templates/new_security/password_reset.html78
-rw-r--r--gn2/wqflask/templates/new_security/register_user.html105
-rw-r--r--gn2/wqflask/templates/new_security/registered.html24
-rw-r--r--gn2/wqflask/templates/new_security/thank_you.html23
-rw-r--r--gn2/wqflask/templates/new_security/verification_still_needed.html26
-rw-r--r--gn2/wqflask/templates/news.html24
-rw-r--r--gn2/wqflask/templates/oauth2/create-resource.html89
-rw-r--r--gn2/wqflask/templates/oauth2/create-role.html46
-rw-r--r--gn2/wqflask/templates/oauth2/data-list-genotype.html166
-rw-r--r--gn2/wqflask/templates/oauth2/data-list-mrna.html168
-rw-r--r--gn2/wqflask/templates/oauth2/data-list-phenotype.html209
-rw-r--r--gn2/wqflask/templates/oauth2/data-list.html53
-rw-r--r--gn2/wqflask/templates/oauth2/display_error.html10
-rw-r--r--gn2/wqflask/templates/oauth2/group.html114
-rw-r--r--gn2/wqflask/templates/oauth2/group_join_or_create.html99
-rw-r--r--gn2/wqflask/templates/oauth2/join-requests.html73
-rw-r--r--gn2/wqflask/templates/oauth2/list_roles.html80
-rw-r--r--gn2/wqflask/templates/oauth2/login.html47
-rw-r--r--gn2/wqflask/templates/oauth2/masquerade.html39
-rw-r--r--gn2/wqflask/templates/oauth2/profile_nav.html64
-rw-r--r--gn2/wqflask/templates/oauth2/register_user.html62
-rw-r--r--gn2/wqflask/templates/oauth2/request_error.html32
-rw-r--r--gn2/wqflask/templates/oauth2/resources.html58
-rw-r--r--gn2/wqflask/templates/oauth2/role.html56
-rw-r--r--gn2/wqflask/templates/oauth2/view-group-role.html102
-rw-r--r--gn2/wqflask/templates/oauth2/view-resource.html352
-rw-r--r--gn2/wqflask/templates/oauth2/view-user.html48
-rw-r--r--gn2/wqflask/templates/pair_scan_results.html114
-rw-r--r--gn2/wqflask/templates/partial_correlations/pcorrs_error.html65
-rw-r--r--gn2/wqflask/templates/partial_correlations/pcorrs_poll_results.html19
-rw-r--r--gn2/wqflask/templates/partial_correlations/pcorrs_results_presentation.html261
-rw-r--r--gn2/wqflask/templates/partial_correlations/pcorrs_results_with_target_traits.html115
-rw-r--r--gn2/wqflask/templates/partial_correlations/pcorrs_select_operations.html167
-rw-r--r--gn2/wqflask/templates/pca_scree_plot.html85
-rw-r--r--gn2/wqflask/templates/phenotype.html136
-rw-r--r--gn2/wqflask/templates/policies.html23
-rw-r--r--gn2/wqflask/templates/publication.html62
-rw-r--r--gn2/wqflask/templates/references.html19
-rw-r--r--gn2/wqflask/templates/search_autocomplete.html249
-rw-r--r--gn2/wqflask/templates/search_error.html20
-rw-r--r--gn2/wqflask/templates/search_history.html297
-rw-r--r--gn2/wqflask/templates/search_result_page.html453
-rw-r--r--gn2/wqflask/templates/set_group_privileges.html77
-rw-r--r--gn2/wqflask/templates/show_image.html5
-rw-r--r--gn2/wqflask/templates/show_trait.html276
-rw-r--r--gn2/wqflask/templates/show_trait_calculate_correlations.html165
-rw-r--r--gn2/wqflask/templates/show_trait_details.html255
-rw-r--r--gn2/wqflask/templates/show_trait_edit_data.html75
-rw-r--r--gn2/wqflask/templates/show_trait_error.html20
-rwxr-xr-xgn2/wqflask/templates/show_trait_mapping_tools.html436
-rw-r--r--gn2/wqflask/templates/show_trait_progress_bar.html35
-rw-r--r--gn2/wqflask/templates/show_trait_statistics.html106
-rw-r--r--gn2/wqflask/templates/show_trait_transform_and_filter.html140
-rw-r--r--gn2/wqflask/templates/snp_browser.html582
-rw-r--r--gn2/wqflask/templates/startup_errors.html20
-rw-r--r--gn2/wqflask/templates/submit_trait.html111
-rw-r--r--gn2/wqflask/templates/test_correlation_page.html159
-rw-r--r--gn2/wqflask/templates/tool_buttons.html38
-rw-r--r--gn2/wqflask/templates/tutorials.html256
-rw-r--r--gn2/wqflask/templates/view_case_attribute_diff.html117
-rw-r--r--gn2/wqflask/templates/view_case_attribute_diff_error.html35
-rw-r--r--gn2/wqflask/templates/webgestalt_page.html35
-rw-r--r--gn2/wqflask/templates/wgcna_results.html76
-rw-r--r--gn2/wqflask/templates/wgcna_setup.html142
-rw-r--r--gn2/wqflask/templates/with-trait-items.html18
142 files changed, 17220 insertions, 0 deletions
diff --git a/gn2/wqflask/templates/admin/change_resource_owner.html b/gn2/wqflask/templates/admin/change_resource_owner.html
new file mode 100644
index 00000000..7fd84387
--- /dev/null
+++ b/gn2/wqflask/templates/admin/change_resource_owner.html
@@ -0,0 +1,114 @@
+{% extends "base.html" %}
+{% block title %}Resource Manager{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div class="container">
+ <div class="page-header">
+ <h1>Search for user to assign ownership to:</h1>
+ </div>
+ <form id="change_owner_form" action="/resource-management/resources/{{ resource_id }}/change-owner" method="POST">
+ <div style="min-width: 600px; max-width: 800px;">
+ <fieldset>
+ <div class="form-horizontal" style="width: 900px;">
+ <div style="margin-bottom: 30px;">
+ <h2>Search for user by either name or e-mail:</h2>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="user_name" class="col-xs-3" style="float: left; font-size: 18px;">User's Name:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <input name="user_name" type="text" value="">
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="user_email" class="col-xs-3" style="float: left; font-size: 18px;">User's E-mail:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <input name="user_email" type="text" value="">
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label class="col-xs-3" style="float: left; font-size: 18px;"></label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <button type="button" id="find_users" class="btn btn-primary">Search</button>
+ <button style="margin-left: 20px; display: none;" type="submit" id="submit_new_owner" class="btn btn-success">Assign Ownership to Selected User</button>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+ <hr>
+ <div id="user_results">
+ </div>
+ </div>
+ </form>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+
+ <script language="javascript">
+ $('#find_users').click(function() {
+ $.ajax({
+ method: "POST",
+ url: "/resource-management/{{ resource_id }}/users/search",
+ data: {
+ user_name: $('input[name=user_name]').val(),
+ user_email: $('input[name=user_email]').val()
+ },
+ success: populate_users
+ });
+ })
+
+ populate_users = function(json_user_list){
+ let user_list = JSON.parse(json_user_list)
+ let searchResultsHtml = ""
+ if (user_list.length > 0){
+ searchResultsHtml += "<table id='users_table' style='padding-top: 10px; width: 100%;' class='table-hover table-striped cell-border'>";
+ searchResultsHtml += "<thead><tr><th></th><th>Index</th><th>Name</th><th>E-mail Address</th><th>Organization</th></tr></thead>";
+ searchResultsHtml += "<tbody>";
+ for (_i = 0, _len = user_list.length; _i < _len; _i++) {
+ this_user = user_list[_i]
+ searchResultsHtml += "<tr>";
+ searchResultsHtml += "<td align='center' class='select_user'><input type='radio' name='new_owner' value='" + this_user.user_id + "'></td>";
+ searchResultsHtml += "<td>" + (_i + 1).toString() + "</td>"
+ if ("full_name" in this_user) {
+ searchResultsHtml += "<td>" + this_user.full_name + "</td>";
+ } else {
+ searchResultsHtml += "<td>N/A</td>"
+ }
+ if ("email_address" in this_user) {
+ searchResultsHtml += "<td>" + this_user.email_address + "</td>";
+ } else {
+ searchResultsHtml += "<td>N/A</td>"
+ }
+ if ("organization" in this_user) {
+ searchResultsHtml += "<td>" + this_user.organization + "</td>";
+ } else {
+ searchResultsHtml += "<td>N/A</td>"
+ }
+ searchResultsHtml += "</tr>"
+ }
+ searchResultsHtml += "</tbody>";
+ searchResultsHtml += "</table>";
+ } else {
+ searchResultsHtml = "<span>No users were found matching the entered criteria.</span>"
+ }
+
+ $('#user_results').html(searchResultsHtml)
+ if (user_list.length > 0){
+ $('#users_table').dataTable({
+ 'order': [[1, "asc" ]],
+ 'sDom': 'tr'
+ });
+ $('input[name=select_user]:eq(0)').prop("checked", true)
+ $('#submit_new_owner').css("display", "inline-block")
+ }
+ }
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/admin/create_group.html b/gn2/wqflask/templates/admin/create_group.html
new file mode 100644
index 00000000..b1d214ea
--- /dev/null
+++ b/gn2/wqflask/templates/admin/create_group.html
@@ -0,0 +1,84 @@
+{% extends "base.html" %}
+{% block title %}Group Manager{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div class="container">
+ <div class="page-header">
+ <h1>Create Group</h1>
+ </div>
+ <form action="{{ url_for('group_management.create_new_group') }}"
+ method="POST">
+ <input type="hidden" name="admin_emails_to_add" value="">
+ <input type="hidden" name="member_emails_to_add" value="">
+ <fieldset>
+ <div class="form-horizontal" style="width: 900px; margin-bottom: 50px;">
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="group_name" class="col-xs-3" style="float: left; font-size: 18px;">Group Name:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <div class="col-xs-12">
+ <input name="group_name" type="text" style="width:100%;"></input>
+ </div>
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="user_email" class="col-xs-3" style="float: left; font-size: 18px;">Add User Email:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <div class="col-xs-12">
+ <input name="user_email" type="text" style="width:100%;"></input>
+ </div>
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label class="col-xs-3"></label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <div class="col-xs-6">
+ <button type="button" id="add_to_admins" class="btn btn-default">Add to Admins</button>
+ </div>
+ <div class="col-xs-6">
+ <button type="button" id="add_to_members" class="btn btn-default">Add to Members</button>
+ </div>
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label class="col-xs-3" style="font-size: 18px;">Members to be added:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <div class="col-xs-6">
+ <textarea rows="8" cols="60" readonly placeholder="No users added" style="overflow-y: scroll; resize: none; width: 200px;" class="added_admins"></textarea>
+ </div>
+ <div class="col-xs-6">
+ <textarea rows="8" cols="60" readonly placeholder="No users added" style="overflow-y: scroll; resize: none; width: 200px;" class="added_members"></textarea>
+ </div>
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label class="col-xs-3"></label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <div class="col-xs-6">
+ <button type="button" id="clear_admins" class="btn btn-default">Clear</button>
+ </div>
+ <div class="col-xs-6">
+ <button type="button" id="clear_members" class="btn btn-default">Clear</button>
+ </div>
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="create_group" class="col-xs-3" style="float: left; font-size: 18px;"></label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <div class="col-xs-6">
+ <button type="submit" id="create_group" class="btn btn-primary">Create Group</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+ </form>
+ </div>
+
+<!-- End of body -->
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/group_manager.js"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/admin/group_manager.html b/gn2/wqflask/templates/admin/group_manager.html
new file mode 100644
index 00000000..eedfe138
--- /dev/null
+++ b/gn2/wqflask/templates/admin/group_manager.html
@@ -0,0 +1,147 @@
+{% extends "base.html" %}
+{% block title %}Group Manager{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div class="container">
+ <div class="page-header">
+ <h1>Manage Groups</h1>
+ {% if admin_groups|length != 0 or member_groups|length != 0 %}
+ <div style="display: inline;">
+ <a href="{{ url_for('group_management.view_create_group_page') }}" target="_blank">
+ <button type="button" class="btn btn-primary">
+ Create Group
+ </button>
+ </a>
+ <button type="button" id="remove_groups" class="btn btn-primary"
+ data-url="{{ url_for('group_management.delete_groups') }}">
+ Remove Selected Groups
+ </button>
+ </div>
+ {% endif %}
+ </div>
+ <form id="groups_form" action="/groups/manage" method="POST">
+ <input type="hidden" name="selected_group_ids" value="">
+ <div style="min-width: 800px; max-width: 1000px;">
+ {% if admin_groups|length == 0 and member_groups|length == 0 %}
+ <h4>You currently aren't a member or admin of any groups.</h4>
+ <br>
+ <a href="{{ url_for('group_management.view_create_group_page') }}" target="_blank">
+ <button type="button" class="btn btn-primary">
+ Create Group
+ </button>
+ </a>
+ {% else %}
+ <div style="margin-top: 20px;"><h2>Admin Groups</h2></div>
+ <hr>
+ {% if admin_groups|length == 0 %}
+ <h4>You currently aren't the administrator of any groups.</h4>
+ {% else %}
+ <table id="admin_groups" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Name</th>
+ <th># Members</th>
+ <th>Created</th>
+ <th>Last Changed</th>
+ <th>Group ID</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for group in admin_groups %}
+ <tr>
+ <td><input type="checkbox" name="group_id" value="{{ group.id }}"></td>
+ <td align="right">{{ loop.index }}</td>
+ {% set group_url = url_for('group_management.view_group', group_id=group.uuid) %}
+ <td><a href="{{ group_url }}">{{ group.name }}</a></td>
+ <td align="right">{{ group.admins|length + group.members|length }}</td>
+ <td>{{ group.created_timestamp }}</td>
+ <td>{{ group.changed_timestamp }}</td>
+ <td>{{ group.uuid }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+ </div>
+ <hr>
+ <div style="min-width: 800px; max-width: 1000px;">
+ <div><h2>User Groups</h2></div>
+ <hr>
+ {% if member_groups|length == 0 %}
+ <h4>You currently aren't a member of any groups.</h4>
+ {% else %}
+ <table id="member_groups" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Name</th>
+ <th># Members</th>
+ <th>Created</th>
+ <th>Last Changed</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for group in member_groups %}
+ <tr>
+ <td><input type="checkbox" name="read" value="{{ group.id }}"></td>
+ <td>{{ loop.index }}</td>
+ {% set group_url = url_for('group_management.view_group', group_id=group.uuid) %}
+ <td><a href="{{ group_url }}">{{ group.name }}</a></td>
+ <td>{{ group.admins|length + group.members|length }}</td>
+ <td>{{ group.created_timestamp }}</td>
+ <td>{{ group.changed_timestamp }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+ {% endif %}
+ </div>
+ </form>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+
+ <script type="text/javascript" charset="utf-8">
+ $(document).ready( function () {
+ {% if admin_groups|length != 0 %}
+ $('#admin_groups').dataTable({
+ 'sDom': 'tr'
+ });
+ {% endif %}
+ {% if member_groups|length != 0 %}
+ $('#member_groups').dataTable({
+ 'sDom': 'tr'
+ });
+ {% endif %}
+ submit_special = function(url) {
+ $("#groups_form").attr("action", url);
+ return $("#groups_form").submit();
+ };
+
+ $("#remove_groups").on("click", function() {
+ url = $(this).data("url")
+ groups = []
+ $("input[name=group_id]:checked").each(function() {
+ groups.push($(this).val());
+ });
+ groups_string = groups.join(":")
+ $("input[name=selected_group_ids]").val(groups_string)
+ return submit_special(url)
+ });
+ });
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/admin/ind_user_manager.html b/gn2/wqflask/templates/admin/ind_user_manager.html
new file mode 100644
index 00000000..b821e5d5
--- /dev/null
+++ b/gn2/wqflask/templates/admin/ind_user_manager.html
@@ -0,0 +1,111 @@
+{% extends "base.html" %}
+{% block title %}User Manager{% endblock %}
+{% block content %}
+<!-- Start of body -->
+
+ <div class="container">
+ <div class="page-header">
+ <h1 title="{{ user.id }}">{{ user.email_address }}</h1>
+
+ <span class="badge">{{ numify(user.login_count, "login", "logins").capitalize() }}</span>
+
+ {% if user.active %}
+ <span class="label label-success">Active</span>
+ {% else %}
+ <span class="label label-warning">Inactive</span>
+ {% endif %}
+ </div>
+
+ {{ flash_me() }}
+
+ <table class="table table-hover">
+<!-- <thead>
+ <tr>
+ <th>Field</th>
+ <th>Value</th>
+ </tr>
+ </thead>-->
+
+ <tr>
+ <td>Name</td>
+ <td>{{ user.full_name }}</td>
+ </tr>
+
+ <tr>
+ <td>Organization</td>
+ <td>{{ user.organization }}</td>
+ </tr>
+
+
+ <tr>
+ <td>Confirmed</td>
+
+ {% if user.confirmed_at %}
+ <td>{{ timeago(user.confirmed_at + "Z") }}</td>
+ {% else %}
+ <td><span class="label label-warning">Unconfirmed</span></td>
+ {% endif %}
+ </tr>
+
+ <tr>
+ <td>Superuser</td>
+
+ {% if user.superuser %}
+ <td>Made a superuser {{ timeago(user.superuser_info['timestamp'] + "Z") }} by
+ {{ user.crowner.name_and_org }}.
+ </td>
+ {% else %}
+ <td>
+ <span>
+ <a class="btn btn-danger btn-small" href={{"/manage/make_superuser?user_id={}".format(user.id)}}>
+ Make Superuser
+ </a>
+ </span>
+ </td>
+ {% endif %}
+ </tr>
+
+
+ <tr>
+ <td>Most recent login</td>
+ {% if user.most_recent_login %}
+ <td>{{ timeago(user.most_recent_login.timestamp.isoformat() + "Z") }} from {{ user.most_recent_login.ip_address }}</td>
+ {% else %}
+ <td><span class="label label-warning">Never</span></td>
+ {% endif %}
+ </tr>
+
+<!-- <tr>
+ <td>Last login</td>
+ <td>{{ user.last_login_at }} from {{ user.last_login_ip }}</td>
+ </tr>
+-->
+ <!-- <tr>
+ <td>Number of logins</td>
+ <td>{{ user.login_count }}</td>
+ </tr>-->
+ <tr>
+ <td colspan="2">
+ <a class="btn btn-danger btn-small" href={{"/manage/assume_identity?user_id={}".format(user.id)}}>
+ Become this user for debugging
+ </a>
+ </td>
+ </tr>
+
+ </table>
+
+
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/timeago.min.js') }}"></script>
+ <script>
+ $('body').timeago();
+ </script>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/admin/manage_resource.html b/gn2/wqflask/templates/admin/manage_resource.html
new file mode 100644
index 00000000..63ec17c0
--- /dev/null
+++ b/gn2/wqflask/templates/admin/manage_resource.html
@@ -0,0 +1,124 @@
+{% extends "base.html" %}
+{% block title %}Resource Manager{% endblock %}
+{% block content %}
+<!-- Start of body -->
+<div class="container">
+ <section>
+ {{ flash_me() }}
+ {% set DATA_ACCESS = access_role.get('data') %}
+ {% set METADATA_ACCESS = access_role.get('metadata') %}
+ {% set ADMIN_STATUS = access_role.get('admin') %}
+ {% set ADMIN_STATUS = access_role.get('admin') %}
+ <h1>Resource Manager</h1>
+ {% if resource_info.get('owner_id') %}
+ {% set user_details = resource_info.get('owner_details') %}
+ <h3>
+ Current Owner: {{ user_details.get('full_name') }}
+ </h3>
+ {% if user_details.get('organization') %}
+ <h3>
+ Organization: {{ user_details.get('organization')}}
+ </h3>
+ {% endif %}
+ {% endif %}
+ {% if DATA_ACCESS > DataRole.VIEW and ADMIN_STATUS > AdminRole.NOT_ADMIN %}
+ <a class="btn btn-danger" target="_blank"
+ href="/resource-management/resources/{{ resource_info.get('resource_id') }}/change-owner">
+ Change Owner
+ </a>
+ {% endif %}
+ </section>
+
+ <section class="container" style="margin-top: 2em;">
+ <form class="container-fluid" action="/resource-management/resources/{{ resource_info.get('resource_id') }}/make-public" method="POST">
+ <input type="hidden" name="resource_id" value="{{ resource_info.get('resource_id') }}">
+ <div>
+ <fieldset>
+ <div class="form-horizontal" style="width: 900px; margin-bottom: 50px;">
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="group_name" class="col-xs-3" style="float: left; font-size: 18px;">Resource Name:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ {{ resource_info.get('name') }}
+ </div>
+ </div>
+ {% if DATA_ACCESS > DataRole.VIEW and ADMIN_STATUS > AdminRole.NOT_ADMIN %}
+ {% set is_open_to_public = DataRole(resource_info.get('default_mask').get('data')) > DataRole.NO_ACCESS %}
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="user_email" class="col-xs-3" style="float: left; font-size: 18px;">Open to Public:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <label class="radio-inline">
+ <input type="radio" name="open_to_public" value="True" {{ 'checked' if is_open_to_public }}>
+ Yes
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="open_to_public" value="False" {{ 'checked' if not is_open_to_public }}>
+ No
+ </label>
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label class="col-xs-3" style="float: left; font-size: 18px;"></label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <button id="save_changes" class="btn btn-primary" data-url="/resource-management/resources/change_default_privileges">Save Changes</button>
+ </div>
+ </div>
+ {% endif %}
+ </div>
+ </fieldset>
+ </div>
+ {% if ADMIN_STATUS > AdminRole.NOT_ADMIN %}
+ <div style="min-width: 600px; max-width: 800px;">
+ <hr>
+ <button id="add_group_to_resource" class="btn btn-primary" style="margin-bottom: 30px;" data-url="/resources/add_group">Add Group</button>
+ <br>
+ {% if resource_info.get('group_masks', [])|length > 0 %}
+ <h2>Current Group Permissions</h2>
+ <hr>
+ <table id="groups_table" class="table table-hover table-striped cell-border">
+ <thead>
+ <tr>
+ <th>Id</th>
+ <th>Name</th>
+ <th>Data</th>
+ <th>Metadata</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for key, value in resource_info.get('group_masks').items() %}
+ <tr>
+ <td>{{ key }}</td>
+ <td>{{ value.group_name}}</td>
+ <td>{{ value.data }}</td>
+ <td>{{ value.metadata }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% else %}
+ <h3>No groups are currently added to this resource.</h3>
+ {% endif %}
+ </div>
+ {% endif %}
+ </form>
+ </section>
+
+ <!-- End of body -->
+
+ {% endblock %}
+ {% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+
+ <script type="text/javascript" charset="utf-8">
+ $('#add_group_to_resource, #save_changes, #change_owner').click(function(){
+ url = $(this).data("url");
+ $('#manage_resource').attr("action", url)
+ $('#manage_resource').submit()
+ })
+
+ {% if group_masks|length > 0 %}
+ $('#groups_table').dataTable({
+ 'sDom': 'tr',
+ });
+ {% endif %}
+ </script>
+ {% endblock %}
diff --git a/gn2/wqflask/templates/admin/manage_user.html b/gn2/wqflask/templates/admin/manage_user.html
new file mode 100644
index 00000000..3ef90b90
--- /dev/null
+++ b/gn2/wqflask/templates/admin/manage_user.html
@@ -0,0 +1,79 @@
+{% extends "base.html" %}
+{% block title %}View and Edit Group{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div class="container">
+ {% if 'full_name' in user_details %}
+ <div class="page-header">
+ <h1>User details for: {{ user_details.full_name }}</h1>
+ </div>
+ {% endif %}
+ <form id="user_form" action="/user/manage" method="POST">
+ <div class="row">
+ <div id="user_info_div" class="col-xs-8" style="margin-right: 30px; min-width: 800px; max-width: 1000px;">
+ <div class="form-horizontal">
+ <div class="form-group">
+ <label for="email_address" style="text-align: left;" class="col-xs-2">Email Address:</label>
+ <div style="margin-left: 20px; text-align: left;" class="col-xs-2 controls">
+ <span id="email_address">{% if 'email_address' in user_details %}{{ user_details.email_address }}{% else %}N/A{% endif %}</span>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="full_name" style="text-align: left;" class="col-xs-2">User Name:</label>
+ <div style="margin-left: 20px; text-align: left;" class="col-xs-2 controls">
+ <span id="full_name" class="old_user_attribute">{% if 'full_name' in user_details %}{{ user_details.full_name }}{% else %}N/A{% endif %}</span>
+ <input type="text" name="new_full_name" style="display: none; width: 500px;" class="form-control new_user_attribute" placeholder="{% if 'full_name' in user_details %}{{ user_details.full_name }}{% else %}N/A{% endif %}">
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="organization" style="text-align: left;" class="col-xs-2">Organization:</label>
+ <div style="margin-left: 20px; text-align: left;" class="col-xs-2 controls">
+ <span id="organization" class="old_user_attribute">{% if 'organization' in user_details %}{{ user_details.organization }}{% else %}N/A{% endif %}</span>
+ <input type="text" name="new_organization" style="display: none; width: 500px;" class="form-control new_user_attribute" placeholder="{% if 'organization' in user_details %}{{ user_details.organization }}{% else %}N/A{% endif %}">
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="change_user_details" style="text-align: left;" class="col-xs-2"></label>
+ <div style="margin-left: 20px; text-align: left;" class="col-xs-2 controls">
+ <input type="button" id="change_user_details" value="Change Details">
+ <input type="button" id="save_changes" value="Save Changes" style="display: none;">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+
+ <script type="text/javascript" charset="utf-8">
+ $(document).ready( function () {
+ $('#change_user_details').click(function(){
+ $('.new_user_attribute').css("display", "inline-block");
+ $('.old_user_attribute').css("display", "none");
+ $('#change_user_details').css("display", "none");
+ $('#save_changes').css("display", "inline-block");
+ });
+
+ $('#save_changes').click(function(){
+ $('.new_user_attribute').each(function(){
+ if ($(this).val() == ""){
+ $(this).val($(this).attr("placeholder"))
+ }
+ });
+ $('#user_form').submit();
+ });
+ });
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/admin/search_for_groups.html b/gn2/wqflask/templates/admin/search_for_groups.html
new file mode 100644
index 00000000..0e1ec720
--- /dev/null
+++ b/gn2/wqflask/templates/admin/search_for_groups.html
@@ -0,0 +1,134 @@
+{% extends "base.html" %}
+{% block title %}Resource Manager{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div class="container">
+ <div class="page-header">
+ <h1>Find Groups</h1>
+ </div>
+ <form id="add_group" action="/resources/add_group" method="POST">
+ <input type="hidden" name="resource_id" value="{{ resource_id }}">
+ <div style="min-width: 600px; max-width: 800px;">
+ <fieldset>
+ <div class="form-horizontal" style="width: 900px;">
+ <div style="margin-bottom: 30px;">
+ <h2>Search by:</h2>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="group_name" class="col-xs-3" style="float: left; font-size: 18px;">Group ID:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <input name="group_id" type="text" value="">
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="group_name" class="col-xs-3" style="float: left; font-size: 18px;">Group Name:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <input name="group_name" type="text" value="">
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="user_name" class="col-xs-3" style="float: left; font-size: 18px;">User Name:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <input name="user_name" type="text" value="">
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label for="user_email" class="col-xs-3" style="float: left; font-size: 18px;">User E-mail:</label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <input name="user_email" type="text" value="">
+ </div>
+ </div>
+ <div class="form-group" style="padding-left: 20px;">
+ <label class="col-xs-3" style="float: left; font-size: 18px;"></label>
+ <div class="controls input-append col-xs-9" style="display: flex; padding-left: 20px; float: left;">
+ <button type="button" id="find_groups" class="btn btn-primary">Search</button>
+ <button style="margin-left: 20px; display: none;" type="submit" id="submit_group" class="btn btn-success">Add Privileges for Selected Group</button>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+ <hr>
+ <div id="group_results">
+ </div>
+ </div>
+ </form>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/group_manager.js"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+
+ <script type="text/javascript" charset="utf-8">
+
+ $('#find_groups').click(function() {
+ $.ajax({
+ method: "POST",
+ url: "/search_for_groups",
+ data: {
+ group_id: $('input[name=group_id]').val(),
+ group_name: $('input[name=group_name]').val(),
+ user_name: $('input[name=user_name]').val(),
+ user_email: $('input[name=user_email]').val()
+ },
+ success: populate_groups
+ });
+ })
+
+ populate_groups = function(json_group_list){
+ console.log(json_group_list)
+ var group_list = JSON.parse(json_group_list)
+
+ var the_html = ""
+ if (group_list.length > 0){
+ the_html += "<table id='groups_table' style='padding-top: 10px; width: 100%;' class='table-hover table-striped cell-border'>";
+ the_html += "<thead><tr><th></th><th>Index</th><th>Name</th><th># Admins</th><th># Members</th></tr></thead>";
+ the_html += "<tbody>";
+ for (_i = 0, _len = group_list.length; _i < _len; _i++) {
+ this_group = group_list[_i]
+ the_html += "<tr>";
+ the_html += "<td align='center' class='select_group'><input type='radio' name='selected_group' value='" + this_group.id + "'></td>";
+ the_html += "<td>" + (_i + 1).toString() + "</td>"
+ if ("name" in this_group) {
+ the_html += "<td>" + this_group.name + "</td>";
+ } else {
+ the_html += "<td>N/A</td>"
+ }
+ if ("admins" in this_group) {
+ the_html += "<td>" + this_group.admins.length + "</td>";
+ } else {
+ the_html += "<td>0</td>"
+ }
+ if ("members" in this_group) {
+ the_html += "<td>" + this_group.members.length + "</td>";
+ } else {
+ the_html += "<td>0</td>"
+ }
+ the_html += "</tr>"
+ }
+ the_html += "</tbody>";
+ the_html += "</table>";
+ } else {
+ the_html = "<span>No groups were found matching the entered criteria.</span>"
+ }
+
+ $('#group_results').html(the_html)
+ if (group_list.length > 0){
+ $('#groups_table').dataTable({
+ 'order': [[1, "asc" ]],
+ 'sDom': 'tr'
+ });
+ $('input[name=selected_group]:eq(0)').prop("checked", true)
+ $('#submit_group').css("display", "inline-block")
+ }
+ }
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/admin/set_group_privileges.html b/gn2/wqflask/templates/admin/set_group_privileges.html
new file mode 100644
index 00000000..04842453
--- /dev/null
+++ b/gn2/wqflask/templates/admin/set_group_privileges.html
@@ -0,0 +1,102 @@
+{% extends "base.html" %}
+{% block title %}Set Group Privileges{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div class="container">
+ <h1>Group Privileges</h1>
+ <br>
+ <form id="set_group_privileges" action="/resources/add_group" method="POST">
+ <input type="hidden" name="resource_id" value="{{ resource_id }}">
+ <input type="hidden" name="group_id" value="{{ group_id }}">
+ <div style="min-width: 600px; max-width: 800px;">
+ <button type="submit" class="btn btn-primary" style="margin-bottom: 10px;">Add Group</button>
+ <hr>
+ <h2>Data and Metadata Privileges</h2>
+ <table id="data_privileges_table" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>No-Access</th>
+ <th>View</th>
+ <th>Edit</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Data:</td>
+ {% if 'data' in default_privileges %}
+ <td align="center" style="padding: 0px;"><input type="radio" name="data_privilege" VALUE="no-access" {% if default_privileges.data == "no-access" %}checked{% endif %}></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="data_privilege" VALUE="view" {% if default_privileges.data == "view" %}checked{% endif %}></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="data_privilege" VALUE="edit" {% if default_privileges.data == "edit" %}checked{% endif %}></td>
+ {% else %}
+ <td align="center" style="padding: 0px;"><input type="radio" name="data_privilege" VALUE="no-access" checked></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="data_privilege" VALUE="view"></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="data_privilege" VALUE="edit"></td>
+ {% endif %}
+ </tr>
+ <tr>
+ <td>Metadata:</td>
+ {% if 'metadata' in default_privileges %}
+ <td align="center" style="padding: 0px;"><input type="radio" name="metadata_privilege" VALUE="no-access" {% if default_privileges.metadata == "no-access" %}checked{% endif %}></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="metadata_privilege" VALUE="view" {% if default_privileges.metadata == "view" %}checked{% endif %}></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="metadata_privilege" VALUE="edit" {% if default_privileges.metadata[-1] == "edit" %}checked{% endif %}></td>
+ {% else %}
+ <td align="center" style="padding: 0px;"><input type="radio" name="metadata_privilege" VALUE="no-access" checked></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="metadata_privilege" VALUE="view"></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="metadata_privilege" VALUE="edit"></td>
+ {% endif %}
+ </tr>
+ </tbody>
+ </table>
+ <hr>
+ <h2>Admin Privileges</h2>
+ <table id="admin_privileges_table" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Not Admin</th>
+ <th>Edit Access</th>
+ <th>Edit Admins</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Admin:</td>
+ {% if 'admin' in default_privileges %}
+ <td align="center" style="padding: 0px;"><input type="radio" name="admin_privilege" VALUE="not-admin" {% if default_privileges.admin == "not-admin" %}checked{% endif %}></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="admin_privilege" VALUE="edit-access" {% if default_privileges.admin == "edit-access" %}checked{% endif %}></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="admin_privilege" VALUE="edit-admins" {% if default_privileges.admin == "edit-admins" %}checked{% endif %}></td>
+ {% else %}
+ <td align="center" style="padding: 0px;"><input type="radio" name="admin_privilege" VALUE="not-admin" checked></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="admin_privilege" VALUE="edit-access"></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="admin_privilege" VALUE="edit-admins"></td>
+ {% endif %}
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </form>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script>
+ $('#data_privileges_table').dataTable({
+ 'sDom': 'tr',
+ 'bSort': false
+ });
+ $('#admin_privileges_table').dataTable({
+ 'sDom': 'tr',
+ 'bSort': false
+ });
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/admin/user_manager.html b/gn2/wqflask/templates/admin/user_manager.html
new file mode 100644
index 00000000..2b6c1b2b
--- /dev/null
+++ b/gn2/wqflask/templates/admin/user_manager.html
@@ -0,0 +1,41 @@
+{% extends "base.html" %}
+{% block title %}User Manager{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ {{ header("List of users", "" )}}
+
+
+ <div class="container">
+ <div class="page-header">
+ <h1>User Manager</h1>
+ </div>
+
+ <table class="table table-hover">
+ <thead>
+ <tr>
+ <th>Email</th>
+ <th>Organization</th>
+ <th>Active</th>
+ <th>Confirmed</th>
+ <th>Superuser</th>
+ </tr>
+ </thead>
+ {% for user in users %}
+ <tr>
+ <td title="{{ user.id }}">
+ <a href="{{ url_for('manage_user', user_id=user.id) }}">{{ user.email_address }}</a>
+ </td>
+ <td>{{ user.organization }}</td>
+ <td>{{ 'Yes' if user.active else 'No' }}</td>
+ <td title="{{ user.confirmed }}">{{ 'True' if user.confirmed else 'False' }}</td>
+ <td title="{{ user.superuser }}">{{ 'True' if user.superuser else 'False' }}</td>
+ </tr>
+ {% endfor %}
+ </table>
+
+
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/admin/view_group.html b/gn2/wqflask/templates/admin/view_group.html
new file mode 100644
index 00000000..c88ce0e7
--- /dev/null
+++ b/gn2/wqflask/templates/admin/view_group.html
@@ -0,0 +1,270 @@
+{% extends "base.html" %}
+{% block title %}View and Edit Group{% endblock %}
+{% block css %}
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+{% set GROUP_URL = url_for('group_management.view_group', group_id=group_info.guid) %}
+{% set UPDATE_GROUP_URL = url_for('group_management.update_group', group_id=group_info.guid) %}
+<div class="container">
+ <div class="page-header">
+ <h1>
+ <span id="group_name">Name: {{ group_info.name }}</span>
+ <input type="text" name="new_group_name" style="font-size: 20px; display: none; width: 500px;" class="form-control" placeholder="{{ group_info.name }}">
+ {% if is_admin %}
+ <button class="btn btn-default" style="display: inline;" id="change_group_name">Change Group Name</button>
+ {% endif %}
+ </h1>
+ {% if is_admin %}
+ <div style="display: inline;">
+ <button type="button" id="remove_users" class="btn btn-danger" data-url="/groups/remove_users">Remove Selected Users from Group</button>
+ </div>
+ {% endif %}
+ </div>
+ <form id="group_form" action="{{ UPDATE_GROUP_URL }}" method="POST">
+ <input type="hidden" name="group_id" value="{{ group_info.id }}">
+ <input type="hidden" name="selected_admin_ids" value="">
+ <input type="hidden" name="selected_member_ids" value="">
+ <div class="row">
+ <div id="groups_div" class="col-xs-6" style="margin-right: 30px; min-width: 600px; max-width: 800px;">
+ <div>
+ <div style="margin-top: 20px;"><h2>Admins</h2></div>
+ <hr>
+ <table id="group_admins" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Name</th>
+ <th>Email Address</th>
+ <th>Organization</th>
+ {% if is_admin %}
+ <th>UID</th>
+ {% endif %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for admin in admins %}
+ <tr>
+ <td style="text-align: center; padding: 0px 10px 2px 10px;"><input type="checkbox" name="admin_id" value="{{ admin.user_id }}"></td>
+ <td align="right">{{ loop.index }}</td>
+ <td>{% if 'full_name' in admin %}{{ admin.full_name }}{% elif 'name' in admin %}{{ admin.name }}{% else %}N/A{% endif %}</td>
+ <td>{% if 'email_address' in admin %}{{ admin.email_address }}{% else %}N/A{% endif %}</td>
+ <td>{% if 'organization' in admin %}{{ admin.organization }}{% else %}N/A{% endif %}</td>
+ {% if is_admin %}
+ <td>{{admin.user_id}}</td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% if is_admin %}
+ <div style="margin-top: 20px;">
+ <span>E-mail of user to add to admins (multiple e-mails can be added separated by commas):</span>
+ <input type="text" size="60" name="admin_emails_to_add" placeholder="Enter E-mail(s)" value="">
+ </div>
+ <div style="margin-bottom: 30px; margin-top: 20px;">
+ <button type="button" id="add_admins" class="btn btn-primary" data-usertype="admin" data-url="{{ UPDATE_GROUP_URL }}">Add Admin(s)</button>
+ </div>
+ {% endif %}
+ </div>
+ <hr>
+ <div>
+ {% if members|length > 0 %}
+ <div><h2>Members</h2></div>
+ <hr>
+ <table id="group_members" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Name</th>
+ <th>Email Address</th>
+ <th>Organization</th>
+ {% if is_admin %}
+ <th>UID</th>
+ {% endif %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for member in members %}
+ <tr>
+
+ <td style="text-align: center; padding: 0px 10px 2px 10px;">
+ {% if is_admin %}
+ <input type="checkbox" name="member_id" value="{{ member.user_id }}">
+ {% endif %}
+ </td>
+ <td align="right">{{ loop.index }}</td>
+ <td>{% if 'full_name' in member %}{{ member.full_name }}{% elif 'name' in admin %}{{ admin.name }}{% else %}N/A{% endif %}</td>
+ <td>{% if 'email_address' in member %}{{ member.email_address }}{% else %}N/A{% endif %}</td>
+ <td>{% if 'organization' in member %}{{ member.organization }}{% else %}N/A{% endif %}</td>
+ {% if is_admin %}
+ <td>{{ member }}</td>
+ {% endif %}
+
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% if is_admin %}
+ <div style="margin-top: 20px;">
+ <span>E-mail of user to add to members (multiple e-mails can be added separated by commas):</span>
+ <input type="text" size="60" name="member_emails_to_add" placeholder="Enter E-mail(s)" value="">
+ </div>
+ <div style="margin-bottom: 30px; margin-top: 20px;">
+ <button type="button" id="add_members" class="btn btn-primary" data-usertype="member" data-url="{{ GROUP_URL }}">Add Member(s)</button>
+ </div>
+ {% endif %}
+ {% else %}
+ There are currently no members in this group.
+ {% if is_admin %}
+ <div style="margin-top: 20px;">
+ <span>E-mail of user to add to members (multiple e-mails can be added separated by commas):</span>
+ <input type="text" size="60" name="member_emails_to_add" placeholder="Enter E-mail(s)" value="">
+ </div>
+ <div style="margin-bottom: 30px; margin-top: 20px;">
+ <button type="button" id="add_members" class="btn btn-primary" data-usertype="member" data-url="{{ GROUP_URL }}">Add Member(s)</button>
+ </div>
+ {% endif %}
+ {% endif %}
+ </div>
+ </div>
+ <div id="resources_div" class="col-xs-6" style="border-left: 1px solid #eee; margin-right: 30px; min-width: 600px; max-width: 800px;">
+ <div style="margin-top: 20px;"><h2>Resources</h2></div>
+ <hr>
+ {% if resources|length > 0 %}
+ <table id="resources" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th>Index</th>
+ <th>Name</th>
+ <th>Data</th>
+ <th>Metadata</th>
+ <th>Admin</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for resource in resources %}
+ <tr>
+ <td align="right">{{ loop.index }}</td>
+ <td>{% if 'name' in resource %}<a href="/resources/manage?resource_id={{ resource.id }}">{{ resource.name }}</a>{% else %}N/A{% endif %}</td>
+ <td>{% if 'data' in resource %}{{ resource.data }}{% else %}N/A{% endif %}</td>
+ <td>{% if 'metadata' in resource %}{{ resource.metadata }}{% else %}N/A{% endif %}</td>
+ <td>{% if 'admin' in resource %}{{ resource.admin }}{% else %}N/A{% endif %}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% else %}
+ There are currently no resources associated with this group.
+ {% endif %}
+ </div>
+ </div>
+ </form>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+
+ <script type="text/javascript" charset="utf-8">
+ $(document).ready( function () {
+ $('#group_admins').dataTable({
+ 'order': [[1, "asc" ]],
+ 'columns': [
+ { "type": "natural", "width": "25px"},
+ { "type": "natural", "width": "30px" },
+ { "type": "natural", "width": "150px" },
+ { "type": "natural" },
+ { "type": "natural" }
+ ],
+ 'sDom': 'tr'
+ });
+ {% if members|length > 0 %}
+ $('#group_members').dataTable({
+ 'order': [[1, "asc" ]],
+ 'columns': [
+ { "type": "natural", "width": "25px"},
+ { "type": "natural", "width": "30px" },
+ { "type": "natural", "width": "150px" },
+ { "type": "natural" },
+ { "type": "natural" }
+ ],
+ 'sDom': 'tr'
+ });
+ {% endif %}
+ {% if resources|length > 0 %}
+ $('#resources').dataTable({
+ 'order': [[0, "asc" ]],
+ 'columns': [
+ { "type": "natural", "width": "30px" },
+ { "type": "natural", "width": "150px" },
+ { "type": "natural" },
+ { "type": "natural" },
+ { "type": "natural" }
+ ],
+ 'sDom': 'tr'
+ });
+ {% endif %}
+
+ $('#resources_div').css('height', $('#groups_div').css('height'))
+
+ submit_special = function(url) {
+ $("#group_form").attr("action", url);
+ return $("#group_form").submit();
+ };
+
+ $("#remove_users").on("click", function() {
+ url = $(this).data("url");
+ admins = [];
+ $("input[name=admin_id]:checked").each(function() {
+ admins.push($(this).val());
+ });
+ admins_string = admins.join(":")
+ $("input[name=selected_admin_ids]").val(admins_string)
+
+ members = [];
+ $("input[name=member_id]:checked").each(function() {
+ members.push($(this).val());
+ });
+ members_string = members.join(":")
+ $("input[name=selected_member_ids]").val(members_string)
+ return submit_special(url)
+ });
+
+ $("#add_admins, #add_members").on("click", function() {
+ url = $(this).data("url");
+ console.log(url)
+ return submit_special(url)
+ });
+
+ $("#change_group_name").on("click", function() {
+ if ($('input[name=new_group_name]').css('display') == 'none') {
+ $('input[name=new_group_name]').css('display', 'inline');
+ $('#group_name').css('display', 'none');
+ } else {
+ new_name = $('input[name=new_group_name]').val()
+ $.ajax({
+ type: "POST",
+ url: "{{ GROUP_URL }} ",
+ data: {
+ group_id: $('input[name=group_id]').val(),
+ new_name: new_name
+ }
+ });
+ $('input[name=new_group_name]').css('display', 'none');
+ $('input[name=group_name]').val(new_name);
+ $('#group_name').text(new_name)
+ $('#group_name').css('display', 'inline');
+ }
+ });
+ });
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/authorisation_error.html b/gn2/wqflask/templates/authorisation_error.html
new file mode 100644
index 00000000..3dce8b52
--- /dev/null
+++ b/gn2/wqflask/templates/authorisation_error.html
@@ -0,0 +1,19 @@
+{%extends "base.html"%}
+{%block title%}{{error_type}}: ...{%endblock%}
+{%block content%}
+<div class="container">
+ <div class="page-header">
+ <h3>Access Error: {{error_type}}</h3>
+ </div>
+ <p>
+ <span class="glyphicon glyphicon-exclamation-sign text-danger"></span>
+ <strong>{{error_type}}:</strong>&nbsp;
+ <small class="text-danger">{{error.description}}</small>
+ </p>
+ <p>
+ Please contact the data's owner or GN administrators if you believe you
+ should have access to these data.
+ </p>
+</div>
+
+{%endblock%}
diff --git a/gn2/wqflask/templates/base.html b/gn2/wqflask/templates/base.html
new file mode 100644
index 00000000..984cf92a
--- /dev/null
+++ b/gn2/wqflask/templates/base.html
@@ -0,0 +1,397 @@
+{% from "base_macro.html" import header, flash_me, timeago %}
+<!DOCTYPE HTML>
+<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+ <meta charset="utf-8">
+ <title>{% block title %}{% endblock %} GeneNetwork 2</title>
+ <meta name="description" content="">
+ <meta name="author" content="">
+ <script type="text/javascript">
+ var pageLoadStart = Date.now();
+ </script>
+ <link rel="icon" type="image/png" sizes="64x64" href="/static/new/images/CITGLogo.png">
+ <link rel="apple-touch-icon" type="image/png" sizes="64x64" href="/static/new/images/CITGLogo.png">
+ <link REL="stylesheet" TYPE="text/css" href="{{ url_for('css', filename='bootstrap/css/bootstrap.css') }}" />
+ <link REL="stylesheet" TYPE="text/css" href="/static/new/css/bootstrap-custom.css" />
+ <link REL="stylesheet" TYPE="text/css" href="/static/new/css/non-responsive.css" />
+ <link REL="stylesheet" TYPE="text/css" href="/static/new/css/docs.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/colorbox.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/parsley.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/broken_links.css" />
+ <link rel="stylesheet" href="/static/new/css/autocomplete.css" />
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+ {% block css %}
+ {% endblock %}
+ <style>
+ .form-rounded {
+ border-radius: 1rem;
+ }
+ table.dataTable thead .sorting_asc {
+ background-image: url({{ url_for("js", filename="DataTables/images/sort_asc_disabled.png") }});
+ }
+ table.dataTable thead .sorting_desc {
+ background-image: url({{ url_for("js", filename="DataTables/images/sort_desc_disabled.png") }});
+ }
+
+
+ .global_search_input{
+ padding:9px 8px;
+ text-decoration: none;
+ border: none;
+
+ border-radius: 5px;
+ }
+
+
+ .global_search_input:focus{
+ outline: none;
+}
+
+
+
+.btn-stc {
+ padding:9px 8px;
+
+ border-left:none;
+
+ border-radius:0 40px 40px 0;
+
+ cursor: pointer;
+
+ height: 40px;
+ width: 64px;
+ margin:0;
+ border:1px solid #d3d3d3;
+ background-color: white;
+
+ position: absolute;
+
+ top:0;
+ left: 100%;
+
+ right: 0;
+
+ border-left: none;
+
+
+
+
+
+
+}
+
+
+</style>
+</head>
+
+<body style="width: 100%">
+ <!-- Navbar ================================================== -->
+ <div class="navbar navbar-inverse navbar-static-top pull-left" role="navigation" style="width: 100%; min-width: 850px; white-space: nowrap;">
+ <div class="container-fluid" style="width: 100%;">
+ <!-- Collect the nav links, forms, and other content for toggling -->
+ <div>
+ <ul class="nav navbar-nav">
+ <li class="" style="margin-right: 20px;">
+ <a href="/" style="font-weight: bold;">GeneNetwork</a>
+ </li>
+ <li class="">
+ <a href="/help" class="dropdow-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Intro <span class="caret"></a>
+ <ul class="dropdown-menu">
+ <li><a href="/intro">Intro</a></li>
+ <li><a href="/submit_trait">Submit Trait</a></li>
+ <li><a href="http://genenetwork.org/webqtl/main.py?FormID=batSubmit">Batch Submission</a></li>
+ </ul>
+ </li>
+ <li class="">
+ <a href="/help" class="dropdow-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Help <span class="caret"></a>
+ <ul class="dropdown-menu">
+ <li><a href="{{ url_for('references_blueprint.references') }}">References</a></li>
+ <li><a href="/tutorials">Webinars, Tutorials/Primers</a></li>
+ <li><a href="{{ url_for('blogs_blueprint.blogs_list') }}">Blogs</a></li>
+ <li><a href="{{ url_for('glossary_blueprint.glossary') }}">Glossary of Term</a></li>
+ <li><a href="http://gn1.genenetwork.org/faq.html">FAQ</a></li>
+ <li><a href="{{ url_for('policies_blueprint.policies') }}">Policies</a></li>
+ <li><a href="{{ url_for('links_blueprint.links') }}">Links</a></li>
+ <li><a href="{{ url_for('facilities_blueprint.facilities') }}">Facilities</a></li>
+ <li><a href="{{ url_for('environments_blueprint.environments') }}">Environments</a></li>
+ <li><a href="/news">GN1 News</a></li>
+ </ul>
+ </li>
+ <li class="">
+ <a href="/help" class="dropdow-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Tools <span class="caret"></a>
+ <ul class="dropdown-menu">
+ <li><a href="/snp_browser">Variant Browser</a></li>
+ <li><a href="http://bnw.genenetwork.org/sourcecodes/home.php">Bayesian Network Webserver</a></li>
+ <li><a href="https://systems-genetics.org/">Systems Genetics PheWAS</a></li>
+ <li><a href="http://ucscbrowser.genenetwork.org/">Genome Browser</a></li>
+ <li><a href="http://power.genenetwork.org">BXD Power Calculator</a></li>
+ <li><a href="{{url_for('jupyter_notebooks.launcher')}}">Jupyter Notebooks</a></li>
+ <li><a href="https://files.genenetwork.org/current/">Public Datasets</a></li>
+ </ul>
+ </li>
+ {% if g.user_session %}
+ <li class="">
+ <a href="/collections/list">Collections
+ <span class="badge badge-info">{{num_collections()}}</span>
+ </a>
+ </li>
+ <li class="">
+ <a href="/repositories" class="dropdow-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Source Code <span class="caret"></a>
+ <ul class="dropdown-menu">
+ <li><a href="https://github.com/genenetwork/genenetwork2">GN2 Source Code</a></li>
+ <li><a href="https://github.com/genenetwork/genenetwork">GN1 Source Code</a></li>
+ <li><a href="https://github.com/genenetwork/sysmaintenance">System Maintenance Code</a></li>
+ <li><a href="https://github.com/genenetwork/genenetwork2/blob/testing/doc/API_readme.md">REST API Documentation</a></li>
+ </ul>
+ </li>
+ {% if g.user_session.logged_in %}
+ <li class="">
+ <a href="/edit_account_settings" class="dropdow-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{% if g.user_session.user_email %}{{ g.user_session.user_email }}{% else %}User Account Settings{% endif %}<span class="caret"></a>
+ <ul class="dropdown-menu">
+ <li><a id="manage_user" title="User Options" href="/user/manage">User Options</a></li>
+ <li><a id="manage_groups" title="Manage Groups" href="/group-management/groups">Manage Groups</a></li>
+ </ul>
+ </li>
+ {% endif %}
+ <li class="">
+ {%if logged_in()%}
+ {%if user_details is mapping%}
+ {%set user_dets = user_details%}
+ {%else%}
+ {%set user_dets = user_details()%}
+ {%endif%}
+ <a id="login_out"
+ title="Signed in as {{user_dets.name}}({{user_dets.email}})"
+ href="{{url_for('oauth2.user.logout')}}">Sign out</a>
+ {%else%}
+ <a id="login_in" href="{{authserver_authorise_uri()}}">Sign in</a>
+ {%endif%}
+ </li>
+ {% endif %}
+
+ {%if not logged_in()%}
+ <li class="">
+ <a id="user:register" title="Register a new user account."
+ href="{{url_for('oauth2.user.register_user')}}">
+ Register
+ </a>
+ </li>
+ {%endif%}
+
+ {%if logged_in()%}
+ <li class="">
+ <a id="user:profile" title="User's profile page."
+ href="{{url_for('oauth2.user.user_profile')}}">
+ Profile
+ </a>
+ </li>
+ {%endif%}
+ <!--
+ <li style="margin-left: 20px;">
+ <a href="http://gn2-staging.genenetwork.org" style="font-weight: bold;" >Use Staging Branch</a>
+ </li>
+ -->
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div class="container-fluid" style="width: 100%; min-width: 650px; position: relative;background-color: #d5d5d5; height: 100px;">
+ <form id="gnqna_search_home" method="POST" action="/gnqna" style="display:none;width: 100%;">
+
+ <div >
+ <input id="gnqna_search_home_input" style="width:45vw" type="text" autocomplete="off"
+required placeholder="Ask More Questions or Topics (E.g Genes) " value='' name="querygnqa">
+ </div>
+ </form>
+ <form method="get" action="/gsearch" id="globalsearchform">
+ <div class="form-group">
+ <div class="controls">
+ <select name="type">
+ <option value="gene">Genes / Molecules</option>
+ <option value="phenotype" {% if type=="phenotype" %}selected{% endif %}>Phenotypes</option>
+ </select>
+ <div class="col-8 autocomplete" style="margin-left: 30px;margin-right: 10px;">
+ <input autocomplete="off" class="global_search_input" id="term" style="width:45vw" type="text" required placeholder="Enter you search term here (ex: cytochrome AND P450)" name="terms">
+
+ <button type="submit" class="btn-stc" style="position: absolute; background-color: #336699"><i class="fa fa-search" title="Search " style="color:white;"></i></button>
+ </div>
+
+
+
+ <!-- todo fix text overlap for this;;responsiveness-->
+
+ <span style="padding: 5px;margin-left: 65px;" id="gnqna_home">
+ <a href="/gnqna">GNQNA Search</a>
+ </span>
+
+ <span style="padding: 5px;margin-left: 65px;" >
+ <a style="text-decoration: none" target="_blank" href="https://issues.genenetwork.org/topics/xapian/xapian-search-queries">
+ <i style="text-align: center;color:#336699;;" class="fa fa-question-circle fa-2x" title="see more search hints" aria-hidden="true"></i>
+ </a>
+
+ </span>
+
+ </div>
+ </div>
+ </form>
+
+ </div>
+ {% block content %}
+ {% endblock %}
+ <footer class="footer">
+ <div class="row" style="margin: 10px; width: 100%; min-width: 1200px;">
+ <div class="col-xs-6">
+ <p>Web services initiated January, 1994 as
+ <a href="http://www.ncbi.nlm.nih.gov/pubmed?term=8043953">
+ The Portable Dictionary of the Mouse Genome
+ </a>; June 15, 2001 as <a href="https://www.ncbi.nlm.nih.gov/pubmed/15043217">WebQTL</a>; and Jan 5, 2005 as GeneNetwork.
+ </p>
+ <p>
+ This site is currently operated by
+ <a href="mailto:rwilliams@uthsc.edu">Rob Williams</a>,
+ <a href="https://thebird.nl/">Pjotr Prins</a>,
+ <a href="http://www.senresearch.org">Saunak Sen</a>,
+ <a href="mailto:zachary.a.sloan@gmail.com">Zachary Sloan</a>,
+ <a href="mailto:acenteno@uthsc.edu">Arthur Centeno</a>,
+ and <a href="mailto:bonfacemunyoki@gmail.com">Bonface Munyoki</a>.
+ </p>
+ <p>Design and code by Pjotr Prins, Shelby Solomon, Zach Sloan, Arthur Centeno, Christan Fischer, Bonface Munyoki, Danny Arends, Arun Isaac, Alex Mwangi, Fred Muriithi, Sam Ockman, Lei Yan, Xiaodong Zhou, Christian Fernandez,
+ Ning Liu, Rudi Alberts, Elissa Chesler, Sujoy Roy, Evan G. Williams, Alexander G. Williams, Kenneth Manly, Jintao Wang, Robert W. Williams, and
+ <a href="/credits">colleagues</a>.</p>
+ <br />
+ <p>GeneNetwork support from:</p>
+ <ul>
+ <li>
+ <a href="http://citg.uthsc.edu">
+ The UT Center for Integrative and Translational Genomics
+ </a>
+ </li>
+ <li>
+ <a href="https://www.nigms.nih.gov/">NIGMS</a>
+ Systems Genetics and Precision Medicine Project (R01 GM123489, 2017-2026)
+ </li>
+ <li>
+ <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2118709">NSF</a>
+ Panorama: Integrated Rack-Scale Acceleration for Computational Pangenomics
+ (PPoSS 2118709, 2021-2016)
+ </li>
+ <li>
+ <a href="https://www.drugabuse.gov/">NIDA</a>
+ NIDA Core Center of Excellence in Transcriptomics, Systems Genetics, and the Addictome (P30 DA044223, 2017-2022)
+ </li>
+ <li>
+ <a href="http://www.nia.nih.gov/">NIA</a>
+ Translational Systems Genetics of Mitochondria, Metabolism, and Aging (R01AG043930, 2013-2018)
+ </li>
+ <li>
+ <a href="https://www.ohsu.edu/iniastress-consortium">NIAAA</a>
+ Integrative Neuroscience Initiative on Alcoholism (U01 AA016662, U01 AA013499, U24 AA013513, U01 AA014425, 2006-2017)
+ </li>
+ <li>
+ <a href="http://www.drugabuse.gov/">NIDA</a>, <a href="http://www.nimh.nih.gov/">NIMH</a>, and <a href="http://www.niaaa.nih.gov/">NIAAA</a>
+ (P20-DA 21131, 2001-2012)
+ </li>
+ <li>
+ NCI <a href="http://emice.nci.nih.gov/">MMHCC</a> (U01CA105417), NCRR, <span class="broken_link test" href="http://www.birncommunity.org/">BIRN</span>, (U24 RR021760)
+ </li>
+ </UL>
+ <p>Published in
+ <a href="http://joss.theoj.org/papers/10.21105/joss.00025"><img src="https://camo.githubusercontent.com/846b750f582ae8f1d0b4f7e8fee78bed705c88ba/687474703a2f2f6a6f73732e7468656f6a2e6f72672f7061706572732f31302e32313130352f6a6f73732e30303032352f7374617475732e737667" alt="JOSS" data-canonical-src="http://joss.theoj.org/papers/10.21105/joss.00025/status.svg" style="max-width:100%;"></a>
+ </p>
+ <p>
+ Development and source code on <a href="https://github.com/genenetwork/">github</a> with <a href="https://issues.genenetwork.org/">issue tracker</a> and <a href="https://github.com/genenetwork/genenetwork2/blob/master/README.md">documentation</a>.
+ {% if version: %}
+ <p><small>GeneNetwork {{ version }}</small></p>
+ {% endif %}
+ <p> It took the server {{ g.request_time() }} seconds to process this page.</p>
+ </div>
+ <div class="col-xs-2">
+ <a href="http://www.python.org/" target="_blank">
+ <img src="/static/new/images/PythonLogo.png" alt="Python Powered" border="0">
+ </a>
+ <a href="http://www.neuinfo.org" target="_blank">
+ <img src="/static/new/images/Nif.png" alt="Registered with Nif" border="0">
+ </a>
+ </div>
+ </div>
+ </footer>
+ <!--http://stackoverflow.com/questions/14045515/how-can-i-reuse-one-bootstrap-modal-div-->
+ <!-- Modal -->
+ <div id="utility" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+ <div class="modal-body">
+ <p>.</p>
+ </div>
+ </div>
+ <script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script>
+ <script src="{{ url_for('js', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script>
+ <script src="/static/new/javascript/search_autocomplete.js"></script>
+ <script>
+ //http://stackoverflow.com/questions/11521763/bootstrap-scrollspy-not-working
+ var $window = $(window)
+ $('.bs-docs-sidenav').affix({
+ offset: {
+ top: function() { return $window.width() <= 980 ? 290 : 210 },
+ bottom: 270
+ }
+ })
+ </script>
+ <script type="text/javascript">
+ $(document).ready(function() {
+
+ const urlParams = new URLSearchParams(window.location.search)
+ let term = urlParams.get("terms")
+
+ //should web scrap
+ var global_search_hint = [
+ "cytochrome",
+ "cytochrome AND P450",
+ "cytochrome NEAR P450",
+ "cytochrome -P450",
+ "cytochrome NOT P450",
+ "species:human",
+ "group:BXD",
+ "Hs:chr4:9930021 species:mouse",
+ "Hs:chr4:9130000..9980000 species:mouse",
+ "mean:5..7",
+ "mean:7..",
+ "Hs:chr4:9930021",
+ "Hs:chr4:9930021 species:mouse",
+ "Hs:chr4:9130000..9980000 species:mouse",
+ "bx*",
+ "*",
+ ]
+ autocomplete(document.getElementById("term"), global_search_hint);
+ $("#term").keyup(function(event) {
+ if (event.keyCode === 13) {
+ event.preventDefault();
+ $('#globalsearchform').attr('action', "/gsearch").submit();
+ if ($("#term").val().trim() != "") {
+ saveBeforeSubmit($("#term").val().trim())
+ $("#globalsearchform")[0].submit();
+ }
+
+ }
+ })
+
+ });
+ </script>
+ <script src="{{ url_for('js', filename='jquery-cookie/jquery.cookie.js') }}" type="text/javascript"></script>
+ <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='colorbox/jquery.colorbox-min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/parsley.min.js') }}"></script>
+ {% block js %}
+ {% endblock %}
+ <script type="text/javascript">
+ document.addEventListener('DOMContentLoaded', function() {
+ let timeToLoad = document.createElement("p");
+ timeToLoad.innerHTML = "It took your browser " + ((Date.now() - pageLoadStart) / 1000) + " second(s) to render this page";
+ document.querySelector("footer .row .col-xs-6").appendChild(timeToLoad);
+
+
+ });
+ </script>
+</body>
+
+</html>
diff --git a/gn2/wqflask/templates/base_macro.html b/gn2/wqflask/templates/base_macro.html
new file mode 100644
index 00000000..7fcb6fe7
--- /dev/null
+++ b/gn2/wqflask/templates/base_macro.html
@@ -0,0 +1,28 @@
+{% macro flash_me() -%}
+ {% with messages = get_flashed_messages(with_categories=true) %}
+ {% if messages %}
+ <div class="container">
+ {% for category, message in messages %}
+ <div class="alert {{ category }}" role="alert">{{ message }}</div>
+ {% endfor %}
+ </div>
+ {% endif %}
+ {% endwith %}
+{% endmacro %}
+
+{% macro header(main, second) %}
+ <header class="jumbotron subhead" id="overview" >
+ <div class="container">
+ <h1>{{ main }}</h1>
+ <p class="lead">
+ {{ second }}
+ </p>
+ </div>
+ </header>
+
+ {{ flash_me() }}
+{% endmacro %}
+
+{% macro timeago(timestamp) %}
+<time class="timeago" datetime="{{ timestamp }}">{{ timestamp }}</time>
+{% endmacro %}
diff --git a/gn2/wqflask/templates/blogs.html b/gn2/wqflask/templates/blogs.html
new file mode 100644
index 00000000..314eb733
--- /dev/null
+++ b/gn2/wqflask/templates/blogs.html
@@ -0,0 +1,12 @@
+{% extends "base.html" %}
+{% block title %}Blogs {% endblock %}
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+{% block content %}
+<div class="github-btn-container">
+</div>
+<div id="markdown" class="container">
+ {{ rendered_markdown|safe }}
+</div>
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/blogs_list.html b/gn2/wqflask/templates/blogs_list.html
new file mode 100644
index 00000000..6bad4628
--- /dev/null
+++ b/gn2/wqflask/templates/blogs_list.html
@@ -0,0 +1,52 @@
+{% extends "base.html" %}
+{% block title %}Blogs {% endblock %}
+{% block css %}
+<style type="text/css">
+.container {
+ height: 100vh;
+}
+
+.blog_year {
+ font-weight: bold;
+ font-size: 48px;
+ padding: 12px 10px;
+}
+
+.blog_title {
+ padding: 10px 15px;
+
+}
+
+
+
+.blog_title a {
+ font-size: 1.3em;
+ padding-left: 10px;
+ letter-spacing: 0.07em;
+ text-decoration: underline;
+}
+</style>
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+{% block content %}
+<div id="markdown" class="container">
+ <div>
+ {% for year, year_blogs in blogs.items() %}
+ <div class="blog_year">
+ <h3>{{year}}</h3>
+ </div>
+ {%for blog in year_blogs%}
+ <div>
+ <div class="blog_title">
+ <ul>
+ <li>
+ <a href="{{ url_for('blogs_blueprint.display_blog',blog_path = blog.full_path)}}">{{blog['subtitle']}}</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ {% endfor %}
+ {%endfor%}
+ </div>
+</div>
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/bnw_page.html b/gn2/wqflask/templates/bnw_page.html
new file mode 100644
index 00000000..317b4bd7
--- /dev/null
+++ b/gn2/wqflask/templates/bnw_page.html
@@ -0,0 +1,7 @@
+<title>Opening BNW</title>
+<form method="post" action="https://bnw.genenetwork.org/sourcecodes/bn_genenet.php" name="bnwform" id="bnwform">
+ <input type="hidden" name="My_Genenet" value="{{ form_value }}">
+</form>
+<script type="text/javascript">
+ document.bnwform.submit();
+</script>
diff --git a/gn2/wqflask/templates/case_attributes.html b/gn2/wqflask/templates/case_attributes.html
new file mode 100644
index 00000000..d1669761
--- /dev/null
+++ b/gn2/wqflask/templates/case_attributes.html
@@ -0,0 +1,415 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+<style>
+ .reject, .approve {
+ margin-bottom: 5px;
+ }
+.case-attribute {
+ width: 10em;
+ }
+ .table-title {
+ padding-bottom: 10px;
+ margin: 0 0 10px;
+ }
+
+ .table-title h2 {
+ margin: 6px 0 0;
+ font-size: 22px;
+ }
+ .table-title .add-new {
+ float: right;
+ height: 30px;
+ font-weight: bold;
+ font-size: 12px;
+ text-shadow: none;
+ min-width: 100px;
+ border-radius: 50px;
+ line-height: 13px;
+ }
+ .table-title .add-new i {
+ margin-right: 4px;
+ }
+ table.table {
+ table-layout: fixed;
+ width: 70%;
+ }
+ table.table tr th, table.table tr td {
+ border-color: #e9e9e9;
+ }
+ table.table th i {
+ font-size: 13px;
+ margin: 0 5px;
+ cursor: pointer;
+ }
+ table.table th:last-child {
+ width: 100px;
+ }
+ table.table td a {
+ cursor: pointer;
+ display: inline-block;
+ margin: 0 5px;
+ min-width: 24px;
+ }
+ table.table td a.add {
+ color: #27C46B;
+ }
+ table.table td a.edit {
+ color: #FFC107;
+ }
+ table.table td a.delete {
+ color: #E34724;
+ }
+ table.table td i {
+ font-size: 19px;
+ }
+ table.table td a.add i {
+ font-size: 24px;
+ margin-right: -1px;
+ position: relative;
+ top: 3px;
+ }
+ table.table .form-control {
+ height: 32px;
+ line-height: 32px;
+ box-shadow: none;
+ border-radius: 2px;
+ }
+ table.table .form-control.error {
+ border-color: #f50000;
+ }
+ table.table td .add {
+ display: none;
+ }
+</style>
+{% endblock %}
+
+{% block content %}
+<!-- Start of body -->
+<div class="container">
+ <div class="table-wrapper">
+ <div class="table-title">
+ <div class="row">
+ <div class="col-sm-8">
+ <h2>Case Attributes Reference Table</h2>
+ </div>
+ </div>
+ </div>
+ <table class="table table-bordered table-responsive">
+ <colgroup>
+ <col class="case-attribute">
+ <col>
+ <col>
+ </colgroup>
+ <thead>
+ <th scope="col">Case Attribute</th>
+ <th scope="col">Description</th>
+ <th scope="col">Actions</th>
+ </thead>
+ <tbody>
+ {% for id_, name, description in case_attributes %}
+ <tr data-id="{{id_}}">
+ <td class="name" data-original-value="{{ name }}">{{ name }}</td>
+ <td class="description" data-original-value="{{ description }}">{{ description }}</td>
+ <td>
+ <a class="add" title="Add" data-toggle="tooltip"><i><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></i></a>
+ <a class="edit" title="Edit" data-toggle="tooltip"><i><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></i></a>
+ <a class="delete" title="Delete" data-toggle="tooltip"><i><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></i></a>
+ </td>
+ </tr>
+ {% endfor %}
+ <tr id="addNew">
+ <td></td>
+ <td></td>
+ <td><button type="button" class="btn btn-info add-new"><i class="fa fa-plus"></i> Add New</button></td>
+ </tr>
+ </tbody>
+ </table>
+
+ {% if modifications or inserts or deletions %}
+ <h2>Please Review These Changes</h2>
+ {% endif %}
+ {% if modifications %}
+ <h3>Modify Existing Case Attributes</h3>
+ <table class="table table-responsive table-hover table-striped cell-border" id="table-modifications">
+ <thead>
+ <th scope="col">Author</th>
+ <th scope="col">Diff</th>
+ <th scope="col">Action</th>
+ </thead>
+ <tbody>
+ {% for data in modifications %}
+ <tr>
+ <td>{{ data.get('author') }}</td>
+ <td>
+ {% if data.get("name")%}
+ <b>Name:</b><br/>
+ <small>Original: </small>{{ data["name"].get("Original") }}<br/>
+ <small>Current: </small>{{ data["name"].get("Current") }} <br/>
+ <small>Diff:</small><br/>
+ <pre>{{data["name"].get("Diff")}}</pre>
+ {% endif %}
+ {% if data.get("description")%}
+ <b>Description:</b><br/>
+ <small>Original: </small>{{ data["description"].get("Original") }}<br/>
+ <small>Current: </small>{{ data["description"].get("Current") }} <br/>
+ <small>Diff:</small><br/>
+ <pre>{{data["description"].get("Diff")}}</pre>
+ {% endif %}
+ </td>
+ <td>
+ <button data-id="{{ data.get('id') }}" type="button"
+ class="btn btn-default reject">
+ Reject
+ </button>
+ <button data-id="{{ data.get('id') }}" type="button"
+ class="btn btn-success approve">
+ Approve
+ </button>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+ {% if deletions %}
+ <h3>Delete Existing Case Attributes</h3>
+ <table class="table table-responsive table-hover table-striped cell-border" id="table-modifications">
+ <colgroup>
+ <col class="case-attribute">
+ <col>
+ <col>
+ <col>
+ </colgroup>
+ <thead>
+ <th scope="col">Case Attribute</th>
+ <th scope="col">Author</th>
+ <th scope="col">Description</th>
+ <th scope="col">Action</th>
+ </thead>
+ <tbody>
+ {% for data in deletions %}
+ <tr>
+ <td>{{data.get("name")}}</td>
+ <td>{{ data.get('author') }}</td>
+ <td>{{data.get("description")}}</td>
+ <td>
+ <button data-id="{{data.get('id')}}" type="button"
+ class="btn btn-default reject">
+ Reject
+ </button>
+ <button data-id="{{data.get('id')}}" type="button" class="btn btn-success approve">
+ Approve
+ </button>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+
+ {% if inserts %}
+ <h3>Insert New Case Attributes</h3>
+ <table class="table table-responsive table-hover table-striped cell-border" id="table-modifications">
+ <colgroup>
+ <col class="case-attribute">
+ <col>
+ <col>
+ <col>
+ </colgroup>
+ <thead>
+ <th scope="col">Case Attribute</th>
+ <th scope="col">Author</th>
+ <th scope="col">Description</th>
+ <th scope="col">Action</th>
+ </thead>
+ <tbody>
+ {% for data in inserts %}
+ <tr>
+ <td>{{ data.get("name") }}</td>
+ <td>{{ data.get("author")}}</td>
+ <td>{{ data.get("description") }} </td>
+ <td>
+ <button data-id="{{ data.get('id') }}" type="button"
+ class="btn btn-default reject">
+ Reject
+ </button>
+ <button data-id="{{ data.get('id') }}" type="button" class="btn btn-success approve">
+ Approve
+ </button>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+ </div>
+ {%endblock%}
+
+ {% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+ <script language="javascript" type="text/javascript">
+ gn_server_url = "{{ gn_server_url }}";
+
+ $(document).ready( function() {
+ let actions = $("table td:last-child").html();
+ // Append table with add row form on add new button click
+ $(".add-new").click(function(){
+ $(this).attr("disabled", "disabled");
+ let index = $("table tbody tr:nth-last-child(2)").index();
+ let row = '<tr>' +
+ '<td class="name"><input type="text" class="form-control"></td>' +
+ '<td class="description"><input type="text" class="form-control"></td>' +
+ '<td>' + actions + '</td>' +
+ '</tr>';
+ $(row).insertBefore("#addNew")
+ $("table tbody tr").eq(index + 1).find(".add, .edit").toggle();
+ });
+ // Add row on add button click
+ $(document).on("click", ".add", function(){
+ let empty = false;
+ let input = $(this).parents("tr").find('input[type="text"]');
+ input.each(function(){
+ if(!$(this).val()){
+ $(this).addClass("error");
+ empty = true;
+ } else{
+ $(this).removeClass("error");
+ }
+ });
+ $(this).parents("tr").find(".error").first().focus();
+ if(!empty){
+ input.each(function(){
+ $(this).parent("td").html($(this).val());
+ });
+ $(this).parents("tr").find(".add, .edit").toggle();
+ $(".add-new").removeAttr("disabled");
+ }
+ else {
+ return;
+ }
+
+ let nameNode = $(this).parents("tr").find(".name");
+ let descNode = $(this).parents("tr").find(".description");
+ let name = nameNode.html();
+ let desc = descNode.html();
+ let nodeId = $(this).parents("tr").data("id");
+ let originalName = nameNode.data("original-value");
+ let originalDesc = descNode.data("original-value");
+ let diff = {};
+ if (nodeId) {
+ if (name !== originalName) {
+ diff["Modification"] = {
+ name: {
+ Original: originalName,
+ Current: name,
+ }};
+ }
+ if (desc !== originalDesc) {
+ let desc_ = {
+ Original: originalDesc,
+ Current: desc,
+ }
+ if (Object.keys(diff).length == 0) {
+ diff["Modification"] = {
+ description: desc_
+ }
+ }
+ else {
+ diff["Modification"].description = desc_;
+ }
+ }
+ if (!Object.keys(diff).length == 0) {
+ diff["id"] = nodeId;
+ }
+ } else {
+ if (name) {
+ diff["Insert"] = {
+ name: name,
+ }
+ }
+ if (desc) {
+ if (Object.keys(diff).length == 0) {
+ diff["Insert"] = {
+ description: desc,
+ }
+ }
+ else {
+ diff["Insert"].description = desc;
+ }
+ }
+ }
+ if(diff) {
+ $.ajax({
+ type: "POST",
+ data: {"data": JSON.stringify(diff)},
+ url: '{{ url_for("metadata_edit.update_case_attributes") }}',
+ /* contentType: "application/json", */
+ success: function(data, status, xhr) { location.reload() }
+ }
+ )
+ }
+ });
+ // Edit row on edit button click
+ $(document).on("click", ".edit", function(){
+ $(this).parents("tr").find("td:not(:last-child)").each(function(){
+ $(this).html('<input type="text" class="form-control" value="' + $(this).text() + '">');
+ });
+ $(this).parents("tr").find(".add, .edit").toggle();
+ $(".add-new").attr("disabled", "disabled");
+ });
+
+ // Delete row on delete button click
+ $(document).on("click", ".delete", function(){
+ $(this).parents("tr").remove();
+ $(".add-new").removeAttr("disabled");
+ let node = $(this).parents("tr")
+
+ let diff = {};
+ let nodeId = $(this).parents("tr").data("id");
+ diff["Deletion"] = {
+ name: node.find(".name").data("original-value"),
+ description: node.find(".description").data("original-value"),
+ id: node.data("id")}
+ if (nodeId){
+ $.ajax({
+ type: "POST",
+ data: {"data": JSON.stringify(diff)},
+ url: '{{ url_for("metadata_edit.update_case_attributes") }}',
+ success: function(data, status, xhr) {
+ location.reload();
+ }
+ })}
+ });
+ });
+
+ $(".reject").click(function(){
+ let id = $(this).data("id");
+ if (Number.isInteger(id)) {
+ $.ajax({
+ type: "POST",
+ data: {"id": id},
+ url: '{{ url_for("metadata_edit.reject_case_attribute_data") }}',
+ success: function(data, status, xhr) {
+ location.reload();
+ }
+ })
+ }
+ });
+ $(".approve").click(function(){
+ let id = $(this).data("id");
+ if (Number.isInteger(id)) {
+ $.ajax({
+ type: "POST",
+ data: {"id": id},
+ url: '{{ url_for("metadata_edit.approve_case_attribute_data") }}',
+ success: function(data, status, xhr) {
+ location.reload();
+ }
+ })
+ }
+ });
+ </script>
+ {% endblock %}
diff --git a/gn2/wqflask/templates/collections/add.html b/gn2/wqflask/templates/collections/add.html
new file mode 100644
index 00000000..478c80fb
--- /dev/null
+++ b/gn2/wqflask/templates/collections/add.html
@@ -0,0 +1,86 @@
+<div id="myModal">
+ <div class="modal-header">
+ <h2>Define or Add to Collection</h2>
+ <p>You have two choices: Name a new collection
+ or add to an existing collection.</p>
+ </div>
+ <div class="modal-body" style="margin-left: 20px;">
+ <form action="/collections/new"
+ method="POST"
+ target="_blank"
+ data-validate="parsley"
+ id="add_form"
+ class="form-inline">
+ {% if traits is defined %}
+ <input type="hidden" name="traits" value="{{ traits }}" />
+ {% else %}
+ <input type="hidden" name="hash" value="{{ hash }}" />
+ {% endif %}
+ {% if collections|length > 0 %}
+ <fieldset>
+ <legend>1. Add to an existing collection</legend>
+ <div style="margin-left: 20px;">
+ <select name="existing_collection" class="form-control" style="width: 80%;">
+ {% for col in collections %}
+ {% if loop.index == 1 %}
+ <option value="{{ col.id }}:{{ col.name }}" selected>{{ col.name }}</option>
+ {% else %}
+ <option value="{{ col.id }}:{{ col.name }}">{{ col.name }}</option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ <input type="button" style="display: inline;" id="make_default" value="Make Default">
+ <br><br>
+ <button type="submit" name="add_to_existing" class="btn btn-primary">Add</button>
+ </div>
+ </fieldset>
+ {% endif %}
+ <hr />
+ <fieldset>
+ <legend>{% if collections|length > 0 %}2. {% else %}{% endif %}Create a new collection</legend>
+ <div style="margin-left: 20px;">
+ <input type="text" name="new_collection" placeholder=" Name of new collection..."
+ data-trigger="change" data-minlength="5" data-maxlength="50" style="width: 100%">
+ <button type="submit" name="create_new" class="btn btn-primary" style="margin-top: 20px;">Create collection</button>
+ {% if uc is not defined %}
+ <span class="help-block">This collection will be saved to your computer for a year (or until you clear your cache).</span>
+ {% endif %}
+ </div>
+ </fieldset>
+ </form>
+ </div>
+</div>
+
+<script>
+ $('#add_form').parsley();
+ $('#add_form').on('submit', function(){
+ parent.jQuery.colorbox.close();
+ });
+
+ make_default = function() {
+ alert("The current collection is now your default collection.")
+ let uc_id = $('[name=existing_collection] option:selected').val().split(":")[0]
+ $.cookie('default_collection', uc_id, {
+ expires: 365,
+ path: '/'
+ });
+
+ let default_collection_id = $.cookie('default_collection');
+ };
+
+ $("#make_default").on("click", function(){
+ make_default();
+ });
+
+ apply_default = function() {
+ let default_collection_id = $.cookie('default_collection');
+ if (default_collection_id) {
+ let the_option = $('[name=existing_collection] option').filter(function() {
+ return ($(this).val().split(":")[0] == default_collection_id);
+ })
+ the_option.prop('selected', true);
+ }
+ }
+
+ apply_default();
+</script>
diff --git a/gn2/wqflask/templates/collections/add_anonymous.html b/gn2/wqflask/templates/collections/add_anonymous.html
new file mode 100644
index 00000000..2eb7525f
--- /dev/null
+++ b/gn2/wqflask/templates/collections/add_anonymous.html
@@ -0,0 +1,21 @@
+<div id="myModal">
+ <div class="modal-header">
+ <h3>Add to collection</h3>
+ <br />
+ <div>
+ <p>We can add this to a temporary collection for you.</p>
+ <p>For the most features you'll want to sign in or create an account.</p>
+ </div>
+ </div>
+ <div class="modal-body">
+ <form action="/collections/new" data-validate="parsley" id="add_form">
+ <input type="hidden" name="traits" value="{{ traits }}" />
+ <button type="submit" name="anonymous_add" class="btn btn-large btn-block btn-primary">Continue without signing in</button>
+ <button type="submit" name="sign_in" class="btn btn-large btn-block">Sign in or create an account</button>
+ </form>
+ </div>
+</div>
+
+<script>
+ $('#add_form').parsley();
+</script>
diff --git a/gn2/wqflask/templates/collections/list.html b/gn2/wqflask/templates/collections/list.html
new file mode 100644
index 00000000..c553717f
--- /dev/null
+++ b/gn2/wqflask/templates/collections/list.html
@@ -0,0 +1,189 @@
+{% extends "base.html" %}
+{%from "oauth2/display_error.html" import display_error%}
+{% block title %}Your Collections{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonsBootstrap/css/buttons.bootstrap.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div class="container">
+ {{flash_me()}}
+
+ {% if g.user_session.logged_in %}
+ <h1>Collections owned by {% if g.user_session.user_name %}{{ g.user_session.user_name }}{% else %}{{ g.user_session.user_email }} {% endif %}</h1>
+ {% else %}
+ <h1>Your Collections</h1>
+ {% endif %}
+
+ <div>
+ <button class="btn btn-default" id="select_all"><span class="glyphicon glyphicon-ok"></span> Select All</button>
+ <button class="btn btn-default" id="deselect_all"><span class="glyphicon glyphicon-remove"></span> Deselect All</button>
+ <button class="btn btn-default" id="invert"><span class="glyphicon glyphicon-resize-vertical"></span> Invert</button>
+ <button class="btn btn-danger" id="remove_collections" data-url="/collections/delete">Remove Collections</button>
+ <input type="text" id="searchbox" class="form-control" style="width: 200px; display: inline;" placeholder="Search This Table For ...">
+ <input type="text" id="select_top" class="form-control" style="width: 200px; display: inline;" placeholder="Select Top ...">
+ <br>
+ <form id="collections_form" action="javascript:void(0);" method="post" enctype="multipart/form-data">
+ <input type="hidden" name="uc_id" id="uc_id" value="" />
+ <div style="margin-top: 10px; display: inline-block;"><button class="btn btn-default" id="import_collection" data-url="/collections/import"> Import Collection</button> <input type="file" name="import_file" id="import_file" size="20" style="display: inline-block;"></input></div>
+ </form>
+ </div>
+ <br>
+ <div id="collections_list" style="width:50%; margin-top: 10px; margin-bottom: 10px;">
+ {%if anon_collections_error is defined%}
+ {{display_error("Anonymous Collections", anon_collections_error)}}
+ {%endif%}
+ {%if anon_collections | length > 0%}
+ <table class="table-hover table-striped cell-border" id='anon_trait_table'
+ style="float: left;">
+ <caption>Anonymous Collections</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Name</th>
+ <th>Created</th>
+ <th>Last Changed</th>
+ <th># Records</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for uc in anon_collections %}
+ <tr class="collection_line">
+ <td align="center" style="padding: 0px;"><INPUT TYPE="checkbox" NAME="collection" class="checkbox trait_checkbox" VALUE="{{ uc.id }}"></td>
+ <td align="right">{{ loop.index }}
+ <td><a class="collection_name" href="{{ url_for('view_collection', uc_id=uc.id) }}">{{ uc.name }}</a></td>
+ <td>{{ uc.created_timestamp }}</td>
+ <td>{{ uc.changed_timestamp }}</td>
+ <td align="right">{{ uc.num_members }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {%endif%}
+ {% if collections|length > 0 %}
+ {% if (anon_collections | length > 0) and (collections | length > 0) %}
+ <hr />
+ {%endif%}
+ <table class="table-hover table-striped cell-border" id='trait_table' style="float: left;">
+ <caption>User Collections</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Name</th>
+ <th>Created</th>
+ <th>Last Changed</th>
+ <th># Records</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for uc in collections %}
+ <tr class="collection_line">
+ <td align="center" style="padding: 0px;"><INPUT TYPE="checkbox" NAME="collection" class="checkbox trait_checkbox" VALUE="{{ uc.id }}"></td>
+ <td align="right">{{ loop.index }}
+ <td><a class="collection_name" href="{{ url_for('view_collection', uc_id=uc.id) }}">{{ uc.name }}</a></td>
+ <td>{{ uc.created_timestamp }}</td>
+ <td>{{ uc.changed_timestamp }}</td>
+ <td align="right">{{ uc.num_members }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% else %}
+ You have no collections yet.
+ {% endif %}
+ </div>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/timeago.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+ <script type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
+ <script type="text/javascript" src="/static/new/javascript/create_datatable.js"></script>
+ <script>
+ $(document).ready( function () {
+ tableId = "trait_table";
+
+ columnDefs = [
+ { "type": "natural", "width": "3%", "targets": 0, "orderable": false},
+ { "type": "natural", "width": "8%", "targets": 1},
+ { "type": "natural", "width": "20%", "targets": 2},
+ { "type": "natural", "width": "25%", "targets": 3},
+ { "type": "natural", "width": "25%", "targets": 4},
+ { "type": "natural", "width": "15%", "targets": 5}
+ ];
+
+ create_table("anon_trait_table", [], columnDefs)
+ create_table(tableId, [], columnDefs)
+
+ submit_special = function(url) {
+ $("#collections_form").attr("action", url);
+ return $("#collections_form").submit();
+ };
+
+ add_collection = function(trait_data, textStatus, jqXHR) {
+ var traits_hash = md5(trait_data.toString());
+
+ $.ajax({
+ type: "POST",
+ url: "/collections/store_trait_list",
+ data: {
+ hash: traits_hash,
+ traits: trait_data.toString()
+ }
+ });
+
+ return $.colorbox({
+ href: "/collections/add?hash=" + traits_hash
+ });
+ }
+
+ $("#import_collection").on("click", function() {
+ var fd = new FormData();
+ var files = $('#import_file')[0].files;
+ if(files.length > 0){
+ fd.append('import_file', files[0])
+ $.ajax({
+ type: "POST",
+ url: "/collections/import",
+ data: fd,
+ dataType: "json",
+ contentType: false,
+ processData: false,
+ success: add_collection
+ });
+ } else {
+ alert("No file selected")
+ }
+ });
+
+
+ $("#remove_collections").on("click", function() {
+ url = $(this).data("url")
+ collections = []
+ $(".trait_checkbox:checked").each(function() {
+ collections.push($(this).val());
+ });
+ collections_string = collections.join(":")
+ $("input[name=uc_id]").val(collections_string)
+ return submit_special(url)
+ });
+
+ });
+
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/collections/not_logged_in.html b/gn2/wqflask/templates/collections/not_logged_in.html
new file mode 100644
index 00000000..49b0e07d
--- /dev/null
+++ b/gn2/wqflask/templates/collections/not_logged_in.html
@@ -0,0 +1,23 @@
+{% extends "base.html" %}
+{% block title %}Your Collections{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ {{ header("Not logged in") }}
+
+
+ <div id="collections_holder" class="container">
+ <div class="page-header">
+ <h1>Please log in in order to use this feature.</h1>
+ </div>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/timeago.min.js') }}"></script>
+ <script>
+ $('body').timeago();
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/collections/remove.html b/gn2/wqflask/templates/collections/remove.html
new file mode 100644
index 00000000..faee4f78
--- /dev/null
+++ b/gn2/wqflask/templates/collections/remove.html
@@ -0,0 +1,48 @@
+<div id="myModal">
+ <div class="modal-header">
+ <h3>Add to collection</h3>
+ <p>You have three choices: Use your default collection, create a new named collection,
+ or add the traits to an existing collection.</p>
+ </div>
+ <div class="modal-body">
+ <form action="/collections/new" data-validate="parsley" id="add_form">
+ <fieldset>
+ <legend>Use your default collection</legend>
+ <span class="help-block">Choose this if you're in a hurry or don't plan on using the collection again.</span>
+ <span class="help-block"><em></em>If you are unsure this is probably the option you want.</em></span>
+ <button type="submit" name="Default" class="btn">Continue</button>
+ </fieldset>
+ <hr />
+
+
+ <input type="hidden" name="traits" value="{{ traits }}" />
+ <fieldset>
+ <legend>Or create a new named collection</legend>
+ <label>New collection name</label>
+ <input type="text" name="new_collection" placeholder="Name of new collection..."
+ data-trigger="change" data-minlength="5" data-maxlength="50">
+ <span class="help-block">Type the name of the new collection.</span>
+ <button type="submit" name="create_new" class="btn">Create and add traits</button>
+ </fieldset>
+
+ <hr />
+ <fieldset>
+ <legend>Or add to an existing collection</legend>
+ <label>Existing collection name</label>
+
+ <select name="existing_collection" class="form-control">
+ {% for col in user_collections %}
+ <option value="{{ col.id }}">{{ col.name }}</option>
+ {% endfor %}
+ </select>
+ <br />
+
+ <button type="submit" name="add_to_existing" class="btn">Add to existing collection</button>
+ </fieldset>
+ </form>
+ </div>
+</div>
+
+<script>
+ $('#add_form').parsley();
+</script>
diff --git a/gn2/wqflask/templates/collections/view.html b/gn2/wqflask/templates/collections/view.html
new file mode 100644
index 00000000..c850e163
--- /dev/null
+++ b/gn2/wqflask/templates/collections/view.html
@@ -0,0 +1,483 @@
+{% extends "base.html" %}
+{% block title %}View Collection{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}">
+ <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+
+ <div class="container">
+ {{flash_me()}}
+ <h1>
+ <span id="collection_name">{{ uc.name }}</span>
+ <form id="frm-change-collection-name"
+ method="POST"
+ action="{{url_for('change_collection_name')}}"
+ style="display:inline;">
+ <input type="hidden" name="collection_id" value="{{uc.id}}" />
+ <input type="text"
+ name="new_collection_name"
+ style="font-size: 20px; display: none; width: 500px;"
+ class="form-control"
+ placeholder="{{ uc.name }}" />
+ </form>
+ <button class="btn btn-default" style="display: inline;" id="change_collection_name">Change Collection Name</button>
+ <button class="btn btn-default" style="display: inline;" id="make_default">Make Default</button>
+ </h1>
+ <h3>This collection has {{ '{}'.format(numify(trait_obs|count, "record", "records")) }}</h3>
+
+ <div class="tool-button-container">
+ <form id="collection_form" action="/loading" method="post">
+ <input type="hidden" name="uc_id" id="uc_id" value="{{ uc.id }}" />
+ <input type="hidden" name="collection_name" id="collection_name" value="{{ uc.name }}" />
+ <input type="hidden" name="tool_used" value="" />
+ <input type="hidden" name="form_url" value="" />
+ <input type="hidden" name="trait_list" id="trait_list" value= "
+ {% for this_trait in trait_obs %}
+ {{ this_trait.name }}:{{ this_trait.dataset.name }}:{{ data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name)) }},
+ {% endfor %}" >
+
+ {% include 'tool_buttons.html' %}
+
+ </form>
+ </div>
+ <div style="display: flex;">
+ <form id="heatmaps_form">
+ <button id="clustered-heatmap"
+ class="btn btn-primary"
+ data-url="{{heatmap_data_url}}"
+ title="Generate heatmap from this collection" style="margin-top: 10px; margin-bottom: 10px;">
+ Generate Heatmap
+ </button>
+ <br>
+ <div id="heatmap-options" style="display: none;">
+ <div style="margin-bottom: 10px;">
+ <b>Heatmap Orientation: </b>
+ <br>
+ Vertical
+ <input id="heatmap-orient-vertical"
+ type="radio"
+ name="vertical"
+ value="true" checked="checked"/>
+ Horizontal
+ <input id="heatmap-orient-horizontal"
+ type="radio"
+ name="vertical"
+ value="false" />
+ </div>
+ <div style="margin-bottom: 10px;">
+ <button id="clear-heatmap"
+ class="btn btn-danger"
+ title="Clear Heatmap">
+ Clear Heatmap
+ </button>
+ </div>
+ </div>
+ </form>
+ &nbsp;
+ </div>
+
+ <div>
+ <div id="clustered-heatmap-image-area"></div>
+ <br />
+ <div class="collection-table-options">
+ <form id="export_form" method="POST" action="/export_traits_csv">
+ <button class="btn btn-default" id="select_all" type="button"><span class="glyphicon glyphicon-ok"></span> Select All</button>
+ <button class="btn btn-default" id="invert" type="button"><span class="glyphicon glyphicon-ok"></span> Invert</button>
+ <button class="btn btn-success" id="add" type="button" disabled><i class="icon-plus-sign"></i> Copy</button>
+ <input type="hidden" name="database_name" id="database_name" value="None">
+ <input type="hidden" name="export_data" id="export_data" value="">
+ <input type="hidden" name="file_name" id="file_name" value="collection_table">
+ <input type="hidden" name="collection_name_export" value="{{ uc.name }}">
+ <input type="hidden" name="user_email_export" value="{% if g.user_session.user_email %}{{ g.user_session.user_email }}{% else %}N/A{% endif %}">
+ <button class="btn btn-default" id="export_traits">Download</button>
+ <button class="btn btn-default" id="export_collection">Export Collection</button>
+ <input type="text" id="searchbox" class="form-control" style="width: 200px; display: inline; padding-bottom: 9px;" placeholder="Search Table For ...">
+ <input type="text" id="select_top" class="form-control" style="width: 200px; display: inline; padding-bottom: 9px;" placeholder="Select Top ...">
+ <button class="btn btn-default" id="deselect_all" type="button"><span class="glyphicon glyphicon-remove"></span> Deselect</button>
+ <button id="remove" class="btn btn-danger" data-url="/collections/remove" type="button" disabled><i class="icon-minus-sign"></i> Remove</button>
+ </form>
+ </div>
+ <div style="margin-top: 10px; margin-bottom: 5px;" class="show-hide-container">
+ <b>Show/Hide Columns:&nbsp;&nbsp;</b>
+ <button class="toggle-vis" data-column="1">Index</button>
+ <button class="toggle-vis" data-column="2">Dataset</button>
+ <button class="toggle-vis" data-column="3">Record</button>
+ <button class="toggle-vis" data-column="4">Symbol</button>
+ <button class="toggle-vis" data-column="5">Description</button>
+ <button class="toggle-vis" data-column="6">Location</button>
+ <button class="toggle-vis" data-column="7">Mean</button>
+ <button class="toggle-vis" data-column="8">Peak -logP</button>
+ <button class="toggle-vis" data-column="9">Peak Location</button>
+ <button class="toggle-vis" data-column="10">Effect Size</button>
+ </div>
+ <div id="trait_table_container" style="width: 2000px; min-width: 1500px;">
+ <table class="table-hover table-striped cell-border" id='trait_table' style="float: left;">
+ <tbody>
+ <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td>
+ </tbody>
+ </table>
+ </div>
+ <br />
+ </div>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/buttons.colVis.min.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+ <script type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
+ <script type="text/javascript" src="/static/new/javascript/create_datatable.js"></script>
+
+ <script type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script>
+
+ <script type="text/javascript"
+ src="/static/new/javascript/partial_correlations.js"></script>
+ <script type='text/javascript'>
+ var traitsJson = {{ traits_json|safe }};
+ </script>
+ <script language="javascript" type="text/javascript">
+ $(document).ready( function () {
+
+ tableId = "trait_table"
+
+ columnDefs = [
+ {
+ 'data': null,
+ 'width': "5px",
+ 'orderDataType': "dom-checkbox",
+ 'targets': 0,
+ 'render': function(data) {
+ return '<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + data.hmac + '" data-trait-info="' + data.trait_info_str + '">'
+ }
+ },
+ {
+ 'title': "Index",
+ 'type': "natural",
+ 'width': "35px",
+ 'searchable': false,
+ 'orderable': false,
+ 'targets': 1,
+ 'render': function(data, type, row, meta) {
+ return meta.row
+ }
+ },
+ {
+ 'title': "Dataset",
+ 'type': "natural",
+ 'targets': 2,
+ 'data': "dataset"
+ },
+ {
+ 'title': "Record",
+ 'type': "natural-minus-na",
+ 'width': "120px",
+ 'targets': 3,
+ 'data': null,
+ 'render': function(data) {
+ return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>'
+ }
+ },
+ {
+ 'title': "Symbol",
+ 'type': "natural",
+ 'targets': 4,
+ 'data': null,
+ 'render': function(data) {
+ if (Object.hasOwn(data, 'symbol')){
+ return data.symbol
+ } else if (Object.hasOwn(data, 'name')){
+ return data.name
+ } else {
+ return "N/A"
+ }
+ }
+ },
+ {
+ 'title': "Description",
+ 'type': "natural",
+ 'targets': 5,
+ 'data': null,
+ 'render': function(data) {
+ if (Object.hasOwn(data, 'description')){
+ try {
+ return decodeURIComponent(escape(data.description))
+ } catch(err){
+ return escape(data.description)
+ }
+ } else if (Object.hasOwn(data, 'location')){
+ return data.location
+ } else if (Object.hasOwn(data, 'name')){
+ return data.name
+ } else {
+ return "N/A"
+ }
+ }
+ },
+ {
+ 'title': "<div style='text-align: right;'>Location</div>",
+ 'type': "natural-minus-na",
+ 'width': "125px",
+ 'targets': 6,
+ 'data': null,
+ 'render': function(data) {
+ if (Object.hasOwn(data, 'location')){
+ return data.location
+ } else {
+ return "N/A"
+ }
+ }
+ },
+ {
+ 'title': "<div style='text-align: right;'>Mean</div>",
+ 'type': "natural-minus-na",
+ 'width': "60px",
+ 'data': null,
+ 'targets': 7,
+ 'orderSequence': [ "desc", "asc"],
+ 'render': function(data) {
+ if (Object.hasOwn(data, 'mean')){
+ if (data.mean != 'N/A'){
+ return data.mean.toFixed(3)
+ } else {
+ return "N/A"
+ }
+ } else {
+ return "N/A"
+ }
+ }
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Peak</div> <div style='text-align: right;'>-logP <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>",
+ 'type': "natural-minus-na",
+ 'data': null,
+ 'width': "60px",
+ 'targets': 8,
+ 'orderSequence': [ "desc", "asc"],
+ 'render': function(data) {
+ if (Object.hasOwn(data, 'lrs_score')){
+ return (data.lrs_score / 4.61).toFixed(3)
+ } else {
+ return "N/A"
+ }
+ }
+ },
+ {
+ 'title': "<div style='text-align: right;'>Peak Location</div>",
+ 'type': "natural-minus-na",
+ 'data': null,
+ 'width': "125px",
+ 'targets': 9,
+ 'render': function(data) {
+ if (Object.hasOwn(data, 'lrs_location')){
+ return data.lrs_location
+ } else {
+ return "N/A"
+ }
+ }
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Effect</div> <div style='text-align: right;'>Size <a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>",
+ 'type': "natural-minus-na",
+ 'data': null,
+ 'width': "85px",
+ 'targets': 10,
+ 'orderSequence': [ "desc", "asc"],
+ 'render': function(data) {
+ if (Object.hasOwn(data, 'additive')){
+ if (data.additive != "") {
+ return data.additive.toFixed(3)
+ } else {
+ return "N/A"
+ }
+ } else {
+ return "N/A"
+ }
+ }
+ }
+ ]
+
+ tableSettings = {
+ "createdRow": function ( row, data, index ) {
+ $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;");
+ $('td', row).eq(1).attr("align", "right");
+ $('td', row).eq(1).attr('data-export', index+1);
+ $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text());
+ $('td', row).eq(3).attr('title', $('td', row).eq(3).text());
+ $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text());
+ $('td', row).eq(4).attr('title', $('td', row).eq(4).text());
+ $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text());
+ $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text());
+ if ($('td', row).eq(5).text().length > 500) {
+ $('td', row).eq(5).text($('td', row).eq(5).text().substring(0, 500));
+ $('td', row).eq(5).text($('td', row).eq(5).text() + '...')
+ }
+ $('td', row).slice(6,11).attr("align", "right");
+ $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text());
+ $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text());
+ $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text());
+ $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text());
+ $('td', row).eq(10).attr('data-export', $('td', row).eq(9).text());
+ },
+ "order": [[1, "asc" ]],
+ {% if traits_json|length > 20 %}
+ "scroller": true
+ {% else %}
+ "scroller": false
+ {% endif %}
+ }
+
+ create_table(tableId, traitsJson, columnDefs, tableSettings)
+
+ submit_special = function(url) {
+ $("#collection_form").attr("action", url);
+ $("#collection_form").attr('target', '_blank').submit();
+ return false;
+ };
+
+ $("#delete").on("click", function() {
+ url = $(this).data("url")
+ $("#collection_form").attr("action", url);
+ return $("#collection_form").removeAttr('target').submit();
+ });
+
+ $("#remove").on("click", function() {
+ url = $(this).data("url")
+ traits = $("#trait_table input:checked").map(function() {
+ return $(this).val();
+ }).get();
+ $("#trait_list").val(traits)
+ $("#collection_form").attr("action", url);
+ return $("#collection_form").removeAttr('target').submit();
+ });
+
+ $("#change_collection_name").on("click", function() {
+ if ($('input[name=new_collection_name]').css('display') == 'none') {
+ $('input[name=new_collection_name]').css('display', 'inline');
+ $('#collection_name').css('display', 'none');
+ } else {
+ new_name = $('input[name=new_collection_name]').val();
+ $('#frm-change-collection-name').submit();
+ console.debug("We really should not get here, but, whatever...");
+ $('input[name=new_collection_name]').css('display', 'none');
+ $('input[name=collection_name]').val(new_name);
+ $('#collection_name').text(new_name)
+ $('#collection_name').css('display', 'inline');
+ }
+ });
+
+ make_default = function() {
+ alert("The current collection is now your default collection.")
+ let uc_id = $('#uc_id').val();
+ $.cookie('default_collection', uc_id, {
+ expires: 365,
+ path: '/'
+ });
+
+ let default_collection_id = $.cookie('default_collection');
+ };
+
+ $("#make_default").on("click", function(){
+ make_default();
+ });
+
+ $("#heatmaps_form").submit(function(e) {
+ e.preventDefault();
+ });
+
+ function clear_heatmap_area() {
+ area = document.getElementById("clustered-heatmap-image-area");
+ area.querySelectorAll("*").forEach(function(child) {
+ child.remove();
+ });
+ }
+
+ function generate_progress_indicator() {
+ count = 0;
+ default_message = "Computing"
+ return function() {
+ message = default_message;
+ if(count >= 10) {
+ count = 0;
+ }
+ for(i = 0; i < count; i++) {
+ message = message + " .";
+ }
+ clear_heatmap_area();
+ $("#clustered-heatmap-image-area").append(
+ '<div class="alert alert-info"' +
+ ' style="font-weigh: bold; font-size: 150%;">' +
+ message + '</div>');
+ count = count + 1;
+ };
+ }
+
+ function display_clustered_heatmap(heatmap_data) {
+ clear_heatmap_area();
+ image_area = document.getElementById("clustered-heatmap-image-area")
+ Plotly.newPlot(image_area, heatmap_data)
+ }
+
+ function process_clustered_heatmap_error(xhr, status, error) {
+ clear_heatmap_area()
+ $("#clustered-heatmap-image-area").append(
+ $(
+ '<div class="alert alert-danger">ERROR: ' +
+ xhr.responseJSON.message +
+ '</div>'));
+ }
+
+ $("#clustered-heatmap").on("click", function() {
+ clear_heatmap_area();
+ $("#heatmap-options").show();
+ intv = window.setInterval(generate_progress_indicator(), 300);
+ vert_element = document.getElementById("heatmap-orient-vertical");
+ vert_true = vert_element == null ? false : vert_element.checked;
+ heatmap_url = $(this).attr("data-url")
+ traits = $(".trait_checkbox:checked").map(function() {
+ return this.value
+ }).get();
+ $.ajax({
+ type: "POST",
+ url: heatmap_url,
+ contentType: "application/json",
+ data: JSON.stringify({
+ "traits_names": traits,
+ "vertical": vert_true
+ }),
+ dataType: "JSON",
+ success: function(data, status, xhr) {
+ window.clearInterval(intv);
+ display_clustered_heatmap(data);
+ },
+ error: function(xhr, status, error) {
+ window.clearInterval(intv);
+ process_clustered_heatmap_error(xhr, status, error);
+ }
+ });
+ });
+
+ $("#clear-heatmap").on("click", function() {
+ clear_heatmap_area();
+ $("#heatmap-options").hide();
+ });
+
+ });
+ </script>
+
+
+{% endblock %}
+
diff --git a/gn2/wqflask/templates/collections/view_anonymous.html b/gn2/wqflask/templates/collections/view_anonymous.html
new file mode 100644
index 00000000..56323e10
--- /dev/null
+++ b/gn2/wqflask/templates/collections/view_anonymous.html
@@ -0,0 +1,143 @@
+{% extends "base.html" %}
+{% block title %}View Collection{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ {% if uc %}
+ {{ header(uc.name,
+ 'This collection has {}.'.format(numify(trait_obs|count, "record", "records"))) }}
+ {% else %}
+ {{ header('Your Collection',
+ 'This collection has {}.'.format(numify(trait_obs|count, "record", "records"))) }}
+ {% endif %}
+ <div class="container">
+ <div class="page-header">
+ <h1>Your Collection</h1>
+ {% if uc %}
+ <h2>{{ uc.name }}</h2>
+ {% endif %}
+
+ <div class="form-group">
+ <form action="/collections/delete" method="post">
+ {% if uc %}
+ <input type="hidden" name="uc_id" id="uc_id" value="{{ uc.id }}" />
+ {% endif %}
+ <div class="col-xs-3 controls">
+ <input type="submit" class="btn btn-danger" value="Delete this collection" />
+ </div>
+ </form>
+ <form action="/corr_matrix" method="post">
+ {% if uc %}
+ <input type="hidden" name="uc_id" id="uc_id" value="{{ uc.id }}" />
+ {% endif %}
+ <input type="hidden" name="trait_list" id="trait_list" value= "
+ {% for this_trait in trait_obs %}
+ {{ this_trait.name }}:{{ this_trait.dataset.name }},
+ {% endfor %}" >
+ <div class="col-xs-2 controls">
+ <input type="submit" class="btn btn-primary" value="Correlation Matrix" />
+ </div>
+ </form>
+ <form action="/heatmap" method="post">
+ {% if uc %}
+ <input type="hidden" name="uc_id" id="uc_id" value="{{ uc.id }}" />
+ {% endif %}
+ <input type="hidden" name="trait_list" id="trait_list" value= "
+ {% for this_trait in trait_obs %}
+ {{ this_trait.name }}:{{ this_trait.dataset.name }},
+ {% endfor %}" >
+ <div class="col-xs-2 controls">
+ <input type="submit" class="btn btn-primary" value="Heatmap" />
+ </div>
+ </form>
+ </div>
+
+ <!--
+ <form action="/corr_matrix" method="post">
+ {% if uc %}
+ <input type="hidden" name="uc_id" id="uc_id" value="{{ uc.id }}" />
+ {% endif %}
+ <input type="hidden" name="trait_list" id="trait_list" value= "
+ {% for this_trait in trait_obs %}
+ {{ this_trait.name }}:{{ this_trait.dataset.name }},
+ {% endfor %}" >
+ <input type="submit"
+ class="btn btn-small"
+ value="Correlation Matrix" />
+ </form>
+ <form action="/heatmap" method="post">
+ {% if uc %}
+ <input type="hidden" name="uc_id" id="uc_id" value="{{ uc.id }}" />
+ {% endif %}
+ <input type="hidden" name="trait_list" id="trait_list" value= "
+ {% for this_trait in trait_obs %}
+ {{ this_trait.name }}:{{ this_trait.dataset.name }},
+ {% endfor %}" >
+ <input type="submit"
+ class="btn btn-small"
+ value="Heatmap" />
+ </form>
+ -->
+ </div>
+
+
+
+ <div class="bs-docs-example">
+ <table class="table table-hover" id='trait_table'>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Record</th>
+ <th>Description</th>
+ <th>Location</th>
+ <th>Mean</th>
+ <th>Max LRS</th>
+ <th>Max LRS Location</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for this_trait in trait_obs %}
+ <TR id="trait:{{ this_trait.name }}:{{ this_trait.dataset.name }}">
+ <TD>
+ <INPUT TYPE="checkbox" NAME="searchResult" class="checkbox trait_checkbox"
+ VALUE="{{ data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name)) }}">
+ </TD>
+ <TD>
+ <a href="{{ url_for('show_trait_page',
+ trait_id = this_trait.name,
+ dataset = this_trait.dataset.name
+ )}}">
+ {{ this_trait.name }}
+ </a>
+ </TD>
+
+ <TD>{{ this_trait.description_display }}</TD>
+ <TD>{{ this_trait.location_repr }}</TD>
+ <TD>{{ this_trait.mean }}</TD>
+ <TD>{{ this_trait.LRS_score_repr }}</TD>
+ <TD>{{ this_trait.LRS_location_repr }}</TD>
+
+ </TR>
+ {% endfor %}
+ </tbody>
+
+ </table>
+
+ <br />
+
+ <button class="btn" id="select_all"><i class="icon-ok"></i> Select All</button>
+ <button class="btn" id="deselect_all"><i class="icon-remove"></i> Deselect All</button>
+ <button class="btn" id="invert"><i class="icon-resize-vertical"></i> Invert</button>
+ <button class="btn" id="add" disabled="disabled"><i class="icon-plus-sign"></i> Add Record to Other Collection</button>
+ <button class="btn" id="remove" disabled="disabled"><i class="icon-minus-sign"></i> Remove Record</button>
+ <button class="btn btn-primary pull-right"><i class="icon-download icon-white"></i> Download Table</button>
+ </div>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/comparison_bar_chart.html b/gn2/wqflask/templates/comparison_bar_chart.html
new file mode 100644
index 00000000..d77e0515
--- /dev/null
+++ b/gn2/wqflask/templates/comparison_bar_chart.html
@@ -0,0 +1,38 @@
+{% extends "base.html" %}
+{% block title %}Comparison Bar Chart{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/panelutil.css" />
+{% endblock %}
+{% block content %} <!-- Start of body -->
+ <div class="container">
+ <h1>Comparison Bar Chart</h1>
+ <hr style="height: 1px; background-color: #A9A9A9;">
+ <div>
+ <h3>
+ The following is a grouped bar chart with the sample values for each selected trait.
+ </h3>
+ </div>
+ <div id="chart_container">
+ <div id="comp_bar_chart"></div>
+ </div>
+
+ </div>
+
+ <!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script>
+ js_data = {{ js_data | safe }}
+ </script>
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/panelutil.js"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/comparison_bar_chart.js"></script>
+
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/corr_scatterplot.html b/gn2/wqflask/templates/corr_scatterplot.html
new file mode 100644
index 00000000..554471be
--- /dev/null
+++ b/gn2/wqflask/templates/corr_scatterplot.html
@@ -0,0 +1,364 @@
+{% extends "base.html" %}
+
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/panelutil.css" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='nvd3/nv.d3.min.css') }}">
+ <link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/corr_scatter_plot.css" />
+{% endblock %}
+
+{% block content %}
+
+<div class="container-fluid">
+
+ <input type="hidden" name="cofactor1_vals"></input>
+ <input type="hidden" name="ranked_cofactor1_vals"></input>
+ <input type="hidden" name="cofactor2_vals"></input>
+ <input type="hidden" name="ranked_cofactor2_vals"></input>
+ <input type="hidden" name="cofactor3_vals"></input>
+ <input type="hidden" name="ranked_cofactor3_vals"></input>
+ <input type="hidden" name="selecting_which_cofactor"></input>
+
+ <h1>Correlation Scatterplot</h1>
+ <hr style="height: 1px; background-color: #A9A9A9;">
+
+ <table>
+ <tr>
+ <td style="vertical-align: middle;">Width <input class="chartupdatewh" id="width" type="text" value="800" style="width: 44px; height: 22px;"> px </td>
+ <td style="vertical-align: middle; padding-left: 5px;">Height <input class="chartupdatewh" id="height" type="text" value="700" style="width: 44px; height: 22px;"> px</td>
+ <td style="vertical-align: middle; padding-left: 5px;"><button type="button" class="btn btn-default" id="invert_axes">
+ Invert Axes
+ </button></td>
+ </tr>
+ </table>
+ <hr style="height: 1px; background-color: #A9A9A9;">
+ {% if collections_exist == "True" %}
+ <div>
+ <div style="margin-bottom: 10px;">
+ You can select up to three traits from a saved trait collection to use as cofactors in the scatterplots, with each trait corresponding to point color, size, or symbol.
+ For symbol, traits must have no more than 4 distinct values.
+ </div>
+ <div style="display: inline-block;">
+ <div id="cofactor1_button" style="display: inline-block;">
+ <button type="button" class="btn btn-default" id="select_cofactor1">
+ Select Cofactor 1
+ </button>
+ <select id="cofactor1_type">
+ <option value="color" selected>Color</option>
+ <option value="size">Size</option>
+ <option value="symbol">Symbol</option>
+ </select>
+ </div>
+ <div id="cofactor2_button" style="margin-left: 10px; display: none;">
+ <button type="button" class="btn btn-default" id="select_cofactor2">
+ Add a Second Cofactor?
+ </button>
+ <select id="cofactor2_type">
+ <option value="color">Color</option>
+ <option value="size" selected>Size</option>
+ <option value="symbol">Symbol</option>
+ </select>
+ </div>
+ <div id="cofactor3_button" style="margin-left: 10px; display: none;">
+ <button type="button" class="btn btn-default" id="select_cofactor3">
+ Add a Third Cofactor?
+ </button>
+ <select id="cofactor3_type">
+ <option value="color">Color</option>
+ <option value="size">Size</option>
+ <option value="symbol" selected>Symbol</option>
+ </select>
+ </div>
+ <div id="remove_cofactors_button" style="margin-left: 20px; display: inline-block;">
+ <button type="button" class="btn btn-danger" id="remove_cofactors">
+ Remove Cofactors
+ </button>
+ </div>
+ </div>
+ </div>
+ <div id="collections_holder_wrapper" style="display:none;">
+ <div id="collections_holder"></div>
+ </div>
+
+ <div id="cofactor_color_selector" style="margin-bottom: 10px; display:none;">
+ <hr>
+ <b>Cofactor Color Range:</b>
+ <input class="chartupdatedata" name="color2" type="hidden" id="cocolorfrom" value="#0000FF">
+ <button class="chartupdatedata jscolor {valueElement: 'cocolorfrom'}">Low</button>
+ <input class="chartupdatedata" name="color1" type="hidden" id="cocolorto" value="#FF0000">
+ <button class="chartupdatedata jscolor {valueElement: 'cocolorto'}">High</button>
+ <hr>
+ </div>
+
+ <div id="cofactor1_info_container" style="margin-left: 0px; display: none;">
+ <div>
+ <b>Cofactor 1</b>: <a id="cofactor1_trait_link" href="#"></a>
+ </div>
+ <div id="cofactor1_description"></div>
+ <hr>
+ </div>
+
+ <div id="cofactor2_info_container" style="margin-left: 0px; display: none;">
+ <div>
+ <b>Cofactor 2</b>: <a id="cofactor2_trait_link" href="#"></a>
+ </div>
+ <div id="cofactor2_description"></div>
+ <hr>
+ </div>
+
+ <div id="cofactor3_info_container" style="margin-left: 0px; display: none;">
+ <div>
+ <b>Cofactor 3</b>: <a id="cofactor3_trait_link" href="#"></a>
+ </div>
+ <div id="cofactor3_description"></div>
+ <hr>
+ </div>
+
+ {% else %}
+ <div style="margin-bottom: 10px;">No collections currently exist. Please create a collection first if you wish to include cofactors in the scatterplots.</div>
+ <hr>
+ {% endif %}
+
+ <ul class="nav nav-tabs">
+ <li {% if method == 'pearson' %}class="active"{% endif %}>
+ <a href="#tp1" data-toggle="tab">Pearson</a>
+ </li>
+ <li {% if method == 'spearman' %}class="active"{% endif %}>
+ <a href="#tp2" data-toggle="tab">Spearman Rank</a>
+ </li>
+ </ul>
+
+ <div class="tab-content" style="min-width: 800px;">
+
+ <div class="tab-pane {% if method == 'pearson' %}active{% endif %}" id="tp1">
+ <br>
+ <div id="scatterplot2"></div>
+ <br>
+ <div style="min-width: 700px; overflow: hidden;">
+ <div style="margin-left: 50px; min-width: 300px;">
+ {% if trait_1.dataset.type == "ProbeSet" %}
+ <div>
+ X axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_1.name, dataset = trait_1.dataset.name)}}">
+ {{trait_1.dataset.group.species + " " + trait_1.dataset.group.name + " " + trait_1.dataset.tissue + " " + trait_1.dataset.name + ": " + trait_1.name|string}}
+ </a>
+ </div>
+ <div>
+ [{{trait_1.symbol}} on {{trait_1.location_repr}} Mb]
+ {{trait_1.description_display}}
+ </div>
+ {% elif trait_1.dataset.type == "Publish" %}
+ <div>
+ X axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_1.name, dataset = trait_1.dataset.name)}}">
+ {{trait_1.dataset.group.species + " " + trait_1.dataset.group.name + " " + trait_1.dataset.name + ": " + trait_1.name|string}}
+ </a>
+ </div>
+ <div>
+ <a href="{{trait_1.pubmed_link}}">PubMed: {{trait_1.pubmed_text}}</a>
+ {{trait_1.description_display}}
+ </div>
+ {% elif trait_1.dataset.type == "Geno" %}
+ <div>
+ X axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_1.name, dataset = trait_1.dataset.name)}}">
+ {{trait_1.dataset.group.species + " " + trait_1.dataset.group.name + " " + trait_1.dataset.name + ": " + trait_1.name|string}}
+ </a>
+ </div>
+ <div>
+ Location: {{trait_1.location_repr}} Mb
+ </div>
+ {% endif %}
+
+ <br/>
+
+ {% if trait_2.dataset.type == "ProbeSet" %}
+ <div>
+ Y axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_2.name, dataset = trait_2.dataset.name)}}">
+ {{trait_2.dataset.group.species + " " + trait_2.dataset.group.name + " " + trait_2.dataset.tissue + " " + trait_2.dataset.name + ": " + trait_2.name|string}}
+ </a>
+ </div>
+ <div>
+ [{{trait_2.symbol}} on {{trait_2.location_repr}} Mb]
+ {{trait_2.description_display}}
+ </div>
+ {% elif trait_2.dataset.type == "Publish" %}
+ <div>
+ Y axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_2.name, dataset = trait_2.dataset.name)}}">
+ {{trait_2.dataset.group.species + " " + trait_2.dataset.group.name + " " + trait_2.dataset.name + ": " + trait_2.name|string}}
+ </a>
+ </div>
+ <div>
+ <a href="{{trait_2.pubmed_link}}">PubMed: {{trait_2.pubmed_text}}</a>
+ {{trait_2.description_display}}
+ </div>
+ {% elif trait_2.dataset.type == "Geno" %}
+ <div>
+ Y axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_2.name, dataset = trait_2.dataset.name)}}">
+ {{trait_2.dataset.group.species + " " + trait_2.dataset.group.name + " " + trait_2.dataset.name + ": " + trait_2.name|string}}
+ </a>
+ </div>
+ <div>
+ Location: {{trait_2.location_repr}} Mb
+ </div>
+ {% endif %}
+ </div>
+ <div style="float: left; margin-top:30px;">
+ <table class="table table-hover table-striped table-bordered" style="width: 80%; margin-left: 60px; text-align: right;">
+ <thead>
+ <tr><th style="text-align: right;">Statistic</th><th style="text-align: right;">Value</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Number</td>
+ <td>{{jsdata.num_overlap}}</td>
+ </tr>
+ <tr>
+ <td>Slope</td>
+ <td>{{ jsdata.slope_string }}</td>
+ </tr>
+ <tr>
+ <td>Intercept</td>
+ <td>{{'%0.3f' % jsdata.intercept}}</td>
+ </tr>
+ <tr>
+ <td>r value</td>
+ <td>{{'%0.3f' % jsdata.r_value}}</td>
+ </tr>
+ <tr>
+ <td>P value</td>
+ <td>{% if jsdata.p_value < 0.001 %}{{'%0.3e' % jsdata.p_value}}{% else %}{{'%0.3f' % jsdata.p_value}}{% endif %}</td>
+ </tr>
+ <tr>
+ <td style="text-align: left;" colspan="2">
+ Regression Line
+ <br>
+ y = {{ jsdata.slope_string }} * x {% if jsdata.intercept < 0 %}- {{'%0.3f' % (jsdata.intercept * -1)}}{% else %}+ {{'%0.3f' % jsdata.intercept}}{% endif %}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+ <div class="tab-pane {% if method == 'spearman' %}active{% endif %}" id="tp2">
+ <br>
+ <div id="srscatterplot2"></div>
+ <br>
+ <div class="row" style="min-width: 700px; overflow: hidden;">
+ <div style="margin-left: 50px; min-width: 300px;">
+ {% if trait_1.dataset.type == "ProbeSet" %}
+ <div>
+ X axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_1.name, dataset = trait_1.dataset.name)}}">
+ {{trait_1.dataset.group.species + " " + trait_1.dataset.group.name + " " + trait_1.dataset.tissue + " " + trait_1.dataset.name + ": " + trait_1.name|string}}
+ </a>
+ </div>
+ <div>
+ [{{trait_1.symbol}} on {{trait_1.location_repr}} Mb]
+ {{trait_1.description_display}}
+ </div>
+ {% elif trait_1.dataset.type == "Publish" %}
+ <div>
+ X axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_1.name, dataset = trait_1.dataset.name)}}">
+ {{trait_1.dataset.group.species + " " + trait_1.dataset.group.name + " " + trait_1.dataset.name + ": " + trait_1.name|string}}
+ </a>
+ </div>
+ <div>
+ <a href="{{trait_1.pubmed_link}}">PubMed: {{trait_1.pubmed_text}}</a>
+ {{trait_1.description_display}}
+ </div>
+ {% endif %}
+
+ <br/>
+
+ {% if trait_2.dataset.type == "ProbeSet" %}
+ <div>
+ Y axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_2.name, dataset = trait_2.dataset.name)}}">
+ {{trait_2.dataset.group.species + " " + trait_2.dataset.group.name + " " + trait_2.dataset.tissue + " " + trait_2.dataset.name + ": " + trait_2.name|string}}
+ </a>
+ </div>
+ <div>
+ [{{trait_2.symbol}} on {{trait_2.location_repr}} Mb]
+ {{trait_2.description_display}}
+ </div>
+ {% elif trait_2.dataset.type == "Publish" %}
+ <div>
+ Y axis:
+ <a href="{{url_for('show_trait_page', trait_id = trait_2.name, dataset = trait_2.dataset.name)}}">
+ {{trait_2.dataset.group.species + " " + trait_2.dataset.group.name + " " + trait_2.dataset.name + ": " + trait_2.name|string}}
+ </a>
+ </div>
+ <div>
+ <a href="{{trait_2.pubmed_link}}">PubMed: {{trait_2.pubmed_text}}</a>
+ {{trait_2.description_display}}
+ </div>
+ {% endif %}
+ </div>
+ <div style="float: left; margin-top: 30px;">
+ <table class="table table-hover table-striped table-bordered" style="width: 80%; margin-left: 60px; text-align: right;">
+ <thead>
+ <tr><th style="text-align: right;">Statistic</th><th style="text-align: right;">Value</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Number</td>
+ <td>{{jsdata.num_overlap}}</td>
+ </tr>
+ <tr>
+ <td>Slope</td>
+ <td>{{ jsdata.srslope_string }}</td>
+ </tr>
+ <tr>
+ <td>Intercept</td>
+ <td>{{'%0.3f' % jsdata.srintercept}}</td>
+ </tr>
+ <tr>
+ <td>r value</td>
+ <td>{{'%0.3f' % jsdata.srr_value}}</td>
+ </tr>
+ <tr>
+ <td>P value</td>
+ <td>{% if jsdata.srp_value < 0.001 %}{{'%0.3e' % jsdata.srp_value}}{% else %}{{'%0.3f' % jsdata.srp_value}}{% endif %}</td>
+ </tr>
+ <tr>
+ <td style="text-align: left;" colspan="2">
+ Regression Line
+ <br>
+ y = {{ jsdata.srslope_string }} * x {% if jsdata.srintercept < 0 %}- {{'%0.3f' % (jsdata.srintercept * -1)}}{% else %}+ {{'%0.3f' % jsdata.srintercept}}{% endif %}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+</div>
+
+{% endblock %}
+
+{% block js %}
+ <script>
+ js_data = {{ js_data | safe }};
+ </script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jscolor/jscolor.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/panelutil.js"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <!--<script language="javascript" type="text/javascript" src="/static/new/javascript/get_traits_from_collection.js"></script>-->
+ <script type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/draw_corr_scatterplot.js"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/correlation_error_page.html b/gn2/wqflask/templates/correlation_error_page.html
new file mode 100644
index 00000000..7d11daf0
--- /dev/null
+++ b/gn2/wqflask/templates/correlation_error_page.html
@@ -0,0 +1,23 @@
+{%extends "base.html"%}
+{%block title%}Correlation Results{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonsBootstrap/css/buttons.bootstrap.css') }}" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/all.min.css') }}"/>
+<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container">
+ <h3 style="color: red;">{{error["error-type"]}}</h3>
+ <p>{{error["error-message"]}}</p>
+ <p style="background-color: black; color: green;">
+ {%for line in error["stderr-output"]%}
+ {{line}}<br />
+ {%endfor%}
+ </p>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/correlation_matrix.html b/gn2/wqflask/templates/correlation_matrix.html
new file mode 100644
index 00000000..17fd66fa
--- /dev/null
+++ b/gn2/wqflask/templates/correlation_matrix.html
@@ -0,0 +1,203 @@
+{% extends "base.html" %}
+{% block title %}Correlation Matrix{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/corr_matrix.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/panelutil.css" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
+{% endblock %}
+{% block content %}
+
+<div class="container" width="100%">
+<h1>Correlation Matrix</h1>
+<div style="width: 100%; max-width: 850px;">Select any cell in the matrix to generate a <b>scatter plot.</b><br><b>Lower left</b> cells list Pearson product-moment correlations; <b>upper right</b> cells list Spearman rank order correlations. Each cell also contains the <b><i>n</i> of cases</b> in parenthesis. Values ranging from 0.4 to 1.0 range from orange to white, while values ranging from –0.4 to –1.0 range from dark blue to white.</div>
+<hr style="height: 1px; background-color: #A9A9A9;">
+{% if lowest_overlap < 8 %}
+<div style="margin-bottom: 10px;"><i><font style="color: red;">Caution</font>: This matrix of correlations contains some cells with small sample sizes of fewer than 8.</i></div>
+{% endif %}
+<table class="matrix" border="1" cellpadding="5" cellspacing="1" width="100%">
+ <tbody>
+ <tr>
+ <td style="background-color: #369;" ></td>
+ <td align="center" colspan="{{traits|length + 2 }}" style="font-weight: Bold; border: 1px solid #000000; padding: 3px; color: #fff; background-color: #369;">Spearman Rank Correlation (rho)</td>
+ </tr>
+ <tr>
+ <td align="center" rowspan="{{traits|length + 2 }}" width="10" style="font-weight: Bold; border: 1px solid #000000; padding: 3px; color: #fff; background-color: #369;">P e a r s o n &nbsp;&nbsp;&nbsp; r</td>
+ <td></td>
+ <td width="300" align="center" style="white-space: nowrap"><div style="display: inline-block; margin: 4px;"><button class="btn btn-default" id="short_labels" style="display: inline-block"><span style="display: none;" class="short_check glyphicon glyphicon-ok"></span>&nbsp;Short Labels</button>&nbsp;&nbsp;<button class="btn btn-default" id="long_labels" style="display: inline-block;"><span style="display: none;" class="long_check glyphicon glyphicon-ok"></span>&nbsp;Long Labels</button></div></td>
+ {% for trait in traits %}
+ <td align="center" style="padding: 5px;">
+ <a href="/show_trait?trait_id={{ trait.name }}&dataset={{ trait.dataset.name }}"><font style="font-size: 14px;"><b>{{ loop.index }}</b></font></a>
+ </td>
+ {% endfor %}
+ </tr>
+ {% for trait in traits %}
+ {% set outer_loop = loop.index %}
+ <tr>
+ <td align="center"><input type="checkbox" class="checkbox" style="margin-left: 3px; margin-right: 1px;"></td>
+ <td align="right" style="padding-right: 4px;" >
+ <a href="/show_trait?trait_id={{ trait.name }}&dataset={{ trait.dataset.name }}"><font style="font-size: 14px; font-style: Bold;"><b>{{ loop.index }}: {{ trait.dataset.name }}&nbsp;&nbsp;{{ trait.name }}</b></font></a>
+ <div class="shortName">{% if trait.dataset.type == "ProbeSet" %}Gene Symbol: {{ trait.symbol }}{% elif trait.dataset.type == "Publish" %}Trait Symbol: {{ trait.post_publication_abbreviation }}{% elif trait.dataset.type == "Geno" %}Genotype{% endif %} </div>
+ <div class="verboseName" style="display: none;">
+ {% if trait.dataset.type == "ProbeSet" %}
+ <div>{{ trait.symbol }} on Chr {{ trait.chr }} @ {{ trait.mb }} Mb</div><div>{{ trait.description }}</div><div>{{ trait.probe_target_description }}</div>
+ {% elif trait.dataset.type == "Publish" %}
+ <div>PMID: <a href="http://www.ncbi.nlm.nih.gov/pubmed/?term={{ trait.pubmed_id }}">{{ trait.pubmed_id }}</a>, Record ID {{ trait.name }}</div><div>Phenotype: {{ trait.description_display }}</div>
+ {% elif trait.dataset.type == "Geno" %}
+ <div>Locus {{ trait.name }}</div><div>Chr {{ trait.chr }} @ {{ trait.mb }} Mb</div>
+ {% endif %}
+ </div>
+ </td>
+ {% for result in corr_results[loop.index-1] %}
+ {% if result[0].name == trait.name and result[0].dataset == trait.dataset %}
+ <td nowrap="ON" align="center" bgcolor="#cccccc" style="padding: 3px; line-height: 1.1;"><a href="/show_trait?trait_id={{ trait.name }}&dataset={{ trait.dataset.name }}"><font style="font-size: 12px; color: #3071a9; font-weight: bold;" ><em>n</em><br>{{ result[2] }}</font></a></td>
+ {% else %}
+ {% if result[1] == 0 %}
+ <td nowrap="ON" align="middle" bgcolor="#eeeeee" style="padding: 3px; line-height: 1.1;">N/A</td>
+ {% else %}
+ <td nowrap="ON" align="middle" class="corr_cell" style="padding: 3px; line-height: 1.1;"><a href="/corr_scatter_plot?method={% if loop.index > outer_loop %}spearman{% else %}pearson{% endif %}&dataset_1={% if trait.dataset.name == 'Temp' %}Temp_{{ trait.dataset.group.name }}{% else %}{{ trait.dataset.name }}{% endif %}&dataset_2={% if result[0].dataset.name == 'Temp' %}Temp_{{ result[0].dataset.group.name }}{% else %}{{ result[0].dataset.name }}{% endif %}&trait_1={{ trait.name }}&trait_2={{ result[0].name }}"><span class="corr_value" style="font-size: 14px; color: #3071a9; font-weight: bold;">{{ '%0.2f' % result[1] }}</span><br><span class="corr_value" style="font-size: 12px; color: #3071a9; font-weight: bold;">({{ result[2] }})</span></a></td>
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+<br>
+<form method="post" target="_blank" action="/export_corr_matrix" id="matrix_export_form">
+ <input type="hidden" name="export_filepath" value="{{ export_filepath }}">
+ <input type="hidden" name="export_filename" value="{{ export_filename }}">
+ <button class="btn btn-default" id="export">Download <span class="glyphicon glyphicon-download"></span></button>
+</form>
+<br>
+
+{% if pca_works == "True" %}
+<div>
+ {% include 'pca_scree_plot.html' %}
+</div>
+
+<h2>PCA Traits</h2>
+<div style="margin-bottom: 20px; overflow:hidden; width: 450px;">
+<table class="table-hover table-striped cell-border pca_table" id='trait_table' style="float: left;">
+ <colgroup>
+ <col span="1" style="width: 30px;">
+ <col span="1" style="width: 50px;">
+ <col span="1">
+ </colgroup>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>PCA Trait</th>
+ </tr>
+ </tr>
+ </thead>
+ <tbody>
+ {% for this_trait_id in pca_trait_ids %}
+ <tr>
+ <td align="center" style="padding: 0px;"><input type="checkbox" class="trait_checkbox" name="pca_trait" value="{{ data_hmac('{}:{}'.format(pca_trait_ids[loop.index - 1], "Temp")) }}"></td>
+ <td align="right">{{ loop.index }}</td>
+ <td><a href="{{ url_for('show_trait_page', trait_id = pca_trait_ids[loop.index - 1], dataset = "Temp") }}">{{ pca_trait_ids[loop.index - 1] }}</a></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+<br>
+<button class="btn btn-default" id="select_all"><span class="glyphicon glyphicon-ok"></span> Select All</button>
+<button class="btn btn-default" id="deselect_all"><span class="glyphicon glyphicon-remove"></span> Deselect All</button>
+<button class="btn btn-success" id="add" disabled><span class="glyphicon glyphicon-plus-sign"></span> Add</button>
+</div>
+<h2>Factor Loadings Plot</h2>
+<div id="loadings_plot" style="margin-top: 20px; margin-bottom: 20px; width: 980px; border-style: solid; border-width: 1px;"></div>
+<h2>Factor Loadings Table</h2>
+<table class="table-hover table-striped cell-border loadings_table" id='trait_table' style="float: left;">
+ <thead>
+ <tr>
+ <th>Trait</th>
+ <th style="text-align: right;" >Factor 1</th>
+ <th style="text-align: right;" >Factor 2</th>
+ {% if trait_list|length > 2 %}<th style="text-align: right;">Factor 3</th>{% endif %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for row in loadings_array %}
+ {% set row_counter = loop.index-1 %}
+ <tr>
+ <td>
+ <a title="{% if traits[loop.index-1].dataset.type == "ProbeSet" %}{{ traits[loop.index-1].symbol }}{% elif traits[loop.index-1].dataset.type == "Publish" %}{{ traits[loop.index-1].post_publication_abbreviation }}{% endif %}" href="{{ url_for('show_trait_page', trait_id = traits[loop.index-1].name, dataset = traits[loop.index-1].dataset.name) }}">
+ {{ traits[loop.index-1].name }}
+ </a>
+ </td>
+ {% for column in row %}
+ <td><span style="float: right;">{{ '%0.3f' % loadings_array[row_counter][loop.index-1]|float }}</span></td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+
+ </tbody>
+</table>
+</div>
+{% endif %}
+<div id="myModal"></div>
+{% endblock %}
+
+{% block js %}
+
+ <script>
+ js_data = {{ js_data | safe }}
+ loadings = {{ loadings_array | safe }}
+ </script>
+
+ <script type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/panelutil.js"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='chroma/chroma.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/loadings_plot.js"></script>
+ <script type="text/javascript" src="/static/new/javascript/create_corr_matrix.js"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+
+ <script>
+ $('.pca_table').dataTable( {
+ "columnDefs": [ {
+ "targets": 0,
+ "orderable": false
+ } ],
+ "order": [[1, "asc" ]],
+ "sDom": "t",
+ "iDisplayLength": -1,
+ "autoWidth": true,
+ "bDeferRender": true,
+ "bSortClasses": false,
+ "paging": false,
+ "orderClasses": true
+ } );
+
+ $('.loadings_table').dataTable( {
+ "columnDefs": [ {
+ "targets": 0,
+ "orderable": false
+ } ],
+ "order": [[1, "asc" ]],
+ "sDom": "t",
+ "iDisplayLength": -1,
+ "autoWidth": true,
+ "bDeferRender": true,
+ "bSortClasses": false,
+ "paging": false,
+ "orderClasses": true
+ } );
+
+ export_corr_matrix = function() {
+ $('#matrix_export_form').attr('action', '/export_corr_matrix');
+ return $('#matrix_export_form').submit();
+ }
+
+ $('#export').click(export_corr_matrix);
+
+ </script>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/correlation_page.html b/gn2/wqflask/templates/correlation_page.html
new file mode 100644
index 00000000..d3ee32f3
--- /dev/null
+++ b/gn2/wqflask/templates/correlation_page.html
@@ -0,0 +1,550 @@
+{% extends "base.html" %}
+{% block title %}Correlation Results{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonsBootstrap/css/buttons.bootstrap.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}">
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/all.min.css') }}"/>
+ <link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+ <div class="container">
+ <div class="page-header">
+ <h1>Correlation Table</h1>
+ <h2>Trait: {{ this_trait.name }}
+
+ <hr style="height: 1px; background-color: #A9A9A9;">
+ </div>
+ <div style="max-width: 100%;">
+ <p>Values of record {{ this_trait.name }} in the <a href="http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&{% if this_dataset.accession_id %}GN_AccessionId={{ this_dataset.accession_id }}{% else %}InfoPageName={{ this_dataset.name }}{% endif %}">{{ this_dataset.fullname }}</a>
+ dataset were compared to all records in the <a href="http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&{% if target_dataset.accession_id %}GN_AccessionId={{ target_dataset.accession_id }}{% else %}InfoPageName={{ target_dataset.name }}{% endif %}">{{ target_dataset.fullname }}</a>
+ dataset. The top {{ return_results }} correlations ranked by the {{ formatted_corr_type }} are displayed.
+ You can resort this list by clicking the headers. Select the Record ID to open the trait data
+ and analysis page.
+ </p>
+ </div>
+ <div class="tool-button-container">
+ <form id="correlation_form" target="_blank" action="/corr_matrix" method="post">
+ <input type="hidden" name="tool_used" value="" />
+ <input type="hidden" name="form_url" value="" />
+ <input type="hidden" name="trait_list" id="trait_list" value= "
+ {% for this_trait in trait_list %}
+ {{ this_trait }}:{{ this_dataset.name }},
+ {% endfor %}" >
+ {% include 'tool_buttons.html' %}
+ </form>
+ </div>
+ <br />
+ <div style="min-width: 900px;">
+ <form id="export_form" method="POST" action="/export_traits_csv">
+ <button class="btn btn-default" id="select_all" type="button"><span class="glyphicon glyphicon-ok"></span> Select All</button>
+ <button class="btn btn-default" id="invert" type="button"><span class="glyphicon glyphicon-adjust"></span> Invert</button>
+ <button class="btn btn-success" id="add" type="button" disabled><span class="glyphicon glyphicon-plus-sign"></span> Add</button>
+ <input type="hidden" name="database_name" id="database_name" value="None">
+ <input type="hidden" name="export_data" id="export_data" value="">
+ <input type="hidden" name="file_name" id="file_name" value="{{ this_trait.name }}_{{ this_dataset.name }}_correlation">
+ <input type="text" id="searchbox" class="form-control" style="width: 200px; display: inline;" placeholder="Search Table For ...">
+ <input type="text" id="select_top" class="form-control" style="width: 200px; display: inline;" placeholder="Select Rows (1-5, 11)">
+ <button class="btn btn-default" id="deselect_all" type="button"><span class="glyphicon glyphicon-remove"></span> Deselect</button>
+ <button id="redraw" class="btn btn-default" type="button">Reset Columns</button>
+ </form>
+ <br />
+ <div id="export_options" style="float: left;"></div>
+ <br />
+ <div style="float: left; clear: left; margin-top: 10px; margin-bottom: 20px;">
+ <button id="more_options" class="btn btn-primary">More Options...</button>
+ </div>
+ <br />
+ <br />
+ <div id="filter_options" style="display: none; float: left; clear: left;">
+ <span style="border: 1px dashed #999999; padding: 8px; background-color: #ddf; font-size: 12px;">
+ <button id="select_traits" class="btn btn-primary" style="font-size: 12px; padding: 2px 3px;">Select Traits</button> with r >
+ <input type="text" name="r_greater_select" value="-1.0" size="6" maxlength="10">
+ <select id="r_and_or" size="1">
+ <option value="and" selected>AND</option>
+ <option value="or">OR</option>
+ </select>
+ r <
+ <input type="text" name="r_less_select" value="1.0" size="6" maxlength="10">, with mean >
+ <input type="text" name="mean_greater_select" value="0" size="6" maxlength="10">
+ <select id="mean_and_or" size="1">
+ <option value="and" selected>AND</option>
+ <option value="or">OR</option>
+ </select>
+ mean <
+ <input type="text" name="mean_less_select" value="100" size="6" maxlength="10">
+ </span>
+ <br />
+ <br />
+ </div>
+ </div>
+ <div class="show-hide-container" style="float: left; clear: left;">
+ <b>Show/Hide Columns:</b>
+ <br>
+ {% if target_dataset.type == 'ProbeSet' %}
+ <button class="toggle-vis" data-column="3">Symbol</button>
+ <button class="toggle-vis" data-column="4">Description</button>
+ <button class="toggle-vis" data-column="5">Location</button>
+ <button class="toggle-vis" data-column="6">Mean</button>
+ <button class="toggle-vis" data-column="7">Peak -logP</button>
+ <button class="toggle-vis" data-column="8">Peak Location</button>
+ <button class="toggle-vis" data-column="9">Effect Size</button>
+ {% elif target_dataset.type == 'Publish' %}
+ <button class="toggle-vis" data-column="3">Abbreviation</button>
+ <button class="toggle-vis" data-column="4">Description</button>
+ <button class="toggle-vis" data-column="5">Mean</button>
+ <button class="toggle-vis" data-column="6">Authors</button>
+ <button class="toggle-vis" data-column="7">Year</button>
+ <button class="toggle-vis" data-column="8">Sample {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}</button>
+ <button class="toggle-vis" data-column="9">N</button>
+ <button class="toggle-vis" data-column="10">Sample p({% if corr_method == 'pearson' %}r{% else %}rho{% endif %})</button>
+ <button class="toggle-vis" data-column="11">Peak -logP</button>
+ <button class="toggle-vis" data-column="12">Peak Location</button>
+ <button class="toggle-vis" data-column="13">Effect Size</button>
+ {% else %}
+ <button class="toggle-vis" data-column="3">Location</button>
+ <button class="toggle-vis" data-column="4">Sample {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}</button>
+ <button class="toggle-vis" data-column="5">N</button>
+ <button class="toggle-vis" data-column="6">Sample p({% if corr_method == 'pearson' %}r{% else %}rho{% endif %})</button>
+ {% endif %}
+ </div>
+ <div style="width: 90%; {% if target_dataset.type == "ProbeSet" %}min-width: 1700px;{% elif target_dataset.type == "Publish" %}min-width: 1600px;{% else %}width: 650px;{% endif %}">
+ <table id="trait_table" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ {% for header in header_fields %}
+ <th {% if header != "" %}data-export="{{ header }}"{% endif %}>{{header}}</th>
+ {% endfor %}
+ </tr>
+ </thead>
+
+ <tbody>
+ <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td>
+ </tbody>
+ </table>
+ </div>
+ </div>
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/buttons.html5.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='fontawesome/js/all.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+ <script type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
+ <script type="text/javascript" src="/static/new/javascript/create_datatable.js"></script>
+
+
+ <script type="text/javascript" charset="utf-8">
+ var tableJson = {{ table_json | safe }}
+ </script>
+
+ <script type="text/javascript" charset="utf-8">
+ $.fn.dataTable.ext.order['dom-innertext'] = function (settings, col) {
+ return this.api().column(col, { order: 'index' }).nodes().map(function (td, i) {
+ return Math.abs(parseFloat($('a', td).text()));
+ });
+ }
+
+ $.fn.dataTableExt.oSort['numeric-html-asc'] = function(a,b) {
+ a = Math.abs(parseFloat(a));
+ b = Math.abs(parseFloat(b));
+ return ((a < b) ? -1 : ((a > b) ? 1 : 0));
+ };
+
+ $.fn.dataTableExt.oSort['numeric-html-desc'] = function(a,b) {
+ a = Math.abs(parseFloat(a));
+ b = Math.abs(parseFloat(b));
+ return ((a < b) ? 1 : ((a > b) ? -1 : 0));
+ };
+
+ $.fn.dataTableExt.oSort['scientific-asc'] = function ( a, b ) {
+ var x = parseFloat(a);
+ var y = parseFloat(b);
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+ };
+
+ $.fn.dataTableExt.oSort['scientific-desc'] = function ( a, b ) {
+ var x = parseFloat(a);
+ var y = parseFloat(b);
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
+ };
+
+ $.fn.dataTable.ext.search.push( function( settings, data, dataIndex ) {
+ var r_column = {{ filter_cols[0] }};
+ var r_greater = parseFloat($('input[name=r_greater_select]').val())
+ var r_less = parseFloat($('input[name=r_less_select]').val());
+ var r_and_or = $('#r_and_or').val();
+
+ var mean_column = {{ filter_cols[1] }};
+ var mean_greater = parseFloat($('input[name=mean_greater_select]').val());
+ var mean_less = parseFloat($('input[name=mean_less_select]').val());
+ var mean_and_or = $('#mean_and_or').val();
+
+ if (r_and_or == "and" && mean_and_or == "and"){
+ if ( (data[r_column] >= r_greater && data[r_column] <= r_less) && {% if filter_cols[1] != 0 %}(data[mean_column] > mean_greater && data[mean_column] < mean_less){% else %} true{% endif %} ){
+ return true
+ }
+ else {
+ return false
+ }
+ } else if (r_and_or == "and" && mean_and_or == "or"){
+ if ( (data[r_column] >= r_greater && data[r_column] <= r_less) && {% if filter_cols[1] != 0 %}(data[mean_column] >= mean_greater || data[mean_column] <= mean_less){% else %} true{% endif %} ){
+ return true
+ } else {
+ return false
+ }
+ } else if (r_and_or == "or" && mean_and_or == "and") {
+ if ( (data[r_column] >= r_greater || data[r_column] <= r_less) && {% if filter_cols[1] != 0 %}(data[mean_column] >= mean_greater && data[mean_column] <= mean_less){% else %} true{% endif %} ){
+ return true
+ } else {
+ return false
+ }
+ } else {
+ if ( (data[r_column] >= r_greater || data[r_column] <= r_less) && {% if filter_cols[1] != 0 %}(data[mean_column] >= mean_greater || data[mean_column] <= mean_less){% else %} true{% endif %} ){
+ return true
+ } else {
+ return false
+ }
+ }
+ return true
+ });
+
+ $(document).ready( function () {
+
+ tableId = "trait_table";
+
+ {% if corr_method == 'pearson' %}
+ rOrRho = "r"
+ corr_method = "pearson"
+ {% else %}
+ rOrRho = "rho"
+ corr_method = "spearman"
+ {% endif %}
+
+ columnDefs = [
+ {
+ 'data': null,
+ 'width': "25px",
+ 'orderDataType': "dom-checkbox",
+ 'orderSequence': [ "desc", "asc"],
+ 'render': function(data) {
+ return '<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + data.hmac + '">'
+ }
+ },
+ {
+ 'title': "Index",
+ 'type': "natural",
+ 'width': "30px",
+ 'data': "index"
+ },
+ {
+ 'title': "Record",
+ 'type': "natural-minus-na",
+ 'data': null,
+ 'width': "60px",
+ 'render': function(data) {
+ return '<a target="_blank" href="/show_trait?trait_id=' + data.trait_id + '&dataset=' + data.dataset + '">' + data.trait_id + '</a>'
+ }
+ }{% if target_dataset.type == 'ProbeSet' %},
+ {
+ 'title': "Symbol",
+ 'type': "natural",
+ 'width': "120px",
+ 'data': "symbol"
+ },
+ {
+ 'title': "Description",
+ 'type': "natural",
+ 'data': null,
+ 'render': function(data) {
+ try {
+ return decodeURIComponent(escape(data.description))
+ } catch(err){
+ return escape(data.description)
+ }
+ }
+ },
+ {
+ 'title': "Location",
+ 'type': "natural-minus-na",
+ 'width': "125px",
+ 'data': "location"
+ },
+ {
+ 'title': "Mean",
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': "mean",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Sample " + rOrRho,
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': null,
+ 'orderSequence': [ "desc", "asc"],
+ 'render': function(data) {
+ if (data.sample_r != "N/A") {
+ return "<a target\"_blank\" href=\"corr_scatter_plot?method=" + corr_method + "&dataid={{ dataid }}&dataset_1={% if this_dataset.name == 'Temp' %}Temp_{{ this_dataset.group }}{% else %}{{ this_dataset.name }}{% endif %}&dataset_2=" + data.dataset + "&trait_1={{ this_trait.name }}&trait_2=" + data.trait_id + "\">" + data.sample_r + "</a>"
+ } else {
+ return data.sample_r
+ }
+ }
+ },
+ {
+ 'title': "N",
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': "num_overlap",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Sample p(" + rOrRho + ")",
+ 'type': "scientific",
+ 'width': "65px",
+ 'data': "sample_p",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Lit " + rOrRho,
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': "lit_corr",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Tissue " + rOrRho,
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': "tissue_corr",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Tissue p(" + rOrRho + ")",
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': "tissue_pvalue",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Peak</div> <div style='text-align: right;'>-logP <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>",
+ 'type': "natural-minus-na",
+ 'data': "lod_score",
+ 'width': "60px",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Peak Location",
+ 'type': "natural-minus-na",
+ 'width': "125px",
+ 'data': "lrs_location"
+ },
+ {
+ 'title': "Effect Size<a href=\"http://gn1.genenetwork.org/glossary.html#A\" target=\"_blank\" style=\"color: white;\">&nbsp;<i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>",
+ 'type': "natural-minus-na",
+ 'data': "additive",
+ 'width': "85px",
+ 'orderSequence': [ "desc", "asc"]
+ }{% elif target_dataset.type == 'Publish' %},
+ {
+ 'title': "Abbreviation",
+ 'type': "natural",
+ 'data': null,
+ 'render': function(data) {
+ try {
+ return decodeURIComponent(escape(data.abbreviation_display))
+ } catch(err){
+ return data.abbreviation_display
+ }
+ }
+ },
+ {
+ 'title': "Description",
+ 'type': "natural",
+ 'data': null,
+ 'render': function(data) {
+ try {
+ return decodeURIComponent(escape(data.description))
+ } catch(err){
+ return data.description
+ }
+ }
+ },
+ {
+ 'title': "Mean",
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': "mean",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Authors",
+ 'type': "natural",
+ 'width': "400px",
+ 'data': null,
+ 'render': function(data) {
+ try {
+ return decodeURIComponent(escape(data.authors_display))
+ } catch(err){
+ return data.authors_display
+ }
+ }
+ },
+ {
+ 'title': "Year",
+ 'type': "natural-minus-na",
+ 'data': null,
+ 'width': "80px",
+ 'render': function(data) {
+ if (data.pubmed_link != "N/A"){
+ return '<a href="' + data.pubmed_link + '">' + data.pubmed_text + '</a>'
+ } else {
+ return data.pubmed_text
+ }
+ },
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Sample " + rOrRho,
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': null,
+ 'orderSequence': [ "desc", "asc"],
+ 'render': function(data) {
+ if (data.sample_r != "N/A") {
+ return "<a target\"_blank\" href=\"corr_scatter_plot?method=" + corr_method + "&dataset_1={% if this_dataset.name== 'Temp' %}Temp_{{ this_dataset.group }}{% else %}{{ this_dataset.name }}{% endif %}&dataset_2=" + data.dataset + "&trait_1={{ this_trait.name }}&trait_2=" + data.trait_id + "\">" + data.sample_r + "</a>"
+ } else {
+ return data.sample_r
+ }
+ }
+ },
+ {
+ 'title': "N",
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': "num_overlap",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Sample p(" + rOrRho + ")",
+ 'type': "scientific",
+ 'width': "65px",
+ 'data': "sample_p",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Peak</div> <div style='text-align: right;'>-logP <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>",
+ 'type': "natural-minus-na",
+ 'data': "lod_score",
+ 'width': "60px",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Peak Location",
+ 'type': "natural-minus-na",
+ 'width': "160px",
+ 'data': "lrs_location"
+ },
+ {
+ 'title': "Effect Size<a href=\"http://gn1.genenetwork.org/glossary.html#A\" target=\"_blank\" style=\"color: white;\">&nbsp;<i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>",
+ 'type': "natural-minus-na",
+ 'data': "additive",
+ 'width': "85px",
+ 'orderSequence': [ "desc", "asc"]
+ }{% elif target_dataset.type == 'Geno' %},
+ {
+ 'title': "Location",
+ 'type': "natural-minus-na",
+ 'width': "120px",
+ 'data': "location"
+ },
+ {
+ 'title': "Sample " + rOrRho,
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': null,
+ 'orderSequence': [ "desc", "asc"],
+ 'render': function(data) {
+ if (data.sample_r != "N/A") {
+ return "<a target\"_blank\" href=\"corr_scatter_plot?method=" + corr_method + "&dataset_1={% if this_dataset.name == 'Temp' %}Temp_{{ this_dataset.group }}{% else %}{{ this_dataset.name }}{% endif %}&dataset_2=" + data.dataset + "&trait_1={{ this_trait.name }}&trait_2=" + data.trait_id + "\">" + data.sample_r + "</a>"
+ } else {
+ return data.sample_r
+ }
+ }
+ },
+ {
+ 'title': "N",
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': "num_overlap",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Sample p(" + rOrRho + ")",
+ 'type': "scientific",
+ 'width': "65px",
+ 'data': "sample_p",
+ 'orderSequence': [ "desc", "asc"]
+ }{% endif %}
+ ]
+
+ tableSettings = {
+ "buttons": [
+ {
+ extend: 'csvHtml5',
+ text: 'Download <span class="glyphicon glyphicon-download"></span>',
+ className: 'btn btn-default',
+ exportOptions: {
+ columns: 'th:not(:first-child)'
+ }
+ }
+ ],
+ {% if table_json|length > 2000 %}
+ "scroller": false,
+ {% endif %}
+ {% if target_dataset.type == 'Geno' %}
+ "order": [[6, "asc" ]],
+ {% elif target_dataset.type == 'Publish' %}
+ "order": [[10, "asc" ]],
+ {% else %}
+ "order": [[9, "asc" ]],
+ {% endif %}
+ }
+
+ create_table(tableId, tableJson, columnDefs, tableSettings)
+
+ trait_table = $('#trait_table').DataTable();
+ trait_table.buttons().container().appendTo('#export_options')
+
+ $('.buttons-csv').removeClass('dt-button')
+
+ submit_special = function(url) {
+ $("#correlation_form").attr("action", url);
+ return $("#correlation_form").submit();
+ };
+
+ $("#delete").on("click", function() {
+ url = $(this).data("url")
+ return submit_special(url)
+ });
+
+ $("#more_options").click(function() {
+ $("div#filter_options").toggle();
+ });
+
+ $("#select_traits").click(function() {
+ trait_table.draw();
+ });
+ });
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/credits.html b/gn2/wqflask/templates/credits.html
new file mode 100644
index 00000000..aab1dfb1
--- /dev/null
+++ b/gn2/wqflask/templates/credits.html
@@ -0,0 +1,58 @@
+{% extends "base.html" %}
+{% block title %}Credit{% endblock %}
+{% block content %}
+<Table width= "100%" cellSpacing=0 cellPadding=5 style="margin: 10px;"><TR>
+<!-- Body Start from Here -->
+<TD valign="top" height="200" width="100%">
+ <P class="title"><H2>Web site design and coding</H2></P>
+ <UL>
+<LI> <A HREF="mailto:rwilliams@uthsc.edu">Robert W Williams</a>
+<LI>Kenneth Manly (design and QTL mapping, 1995-2007)
+<LI>Jintao Wang (lead programmer, 2001–2006)
+<LI><a href="http://www.nervenet.org/main/people.html">Arthur G. Centeno (IT Analyst III, 2001–present)</a>
+<LI><a href="http://www.nervenet.org/main/people.html">Zachary Sloan (IT Analyst III, 2009–present)</a>
+<LI>Frederick Muriithi (programmer, 2017-present)</LI>
+<LI>Bonface Munyoki (programmer, 2020-present)</LI>
+<LI>Alexander Kabua (programmer, 2020-present)</LI>
+<LI>Arun Isaac (programmer, 2021-present)</LI>
+<LI><a href="http://www.nervenet.org/main/people.html">Lei Yan (systems and web services interface 2008-2018)</a>
+<LI><a href="http://www.nervenet.org/main/people.html">Xusheng Wang (data analysis, 2008-2012)</a>
+<LI><a href="http://www.nervenet.org/main/people.html">Xiaodong Zhou (lead programmer 2009–2011)</a>
+<LI>Ning Liu (programmer 2008–2009)</LI>
+<LI>Zhaohui Sun (SNP browser, programmer 2007)
+<LI>Yanhua Qu (data entry, 2005-2008)
+<LI>Stephen Pitts (programmer)
+<LI>Hongqiang Li (lead programmer, 2007-2009)
+<LI><A HREF="http://www.jax.org/news/archives/2009/chesler.html">Elissa Chesler</A> (design of QTL Heat Map, Compare Correlations, 2004-2006)
+<LI>Kevitt Adler (systems, 2006-2008)
+<LI>Robert Crowell (SNP Browser, 2006-2007)
+<LI>David Crowell (partial correlations, 2008-2009)
+<LI>Evan G. Williams (SNP and Variant Browser, data entry, 2004-2006)
+<LI>Alex G Williams (QTL Maps GUI, 2003-2006)
+ </UL>
+ <P class="title"><H2>Published and Unpublished Phenotype Data</H2></P>
+ <UL>
+ <LI><A HREF="http://www.nervenet.org/people/lulu_cv.html">Lu Lu</A>
+ <LI> <A HREF="http://www.jax.org/news/archives/2009/chesler.html">Elissa J. Chesler</A>
+ <LI><span class="broken-link" href="http://www.ohsu.edu/som-BehNeuro/Faculty/Crabbe.html">John C Crabbe</span>, OHSU
+ <LI><span class="broken-link" href="http://www.ohsu.edu/som-BehNeuro/Faculty/Belknap.html">John K Belknap</span>, OHSU
+ <LI>Mary-Kathleen Sullivan
+ <LI>Emily English
+ <LI>Byron Jones
+ <LI>Ryan McNieve
+ <LI>Nathan Copeland
+ </UL>
+ <P class="title"><H2>Genotype / Genomic Data</H2></P>
+ <UL>
+ <LI> <A HREF="http://www.nervenet.org/people/lulu_cv.html">Lu Lu</A>
+ <LI><a href="http://www.nervenet.org/people/Gu_cv.html">Jing Gu</a>
+ <LI>Shuhua Qi
+ <LI>John Hogenesch
+ <LI>Timothy Wiltshire
+ <LI><a href="http://www.nervenet.org/people/Yanhua_cv.html">Yanhua Qu</a>
+ </UL>
+ <P></P>
+</TD>
+</TR></TABLE>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/ctl_results.html b/gn2/wqflask/templates/ctl_results.html
new file mode 100644
index 00000000..1c31b499
--- /dev/null
+++ b/gn2/wqflask/templates/ctl_results.html
@@ -0,0 +1,77 @@
+{% extends "base.html" %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="/static/new/css/network_graph.css" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='cytoscape-panzoom/cytoscape.js-panzoom.css') }}">
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='qtip2/jquery.qtip.min.css') }}">
+ <style>
+ /* The Cytoscape Web container must have its dimensions set. */
+ html, body { height: 100%; width: 100%; padding: 0; margin: 0; }
+ #cytoscapeweb { width: 70%; height: 70%; }
+ </style>
+{% endblock %}
+
+{% block title %}CTL results{% endblock %}
+
+{% block content %} <!-- Start of body -->
+<div class="container">
+ <h1>CTL Results</h1>
+ {{(request.form['trait_list'].split(',')|length)}} phenotypes as input<br>
+
+ <!--
+ <a href="/tmp/{{ results['imgurl1'] }}">
+ <img alt="Embedded Image" src="data:image/png;base64,
+ {% for elem in results['imgdata1'] -%}
+ {% print("%c"|format(elem)) %}
+ {%- endfor %}
+ " /></a> -->
+
+ <h3>CTL/QTL Plots for individual traits</h3>
+ {% for r in range(2, (request.form['trait_list'].split(',')|length +1)) %}
+ <a href="/tmp/{{ results['imgurl' + r|string] }}">
+ <img width=100 height=100 alt="Embedded Image" src="data:image/png;base64,
+ {% for elem in results['imgdata' + r|string] -%}
+ {% print("%c"|format(elem)) %}
+ {%- endfor %}
+ " /></a>
+ {% endfor %}
+ <h3>Tabular results</h3>
+ <table width="80%">
+ <tr><th>trait</th><th>marker</th><th>trait</th><th>LOD</th><th>dCor</th></tr>
+ significant CTL:<br>
+ {% for r in range(results['ctlresult'][0]|length) %}
+ <tr>
+ {% for c in range(results['ctlresult']|length) %}
+ <td>
+ {% if c > 2 %}
+ {{results['ctlresult'][c][r]|float|round(2)}}
+ {% else %}
+ {{results['ctlresult'][c][r]}}
+ {% endif %}
+ </td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </table>
+ <h3>Network Figure</h3>
+ <div id="cytoscapeweb" class="col-xs-9" style="min-height:700px !important;"></div>
+</div>
+{% endblock %}
+
+{% block js %}
+
+ <script>
+ elements_list = {{ elements | safe }}
+ gn2_url = "{{ gn2_url | safe }}"
+ </script>
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='qtip2/jquery.qtip.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='cytoscape/cytoscape.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='cytoscape-panzoom/cytoscape-panzoom.js') }}"></script>
+ <!-- should be using cytoscape-popper for tips, see docs -->
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='cytoscape-qtip/cytoscape-qtip.js') }}"></script>
+
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/ctl_graph.js"></script>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/ctl_setup.html b/gn2/wqflask/templates/ctl_setup.html
new file mode 100644
index 00000000..f5b0baf8
--- /dev/null
+++ b/gn2/wqflask/templates/ctl_setup.html
@@ -0,0 +1,70 @@
+{% extends "base.html" %}
+{% block title %}CTL analysis{% endblock %}
+{% block content %}
+<!-- Start of body -->
+<div class="container">
+ {% if request.form['trait_list'].split(",")|length < 2 %} <div class="alert alert-danger" role="alert">
+ <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
+ <span class="sr-only">Error:</span>
+ <h2>Too few traits as input</h2>
+ Please make sure you select enough traits to perform CTL. Your collection needs to contain at least 2 different traits. You provided {{request.form['trait_list'].split(',')|length}} traits as input.
+</div>
+{% else %}
+<h1>CTL analysis</h1>
+CTL analysis is published as open source software, if you are using this method in your publications, please cite:<br><br>
+Arends D, Li Y, Brockmann GA, Jansen RC, Williams RW, Prins P<br>
+Correlation trait locus (CTL) mapping: Phenotype network inference subject to genotype.<br>
+The Journal of Open Source Software (2016)<br>
+Published in <a href="http://joss.theoj.org/papers/10.21105/joss.00087"><img src="http://joss.theoj.org/papers/10.21105/joss.00087/status.svg"></a>
+<br><br>
+<form class="col-md-8" action="/ctl_results" method="post" class="form-horizontal" id="ctl_form">
+ <input type="hidden" name="trait_list" id="trait_list" value="{{request.form['trait_list']}}">
+ <div class="form-group row">
+ <label for="Strategy" class="col-md-3 col-form-label col-form-label-sm">Strategy</label>
+ <div class="col-md-9">
+ <select class="form-control col-md-9" name="strategy" id="strategy">
+ <option value="Exact" selected="selected">Exact</option>
+ <option value="Full">Full</option>
+ <option value="Pairwise">Pairwise</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="corType" class="col-md-3 col-form-label col-form-label-sm">Perform parametric analysis</label>
+ <div class="col-md-9">
+ <select class="form-control col-md-9" name="parametric" id="parametric">
+ <option value="True" selected="selected">True</option>
+ <option value="False">False</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="Permutations" class="col-md-3 col-form-label col-form-label-sm">Number of permutation <span style="color:red;">(Used when strategy is Full or Pairwise)</span></label>
+ <div class="col-md-9">
+ <select class="form-control" name="nperm" id="nperm">
+ <option value="100">100</option>
+ <option value="1000" selected="selected">1000</option>
+ <option value="10000">10000</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="Significance" class="col-md-3 col-form-label col-form-label-sm"> Significance level</label>
+ <div class="col-md-9">
+ <select class="form-control" name="significance" id="significance">
+ <option value="0.1">0.1</option>
+ <option value="0.05" selected="selected">0.05</option>
+ <option value="0.001">0.001</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="text-center">
+ <input type="submit" class="btn btn-primary" value="Run CTL using these settings" />
+ </div>
+ </div>
+</form>
+{% endif %}
+</div>
+{% endblock %}
+
diff --git a/gn2/wqflask/templates/data_sharing.html b/gn2/wqflask/templates/data_sharing.html
new file mode 100644
index 00000000..cca498ec
--- /dev/null
+++ b/gn2/wqflask/templates/data_sharing.html
@@ -0,0 +1,262 @@
+{% extends "base.html" %}
+{% block title %}Data Sharing{% endblock %}
+{% block content %}
+
+ <!-- Start of body -->
+ <TR>
+ <TD bgColor=#eeeeee class="solidBorder">
+ <Table width= "100%" cellSpacing=0 cellPadding=5>
+ <TR>
+ <td>
+<a href="/webqtl/main.py?FormID=sharingListDataset">List of DataSets</a><br>
+<H1 class="title" id="parent-fieldname-title">{{ info.DB_Name }}
+<a href="/webqtl/main.py?FormID=sharinginfoedit&GN_AccessionId={{ info.GN_AccesionId }}"><img src="/images/modify.gif" alt="modify this page" border="0" valign="middle"></a>
+<span style="color:red;"></span>
+</H1>
+<table border="0" width="100%">
+<tr>
+<td valign="top" width="50%">
+<TABLE cellSpacing=0 cellPadding=5 width=100% border=0>
+ <TR><td><b>GN Accession:</b> {{ info.GN_AccesionId }}</TD></tr>
+ <TR><TD><b>GEO Series:</b> {{ info.GEO_Series }}</TD></TR>
+ <TR><TD><b>Title:</b> {{ info.Title }}</TD></TR>
+ <TR><TD><b>Organism:</b> <a href=http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id={{ info.Organism_Id }}>{{ info.Organism }}</a></TD></tr>
+ <tr><TD><b>Group:</b> {{ info.InbredSet }}</TD></TR>
+ <TR><TD><b>Tissue:</b> {{ info.Tissue }}</TD></tr>
+ <tr><TD><b>Dataset Status:</b> {{ info.Status }}</TD></tr>
+ <TR><TD><b>Platforms:</b> {{ info.Platforms }}</TD></TR>
+ <TR><TD><b>Normalization:</b> {{ info.Normalization }}</TD></TR>
+ <TR><TD><!--Code below to Show hide Contact information -->
+ <a href="#" onclick="colapse('answer1')">See Contact Information</a><br>
+ <span id="answer1" style="display: none; return: false;">
+ {{ info.Contact_Name }}<br>
+ {{ info.Organization_Name }}<br>
+ {{ info.Department }}<br>
+ {{ info.Street }}<br>
+ {{ info.City }}, {{ info.State }} {{ info.ZIP }} {{ info.Country }}<br>
+ Tel. {{ info.Phone }}<br>
+ {{ info.Emails }}<br>
+ <a href="{{ info.URL }}">{{ info.URL }}</a>
+ </span><!--Code above to Show hide Contact information --></TD></TR>
+</TABLE>
+</td>
+<td valign="top" width="50%">
+<table border="0" width="100%">
+<tr>
+ <td bgcolor="#dce4e1"><b>Download datasets and supplementary data files</b></td>
+</tr>
+<tr>
+ <td>{{ htmlfilelist|safe }}</td>
+</tr>
+</table>
+</td>
+</tr>
+</table>
+<HR>
+<p>
+<table width="100%" border="0" cellpadding="5" cellspacing="0">
+<tr><td><span style="font-size:115%;font-weight:bold;">Summary:</span></td></tr>
+ <tr><td>{{ info.Summary | safe}}<br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">About the cases used to generate this set of data:</span></td></tr>
+ <tr><td>{{ info.About_Cases | safe}}</td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">About the tissue used to generate this set of data:</span></td></tr>
+ <tr><td>{{ info.About_Tissue | safe }}</td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">About downloading this data set:</span></td></tr>
+ <tr><td> <P>All data links (right-most column above) will be made active as sooon as the global analysis of these data by the Consortium has been accepted for publication. Please see text on <A HREF="http://www.genenetwork.org/dataSharing.html" target="_empty" class="normalsize">Data Sharing Policies</A>, and <A HREF="http://www.genenetwork.org/conditionsofUse.html" target="_empty" class="normalsize">Conditions and Limitations</A>, and <A HREF="http://www.genenetwork.org/statusandContact.html" target="_empty" class="normalsize">Contacts</A>. Following publication, download a summary text file or Excel file of the PDNN probe set data. Contact RW Williams regarding data access problems.
+</P><br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">About the array platform:</span></td></tr>
+ <tr><td> <P><B>Affymetrix Mouse Genome 430 2.0 array: </B>The <A HREF="http://www.affymetrix.com/support/technical/byproduct.affx?product=moe430-20" target="_blank" class="normalsize">430v2</A> array consists of 992936 useful 25-nucleotide probes that estimate the expression of approximately 39,000 transcripts and the majority of known genes and expressed sequence tags. The array sequences were selected late in 2002 using Unigene Build 107 by Affymetrix. The UTHSC group has recently reannotated all probe sets on this array, producing more accurate data on probe and probe set targets. All probes were aligned to the most recent assembly of the Mouse Genome (Build 34, mm6) using Jim Kent's BLAT program. Many of the probe sets have been manually curated by Jing Gu and Rob Williams. </P><br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">About data values and data processing:</span></td></tr>
+ <tr><td> <A HREF="http://www.biomedcentral.com/1471-2105/6/65" target="_empty" class="normalsize">Harshlight</A> was used to examine the image quality of the array (CEL files). Bad areas (bubbles, scratches, blemishes) of arrays were masked.
+
+<P>First pass data quality control: Affymetrix GCOS provides useful array quality control data including:
+<OL>
+<LI>The scale factor used to normalize mean probe intensity. This averaged 3.3 for the 179 arrays that passed and 6.2 for arrays that were excluded. The scale factor is not a particular critical parameter.
+<LI>The average background level. Values averaged 54.8 units for the data sets that passed and 55.8 for data sets that were excluded. This factor is not important for quality control.
+<LI>The percentage of probe sets that are associated with good signal ("present" calls). This averaged 50% for the 179 data sets that passed and 42% for those that failed. Values for passing data sets extended from 43% to 55%. This is a particularly important criterion.
+<LI>The 3':5' signal ratios of actin and Gapdh. Values for passing data sets averaged 1.5 for actin and 1.0 for Gapdh. Values for excluded data sets averaged 12.9 for actin and 9.6 for Gapdh. This is a highly discriminative QC criterion, although one must keep in mind that only two transcripts are being tested. Sequence variation among strains (particularly wild derivative strains such as CAST/Ei) may affect these ratios.
+</OL>
+
+<P>The second step in our post-processing QC involves a count of the number of probe sets in each array that are more than 2 standard deviations (z score units) from the mean across the entire 206 array data sets. This was the most important criterion used to eliminate "bad" data sets. All 206 arrays were processed togther using standard RMA and PDNN methods. The count and percentage of probe sets in each array that were beyond the 2 z theshold was computed. Using the RMA transform the average percentage of probe sets beyond the 2 z threshold for the 179 arrays that finally passed of QC procedure was 1.76% (median of 1.18%). In contrast the 2 z percentage was more than 10-fold higher (mean of 22.4% and median 20.2%) for those arrays that were excluded. This method is not very sensitive to the transformation method that is used. Using the PDNN transform, the average percent of probe sets exceeding was 1.31% for good arrays and was 22.6% for those that were excluded. In our opinion, this 2 z criterion is the most useful criterion for the final decision of whether or not to include arrays, although again, allowances need to be made for wild strains that one expects to be different from the majority of conventional inbred strains. For example, if a data set has excellent characteristics on all of the Affymetrix GCOS metrics listed above, but generates a high 2 z percentage, then one would include the sample if one can verify that there are no problems in sample and data set identification.
+
+<P>The entire procedure can be reapplied once the initial outlier data sets have been eliminated to detect any remaining outlier data sets.
+
+
+<P><span class="broken_link" HREF="http://www.datadesk.com/products/data_analysis/datadesk/" target="_empty" class="normalsize">DataDesk</span> was used to examine the statistical quality of the probe level (CEL) data after step 5 below. DataDesk allows the rapid detection of subsets of probes that are particularly sensitive to still unknown factors in array processing. Arrays can then be categorized at the probe level into "reaction classes." A reaction class is a group of arrays for which the expression of essentially all probes are colinear over the full range of log2 values. A single but large group of arrays (n = 32) processed in essentially the identical manner by a single operator can produce arrays belonging to as many as four different reaction classes. Reaction classes are NOT related to strain, age, sex, treatment, or any known biological parameter (technical replicates can belong to different reaction classes). We do not yet understand the technical origins of reaction classes. The number of probes that contribute to the definition of reaction classes is quite small (<10% of all probes). We have categorized all arrays in this data set into one of 5 reaction classes. These have then been treated as if they were separate batches. Probes in these data type "batches" have been aligned to a common mean as described below.
+
+<P><B>Probe (cell) level data from the CEL file: </B>These CEL values produced by <span href="http://www.affymetrix.com/support/technical/product_updates/gcos_download.affx" target="_blank" class="normalsize broken_link">GCOS</span> are 75% quantiles from a set of 91 pixel values per cell.
+<OL>
+
+<LI>We added an offset of 1.0 unit to each cell signal to ensure that all values could be logged without generating negative values. We then computed the log base 2 of each cell.
+
+<LI>We performed a quantile normalization of the log base 2 values for all arrays using the same initial steps used by the RMA transform.
+
+<LI>We computed the Z scores for each cell value.
+
+<LI>We multiplied all Z scores by 2.
+
+<LI>We added 8 to the value of all Z scores. The consequence of this simple set of transformations is to produce a set of Z scores that have a mean of 8, a variance of 4, and a standard deviation of 2. The advantage of this modified Z score is that a two-fold difference in expression level (probe brightness level) corresponds approximately to a 1 unit difference.
+
+<LI>Finally, we computed the arithmetic mean of the values for the set of microarrays for each strain. Technical replicates were averaged before computing the mean for independent biological samples. Note, that we have not (yet) corrected for variance introduced by differences in sex or any interaction terms. We have not corrected for background beyond the background correction implemented by Affymetrix in generating the CEL file. We eventually hope to add statistical controls and adjustments for some of these variables.
+</OL>
+<P><B>Probe set data from the CHP file: </B>The expression values were generated using PDNN. The same simple steps described above were also applied to these values. Every microarray data set therefore has a mean expression of 8 with a standard deviation of 2. A 1 unit difference represents roughly a two-fold difference in expression level. Expression levels below 5 are usually close to background noise levels. </Blockquote>
+
+
+<P>Probe level QC: Log2 probe data of all arrays were inspected in DataDesk before and after quantile normalization. Inspection involved examining scatterplots of pairs of arrays for signal homogeneity (i.e., high correlation and linearity of the bivariate plots) and looking at all pairs of correlation coefficients. XY plots of probe expression and signal variance were also examined. Probe level array data sets were organized into reaction groups. Arrays with probe data that were not homogeneous when compared to other arrays were flagged.
+
+<P>Probe set level QC: The final normalized individual array data were evaluated for outliers. This involved counting the number of times that the probe set value for a particular array was beyond two standard deviations of the mean. This outlier analysis was carried out using the PDNN, RMA and MAS5 transforms and outliers across different levels of expression. Arrays that were associated with an average of more than 8% outlier probe sets across all transforms and at all expression levels were eliminated. In contrast, most other arrays generated fewer than 5% outliers.
+
+
+<P>Validation of strains and sex of each array data set: A subset of probes and probe sets with a Mendelian pattern of inheritance were used to construct a expression correlation matrix for all arrays and the ideal Mendelian expectation for each strain constructed from the genotypes. There should naturally be a very high correlation in the expression patterns of transcripts with Mendelian phenotypes within each strain, as well as with the genotype strain distribution pattern of markers for the strain.
+
+<P>Sex of the samples was validated using sex-specific probe sets such as <I>Xist</I> and <I>Dby</I>.<br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">Data source acknowledgment:</span></td></tr>
+ <tr><td> <P>Data were generated with funds provided by a variety of public and private source to members of the Consortium. All of us thank Muriel Davisson, Cathy Lutz, and colleagues at the Jackson Laboratory for making it possible for us to add all of the CXB strains, and one or more samples from KK/HIJ, WSB/Ei, NZO/HILtJ, LG/J, CAST/Ei, PWD/PhJ, and PWK/PhJ to this study. We thank Yan Cui at UTHSC for allowing us to use his Linux cluster to align all M430 2.0 probes and probe sets to the mouse genome. We thank Hui-Chen Hsu and John Mountz for providing us BXD tissue samples, as well as many strains of BXD stock. We thanks Douglas Matthews (UMem in Table 1) and John Boughter (JBo in Table 1) for sharing BXD stock with us. Members of the Hippocampus Consortium thank the following sources for financial support of this effort:
+
+<UL>
+<LI>David C. Airey, Ph.D. <!--$5,000 contribution -->
+<BR>Grant Support: Vanderbilt Institute for Integratie Genomics
+<BR>Department of Pharmacology
+<BR>david.airey at vanderbilt.edu
+
+<LI>Lu Lu, M.D. <!--Tissue acquisition, RNA processing, experimental design-->
+<BR>Grant Support: NIH U01AA13499, U24AA13513
+
+<LI><span HREF="http://www.salk.edu/faculty/faculty/details.php?id=23" target="_empty" class="broken_link normalsize">Fred H. Gage, Ph.D.</span> <!--$10,000 contribution -->
+<BR>Grant Support: Lookout Foundation
+
+<LI>Dan Goldowitz, Ph.D. <!--$30,000 contribution -->
+<BR>Grant Support: NIAAA INIA AA013503
+<BR>University of Tennessee Health Science Center
+<BR>Dept. Anatomy and Neurobiology
+<BR>email: dgold@nb.utmem.edu
+
+<LI>Shirlean Goodwin, Ph.D. <!--All array processing-->
+<BR>Grant Support: NIAAA INIA U01AA013515
+
+<LI><span HREF="http://www.bccn-berlin.de/ResearchGroups/Kempermann" class="broken_link normalsize">Gerd Kempermann, M.D.</span> <!--$30,000 contribution -->
+<BR>Grant Support: The <A HREF="http://www.volkswagen-stiftung.de/" target="_empty" class="normalsize">Volkswagen Foundation</A> Grant on Permissive and Persistent Factors in Neurogenesis in the Adult Central Nervous System
+<BR>Humboldt-Universitat Berlin
+<BR>Universitatsklinikum Charite
+<BR>email: gerd.kempermann at mdc-berlin.de
+
+<LI>Kenneth F. Manly, Ph.D. <!--Data handling in The GeneNetwork-->
+<BR>Grant Support: NIH P20MH062009 and U01CA105417
+
+<LI>Richard S. Nowakowski, Ph.D. <!--$10,000 contribution-->
+<BR>Grant Support: R01 NS049445-01
+
+<LI>Glenn D. Rosen, Ph.D. <!--Tissue and dissections-->
+<BR>Grant Support: NIH P20
+
+<LI>Leonard C. Schalkwyk, Ph.D. <!--$5,000 contribution -->
+<BR>Grant Support: MRC Career Establishment Grant G0000170
+<BR>Social, Genetic and Developmental Psychiatry
+<BR>Institute of Psychiatry,Kings College London
+<BR>PO82, De Crespigny Park London SE5 8AF
+<BR>L.Schalkwyk@iop.kcl.ac.uk
+
+<LI>Guus Smit, Ph.D. <!--$6,000 contribution -->
+<BR>Dutch NeuroBsik Mouse Phenomics Consortium
+<BR>Center for Neurogenomics & Cognitive Research
+<BR>Vrije Universiteit Amsterdam, The Netherlands
+<BR>e-mail: guus.smit at falw.vu.nl
+<BR>Grant Support: BSIK 03053
+
+<LI>Thomas Sutter, Ph.D. <!--All array handling and ~$20,000 for array chemistry -->
+<BR>Grant Support: INIA U01 AA13515 and the W. Harry Feinstone Center for Genome Research
+
+<LI>Stephen Whatley, Ph.D. <!--$5,000 contribution -->
+<BR>Grant Support: XXXX
+
+<LI>Robert W. Williams, Ph.D. <!--Consortium director, design, error checking, metadata, and GeneNetwork-->
+<BR>Grant Support: NIH U01AA013499, P20MH062009, U01AA013499, U01AA013513
+</UL>
+</P><br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">Experiment Type:</span></td></tr>
+ <tr><td> <P>Pooled RNA samples (usually one pool of male hippocampii and one pool of female hippocampii) were prepared using standard protocols. Samples were processed using a total of 206 Affymetrix GeneChip Mouse Expression 430 2.0 short oligomer arrays (MOE430 2.0 or M430v2; see GEO platform ID <A HREF="http://www.ncbi.nlm.nih.gov/projects/geo/query/acc.cgi?acc=GPL1261" target="_empty" class="normalsize">GPL1261</A>), of which 201 passed quality control and error checking. This particular data set was processed using the <span href="http://odin.mdacc.tmc.edu/~zhangli/PerfectMatch/" target="_blank" class="broken_link normalsize">PDNN</span> protocol. To simplify comparisons among transforms, PDNN values of each array were adjusted to an average of 8 units and a standard deviation of 2 units.
+<br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">Overall Design:</span></td></tr>
+ <tr><td> <P>Pooled RNA samples (usually one pool of male hippocampii and one pool of female hippocampii) were prepared using standard protocols. Samples were processed using a total of 206 Affymetrix GeneChip Mouse Expression 430 2.0 short oligomer arrays (MOE430 2.0 or M430v2; see GEO platform ID <A HREF="http://www.ncbi.nlm.nih.gov/projects/geo/query/acc.cgi?acc=GPL1261" target="_empty" class="normalsize">GPL1261</A>), of which 201 passed quality control and error checking. This particular data set was processed using the <span href="http://odin.mdacc.tmc.edu/~zhangli/PerfectMatch/" target="_blank" class="broken_link normalsize">PDNN</span> protocol. To simplify comparisons among transforms, PDNN values of each array were adjusted to an average of 8 units and a standard deviation of 2 units.
+<br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">Contributor:</span></td></tr>
+ <tr><td> <UL>
+<LI>David C. Airey, Ph.D. <!--$5,000 contribution -->
+<BR>Grant Support: Vanderbilt Institute for Integratie Genomics
+<BR>Department of Pharmacology
+<BR>david.airey at vanderbilt.edu
+
+<LI>Lu Lu, M.D. <!--Tissue acquisition, RNA processing, experimental design-->
+<BR>Grant Support: NIH U01AA13499, U24AA13513
+
+<LI><span HREF="http://www.salk.edu/faculty/faculty/details.php?id=23" target="_empty" class="broken_link normalsize">Fred H. Gage, Ph.D.</span> <!--$10,000 contribution -->
+<BR>Grant Support: Lookout Foundation
+
+<LI>Dan Goldowitz, Ph.D. <!--$30,000 contribution -->
+<BR>Grant Support: NIAAA INIA AA013503
+<BR>University of Tennessee Health Science Center
+<BR>Dept. Anatomy and Neurobiology
+<BR>email: dgold@nb.utmem.edu
+
+<LI>Shirlean Goodwin, Ph.D. <!--All array processing-->
+<BR>Grant Support: NIAAA INIA U01AA013515
+
+<LI><span HREF="http://www.bccn-berlin.de/ResearchGroups/Kempermann" class="broken_link normalsize">Gerd Kempermann, M.D.</span> <!--$30,000 contribution -->
+<BR>Grant Support: The <A HREF="http://www.volkswagen-stiftung.de/" target="_empty" class="normalsize">Volkswagen Foundation</A> Grant on Permissive and Persistent Factors in Neurogenesis in the Adult Central Nervous System
+<BR>Humboldt-Universitat Berlin
+<BR>Universitatsklinikum Charite
+<BR>email: gerd.kempermann at mdc-berlin.de
+
+<LI>Kenneth F. Manly, Ph.D. <!--Data handling in The GeneNetwork-->
+<BR>Grant Support: NIH P20MH062009 and U01CA105417
+
+<LI>Richard S. Nowakowski, Ph.D. <!--$10,000 contribution-->
+<BR>Grant Support: R01 NS049445-01
+
+<LI>Glenn D. Rosen, Ph.D. <!--Tissue and dissections-->
+<BR>Grant Support: NIH P20
+
+<LI>Leonard C. Schalkwyk, Ph.D. <!--$5,000 contribution -->
+<BR>Grant Support: MRC Career Establishment Grant G0000170
+<BR>Social, Genetic and Developmental Psychiatry
+<BR>Institute of Psychiatry,Kings College London
+<BR>PO82, De Crespigny Park London SE5 8AF
+<BR>L.Schalkwyk@iop.kcl.ac.uk
+
+<LI>Guus Smit, Ph.D. <!--$6,000 contribution -->
+<BR>Dutch NeuroBsik Mouse Phenomics Consortium
+<BR>Center for Neurogenomics & Cognitive Research
+<BR>Vrije Universiteit Amsterdam, The Netherlands
+<BR>e-mail: guus.smit at falw.vu.nl
+<BR>Grant Support: BSIK 03053
+
+<LI>Thomas Sutter, Ph.D. <!--All array handling and ~$20,000 for array chemistry -->
+<BR>Grant Support: INIA U01 AA13515 and the W. Harry Feinstone Center for Genome Research
+
+<LI>Stephen Whatley, Ph.D. <!--$5,000 contribution -->
+<BR>Grant Support: XXXX
+
+<LI>Robert W. Williams, Ph.D. <!--Consortium director, design, error checking, metadata, and GeneNetwork-->
+<BR>Grant Support: NIH U01AA013499, P20MH062009, U01AA013499, U01AA013513
+</UL><br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">Citation:</span></td></tr>
+ <tr><td>
+<P>Please cite: Overall RW, Kempermann G, Peirce J, Lu L, Goldowitz D, Gage FH, Goodwin S, Smit AB, Airey DC, Rosen GD, Schalkwyk LC, Sutter TR, Nowakowski RS, Whatley S, Williams RW (<span class="broken_link" href="http://frontiersin.org/neurogenomics/paper/pending/0/815/" target="_blank" class="normalsize">2009</span>) Genetics of the hippocampal transcriptome in mice: a systematic survey and online neurogenomic resource. Front. Neurogen. 1:3 <span href="http://frontiersin.org/neurogenomics/paper/pending/0/815/" target="_blank" class="broken_link smallsize"><I>Full Text HTML</I></A> doi:10.3389/neuro.15.003.2009
+
+<br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">Submission Date:</span></td></tr>
+ <tr><td> 01 Jul. 2009<br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">Laboratory:</span></td></tr>
+ <tr><td> Williams and Lu Labs<br><br></td></tr>
+<tr><td><span style="font-size:115%;font-weight:bold;">Samples:</span></td></tr>
+ <tr><td> None<br><br></td></tr>
+</table>
+</p>
+</td>
+
+ </TR>
+ </TABLE>
+ </TD>
+ </TR>
+ <!-- End of body -->
+{% endblock %}
diff --git a/gn2/wqflask/templates/dataset.html b/gn2/wqflask/templates/dataset.html
new file mode 100644
index 00000000..2e22be17
--- /dev/null
+++ b/gn2/wqflask/templates/dataset.html
@@ -0,0 +1,107 @@
+{% extends "base.html" %}
+
+{% block css %}
+<style type="text/css">
+ .page-header, .dataset-content {
+ padding-left: 10%;
+ line-height: 1.375;
+ }
+
+ .dataset-content blockquote {
+ font-size: 13px;
+ }
+ .page-header h1 {
+ font-size: 1.8em;
+ line-height: 1.375;
+ }
+ .panel-about {
+ background: #F8F8F8;
+ max-width: 35em;
+ margin: 10px;
+ }
+ .panel-metadata {
+ display: inline-block;
+ width: fit-content;
+ height: fit-content;
+ padding: 0;
+ {% if dataset.description or dataset.specificity or dataset.experimentDesignInfo or
+ dataset.caseInfo or dataset.tissue or
+ dataset.platform or dataset.processingInfo or
+ dataset.notes or dataset.references or dataset.acknowledgment or dataset.contributors
+ %}
+ float: right;
+ {% endif %}
+ }
+
+ .panel-metadata dt {
+ color: green;
+ }
+
+ .panel-metadata dt::after {
+ content: ":";
+ }
+
+ .search {
+ width: 50%;
+ margin: 1em auto;
+ }
+ .has-search .form-control-feedback {
+ right: initial;
+ left: 0;
+ color: #ccc;
+ }
+
+ .has-search .form-control {
+ padding-right: 12px;
+ padding-left: 34px;
+ }
+
+ .search {
+ transform: scale(1.5, 1.5);
+ }
+ .search input {
+ min-width: 17em;
+ }
+ .dataset-search {
+ padding: 0 17%;
+ }
+</style>
+{% endblock %}
+
+{% block title %}Dataset: {{ name }}{% endblock %}
+{% block content %}
+
+{% if dataset %}
+
+{% include 'metadata/dataset.html' %}
+
+{% else %}
+<div class="container dataset-search">
+ <p class="lead">We appreciate your interest, but unfortunately, we don't have any additional information available for: <strong>{{ name }}</strong>. If you have other inquiries or need assistance with something else, please don't hesitate to get in touch with us. <b><i>In the meantime you can explore other datasets here:</i></b></p>.
+
+ <!-- Actual search box -->
+ <div class="search">
+ <form class="form-group has-feedback has-search"
+ hx-post="/datasets/search"
+ hx-target="#search-results">
+ <span class="glyphicon glyphicon-search form-control-feedback"></span>
+ <input class="form-control"
+ type="search"
+ name="search" placeholder="Start your dataset search here">
+ </form>
+ </div>
+
+ <div id="search-results"></div>
+
+</div>
+
+
+{% endif %}
+
+{% endblock %}
+
+{% block js %}
+<script language="javascript"
+ type="text/javascript"
+ src="{{ url_for('js', filename='htmx.min.js') }}"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/display_diffs.html b/gn2/wqflask/templates/display_diffs.html
new file mode 100644
index 00000000..ce50c1b4
--- /dev/null
+++ b/gn2/wqflask/templates/display_diffs.html
@@ -0,0 +1,95 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+{% endblock %}
+
+{% block content %}
+<!-- Start of body -->
+<div class="container">
+ {% set additions = diff.get("Additions") %}
+ {% set modifications = diff.get("Modifications") %}
+ {% set deletions = diff.get("Deletions") %}
+ {% set header = diff.get("Columns", "Strain Name,Value,SE,Count") %}
+ {% if additions %}
+ <h2>Additions Data:</h2>
+ <div class="row">
+ <div class="col-md-8">
+ <table class="table-responsive table-hover table-striped cell-border" id="table-additions">
+ <thead>
+ <th scope="col">Added Data ({{ header }})</th>
+ </thead>
+ <tbody>
+ {% for data in additions %}
+ <tr>
+ <td>{{ data }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endif %}
+
+ {% if modifications %}
+ <h2>Modified Data:</h2>
+
+ <div class="row">
+ <div class="col-md-8">
+ <table class="table-responsive table-hover table-striped cell-border" id="table-modifications">
+ <thead>
+ <th scope="col">Original</th>
+ <th scope="col">Current</th>
+ <th scope="col">Diff ({{ header }})</th>
+ </thead>
+ <tbody>
+ {% for data in modifications %}
+ <tr>
+ <td>{{ data.get("Original") }}</td>
+ <td>{{ data.get("Current") }}</td>
+ <td><pre>{{data.get("Diff")}}</pre></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endif %}
+
+ {% if deletions %}
+ <h2>Deleted Data:</h2>
+ <div class="row">
+ <div class="col-md-8">
+ <table class="table-responsive table-hover table-striped cell-border" id="table-deletions">
+ <thead>
+ <th scope="col">Deleted Data</</th>
+ </thead>
+ <tbody>
+ {% for data in deletions %}
+ <tr>
+ <td>{{ data }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endif %}
+
+</div>
+{%endblock%}
+
+{% block js %}
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+<script language="javascript" type="text/javascript">
+ gn_server_url = "{{ gn_server_url }}";
+
+ $(document).ready( function() {
+ $('#table-additions').dataTable();
+ $('#table-modifications').dataTable();
+ $('#table-deletions').dataTable();
+ });
+</script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/display_files.html b/gn2/wqflask/templates/display_files.html
new file mode 100644
index 00000000..d0e8cc33
--- /dev/null
+++ b/gn2/wqflask/templates/display_files.html
@@ -0,0 +1,131 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+{% endblock %}
+
+{% block content %}
+<!-- Start of body -->
+{% with messages = get_flashed_messages(with_categories=true) %}
+{% if messages %}
+<div class="container-fluid bg-{{ category }}">
+ {% for category, message in messages %}
+ <div class="alert {{category}}" role="alert">{{ message }}</div>
+ {% endfor %}
+</div>
+{% endif %}
+{% endwith %}
+
+<div class="container">
+ {%if (not waiting) and (not approved) and (not rejected)%}
+ <div class="row" style="text-align: left; padding: 5em 0 0 5em;">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ <strong>There are no diffs to act on.</strong>
+ </div>
+ {%endif%}
+ {% if waiting %}
+ <h2>Files for approval:</h2>
+ <div class="row">
+ <div class="col-md-7">
+ <table class="table table-hover table-striped cell-border">
+ <thead>
+ <th scope="col">Resource Id</</th>
+ <th scope="col">Author</th>
+ <th scope="col">TimeStamp</th>
+ <th scope="col"></th>
+ <th scope="col"></th>
+ </thead>
+ <tbody>
+ {% for data in waiting %}
+ <tr>
+ {% set file_url = url_for('metadata_edit.show_diff', name=data.filepath.name) %}
+ <td><a href="{{ file_url }}" target="_blank">{{ data.meta.get("resource_id") }}</a></td>
+ <td>{{ data.meta.get("author")}}</td>
+ <td>{{ data.meta.get("time_stamp")}}</td>
+ {% set reject_url = url_for('metadata_edit.reject_data', resource_id=data.meta.get('resource_id'), file_name=data.filepath.name, dataset_name=data.diff.dataset_name, trait_name=data.diff.trait_name) %}
+ {% set approve_url = url_for('metadata_edit.approve_data', resource_id=data.meta.get('resource_id'), file_name=data.filepath.name, dataset_name=data.diff.dataset_name, trait_name=data.diff.trait_name) %}
+ <td>
+ <button type="button"
+ class="btn btn-secondary btn-sm">
+ <a href="{{ reject_url }}">Reject</a>
+ </button>
+ </td>
+ <td>
+ <button type="button"
+ class="btn btn-warning btn-sm">
+ <a href="{{ approve_url }}">Approve</a>
+ </button>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endif %}
+
+ {% if approved %}
+ <h2>Approved Data:</h2>
+ <div class="row">
+ <div class="col-md-8">
+ <table class="table-responsive table-hover table-striped cell-border" id="table-approved">
+ <thead>
+ <th scope="col">Resource Id</</th>
+ <th scope="col">Author</th>
+ <th scope="col">TimeStamp</th>
+ </thead>
+ <tbody>
+ {% for data in approved %}
+ <tr>
+ {% set file_url = url_for('metadata_edit.show_diff', name=data.filepath.name) %}
+ <td><a href="{{ file_url }}" target="_blank">{{ data.meta.get("resource_id") }}</a></td>
+ <td>{{ data.meta.get("author")}}</td>
+ <td>{{ data.meta.get("time_stamp")}}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endif %}
+
+ {% if rejected %}
+ <h2>Rejected Files:</h2>
+ <div class="row">
+ <div class="col-md-8">
+ <table class="table-responsive table-hover table-striped cell-border" id="table-rejected">
+ <thead>
+ <th scope="col">Resource Id</</th>
+ <th scope="col">Author</th>
+ <th scope="col">TimeStamp</th>
+ </thead>
+ <tbody>
+ {% for data in rejected %}
+ <tr>
+ {% set file_url = url_for('metadata_edit.show_diff', name=data.filepath.name) %}
+ <td><a href="{{ file_url }}" target="_blank">{{ data.meta.get("resource_id") }}</a></td>
+ <td>{{ data.meta.get("author")}}</td>
+ <td>{{ data.meta.get("time_stamp")}}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endif %}
+</div>
+{%endblock%}
+
+{% block js %}
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+<script language="javascript" type="text/javascript">
+ gn_server_url = "{{ gn_server_url }}";
+
+ $(document).ready( function() {
+ $('#table-approved').dataTable();
+ $('#table-rejected').dataTable();
+ });
+</script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/docedit.html b/gn2/wqflask/templates/docedit.html
new file mode 100644
index 00000000..50bb96c0
--- /dev/null
+++ b/gn2/wqflask/templates/docedit.html
@@ -0,0 +1,31 @@
+{% extends "base.html" %}
+
+{% block title %}Edit: {{title}}{% endblock %}
+
+{% block content %}
+<div class="container">
+ <h3>Edit: {{title}}</h3>
+ <form id="update_text" action="/update_text" method="post">
+ <input type="hidden" name="entry_type" value="{{ entry }}">
+ <input type="hidden" name="title" value="{{ title }}">
+ {% if editable is defined %}
+ <input type="hidden" name="edit" value="{{ editable }}">
+ {% endif %}
+ <button class="submit_changes" style="margin-bottom: 20px;">Submit Changes</button>
+ <textarea name="ckcontent" id="ckcontent">
+ {{content|safe}}
+ </textarea>
+ <button class="submit_changes" style="margin-top: 20px;">Submit Changes</button>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='ckeditor/ckeditor.js') }}"></script>
+ <script type="text/javascript">
+ CKEDITOR.replace('ckcontent', {
+ height: '650px',
+ });
+
+ $('.submit_changes').click(function() {
+ $('#update_text').submit();
+ })
+ </script>
+ </form>
+</div>
+{% endblock %}
diff --git a/gn2/wqflask/templates/docs.html b/gn2/wqflask/templates/docs.html
new file mode 100644
index 00000000..1e5a7aef
--- /dev/null
+++ b/gn2/wqflask/templates/docs.html
@@ -0,0 +1,17 @@
+{% extends "base.html" %}
+
+{% block title %}{{title}}{% endblock %}
+
+{% block content %}
+<div class="container">
+ <h3>{{title}}</h3>
+ <div style="text-align: right;">
+ {% if editable == "true" %}
+ <a href="docedit?entry={{entry}}&edit=true">
+ <img style="width: 16px;" src="/static/new/images/edit.gif">
+ </a>
+ {% endif %}
+ </div>
+ {{content|safe}}
+</div>
+{% endblock %}
diff --git a/gn2/wqflask/templates/edit_case_attributes.html b/gn2/wqflask/templates/edit_case_attributes.html
new file mode 100644
index 00000000..3c97b992
--- /dev/null
+++ b/gn2/wqflask/templates/edit_case_attributes.html
@@ -0,0 +1,104 @@
+{%extends "base.html"%}
+{%block title%}Edit Case Attributes{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+
+<style>
+ .table-fixed-head {overflow-y: auto; height: 32em;}
+ .table-fixed-head thead th {position: sticky; top: 0;}
+</style>
+{%endblock%}
+
+{%block content%}
+<div class="container">
+ <h1>{{inbredset_group.InbredSetName}}: Edit Case-Attributes</h1>
+
+ {{flash_me()}}
+
+ <h3>Instructions</h3>
+ <ul>
+ <li>
+ The table is scrollable. Scroll to find the strain(s) you want to edit.
+ </li>
+ <li>Change value(s) to edit them in the database.</li>
+ <li>Delete value(s) to delete them from the database.</li>
+ <li>Click "Submit" to submit all the changes you have made</li>
+ <li>
+ Click "Reset" to undo <strong>ALL</strong> the changes you have made and
+ start over.
+ </li>
+ </ul>
+
+ <a href="{{url_for('list_case_attribute_diffs', inbredset_id=inbredset_id)}}"
+ title="List out diffs awaiting review"
+ class="btn btn-info">View Diffs</a>
+
+ <form method="POST" action="{{url_for('edit_case_attributes', inbredset_id=inbredset_id)}}">
+ <div class="form-group" style="text-align: center; padding: 1em 0 0 0;">
+ <input type="submit" value="Submit" class="btn btn-primary" />
+ <input type="reset" value="Reset" class="btn btn-warning" />
+ </div>
+
+ <div class="table-fixed-head">
+ <table class="table-hover table-striped cell-border dataTable no-footer">
+ <thead>
+ <tr>
+ <th>Sample/Strain</th>
+ {%for caname in case_attribute_names%}
+ <th>{{caname.Name}}</th>
+ {%endfor%}
+ </tr>
+ </thead>
+ <tbody>
+ {%for strain in strains%}
+ <tr>
+ <div class="form-group">
+ <td>{{strain.Name}}</td>
+ {%for attr in case_attribute_names%}
+ {%if case_attribute_values.get(strain.Name)%}
+ <td>
+ <input type="text"
+ value="{{case_attribute_values[strain.Name]['case-attributes'].get(attr.Name, '')}}"
+ name="new:{{strain.Name}}:{{attr.Name}}"
+ class="form-control" />
+ </td>
+ {%else%}
+ <td>
+ <input type="text"
+ value=""
+ name="new:{{strain.Name}}:{{attr.Name}}"
+ class="form-control" />
+ </td>
+ {%endif%}
+ {%endfor%}
+ </div>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="{{case_attribute_names | length + 1}}">
+ No samples/strains for this InbredSet group.
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="form-group" style="text-align: center; padding: 1em 0 0 0;">
+ <input type="submit" value="Submit" class="btn btn-primary" />
+ <input type="reset" value="Reset" class="btn btn-warning" />
+ </div>
+ </form>
+</div>
+{%endblock%}
+
+{%block js%}
+<script language="javascript"
+ type="text/javascript"
+ src="{{url_for('js', filename='DataTables/js/jquery.js')}}"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/edit_history.html b/gn2/wqflask/templates/edit_history.html
new file mode 100644
index 00000000..876ab085
--- /dev/null
+++ b/gn2/wqflask/templates/edit_history.html
@@ -0,0 +1,56 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+{% endblock %}
+
+{% block content %}
+<!-- Start of body -->
+<div class="container">
+
+ <h1>History</h1>
+ {% if diff %}
+ <div class="row">
+ <table id="history" class="table-responsive table-hover table-striped cell-border">
+ <thead>
+ <th>Timestamp</th>
+ <th>Editor</th>
+ <th>Field</th>
+ <th>Diff</th>
+ </thead>
+ <tbody>
+ {%set ns = namespace(display_ts=True)%}
+ {%for ts, item in diff.items()%}
+ {%set ns.display_ts = True%}
+ {%for the_diff in item%}
+ <tr>
+ {%if ns.display_ts%}
+ <td rowspan={{item | length}}>{{ts}}</td>
+ {%set ns.display_ts = False%}
+ {%endif%}
+ <td>{{the_diff.author}}</td>
+ <td>{{the_diff.diff.field}}</td>
+ <td><pre>{{the_diff.diff.diff}}</pre></td>
+ </tr>
+ {%endfor%}
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+ {% endif %}
+
+</div>
+{%endblock%}
+
+{% block js %}
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+<script language="javascript" type="text/javascript">
+ gn_server_url = "{{ gn_server_url }}";
+
+ $(document).ready( function() {
+ $('#history').dataTable();
+ });
+</script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/edit_phenotype.html b/gn2/wqflask/templates/edit_phenotype.html
new file mode 100644
index 00000000..99efa46c
--- /dev/null
+++ b/gn2/wqflask/templates/edit_phenotype.html
@@ -0,0 +1,279 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+{% block content %}
+<!-- Start of body -->
+{% with messages = get_flashed_messages(with_categories=true) %}
+{% if messages %}
+{% for category, message in messages %}
+<div class="container-fluid bg-{{ category }}">
+ <p>{{ message|safe }}</p>
+</div>
+{% endfor %}
+{% endif %}
+{% endwith %}
+<div class="container">
+ <div class="page-header text-left">
+ <h1>Trait Metadata and Data Editing Form: {{ name }}</h1>
+ <small><a href="{{url_for('metadata_edit.show_history', dataset_id=dataset_id, name=name)}}" target="_blank">[View History]</a></small>
+ </div>
+
+ <form id="edit-form" class="form-horizontal" method="post" action="/datasets/{{dataset_id}}/traits/{{publish_xref.id_}}?resource-id={{resource_id}}&dataset_name={{dataset_name}}" enctype='multipart/form-data'>
+ <div class="form-group">
+ <div class="controls left-block col-sm-8 col-lg-8" style="width: max-content;">
+ <input name="inbred-set-id" class="changed" type="hidden" value="{{ publish_xref.inbred_set_id }}"/>
+ <input name="phenotype-id" class="changed" type="hidden" value="{{ publish_xref.phenotype_id }}"/>
+ <input name="comments" class="changed" type="hidden" value="{{ publish_xref.comments }}"/>
+ <input name="edited" class="changed" type="hidden" value="false"/>
+ </div>
+ </div>
+ <div>
+ <h2>Edit Sample Data</h2>
+ <p>
+ Download a spreadsheet of sample values to edit in Excel (or a similar program) and then upload the edited file
+ </p>
+ <div>
+ <a href="/datasets/pheno/{{ name }}/group/{{ dataset_id }}/csv?resource-id={{ resource_id }}" class="btn btn-link">
+ Click to Download Sample Data
+ </a>
+ </div>
+ <div class="form-group">
+ <input type = "file" class="col-md-4 control-label text-left" name = "file" />
+ </div>
+ <input type="submit" style="width: 125px; margin-right: 25px;" class="btn btn-success form-control changed" value="Submit Change">
+ </div>
+ <hr>
+ <div>
+ <h2>Edit Metadata</h2>
+ <div class="form-group">
+ <label for="pubmed-id" class="col-sm-3 col-lg-2 control-label text-left">PubMed ID</label>
+ <!-- Do not enter PubMed_ID if this trait has not been Published.
+ If the PubMed_ID you entered is alreday stored in our
+ database, all the following fields except Postpublication
+ Description will be ignored. Do not enter any non-digit
+ character in this field. -->
+ <div class="col-sm-7 col-lg-8">
+ <input type="text" name="pubmed-id" class="form-control"
+ value="{{publication.pubmed_id |default('', true)}}">
+ <input name="old_id_" class="changed" type="hidden" value="{{ publication.id_ |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="pre-pub-desc" class="col-sm-3 col-lg-2 control-label text-left">Prepublication Description</label>
+ <div class="col-sm-7 col-lg-8">
+ <textarea name="pre-pub-desc" class="form-control" rows="4">{{ phenotype.pre_pub_description |default('', true) }}</textarea>
+ <input name="old_pre_pub_description" class="changed" type="hidden" value="{{ phenotype.pre_pub_description |default('', true) }}"/>
+ </div>
+ <!-- If the PubMed ID is entered, the Postpublication Description
+ will be shown to all users. If there is no PubMed ID, and the
+ Prepublication Description is entered, only you and
+ authorized users can see the Postpublication Description -->
+ </div>
+ <div class="form-group">
+ <label for="post-pub-desc" class="col-sm-3 col-lg-2 control-label text-left">Postpublication Description</label>
+ <div class="col-sm-7 col-lg-8">
+ <textarea name="post-pub-desc" class="form-control" rows="4">{{ phenotype.post_pub_description |default('', true) }}</textarea>
+ <input name="old_post_pub_description" class="changed" type="hidden" value="{{ phenotype.post_pub_description |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="orig-desc" class="col-sm-3 col-lg-2 control-label text-left">Original Description</label>
+ <div class="col-sm-7 col-lg-8">
+ <textarea name="orig-desc" class="form-control" rows="4">{{ phenotype.original_description |default('', true) }}</textarea>
+ <input name="old_original_description" class="changed" type="hidden" value="{{ phenotype.original_description |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="txt:units" class="col-sm-3 col-lg-2 control-label text-left">Units</label>
+ <div class="col-sm-7 col-lg-8">
+ <input id="txt:units" type="text" name="units"
+ class="form-control"
+ value="{{phenotype.units |default('', true)}}" />
+ <input name="old_units" class="changed" type="hidden" value="{{ phenotype.units |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="pre-pub-abbrev" class="col-sm-3 col-lg-2 control-label text-left">
+ Prepublication Abbreviation
+ </label>
+ <div class="col-sm-7 col-lg-8">
+ <input id="pre-pub-abbrev" name="pre-pub-abbrev"
+ class="form-control"
+ value="{{phenotype.pre_pub_abbreviation |default('', true)}}" />
+ <input name="old_pre_pub_abbreviation" class="changed" type="hidden" value="{{ phenotype.pre_pub_abbreviation |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="post-pub-abbrev" class="col-sm-3 col-lg-2 control-label text-left">
+ Postpublication Abbreviation
+ </label>
+ <div class="col-sm-7 col-lg-8">
+ <input type="text" id="post-pub-abbrex" name="post-pub-abbrev"
+ class="form-control"
+ value="{{phenotype.post_pub_abbreviation |default('', true)}}" />
+ <input name="old_post_pub_abbreviation" class="changed" type="hidden" value="{{ phenotype.post_pub_abbreviation |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="labcode" class="col-sm-3 col-lg-2 control-label text-left">
+ Lab Code
+ </label>
+ <div class="col-sm-7 col-lg-8">
+ <input type="text" id="labcode" name="labcode"
+ class="form-control"
+ value="{{phenotype.lab_code |default('', true) }}" />
+ <input name="old_lab_code" class="changed" type="hidden" value="{{ phenotype.lab_code |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="submitter" class="col-sm-3 col-lg-2 control-label text-left">
+ Submitter
+ </label>
+ <div class="col-sm-7 col-lg-8">
+ <input type="text" id="submitter" name="submitter"
+ class="form-control"
+ value="{{phenotype.submitter |default('', true)}}" />
+ <input name="old_submitter" class="changed" type="hidden" value="{{ phenotype.submitter |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="authorized-users" class="col-sm-3 col-lg-2 control-label text-left">
+ Authorized Users
+ </label>
+ <div class="col-sm-7 col-lg-8">
+ <input type="text" id="authorized-users" name="authorized-users"
+ class="form-control"
+ value="{{phenotype.authorized_users |default('', true)}}" />
+ <input name="old_authorized_users" class="changed" type="hidden" value="{{ phenotype.authorized_users |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="authors" class="col-sm-3 col-lg-2 control-label text-left">Authors</label>
+ <div class="col-sm-7 col-lg-8">
+ <textarea name="authors" class="form-control" rows="3" placeholder="Example: Roy S, Ingels J, Bohl CJ, McCarty M, Lu L, Mulligan MK, Mozhui K, Centeno A, Williams EG, Auwerx J, Williams RW">{{ publication.authors |default('', true) }}</textarea>
+ <input name="old_authors" class="changed" type="hidden" value="{{ publication.authors |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="year" class="col-sm-3 col-lg-2 control-label text-left">Year</label>
+ <div class="col-sm-7 col-lg-8">
+ <input type="number" name="year" class="form-control"
+ min="1000"
+ value="{{publication.year |default(datetime.datetime.now().year) }}" />
+ <input name="old_year" class="changed" type="hidden" value="{{ publication.year |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="month" class="col-sm-3 col-lg-2 control-label text-left">Month</label>
+ <div class="col-sm-7 col-lg-8">
+ <select id="month" name="month" class="form-control">
+ {%set selected_month =(publication.month or datetime.datetime.now().strftime("%b"))%}
+ {%for smonth, lmonth in (("Jan", "January"),("Feb", "February"),("Mar", "March"),("Apr", "April"),("May", "May"),("Jun", "Jun"),("Jul", "July"),("Aug", "August"),("Sep", "September"),("Oct", "October"),("Nov", "November"),("Dec", "December"))%}
+ <option value="{{smonth}}"
+ {%if smonth == selected_month%}
+ selected="selected"
+ {%endif%}>{{lmonth}}</option>
+ {%endfor%}
+ </select>
+ <input name="old_month" class="changed" type="hidden" value="{{ publication.month |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="txt:title" class="col-sm-3 col-lg-2 control-label text-left">Title</label>
+ <div class="col-sm-7 col-lg-8">
+ <input type="text" id="txt:title" name="title"
+ class="form-control"
+ value="{{publication.title |default('', true)}}" />
+ <input name="old_title" class="changed" type="hidden" value="{{ publication.title |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="abstract" class="col-sm-3 col-lg-2 control-label text-left">Abstract</label>
+ <div class="col-sm-7 col-lg-8">
+ <textarea name="abstract" class="form-control" rows="6">{{ publication.abstract |default('', true) }}</textarea>
+ <input name="old_abstract" class="changed" type="hidden" value="{{ publication.abstract |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="volume" class="col-sm-3 col-lg-2 control-label text-left">Volume</label>
+ <div class="col-sm-7 col-lg-8">
+ <input type="text" id="volume" name="volume"
+ class="form-control"
+ value="{{publication.volume |default('', true)}}" />
+ <input name="old_volume" class="changed" type="hidden" value="{{ publication.volume |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="journal" class="col-sm-3 col-lg-2 control-label text-left">Journal</label>
+ <div class="col-sm-7 col-lg-8">
+ <input type="text" id="journal" name="journal"
+ class="form-control"
+ value="{{publication.journal |default('', true)}}" />
+ <input name="old_journal" class="changed" type="hidden" value="{{ publication.journal_ |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="pages" class="col-sm-3 col-lg-2 control-label text-left">Pages</label>
+ <div class="col-sm-7 col-lg-8">
+ <input type="text" id="pages" name="pages"
+ class="form-control"
+ value="{{publication.pages |default('', true)}}" />
+ <input name="old_pages" class="changed" type="hidden" value="{{ publication.pages |default('', true) }}"/>
+ </div>
+ </div>
+ <input type="submit" style="width: 125px; margin-right: 25px;" class="btn btn-success form-control changed" value="Submit Change">
+ </div>
+ {% if sample_list|length < 2000 %}
+ <div style="padding-top: 20px;">
+ <p class="text-info" style="padding-left: 5em;">
+ <strong>Type "x" to delete a value.</strong>
+ </p>
+ <table style="width: 500px;" class="table table-hover table-striped table-bordered left-float">
+ <thead>
+ <th></th>
+ <th>ID</th>
+ <th>Sample</th>
+ <th>Value</th>
+ <th></th>
+ <th>SE</th>
+ <th>N</th>
+ </thead>
+ <tbody>
+ {% for sample in sample_list %}
+ <tr>
+ <td><input type="checkbox"></td>
+ <td>{{ loop.index }}</td>
+ <td>{{ sample }}</td>
+ <td><input type="text" name="value:{{ sample }}" class="table_input" value="{% if sample_data.get(sample) %}{{ '%0.3f' | format(sample_data.get(sample).value | float) }}{% else %}x{% endif %}" size=4 maxlength=6></input></td>
+ <td>±</td>
+ <td><input type="text" name="error:{{ sample }}" class="table_input" value="{% if sample_data.get(sample).error %}{{ '%0.3f' | format(sample_data.get(sample).error | float) }}{% else %}x{% endif %}" size=4 maxlength=5></input></td>
+ <td><input type="text" name="n_cases:{{ sample }}" class="table_input" value="{% if sample_data.get(sample).n_cases %}{{ sample_data.get(sample).n_cases }}{% else %}x{% endif %}" size=3 maxlength=3></input></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ {% endif %}
+
+ </form>
+</div>
+
+{%endblock%}
+
+{% block js %}
+<script>
+ gn_server_url = "{{ gn_server_url }}";
+ function MarkAsChanged(){
+ $(this).addClass("changed");
+ }
+ $(":input").blur(MarkAsChanged).change(MarkAsChanged);
+
+ $("input[type=submit]").click(function(){
+ $(":input:not(.changed)").attr("disabled", "disabled");
+ });
+
+ // This is an awkward way to detect changes to table data, so it doesn't process it otherwise
+ $(".table_input").change(function(){
+ $("input[name=edited]").val("true");
+ });
+</script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/edit_probeset.html b/gn2/wqflask/templates/edit_probeset.html
new file mode 100644
index 00000000..88e97837
--- /dev/null
+++ b/gn2/wqflask/templates/edit_probeset.html
@@ -0,0 +1,282 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+{% block content %}
+<!-- Start of body -->
+<div class="container">
+ {% with messages = get_flashed_messages(category_filter=["warning"]) %}
+ {% if messages %}
+ {% for message in messages %}
+ <div class="alert alert-warning alert-dismissible" role="alert">
+ <button class="close" type="button" data-dismiss="alert" aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ {{ message }}
+ </div>
+ {% endfor %}
+ {% endif %}
+ {% endwith %}
+
+ {% with messages = get_flashed_messages(category_filter=["success"]) %}
+ {% if messages %}
+ {% for message in messages %}
+ <div class="alert alert-success alert-dismissible" role="alert">
+ <button class="close" type="button" data-dismiss="alert" aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ {{ message|safe }}
+ </div>
+ {% endfor %}
+ {% endif %}
+ {% endwith %}
+ <div class="page-header text-left">
+ <h1>Trait Metadata and Data Editing Form: {{ name }}</h1>
+ <small><a href="{{url_for('metadata_edit.show_history', dataset_id=dataset_id, name=name)}}" target="_blank">[View History]</a></small>
+ </div>
+ <form id="edit-form" class="form-horizontal" method="post" action="/datasets/traits/{{name}}?resource-id={{resource_id}}&dataset_id={{dataset_name}}" enctype='multipart/form-data'>
+ <div class="form-group">
+ <div class="controls left-block col-sm-8 col-lg-8" style="width: max-content;">
+ <input name="id" class="changed" type="hidden" value="{{ probeset.id_ }}"/>
+ <input name="old_id_" class="changed" type="hidden" value="{{ probeset.id_ }}"/>
+ <input name="probeset_name" class="changed" type="hidden" value="{{ probeset.name }}"/>
+ <input name="dataset_name" class="changed" type="hidden" value="{{ dataset_name }}"/>
+ <input name="edited" class="changed" type="hidden" value="false"/>
+ </div>
+ </div>
+ <div>
+ <h2>Edit Sample Data</h2>
+ <p>
+ Download a spreadsheet of sample values to edit in Excel (or a similar program) and then upload the edited file
+ </p>
+ <div>
+ <a href="/datasets/mrna/{{ probeset_id }}/dataset/{{ dataset_name }}/csv?resource-id={{ resource_id }}" class="btn btn-link">
+ Click to Download Sample Data
+ </a>
+ </div>
+ <div class="form-group">
+ <input type = "file" class="col-md-4 control-label text-left" name = "file" />
+ </div>
+ <input type="submit" style="width: 125px; margin-right: 25px;" class="btn btn-success form-control changed" value="Submit Change">
+ </div>
+ <hr>
+ <div>
+ <h2>Edit Metadata</h2>
+ <div class="form-group">
+ <label for="symbol" class="col-sm-3 col-lg-2 control-label text-left">Symbol</label>
+ <div class="col-sm-4">
+ <textarea name="symbol" class="form-control" rows="1">{{ probeset.symbol |default('', true) }}</textarea>
+ <input name="old_symbol" class="changed" type="hidden" value="{{ probeset.symbol |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="description" class="col-sm-3 col-lg-2 control-label text-left">Description</label>
+ <div class="col-sm-4">
+ <textarea name="description" class="form-control" rows="3">{{ probeset.description |default('', true) }}</textarea>
+ <input name="old_description" class="changed" type="hidden" value="{{ probeset.description |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_target_description" class="col-sm-3 col-lg-2 control-label text-left">Probe Target Description</label>
+ <div class="col-sm-4">
+ <textarea name="probe_target_description" class="form-control" rows="4">{{ probeset.probe_target_description |default('', true) }}</textarea>
+ <input name="old_probe_target_description" class="changed" type="hidden" value="{{ probeset.probe_target_description |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="chr" class="col-sm-3 col-lg-2 control-label text-left">Chr</label>
+ <div class="col-sm-4">
+ <textarea name="chr" class="form-control" rows="1">{{ probeset.chr_ |default('', true) }}</textarea>
+ <input name="old_chr_" class="changed" type="hidden" value="{{ probeset.chr_ |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="mb" class="col-sm-3 col-lg-2 control-label text-left">Mb</label>
+ <div class="col-sm-4">
+ <textarea name="mb" class="form-control" rows="1">{{ probeset.mb |default('', true) }}</textarea>
+ <input name="old_mb" class="changed" type="hidden" value="{{ probeset.mb |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="alias" class="col-sm-3 col-lg-2 control-label text-left">
+ Alias:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="alias" class="form-control" rows="1">{{ probeset.alias |default('', true) }}</textarea>
+ <input name="old_alias" class="changed" type="hidden" value="{{ probeset.alias |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="geneid" class="col-sm-3 col-lg-2 control-label text-left">
+ Gene Id:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="geneid" class="form-control" rows="1">{{ probeset.geneid |default('', true) }}</textarea>
+ <input name="old_geneid" class="changed" type="hidden" value="{{ probeset.geneid |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="homologeneid" class="col-sm-3 col-lg-2 control-label text-left">
+ Homologene Id:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="homologeneid" class="form-control" rows="1">{{ probeset.homologeneid |default('', true) }}</textarea>
+ <input name="old_homologeneid" class="changed" type="hidden" value="{{ probeset.homologeneid |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="unigeneid" class="col-sm-3 col-lg-2 control-label text-left">
+ Unigene Id:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="unigeneid" class="form-control" rows="1">{{ probeset.unigeneid |default('', true) }}</textarea>
+ <input name="old_unigeneid" class="changed" type="hidden" value="{{ probeset.unigeneid |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="omim" class="col-sm-3 col-lg-2 control-label text-left">OMIM</label>
+ <div class="col-sm-4">
+ <textarea name="omim" class="form-control" rows="1">{{ probeset.omim |default('', true) }}</textarea>
+ <input name="old_omim" class="changed" type="hidden" value="{{ probeset.omim |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="refseq_transcriptid" class="col-sm-3 col-lg-2 control-label text-left">
+ Refseq TranscriptId:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="refseq_transcriptid" class="form-control" rows="1">{{ probeset.refseq_transcriptid |default('', true) }}</textarea>
+ <input name="old_refseq_transcriptid" class="changed" type="hidden" value="{{ probeset.refseq_transcriptid |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="blatseq" class="col-sm-3 col-lg-2 control-label text-left">BlatSeq</label>
+ <div class="col-sm-8">
+ <textarea name="blatseq" class="form-control" rows="6">{{ probeset.blatseq |default('', true) }}</textarea>
+ <input name="old_blatseq" class="changed" type="hidden" value="{{ probeset.blatseq |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="targetseq" class="col-sm-3 col-lg-2 control-label text-left">TargetSeq</label>
+ <div class="col-sm-8">
+ <textarea name="targetseq" class="form-control" rows="6">{{ probeset.targetseq |default('', true) }}</textarea>
+ <input name="old_targetseq" class="changed" type="hidden" value="{{ probeset.targetseq |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="strand_probe" class="col-sm-3 col-lg-2 control-label text-left">Strand Probe</label>
+ <div class="col-sm-2">
+ <textarea name="strand_probe" class="form-control" rows="1">{{ probeset.strand_probe |default('', true) }}</textarea>
+ <input name="old_strand_probe" class="changed" type="hidden" value="{{ probeset.strand_probe |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_target_region" class="col-sm-3 col-lg-2 control-label text-left">Probe Set Target Region</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_target_region" class="form-control" rows="1">{{ probeset.probe_set_target_region |default('', true) }}</textarea>
+ <input name="old_probe_set_target_region" class="changed" type="hidden" value="{{ probeset.probe_set_target_region_ |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_specificity" class="col-sm-3 col-lg-2 control-label text-left">Probeset Specificity</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_specificity" class="form-control" rows="1">{{ probeset.probe_set_specificity |default('', true) }}</textarea>
+ <input name="old_probe_set_specificity" class="changed" type="hidden" value="{{ probeset.probe_set_specificity |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_blat_score" class="col-sm-3 col-lg-2 control-label text-left">Probeset Blat Score</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_blat_score" class="form-control" rows="1">{{ probeset.probe_set_blat_score |default('', true) }}</textarea>
+ <input name="old_probe_set_blat_score" class="changed" type="hidden" value="{{ probeset.probe_set_blat_score |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_blat_mb_start" class="col-sm-3 col-lg-2 control-label text-left">
+ Probeset Blat Mb Start</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_blat_mb_start" class="form-control" rows="1">{{ probeset.probe_set_blat_mb_start |default('', true) }}</textarea>
+ <input name="old_probe_set_blat_mb_start" class="changed" type="hidden" value="{{ probeset.probe_set_blat_mb_start |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_blat_mb_end" class="col-sm-3 col-lg-2 control-label text-left">Probeset Blat Mb End</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_blat_mb_end" class="form-control" rows="1">{{ probeset.probe_set_blat_mb_end |default('', true) }}</textarea>
+ <input name="old_probe_set_blat_mb_end" class="changed" type="hidden" value="{{ probeset.probe_set_blat_mb_end |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_strand" class="col-sm-3 col-lg-2 control-label text-left">Probeset Strand</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_strand" class="form-control" rows="6">{{ probeset.probe_set_strand |default('', true) }}</textarea>
+ <input name="old_probe_set_strand" class="changed" type="hidden" value="{{ probeset.probe_set_strand |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_note_by_rw" class="col-sm-3 col-lg-2 control-label text-left">Probeset Strand</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_note_by_rw" class="form-control" rows="6">{{ probeset.probe_set_note_by_rw |default('', true) }}</textarea>
+ <input name="old_probe_set_note_by_rw" class="changed" type="hidden" value="{{ probeset.probe_set_note_by_rw |default('', true) }}"/>
+ </div>
+ </div>
+ <input type="submit" style="width: 125px; margin-right: 25px;" class="btn btn-success form-control col-xs-2 changed" value="Submit Change">
+ </div>
+ <div style="padding-top: 20px;">
+ <p class="text-info" style="padding-left: 5em;">
+ <strong>Type "x" to delete a value.</strong>
+ </p>
+ <table style="width: 500px;" class="table table-hover table-striped table-bordered left-float">
+ <thead>
+ <th></th>
+ <th>ID</th>
+ <th>Sample</th>
+ <th>Value</th>
+ <th></th>
+ <th>SE</th>
+ <th>N</th>
+ </thead>
+ <tbody>
+ {% for sample in sample_list %}
+ <tr>
+ <td><input type="checkbox"></td>
+ <td>{{ loop.index }}</td>
+ <td>{{ sample }}</td>
+ <td><input type="text" name="value:{{ sample }}" class="table_input" value="{% if sample_data.get(sample) %}{{ '%0.3f' | format(sample_data.get(sample).value | float) }}{% else %}x{% endif %}" size=4 maxlength=6></input></td>
+ <td>±</td>
+ <td><input type="text" name="error:{{ sample }}" class="table_input" value="{% if sample_data.get(sample).error %}{{ '%0.3f' | format(sample_data.get(sample).error | float) }}{% else %}x{% endif %}" size=4 maxlength=5></input></td>
+ <td><input type="text" name="n_cases:{{ sample }}" class="table_input" value="{% if sample_data.get(sample).n_cases %}{{ sample_data.get(sample).n_cases }}{% else %}x{% endif %}" size=3 maxlength=3></input></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+
+ </form>
+</div>
+
+{%endblock%}
+
+{% block js %}
+<script>
+ gn_server_url = "{{ gn_server_url }}";
+ spans = document.querySelectorAll("[data-message-id]")
+ spans.forEach((span) => {
+ span.innerHTML = $("[for='" + span.getAttribute("data-message-id") + "']").text();
+ });
+ $("[data-message-id]").lead
+
+ function MarkAsChanged(){
+ $(this).addClass("changed");
+ }
+ $(":input").blur(MarkAsChanged).change(MarkAsChanged);
+
+ $("input[type=submit]").click(function(){
+ $(":input:not(.changed)").attr("disabled", "disabled");
+ });
+
+ // This is an awkward way to detect changes to table data, so it doesn't process it otherwise
+ $(".table_input").change(function(){
+ $("input[name=edited]").val("true");
+ });
+
+</script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/email/forgot_password.txt b/gn2/wqflask/templates/email/forgot_password.txt
new file mode 100644
index 00000000..e7d1389b
--- /dev/null
+++ b/gn2/wqflask/templates/email/forgot_password.txt
@@ -0,0 +1,5 @@
+Sorry to hear you lost your GeneNetwork password.
+
+To reset your password please click the following link, or cut and paste it into your browser window:
+
+{{ url_for_hmac("password_reset", code = verification_code, _external=True )}}
diff --git a/gn2/wqflask/templates/empty_collection.html b/gn2/wqflask/templates/empty_collection.html
new file mode 100644
index 00000000..d1b779ef
--- /dev/null
+++ b/gn2/wqflask/templates/empty_collection.html
@@ -0,0 +1,15 @@
+{% extends "base.html" %}
+{% block title %}{{ tool }}{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ {{ header("Error") }}
+
+ <div class="container">
+ <input type="hidden" name="uc_id" id="uc_id" value="{{ uc_id }}">
+ <p>You must select at least two traits to use the {{ tool }}.</p>
+ </div>
+
+
+<!-- End of body -->
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/environment.html b/gn2/wqflask/templates/environment.html
new file mode 100644
index 00000000..89e805ce
--- /dev/null
+++ b/gn2/wqflask/templates/environment.html
@@ -0,0 +1,160 @@
+{% extends "base.html" %}
+
+{% block title %}Glossary{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+
+{% block content %}
+
+<div id="markdown" class="container">
+
+ <div class="cls-table-style">{{ rendered_markdown|safe }} </div>
+</div>
+
+{% if svg_data %}
+
+<div class="graph-legend">
+ <h1>Chord dependency Graph of Genenetwork2</h1>
+ Graph generated from <a href="http://git.genenetwork.org/guix-bioinformatics/guix-bioinformatics/src/branch/master/gn/packages/genenetwork.scm">genenetwork.scm</a>. You can zoom in and out within the bounding box.
+</div>
+
+<div id="guix-graph"></div>
+
+<!-- Display the svg graph -->
+
+<div id="guix-svg-graph">
+ <h1>The dependency graph is shown below</h1>
+
+ <p>To explore this image SVG you may want to open it in new browser page and zoom in. Or use an SVG viewing application.</p>
+
+ <img alt="Dependency graph of the tools needed to build python3-genenetwork2" src="{{url_for('environments_blueprint.svg_graph')}}"/>
+</div>
+{% endif %}
+
+{% endblock %}
+
+{% block js %}
+
+{% if svg_data %}
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script>
+<script type="text/javascript">
+ {{ svg_data|safe }}
+ // based on http://bl.ocks.org/mbostock/1046712 under GPLv3
+ // Adapted from: https://elephly.net/graph.html
+ var outerRadius = (nodeArray.length * 10) / 2,
+ innerRadius = outerRadius - 100,
+ width = outerRadius * 2,
+ height = outerRadius * 2,
+ colors = d3.scale.category20c(),
+ matrix = [];
+
+ function neighborsOf (node) {
+ return links.filter(function (e) {
+ return e.source === node;
+ }).map(function (e) {
+ return e.target;
+ });
+ }
+
+ function zoomed () {
+ zoomer.attr("transform",
+ "translate(" + d3.event.translate + ")" +
+ "scale(" + d3.event.scale + ")");
+ }
+
+ function fade (opacity, root) {
+ return function (g, i) {
+ root.selectAll("g path.chord")
+ .filter(function (d) {
+ return d.source.index != i && d.target.index != i;
+ })
+ .transition()
+ .style("opacity", opacity);
+ };
+ }
+
+ // Now that we have all nodes in an object we can replace each reference
+ // with the actual node object.
+ links.forEach(function (link) {
+ link.target = nodes[link.target];
+ link.source = nodes[link.source];
+ });
+
+ // Construct a square matrix for package dependencies
+ nodeArray.forEach(function (d, index, arr) {
+ var source = index,
+ row = matrix[source];
+ if (!row) {
+ row = matrix[source] = [];
+ for (var i = -1; ++i < arr.length;) row[i] = 0;
+ }
+ neighborsOf(d).forEach(function (d) { row[d.index]++; });
+ });
+
+ // chord layout
+ var chord = d3.layout.chord()
+ .padding(0.01)
+ .sortSubgroups(d3.descending)
+ .sortChords(d3.descending)
+ .matrix(matrix);
+
+ var arc = d3.svg.arc()
+ .innerRadius(innerRadius)
+ .outerRadius(innerRadius + 20);
+
+ var zoom = d3.behavior.zoom()
+ .scaleExtent([0.1, 10])
+ .on("zoom", zoomed);
+
+ var svg = d3.select("#guix-graph").append("svg")
+ .attr("width", "100%")
+ .attr("height", "100%")
+ .attr('viewBox','0 0 '+Math.min(width,height)+' '+Math.min(width,height))
+ .attr('preserveAspectRatio','xMinYMin')
+ .call(zoom);
+
+ var zoomer = svg.append("g");
+
+ var container = zoomer.append("g")
+ .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");
+
+ // Group for arcs and labels
+ var g = container.selectAll(".group")
+ .data(chord.groups)
+ .enter().append("g")
+ .attr("class", "group")
+ .on("mouseout", fade(1, container))
+ .on("mouseover", fade(0.1, container));
+
+ // Draw one segment per package
+ g.append("path")
+ .style("fill", function (d) { return colors(d.index); })
+ .style("stroke", function (d) { return colors(d.index); })
+ .attr("d", arc);
+
+ // Add circular labels
+ g.append("text")
+ .each(function (d) { d.angle = (d.startAngle + d.endAngle) / 2; })
+ .attr("dy", ".35em")
+ .attr("transform", function (d) {
+ return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
+ + "translate(" + (innerRadius + 26) + ")"
+ + (d.angle > Math.PI ? "rotate(180)" : "");
+ })
+ .style("text-anchor", function (d) { return d.angle > Math.PI ? "end" : null; })
+ .text(function (d) { return nodeArray[d.index].label; });
+
+ // Draw chords from source to target; color by source.
+ container.selectAll(".chord")
+ .data(chord.chords)
+ .enter().append("path")
+ .attr("class", "chord")
+ .style("stroke", function (d) { return d3.rgb(colors(d.source.index)).darker(); })
+ .style("fill", function (d) { return colors(d.source.index); })
+ .attr("d", d3.svg.chord().radius(innerRadius));
+</script>
+{% endif %}
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/error.html b/gn2/wqflask/templates/error.html
new file mode 100644
index 00000000..2f1e06fa
--- /dev/null
+++ b/gn2/wqflask/templates/error.html
@@ -0,0 +1,61 @@
+{% extends "base.html" %}
+{% block title %}Error: {{message}}{% endblock %}
+{% block content %}
+<!-- Start of body -->
+
+<div class="col-md-8">
+<div class="form-group has-error">
+ <div class="control-label" for="inputError1">
+
+ <img src="/static/gif/error/{{ error_image }}">
+
+ <h1>ERROR</h1>
+
+ <p>
+ This error is not what we wanted to see. Unfortunately errors
+ are part of all software systems and we need to resolve this
+ together.
+ </p>
+ <p>
+ <b>It is important to report this ERROR so we can fix it for everyone</b>.
+ </p>
+
+ <p>
+ Report to the GeneNetwork team by recording the steps you take
+ to reproduce this ERROR. Next to those steps, copy-paste below
+ stack trace, either as
+ a <a href="https://github.com/genenetwork/genenetwork2/issues/new">new
+ issue</a> or E-mail this full page to one of the developers
+ directly.
+ </p>
+ </div>
+
+ <p>
+ (GeneNetwork error: {{message[:128]}})
+ </p>
+
+ <pre>
+ GeneNetwork {{ version }} {{ stack[0] }}
+ {{ message }} (error)
+ {{ stack[-3] }}
+ {{ stack[-2] }}
+ </pre>
+
+ <p>
+ To check if this already a known issue, search the
+ <a href="https://github.com/genenetwork/genenetwork2/issues">issue
+ tracker</a>.
+ </p>
+
+ <a href="#Stack" class="btn btn-default" data-toggle="collapse">Toggle full stack trace</a>
+ <div id="Stack" class="collapse">
+ <pre>
+ GeneNetwork {{ version }} {% for line in stack %} {{ line }}
+ {% endfor %}
+ </pre>
+ </div>
+</div>
+</div>
+
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/facilities.html b/gn2/wqflask/templates/facilities.html
new file mode 100644
index 00000000..56b127f9
--- /dev/null
+++ b/gn2/wqflask/templates/facilities.html
@@ -0,0 +1,24 @@
+{% extends "base.html" %}
+
+{% block title %}Facilities{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+
+{% block content %}
+
+ <div class="github-btn-container">
+ <div class="github-btn">
+ <a href="https://github.com/genenetwork/gn-docs/blob/master/general/help/facilities.md">
+ Edit Text
+ <img src="/static/images/edit.png">
+ </a>
+ </div>
+</div>
+<div id="markdown" class="container">
+ {{ rendered_markdown|safe }}
+
+</div>
+
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/generif.html b/gn2/wqflask/templates/generif.html
new file mode 100644
index 00000000..ac815b43
--- /dev/null
+++ b/gn2/wqflask/templates/generif.html
@@ -0,0 +1,101 @@
+{% extends "base.html" %}
+
+{% block title %}
+GeneWiki Entry for {{ symbol }}
+{% endblock %}
+
+{% block css %}
+<style>
+
+ .badge {
+ vertical-align: top;
+ background-color: #336699;
+ }
+
+ .list-group {
+ counter-reset: gnentries;
+ }
+
+ summary::before {
+ counter-increment: gnentries;
+ content: counter(gnentries) "." " ";
+ }
+
+ summary:hover {
+ cursor: zoom-in;
+ }
+</style>
+
+{% endblock %}
+{% block content %}
+
+
+<div class="container">
+ <h1 class="page-header">GeneWiki For {{ symbol }}</h1>
+ <p class="well"><strong>GeneWiki</strong> enables you to enrich the annotation of genes and transcripts.</p>
+
+ <h3>
+ <strong>GeneNetwork</strong>
+ <span class="badge">
+ {{ entries.gn_entries|length if entries.gn_entries[0] else 0 }}
+ </span>:
+ </h3>
+ {% if entries.gn_entries[0] %}
+ <ul class="list-group">
+ {% for entry in entries.gn_entries %}
+ <li class="list-group-item">
+ <details>
+ <summary>
+ {{ entry["entry"]["value"] }}
+ {% if entry.get("weburl") %}
+ <sup><small><a href="{{ entry.weburl.value }}" target="_blank"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> web</a></small></sup>
+ {% endif %}
+ </summary>
+ <dl class="dl-horizontal">
+ <dt>Author:</dt>
+ <dd>{{ entry["author"]["value"] }}</dd>
+
+ {% if entry.get("geneCategory") %}
+ <dt>Category:</dt>
+ <dd>{{ entry["geneCategory"]["value"]}}</dd>
+ {% endif %}
+
+ <dt>Add Time:</dt>
+ <dd>{{ entry["created"]["value"]}}</dd>
+ </dl>
+ </details>
+ </li>
+ {% endfor %}
+ </ul>
+
+ {% else %}
+
+ <p class="well"><u>There are no GeneNetwork entries for <b>{{ symbol }}.</b></u></p>
+
+ {% endif %}
+
+ <h3>
+ <strong>GeneRIF from NCBI</strong>
+ <span class="badge">
+ {{ entries.ncbi_entries|length if entries.ncbi_entries[0] else 0 }}
+ </span>:
+ </h3>
+ {% if entries.ncbi_entries[0] %}
+ <ol>
+ {% for entry in entries.ncbi_entries %}
+ <li>
+ {{ entry.entry.value }}
+ (<a href="{{ entry['generif']['value'] }}" target="_blank">{{ entry["speciesBinomialName"]["value"] }}</a>)
+ {% if entry.PubMedId.value != "" %}
+ {% set pmids = entry.PubMedId.value.split(",") %}
+ (PubMed: {% for id in pmids %} <a href="http://rdf.ncbi.nlm.nih.gov/pubmed/{{ id }}" target="_blank">{{ id }}</a>{% endfor %})
+ <sup><small><em>{{ entry.createdOn.value }}</em></small></sup>
+ {% endif %}
+ </li>
+ {% endfor %}
+ </ol>
+ {% else %}
+ <p class="well"><u>There are no NCBI entries for <b>{{ symbol }}.</b></u></p>
+ {% endif %}
+</div>
+{% endblock %}
diff --git a/gn2/wqflask/templates/geneweaver_page.html b/gn2/wqflask/templates/geneweaver_page.html
new file mode 100644
index 00000000..7687cb6a
--- /dev/null
+++ b/gn2/wqflask/templates/geneweaver_page.html
@@ -0,0 +1,35 @@
+{% extends "base.html" %}
+{% block title %}{% if wrong_input == "True" %}WebGestalt Error{% else %}Opening WebGestalt{% endif %}{% endblock %}
+{% block content %}
+ {% if wrong_input == "True" %}
+ <div class="container">
+ <h1>Error</h1>
+ <hr style="height: 1px; background-color: #A9A9A9;">
+ {% if chip_name == "mixed" %}
+ <h3>Sorry, the analysis was interrupted because your selections from GeneNetwork apparently include data from more than one array platform (i.e., Affymetrix U74A and M430 2.0). Most WebGestalt analyses assume that you are using a single array type and compute statistical values on the basis of that particular array. Please reselect traits from a signle platform and submit again.</h3>
+ {% elif chip_name == "not_microarray" %}
+ <h3>You need to select at least one microarray trait to submit.</hr>
+ {% elif '_NA' in chip_name %}
+ <h3>Sorry, the analysis was interrupted because your selections from GeneNetwork apparently include data from platform {{ chip_name }} which is unknown by GeneWeaver. Please reselect traits and submit again.</h3>
+ {% else %}
+ <h3>Sorry, an error occurred while submitting your traits to GeneWeaver.</h3>
+ {% endif %}
+ </div>
+ {% else %}
+ <div class="container">
+ <h3>Opening GeneWeaver...</h3>
+ </div>
+ <form method="post" action="http://ontologicaldiscovery.org/index.php?action=manage&cmd=importGeneSet" name="formODE">
+ {% for key in hidden_vars %}
+ <input type="hidden" name="{{ key }}" value="{{ hidden_vars[key] }}">
+ {% endfor %}
+ </form>
+ {% endif %}
+{% endblock %}
+{% block js %}
+{% if wrong_input == "False" %}
+<script type="text/javascript">
+ setTimeout('document.formODE.submit()', 1000);
+</script>
+{% endif %}
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/genotype.html b/gn2/wqflask/templates/genotype.html
new file mode 100644
index 00000000..fc5b1ad7
--- /dev/null
+++ b/gn2/wqflask/templates/genotype.html
@@ -0,0 +1,87 @@
+{% extends "base.html" %}
+
+{% block css %}
+<style type="text/css">
+ .page-header {
+ text-underline-offset: 0.5rem;
+ padding: 1em;
+ }
+</style>
+{% endblock %}
+
+{% block title %}Genotype: {{ name }}{% endblock %}
+
+{% block content %}
+
+<h1 class="page-header">
+ {% if metadata.name %}
+ <u>Genotype: {{ metadata.name }}</u>
+ {% else %}
+ {{ name }}
+ {% endif %}
+</h1>
+
+<div class="container">
+ <table class="table">
+ {% if metadata.datasetName %}
+ <tr>
+ <td><b>Dataset: </b></td>
+ <td>
+ <a href="{{ metadata.genotypeOfDataset }}" target="_blank">{{ metadata.datasetName }}</a>
+ </td>
+ </tr>
+ {% endif %}
+
+ {% if metadata.inbredSetName %}
+ <tr>
+ <td><b>Group</b></td>
+ <td>{{ metadata.inbredSetName }}</td>
+ </tr>
+ {% endif %}
+
+ <tr>
+ <td><b>Species</b></td>
+ <td>{{ metadata.species or "N/A"}}</td>
+ </tr>
+ <tr>
+ <td><b>Location</b></td>
+ <td>Chr {{ metadata.ch }} @ {{ metadata.mb }} mb </td>
+ </tr>
+ {% if metadata.cM %}
+ <tr>
+ <td><b>cM</b></td>
+ <td>{{ metadata.cM }}</td>
+ </tr>
+ {% endif %}
+
+ {% if metadata.mb %}
+ <tr>
+ <td><b>mb</b></td>
+ <td>{{ metadata.mb }}</td>
+ </tr>
+ {% endif %}
+
+ {% if metadata.sequence %}
+ <tr>
+ <td><b>Sequence</b></td>
+ <td>metadata.sequence</td>
+ </tr>
+ {% endif %}
+
+ {% if metadata.source %}
+ <tr>
+ <td><b>Source</b></td>
+ <td>{{ metadata.source}}</td>
+ </tr>
+ {% endif %}
+
+ {% if metadata.markerName %}
+ <tr>
+ <td><b>Marker Name</b></td>
+ <td>{{ metadata.markerName}}</td>
+ </tr>
+ {% endif %}
+ </table>
+</div>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/glossary.html b/gn2/wqflask/templates/glossary.html
new file mode 100644
index 00000000..aaee7c5a
--- /dev/null
+++ b/gn2/wqflask/templates/glossary.html
@@ -0,0 +1,23 @@
+{% extends "base.html" %}
+
+{% block title %}Glossary{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+
+{% block content %}
+
+<div class="github-btn-container">
+ <div class="github-btn">
+ <a href="https://github.com/genenetwork/gn-docs/blob/master/general/glossary/glossary.md">
+ Edit Text
+ <img src="/static/images/edit.png">
+ </a>
+ </div>
+</div>
+<div id="markdown" class="container">
+
+ {{ rendered_markdown|safe }}
+</div>
+{% endblock %}
diff --git a/gn2/wqflask/templates/gn3_ctl_results.html b/gn2/wqflask/templates/gn3_ctl_results.html
new file mode 100644
index 00000000..c42707f6
--- /dev/null
+++ b/gn2/wqflask/templates/gn3_ctl_results.html
@@ -0,0 +1,101 @@
+{% extends "base.html" %}
+{% block title %}Ctl results{% endblock %}
+{% block content %}
+<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
+<link REL="stylesheet" TYPE="text/css" href="{{ url_for('css', filename='bootstrap/css/bootstrap.css') }}" />
+<link rel="stylesheet" href="https://cdn.datatables.net/1.11.3/css/jquery.dataTables.min.css">
+<style type="text/css">
+.carousel-control-next,
+.carousel-control-prev
+
+/*, .carousel-indicators */
+ {
+ filter: invert(100%);
+}
+</style>
+<div style="margin-top:10px">
+
+{% if error %}
+ <div>
+ <h4 style="text-align:center;color:red">{{error}}</h4>
+ </div>
+
+{% else %}
+ <div>
+ <div>
+ <div style="text-align: center;">
+ <h3>CTL/QTL Plots for Individual Traits</h3>
+ <h4> {{ctl_plots|length}} phenotypes as input</h4>
+ </div>
+ <div id="carouselExampleControls" class="carousel slide" data-interval="false">
+ <div class="carousel-inner">
+ {% for ctl_plot in ctl_plots %}
+ <div class="item{% if loop.index == 1 %} active{% endif %}">
+ <img style="width:1000px;height: 600px;" class="center-block" src="data:image/jpeg;base64,{{ ctl_plot | safe }}" alt="First slide">
+ </div>
+ {% endfor %}
+ <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
+ <span class="carousel-control-prev-icon" aria-hidden="true"></span>
+ <span class="sr-only">Previous</span>
+ </a>
+ <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
+ <span class="carousel-control-next-icon" aria-hidden="true"></span>
+ <span class="sr-only">Next</span>
+ </a>
+ </div>
+ </div>
+ </div>
+ <div>
+ <div style="text-align:center;">
+ <h2>Ctl line plot</h2>
+ <h4>Plot the CTL for genome-wide CTL on all traits (the output of CTLscan).</h4>
+ </div>
+ <div class="row">
+ <div class="col-8">
+ <img style="width:100%;height: 600px;" class="center-block" src="data:image/jpeg;base64,{{ image_data | safe }}">
+ </div>
+ <div class="col-4">
+ <ol style="height: 100%;display:flex;flex-direction: column;align-items: center;justify-content: center;">
+ {% for trait in phenotypes %}
+ {% set trait_data = trait.split(':') %}
+ <li><a href="/show_trait?trait_id={{trait_data[0]}}&dataset={{trait_data[1]}}">{{trait_data[0]}}</a></li>
+ {% endfor %}
+ </ol>
+ </div>
+ </div>
+ </div>
+ <h2 style="text-align:center">Significant CTL </h2>
+ <table id="significance" width="80vw"></table>
+ <div style="text-align: center;margin-top: 20px;">
+ <h3 style="text-align:center;">Network figure</h3>
+ <div style="margin-top: 20px;">
+ <p>Use tools like cytoscape to visualize the network</p>
+ <a href="/ctl_network_files/{{network_file_name}}/sif" class="btn btn-secondary btn-lg mx-2">Download Sif file</a>
+ <a href="/ctl_network_files/{{network_file_name}}/nodes" class="btn btn-secondary btn-lg mx-2">Download Node file</a>
+ </div>
+ </div>
+</div>
+
+{% endif %}
+</div>
+
+<!-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> -->
+<script src="{{ url_for('js', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+<script type="text/javascript">
+let { data_set_rows, col_names } = {{ significance_data | safe }}
+
+
+$('#significance').DataTable({
+ data: data_set_rows,
+ columns: col_names.map((name) => {
+ return {
+ title: name
+ }
+ })
+});
+</script>
+{% endblock %}
+
diff --git a/gn2/wqflask/templates/gn3_wgcna_results.html b/gn2/wqflask/templates/gn3_wgcna_results.html
new file mode 100644
index 00000000..8a31bf28
--- /dev/null
+++ b/gn2/wqflask/templates/gn3_wgcna_results.html
@@ -0,0 +1,192 @@
+{% extends "base.html" %}
+{% block title %}WCGNA results{% endblock %}
+{% block content %}
+<!-- Start of body -->
+
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.5/xterm.min.css" integrity="sha512-iLYuqv+v/P4u9erpk+KM83Ioe/l7SEmr7wB6g+Kg1qmEit8EShDKnKtLHlv2QXUp7GGJhmqDI+1PhJYLTsfb8w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
+
+<link rel="stylesheet" href="https://cdn.datatables.net/1.11.3/css/jquery.dataTables.min.css">
+
+
+<style type="text/css">
+
+
+.container {
+ min-height: 100vh;
+ width: 100vw;
+ padding: 20px;
+
+}
+
+.grid_container {
+
+
+ width: 80vw;
+ margin: auto;
+ padding: 20px;
+
+
+ display: grid;
+ grid-template-columns: repeat(7, 1fr);
+ /*grid-gap: 5px;*/
+ border: 1px solid black;
+ grid-column-gap: 20px;
+
+}
+
+.control_sft_column {
+ text-align: center;
+}
+
+.grid_container div:not(:last-child) {
+ border-right: 1px solid #000;
+}
+
+.grid_container .control_sft_column h3 {
+ font-weight: bold;
+ font-size: 18px;
+}
+
+.control_net_colors {
+
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ text-align: center;
+}
+
+
+.control_mod_eigens {
+ display: grid;
+ grid-template-columns: repeat(2, 200px);
+}
+
+.control-image{
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 80vw;
+}
+</style>
+<div class="container">
+ {% if error!='null' %}
+ <h4 style="text-align: center;">{{error}}</h4>
+
+ {% else %}
+ <div>
+ <div>
+ <h2 style="text-align:center;">Parameters used</h2>
+
+ <table id="summary" class="display" width="40vw" ></table>
+
+ </div>
+ <div >
+ <h2 style="text-align:center">Soft Thresholds </h2>
+ <div class="grid_container">
+
+ {% for key, value in results["data"]["output"]["soft_threshold"].items()%}
+ <div class="control_sft_column">
+ <h3>{{key}}</h3>
+ {% for val in value %}
+ <p>{{val|round(3)}}</p>
+ {% endfor %}
+ </div>
+ {% endfor %}
+ </div>
+ </div>
+
+ <div>
+
+ {% if image["image_generated"] %}
+ <div >
+ <img class="control-image" src="data:image/jpeg;base64,{{ image['image_data']| safe }}">
+ </div>
+
+ {% endif %}
+<!-- <div >
+ <img class="control-image" src="data:image/jpeg;base64,{{ results['data']['output']['image_data2']| safe }}">
+ </div> -->
+ </div>
+
+ <div>
+ <h2 style="text-align:center;"> Module eigen genes </h2>
+ <table id="eigens" class="display" width="80vw"></table>
+ </div>
+
+ <div>
+ <h2 style="text-align:center;">Phenotype modules </h2>
+
+ <table id="phenos" class="display" width="40vw" ></table>
+ </div>
+ </div>
+
+{% endif %}
+
+</div>
+
+{% endblock %}
+
+{% block js %}
+
+<script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.5/xterm.min.js"></script>
+
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+
+
+<script type="text/javascript">
+
+
+let phenoModules = {{results|safe}}["data"]["output"]["net_colors"]
+let phenotypes = Object.keys(phenoModules)
+let phenoMods = Object.values(phenoModules)
+
+let {col_names,mod_dataset} = {{data|safe}}
+const summary = {
+ modules_found:phenoMods.length,
+ ...{{parameters|safe}}
+
+}
+
+ $("#summary").DataTable( {
+
+ data: Object.keys(summary).map((key)=>{
+ return [key,summary[key]]
+ }),
+ columns: [ {
+ title: "parameter",
+
+ },
+
+ {
+ title:" param_values"
+ }
+ ]
+ })
+
+
+ $('#eigens').DataTable( {
+ data: mod_dataset,
+ columns: col_names.map((name)=>{
+ return {
+ title:name
+ }
+ })
+ } );
+ $('#phenos').DataTable( {
+ data:phenotypes.map((phenoName,idx)=>{
+ return [phenoName,phenoMods[idx]]
+ }),
+ columns: [{
+ title:"Phenotypes"
+ },
+ {
+ title: "Modules"
+ }]
+ } );
+
+
+</script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/gnqa.html b/gn2/wqflask/templates/gnqa.html
new file mode 100644
index 00000000..46cc1e90
--- /dev/null
+++ b/gn2/wqflask/templates/gnqa.html
@@ -0,0 +1,84 @@
+{% extends "base.html" %}
+{% block title %}GNQNA{% endblock %}
+
+{% block content %} <!-- Start of body -->
+
+
+ <style>
+
+
+
+ #gnqna_search {
+ padding:15px 10px;
+ border-radius: 15px;
+ border:1px solid blue;
+ }
+
+ #gnqna_search{
+ font-weight: bold;
+ font-weight: 18px;
+ }
+
+ #main-search-controller{
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+ #loader {
+ display: none;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100%;
+ background: rgba(0,0,0,0.75) url("/static/gif/loader.gif") no-repeat center center;
+ z-index: 10000;
+}
+
+
+</style>
+
+
+<div style="height: 100vh;width: 100vw; ">
+
+<div id="loader"></div>
+<div id="main-search-controller" style="margin: 20px;width: 100%;height: 100%;">
+<div id="gnqna_controller">
+ <form method="POST" action="/gnqna" id="gnqna_form">
+ <input id="gnqna_search" style="width:45vw" type="text" autocomplete="off"
+required placeholder="Ask a Question or Topic e.g ( Genes) " value='' name="querygnqa">
+
+</form>
+</div>
+
+</div>
+
+<div>
+
+</div>
+
+
+<script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script>
+
+ <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
+<script type="text/javascript">
+
+ document.addEventListener('DOMContentLoaded', function() {
+ $("#gnqna_search").keypress(function(event) {
+ if (event.keyCode === 13) {
+ $('#gnqna_form').submit();
+ let spinner = $("#loader")
+ spinner.show()
+ }
+ })
+
+
+ });
+
+
+</script>
+<!-- Bootstrap JS and Popper.js -->
+{% endblock %}
+
diff --git a/gn2/wqflask/templates/gnqa_answer.html b/gn2/wqflask/templates/gnqa_answer.html
new file mode 100644
index 00000000..99242b29
--- /dev/null
+++ b/gn2/wqflask/templates/gnqa_answer.html
@@ -0,0 +1,174 @@
+{% extends "base.html" %}
+{% block title %}GNQNA{% endblock %}
+
+{% block content %} <!-- Start of body -->
+
+
+ <style>
+
+
+
+ #gnqna_search {
+ padding:15px 10px;
+ border-radius: 15px;
+ border:1px solid blue;
+ }
+
+ #gnqna_search{
+ font-weight: bold;
+ font-weight: 18px;
+ }
+
+ #main-search-controller{
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+
+</style>
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+
+
+<style type="text/css">
+
+ #gnqa_ref {
+ height: 90vh;
+ overflow: hidden;
+ overflow-y: scroll;
+ }
+
+
+ #gnqa_ref_item{
+ border-bottom: 1px solid lightgrey;
+ padding:12px;
+ }
+
+
+ #gnqa_query {
+ font-size: 24px;
+ font-family: serif;
+ color: #3071a9;
+ font-style: italic;
+ letter-spacing: 0.3em;
+ text-transform: capitalize;
+
+ text-decoration: underline;
+ }
+
+ #gnqa_query::first-letter {
+ font-size: 30px;
+ font-style: italic;
+
+ }
+
+ #gnqa_answer {
+ text-transform: capitalize;
+ }
+
+ #gnqa_answer::first-letter{
+ font-weight: bold;
+
+
+ }
+ #gnqna_search_home{
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+
+ #gnqna_search_home input{
+ padding:7px 5px;
+ border-radius: 10px;
+ border:1px solid blue;
+ }
+
+ #gnqna_search_home input{
+ font-weight: bold;
+ }
+
+ .container{
+ / box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px; */
+ }
+
+ #loader {
+ display: none;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100%;
+ background: rgba(0,0,0,0.75) url("/static/gif/loader.gif") no-repeat center center;
+ z-index: 10000;
+}
+
+
+
+</style>
+
+<div style="height: 90vh;width: 100vw; margin-bottom: 10px;">
+
+ <div id="loader">
+
+ </div>
+<div style="margin:10px; border:1px solid #ccc;padding: 15px;">
+ <div >
+ <h1 id="gnqa_query" style="font-weight: bolder">{{query}}<h1>
+ </div>
+
+ <div style="width:40vw;overflow-wrap: normal; margin-top: 5px;">
+ <p style="word-spacing: 0.7em;" id="gnqa_answer">{{answer}} <p>
+ </div>
+</div>
+
+<div>
+
+
+
+ <div class="container" style="overflow-y: hidden;">
+ <h4> <a href="#">References</a></h4>
+ {% if references %}
+ <ul id="gnqa_ref">
+ {% for reference in references %}
+ <li id="gnqa_ref_item">
+ <h2 style="font-weight:bolder;">{{ reference.bibInfo }} </h2>
+ <p>{{reference.comboTxt}}</p>
+ </li>
+ {% endfor %}
+ </ul>
+ {% else %}
+ <p>No references available.</p>
+ {% endif %}
+ </div>
+</div>
+</div>
+<script type="text/javascript">
+
+ document.addEventListener('DOMContentLoaded', function() {
+ $('#globalsearchform').hide()
+ $('#gnqna_search_home').show()
+ $('footer').hide()
+ $("#gnqna_search_home_input").keypress(function(event) {
+ if (event.keyCode === 13) {
+ console.log("clicked this button")
+ $('#gnqna_search_home').submit();
+ let spinner = $("#loader")
+ spinner.show();
+
+ }
+ })
+ });
+
+</script>
+
+<!-- Bootstrap JS and Popper.js -->
+
+
+
+{% endblock %}
+
diff --git a/gn2/wqflask/templates/gsearch_gene.html b/gn2/wqflask/templates/gsearch_gene.html
new file mode 100644
index 00000000..6bc92377
--- /dev/null
+++ b/gn2/wqflask/templates/gsearch_gene.html
@@ -0,0 +1,267 @@
+{% extends "base.html" %}
+{% block title %}Search Results{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+
+ <div class="container">
+
+ <h3>GN searched for the term(s) <b>"{{ terms }}"</b> in 754 datasets and 39,765,944 traits across 10 species<br/>
+ and found <b>{{ trait_count }}</b> results that match your query.<br/>
+ You can filter these results by adding key words in the fields below<br/>
+ and you can also sort results on most columns.</h3>
+ <p>To study a record, click on its Record ID below.<br />Check records below and click Add button to add to selection.</p>
+
+ <div>
+ <br />
+ <button class="btn btn-default" id="select_all"><span class="glyphicon glyphicon-ok"></span> Select All</button>
+ <button class="btn btn-default" id="deselect_all"><span class="glyphicon glyphicon-remove"></span> Deselect All</button>
+ <button class="btn btn-default" id="invert"><span class="glyphicon glyphicon-resize-vertical"></span> Invert</button>
+ <button class="btn btn-success" id="add" disabled ><span class="glyphicon glyphicon-plus-sign"></span> Add</button>
+ <input type="text" id="searchbox" class="form-control" style="width: 180px; display: inline;" placeholder="Search This Table For ...">
+ <input type="text" id="select_top" class="form-control" style="width: 120px; display: inline;" placeholder="Select Top ...">
+ <form id="export_form" method="POST" action="/export_traits_csv" style="display: inline;">
+ <input type="hidden" name="headers" id="headers" value="{% for field in header_fields %}{{ field }},{% endfor %}">
+ <input type="hidden" name="database_name" id="database_name" value="None">
+ <input type="hidden" name="export_data" id="export_data" value="">
+ <button class="btn btn-default" id="export_traits">Download</button>
+ </form>
+ <br />
+ <br />
+ <div id="table_container" style="width: 2000px;">
+ <table id="trait_table" class="table-hover table-striped cell-border" style="float: left;">
+ <tbody>
+ <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/colReorder/js/dataTables.colReorder.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/colResize/dataTables.colResize.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script>
+
+ <script type='text/javascript'>
+ var getParams = function(url) {
+ let parser = document.createElement('a');
+ parser.href = url;
+ let params = parser.search.substring(1);
+ if(params.length > 0) {
+ return ('?'+params);
+ }
+ return params;
+ };
+ </script>
+
+ <script type='text/javascript'>
+ var traitsJson = {{ trait_list|safe }};
+ </script>
+
+ <script type="text/javascript" charset="utf-8">
+ $(document).ready( function () {
+ var tableId = "trait_table";
+
+ columnDefs = [
+ {
+ 'orderDataType': "dom-checkbox",
+ 'width': "5px",
+ 'data': null,
+ 'targets': 0,
+ 'render': function(data) {
+ return '<input type="checkbox" name="searchResult" class="trait_checkbox checkbox" value="' + data.hmac + '">'
+ }
+ },
+ {
+ 'title': "Index",
+ 'type': "natural",
+ 'width': "30px",
+ 'targets': 1,
+ 'data': "index",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Record",
+ 'type': "natural",
+ 'orderDataType': "dom-inner-text",
+ 'width': "60px",
+ 'data': null,
+ 'targets': 2,
+ 'render': function(data) {
+ return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset=' + data.dataset + '">' + data.name + '</a>'
+ }
+ },
+ {
+ 'title': "Species",
+ 'type': "natural",
+ 'width': "60px",
+ 'targets': 3,
+ 'data': "species",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Group",
+ 'type': "natural",
+ 'width': "150px",
+ 'targets': 4,
+ 'data': "group",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Tissue",
+ 'type': "natural",
+ 'width': "150px",
+ 'targets': 5,
+ 'data': "tissue",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Dataset",
+ 'type': "natural",
+ 'targets': 6,
+ 'width': "320px",
+ 'data': "dataset_fullname",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Symbol",
+ 'type': "natural",
+ 'width': "60px",
+ 'targets': 7,
+ 'data': "symbol",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Description",
+ 'type': "natural",
+ 'data': null,
+ 'width': "120px",
+ 'targets': 8,
+ 'render': function(data) {
+ try {
+ return decodeURIComponent(escape(data.description))
+ } catch(err) {
+ return escape(data.description)
+ }
+ }
+ },
+ {
+ 'title': "Location",
+ 'type': "natural-minus-na",
+ 'width': "125px",
+ 'targets': 9,
+ 'data': "location_repr",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Mean",
+ 'type': "natural-minus-na",
+ 'orderSequence': [ "desc", "asc"],
+ 'width': "30px",
+ 'targets': 10,
+ 'data': null,
+ 'defaultContent': "N/A",
+ 'render': function(data) {
+ if (data.mean > 100) {
+ return Math.log2(data.mean).toFixed(3)
+ } else {
+ return data.mean
+ }
+ }
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Peak</div> <div style='text-align: right;'>-logP <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"><sup>?</sup></a></div>",
+ 'type': "natural-minus-na",
+ 'width': "60px",
+ 'targets': 11,
+ 'data': "LRS_score_repr",
+ 'defaultContent': "N/A",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Peak Location",
+ 'type': "natural-minus-na",
+ 'width': "125px",
+ 'targets': 12,
+ 'data': "max_lrs_text",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Additive<br>Effect<a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"><sup>?</sup></a>",
+ 'type': "natural-minus-na",
+ 'width': "50px",
+ 'targets': 13,
+ 'data': "additive",
+ 'defaultContent': "N/A",
+ 'orderSequence': [ "desc", "asc"]
+ }
+ ]
+
+ tableSettings = {
+ 'createdRow': function ( row, data, index ) {
+ $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;");
+ $('td', row).eq(1).attr("align", "right");
+ $('td', row).eq(4).attr('title', $('td', row).eq(4).text());
+ if ($('td', row).eq(4).text().length > 30) {
+ $('td', row).eq(4).text($('td', row).eq(4).text().substring(0, 30));
+ $('td', row).eq(4).text($('td', row).eq(4).text() + '...')
+ }
+ $('td', row).eq(5).attr('title', $('td', row).eq(5).text());
+ if ($('td', row).eq(5).text().length > 35) {
+ $('td', row).eq(5).text($('td', row).eq(5).text().substring(0, 35));
+ $('td', row).eq(5).text($('td', row).eq(5).text() + '...')
+ }
+ $('td', row).eq(6).attr('title', $('td', row).eq(6).text());
+ if ($('td', row).eq(6).text().length > 60) {
+ $('td', row).eq(6).text($('td', row).eq(6).text().substring(0, 60));
+ $('td', row).eq(6).text($('td', row).eq(6).text() + '...')
+ }
+ $('td', row).eq(8).attr('title', $('td', row).eq(8).text());
+ if ($('td', row).eq(8).text().length > 60) {
+ $('td', row).eq(8).text($('td', row).eq(8).text().substring(0, 60));
+ $('td', row).eq(8).text($('td', row).eq(8).text() + '...')
+ }
+ $('td', row).slice(10,14).attr("align", "right");
+ $('td', row).eq(1).attr('data-export', $('td', row).eq(1).text());
+ $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text());
+ $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text());
+ $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text());
+ $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text());
+ $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text());
+ $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text());
+ $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text());
+ $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text());
+ $('td', row).eq(10).attr('data-export', $('td', row).eq(10).text());
+ $('td', row).eq(11).attr('data-export', $('td', row).eq(11).text());
+ $('td', row).eq(12).attr('data-export', $('td', row).eq(12).text());
+ $('td', row).eq(13).attr('data-export', $('td', row).eq(13).text());
+ },
+ {% if trait_count <= 20 %}
+ "scroller": false
+ {% else %}
+ "scroller": true
+ {% endif %}
+ }
+
+ create_table(tableId, traitsJson, columnDefs, tableSettings);
+
+ });
+
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/gsearch_pheno.html b/gn2/wqflask/templates/gsearch_pheno.html
new file mode 100644
index 00000000..a1fef2c8
--- /dev/null
+++ b/gn2/wqflask/templates/gsearch_pheno.html
@@ -0,0 +1,238 @@
+{% extends "base.html" %}
+{% block title %}Search Results{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+
+ <div class="container">
+
+ <h3>GN searched for the term(s) <b>"{{ terms }}"</b> in 51 datasets and 13763 traits across 10 species<br/>
+ and found <b>{{ trait_count }}</b> results that match your query.<br/>
+ You can filter these results by adding key words in the fields below<br/>
+ and you can also sort results on most columns.</h3>
+ <p>To study a record, click on its ID below.<br />Check records below and click Add button to add to selection.</p>
+
+ <div>
+ <br />
+ <button class="btn btn-default" id="select_all"><span class="glyphicon glyphicon-ok"></span> Select All</button>
+ <button class="btn btn-default" id="deselect_all"><span class="glyphicon glyphicon-remove"></span> Deselect All</button>
+ <button class="btn btn-default" id="invert"><span class="glyphicon glyphicon-resize-vertical"></span> Invert</button>
+ <button class="btn btn-success" id="add" disabled ><span class="glyphicon glyphicon-plus-sign"></span> Add</button>
+ <input type="text" id="searchbox" class="form-control" style="width: 180px; display: inline;" placeholder="Search This Table For ...">
+ <input type="text" id="select_top" class="form-control" style="width: 120px; display: inline;" placeholder="Select Top ...">
+ <form id="export_form" method="POST" action="/export_traits_csv" style="display: inline;">
+ <input type="hidden" name="headers" id="headers" value="{% for field in header_fields %}{{ field }},{% endfor %}">
+ <input type="hidden" name="database_name" id="database_name" value="None">
+ <input type="hidden" name="export_data" id="export_data" value="">
+ <button class="btn btn-default" id="export_traits">Download CSV</button>
+ </form>
+ <br />
+ <br />
+ <div id="table_container" style="width: 2000px;">
+ <table id="trait_table" class="table-hover table-striped cell-border" style="float: left;">
+ <tbody>
+ <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/colReorder/js/dataTables.colReorder.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/colResize/dataTables.colResize.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script>
+
+ <script type='text/javascript'>
+ var getParams = function(url) {
+ let parser = document.createElement('a');
+ parser.href = url;
+ let params = parser.search.substring(1);
+ if(params.length > 0) {
+ return ('?'+params);
+ }
+ return params;
+ };
+ </script>
+
+ <script type='text/javascript'>
+ var traitsJson = {{ trait_list|safe }};
+ </script>
+
+ <script type="text/javascript" charset="utf-8">
+ $(document).ready( function () {
+ var tableId = "trait_table";
+
+ columnDefs = [
+ {
+ 'data': null,
+ 'orderDataType': "dom-checkbox",
+ 'width': "10px",
+ 'targets': 0,
+ 'render': function(data) {
+ return '<input type="checkbox" name="searchResult" class="trait_checkbox checkbox" value="' + data.hmac + '">'
+ }
+ },
+ {
+ 'title': "Index",
+ 'type': "natural",
+ 'width': "30px",
+ 'targets': 1,
+ 'data': "index",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Species",
+ 'type': "natural",
+ 'width': "60px",
+ 'targets': 2,
+ 'data': "species",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Group",
+ 'type': "natural",
+ 'width': "100px",
+ 'targets': 3,
+ 'data': "group",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Record",
+ 'type': "natural",
+ 'data': null,
+ 'width': "60px",
+ 'targets': 4,
+ 'orderDataType': "dom-inner-text",
+ 'render': function(data) {
+ return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>'
+ }
+ },
+ {
+ 'title': "Description",
+ 'type': "natural",
+ 'width': "500px",
+ 'targets': 5,
+ 'data': null,
+ 'render': function(data) {
+ try {
+ return decodeURIComponent(escape(data.description))
+ } catch(err) {
+ return data.description
+ }
+ }
+ },
+ {
+ 'title': "Mean",
+ 'type': "natural-minus-na",
+ 'width': "30px",
+ 'targets': 6,
+ 'data': "mean",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Authors",
+ 'type': "natural",
+ 'width': "300px",
+ 'targets': 7,
+ 'data': "authors_display",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Year",
+ 'type': "natural-minus-na",
+ 'data': null,
+ 'orderDataType': "dom-inner-text",
+ 'width': "25px",
+ 'targets': 8,
+ 'render': function(data) {
+ if ("pubmed_id" in data){
+ return '<a href="' + data.pubmed_link + '">' + data.pubmed_text + '</a>'
+ } else {
+ return data.pubmed_text
+ }
+ },
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Peak</div> <div style='text-align: right;'>-logP <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"><sup>?</sup></a></div>",
+ 'type': "natural-minus-na",
+ 'data': "LRS_score_repr",
+ 'defaultContent': "N/A",
+ 'width': "60px",
+ 'targets': 9,
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Peak Location",
+ 'type': "natural-minus-na",
+ 'width': "125px",
+ 'targets': 10,
+ 'data': "max_lrs_text",
+ 'defaultContent': "N/A"
+ },
+ {
+ 'title': "Additive Effect<a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"><sup>?</sup></a>",
+ 'type': "natural-minus-na",
+ 'data': "additive",
+ 'defaultContent': "N/A",
+ 'width': "60px",
+ 'targets': 11,
+ 'orderSequence': [ "desc", "asc"]
+ }
+ ]
+
+ tableSettings = {
+ "createdRow": function ( row, data, index ) {
+ $('td', row).eq(0).attr("style", "text-align: center; padding: 4px 10px 2px 10px;");
+ $('td', row).eq(1).attr("align", "right");
+ $('td', row).eq(5).attr('title', $('td', row).eq(5).text());
+ if ($('td', row).eq(5).text().length > 150) {
+ $('td', row).eq(5).text($('td', row).eq(5).text().substring(0, 150));
+ $('td', row).eq(5).text($('td', row).eq(5).text() + '...')
+ }
+ $('td', row).eq(6).attr('title', $('td', row).eq(6).text());
+ if ($('td', row).eq(6).text().length > 150) {
+ $('td', row).eq(6).text($('td', row).eq(6).text().substring(0, 150));
+ $('td', row).eq(6).text($('td', row).eq(6).text() + '...')
+ }
+ $('td', row).eq(6).attr("align", "right");
+ $('td', row).slice(8,11).attr("align", "right");
+ $('td', row).eq(1).attr('data-export', $('td', row).eq(1).text());
+ $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text());
+ $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text());
+ $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text());
+ $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text());
+ $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text());
+ $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text());
+ $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text());
+ $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text());
+ $('td', row).eq(10).attr('data-export', $('td', row).eq(10).text());
+ },
+ {% if trait_count <= 20 %}
+ "scroller": false
+ {% else %}
+ "scroller": true
+ {% endif %}
+ }
+
+ create_table(tableId, traitsJson, columnDefs, tableSettings);
+
+ });
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/heatmap.html b/gn2/wqflask/templates/heatmap.html
new file mode 100644
index 00000000..92754266
--- /dev/null
+++ b/gn2/wqflask/templates/heatmap.html
@@ -0,0 +1,44 @@
+{% extends "base.html" %}
+{% block title %}Heatmap{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/panelutil.css" />
+{% endblock %}
+{% block content %} <!-- Start of body -->
+ <div class="container">
+ <h1>Heatmap</h1>
+ <hr style="height: 1px; background-color: #A9A9A9;">
+ <div>
+ <h3>
+ The following heatmap is a work in progress. The heatmap for each trait runs horizontally (as opposed to vertically in GeneNetwork 1),
+ and hovering over a given trait's heatmap track will display its corresponding QTL chart below. White on the heatmap corresponds with a
+ low positive or negative z-score (darker when closer to 0), while light blue and red correspond to high negative and positive z-scores respectively.
+ </h3>
+ </div>
+ <div id="chart_container">
+ <div class="qtlcharts" id="chart">
+
+ </div>
+ </div>
+
+ </div>
+
+ <!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script>
+ js_data = {{ js_data | safe }}
+ </script>
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/panelutil.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/lodheatmap.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/lod_chart.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/curvechart.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/iplotMScanone_noeff.js"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/index_page.html b/gn2/wqflask/templates/index_page.html
new file mode 100755
index 00000000..7b5a1d16
--- /dev/null
+++ b/gn2/wqflask/templates/index_page.html
@@ -0,0 +1,397 @@
+{% extends "base.html" %}
+{% block title %}GeneNetwork{% endblock %}
+{% block css %}
+<!-- UIkit CSS -->
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.7.4/dist/css/uikit.min.css" />
+<link rel="stylesheet" href="/static/new/css/index_page.css" />
+<link rel="stylesheet" href="/static/new/css/autocomplete.css"/>
+
+<!-- UIkit JS -->
+<script src="https://cdn.jsdelivr.net/npm/uikit@3.7.4/dist/js/uikit.min.js"></script>
+<script src="https://cdn.jsdelivr.net/npm/uikit@3.7.4/dist/js/uikit-icons.min.js"></script>
+<script type="module" src="https://esm.sh/emfed"></script>
+<link rel="stylesheet" type="text/css"
+ href="https://cdn.jsdelivr.net/gh/sampsyo/emfed@1/toots.css">
+
+<style TYPE="text/css">
+ p.interact { display: none; }
+
+
+ .media {
+ padding-bottom:10px;
+ border-bottom: 1px solid #c8ccc9;
+ }
+
+ .media img {
+
+ width: 95%;
+ height: 100%;
+ border-radius: 5px;
+ /*transform: scale(1.1); image small?*/
+ border:1px solid #c8ccc9;
+ }
+
+ .toots {
+ margin:0 auto;
+ max-width: 500px;
+ height: 160px;
+ position: relative;
+ border-radius:10px;
+ background-color: #F9F9F9;
+
+ }
+
+ h2 {
+ margin-bottom: 0px;
+ }
+
+ ul {
+ margin-top: 0px;
+ }
+
+ .toot {
+ padding-top:8px;
+ background:#f9f9f9;
+ color:#000;
+
+ }
+</style>
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div class="container-fluid" style="min-width: 1210px;">
+
+ {{ flash_me() }}
+
+ {%if anon_collections | length > 0%}
+ <div class="panel panel-warning">
+ <div class="panel-heading">
+ <h3 class="panel-title">Import Anonymous Collections</h3>
+ </div>
+ <div class="panel-body">
+ <p>
+ There {%if anon_collections | length > 1%}are{%else%}is{%endif%}
+ {{anon_collections | length}} anonymous
+ collection{%if anon_collections | length > 1%}s{%endif%}
+ associated with your current session. What do you wish to do?
+ </p>
+ <p class="text-danger" style="font-weight: bold;">
+ <small>
+ If you choose to ignore this, the anonymous collections will be
+ eventually deleted and lost.
+ </small>
+ </p>
+ <form action="{{url_for('handle_anonymous_collections')}}"
+ method="POST">
+ <div class="form-group">
+ <input type="radio" id="rdo-import" value="import"
+ name="anon_choice" />
+ <label for="rdo-import">Import</label>
+ <input type="radio" id="rdo-delete" value="delete"
+ name="anon_choice" />
+ <label for="rdo-delete">Delete</label>
+ </div>
+
+ <input type="submit" class="btn btn-warning" value="Submit" />
+ </form>
+ </div>
+ </div>
+ {%endif%}
+
+ <div class="row" style="width: 100%;">
+
+ <div class="col-xs-4" style="margin-right:50px; min-width: 530px; max-width: 550px;">
+ <section id="search">
+ <div class="page-header">
+ <h2>Select and Search</h2>
+ </div>
+ <form method="get" action="/search" target="_blank" id="searchform" name="SEARCHFORM",
+ data-gn_server_url="{{gn_server_url}}">
+ <fieldset>
+ <div style="padding-left: 20px; padding-right: 20px;" class="form-horizontal">
+
+ <div class="form-group">
+ <label for="species" class="col-xs-1 control-label" style="width: 65px !important;">Species:</label>
+ <div class="col-xs-10 controls input-append" style="display: flex; padding-left: 20px;">
+ <div class="col-9">
+ <select name="species" id="species" class="form-control" style="width: 340px !important;"><option>Loading...</option></select>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="group" class="col-xs-1 control-label" style="width: 65px !important;">Group:</label>
+ <div class="col-xs-10 controls input-append" style="display: flex; padding-left: 20px;">
+ <div class="col-9">
+ <select name="group" id="group" class="form-control" style="width: 340px !important;"><option>Loading...</option></select>
+ <i class="icon-question-sign"></i>
+ </div>
+ <div class="col-3" style="margin-left: 10px;">
+ <button type="button" id="group_info" class="btn form-control info-button"><span class="glyphicon glyphicon-flag"></span> Info</button>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="tissue" class="col-xs-1 control-label" style="width: 65px !important;">Type:</label>
+ <div class="col-xs-10 controls input-append" style="display: flex; padding-left: 20px;">
+ <div class="col-9">
+ <select name="type" id="type" class="form-control" style="width: 340px !important;"><option>Loading...</option></select>
+ </div>
+ <div class="col-3" style="margin-left: 10px;">
+ <button type="button" id="dataset_info" class="btn form-control info-button"><span class="glyphicon glyphicon-flag"></span> Info</button>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="dataset" class="col-xs-1 control-label" style="width: 65px !important;">Dataset:</label>
+ <div class="col-xs-10 controls" style="display: flex; padding-left: 20px;">
+ <div class="col-9">
+ <select name="dataset" id="dataset" class="form-control" style="max-width: 550px; width: 450px !important;"><option>Loading...</option></select>
+ <i class="icon-question-sign"></i>
+ </div>
+ </div>
+ </div>
+ <!-- GET ANY SEARCH -->
+
+ <div class="form-group">
+ <label for="or_search" class="col-xs-1 control-label" style="padding-left: 0px; padding-right: 0px; width: 65px !important;">Get Any:</label>
+ <div class="col-xs-10 controls" style="padding-left: 20px;">
+ <div class="col-8 autocomplete">
+ <textarea id="myInput" onkeyup="pressed(event)" name="search_terms_or" rows="1" class="form-control search-query" style="resize: vertical; max-width: 550px; width: 450px !important;" id="or_search"></textarea>
+ </div>
+ </div>
+ </div>
+
+ <!-- GET ANY HELP -->
+ <div class="form-group">
+ <label for="btsearch" class="col-xs-1 control-label" style="width: 65px !important;"></label>
+ <div class="col-xs-10 controls" style="padding-left: 20px;">
+ <div class="col-12 controls">
+ Enter terms, genes, ID numbers in the <b>Search</b> field.<br>
+ Use <b>*</b> or <b>?</b> wildcards (Cyp*a?, synap*).<br>
+ Use <b>quotes</b> for terms such as <i>"tyrosine kinase"</i>.
+
+
+ <div><strong><a style="text-decoration: none;" href="https://issues.genenetwork.org/topics/xapian-search-queries" target=”_blank” >see more hints</a></strong></div>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="and_search" class="col-xs-1 control-label" style="padding-left: 0px; padding-right: 0px; width: 65px !important;">Combined:</label>
+ <div class="col-xs-10 controls" style="padding-left: 20px;">
+ <div class="col-8 autocomplete">
+ <textarea id="myInput" onkeyup="pressed(event)" name="search_terms_and" rows="1" class="form-control search-query" style="resize: vertical; max-width: 550px; width: 450px !important;" id="and_search"></textarea>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="btsearch" class="col-xs-1 control-label" style="width: 65px !important;"></label>
+ <div class="col-xs-10 controls" style="display: flex; padding-left: 20px;">
+ <div class="col-2 controls">
+ <button id="btsearch" class="btn btn-primary form-control"><span class="glyphicon glyphicon-search"></span> Search</button>
+ </div>
+ <div class="col-2 align-self-end controls" style="padding-left: 20px;">
+ <button type="button" id="make_default" class="btn form-control info-button"><span class="glyphicon glyphicon-pushpin"></span> Lock Menu</button>
+ </div>
+ </div>
+ </div>
+
+ <!-- SEARCH, MAKE DEFAULT -->
+ <div class="form-group">
+ </div>
+
+ <input type="hidden" name="FormID" value="searchResult" class="form-control">
+ </div>
+ </fieldset>
+ </form>
+ </section>
+ <section id="advanced">
+ <div class="page-header">
+ <h2>Advanced Commands</h2>
+ </div>
+
+ <p>You can also use advanced commands. Copy these simple examples into the Get Any field for single term searches and Combined for searches with multiple terms:</p>
+
+ <ul>
+ <li><b>POSITION=(chr1 25 30)</b> finds genes, markers, or transcripts on
+ chromosome 1 between 25 and 30 Mb.</li>
+
+ <li><b>MEAN=(15 16)</b> in the <b>Combined</b> field finds
+ highly expressed genes (15 to 16 log2 units)</li>
+
+ <li><b>RANGE=(1.5 2.5)</b> in the <b>Any</b> field finds traits with values with a specified fold-range (minimum = 1).
+ Useful for finding "housekeeping genes" <b>(1.0 1.2)</b> or highly variable molecular assays <b>(10 100)</b>.</li>
+
+ <li><b>LRS=(15 1000)</b> or <b>LOD=(2 8)</b> finds all traits with peak LRS or LOD scores between lower and upper limits.</li>
+
+ <li><b>LRS=(9 999 Chr4 122 155)</b> finds all traits on Chr 4 from 122 and 155 Mb with LRS scores between 9 and 999.</li>
+
+ <li><b>cisLRS=(15 1000 5)</b> or <b>cisLOD=(2 8 5)</b> finds all cis eQTLs with peak LRS or LOD scores between lower and upper limits,
+ with an <b>inclusion</b> zone of 5 Mb around the parent gene.</li>
+
+ <li><b>transLRS=(15 1000 5)</b> or <b>transLOD=(2 8 5)</b> finds all trans eQTLs with peak LRS or LOD scores between lower and upper limits,
+ with an <b>exclusion</b> zone of 5 Mb around the parent gene. You can also add a fourth term specifying which chromosome you want the transLRS to be on
+ (for example transLRS=(15 1000 5 7) would find all trans eQTLs with peak LRS on chromosome 7 that is also a trans eQTL with exclusionary zone of 5Mb).</li>
+
+ <li><b>POSITION=(Chr4 122 130) cisLRS=(9 999 10)</b>
+ finds all traits on Chr 4 from 122 and 155 Mb with cisLRS scores
+ between 9 and 999 and an inclusion zone of 10 Mb.</li>
+
+ <li><b>RIF=mitochondrial</b> searches RNA databases for <a href="https://en.wikipedia.org/wiki/GeneRIF">
+ GeneRIF</a> links.</li>
+
+ <li><b>WIKI=nicotine</b> searches <a href="http://gn1.genenetwork.org/webqtl/main.py?FormID=geneWiki">
+ GeneWiki</a> for genes that you or other users have annotated
+ with the word <i>nicotine</i>.</li>
+
+ <li><b>GO:0045202</b> searches for synapse-associated genes listed in the
+ <a href="http://amigo.geneontology.org/amigo/medial_search?q=GO%3A0045202">
+ Gene Ontology</a>.</li>
+
+ <li><b>RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10)</b>
+ finds diabetes-associated transcripts with peak <a href="{{ url_for('glossary_blueprint.glossary') }}#E">
+ trans eQTLs</a> on Chr 2 between 100 and 105 Mb with LRS
+ scores between 9 and 999.</li>
+ </ul>
+ </section>
+ </div>
+
+ <div class="col-xs-4" style="width: 600px !important;">
+ <section id="tutorials">
+ <div class="page-header">
+ <h2>Tutorials</h2>
+ </div>
+ <div class="uk-grid-match uk-child-width-1-3@m" uk-grid>
+ <div>
+ <strong><a class="uk-link-text" href="/tutorials">Webinars & Courses</a></strong><br>
+ In-person courses, live webinars and webinar recordings<br>
+ <a href="/tutorials" class="uk-icon-link" uk-icon="laptop" ratio="2"></a>
+ </div>
+ <div>
+ <strong><a class="uk-link-text" href="/tutorials">Tutorials</a></strong><br>
+ Tutorials: Training materials in HTML, PDF and video formats<br>
+ <a href="/tutorials" class="uk-icon-link" uk-icon="file-text" ratio="2"></a>
+ </div>
+ <div>
+ <strong><a class="uk-link-text" href="/tutorials">Documentation</a></strong><br>
+ Online manuals, handbooks, fact sheets and FAQs<br>
+ <a href="/tutorials" class="uk-icon-link" uk-icon="album" ratio="2"></a>
+ </div>
+ </div>
+ </section>
+ <section id="news-section">
+ <div class="page-header">
+ <h2>News</h2>
+ </div>
+ <div id="mastadon" style="height: 405px; overflow: scroll; overflow-x: hidden;">
+ <a class="mastodon-feed" target="_blank"
+ href="https://genomic.social/@genenetwork"
+ data-toot-limit="5"
+ >Genenetwork mastadon</a>
+
+ </div>
+ <div align="right">
+
+ <a href="https://genomic.social/@genenetwork">more news items...</a>
+ </div>
+ </section>
+ <section id="websites">
+ <div class="page-header">
+ <h2>Links</h2>
+ </div>
+ <ul>
+ <li>Github</li>
+ <ul>
+ <li><a href="https://github.com/genenetwork/genenetwork2">GN2 Source Code</a></li>
+ <li><a href="https://github.com/genenetwork/genenetwork3">GN3 Source Code</a></li>
+ <li><a href="https://github.com/genenetwork/genenetwork">GN1 Source Code</a></li>
+ <li><a href="https://github.com/genenetwork/sysmaintenance">System Maintenance Code</a></li>
+ </ul>
+ </ul>
+ <ul>
+ <li>GeneNetwork v2</li>
+ <ul>
+ <li><a href="https://genenetwork.org/">Main website</a> at UTHSC</li>
+ </ul>
+ </ul>
+ <ul>
+ <li>GeneNetwork v1</li>
+ <ul>
+ <li><a href="http://gn1.genenetwork.org/">Main website</a> at UTHSC</li>
+ </ul>
+ </ul>
+ <ul>
+ <li>Affiliates</li>
+ <ul>
+ <li><b><a href="http://gn1.genenetwork.org">GeneNetwork 1</a> at UTHSC</b></li>
+ <li><a href="https://systems-genetics.org/">Systems Genetics</a> at EPFL</li>
+ <li><a href="http://bnw.genenetwork.org/">Bayesian Network Web Server</a> at UTHSC</li>
+ <li><a href="https://www.geneweaver.org/">GeneWeaver</a></li>
+ <li><a href="https://phenogen.org/">PhenoGen</a> at University of Colorado</li>
+ <li><a href="http://www.webgestalt.org/">WebGestalt</a> at Baylor</li>
+ </ul>
+ </ul>
+ <ul>
+ <li>GeneNetwork hosted portals</li>
+ <ul>
+ <li><a href="https://www.opar.io/">Omics Portal For Addiction Research</a></li>
+ <li><a href="https://msk.genenetwork.org/">GN4MSK musculoskeletal</a></li>
+ <li><a href="https://genecup.org/">GeneCup: Mining PubMed for Gene Relationships using Custom Ontologies</a></li>
+ </ul>
+ </ul>
+ </section>
+ </div>
+ </div>
+ </div>
+
+{%endblock%}
+
+{% block js %}
+
+ <script src="/static/new/javascript/dataset_select_menu_orig.js"></script>
+
+
+ <script type="text/javascript">
+
+$(document).on('submit', '#searchform', function(event){
+
+ event.preventDefault()
+ let user_searches = [];
+ $(".search-query").each(function() {
+ this_search = $(this).val().trim();
+ if (this_search != ""){
+ user_searches.push(this_search);
+ }
+ });
+
+ for (i=0; i<user_searches.length; ++i){
+ saveBeforeSubmit(user_searches[i])
+ }
+ $( "#searchform" )[0].submit();
+
+});
+ </script>
+
+ <script>
+ function pressed(e) {
+ // Has the enter key been pressed?
+ if ( (window.event ? event.keyCode : e.which) == 13) {
+ e.preventDefault();
+ // If enter key has been pressed and the search fields are non-empty
+ // manually submit the <form>
+
+ if( event.target.value.trim() != "" ) {
+ saveBeforeSubmit(event.target.value.trim())
+ $("#searchform")[0].submit();
+
+ }
+
+ }
+ }
+
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/info_page.html b/gn2/wqflask/templates/info_page.html
new file mode 100644
index 00000000..91d34573
--- /dev/null
+++ b/gn2/wqflask/templates/info_page.html
@@ -0,0 +1,92 @@
+{% extends "base.html" %}
+{% block title %}Policies{% endblock %}
+{% block content %}
+
+<h1 id="parent-fieldname-title">Data Set Group: {{ info.dataset_name }}
+<!--<a href="/infoshare/manager/member-studies-edit.html?DatasetId=%s"><img src="/images/modify.gif" alt="modify this page" border="0" valign="middle"></a>-->
+<span style="color:red;">{{ info.info_page_name }}</span>
+</h1>
+<table border="0" width="100%">
+<tr>
+<td valign="top" width="50%">
+<table name="info_table" cellSpacing=0 cellPadding=5 width=100% border=0>
+ <tr><td><b>Data Set:</b> {{ info.info_file_title }} <!--<a href="/infoshare/manager/member-infofile-edit.html?GN_AccesionId=%s"><img src="/images/modify.gif" alt="modify this page" border="0" valign="middle"></a>--></td></tr>
+ <tr><td><b>GN Accession:</b> GN{{ gn_accession_id }}</td></tr>
+ <tr><td><b>GEO Series:</b> <a href="http://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={{ info.geo_series }}" target="_blank">{{ info.geo_series }}</a></td></tr>
+ <tr><td><b>Title:</b> {{ info.publication_title }}</td></tr>
+ <tr><td><b>Organism:</b> <a href="http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id={{ info.taxonomy_id }}" target="_blank">{{ info.menu_name }}</a></td></tr>
+ <tr><td><b>Group:</b> {{ info.group_name }}</td></tr>
+ <tr><td><b>Tissue:</b> {{ info.tissue_name }}</td></tr>
+ <tr><td><b>Dataset Status:</b> {{ info.dataset_status_name }}</td></tr>
+ <tr><td><b>Platforms:</b> <a href="http://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={{ info.geo_platform }}" target="_blank">{{ info.gene_chip_name }}</a></td></tr>
+ <tr><td><b>Normalization:</b> {{ info.avg_method_name }}</td></tr>
+</table>
+</td>
+<td valign="top" width="50%">
+<table border="0" width="100%">
+ <tr>
+ <td><b>Contact Information</b></td>
+ </tr>
+ <tr>
+ <td>
+ {{ info.investigator_first_name }} {{ info.inveestigator_last_name }}<br>
+ {{ info.organization_name }} <br>
+ {{ info.investigator_address }}<br>
+ {{ info.investigator_city }}, {{ info.investigator_state }} {{ info.investigator_zipcode }} {{ info.investigator_country }}<br>
+ Tel. {{ info.investigator_phone }}<br>
+ {{ info.investigator_email }}<br>
+ <a href="{{ info.investigator_url }}" target="_blank">Website</a>
+ </td>
+ </tr>
+
+<tr>
+ <td><b>Download datasets and supplementary data files</b></td>
+</tr>
+<tr>
+ <td>
+ <ul style="line-height: 160%">
+ {% for file in filelist %}
+ <li><a href="https://files.genenetwork.org/current/GN{{ gn_accession_id }}/{{ file[0] }}">{{ file[0] }} ({{ file[2] }})</a></li>
+ {% endfor %}
+ </ul>
+ </td>
+</tr>
+
+<tr><td>
+</td></tr>
+
+</table>
+</td>
+</tr>
+</table>
+<HR>
+<p>
+<table name="info_table" width="100%" border="0" cellpadding="5" cellspacing="0">
+<tr><td><span style="font-size:115%%;font-weight:bold;">Specifics of this Data Set:</span></td></tr>
+ <tr><td> {{ info.specifics|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%%;font-weight:bold;">Summary:</span></td></tr>
+ <tr><td> {{ info.dataset_summary|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">About the cases used to generate this set of data:</span></td></tr>
+ <tr><td> {{ info.about_cases|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">About the tissue used to generate this set of data:</span></td></tr>
+ <tr><td> {{ info.about_tissue|safe }}<br><br></td></tr>
+ <tr><td><span style="font-size:115%; font-weight:bold;">About the array platform:</span></td></tr>
+ <tr><td> {{ info.about_platform|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">About data values and data processing:</span></td></tr>
+ <tr><td> {{ info.about_data_processing|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Notes:</span></td></tr>
+ <tr><td> {{ info.notes|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Experiment Type:</span></td></tr>
+ <tr><td> {{ info.experiment_design|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Contributor:</span></td></tr>
+ <tr><td> {{ info.contributors|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Citation:</span></td></tr>
+ <tr><td> {{ info.citation|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Data source acknowledgment:</span></td></tr>
+ <tr><td> {{ info.acknowledgement|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Study Id:</span></td></tr>
+ <tr><td> {{ info.dataset_id }}<br><br></td></tr>
+</table>
+</p>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/jobs/debug.html b/gn2/wqflask/templates/jobs/debug.html
new file mode 100644
index 00000000..828ab1cc
--- /dev/null
+++ b/gn2/wqflask/templates/jobs/debug.html
@@ -0,0 +1,42 @@
+{%extends "base.html"%}
+{%block title%}Debug Job{% endblock%}
+{%block css%}
+{%endblock%}
+
+{%block content%}
+<h1>Debug Job</h1>
+
+The following show details for job "{{job_id}}" to assist in debugging.
+
+<h2>Metadata</h2>
+
+<ul>
+ <li><strong>Job ID:</strong> {{job_id}}</li>
+ <li><strong>Command:</strong> <code>{{command}}</code></li>
+ <li><strong>Received:</strong> {{request_received_time}}</li>
+ <li><strong>Return Code:</strong> {{return_code}}</li>
+ <li><strong>Completion Status:</strong> {{completion_status}}</li>
+ <li><strong>Status:</strong> {{status}}</li>
+</ul>
+
+<h2>STDERR</h2>
+
+<div style="background-color: black; color: red;">
+ {%for line in stderr:%}
+ <p>{{line}}</p>
+ {%endfor%}
+</div>
+
+<h2>STDOUT</h2>
+
+<div style="background-color: black; color: green;">
+ {%for line in stdout:%}
+ <p>{{line}}</p>
+ {%endfor%}
+</div>
+
+
+{%endblock%}
+
+{%block js%}
+{%endblock%}
diff --git a/gn2/wqflask/templates/jobs/no-such-job.html b/gn2/wqflask/templates/jobs/no-such-job.html
new file mode 100644
index 00000000..6fe7d014
--- /dev/null
+++ b/gn2/wqflask/templates/jobs/no-such-job.html
@@ -0,0 +1,13 @@
+{%extends "base.html"%}
+{%block title%}No Such Job{% endblock%}
+{%block css%}
+{%endblock%}
+
+{%block content%}
+<h1>No Such Job</h1>
+
+<p>The job with id <strong>{{job_id | string}}</strong> does not exist</p>
+{%endblock%}
+
+{%block js%}
+{%endblock%}
diff --git a/gn2/wqflask/templates/jupyter_notebooks.html b/gn2/wqflask/templates/jupyter_notebooks.html
new file mode 100644
index 00000000..afc95a15
--- /dev/null
+++ b/gn2/wqflask/templates/jupyter_notebooks.html
@@ -0,0 +1,28 @@
+{%extends "base.html"%}
+
+{%block title%}
+Jupyter Notebooks
+{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css" href="/static/new/css/jupyter_notebooks.css" />
+{%endblock%}
+
+{%block content%}
+
+<div class="container">
+ <h1>Current Notebooks</h1>
+
+ {%for item in links:%}
+ <div class="jupyter-links">
+ <a href="{{item.get('main_url')}}"
+ title="Access running notebook for '{{item.get('notebook_name')}}' on GeneNetwork"
+ class="main-link">{{item.get("notebook_name")}}</a>
+ <a href="{{item.get('src_link_url')}}"
+ title="Link to the notebook repository for {{item.get('notebook_name', '_')}}"
+ class="src-link">View Source</a>
+ </div>
+ {%endfor%}
+</div>
+
+{%endblock%}
diff --git a/gn2/wqflask/templates/links.html b/gn2/wqflask/templates/links.html
new file mode 100644
index 00000000..6e91adae
--- /dev/null
+++ b/gn2/wqflask/templates/links.html
@@ -0,0 +1,24 @@
+{% extends "base.html" %}
+
+{% block title %}Links{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+
+{% block content %}
+
+<div class="github-btn-container">
+ <div class="github-btn ">
+ <a href="https://github.com/genenetwork/gn-docs/blob/master/general/links/links.md">
+ Edit Text
+ <img src="/static/images/edit.png">
+ </a>
+ </div>
+</div>
+
+<div id="markdown" class="container">
+ {{ rendered_markdown|safe }}
+
+</div>
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/list_case_attribute_diffs.html b/gn2/wqflask/templates/list_case_attribute_diffs.html
new file mode 100644
index 00000000..f5c7482f
--- /dev/null
+++ b/gn2/wqflask/templates/list_case_attribute_diffs.html
@@ -0,0 +1,59 @@
+{%extends "base.html"%}
+{%block title%}List Case Attribute Diffs{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+
+<style>
+ .table-fixed-head {overflow-y: auto; height: 32em;}
+ .table-fixed-head thead th {position: sticky; top: 0;}
+</style>
+{%endblock%}
+
+{%block content%}
+<div class="container">
+ <h1>List Diffs</h1>
+
+ {{flash_me()}}
+
+ <table class="table-hover table-striped cell-border dataTable no-footer">
+ <thead>
+ <tr>
+ <th>Edit on</th>
+ <th>Filename</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for diff in diffs%}
+ <tr>
+ <td>{{diff.time_stamp}}</td>
+ <td>
+ <a href="{{url_for('view_diff', inbredset_id=diff.json_diff_data.inbredset_id, diff_id=diff.id)}}"
+ title="View the diff">
+ {{diff.filename}}
+ </a>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="5" class="text-info" style="text-align: center;line-height: 2em;">
+ <span class="glyphicon glyphicon-exclamation-sign">
+ </span>
+ There are no diffs pending review
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+{%endblock%}
+
+{%block js%}
+<script language="javascript"
+ type="text/javascript"
+ src="{{url_for('js', filename='DataTables/js/jquery.js')}}"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/list_case_attribute_diffs_error.html b/gn2/wqflask/templates/list_case_attribute_diffs_error.html
new file mode 100644
index 00000000..6ca70984
--- /dev/null
+++ b/gn2/wqflask/templates/list_case_attribute_diffs_error.html
@@ -0,0 +1,37 @@
+{%extends "base.html"%}
+{%block title%}List Case Attribute Diffs{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+
+<style>
+ .table-fixed-head {overflow-y: auto; height: 32em;}
+ .table-fixed-head thead th {position: sticky; top: 0;}
+</style>
+{%endblock%}
+
+{%block content%}
+<div class="container">
+ <h1>List Diffs</h1>
+
+ {{flash_me()}}
+
+ {%set the_error = error.json()%}
+
+ <p class="text-danger">
+ <span class="glyphicon glyphicon-exclamation-sign">
+ </span>
+ <strong>{{error.status_code}}: {{the_error["error"]}}</strong>
+ {{the_error.error_description}}
+ </p>
+{%endblock%}
+
+{%block js%}
+<script language="javascript"
+ type="text/javascript"
+ src="{{url_for('js', filename='DataTables/js/jquery.js')}}"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/loading.html b/gn2/wqflask/templates/loading.html
new file mode 100644
index 00000000..a6d9ae5e
--- /dev/null
+++ b/gn2/wqflask/templates/loading.html
@@ -0,0 +1,133 @@
+<title>Loading {{ start_vars.tool_used }} Results</title>
+<link REL="stylesheet" TYPE="text/css" href="{{ url_for('css', filename='bootstrap/css/bootstrap.css') }}" />
+<link REL="stylesheet" TYPE="text/css" href="/static/new/css/bootstrap-custom.css" />
+<form method="post" action="" name="loading_form" id="loading_form" class="form-horizontal">
+ {% for key, value in start_vars.items() %}
+ <input type="hidden" name="{{ key }}" value="{{ value }}">
+ {% endfor %}
+ <div class="container">
+ <div>
+ <div style="min-height: 80vh; display: flex; align-items: center; text-align: left;">
+ <div style="margin-bottom: 5px; left: 50%; margin-right: -50%; top: 50%; transform: translate(-50%, -50%); position: absolute;">
+ {% if start_vars.tool_used == "Mapping" %}
+ <h1>Computing the Maps</h1>
+ <br>
+ <b>Time Elapsed:</b> <span class="timer"></span>
+ <br>
+ <b>Trait Metadata</b>
+ <br>
+ species = <b><i>{{ start_vars.species[0] | upper }}{{ start_vars.species[1:] }}</i></b>
+ <br>
+ group = <b><i>{{ start_vars.group[0] | upper }}{{ start_vars.group[1:] }}</i></b>
+ <br>
+ trait identifier = <b><i>{{ start_vars.trait_name }}</i></b>
+ <br>
+ n of sample = <b><i>{{ start_vars.n_samples }}</i></b>
+ {% if start_vars.transform != "" %}
+ <br>
+ transformation = <b><i>{{ start_vars.transform }}</i></b>
+ {% endif %}
+ <br>
+ hash of sample values = <b><i>{{ start_vars.vals_hash }}</i></b>
+ <br><br>
+ <b>Mapping Metadata</b>
+ <br>
+ mapping method = <b><i>{% if start_vars.method == "gemma" %}GEMMA {% if start_vars.use_loco == "True" %}using LOCO {% endif %}{% else %}{{ start_vars.method }}{% endif %}</i></b>
+ {% if start_vars.maf != "" and start_vars.method != "reaper" %}
+ <br>
+ minor allele frequency lower limit = <b><i>{{ start_vars.maf }}</i></b>
+ {% endif %}
+ <br>
+ {% if start_vars.covariates != "" and start_vars.method != "reaper" %}
+ {% set covariate_list = start_vars.covariates.split(",") %}
+ cofactors = <b><i>{% for covariate in covariate_list %}{% set this_covariate = covariate.split(":")[0] %}{{ this_covariate }}{% if not loop.last %}, {% endif %}{% endfor %}</i></b>
+ {% else %}
+ cofactors = <b><i>None</i></b>
+ {% endif %}
+ {% if start_vars.control_marker != "" and start_vars.do_control == "true" and start_vars.method != "gemma" %}
+ <br>
+ marker covariate = <b><i>{{ start_vars.control_marker }}</i></b>
+ {% endif %}
+ <br>
+ {% if start_vars.genofile != "" %}
+ {% set genofile_desc = start_vars.genofile.split(":")[1] %}
+ genotype file = <b><i>{{ genofile_desc }}</i></b>
+ {% else %}
+ genotype file = <b><i>{{ start_vars.group[0] | upper }}{{ start_vars.group[1:] }}.geno</i></b>
+ {% endif %}
+ {% if start_vars.num_perm | int > 0 and start_vars.method != "gemma" %}
+ <br>
+ n of permutations = <b><i>{{ start_vars.num_perm }}</i></b>
+ {% endif %}
+ {% if num_bootstrap in start_vars %}
+ {% if start_vars.num_bootstrap | int > 0 and start_vars.method == "reaper" %}
+ <br>
+ n of bootstrap = <b><i>{{ start_vars.num_bootstrap }}</i></b>
+ {% endif %}
+ {% endif %}
+ {% else %}
+ <h1>&nbsp;{{ start_vars.tool_used }}&nbsp;Computation in progress ...</h1>
+ {% endif %}
+ <br><br>
+ <div style="text-align: center;">
+ <img align="center" src="/static/gif/waitAnima2.gif">
+ </div>
+ {% if start_vars.vals_diff|length != 0 and start_vars.transform == "" %}
+ <br><br>
+ <button id="show_full_diff">Show Full Diff</button>
+ <br>
+ <div id="diff_table_container" style="display: none; height:200px; overflow:auto;">
+ <table class="table table-hover">
+ <thead>
+ <th>Sample</th>
+ <th>New Value</th>
+ <th>Old Value</th>
+ </thead>
+ <tbody>
+ {% for sample in start_vars.vals_diff %}
+ <tr>
+ <td>{{ sample }}</td>
+ <td>{{ start_vars.vals_diff[sample].new_val }}</td>
+ <td>{{ start_vars.vals_diff[sample].old_val }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ {% endif %}
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
+<script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script>
+<script src="{{ url_for('js', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script>
+<script type="text/javascript">
+$('#show_full_diff').click(function() {
+ if ($('#diff_table_container').is(':visible')){
+ $('#diff_table_container').hide();
+ } else {
+ $('#diff_table_container').show();
+ }
+})
+
+var start = new Date;
+
+setInterval(function() {
+ minutes = Math.floor((new Date - start) / 1000 / 60)
+ seconds = Math.round(((new Date - start) / 1000) % 60)
+ if (seconds < 10 && minutes >= 1){
+ seconds_text = "0" + seconds.toString()
+ } else {
+ seconds_text = seconds.toString()
+ }
+ if (minutes < 1) {
+ $('.timer').text(seconds_text + " seconds");
+ } else {
+ $('.timer').text(minutes.toString() + ":" + seconds_text);
+ }
+}, 100);
+
+$("#loading_form").attr("action", "{{ start_vars.form_url }}");
+setTimeout(function(){ $("#loading_form").submit()}, 350);
+</script>
diff --git a/gn2/wqflask/templates/loading_corrs.html b/gn2/wqflask/templates/loading_corrs.html
new file mode 100644
index 00000000..8abd5464
--- /dev/null
+++ b/gn2/wqflask/templates/loading_corrs.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+
+ <head>
+ <title>Loading Correlation Results</title>
+
+ <meta charset="utf-8" />
+ <meta http-equiv="refresh" content="5">
+
+ <link rel="stylesheet" type="text/css"
+ href="{{url_for('css', filename='bootstrap/css/bootstrap.css')}}" />
+ <link rel="stylesheet" type="text/css"
+ href="/static/new/css/bootstrap-custom.css" />
+ </head>
+
+ <body>
+ <div style="margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">
+ <h1>&nbsp;Correlation Computation in progress ...</h1>
+ <div style="text-align: center;">
+ <img align="center" src="/static/gif/waitAnima2.gif">
+ </div>
+ </div>
+
+ <script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script>
+ <script src="{{ url_for('js', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script>
+ </body>
+
+</html>
diff --git a/gn2/wqflask/templates/mapping_error.html b/gn2/wqflask/templates/mapping_error.html
new file mode 100644
index 00000000..8364af3c
--- /dev/null
+++ b/gn2/wqflask/templates/mapping_error.html
@@ -0,0 +1,36 @@
+{%extends "base.html"%}
+{%block titl%}Error{%endblock%}
+{%block content%}
+<!-- Start of body -->
+{{ header("An error occurred during mapping") }}
+
+<div class="container">
+ <h3>
+ {%if error:%}
+ <p>
+ The following error was raised<br /><br />
+ <dl>
+ <dt>Error message</dt>
+ <dd>{{error.args[0]}}</dd>
+ <dt>Error Type</dt>
+ <dd>{{error_type}}</dd>
+ </dl>
+ </p>
+ <p>
+ Please contact Zach Sloan (zachary.a.sloan@gmail.com) or Arthur Centeno
+ (acenteno@gmail.com) about the error.
+ </p>
+ {%else:%}
+ <p>There is likely an issue with the genotype file associated with this group/RISet. Please contact Zach Sloan (zachary.a.sloan@gmail.com) or Arthur Centeno (acenteno@gmail.com) about the data set in question.</p>
+ </h3>
+ <br>
+ <h3>
+ <p>Try mapping using interval mapping instead; some genotype files with many columns of NAs have issues with GEMMA or R/qtl.</p>
+ {%endif%}
+ </h3>
+</div>
+
+
+<!-- End of body -->
+
+{%endblock%}
diff --git a/gn2/wqflask/templates/mapping_results.html b/gn2/wqflask/templates/mapping_results.html
new file mode 100644
index 00000000..0e084ba7
--- /dev/null
+++ b/gn2/wqflask/templates/mapping_results.html
@@ -0,0 +1,698 @@
+{% extends "base.html" %}
+{% block title %}Mapping Results{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='purescript-genome-browser/css/purescript-genetics-browser.css') }}" />
+
+ <link rel="stylesheet" type="text/css" href="/static/new/css/marker_regression.css" />
+ <link rel="stylesheet" type="text/css" href="static/new/css/show_trait.css" />
+
+{% endblock %}
+{% from "base_macro.html" import header %}
+{% block content %}
+ <div class="container">
+ <form method="post" target="_blank" action="/run_mapping" name="marker_regression" id="marker_regression_form">
+ <input type="hidden" name="temp_uuid" value="{{ temp_uuid }}">
+ {% if temp_trait is defined %}
+ <input type="hidden" name="temp_trait" value="{{ temp_trait }}">
+ {% endif %}
+ <input type="hidden" name="inputs_hash" value="{{ hash_of_inputs }}">
+ <input type="hidden" name="group" value="{{ dataset.group.name }}">
+ <input type="hidden" name="species" value="{{ dataset.group.species }}">
+ <input type="hidden" name="trait_id" value="{{ this_trait.name }}">
+ <input type="hidden" name="dataset" value="{{ dataset.name }}">
+ <input type="hidden" name="genofile" value="{{ genofile_string }}">
+ <input type="hidden" name="geno_db_exists" value="{{ geno_db_exists }}">
+ <input type="hidden" name="first_run" value="{{ first_run }}">
+ {% if output_files is defined %}
+ <input type="hidden" name="output_files" value="{{ output_files }}">
+ {% endif %}
+ {% if reaper_version is defined %}
+ <input type="hidden" name="reaper_version" value="{{ reaper_version }}">
+ {% endif %}
+ <input type="hidden" name="results_path" value="{{ mapping_results_path }}">
+ <input type="hidden" name="method" value="{{ mapping_method }}">
+ <input type="hidden" name="sample_vals" value="{{ sample_vals }}">
+ <input type="hidden" name="vals_hash" value="{{ vals_hash }}">
+ <input type="hidden" name="n_samples" value="{{ n_samples }}">
+ <input type="hidden" name="maf" value="{{ maf }}">
+ <input type="hidden" name="use_loco" value="{{ use_loco }}">
+ <input type="hidden" name="selected_chr" value="{{ selectedChr }}">
+ <input type="hidden" name="mapping_scale" value="{{ plotScale }}">
+ <input type="hidden" name="manhattan_plot" value="{{ manhattan_plot }}">
+ {% if manhattan_plot == True %}
+ <input type="hidden" name="color_scheme" value="alternating">
+ {% endif %}
+ <input type="hidden" name="num_perm" value="{{ nperm }}">
+ <input type="hidden" name="perm_info" value="">
+ {% if categorical_vars is defined %}
+ <input type="hidden" name="categorical_vars" value="{{ categorical_vars|join(',') }}">
+ {% endif %}
+ {% if perm_strata is defined %}
+ <input type="hidden" name="perm_strata" value="True">
+ {% endif %}
+ <input type="hidden" name="num_bootstrap" value="{{ nboot }}">
+ <input type="hidden" name="do_control" value="{{ doControl }}">
+ <input type="hidden" name="control_marker" value="{{ controlLocus }}">
+ <input type="hidden" name="covariates" value="{{ covariates }}">
+ <input type="hidden" name="mapmethod_rqtl_geno" value="{{ mapmethod_rqtl_geno }}">
+ <input type="hidden" name="mapmodel_rqtl_geno" value="{{ mapmodel_rqtl_geno }}">
+ <input type="hidden" name="pair_scan" value="{{ pair_scan }}">
+ <input type="hidden" name="transform" value="{{ transform }}">
+ <input type="hidden" name="tool_used" value="Mapping">
+ <input type="hidden" name="wanted_inputs" value="">
+ <input type="hidden" name="form_url" value="/run_mapping">
+
+ <div class="container" style="width: 1200px; float: left;">
+ <div class="col-xs-4" style="word-wrap: normal;">
+ <h2>Map Viewer: Whole Genome</h2><br>
+ <b>Population:</b> {{ dataset.group.species|capitalize }} {{ dataset.group.name }}<br>
+ <b>Database:</b> {{ dataset.fullname }}<br>
+ {% if dataset.type == "ProbeSet" %}<b>Trait ID:</b>{% else %}<b>Record ID:</b>{% endif %} <a href="/show_trait?trait_id={{ this_trait.name }}&dataset={{ dataset.name }}">{{ this_trait.display_name }}</a><br>
+ <b>Trait Hash: </b> {{ vals_hash }}<br>
+ {% if dataset.type == "ProbeSet" %}
+ <b>Gene Symbol:</b> <i>{{ this_trait.symbol }}</i><br>
+ <b>Location:</b> Chr {{ this_trait.chr }} @ {{ this_trait.mb }} Mb<br>
+ {% endif %}
+ {% if genofile_string != "" %}
+ <b>Genotypes:</b> {{ genofile_string.split(":")[1] }}<br>
+ {% endif %}
+ <b>Current Date/Time:</b> {{ current_datetime }}<br>
+ <br>
+ <button class="btn btn-default export_mapping_results"><span class="glyphicon glyphicon-download-alt"></span>Map Data</button>
+ <br><br>
+ <div class="input-group">
+ <input type="text" class="form-control" name="mappingLink" size="75"></input>
+ <div class="input-group-btn">
+ <button class="btn btn-default share-results" type="button">Copy and Share</button>
+ </div>
+ </div>
+ </div>
+ <div id="gn1_map_options" class="col-xs-6" style="outline: 3px double #AAAAAA; padding: 10px; margin: 10px;">
+ <div class="col-xs-8" style="padding: 0px;">
+ <table>
+ <tr>
+ <td><b>Chr:&nbsp;</b></td>
+ <td style="padding: 5px;">
+ <select name="chromosomes" size="1">
+ {% for chr in ChrList %}
+ <option value="{{ chr[1] }}" {% if (chr[1] + 1) == selectedChr %}selected{% endif %}>{{ chr[0] }}</option>
+ {% endfor %}
+ </select>&nbsp;
+ <button type="button" class="btn btn-primary" style="padding-bottom: 2px; padding-top: 2px;" onclick="javascript:remap();">Remap</button>
+ </td>
+ </tr>
+ <tr>
+ <td ><b>View:&nbsp;</b></td>
+ <td style="padding: 5px;">
+ <input type="text" name="startMb" size="7" value="{% if startMb != -1 %}{{ startMb }}{% endif %}"> to <input type="text" name="endMb" size="7" value="{% if endMb != -1 %}{{ endMb }}{% endif %}">
+ </td>
+ </tr>
+ <tr>
+ <td><b>Units:&nbsp;</b></td>
+ <td style="padding: 5px;">
+ <label class="radio-inline">
+ <input type="radio" name="LRSCheck" value="LRS" {% if LRS_LOD == "LRS" %}checked{% endif %}>LRS
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="LRSCheck" value="{% if LRS_LOD == "-logP" %}-logP{% else %}LOD{% endif %}" {% if LRS_LOD == "LOD" or LRS_LOD == "-logP" %}checked{% endif %}>{% if LRS_LOD == "-logP" %}-logP{% else %}LOD{% endif %}
+ </label>
+ <a href="https://genenetwork.org/glossary.html#LOD" target="_blank">
+ <sup style="color:#f00"> ?</sup>
+ </a>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td style="padding: 5px;">
+ <input type="text" name="lrsMax" value="{{ '%0.1f' | format(lrsMax|float) }}" size="3"> <span style="font-size: 12px;">units on the y-axis (0 for default)</span>
+ </td>
+ </tr>
+ <tr>
+ <td><b>Width:&nbsp;</b></td>
+ <td style="padding: 5px;">
+ <input type="text" name="graphWidth" value="{% if graphWidth is defined %}{{ graphWidth }}{% else %}1600{% endif %}" size="5"><span style="font-size: 12px;"> pixels (minimum=900)</span>
+ </td>
+ </tr>
+ </table>
+ {% if manhattan_plot == True and selectedChr == -1 %}
+ <table style="margin-top: 10px;">
+ <tr>
+ <td>
+ <b>Manhattan Plot Color Scheme:&nbsp;</b>
+ </td>
+ <td>
+ <select id="color_scheme">
+ <option value="alternating" {% if color_scheme == "alternating" %}selected{% endif %}>Alternating</option>
+ <option value="varied" {% if color_scheme == "varied" %}selected{% endif %}>Varied by Chr</option>
+ <option value="single" {% if color_scheme == "single" %}selected{% endif %}>Single Color</option>
+ </select>
+ </td>
+ <td>
+ <input name="manhattan_single_color" type="hidden" id="point_color" value={% if manhattan_single_color %}{{ manhattan_single_color }}{% else %}"#D9D9D9"{% endif %}>
+ <button style="display: none; margin-left: 5px;" id="point_color_picker" class="jscolor {valueElement: 'point_color'}">Choose Color</button>
+ </td>
+ </tr>
+ </table>
+ {% endif %}
+ </div>
+ <div class="col-xs-4" style="padding: 0px;">
+ {% if (mapping_method == "reaper" or mapping_method == "rqtl_geno") and nperm > 0 %}
+ <input type="checkbox" name="permCheck" class="checkbox" style="display: inline; margin-top: 0px;" {% if permChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Permutation Test
+ <a href="http://genenetwork.org/glossary.html#Permutation" target="_blank">
+ <sup style="color:#f00"> ?</sup>
+ </a>
+ <br>
+ {% endif %}
+ {% if mapping_method == "reaper" and nboot > 0 %}
+ <input type="checkbox" name="bootCheck" class="checkbox" style="display: inline; margin-top: 0px;" {% if bootChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Bootstrap Test
+ <a href="http://genenetwork.org/glossary.html#bootstrap" target="_blank">
+ <sup style="color:#f00"> ?</sup>
+ </a>
+ <br>
+ {% endif %}
+ {% if mapping_method == "reaper" %}
+ <input type="checkbox" name="additiveCheck" class="checkbox" style="display: inline; margin-top: 0px;" {% if additiveChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Allele Effects
+ <a href="http://genenetwork.org/glossary.html#additive" target="_blank">
+ <sup style="color:#f00"> ?</sup>
+ </a>
+ <br>
+ {% endif %}
+ <input type="checkbox" name="showSNP" class="checkbox" style="display: inline; margin-top: 0px;" {% if SNPChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">SNP Track </span>
+ <a href="http://genenetwork.org/glossary.html#snpSeismograph" target="_blank">
+ <sup style="color:#f00"> ?</sup>
+ </a>
+ <span style="color:red;">*</span>
+ <br>
+ <input type="checkbox" name="showGenes" class="checkbox" style="display: inline; margin-top: 0px;" {% if geneChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Gene Track </span> <span style="color:red;">*</span><br>
+ {% if plotScale != "morgan" %}
+ <input type="checkbox" name="haplotypeAnalystCheck" class="checkbox" style="display: inline; margin-top: 0px;" {% if haplotypeAnalystChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Haplotype Tracks </span> <span style="color:red;">*</span><br>
+ {% endif %}
+ <input type="checkbox" name="viewLegend" class="checkbox" style="display: inline; margin-top: 0px;" {% if legendChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Legend </span><br>
+ <input type="checkbox" name="showHomology" class="checkbox" style="display: inline; margin-top: 0px;" {% if homologyChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Human Chromosomes <a href="http://hgdownload.cse.ucsc.edu/goldenpath/hg38/liftOver/"><sup style="color:#f00" title="Human Syntenic Chromosomes taken from HG38 (Human Genome 38)"> ?</sup></a></span>
+ <br>
+ <span style="color:red;">*</span> <span style="font-size: 12px;">only apply to single chromosome physical mapping</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="tabbable" style="width: 100%; overflow-x: auto; margin: 10px; float: left;">
+ <ul class="nav nav-tabs">
+ <li id="gn1_map_tab">
+ <a href="#gn1_map" data-toggle="tab" aria-expanded="true">GN1 Map</a>
+ </li>
+ {% if mapping_method == "gemma" or mapping_method == "reaper" %}
+ <li id="browser_tab">
+ <a href="#browser_holder" data-toggle="tab" aria-expanded="true">Genome Browser</a>
+ </li>
+ {% endif %}
+ </ul>
+ <div class="tab-content">
+ <div class="tab-pane active" id="gn1_map">
+ <div class="qtlcharts">
+ {{ gifmap|safe }}
+ <img src="/generated/{{ filename }}.png" usemap="#WebQTLImageMap">
+ {% if additiveChecked|upper == "ON" %}
+ <br>
+ <span style="white-space: nowrap;">A positive additive coefficient (green line) indicates that {{ dataset.group.parlist[1] }} alleles increase trait values. In contrast, a negative additive coefficient (orange line) indicates that {{ dataset.group.parlist[0] }} alleles increase trait values.</span>
+ {% endif %}
+ </div>
+ </div>
+ {% if mapping_method == "gemma" or mapping_method == "reaper" %}
+ <div class="tab-pane" id="browser_holder" style="height: 600px;">
+ <div id="browser" style="margin-right: 20px; width: 90%;">
+ <div id="controls">
+ <button id="scrollLeft" type="button" >
+ <i class="fas fa-arrow-left"></i>
+ </button>
+ <button id="scrollRight" type="button" >
+ <i class="fas fa-arrow-right"></i>
+ </button>
+ <button id="zoomOut" type="button" >
+ <i class="fas fa-search-minus"></i>
+ </button>
+ <button id="zoomIn" type="button" >
+ <i class="fas fa-search-plus"></i>
+ </button>
+ <button id="reset" type="button" >Reset</button>
+ </div>
+ <div id="infoBox"></div>
+ </div>
+ </div>
+ {% endif %}
+ </div>
+ </div>
+ <div style="float: left;">
+ {% if nperm > 0 and permChecked == "ON" %}
+ <br><br>
+ <div id="perm_histogram" class="barchart"></div>
+ <br><br>
+ Total of {{ nperm }} permutations&nbsp;&nbsp;<a href="javascript:;" id="download_perm" target="_blank" >Download Permutation Results</a>
+ <br>
+ {% endif %}
+ </div>
+
+ </form>
+ {% if selectedChr == -1 %}
+ <div class="container" style="padding-left: 30px; margin-top: 50px; position: relative; float: left;">
+ <h2>Mapping Statistics</h2>
+ <br />
+ <button class="btn btn-default" id="select_all"><span class="glyphicon glyphicon-ok"></span> Select All</button>
+ <button class="btn btn-default" id="deselect_all"><span class="glyphicon glyphicon-remove"></span> Deselect All</button>
+ <button class="btn btn-default" id="invert"><span class="glyphicon glyphicon-resize-vertical"></span> Invert</button>
+ {% if geno_db_exists == "True" %}<button class="btn btn-success" id="add" disabled><span class="glyphicon glyphicon-plus-sign"></span> Add</button>{% endif %}
+ <button class="btn btn-default export_mapping_results" ><span class="glyphicon glyphicon-download"></span> Download</span></button>
+ <br />
+ <br />
+ <div id="trait_table_container" style="width:{% if 'additive' in trimmed_markers[0] %}600{% else %}550{% endif %}px;">
+ <table class="table-hover table-striped cell-border no-footer" id='trait_table' style="float: left;">
+ <tbody>
+ <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% elif selectedChr != -1 and plotScale =="physic" and (dataset.group.species == 'mouse' or dataset.group.species == 'rat') %}
+ <div style="width: 100%;">
+ <h2>Interval Analyst</h2>
+ <div id="table_container">
+ <table id="trait_table" class="table-hover table-striped cell-border dataTable" style="float: left; width:100%;">
+ <thead>
+ <tr>
+ {% for header in gene_table_header %}
+ <th>{{ header|safe }}</th>
+ {% endfor %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for row in gene_table_body %}
+ <tr>
+ {% for n in range(row|length) %}
+ {% if n == 0 %}
+ <td align="center" style="padding: 1px 0px 1px 0px;">{{ row[n]|safe }}</td>
+ {% else %}
+ <td>{{ row[n]|safe }}</td>
+ {% endif %}
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endif %}
+ </div>
+
+ <!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+
+ <script type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('js', filename='underscore-string/underscore.string.min.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script>
+ {% if manhattan_plot == True and selectedChr == -1 %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jscolor/jscolor.js') }}"></script>
+
+ {% endif %}
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='purescript-genome-browser/js/purescript-genetics-browser.js') }}"></script>
+
+ <script>
+ var js_data = {{ js_data | safe }};
+ var markersJson = {{ trimmed_markers|safe }};
+ </script>
+
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script>
+ {% if mapping_method == "gemma" or mapping_method == "reaper" %}
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/init_genome_browser.js"></script>
+ {% endif %}
+
+ <script type="text/javascript" charset="utf-8">
+ $(document).ready( function () {
+ {% if selectedChr == -1 %}
+ tableId = "trait_table"
+
+ columnDefs = [
+ {
+ 'data': null,
+ 'width': "5px",
+ 'orderDataType': "dom-checkbox",
+ 'targets': 0,
+ 'render': function(data, type, row, meta) {
+ return '<input type="checkbox" name="selectCheck" class="checkbox trait_checkbox" value="'+ data.hmac + '">'
+ }
+ },
+ {
+ 'title': "Row",
+ 'type': "natural",
+ 'width': "35px",
+ 'searchable': false,
+ 'orderable': false,
+ 'targets': 1,
+ 'render': function(data, type, row, meta) {
+ return meta.row
+ }
+ },
+ {
+ 'title': "Marker",
+ 'type': "natural",
+ 'width': "20%",
+ 'targets': 2,
+ {% if geno_db_exists == "True" %}
+ 'data': null,
+ 'render': function(data, type, row, meta) {
+ return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset={{ dataset.group.name }}Geno">' + data.name + '</a>'
+ }
+ {% else %}
+ 'data': "name"
+ {% endif %}
+ },
+ {
+ 'title': "<div style='text-align: right;'>{{ LRS_LOD }}</div>",
+ 'type': "natural",
+ 'width': "60px",
+ 'targets': 3,
+ 'orderSequence': [ "desc", "asc"],
+ 'data': null,
+ 'render': function(data, type, row, meta) {
+ {% if (LRS_LOD == "LOD") or (LRS_LOD == "-logP") %}
+ if ('lod_score' in data){
+ return String(parseFloat(data.lod_score).toFixed(2))
+ } else {
+ return String((parseFloat(data.lrs_value) / 4.61).toFixed(2))
+ }
+ {% else %}
+ if ('lod_score' in data){
+ return String((parseFloat(data.lod_score) * 4.61).toFixed(2))
+ } else {
+ return String(parseFloat(data.lrs_value).toFixed(2))
+ }
+ {% endif %}
+ }
+ },
+ {
+ 'title': "<div style='text-align: right;'>Position ({% if plotScale == 'physic' %}Mb{% else %}cM{% endif %})</div>",
+ 'type': 'natural',
+ 'targets': 4,
+ 'data': "display_pos"
+ },
+ {% if 'additive' in trimmed_markers[0] %}
+ {
+ 'title': "<div style='text-align: right;'>Add Eff</div>",
+ 'type': "natural",
+ 'targets': 5,
+ 'data': null,
+ 'render': function(data, type, row, meta) {
+ {% if geno_db_exists == "True" %}
+ return '<a target"_blank" href="corr_scatter_plot?method=pearson&dataset_1={{ dataset.group.name }}Geno&dataset_2={{ dataset.name }}&trait_1=' + data.name + '&trait_2={{ this_trait.name }}&cached_trait=trait_2&dataid={{ dataid }}">' + String(parseFloat(data.additive).toFixed(3)) + '</a>'
+ {% else %}
+ return String(parseFloat(data.additive).toFixed(3))
+ {% endif %}
+ }
+ },
+ {% endif %}
+ {% if ('dominance' in trimmed_markers[0]) and (dataset.group.genetic_type != "riset") %}
+ {
+ 'title': "<div style='text-align: right;'>Add Eff</div>",
+ 'type': "natural",
+ 'targets': {% if ('additive' in trimmed_markers[0]) %}6{% else %}5{% endif %},
+ 'data': null,
+ 'render': function(data, type, row, meta) {
+ return String(parseFloat(data.dominance).toFixed(2))
+ }
+ }
+ {% endif %}
+ ]
+
+ tableSettings = {
+ "createdRow": function ( row, data, index ) {
+ $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;");
+ $('td', row).eq(1).attr("align", "right");
+ $('td', row).eq(1).attr('data-export', index+1);
+ $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text());
+ $('td', row).eq(3).attr("align", "right");
+ $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text());
+ $('td', row).eq(4).attr("align", "right");
+ $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text());
+ {% if 'additive' in trimmed_markers[0] %}
+ $('td', row).eq(5).attr("align", "right");
+ $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text());
+ {% endif %}
+ {% if 'dominance' in trimmed_markers[0] %}
+ $('td', row).eq(6).attr("align", "right");
+ $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text());
+ {% endif %}
+ },
+ "language": {
+ "info": "Showing from _START_ to _END_ of " + js_data.total_markers + " records",
+ },
+ "order": [[1, "asc" ]],
+ "scrollY": "1000px",
+ "scroller": true
+ }
+
+ create_table(tableId, markersJson, columnDefs, tableSettings)
+
+ {% elif selectedChr != -1 and plotScale =="physic" and (dataset.group.species == 'mouse' or dataset.group.species == 'rat') %}
+ $('#trait_table').dataTable( {
+ "drawCallback": function( settings ) {
+ $('#trait_table tr').off().on("click", function(event) {
+ if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') {
+ var obj =$(this).find('input');
+ obj.prop('checked', !obj.is(':checked'));
+ }
+ if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){
+ $(this).removeClass("selected")
+ } else if (event.target.tagName.toLowerCase() !== 'a') {
+ $(this).addClass("selected")
+ }
+ });
+ },
+ "createdRow": function ( row, data, index ) {
+ $('td', row).eq(1).attr("align", "right");
+ $('td', row).eq(3).attr("align", "right");
+ $('td', row).eq(4).attr("align", "right");
+ $('td', row).eq(5).attr("align", "right");
+ $('td', row).eq(6).attr("align", "right");
+ $('td', row).eq(7).attr("align", "right");
+ $('td', row).eq(8).attr("align", "center");
+ $('td', row).eq(9).attr("align", "right");
+ },
+ "columns": [
+ { "orderDataType": "dom-checkbox" },
+ { "type": "natural"},
+ { "type": "natural" , "orderDataType": "dom-inner-text" },
+ { "type": "natural" , "orderDataType": "dom-inner-text" },
+ { "type": "natural" , "orderDataType": "dom-inner-text" },
+ { "type": "natural" , "orderDataType": "dom-inner-text" },
+ { "type": "natural" },
+ { "type": "natural-minus-na" },
+ { "type": "natural-minus-na" },
+ { "type": "natural-minus-na" , "orderDataType": "dom-inner-text" },
+ { "type": "natural" }
+ ],
+ "columnDefs": [ {
+ "targets": 0,
+ "sortable": false
+ }],
+ "order": [[3, "asc" ]],
+ "sDom": "RZtir",
+ "iDisplayLength": -1,
+ "autoWidth": false,
+ "deferRender": true,
+ "bSortClasses": false,
+ "scrollCollapse": false,
+ "paging": false
+ } );
+ {% endif %}
+
+ $('#vector_map_tab').click(function(){
+ $('div#gn1_map_options').hide();
+ });
+
+ $('#gn1_map_tab').click(function(){
+ $('div#gn1_map_options').show();
+ });
+
+ });
+
+ var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale', 'sample_vals',
+ 'score_type', 'suggestive', 'significant', 'num_perm', 'permCheck', 'perm_output', 'perm_strata', 'categorical_vars', 'num_bootstrap', 'bootCheck', 'bootstrap_results',
+ 'LRSCheck', 'covariates', 'maf', 'use_loco', 'manhattan_plot', 'color_scheme', 'manhattan_single_color', 'control_marker', 'do_control', 'genofile',
+ 'pair_scan', 'startMb', 'endMb', 'graphWidth', 'lrsMax', 'additiveCheck', 'showSNP', 'showHomology', 'showGenes', 'viewLegend', 'haplotypeAnalystCheck',
+ 'mapmethod_rqtl_geno', 'mapmodel_rqtl_geno', 'temp_trait', 'group', 'species', 'reaper_version', 'primary_samples', 'n_samples']
+
+ $('input[name=wanted_inputs]').val(mapping_input_list.join(","));
+
+ chrView = function(this_chr, chr_mb_list) {
+ $('input[name=selected_chr]').val(this_chr)
+ $('input[name=chr_mb_list]').val(chr_mb_list)
+
+ $('#marker_regression_form').attr('action', '/loading');
+ $('#marker_regression_form').submit();
+ };
+
+ rangeView = function(this_chr, start_mb, end_mb) {
+ $('input[name=selected_chr]').val(this_chr)
+ $('input[name=startMb]').val(start_mb)
+ $('input[name=endMb]').val(end_mb)
+ //$('input[name=mb_range]').val(start_mb + "," + end_mb)
+
+ $('#marker_regression_form').attr('action', '/loading');
+ $('#marker_regression_form').submit();
+ };
+
+ remap = function() {
+ $('input[name=selected_chr]').val($('select[name=chromosomes]').val());
+ $('input[name=color_scheme]').val($('select#color_scheme').val());
+ $('#marker_regression_form').attr('action', '/loading');
+ return $('#marker_regression_form').submit();
+ };
+
+ {% if manhattan_plot == True and selectedChr == -1 %}
+ $('#color_scheme').change(function(){
+ if ($(this).val() == "single"){
+ $('#point_color_picker').show();
+ } else {
+ $('#point_color_picker').hide();
+ }
+ });
+ {% endif %}
+
+ {% if mapping_method != "gemma" and mapping_method != "plink" and nperm > 0 and permChecked == "ON" %}
+ $('#download_perm').click(function(){
+ perm_info_dict = {
+ perm_data: js_data.perm_results,
+ num_perm: "{{ nperm }}",
+ trait_name: "{{ this_trait.display_name }}",
+ trait_description: `{{ this_trait.description_display }}`,
+ cofactors: "{{ covariates }}",
+ n_samples: {{ n_samples }},
+ n_genotypes: {{ qtl_results|length }},
+ {% if genofile_string is defined %}
+ genofile: "{{ genofile_string }}",
+ {% else %}
+ genofile: "",
+ {% endif %}
+ units_linkage: "{{ LRS_LOD }}",
+ strat_cofactors: js_data.categorical_vars
+ }
+ json_perm_data = JSON.stringify(perm_info_dict);
+
+ $('input[name=perm_info]').val(json_perm_data);
+ $('#marker_regression_form').attr('action', '/export_perm_data');
+ return $('#marker_regression_form').submit();
+ });
+
+ modebar_options = {
+ modeBarButtonsToAdd:[{
+ name: 'Export as SVG',
+ icon: Plotly.Icons.disk,
+ click: function(gd) {
+ Plotly.downloadImage(gd, {format: 'svg'})
+ }
+ }],
+ modeBarButtonsToRemove:['toImage', 'sendDataToCloud', 'hoverClosest', 'hoverCompare', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'toggleSpikelines'],
+ displaylogo: false
+ //modeBarButtons:['toImage2', 'zoom2d', 'pan2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'autoScale2d', 'resetScale2d'],
+ }
+
+ perm_data = js_data.perm_results
+ var hist_trace = {
+ x: perm_data,
+ type: 'histogram'
+ };
+ histogram_data = [hist_trace];
+ histogram_layout = {
+ bargap: 0.05,
+ title: "<b>Histogram of Permutation Test</b>",
+ xaxis: {
+ autorange: true,
+ title: "<b>{{ LRS_LOD }}</b>",
+ titlefont: {
+ family: "arial",
+ size: 20
+ },
+ ticklen: 4,
+ tickfont: {
+ size: 16
+ }
+ },
+ yaxis: {
+ autorange: true,
+ title: "<b>Count</b>",
+ titlefont: {
+ family: "arial",
+ size: 20
+ },
+ showline: true,
+ ticklen: 4,
+ tickfont: {
+ size: 16
+ },
+ automargin: true
+ },
+ width: 500,
+ height: 300,
+ margin: {
+ l: 70,
+ r: 30,
+ t: 100,
+ b: 50
+ }
+ };
+
+ Plotly.newPlot('perm_histogram', histogram_data, histogram_layout, modebar_options);
+ {% endif %}
+
+ export_mapping_results = function() {
+ $('#marker_regression_form').attr('action', '/export_mapping_results');
+ return $('#marker_regression_form').submit();
+ }
+
+ $('.export_mapping_results').click(export_mapping_results);
+
+ $('#browser_tab').click(function() {
+ $('#gn1_map_options').css("display", "none")
+ })
+ $('#gn1_map_tab').click(function() {
+ $('#gn1_map_options').css("display", "block")
+ })
+
+ hash = $('input[name=inputs_hash]').val();
+ mappingLink = window.location.origin + "/run_mapping/"+ hash;
+ $('input[name=mappingLink]').width(mappingLink.length*0.95 + "ch")
+ $('input[name=mappingLink]').val(mappingLink);
+ $('.share-results').click(function() {
+ $.ajax({
+ method: "POST",
+ url: "/cache_mapping_inputs",
+ data: {
+ inputs_hash: hash
+ },
+ success: function() {
+ document.querySelector("input[name='mappingLink']").select();
+ document.execCommand('copy');
+ }
+ });
+ })
+
+ </script>
+
+{% endblock %}
+
diff --git a/gn2/wqflask/templates/marker_regression.html b/gn2/wqflask/templates/marker_regression.html
new file mode 100644
index 00000000..b633f815
--- /dev/null
+++ b/gn2/wqflask/templates/marker_regression.html
@@ -0,0 +1,119 @@
+{% from "base_macro.html" import header %}
+{% block content %}
+ {{ header("Mapping",
+ '{}: {}'.format(this_trait.name, this_trait.description_fmt)) }}
+
+ <div class="container">
+ <div>
+ <h2>
+ Whole Genome Mapping
+ </h2>
+ <form style ='float: left; padding: 5px;' id="exportform" action="export" method="post">
+ <input type="hidden" id="data" name="data" value="">
+ <input type="hidden" id="filename" name="filename" value="">
+ <input type="submit" id="export" value="Download SVG">
+ </form>
+ <form style ='float: left; padding: 5px;' id="exportpdfform" action="export_pdf" method="post">
+ <input type="hidden" id="data" name="data" value="">
+ <input type="hidden" id="filename" name="filename" value="">
+ <input type="submit" id="export_pdf" value="Download PDF">
+ </form>
+ <button id="return_to_full_view" class="btn" style="display:none">Return to full view</button>
+ </div>
+ <div id="chart_container">
+ <div class="qtlcharts" id="topchart">
+
+ </div>
+ </div>
+ <div style="width:60%;">
+ <h2>
+ Results
+ </h2>
+ <table id="qtl_results" class="table table-hover table-striped">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>{{ score_type }}</th>
+ <th>Chr</th>
+ {% if mapping_scale == "centimorgan" %}
+ <th>cM</th>
+ {% else %}
+ <th>Mb</th>
+ {% endif %}
+ <th>Locus</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for marker in qtl_results %}
+ {% if (score_type == "LOD" and marker.lod_score > cutoff) or
+ (score_type == "LRS" and marker.lrs_value > cutoff) %}
+ <tr>
+ <td>
+ <input type="checkbox" name="selectCheck"
+ class="checkbox edit_sample_checkbox"
+ value="{{ marker.name }}" checked="checked">
+ </td>
+ <Td align="right">{{ loop.index }}</Td>
+ {% if score_type == "LOD" %}
+ <td>{{ '%0.2f' | format(marker.lod_score|float) }}</td>
+ {% else %}
+ <td>{{ '%0.2f' | format(marker.lrs_value|float) }}</td>
+ {% endif %}
+ <td>{{marker.chr}}</td>
+ <td>{{ '%0.6f' | format(marker.Mb|float) }}</td>
+ <td>
+ {{ marker.name }}
+ <!--<a href="{{ url_for('show_trait_page',
+ trait_id = marker.name,
+ dataset = dataset.name
+ )}}">
+ {{ marker.name }}
+ </a>-->
+ </td>
+ </tr>
+ {% endif %}
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+
+ <!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script>
+ js_data = {{ js_data | safe }}
+ </script>
+
+ <script type="text/javascript" charset="utf-8">
+ $(document).ready( function () {
+ console.time("Creating table");
+ $('#qtl_results').dataTable( {
+ "columns": [
+ { "type": "natural", "bSortable": false },
+ { "type": "natural" },
+ { "type": "natural" },
+ { "type": "natural" },
+ { "type": "natural" },
+ { "type": "natural" }
+ ],
+ "buttons": [
+ 'csv'
+ ],
+ "sDom": "RZBtir",
+ "iDisplayLength": -1,
+ "autoWidth": true,
+ "bDeferRender": true,
+ "bSortClasses": false,
+ "scrollY": "700px",
+ "scrollCollapse": true,
+ "paging": false
+ } );
+ console.timeEnd("Creating table");
+
+ });
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/metadata/dataset.html b/gn2/wqflask/templates/metadata/dataset.html
new file mode 100644
index 00000000..06df6a68
--- /dev/null
+++ b/gn2/wqflask/templates/metadata/dataset.html
@@ -0,0 +1,157 @@
+<header class="page-header text-justify">
+ <h1>
+ {% if dataset.title or dataset.label or dataset.altLabel %}
+ {{ dataset.title or dataset.label or dataset.altLabel }}
+ {% if dataset.title != dataset.altLabel and dataset.label != dataset.altLabel %}
+ <br/>
+ <small>({{ dataset.altLabel }})</small>
+ {% endif %}
+ {% else %}
+ {{ name }}
+ {% endif %}
+ </h1>
+</header>
+
+<div class="container dataset-content">
+ <div class="panel-about panel panel-info panel-metadata text-muted">
+ <div class="panel-heading">
+ <strong>
+ <span class="glyphicon glyphicon-info-sign aria-hidden=true"></span>
+ Details
+ </strong>
+ {% if dataset.accessionId %}
+ <small>
+ <a href="https://gn1.genenetwork.org/webqtl/main.py?FormID=sharinginfo&GN_AccessionId={{ dataset.accessionId.split('GN')[-1] }}" target="_blank">(GN1 Link)</a>
+ </small>
+ {% endif %}
+ </div>
+ <div class="panel-body">
+ <dl class="dl-horizontal">
+ {% if dataset.label != dataset.altLabel and dataset.label != dataset.title %}
+ <dt>Name</dt>
+ <dd> {{ dataset.label }} </dd>
+ {% endif %}
+ {% if dataset.created %}
+ <dt>Created</dt>
+ <dd>{{ dataset.created }}</dd>
+ {% endif %}
+ {% if dataset.inbredSet %}
+ <dt>Group</dt>
+ <dd>{{ dataset.inbredSet.label}}</dd>
+ {% endif %}
+
+ {% if dataset.accessionId %}
+ <dt>Accession Id</dt>
+ <dd>{{ dataset.accessionId}}</dd>
+ {% endif %}
+
+ {% if dataset.hasGeoSeriesId %}
+ <dt>GEO Series</dt>
+ <dd>
+ <a href="{{ dataset.geoSeriesId }}" target="_blank">{{ dataset.geoSeriesId.split("=")[-1] }}</a>
+ </dd>
+ {% endif %}
+
+ {% if dataset.tissue %}
+ <dt>Tissue</dt>
+ <dd>{{ dataset.tissue.label }}</dd>
+ {% endif %}
+
+ {% if dataset.platform %}
+ <dt>Platforms</dt>
+ <dd>
+ {{ dataset.platform.label }}
+ [<a href="{{ dataset.platform.id}}" target="_blank">
+ {{ dataset.platform.prefLabel}}
+ </a>]
+ </dd>
+ {% endif %}
+
+ {% if dataset.normalization %}
+ <dt>Normalization</dt>
+ <dd>{{ dataset.normalization.label }}</dd>
+ {% endif %}
+
+ {% if dataset.contactPoint %}
+ <dt>Investigator</dt>
+ <dd>
+ {% if dataset.contactPoint.contactWebUrl %}
+ <a href="{{ dataset.contactPoint.contactWebUrl }}" target="_blank">
+ {{ dataset.contactPoint.contactName }}
+ </a>
+ {% else %}
+ {{ dataset.contactPoint.contactName }}
+ {% endif %}
+ </dd>
+ {% endif %}
+
+ {% if dataset.organization %}
+ <dt>Organization</dt>
+ <dd>{{ dataset.organization }}</dd>
+ {% endif %}
+ </dl>
+ </div>
+ </div>
+
+ <div class="container row dataset-metadata">
+ {% if dataset.description %}
+ <div>{{ dataset.description|safe }}</div>
+ {% endif %}
+
+ {% if dataset.specificity %}
+ <h2><strong>Specifics of this Dataset</strong></h2>
+ <div>{{ dataset.specificity }}</div>
+ {% endif %}
+
+ {% if dataset.experimentDesignInfo %}
+ <h3><strong>Experiment Design</strong></h3>
+ <div>{{ dataset.experimentDesignInfo|safe }}</div>
+ {% endif %}
+
+ {% if dataset.caseInfo %}
+ <h3><strong>About the Cases Used to Generate this Dataset:</strong></h3>
+ <div>{{ dataset.caseInfo|safe }}</div>
+ {% endif %}
+
+ {% if dataset.tissue %}
+ <h3><strong>About the Tissue
+ {%if dataset.tissue and dataset.tissue.label %}({{ dataset.tissue.label }})
+ {% endif %}Used to Generate this Dataset</strong></h3>
+ <div>{{ dataset.tissue.tissueInfo|safe }}</div>
+ {% endif %}
+
+ {% if dataset.platform %}
+ <h3 title="{{ dataset.platform.label }}"><strong>About the Array Platform</strong></h3>
+ <div>{{ dataset.platform.platformInfo|safe }}</div>
+ {% endif %}
+
+ {% if dataset.processingInfo %}
+ <h3><strong>About Data Values and Data Processing</strong></h3>
+ <div>{{ dataset.processingInfo|safe }}</div>
+ {% endif %}
+
+ {% if dataset.notes %}
+ <h3><strong>Notes</strong></h3>
+ <div>{{ dataset.notes|safe }}</div>
+ {% endif %}
+
+ {% if dataset.citation|trim %}
+ <h3><strong>Citation</strong></h3>
+ <div>{{ dataset.citation|safe}}</div>
+ {% endif %}
+
+ {% if dataset.acknowledgement|trim %}
+ <h3><strong>Acknowledgment</strong></h3>
+ <div>{{ dataset.acknowledgement|safe}}</div>
+ {% endif %}
+
+ {% if dataset.contributors %}
+ <h3><strong>Contributors</strong></h3>
+ <div>{{ dataset.contributors|safe }}</div>
+ {% endif %}
+ </div>
+
+</div>
+
+</div>
+
diff --git a/gn2/wqflask/templates/network_graph.html b/gn2/wqflask/templates/network_graph.html
new file mode 100644
index 00000000..cff69ac8
--- /dev/null
+++ b/gn2/wqflask/templates/network_graph.html
@@ -0,0 +1,152 @@
+{% extends "base.html" %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="/static/new/css/network_graph.css" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='cytoscape-panzoom/cytoscape.js-panzoom.css') }}">
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='qtip2/jquery.qtip.min.css') }}">
+ <style>
+ /* The Cytoscape Web container must have its dimensions set. */
+ html, body { height: 100%; width: 100%; padding: 0; margin: 0; }
+ #cytoscapeweb { width: 70%; height: 70%; }
+ </style>
+{% endblock %}
+{% block content %}
+ <div class="container-fluid">
+ <h1>Network Graph</h1>
+ <hr style="height: 1px; background-color: #A9A9A9;">
+ <div class="row" >
+ <div id="content">
+ <div id="secondaryContent" class="col-xs-3">
+ <h3 style="margin-top:0px; margin-bottom: 5px;"> Visualization Options</h3>
+ <table border="0">
+ <tbody>
+ <tr>
+ <td>
+ <button id="reset_graph">Reset Graph</button>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Focus Trait<sup title="Only show edges connected to the specified node" style="color:#f00"> ?</sup>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <select name="focus_select">
+ <option disabled selected value>Select Trait</option>
+ {% for trait in traits %}
+ {% if trait.symbol == None %}
+ <option value="{{ trait.name }}:{{ trait.dataset.name }}">{{ trait.name }}</option>
+ {% else %}
+ <option value="{{ trait.name }}:{{ trait.dataset.name }}">{{ trait.symbol }} ({{ trait.name }})</option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ Correlation Coefficient<sup title="Filter edges to only show correlations less than the negative value specified with the slider and greater than the positive value. For example, moving the slider half way will display correlations less than -0.5 and greater than 0.5" style="color:#f00"> ?</sup>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div style="text-align: center;">
+ <div style="float: left;"><font size="2"><b>-1</b></font></div>
+ <font size="2"><b>0</b></font>
+ <div style="float: right;"><font size="2"><b>1</b></font></div>
+ </div>
+ <!--
+ <font size="2"><b>-1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1</b></font><br>
+ -->
+ <input type="range" id="neg_slide" min="-1" max="0" value="0" step="0.001" list="corr_range" style="display: inline; width: 49%">
+ <input type="range" id="pos_slide" min="0" max="1" value="0" step="0.001" list="corr_range" style="display: inline; width: 49%">
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Layouts:
+ <select name="layout_select">
+ <option value="circle">Circle</option>
+ <option value="concentric">Concentric</option>
+ <option value="cose">Cose</option>
+ <option value="grid">Grid</option>
+ <option value="breadthfirst">Breadthfirst</option>
+ <option value="random">Random</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Node Font Size:
+ <select name="font_size">
+ <option value="6">6</option>
+ <option value="7">7</option>
+ <option value="8">8</option>
+ <option value="9">9</option>
+ <option value="10" selected>10</option>
+ <option value="11">11</option>
+ <option value="12">12</option>
+ <option value="13">13</option>
+ <option value="14">14</option>
+ <option value="15">15</option>
+ <option value="16">16</option>
+ <option value="17">17</option>
+ <option value="18">18</option>
+ </select>
+ </td>
+ <td>
+ </tr>
+ <tr>
+ <td>
+ Edge Width:
+ <select name="edge_width">
+ <option value="1" selected>1x</option>
+ <option value="2">2x</option>
+ <option value="3">3x</option>
+ <option value="4">4x</option>
+ </select>
+ </td>
+ <td>
+ </tr>
+ </tbody>
+ </table>
+ <h3 style="margin-bottom: 5px;"> Download</h3>
+ <table>
+ <tbody>
+ <tr>
+ <td>
+ <a id="image_link" href="javascript:void(0)">
+ <button style="width:100px;height:25px;">Save Image</button>
+ </a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="cytoscapeweb" class="col-xs-9" style="height:700px !important; border-style: solid; border-width: 1px; border-color: grey;"></div>
+ </div>
+ </div>
+ </div>
+
+
+{% endblock %}
+
+{% block js %}
+
+ <script>
+ elements_list = {{ elements | safe }}
+ gn2_url = "{{ gn2_url | safe }}"
+ </script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='qtip2/jquery.qtip.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='cytoscape/cytoscape.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='cytoscape-panzoom/cytoscape-panzoom.js') }}"></script>
+ <!-- should be using cytoscape-popper for tips, see docs -->
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='cytoscape-qtip/cytoscape-qtip.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/network_graph.js"></script>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/new_security/forgot_password.html b/gn2/wqflask/templates/new_security/forgot_password.html
new file mode 100644
index 00000000..60a221da
--- /dev/null
+++ b/gn2/wqflask/templates/new_security/forgot_password.html
@@ -0,0 +1,52 @@
+{% extends "base.html" %}
+{% block title %}Forgot Password{% endblock %}
+{% block content %}
+
+ <div class="container">
+ <div class="page-header">
+ <h1>Password Reset</h1>
+ </div>
+
+ <div class="security_box">
+
+ <h4>Enter your email address and we'll send you a link to reset your password</h4>
+
+ <form class="form-horizontal" action="/n/forgot_password_submit"
+ method="POST" name="login_user_form">
+ <fieldset>
+ <div class="control-group">
+ <div class="controls">
+ <input id="email_address" class="focused" name="email_address" type="text" value="">
+ </div>
+ </div>
+
+
+ <div class="control-group">
+ <div class="controls" style="margin-top: 10px;">
+ <input id="next" name="next" type="hidden" value="">
+
+ <input class="btn btn-primary" id="submit" name="submit" type="submit" value="Send link">
+ </div>
+ </div>
+
+ </fieldset>
+
+ <br />
+
+ <div class="well">
+ <h5>Has your email address changed?</h5>
+
+ If you no longer use the email address connected to your account, you can contact us for assistance.
+
+ </div>
+
+ </form>
+ </div>
+ </div>
+ </div>
+
+ {% endblock %}
+
+{% block js %}
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/new_security/forgot_password_step2.html b/gn2/wqflask/templates/new_security/forgot_password_step2.html
new file mode 100644
index 00000000..1835fd4c
--- /dev/null
+++ b/gn2/wqflask/templates/new_security/forgot_password_step2.html
@@ -0,0 +1,25 @@
+{% extends "base.html" %}
+{% block title %}Register{% endblock %}
+{% block content %}
+
+ {{ header("Password Reset", "Check your email.") }}
+
+
+ <div class="container">
+ <div class="page-header">
+ <h3>One last step</h3>
+ </div>
+
+ <p>You will receive an email with the subject <strong>{{ subject }}</strong>.</p>
+
+ <p>You must click the link in the email to reset the password.</p>
+
+ <p>If you don't see the email, check your spam folder.</p>
+ </div>
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/new_security/login_user.html b/gn2/wqflask/templates/new_security/login_user.html
new file mode 100644
index 00000000..b8cdf6ef
--- /dev/null
+++ b/gn2/wqflask/templates/new_security/login_user.html
@@ -0,0 +1,119 @@
+{% extends "base.html" %}
+{% block title %}Register{% endblock %}
+{% block content %}
+
+ <div class="container" style="min-width: 1250px;">
+
+ {{ flash_me() }}
+
+ <h3>Sign in here.</h3>
+
+ {% if redis_is_available: %}
+ <form class="form-horizontal" action="/n/login" method="POST" name="login_user_form" id="loginUserForm">
+ <input name="anon_id" type="hidden" value="{{ g.user_session.user_id }}">
+ <fieldset>
+ <div class="form-group">
+ <label style="text-align:left;" class="col-xs-1 control-label" for="email_address">Email&nbsp;Address</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="email_address" class="focused" name="email_address" type="text" value="" size="50">
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label style="text-align:left;" class="col-xs-1 control-label" for="password">Password</label>
+ <div style="margin-left:20px;" class="col-xs-4 controls">
+ <input id="password" class="focused" name="password" type="password" value="" size="50">
+ <br />
+ <br />
+ <a href="/n/forgot_password">Forgot your password?</a><br/>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="remember"></label>
+ <div style="margin-left:20px;" class="col-xs-4 controls">
+ <input id="remember" name="remember" type="checkbox" value="y"> <b>Remember me</b><br>
+ <input id="import_collections" name="import_collections" type="checkbox" value="y"> <b>Import existing collections</b>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="submit"></label>
+ <div style="margin-left:20px;" class="col-xs-4 controls">
+ <input id="next" name="next" type="hidden" value="">
+ <input class="btn btn-primary" id="submit" name="submit" type="submit" value="Sign in">
+ </div>
+ </div>
+ </fieldset>
+
+ <div class="security_box">
+
+ <h4>Don't have an account?</h4>
+
+ {% if redis_is_available: %}
+ <a href="/n/register" class="btn btn-primary modalize">Create a new account</a>
+ {% else %}
+ <div class="alert alert-warning">
+ <p>You cannot create an account at this moment.<br />
+ Please try again later.</p>
+ </div>
+ {% endif %}
+
+ <hr />
+ <h4>Login with external services</h4>
+
+ {% if external_login: %}
+ <div>
+ {% if external_login["github"]: %}
+ <a href="{{external_login['github']}}" title="Login with GitHub" class="btn btn-info btn-group">Login with Github</a>
+ {% else %}
+ <p>Github login is not available right now</p>
+ {% endif %}
+
+ {% if external_login["orcid"]: %}
+ <a href="{{external_login['orcid']}}" title="Login with ORCID" class="btn btn-info btn-group">Login with ORCID</a>
+ {% else %}
+ <p>ORCID login is not available right now</p>
+ {% endif %}
+ </div>
+ {% else: %}
+ <div class="alert alert-warning">
+ <p>Sorry, you cannot login with Github or ORCID at this time.</p>
+ </div>
+ {% endif %}
+
+ </form>
+ {% else: %}
+ <div class="alert alert-warning">
+ <p>You cannot login at this moment using your GeneNetwork account (the authentication service is down).<br />
+ Please try again later.</p>
+ </div>
+ {% endif %}
+ {% if not external_login: %}
+ <hr>
+ <div class="alert alert-warning">
+ Note: it is safe to use GeneNetwork without a login. Login is only required for keeping track of
+ collections and getting access to some types of restricted data.
+ </div>
+ {% endif %}
+ </div>
+ </div>
+
+ {% endblock %}
+
+{% block css %}
+<style type="text/css">
+input.error{
+ border:1px solid #FF0000 !important;
+}
+
+label.error,div.error{
+ font-weight:normal;
+ color:#FF0000 !important;
+}
+</style>
+{% endblock %}
+
+{% block js %}
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/new_security/not_authenticated.html b/gn2/wqflask/templates/new_security/not_authenticated.html
new file mode 100644
index 00000000..ea688346
--- /dev/null
+++ b/gn2/wqflask/templates/new_security/not_authenticated.html
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+{% block title %}Authentication Needed{% endblock %}
+{% block content %}
+ <div class="container">
+ <div class="page-header">
+ <h3>You lack the permissions to view these data.</h3>
+ </div>
+ <p>Please contact the data's owner or GN administrators if you believe you should have access to these data.</p>
+ </div>
+
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/new_security/password_reset.html b/gn2/wqflask/templates/new_security/password_reset.html
new file mode 100644
index 00000000..e21f075c
--- /dev/null
+++ b/gn2/wqflask/templates/new_security/password_reset.html
@@ -0,0 +1,78 @@
+{% extends "base.html" %}
+{% block title %}Register{% endblock %}
+{% block content %}
+
+ {{ header("Password Reset", "Create a new password.") }}
+
+
+ <div class="container">
+ <div class="page-header">
+ <h1>Password reset</h1>
+ </div>
+
+ <div class="security_box">
+
+
+ <h4>Enter your new password</h4>
+
+
+ {% if errors %}
+ <div class="alert alert-error">
+ <strong>Please note:</strong>
+ <ul>
+ {% for error in errors %}
+ <li>{{error}}</li>
+ {% endfor %}
+ </ul>
+ </div>
+ {% endif %}
+
+ <form class="form-horizontal" action="/n/password_reset_step2" data-validate="parsley"
+ method="POST" name="login_user_form">
+
+ <fieldset>
+
+ <input class="hidden" name="user_encode" value="{{ user_encode }}">
+
+
+ <div class="control-group">
+ <label class="control-label" for="password">Password</label>
+ <div class="controls">
+ <input id="password" name="password" type="password" value=""
+ data-trigger="change" data-required="true" data-minlength="6">
+ </div>
+ </div>
+
+ <div class="control-group" style="display: none" id="password_alert">
+ <div class="controls"">
+ <span id="password_strength" class="alert"></span>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label class="control-label" for="password_confirm">Confirm Password</label>
+ <div class="controls">
+ <input id="password" name="password_confirm" type="password" value=""
+ data-trigger="change" data-required="true" data-equalto="#password">
+ </div>
+ </div>
+
+ <div class="control-group">
+ <div class="controls"">
+ <input class="btn btn-primary" id="submit" name="submit" type="submit" value="Reset password">
+ </div>
+ </div>
+
+ </fieldset>
+
+ </form>
+ </div>
+ </div>
+
+{% endblock %}
+
+{% block js %}
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/new_security/register_user.html b/gn2/wqflask/templates/new_security/register_user.html
new file mode 100644
index 00000000..c2895517
--- /dev/null
+++ b/gn2/wqflask/templates/new_security/register_user.html
@@ -0,0 +1,105 @@
+{% extends "base.html" %}
+{% block title %}Register{% endblock %}
+{% block content %}
+
+ {{ header("Register", "It's fast and easy to make an account.") }}
+
+
+ <div class="container">
+ <div class="page-header">
+ <h1>Registration</h1>
+ </div>
+
+ <div class="security_box">
+ <h4>Already have an account?</h4>
+
+
+ <a href="/n/login"
+ class="btn btn-info modalize">Sign in using existing account</a>
+
+
+ <hr />
+
+ <h4>Don't have an account?</h4>
+
+ <h5>Register here</h5>
+
+ {% if errors %}
+ <div class="alert alert-error">
+ <strong>Please note:</strong>
+ <ul>
+ {% for error in errors %}
+ <li>{{error}}</li>
+ {% endfor %}
+ </ul>
+ </div>
+ {% endif %}
+
+ <form class="form-horizontal" action="/n/register" data-validate="parsley"
+ method="POST" name="login_user_form">
+ <fieldset>
+
+ <div class="control-group">
+ <label class="control-label" for="email_address">Email Address</label>
+ <div class="controls">
+ <input id="email_address" name="email_address" class="focused" type="text" size="50" value="{{values.email_address}}"
+ data-trigger="change" data-required="true" data-type="email" data-maxlength="50">
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label class="control-label" for="full_name">Full Name</label>
+ <div class="controls">
+ <input id="full_name" name="full_name" type="text" size="50" value="{{values.full_name}}"
+ data-trigger="change" data-required="true" data-minlength="5" data-maxlength="50">
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label class="control-label" for="organization">Organization</label>
+ <div class="controls">
+ <input id="organization" name="organization" type="text" size="50" value="{{values.organization}}" data-minlength="3" data-maxlength="50">
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label class="control-label" for="password">Password</label>
+ <div class="controls">
+ <input id="password" name="password" type="password" size="50" value=""
+ data-trigger="change" data-required="true" data-minlength="6">
+ </div>
+ </div>
+
+ <div class="control-group" style="display: none" id="password_alert">
+ <div class="controls"">
+ <span id="password_strength" class="alert"></span>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label class="control-label" for="password_confirm">Confirm Password</label>
+ <div class="controls">
+ <input id="password" name="password_confirm" type="password" size="50" value=""
+ data-trigger="change" data-required="true" data-equalto="#password">
+ </div>
+ </div>
+
+ <div class="control-group">
+ <div class="controls" style="margin-top: 10px;">
+ <input class="btn btn-primary" id="submit" name="submit" type="submit" value="Create account">
+ </div>
+ </div>
+
+ </fieldset>
+
+ </form>
+ </div>
+ </div>
+
+{% endblock %}
+
+{% block js %}
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/new_security/registered.html b/gn2/wqflask/templates/new_security/registered.html
new file mode 100644
index 00000000..29889a97
--- /dev/null
+++ b/gn2/wqflask/templates/new_security/registered.html
@@ -0,0 +1,24 @@
+{% extends "base.html" %}
+{% block title %}Register{% endblock %}
+{% block content %}
+ {{ header("Almost Done", "Thanks for registering") }}
+
+ <div class="container">
+ <div class="page-header">
+ <h3>One last step</h3>
+ </div>
+
+ <p>You will receive an email with the subject <strong>{{ subject }}</strong>.</p>
+
+ <p>You must click the link in the email to complete registration.</p>
+
+ <p>If you don't see the email, check your spam folder.</p>
+ </div>
+
+{% endblock %}
+
+{% block js %}
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/new_security/thank_you.html b/gn2/wqflask/templates/new_security/thank_you.html
new file mode 100644
index 00000000..d4f5e574
--- /dev/null
+++ b/gn2/wqflask/templates/new_security/thank_you.html
@@ -0,0 +1,23 @@
+{% extends "base.html" %}
+{% block title %}Register{% endblock %}
+{% block content %}
+ {{ header("Thank you", "Thanks for verifying") }}
+
+ <div class="container">
+ <div class="page-header">
+ <h3>You are done registering</h3>
+ </div>
+
+ <p>Enjoy using the site.</p>
+
+ <br />
+
+ <a class="btn btn-primary" href="{{ url_for("index_page") }}">Go to the homepage</a>
+ </div>
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/new_security/verification_still_needed.html b/gn2/wqflask/templates/new_security/verification_still_needed.html
new file mode 100644
index 00000000..1f91fd8d
--- /dev/null
+++ b/gn2/wqflask/templates/new_security/verification_still_needed.html
@@ -0,0 +1,26 @@
+{% extends "base.html" %}
+{% block title %}Verification{% endblock %}
+{% block content %}
+ {{ header("Verification", "You still need to verify") }}
+
+ <div class="container">
+ <div class="page-header">
+ <h3>Verification of e-mail address</h3>
+ </div>
+ <h4>You still need to verify your e-mail address before you can sign in.</h4>
+
+ <p>We've resent the verificaiton email.
+
+ <p>Please check for an email with the subject <strong>{{ subject }}</strong>.</p>
+
+ <p>You must click the link in the email to complete registration.</p>
+
+ <p>If you don't see the email, check your spam folder.</p>
+ </div>
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
+ <script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/news.html b/gn2/wqflask/templates/news.html
new file mode 100644
index 00000000..a615564b
--- /dev/null
+++ b/gn2/wqflask/templates/news.html
@@ -0,0 +1,24 @@
+{% extends "base.html" %}
+
+{% block title %}News{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+
+{% block content %}
+
+ <div class="github-btn-container">
+ <div class="github-btn">
+ <a href="https://github.com/genenetwork/gn-docs/blob/master/general/news/news.md">
+ Edit Text
+ <img src="/static/images/edit.png">
+ </a>
+ </div>
+</div>
+<div id="markdown" class="container">
+ {{ rendered_markdown|safe }}
+
+</div>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/oauth2/create-resource.html b/gn2/wqflask/templates/oauth2/create-resource.html
new file mode 100644
index 00000000..479f4152
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/create-resource.html
@@ -0,0 +1,89 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+
+{%block title%}Create Resource{%endblock%}
+{%block css%}
+<link rel="stylesheet" type="text/css" href="/static/new/css/mytooltip.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("resources", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ {%if resource_category_error%}
+ <p>
+ <span class="glyphicon glyphicon-exclamation-sign text-danger"></span>
+ &nbsp;
+ <span class="text-danger">{{resource_category_error.error}}</span>:
+ {{resource_category_error.error_message}}
+ </p>
+ {%else%}
+ <form method="POST"
+ action="{{url_for('oauth2.resource.create_resource')}}">
+
+ <fieldset>
+ <legend>Resource Category</legend>
+ <div class="form-group">
+ {%for category in resource_categories%}
+ <div class="radio mytooltip">
+ <label for="rdo:resource_category:{{category.resource_category_id}}"
+ class="form-label"
+ style="text-transform: capitalize;">
+ <input type="radio" name="resource_category" required="required"
+ id="rdo:resource_category:{{category.resource_category_id}}"
+ value="{{category.resource_category_id}}"
+ {%if resource_category is defined%}
+ {%if category.resource_category_id == resource_category%}
+ checked="checked"
+ {%endif%}
+ {%endif%} />
+ {{category.resource_category_key}}
+ </label>
+ <span class="mytooltiptext">
+ {{category.resource_category_description}}
+ </span>
+ </div>
+ {%endfor%}
+ </div>
+ </fieldset>
+
+ <fieldset>
+ <legend>Basic Resource Information</legend>
+ <div class="form-group mytooltip">
+ <label for="resource_name" class="form-label">Name</label>
+ <input type="text" name="resource_name" class="form-control"
+ {%if resource_name is defined and resource_name is not none%}
+ value="{{resource_name}}"
+ {%endif%}
+ required="required" />
+ <span class="mytooltiptext">
+ The resource name, e.g. the experiment name.
+ </span>
+ </div>
+ </fieldset>
+
+ <fieldset>
+ <legend>Access Control</legend>
+ <div class="form-group mytooltip">
+ <label for="chk-public">Publicly Viewable?</label>
+ <input type="checkbox" name="public" id="chk-public"
+ checked="checked" />
+ <span class="mytooltiptext">
+ Select whether data in this resource will be publicly viewable.
+ </span>
+ </div>
+ </fieldset>
+
+ <input class="btn btn-primary" type="submit" value="Create" />
+
+ </form>
+ {%endif%}
+ </div>
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/create-role.html b/gn2/wqflask/templates/oauth2/create-role.html
new file mode 100644
index 00000000..f2bff7b4
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/create-role.html
@@ -0,0 +1,46 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("roles", user_privileges)}}
+ <h3>Create Role</h3>
+
+ {{flash_me()}}
+
+ {%if group_privileges_error is defined%}
+ {{display_error("Group Privileges", group_privileges_error)}}
+ {%else%}
+ {%if "group:role:create-role" in user_privileges%}
+ <form method="POST" action="{{url_for('oauth2.role.create_role')}}">
+ <legend>Create Group Role</legend>
+ <div class="form-group">
+ <label for="role_name" class="form-label">Name</label>
+ <input type="text" id="role_name" name="role_name" required="required"
+ class="form-control"
+ {%if prev_role_name is defined and prev_role_name is not none%}
+ value="{{prev_role_name}}"
+ {%endif%} />
+ </div>
+ <label class="form-label">Privileges</label>
+ {%for priv in group_privileges%}
+ <div class="checkbox">
+ <label for="chk:{{priv.privilege_id}}">
+ <input type="checkbox" id="chk:{{priv.privilege_id}}"
+ name="privileges[]" value={{priv.privilege_id}} />
+ <span style="text-transform: capitalize;">
+ {{priv.privilege_description}}
+ </span> ({{priv.privilege_id}})
+ </label>
+ </div>
+ {%endfor%}
+
+ <input type="submit" class="btn btn-primary" value="Create" />
+ </form>
+ {%else%}
+ {{display_error("Privilege", {"error":"PrivilegeError", "error_description": "You do not have sufficient privileges to create a new role."})}}
+ {%endif%}
+ {%endif%}
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/data-list-genotype.html b/gn2/wqflask/templates/oauth2/data-list-genotype.html
new file mode 100644
index 00000000..c780a583
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/data-list-genotype.html
@@ -0,0 +1,166 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+
+{%block title%}Link Data: Genotype{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container" style="width: 98%;">
+ {{profile_nav("data", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="row">
+ <noscript>This page needs javascript to work correctly</noscript>
+ </div>
+
+ <div class="row">
+ <form id="frm-link-genotypes" method="POST"
+ action="{{url_for('oauth2.data.link_genotype_data')}}">
+ <legend>Link Genotype Datasets to Group</legend>
+
+ <input type="hidden" name="species_name" value="{{species_name}}" />
+
+ <div class="form-group">
+ <label for="select-group">Group</label>
+ <select id="select-group" name="group_id" required="required"
+ class="form-control">
+ <option value="">Select group</option>
+ {%for group in groups%}
+ <option value="{{group.group_id}}">{{group.group_name}}</option>
+ {%endfor%}
+ </select>
+ </div>
+
+ <div class="form-group">
+ <table id="tbl-link-genotypes"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-selected-datasets='{{selected_datasets | list | tojson}}'>
+ <thead>
+ <tr>
+ <th>Deselect</th>
+ <th>Group</th>
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Dataset ShortName</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for dataset in selected_datasets%}
+ <tr>
+ <td>
+ <input type="checkbox" class="checkbox checkbox-selected"
+ name="selected"
+ value='{{dataset | tojson}}' />
+ </td>
+ <td>{{dataset.dataset_name}}</td>
+ <td>{{dataset.dataset_fullname}}</td>
+ <td>{{dataset.dataset_shortname}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp
+ No datasets selected for linking.
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="form-group text-center">
+ <input type="submit" value="Link Selected"
+ class="btn btn-primary"
+ style="border-top: 0.3em;"
+ {%if groups | length <= 0 or selected_datasets | length <= 0%}
+ disabled="disabled"
+ {%endif%} />
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <span id="search-messages" class="alert-danger" style="display:none"></span>
+ <form id="frm-search"
+ action="{{search_uri}}"
+ method="POST">
+ <legend>Search: Genotype</legend>
+ <input type="hidden" value="{{species_name}}" name="species"
+ id="txt-species-name" />
+ <input type="hidden" value="{{dataset_type}}" name="dataset_type"
+ id="txt-dataset-type" />
+ <input type="hidden" value="{{per_page}}" name="per_page"
+ id="txt-per-page" />
+
+ <div class="form-group">
+ <label for="txt-query">Dataset Search String</label>
+ <input type="text" id="txt-query" name="query" class="form-control"
+ value="{{query}}"/>
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <div id="search-error" class="text-danger" style="display: none;">
+ <span class="glyphicon glyphicon-exclamation-sign"></span>
+ &nbsp
+ <span id="search-error-text"></span>
+ </div>
+ <table id="tbl-genotypes"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-datasets='{{datasets | list | tojson}}'>
+ <thead>
+ <tr>
+ <th>Select</th>
+ <th>Group</th>
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Dataset ShortName</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for dataset in datasets:%}
+ <tr>
+ <td>
+ <input type="checkbox" class="checkbox checkbox-search"
+ name="search_datasets"
+ value='{{dataset | tojson}}' />
+ </td>
+ <td>{{dataset.InbredSetName}}</td>
+ <td>{{dataset.dataset_name}}</td>
+ <td>{{dataset.dataset_fullname}}</td>
+ <td>{{dataset.dataset_shortname}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp
+ No datasets available for selection.
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+
+</div>
+{%endblock%}
+
+{%block js%}
+<script src="/static/new/javascript/auth/search.js"
+ language="javascript" type="text/javascript"></script>
+<script src="/static/new/javascript/auth/search_genotypes.js"
+ language="javascript" type="text/javascript"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/data-list-mrna.html b/gn2/wqflask/templates/oauth2/data-list-mrna.html
new file mode 100644
index 00000000..0e163235
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/data-list-mrna.html
@@ -0,0 +1,168 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+
+{%block title%}Link Data: Genotype{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container" style="width: 98%;">
+ {{profile_nav("data", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="row">
+ <noscript>This page needs javascript to work correctly</noscript>
+ </div>
+
+ <div class="row">
+ <form id="frm-link" method="POST"
+ action="{{url_for('oauth2.data.link_mrna_data')}}">
+ <legend>Link mRNA Assay Datasets to Group</legend>
+
+ <input type="hidden" name="species_name" value="{{species_name}}" />
+
+ <div class="form-group">
+ <label for="select-group">Group</label>
+ <select id="select-group" name="group_id" required="required"
+ class="form-control">
+ <option value="">Select group</option>
+ {%for group in groups%}
+ <option value="{{group.group_id}}">{{group.group_name}}</option>
+ {%endfor%}
+ </select>
+ </div>
+
+ <div class="form-group">
+ <table id="tbl-link"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-datasets='{{selected_datasets | list | tojson}}'>
+ <thead>
+ <tr>
+ <th>Deselect</th>
+ <th>Group</th>
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Dataset ShortName</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for dataset in selected_datasets%}
+ <tr>
+ <td>
+ <input type="checkbox" class="checkbox checkbox-selected"
+ name="selected"
+ value='{{dataset | tojson}}' />
+ </td>
+ <td>{{dataset.dataset_name}}</td>
+ <td>{{dataset.dataset_fullname}}</td>
+ <td>{{dataset.dataset_shortname}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp
+ No datasets selected for linking.
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="form-group text-center">
+ <input type="submit" value="Link Selected"
+ class="btn btn-primary"
+ style="border-top: 0.3em;"
+ {%if groups | length <= 0 or selected_datasets | length <= 0%}
+ disabled="disabled"
+ {%endif%} />
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <span id="search-messages" class="alert-danger" style="display:none"></span>
+ <form id="frm-search"
+ action="{{search_uri}}"
+ method="POST">
+ <legend>Search: mRNA Assay</legend>
+ <input type="hidden" value="{{species_name}}" name="species"
+ id="txt-species-name" />
+ <input type="hidden" value="{{dataset_type}}" name="dataset_type"
+ id="txt-dataset-type" />
+ <input type="hidden" value="{{per_page}}" name="per_page"
+ id="txt-per-page" />
+
+ <div class="form-group">
+ <label for="txt-query">Dataset Search String</label>
+ <input type="text" id="txt-query" name="query" class="form-control"
+ value="{{query}}"/>
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <div id="search-error" class="text-danger" style="display: none;">
+ <span class="glyphicon glyphicon-exclamation-sign"></span>
+ &nbsp
+ <span id="search-error-text"></span>
+ </div>
+ <table id="tbl-search"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-datasets='{{datasets | list | tojson}}'>
+ <thead>
+ <tr>
+ <th>Select</th>
+ <th>Group</th>
+ <th>Study Name</th>
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Dataset ShortName</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for dataset in datasets:%}
+ <tr>
+ <td>
+ <input type="checkbox" class="checkbox checkbox-search"
+ name="search_datasets"
+ value='{{dataset | tojson}}' />
+ </td>
+ <td>{{dataset.InbredSetName}}</td>
+ <td>{{dataset.StudyName}}</td>
+ <td>{{dataset.dataset_name}}</td>
+ <td>{{dataset.dataset_fullname}}</td>
+ <td>{{dataset.dataset_shortname}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp
+ No datasets available for selection.
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+
+</div>
+{%endblock%}
+
+{%block js%}
+<script src="/static/new/javascript/auth/search.js"
+ language="javascript" type="text/javascript"></script>
+<script src="/static/new/javascript/auth/search_mrna.js"
+ language="javascript" type="text/javascript"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/data-list-phenotype.html b/gn2/wqflask/templates/oauth2/data-list-phenotype.html
new file mode 100644
index 00000000..8c79c0d6
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/data-list-phenotype.html
@@ -0,0 +1,209 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+
+{%block title%}Link Data: Phenotype{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("data", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="row">
+ <noscript>This page needs javascript to work correctly</noscript>
+ </div>
+
+ <div class="row">
+ <form id="frm-link-phenotypes"
+ action="{{url_for('oauth2.data.link_phenotype_data')}}"
+ method="POST">
+ <input type="hidden" value="{{species_name}}" name="species_name" />
+ <legend style="text-transform: capitalize;">
+ {{dataset_type}}: Link Traits to Group
+ </legend>
+
+ <div class="form-group">
+ <label for="select-group">Group</label>
+ <select id="select-group" name="group_id" required="required"
+ class="form-control">
+ <option value="">Select group</option>
+ {%for group in groups%}
+ <option value="{{group.group_id}}">{{group.group_name}}</option>
+ {%endfor%}
+ </select>
+ </div>
+
+ <table id="tbl-link-phenotypes"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-traits="[]">
+ <thead>
+ <tr>
+ <th>Link</th>
+ <th>Name</th>
+ <th>Group</th>
+ <th>Dataset</th>
+ <th>Dataset Fullname</th>
+ <th>Description</th>
+ <th>Authors</th>
+ <th>Year</th>
+ <th>Location</th>
+ <th>LRS</th>
+ <th>Additive</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for trait in selected%}
+ <tr>
+ <th>
+ <input type="checkbox" class="checkbox checkbox-search"
+ name="search_traits" value="{{trait | tojson}}" />
+ </th>
+ <th>{{trait.name}}</th>
+ <th>{{trait.group}}</th>
+ <th>{{trait.dataset}}</th>
+ <th>{{trait.dataset_fullname}}</th>
+ <th>{{trait.description}}</th>
+ <th>{{trait.authors | join(" ")}}</th>
+ <th>
+ <a href="{{trait.pubmed_linj}}" title="Pubmed link for trait">
+ {{trait.year}}
+ </a>
+ </th>
+ <th>CHR{{trait.geno_chr}}@{{trait.geno_mb}}</th>
+ <th>{{trait.lrs}}</th>
+ <th>{{trait.additive}}</th>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center" style="text-align: center;">
+ <br/><b><font size="4">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp;
+ There are no phenotype traits to link to the user group.
+ </font></b><br />
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+
+ <div class="form-group text-center">
+ <input type="submit" value="Link Selected"
+ class="btn btn-primary"
+ style="border-top: 0.3em;"
+ {%if groups | length <= 0 or traits | length <= 0%}
+ disabled="disabled"
+ {%endif%} />
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <span id="search-messages" class="alert-danger" style="display:none"></span>
+ <form id="frm-search-traits"
+ action="#"
+ method="POST"
+ data-gn-server-url="{{gn_server_url}}">
+ {%if dataset_type == "mrna"%}
+ <legend>mRNA: Search</legend>
+ {%else%}
+ <legend style="text-transform: capitalize;">
+ {{dataset_type}}: Search
+ </legend>
+ {%endif%}
+ <input type="hidden" value="{{species_name}}" name="species"
+ id="txt-species-name" />
+ <input type="hidden" value="{{dataset_type}}" name="dataset_type"
+ id="txt-dataset-type" />
+ <input type="hidden" value="{{per_page}}" name="per_page"
+ id="txt-per-page" />
+
+ <div class="form-group">
+ <label for="txt-query">Search</label>
+ <div class="input-group">
+ <span class="input-group-addon">species:{{species_name}} AND </span>
+ <input type="text" id="txt-query" name="query" class="form-control"
+ value="{{query}}"/>
+ </div>
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <table id="tbl-phenotypes"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-traits="{{traits | tojson}}"
+ data-initial-job-id="{{search_results.job_id}}"
+ data-initial-command-id="{{search_results.command_id}}">
+ <thead>
+ <tr>
+ <th>Select</th>
+ <th>Name</th>
+ <th>Group</th>
+ <th>Dataset</th>
+ <th>Dataset Fullname</th>
+ <th>Description</th>
+ <th>Authors</th>
+ <th>Year</th>
+ <th>Location</th>
+ <th>LRS</th>
+ <th>Additive</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for trait in traits%}
+ <tr>
+ <th>
+ <input type="checkbox" class="checkbox checkbox-search"
+ name="search_traits" value="{{trait | tojson}}" />
+ </th>
+ <th>{{trait.name}}</th>
+ <th>{{trait.group}}</th>
+ <th>{{trait.dataset}}</th>
+ <th>{{trait.dataset_fullname}}</th>
+ <th>{{trait.description}}</th>
+ <th>{{trait.authors | join(" ")}}</th>
+ <th>
+ <a href="{{trait.pubmed_linj}}" title="Pubmed link for trait">
+ {{trait.year}}
+ </a>
+ </th>
+ <th>CHR{{trait.geno_chr}}@{{trait.geno_mb}}</th>
+ <th>{{trait.lrs}}</th>
+ <th>{{trait.additive}}</th>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center" style="text-align: center;">
+ <br/><b><font size="4">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp;
+ There are no phenotype traits to select from.
+ </font></b><br />
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+</div>
+
+{%endblock%}
+
+{%block js%}
+<script language="javascript" type="text/javascript"
+ src="/static/new/javascript/auth/search.js"></script>
+<script language="javascript" type="text/javascript"
+ src="/static/new/javascript/auth/search_phenotypes.js"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/data-list.html b/gn2/wqflask/templates/oauth2/data-list.html
new file mode 100644
index 00000000..8a8f6694
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/data-list.html
@@ -0,0 +1,53 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}Link Data{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("data", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="row">
+ <form id="frm-select-datatype"
+ action="{{url_for('oauth2.data.list_data')}}"
+ method="POST">
+ <legend>Search</legend>
+ {%if species_error is defined%}
+ {{display_error("Species", species_error)}}
+ {%elif species | length == 0%}
+ <span class="glyphicon glyphicon-info-sign text-danger">
+ </span>
+ &nbsp;
+ <strong class="text-danger">No list of species to select from</strong>
+ {%else%}
+ <div class="form-group">
+ <label for="select-species">Species</label>
+ <select id="select-species" name="species_name" required="required"
+ class="form-control">
+ <option value="">Select Species</option>
+ {%for spc in species%}
+ <option value="{{spc.Name}}">
+ {{spc.MenuName}} ({{spc.FullName}})
+ </option>
+ {%endfor%}
+ </select>
+ </div>
+
+ <div class="form-group">
+ <label for="select-dataset-type">Dataset/Trait Type</label>
+ <select id="select-dataset-type" name="dataset_type"
+ required="required" class="form-control">
+ <option value="">Select dataset type</option>
+ <option value="mrna">mRNA Assay (ProbeSet) Dataset</option>
+ <option value="genotype">Genotype Dataset</option>
+ <option value="phenotype">Phenotype (Publish) Dataset</option>
+ </select>
+ </div>
+
+ <input type="submit" class="btn btn-primary" value="Search" />
+ {%endif%}
+ </form>
+ </div>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/display_error.html b/gn2/wqflask/templates/oauth2/display_error.html
new file mode 100644
index 00000000..9abe02c4
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/display_error.html
@@ -0,0 +1,10 @@
+{%macro display_error(title, the_error)%}
+
+<strong>{{title}}</strong>:
+<span class="glyphicon glyphicon-exclamation-sign text-danger">
+</span>
+&nbsp;
+<strong class="text-danger">{{the_error.error}}:</strong>
+{{the_error.error_description}}
+
+{%endmacro%}
diff --git a/gn2/wqflask/templates/oauth2/group.html b/gn2/wqflask/templates/oauth2/group.html
new file mode 100644
index 00000000..f4c29d18
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/group.html
@@ -0,0 +1,114 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("group", user_privileges)}}
+
+ {{flash_me()}}
+
+ {%if group_error is defined%}
+ <div class="row" style="text-align:center;line-height:5em;">
+ {{display_error("Group", group_error)}}
+ </div>
+ {%else%}
+ <div class="container-fluid">
+ <div class="row">
+ {%if group_join_requests_error is defined %}
+ {{display_error("Join Requests", group_join_requests_error)}}
+ {%else%}
+ <a href="{{url_for('oauth2.group.list_join_requests')}}"
+ class="btn btn-info">
+ Requests ({{group_join_requests | count}})
+ </a>
+ {%endif%}
+ </div>
+ <div class="row">
+ <table class="table">
+ <caption>Group Information</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th colspan="2" style="text-align: center;">Metadata</th>
+ <th colspan="2" style="text-align: center;">Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <tr>
+ <td rowspan="{{group.group_metadata.items() | count + 1}}">
+ {{group.group_name}}
+ </td>
+ <td><strong>Key</strong></td>
+ <td><strong>Value</strong></td>
+ <td rowspan="{{group.group_metadata.items() | count + 1}}"
+ style="text-align: center;">
+ <a href="{{url_for('oauth2.group.edit_group', group_id=group.group_id)}}"
+ class="btn btn-info" title="Edit group information">Edit</a>
+ </td>
+ <td rowspan="{{group.group_metadata.items() | count + 1}}"
+ style="text-align: center;">
+ <a href="{{url_for('oauth2.group.edit_group', group_id=group.group_id)}}"
+ class="btn btn-danger" title="Delete this group">Delete</a>
+ </td>
+ </tr>
+
+ {%for key,val in group.group_metadata.items()%}
+ <tr>
+ <td>{{key.split("_") | map("capitalize") | join(" ")}}</td>
+ <td>{{val}}</td>
+ </tr>
+ {%endfor%}
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+
+ <div class="container-fluid">
+
+ <table class="table">
+ <caption>Group Users</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Email</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for user in users%}
+ <tr>
+ <td>{{user.name}}</td>
+ <td>{{user.email}}</td>
+ <td>
+ <a href="url_for('oauth2.group.remove_user', user_id=user.user_id)"
+ title="Remove this user from being a member of this group."
+ class="btn btn-danger">Remove</a>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ {%if user_error is defined%}
+ <span class="glyphicon glyphicon-exclamation-sign text-danger">
+ </span>
+ &nbsp;
+ <strong class="text-danger">{{user_error.error}}</strong>
+ {{user_error.error_description}}
+ {%else%}
+ No users found for this group
+ {%endif%}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+
+ </div>
+ {%endif%}
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/group_join_or_create.html b/gn2/wqflask/templates/oauth2/group_join_or_create.html
new file mode 100644
index 00000000..8255d2f8
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/group_join_or_create.html
@@ -0,0 +1,99 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}Join or Create Group{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css" href="/static/new/css/mytooltip.css" />
+{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("group", user_privileges)}}
+
+ <h3>Join or Create Group</h3>
+
+ {{flash_me()}}
+
+ {%if group_join_request is defined and group_join_request.exists %}
+ <p>
+ <span class="glyphicon glyphicon-info-sign text-warning"></span>
+ &nbsp;
+ <span class="text-info">You have an active request to join a group.</span>
+ </p>
+
+ <p class="explainer">
+ You cannot create a group, or request to join a new group until your
+ currently active request has been either accepted or rejected.
+ </p>
+ {%else%}
+ <p>You can</p>
+
+ {%if groups | length > 0 %}
+ <div class="explainer">
+ <p>
+ For most users, this is the preffered choice. You request access to an
+ existing group, and the group leader will chose whether or not to add you to
+ their group.</p>
+
+ <p>You can only be a member of a single group.</p>
+ </div>
+
+ <form action="{{url_for('oauth2.user.request_add_to_group')}}"
+ method="POST">
+ <legend>Request to be added to group</legend>
+ <div class="form-group">
+ <label class="control-label" for="group">Group</label>
+ <select class="form-control" id="group" required="required" name="group">
+ <option value="">Select a group</option>
+ {%for group in groups%}
+ <option value="{{group.group_id}}">{{group.group_name}}</option>
+ {%endfor%}
+ </select>
+ </div>
+ <div class="form-group">
+ <input type="submit" value="Request Access" class="btn btn-primary" />
+ </div>
+ </form>
+
+ <p>or</p>
+ {%else%}
+ <p>
+ <span class="glyphicon glyphicon-warning-sign text-warning"></span>
+ &nbsp;
+ <span class="text-warning">There an currently no groups to join.</span>
+ </p>
+ {%endif%}
+
+ <div class="explainer">
+ <p>
+ Creating a new group automatically makes you that group's administrator.
+ </p>
+
+ <p>You can only be a member of a single group.</p>
+ </div>
+
+ <form action="{{url_for('oauth2.group.create_group')}}"
+ method="POST">
+ <legend>Create a new group</legend>
+ <div class="form-group mytooltip">
+ <label class="control-label" for="group_name">Group Name</label>
+ <input type="text" class="form-control" id="group_name"
+ name="group_name"required="required" />
+ <span class="mytooltiptext">
+ Name of the group.
+ </span>
+ </div>
+ <div class="form-group mytooltip">
+ <label class="control-label" for="group_desc">Group Description</label>
+ <textarea class="form-control" id="group_description"
+ name="group_description"></textarea>
+ <span class="mytooltiptext">
+ A description to help identify the purpose/goal of the group
+ </span>
+ </div>
+ <div class="form-group">
+ <input type="submit" value="Create Group" class="btn btn-primary" />
+ </div>
+ </form>
+ {%endif%}
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/join-requests.html b/gn2/wqflask/templates/oauth2/join-requests.html
new file mode 100644
index 00000000..833b4e93
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/join-requests.html
@@ -0,0 +1,73 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("group", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <table class="table">
+ <caption>Join Requests</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Email</th>
+ <th>Request Date/Time</th>
+ <th>Status</th>
+ <th>Message</th>
+ <th colspan="2" style="text-align: center;">Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for request in requests%}
+ <tr>
+ <td>{{request.name}}</td>
+ <td>{{request.email}}</td>
+ <td>{{datetime_string(request.timestamp)}}</td>
+ <td>{{request.status}}</td>
+ <td>{{request.message}}</td>
+ <td>
+ <form method="POST"
+ action="{{url_for('oauth2.group.accept_join_request')}}">
+ <input type="hidden" name="request_id"
+ value="{{request.request_id}}" />
+ <input type="submit" class="btn btn-primary" value="Accept"
+ {%if request.status != "PENDING"%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ <td>
+ <form method="POST"
+ action="{{url_for('oauth2.group.reject_join_request')}}">
+ <input type="hidden" name="request_id"
+ value="{{request.request_id}}" />
+ <input type="submit" class="btn btn-danger" value="Reject"
+ {%if request.status != "PENDING"%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ {%if error is defined %}
+ {{display_error("Join Requests", error)}}
+ {%else%}
+ No one has requested to join your group yet.
+ {%endif%}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/list_roles.html b/gn2/wqflask/templates/oauth2/list_roles.html
new file mode 100644
index 00000000..a4061fca
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/list_roles.html
@@ -0,0 +1,80 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("roles", user_privileges)}}
+ <h3>Roles</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <h3>Your System-Level Roles</h3>
+ <ul>
+ {%for role in roles %}
+ <li>
+ <a href="{{url_for('oauth2.role.role', role_id=role.role_id)}}"
+ title="Link to role {{role.role_name}}">{{role.role_name}}</a>
+ </li>
+ {%else%}
+ <li>
+ <span class="glyphicon glyphicon-warning-sign"></span>&nbsp;
+ <span class="text-warning">No roles attached to this user</span>
+ </li>
+ {%endfor%}
+ </ul>
+ </div>
+
+ <div class="row">
+ <h3>Group-Wide Roles</h3>
+
+ {%if "group:role:create-role" in user_privileges%}
+ <a href="{{url_for('oauth2.role.create_role')}}"
+ title="Link to create a new group role"
+ class="btn btn-info">New Group Role</a>
+ {%endif%}
+
+ {%if group_roles_error is defined%}
+ {{display_error("Group Roles", group_role_error)}}
+ {%else%}
+ <table class="table">
+ <caption>Group Roles</caption>
+ <thead>
+ <tr>
+ <th>Role Name</th>
+ <th colspan="100%">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for grole in group_roles%}
+ <tr>
+ <td>{{grole.role.role_name}}</td>
+ <td>
+ <a href="{{url_for('oauth2.group.group_role', group_role_id=grole.group_role_id)}}"
+ title="Link to role {{grole.role.role_name}}"
+ class="btn btn-info">
+ View
+ </a>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ <span class="glyphicon glyphicon-exclamation-sign text-info">
+ </span>
+ &nbsp;
+ <span class="text-info">No group roles found</span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/login.html b/gn2/wqflask/templates/oauth2/login.html
new file mode 100644
index 00000000..eaa1a192
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/login.html
@@ -0,0 +1,47 @@
+{%extends "base.html"%}
+{%block title%}Login{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ <h3>Sign in here.</h3>
+
+ <form class="form-horizontal"
+ {%if next_endpoint%}
+ action="{{url_for('oauth2.user.login', next=next_endpoint)}}"
+ {%else%}
+ action="{{url_for('oauth2.user.login')}}"
+ {%endif%}
+ method="POST" id="oauth2-login-form">
+ <fieldset>
+ <legend>Sign in with Genenetwork</legend>
+ {{flash_me()}}
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="email_address"
+ style="text-align:left;">Email</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="email_address" name="email_address" type="email"
+ {%if email%}value="{{email}}"{%endif%}
+ placeholder="your@email.address" size="50"
+ class="form-control" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="password"
+ style="text-align:left;">Password</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="password" name="password" type="password"
+ size="50" class="form-control"
+ placeholder="your password" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div style="margin-left:20px;" class="col-xs-4 controls">
+ <input type="submit" class="btn btn-primary form-control" id="submit" name="submit"
+ value="Sign in" />
+ </div>
+ </div>
+ </fieldset>
+ </form>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/masquerade.html b/gn2/wqflask/templates/oauth2/masquerade.html
new file mode 100644
index 00000000..48ec6cee
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/masquerade.html
@@ -0,0 +1,39 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}Masquerade As{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("masquerade", user_privileges)}}
+
+ {{flash_me()}}
+
+ {%if users_error is defined%}
+ {{display_error("Users", users_error)}}
+ {%else%}
+ <div class="container-fluid">
+ <div class="row">
+ <form method="POST"
+ action="{{url_for('oauth2.user.masquerade')}}">
+ <legend>Masquerade As</legend>
+ <div class="form-group">
+ <label for="select-masquerade" class="form-label">
+ Masquerade as
+ </label>
+ <select id="select-masquerade" name="masquerade_as"
+ required="required" class="form-control">
+ <option value="">Select User</option>
+ {%for user in users%}
+ <option value="{{user.user_id}}">{{user.name}} ({{user.email}})</option>
+ {%endfor%}
+ </select>
+ </div>
+ <div class="form-group">
+ <input type="submit" class="btn btn-primary" value="Masquerade" />
+ </div>
+ </form>
+ </div>
+ </div>
+ {%endif%}
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/profile_nav.html b/gn2/wqflask/templates/oauth2/profile_nav.html
new file mode 100644
index 00000000..aa752905
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/profile_nav.html
@@ -0,0 +1,64 @@
+{%macro profile_nav(calling_page, user_sys_privileges)%}
+
+<ul class="nav nav-pills">
+
+ <li role="presentation"
+ {%if calling_page == "dashboard"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.user.user_profile')}}">Dashboard</a>
+ </li>
+
+ <li role="presentation"
+ {%if calling_page == "group"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.group.user_group')}}">Group</a>
+ </li>
+
+ <li role="presentation"
+ {%if calling_page == "roles"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.role.user_roles')}}">Roles</a>
+ </li>
+
+ <li role="presentation"
+ {%if calling_page == "resources"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.resource.user_resources')}}">Resources</a>
+ </li>
+
+ {%if "system:data:link-to-group" in user_sys_privileges %}
+ <li role="presentation"
+ {%if calling_page == "data"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.data.list_data')}}">Link Data</a>
+ </li>
+ {%endif%}
+
+ {%if "system:user:masquerade" in user_sys_privileges %}
+ <li role="presentation"
+ {%if calling_page == "masquerade"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.user.masquerade')}}"
+ title="Masquerade as another user">
+ Masquerade As
+ </a>
+ </li>
+ {%endif%}
+
+ <li role="presentation">
+ {%if logged_in():%}
+ <a href="{{url_for('oauth2.user.logout')}}">Logout</a>
+ {%else%}
+ <a href="{{url_for('oauth2.user.login')}}">Login</a>
+ {%endif%}
+ </li>
+
+</ul>
+
+{%endmacro%}
diff --git a/gn2/wqflask/templates/oauth2/register_user.html b/gn2/wqflask/templates/oauth2/register_user.html
new file mode 100644
index 00000000..27ccbd30
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/register_user.html
@@ -0,0 +1,62 @@
+{%extends "base.html"%}
+{%block title%}Register New User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ <h3>Register User</h3>
+
+ <form class="form-horizontal"
+ action="{{url_for('oauth2.user.register_user')}}"
+ method="POST" id="oauth2-register-user-form">
+ <fieldset>
+ <legend>Register User</legend>
+ {{flash_me()}}
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="name"
+ style="text-align:left;">Name</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="user_name" name="user_name" type="text"
+ placeholder="Your Name" size="50"
+ class="form-control" required="required" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="email_address"
+ style="text-align:left;">Email</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="email_address" name="email_address" type="email"
+ placeholder="your@email.address" size="50"
+ class="form-control" required="required" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="password"
+ style="text-align:left;">Password</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="password" name="password" type="password"
+ size="50" class="form-control"
+ placeholder="your password" required="required" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="confirm_password"
+ style="text-align:left;">Confirm Password</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="confirm_password" name="confirm_password" type="password"
+ size="50" class="form-control" required="required"
+ placeholder="your password, again" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div style="margin-left:20px;" class="col-xs-4 controls">
+ <input type="submit" class="btn btn-primary form-control" id="submit" name="submit"
+ value="Register" />
+ </div>
+ </div>
+ </fieldset>
+ </form>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/request_error.html b/gn2/wqflask/templates/oauth2/request_error.html
new file mode 100644
index 00000000..e6ed5fff
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/request_error.html
@@ -0,0 +1,32 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("error", user_privileges)}}
+ <h3>ERROR</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+
+ <div class="row">
+ <dl>
+ <dt>Error code</dt>
+ <dd>{{response.status}}[{{response.status_code}}]</dd>
+
+ <dt>URI</dt>
+ <dd>{{response.url}}</dd>
+
+ <dt>Content Type</dt>
+ <dd>{{response.content_type or "-"}}</dd>
+
+ <dt>{{response.content}}</dt>
+ <dd>{{response.content}}</dd>
+ </dl>
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/resources.html b/gn2/wqflask/templates/oauth2/resources.html
new file mode 100644
index 00000000..c52043db
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/resources.html
@@ -0,0 +1,58 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("resources", user_privileges)}}
+ <h3>Resources</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <a href="{{url_for('oauth2.resource.create_resource')}}"
+ class="btn btn-info" title="Create a new resource">
+ Create New Resource
+ </a>
+ </div>
+
+ <div class="row">
+ <table class="table">
+ <caption>Resources</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Category</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for resource in resources %}
+ <tr>
+ <td>
+ <a href="{{url_for(
+ 'oauth2.resource.view_resource',
+ resource_id=resource.resource_id)}}"
+ title="View resource {{resource.resource_name}}">
+ {{resource.resource_name}}
+ </a>
+ </td>
+ <td>{{resource.resource_category.resource_category_key}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ <span class="glyphicon glyphicon-warning-sign"></span>&nbsp;
+ <span class="text-warning">
+ The user has no access to any resource.
+ </span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/role.html b/gn2/wqflask/templates/oauth2/role.html
new file mode 100644
index 00000000..c33c93ee
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/role.html
@@ -0,0 +1,56 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("roles", user_privileges)}}
+ <h3>Role: {{role.role_name}}</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <div class="panel panel-info">
+ <div class="panel-heading">
+ <strong>{{role.role_name}}</strong>
+ </div>
+ <div class="panel-body">
+ <table class="table">
+ <thead>
+ <tr><th>privilege id</th><th>description</th></tr>
+ </thead>
+ <tbody>
+ {%for privilege in role.privileges:%}
+ <tr>
+ <td>{{privilege.privilege_id}}</td>
+ <td>{{privilege.privilege_description}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td>
+ <span class="glyphicon glyphicon-warning-sign text-warning"></span>
+ &nbsp;
+ </td>
+ <td>
+ <span class="text-warning">No privileges found for this role.</span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+ <div class="panel-footer">
+ <p>
+ This role acts on the resource with ID:
+ <a href="{{url_for('oauth2.resource.view_resource', resource_id=resource_id)}}">
+ {{resource_id}}
+ </a>
+ </p>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/view-group-role.html b/gn2/wqflask/templates/oauth2/view-group-role.html
new file mode 100644
index 00000000..5da023bf
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/view-group-role.html
@@ -0,0 +1,102 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("roles", user_privileges)}}
+ <h3>View Group Role</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <h3>Role Details</h3>
+ {%if group_role_error is defined%}
+ {{display_error("Group Role", group_role_error)}}
+ {%else%}
+ <table class="table">
+ <caption>Details for '{{group_role.role.role_name}}' Role</caption>
+ <thead>
+ <tr>
+ <th>Privilege</th>
+ <th>Description</th>
+ <th>Action</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for privilege in group_role.role.privileges%}
+ <tr>
+ <td>{{privilege.privilege_id}}</td>
+ <td>{{privilege.privilege_description}}</td>
+ <td>
+ <form action="{{url_for(
+ 'oauth2.group.delete_privilege_from_role',
+ group_role_id=group_role.group_role_id)}}"
+ method="POST">
+ <input type="hidden" name="privilege_id"
+ value="{{privilege.privilege_id}}" />
+ <input type="submit" class="btn btn-danger"
+ value="Remove"
+ {%if not group_role.role.user_editable%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+ </div>
+
+ <div class="row">
+ <h3>Other Privileges</h3>
+ <table class="table">
+ <caption>Other Privileges not Assigned to this Role</caption>
+ <thead>
+ <tr>
+ <th>Privilege</th>
+ <th>Description</th>
+ <th>Action</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for priv in group_privileges%}
+ <tr>
+ <td>{{priv.privilege_id}}</td>
+ <td>{{priv.privilege_description}}</td>
+ <td>
+ <form action="{{url_for(
+ 'oauth2.group.add_privilege_to_role',
+ group_role_id=group_role.group_role_id)}}"
+ method="POST">
+ <input type="hidden" name="privilege_id"
+ value="{{priv.privilege_id}}" />
+ <input type="submit" class="btn btn-warning"
+ value="Add to Role"
+ {%if not group_role.role.user_editable%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ <span class="glyphicon glyphicon-info-sign text-info">
+ </span>
+ &nbsp;
+ <span class="text-info">All privileges assigned!</span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/view-resource.html b/gn2/wqflask/templates/oauth2/view-resource.html
new file mode 100644
index 00000000..275fcb24
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/view-resource.html
@@ -0,0 +1,352 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("resources", user_privileges)}}
+ <h3>Resources</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+
+ {%if resource_error is defined %}
+ {{display_error("Resource", resource_error)}}
+ {%else%}
+ <div class="row">
+ <h3>Resource Details</h3>
+ <table class="table">
+ <caption>Resource: {{resource.resource_name}}</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Category</th>
+ <th colspan="3" style="text-align: center;">Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <tr>
+ <td>{{resource.resource_name}}</td>
+ <td>{{resource.resource_category.resource_category_description}}</td>
+ <td>
+ <form method="POST"
+ action="{{url_for(
+ 'oauth2.resource.toggle_public',
+ resource_id=resource.resource_id)}}">
+
+ <div class="input-group">
+ {%if resource.public%}
+ <input type="submit" value="Make Private"
+ class="btn btn-success" />
+ {%else%}
+ <input type="submit" value="Make Public"
+ class="btn btn-danger" />
+ {%endif%}
+ </div>
+ </form>
+ </td>
+ <td>
+ <a href="{{url_for(
+ 'oauth2.resource.edit_resource',
+ resource_id=resource.resource_id)}}"
+ title="Edit resource"
+ class="btn btn-warning">Edit</a>
+ </td>
+ <td>
+ <a href="{{url_for(
+ 'oauth2.resource.delete_resource',
+ resource_id=resource.resource_id)}}"
+ title="Edit resource"
+ class="btn btn-danger">Delete</a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="row">
+ <h3>Resource Data</h3>
+ <table class="table">
+ <caption>Resource Data</caption>
+ <thead>
+ <tr>
+ {%if resource.resource_category.resource_category_key == "phenotype"%}
+ <th>Trait</th>
+ <th>Description</th>
+ <th>Year</th>
+ {%endif%}
+ <th>Dataset Name</th>
+ <th>Full Name</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for data_item in resource.resource_data:%}
+ <tr>
+ {%if resource.resource_category.resource_category_key == "phenotype"%}
+ <td>
+ <a href="/show_trait?trait_id={{data_item.PublishXRefId}}&dataset={{data_item.dataset_name}}"
+ title="Trait Data and Analysis for {{data_item.PublishXRefId}}"
+ target="_blank">
+ {{data_item.PublishXRefId}}
+ </a>
+ </td>
+ <td>{{data_item.description}}</td>
+ <td>
+ {%if data_item.PubMed_ID%}
+ <a href="https://pubmed.ncbi.nlm.nih.gov/{{data_item.PubMed_ID}}/"
+ title="{{data_item.Title}}" target="_blank">
+ {{data_item.Year}}
+ </a>
+ {%else%}
+ {{data_item.Year}}
+ {%endif%}
+ </td>
+ {%endif%}
+ <td>
+ <a href="https://gn1.genenetwork.org/webqtl/main.py?FormID=sharinginfo&GN_AccessionId={{data_item.accession_id}}&InfoPageName={{data_item.dataset_name}}"
+ title="Link to information on dataset '{{data_item.dataset_fullname}}'"
+ target="_blank">
+ {{data_item.dataset_name}}
+ </a>
+ </td>
+ <td>{{data_item.dataset_fullname}}</td>
+ <td>
+ <form action="{{url_for('oauth2.resource.unlink_data_from_resource')}}"
+ method="POST">
+ <input type="hidden" name="resource_id"
+ value="{{resource.resource_id}}" />
+ <input type="hidden" name="data_link_id"
+ value="{{data_item.data_link_id}}" />
+ <input type="submit" value="Unlink" class="btn btn-danger" />
+ </form>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="2">
+ <span class="glyphicon glyphicon-info-sign text-danger">
+ </span>
+ &nbsp;
+ <strong class="text-info">No linked data.</strong>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ <form action="{{url_for('oauth2.resource.view_resource', resource_id=resource.resource_id)}}"
+ method="GET"
+ style="width:100%;text-align:center;">
+ <input type="hidden" name="page" value="{{page}}" />
+ <input type="hidden" name="count_per_page" value="{{count_per_page}}" />
+
+ <input type="submit" name="submit" value="prev" class="btn btn-info"
+ {%if page == 1 %}disabled="disabled"{%endif%} />
+ <input type="submit" name="submit" value="next" class="btn btn-info"
+ {%if resource.resource_data | length < count_per_page %}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </div>
+
+ <div class="row">
+ <h3>Unlinked Data</h3>
+ <table class="table">
+ <caption>Link Data</caption>
+ <thead>
+ <tr>
+ {%if resource.resource_category.resource_category_key == "phenotype"%}
+ <th>Trait</th>
+ <th>Description</th>
+ <th>Year</th>
+ {%endif%}
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%if unlinked_error is defined%}
+ {{display_error("Unlinked Data Error", unlinked_error)}}
+ {%else%}
+ {%for data_item in unlinked_data:%}
+ <tr>
+ {%if resource.resource_category.resource_category_key == "phenotype"%}
+ <td>
+ <a href="/show_trait?trait_id={{data_item.PublishXRefId}}&dataset={{data_item.dataset_name}}"
+ title="Trait Data and Analysis for {{data_item.PublishXRefId}}"
+ target="_blank">
+ {{data_item.PublishXRefId}}
+ </a>
+ </td>
+ <td>{{data_item.description}}</td>
+ <td>
+ {%if data_item.PubMed_ID%}
+ <a href="https://pubmed.ncbi.nlm.nih.gov/{{data_item.PubMed_ID}}/"
+ title="{{data_item.Title}}" target="_blank">
+ {{data_item.Year}}
+ </a>
+ {%else%}
+ {{data_item.Year}}
+ {%endif%}
+ </td>
+ {%endif%}
+ <td>
+ <a href="https://gn1.genenetwork.org/webqtl/main.py?FormID=sharinginfo&GN_AccessionId={{data_item.accession_id}}&InfoPageName={{data_item.dataset_name}}"
+ title="Dataset Group: {{data_item.dataset_name}}"
+ target="_blank">
+ {{data_item.dataset_name}}
+ </a>
+ </td>
+ <td>{{data_item.dataset_fullname}}</td>
+ <td>
+ <form method="POST"
+ action="{{url_for('oauth2.resource.link_data_to_resource')}}">
+ <input type="hidden" name="resource_id"
+ value="{{resource.resource_id}}" />
+ <input type="hidden" name="data_link_id"
+ value="{{data_item.data_link_id}}" />
+ <input type="hidden" name="dataset_type"
+ value="{{resource.resource_category.resource_category_key | lower}}" />
+ <input type="submit" value="Link" class="btn btn-info"
+ {%if resource.resource_category.resource_category_description == "mRNA Dataset" and resource.resource_data | count != 0%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ </tr>
+ {%else%}
+ <span class="glyphicon glyphicon-info-sign text-info">
+ </span>
+ &nbsp;
+ <strong class="text-info">No data to link.</strong>
+ {%endfor%}
+ {%endif%}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="row">
+ <h3>User Roles</h3>
+ {%if users_n_roles_error is defined%}
+ {{display_error("Users and Roles", users_n_roles_error)}}
+ {%else%}
+ <table class="table">
+ <caption>User Roles</caption>
+ <thead>
+ <tr>
+ <th>User Email</th>
+ <th>User Name</th>
+ <th>User Group</th>
+ <th colspan="2">Assigned Roles</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for user_row in users_n_roles%}
+ <tr>
+ <td rowspan="{{user_row.roles | length + 1}}">{{user_row.user.email}}</td>
+ <td rowspan="{{user_row.roles | length + 1}}">{{user_row.user.name}}</td>
+ <td rowspan="{{user_row.roles | length + 1}}">
+ {{user_row.user_group.group_name}}</td>
+ <th>Role</th>
+ <th>Action</th>
+ </tr>
+ {%for grole in user_row.roles%}
+ <tr>
+ <td>
+ <a href="{{url_for(
+ 'oauth2.role.role',
+ role_id=grole.role_id)}}"
+ title="Details for '{{grole.role_name}}' role">
+ {{grole.role_name}}
+ </a>
+ </td>
+ <td>
+ <form action="{{url_for('oauth2.resource.unassign_role',
+ resource_id=resource.resource_id)}}"
+ method="POST">
+ <input type="hidden" name="user_id"
+ value="{{user_row.user.user_id}}" />
+ <input type="hidden" name="group_role_id"
+ value="{{grole.group_role_id}}">
+ <input type="submit"
+ value="Unassign"
+ class="btn btn-danger"
+ {%if user_row.user.user_id==this_user.user_id%}
+ disabled="disabled"
+ {%endif%}>
+ </form>
+ </td>
+ </tr>
+ {%endfor%}
+ {%else%}
+ <tr>
+ <td colspan="5">
+ <span class="glyphicon glyphicon-info-sign text-info">
+ </span>
+ &nbsp;
+ <span class="text-info">
+ There are no users assigned any role for this resource.
+ </span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+ </div>
+
+ <div class="row">
+ <h3>Assign</h3>
+ {%if group_roles_error is defined%}
+ {{display_error("Group Roles", group_roles_error)}}
+ {%elif users_error is defined%}
+ {{display_error("Users", users_error)}}
+ {%else%}
+ <form action="{{url_for(
+ 'oauth2.resource.assign_role',
+ resource_id=resource.resource_id)}}"
+ method="POST" autocomplete="off">
+ <input type="hidden" name="resource_id" value="{{resource_id}}" />
+ <div class="form-group">
+ <label for="group_role_id" class="form-label">Role</label>
+ <select class="form-control" name="group_role_id"
+ id="group_role_id" required="required">
+ <option value="">Select role</option>
+ {%for grole in group_roles%}
+ <option value="{{grole.group_role_id}}">
+ {{grole.role.role_name}}
+ </option>
+ {%endfor%}
+ </select>
+ </div>
+ <div class="form-group">
+ <label for="user-email" class="form-label">User Email</label>
+ <input list="users-list" name="user_email" class="form-control"
+ {%if users | length == 0%}
+ disabled="disabled"
+ {%endif%}
+ required="required" />
+ <datalist id="users-list">
+ {%for user in users%}
+ <option value="{{user.email}}">{{user.email}} - {{user.name}}</option>
+ {%endfor%}
+ </datalist>
+ </div>
+
+ <input type="submit" class="btn btn-primary" value="Assign"
+ {%if users | length == 0%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ {%endif%}
+ </div>
+ {%endif%}
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/view-user.html b/gn2/wqflask/templates/oauth2/view-user.html
new file mode 100644
index 00000000..34526b14
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/view-user.html
@@ -0,0 +1,48 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("dashboard", user_privileges)}}
+ <h3>View User</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ {%if user_details%}
+ <p><strong>Name</strong>: {{user_details.name}}</p>
+ <p><strong>E-Mail</strong>: {{user_details.email}}</p>
+ {%if user_details.group%}
+ <p><strong>Group</strong>:{{user_details.group.group_name}}</p>
+ {%else%}
+ <p>
+ <span class="glyphicon glyphicon-warning-sign text-warning"></span>
+ &nbsp;
+ <span class="text-warning">User is not a member of a group.</span>
+ </p>
+
+ {%if group_join_request is defined and group_join_request.exists %}
+ <p>
+ <span class="glyphicon glyphicon-info-sign text-warning"></span>
+ &nbsp;
+ <span class="text-info">You have an active join request to a group.</span>
+ </p>
+ {%else%}
+ <p><a href="{{url_for('oauth2.group.join_or_create')}}"
+ class="btn btn-primary"
+ title="Join an existing group, or create your own group">
+ Join or Create group
+ </a></p>
+ {%endif%}
+
+ {%endif%}
+ {%else%}
+ <p class="text-warning">No details found.</p>
+ {%endif%}
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/pair_scan_results.html b/gn2/wqflask/templates/pair_scan_results.html
new file mode 100644
index 00000000..dbd90bc7
--- /dev/null
+++ b/gn2/wqflask/templates/pair_scan_results.html
@@ -0,0 +1,114 @@
+{% extends "base.html" %}
+{% block title %}Pair Scan{% endblock %}
+{% block css %}
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/d3panels.min.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/pair_scan.css" />
+{% endblock %}
+
+{% block content %} <!-- Start of body -->
+
+{{ header("Mapping",
+ '{}: {}'.format(this_trait.name, this_trait.description_fmt)) }}
+
+<div id="main_div" class="container">
+ <div>
+ <h2>
+ Pair Scan
+ </h2>
+ </div>
+ <div class="qtlcharts" id="chart_container">
+ <div id="pairscan_chart"></div>
+ </div>
+ <div class="pairscan-container">
+ <h2>
+ Results
+ </h2>
+ <table cellpadding="0" cellspacing="0" border="0" id="pair_scan_results" class="table table-hover table-striped table-bordered">
+ <thead>
+ <tr>
+ <th colspan="3">Interval 1</th>
+ <th rowspan="3">LOD</th>
+ <th colspan="3">Interval 2</th>
+ </tr>
+ <tr>
+ <th rowspan="2">Position</th>
+ <th colspan="2">Flanking Markers</th>
+ <th rowspan="2">Position</th>
+ <th colspan="2">Flanking Markers</th>
+ </tr>
+ <tr>
+ <th>Proximal</th>
+ <th>Distal</th>
+ <th>Proximal</th>
+ <th>Distal</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for row in table_data %}
+ <tr>
+ <td>{{ row.pos1 }}</td>
+ <td>{{ row.proximal1 }}</td>
+ <td>{{ row.distal1 }}</td>
+ <td>{{ row.lod }}</td>
+ <td>{{ row.pos2 }}</td>
+ <td>{{ row.proximal2 }}</td>
+ <td>{{ row.distal2 }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+</div>
+
+{% endblock %}
+
+{% block js %}
+
+<script>
+ var figure_data = {{ figure_data | safe }}
+</script>
+
+<script src="https://d3js.org/d3.v7.min.js"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="/static/new/javascript/d3panels.min.js"></script>
+
+<script type="text/javascript">
+
+var data, mychart;
+
+mychart = d3panels.lod2dheatmap({
+ equalCells: true
+});
+
+mychart(d3.select('div#pairscan_chart'), figure_data);
+
+table_conf = {
+ "columns":[
+ { "width": "165px" },
+ { "width": "130px" },
+ { "width": "130px" },
+ { "width": "50px" },
+ { "width": "165px" },
+ { "width": "130px" },
+ { "width": "130px" },
+ ],
+ "sDom": "itir",
+ "autoWidth": false,
+ "bSortClasses": false,
+ "order": [[3, "desc" ]],
+ "scrollY": "100vh",
+ "scroller": true,
+ "scrollCollapse": true
+ }
+
+trait_table = $('#pair_scan_results').DataTable(table_conf);
+
+</script>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/partial_correlations/pcorrs_error.html b/gn2/wqflask/templates/partial_correlations/pcorrs_error.html
new file mode 100644
index 00000000..8d6c4bbe
--- /dev/null
+++ b/gn2/wqflask/templates/partial_correlations/pcorrs_error.html
@@ -0,0 +1,65 @@
+{% extends "base.html" %}
+{% block title %}Error: {{message}}{% endblock %}
+{% block content %}
+<!-- Start of body -->
+
+<div class="container">
+ <div class="col-md-8">
+ <div class="form-group has-error">
+ <div class="control-label" for="inputError1">
+
+ <img src="/static/gif/error/{{ error_image }}">
+
+ <h1>ERROR</h1>
+
+ <p>
+ This error is not what we wanted to see. Unfortunately errors
+ are part of all software systems and we need to resolve this
+ together.
+ </p>
+ <p>
+ <b>It is important to report this ERROR so we can fix it for everyone</b>.
+ </p>
+
+ <p>
+ Report to the GeneNetwork team by recording the steps you take
+ to reproduce this ERROR. Next to those steps, copy-paste below
+ stack trace, either as
+ a <a href="https://github.com/genenetwork/genenetwork2/issues/new">new
+ issue</a> or E-mail this full page to one of the developers
+ directly.
+ </p>
+ </div>
+
+ <p>
+ GeneNetwork error:<br />
+ {{message}}
+ </p>
+
+ {%if command_id %}
+ <p>
+ Please provide the following information to help with
+ troubleshooting:<br />
+ <strong>Command ID</strong>: <em>{{command_id}}</em>
+ </p>
+ {%endif%}
+
+ <p>
+ To check if this already a known issue, search the
+ <a href="https://github.com/genenetwork/genenetwork2/issues">issue
+ tracker</a>.
+ </p>
+
+ <a href="#Stack" class="btn btn-default" data-toggle="collapse">Toggle full stack trace</a>
+ <div id="Stack" class="collapse">
+ <pre>
+ GeneNetwork {{ version }} {% for line in stack %} {{ line }}
+ {% endfor %}
+ </pre>
+ </div>
+ </div>
+ </div>
+</div>
+
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/partial_correlations/pcorrs_poll_results.html b/gn2/wqflask/templates/partial_correlations/pcorrs_poll_results.html
new file mode 100644
index 00000000..38577c32
--- /dev/null
+++ b/gn2/wqflask/templates/partial_correlations/pcorrs_poll_results.html
@@ -0,0 +1,19 @@
+{%extends "base.html"%}
+
+{%block title%}Partial Correlations:{%endblock%}
+
+{%block css%}
+<meta http-equiv="refresh"
+ content="5;URL=/partial_correlations/{{command_id}}">
+{%endblock%}
+
+{%block content%}
+
+<div class="container">
+ <center>
+ <h1>Computing partial correlations...</h1>
+ <img src="/static/gif/waitAnima2.gif"
+ alt="Image indicating computation of partial correlations is ongoing" />
+ </center>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/partial_correlations/pcorrs_results_presentation.html b/gn2/wqflask/templates/partial_correlations/pcorrs_results_presentation.html
new file mode 100644
index 00000000..dac02397
--- /dev/null
+++ b/gn2/wqflask/templates/partial_correlations/pcorrs_results_presentation.html
@@ -0,0 +1,261 @@
+{%extends "base.html"%}
+
+{%block title%}Partial Correlations:{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css" href="/static/new/css/partial_correlations.css" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container">
+ <p>
+ <strong>Primary Trait</strong><br /><br />
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=primary['trait_name'],
+ dataset=primary['dataset_name'])}}"
+ title="Link to trait data for trait {{primary['trait_name']}}">
+ {{primary["dataset_type"]}}/{{primary["trait_name"]}}
+ [{{primary["symbol"] }} on Chr {{primary["chr"]}} @ {{primary["mb"]}}]:
+ {{primary["description"]}}
+ </a> --- FROM: {{primary["dataset_name"]}}
+ </p>
+ <p><strong>Control Traits</strong><br /><br />
+ {%for trait in controls:%}
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}"
+ title="Link to trait data for trait {{trait['trait_name']}}">
+ {{trait["dataset_type"]}}/{{trait["trait_name"]}}
+ [{{trait["symbol"] }} on Chr {{trait["chr"]}} @ {{trait["mb"]}}]:
+ {{trait["description"]}}
+ </a> --- FROM: {{trait["dataset_name"]}}<br />
+ {%endfor%}
+ </p>
+
+ <div id="partial-correlation-results">
+ {%if dataset_type == "Publish":%}
+ <table id="part-corr-results-publish"
+ class="table-hover table-striped cell-border dataTable"
+ style="float: left;">
+ <thead>
+ <tr>
+ <th>
+ </th>
+ <th>Index</th>
+ <th>Record</th>
+ <th>Phenotype</th>
+ <th>Authors</th>
+ <th>Year</th>
+ <th>N</th>
+ <th>Partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>p(partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>{%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>delta {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for idx, trait in enumerate(correlations, start=1):%}
+ <tr class="results-row">
+ <td>
+ <input type="checkbox" name="chk_{{trait['trait_name']}}"
+ value="{{trait['trait_fullname']}}" />
+ </td>
+ <td data-column-heading="Index">{{idx}}</td>
+ <td data-column-heading="Record">
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}"
+ title="Link to trait data for trait {{trait['trait_name']}}">
+ {{trait["trait_name"]}}
+ </a>
+ </td>
+ <td data-column-heading="Phenotype">
+ {{trait["post_publication_description"]}}</td>
+ <td data-column-heading="Authors">{{trait["authors"]}}</td>
+ <td data-column-heading="Year">{{trait["year"]}}</td>
+ <td data-column-heading="N">{{trait["noverlap"]}}</td>
+ <td data-column-heading="Partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("partial_corr"))}}
+ </td>
+ <td data-column-heading="p(partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("partial_corr_p_value"))}}
+ </td>
+ <td data-column-heading="{%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("corr"))}}
+ </td>
+ <td data-column-heading="p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("corr_p_value"))}}
+ </td>
+ <td data-column-heading="delta {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("delta"))}}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+
+ {%if dataset_type == "Geno":%}
+ <table id="part-corr-results-geno"
+ class="table-hover table-striped cell-border dataTable"
+ style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Locus</th>
+ <th>Chr</th>
+ <th>Megabase</th>
+ <th>N</th>
+ <th>Partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>p(partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>{%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>delta {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for idx, trait in enumerate(correlations, start=1):%}
+ <tr class="results-row">
+ <td>
+ <input type="checkbox" name="chk_{{trait['trait_name']}}"
+ value="{{trait['trait_fullname']}}" />
+ </td>
+ <td data-column-heading="Index">{{idx}}</td>
+ <td data-column-heading="Locus">
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}"
+ title="Link to trait data for trait {{trait['trait_name']}}">
+ {{trait["trait_name"]}}
+ </a>
+ </td>
+ <td data-column-heading="Chr">{{trait["chr"]}}</td>
+ <td data-column-heading="Megabase">{{trait["mb"]}}</td>
+ <td data-column-heading="N">{{trait["noverlap"]}}</td>
+ <td data-column-heading="Partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("partial_corr"))}}
+ </td>
+ <td data-column-heading="p(partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("partial_corr_p_value"))}}
+ </td>
+ <td data-column-heading="{%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("corr"))}}
+ </td>
+ <td data-column-heading="p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("corr_p_value"))}}
+ </td>
+ <td data-column-heading="delta {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("delta"))}}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+
+ {%if dataset_type == "ProbeSet":%}
+ <table id="part-corr-results-probeset"
+ class="table-hover table-striped cell-border dataTable"
+ style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Record</th>
+ <th>Gene ID</th>
+ <th>Homologene ID</th>
+ <th>Symbol</th>
+ <th>Description</th>
+ <th>Chr</th>
+ <th>Megabase</th>
+ <th>Mean Expr</th>
+ <th>N</th>
+ <th>Sample Partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>Sample p(partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>Sample {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>Sample p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>delta {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>Lit Corr</th>
+ <th>Tissue {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>Tissue p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for idx, trait in enumerate(correlations, start=1):%}
+ <tr class="results-row">
+ <td>
+ <input type="checkbox" name="chk_{{trait['trait_name']}}"
+ value="{{trait['trait_fullname']}}" />
+ </td>
+ <td data-column-heading="Index">{{idx}}</td>
+ <td data-column-heading="Record">
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}"
+ title="Link to trait data for trait {{trait['trait_name']}}">
+ {{trait["trait_name"]}}
+ </a>
+ </td>
+ <td data-column-heading="Gene ID">{{trait["geneid"]}}</td>
+ <td data-column-heading="Homologene ID">{{trait["homologeneid"]}}</td>
+ <td data-column-heading="Symbol">{{trait["symbol"]}}</td>
+ <td data-column-heading="Description">{{trait["description"]}}</td>
+ <td data-column-heading="Chr">{{trait["chr"]}}</td>
+ <td data-column-heading="Megabase">{{trait["mb"]}}</td>
+ <td data-column-heading="Mean Expr">{{trait["mean_expr"]}}</td>
+ <td data-column-heading="N">{{trait["noverlap"]}}</td>
+ <td data-column-heading="Sample Partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("partial_corr"))}}
+ </td>
+ <td data-column-heading="Sample p(partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("partial_corr_p_value"))}}
+ </td>
+ <td data-column-heading="Sample {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("corr"))}}
+ </td>
+ <td data-column-heading="Sample p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("corr_p_value"))}}
+ </td>
+ <td data-column-heading="delta {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("delta"))}}
+ </td>
+ <td data-column-heading="Lit Corr">
+ {{format_number(trait.get("l_corr"))}}
+ </td>
+ <td data-column-heading="Tissue {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("tissue_corr"))}}
+ </td>
+ <td data-column-heading="Tissue p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("tissue_p_value"))}}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+
+ </div>
+</div>
+{%endblock%}
+
+{%block js%}
+{%if step == "select-corr-method":%}
+<script type="text/javascript"
+ src="/static/new/javascript/partial_correlations.js"></script>
+<script language="javascript" type="text/javascript"
+ src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+{%endif%}
+{%endblock%}
diff --git a/gn2/wqflask/templates/partial_correlations/pcorrs_results_with_target_traits.html b/gn2/wqflask/templates/partial_correlations/pcorrs_results_with_target_traits.html
new file mode 100644
index 00000000..c1ef6001
--- /dev/null
+++ b/gn2/wqflask/templates/partial_correlations/pcorrs_results_with_target_traits.html
@@ -0,0 +1,115 @@
+{%extends "base.html"%}
+
+{%block title%}Partial Correlations:{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="{{url_for('css', filename='DataTables/css/jquery.dataTables.css')}}" />
+<link rel="stylesheet" type="text/css"
+ href="{{url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css')}}">
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+<link rel="stylesheet" type="text/css"
+ href="/static/new/css/partial_correlations.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container">
+ <p>
+ <strong>Primary Trait</strong><br /><br />
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=primary['trait_name'],
+ dataset=primary['dataset_name'])}}"
+ title="Link to trait data for trait {{primary['trait_name']}}">
+ {{primary["dataset_type"]}}/{{primary["trait_name"]}}
+ [{{primary["symbol"] }} on Chr {{primary["chr"]}} @ {{primary["mb"]}}]:
+ {{primary["description"]}}
+ </a> --- FROM: {{primary["dataset_name"]}}
+ </p>
+ <p><strong>Control Traits</strong><br /><br />
+ {%for trait in controls:%}
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}"
+ title="Link to trait data for trait {{trait['trait_name']}}">
+ {{trait["dataset_type"]}}/{{trait["trait_name"]}}
+ [{{trait["symbol"] }} on Chr {{trait["chr"]}} @ {{trait["mb"]}}]:
+ {{trait["description"]}}
+ </a> --- FROM: {{trait["dataset_name"]}}<br />
+ {%endfor%}
+ </p>
+
+ <table id="part-corr-results-publish"
+ class="table-hover table-striped cell-border dataTable">
+ <thead>
+ <tr>
+ <th>_</th>
+ <th>Index</th>
+ <th>Database</th>
+ <th>Record</th>
+ <th>Symbol</th>
+ <th>Description</th>
+ <th>N</th>
+ {%if method == "spearmans":%}
+ <th>Partial rho</th>
+ <th>p(partial rho)</th>
+ <th>rho</th>
+ <th>p(rho)</th>
+ <th>delta rho</th>
+ {%else:%}
+ <th>Partial r</th>
+ <th>p(partial r)</th>
+ <th>r</th>
+ <th>p(r)</th>
+ <th>delta r</th>
+ {%endif%}
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for idx, trait in enumerate(pcorrs, start=1):%}
+ <tr>
+ <td>
+ <input type="checkbox" name="chk_{{trait['trait_name']}}"
+ value="{{trait['trait_fullname']}}">
+ </td>
+ <td>{{idx}}</td>
+ <td>{{trait["dataset_name"]}}</td>
+ <td>
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}">
+ {{trait["trait_name"]}}
+ </a>
+ </td>
+ <td>{{trait["symbol"]}}</td>
+ <td>{{trait["description"]}}</td>
+ <td>{{trait["noverlap"]}}</td>
+ <td>{{format_number(trait["partial_corr"])}}</td>
+ <td>{{format_number(trait["partial_corr_p_value"])}}</td>
+ <td>{{format_number(trait["corr"])}}</td>
+ <td>{{format_number(trait["corr_p_value"])}}</td>
+ <td>{{format_number(trait["delta"])}}</td>
+ </tr>
+ {%else:%}
+ <tr>
+ <td colspan="12">
+ No correlations were computed
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+
+</div>
+{%endblock%}
+
+{%block js%}
+<!--
+ <script type="text/javascript"
+ src="/static/new/javascript/partial_correlations.js"></script>
+-->
+{%endblock%}
diff --git a/gn2/wqflask/templates/partial_correlations/pcorrs_select_operations.html b/gn2/wqflask/templates/partial_correlations/pcorrs_select_operations.html
new file mode 100644
index 00000000..fe7f8cd4
--- /dev/null
+++ b/gn2/wqflask/templates/partial_correlations/pcorrs_select_operations.html
@@ -0,0 +1,167 @@
+{%extends "base.html"%}
+
+{%block title%}Partial Correlations:{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="{{url_for('css', filename='DataTables/css/jquery.dataTables.css')}}" />
+<link rel="stylesheet" type="text/css"
+ href="{{url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css')}}">
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+<link rel="stylesheet" type="text/css"
+ href="/static/new/css/partial_correlations.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container">
+ <form id="pcorrs-form"
+ method="POST"
+ action="{{url_for('partial_correlations')}}">
+ {%with messages = get_flashed_messages(with_categories=true)%}
+ {%if messages:%}
+ <ul class=flashes>
+ {%for category, message in messages:%}
+ <li class="{{category}}">{{message}}</li>
+ {%endfor%}
+ </ul>
+ {%endif%}
+ {%endwith%}
+
+ <input type="hidden" value="{{trait_list_str}}" name="trait_list">
+ <h1>Partial Correlation</h1>
+ <div>Please select one primary trait, one to three control traits, and at least one target trait.</div>
+ <br />
+ <table id="pcorrs_traits_table"
+ class="table-hover table-striped cell-border dataTable"
+ role="grid">
+ <thead>
+ <tr>
+ <th>Primary (X)</th>
+ <th>Controls (Z)</th>
+ <th>Targets (Y)</th>
+ <th>Ignored</th>
+ <th>Dataset</th>
+ <th>Trait ID</th>
+ <th>Symbol</th>
+ <th>Description</th>
+ <th>Location</th>
+ <th>Mean</th>
+ <th>Max LRS</th>
+ <th>Max LRS Location Chr and Mb</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for trait in traits:%}
+ <tr>
+ <td>
+ <input type="radio" name="trait_{{trait['trait_name']}}"
+ id="trait_{{trait['trait_name']}}"
+ value="primary_{{trait['trait_name']}}" />
+ </td>
+ <td>
+ <input type="radio" name="trait_{{trait['trait_name']}}"
+ id="trait_{{trait['trait_name']}}"
+ value="controls_{{trait['trait_name']}}" />
+ </td>
+ <td>
+ <input type="radio" name="trait_{{trait['trait_name']}}"
+ id="trait_{{trait['trait_name']}}"
+ value="targets_{{trait['trait_name']}}" checked="checked" />
+ </td>
+ <td>
+ <input type="radio" name="trait_{{trait['trait_name']}}"
+ id="trait_{{trait['trait_name']}}"
+ value="ignored_{{trait['trait_name']}}" />
+ </td>
+ <td>{{trait.get("dataset", "_")}}
+ <td>{{trait.get("trait_name", "_")}}</td>
+ <td>{{trait.get("symbol", "_")}}</td>
+ <td>{{trait.get("description", "_")}}</td>
+ <td>{{trait.get("location", "_")}}</td>
+ <td>{{trait.get("mean", "_")}}</td>
+ <td>{{trait.get("lrs", "_")}}</td>
+ <td>{{trait.get("lrs_location", "_")}}</td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+
+ <br />
+ <p>Compute partial correlations for target selected above:</p>
+ <button type="submit" class="btn btn-primary" name="submit"
+ value="with_target_pearsons">
+ Pearson's r
+ </button>
+ <button type="submit" class="btn btn-primary" name="submit"
+ value="with_target_spearmans">
+ Spearman's rho
+ </button>
+
+ <hr />
+
+ <p style="color: red; font-weight: bold;">OR</p>
+ <p>Compute partial correlation for each trait in the database below:</p>
+
+ <div class="form-group">
+ <label for="corr-method-input" class="form-label">Compute</label>
+ <select id="corr-method-input" required="required" name="method"
+ class="form-control">
+ <option value="Pearson's r">Pearson's r</option>
+ <option value="Spearman's rho">Spearman's rho</option>
+ </select>
+ </div>
+
+ <div class="form-group">
+ <label for="target-db-input" class="form-label">Choose Database</label>
+ <select id="target-db-input" required="required" name="target_db"
+ class="form-control">
+ {%if target_dbs:%}
+ {%for item in target_dbs:%}
+ {%if "description" in item.keys():%}
+ <option value="{{item['value']}}">{{item['description']}}</option>
+ {%else:%}
+ {%for group, opts in item.items()%}
+ {%if opts | length > 0:%}
+ <optgroup label="{{group}} ------">
+ {%for item2 in opts:%}
+ <option value="{{item2['value']}}">{{item2['description']}}</option>
+ {%endfor%}
+ </optgroup>
+ {%endif%}
+ {%endfor%}
+ {%endif%}
+ {%endfor%}
+ {%endif%}
+ </select>
+ </div>
+
+ <div class="form-group">
+ <label for="criteria-input" class="form-label">Return</label>
+ <select id="criteria-input" required="required" name="criteria" size="1"
+ class="form-control">
+ <option value="100">top 100</option>
+ <option value="200">top 200</option>
+ <option value="500" selected="selected">top 500</option>
+ <option value="1000">top 1000</option>
+ <option value="2000">top 2000</option>
+ <option value="5000">top 5000</option>
+ <option value="10000">top 10000</option>
+ <option value="15000">top 15000</option>
+ <option value="20000">top 20000</option>
+ </select>
+ </div>
+
+ <button type="submit" class="btn btn-primary" name="submit"
+ value="Run Partial Correlations">
+ Run Partial Correlations
+ </button>
+ </form>
+</div>
+{%endblock%}
+
+{%block js%}
+<script type="text/javascript"
+ src="/static/new/javascript/partial_correlations.js"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/pca_scree_plot.html b/gn2/wqflask/templates/pca_scree_plot.html
new file mode 100644
index 00000000..74eb2c15
--- /dev/null
+++ b/gn2/wqflask/templates/pca_scree_plot.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title></title>
+</head>
+
+<body>
+ <div>
+ <h2>Scree Plot</h2>
+ <div style="padding-bottom: 10px;">Review more on <a href="https://en.wikipedia.org/wiki/Scree_plot">scree plots</a>.</div>
+ <div id="scree_plot" style="width:700px;height:600px;"></div>
+ </div>
+</body>
+<script type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script>
+<script type="text/javascript">
+js_data = {{ js_data | safe }}
+
+let { x_coord, y_coord } = js_data["scree_data"]
+
+
+const layout = {
+ yaxis: {
+ title: {
+ text: "% of Variance",
+ font: {
+ "size": 18,
+ "color": ""
+
+ }
+ }
+ },
+
+ xaxis: {
+ title: {
+ text: "Principal Components",
+ font: {
+ "size": 18,
+ "color": ""
+
+ }
+ }
+ },
+
+}
+
+const data = [{
+ x: x_coord,
+ y: y_coord,
+ marker: {
+
+ color: 'rgb(17, 157, 255)',
+ size: 5,
+ line: {
+ color: 'rgb(255, 0, 0)',
+ width: 3
+ }
+
+ }
+}]
+
+
+let custom_configs = (filename, download_format, modebar = true) => {
+
+ return {
+ displayModeBar: modebar,
+ scrollZoom: false,
+ toImageButtonOptions: {
+ filename,
+ format:download_format,
+ height: 600,
+ width: 700,
+ scale: 1
+ }
+ }
+
+}
+
+Plotly.newPlot(document.getElementById("scree_plot"), data, layout,
+ custom_configs(file_name = "scree_plot", download_format = "svg"));
+</script>
+
+</html>
diff --git a/gn2/wqflask/templates/phenotype.html b/gn2/wqflask/templates/phenotype.html
new file mode 100644
index 00000000..4f4fba6e
--- /dev/null
+++ b/gn2/wqflask/templates/phenotype.html
@@ -0,0 +1,136 @@
+{% extends "base.html" %}
+
+{% block css %}
+<style type="text/css">
+ .page-header {
+ padding: 1em;
+ }
+</style>
+{% endblock %}
+
+{% block title %}Phenotype: {{ name }}{% endblock %}
+
+{% block content %}
+
+{% set published_p = "http://rdf.ncbi.nlm.nih.gov/pubmed" in metadata.references.id %}
+
+<h1 class="page-header">
+ Phenotype: {{ metadata.traitName }} ({{ metadata.abbreviation }})
+</h1>
+
+<div class="container">
+ <table class="table">
+ <tr>
+ <td><b>Species</b></td>
+ <td>{{ metadata.species or "N/A" }}</td>
+ </tr>
+ <tr>
+ <td><b>Group</b></td>
+ <td>{{ metadata.group or "N/A" }}</td>
+ </tr>
+
+ <tr>
+ <td><b>Phenotype</b></td>
+ <td>{{ metadata.description or "N/A"}}</td>
+ </tr>
+
+ {% if metadata.creator %}
+ <tr>
+ <td><b>Authors</b></td>
+ <td>
+ {% if metadata.creator is iterable %}
+ {{ metadata.creator |join(", ") }}
+ {% for creator in metadata.creator %}
+ {{ creator }}
+ {% endfor %}
+ {% else %}
+ metadata.creator
+ {% endif %}
+ {% endif %}
+ </td>
+ </tr>
+ {% if metadata.references.id %}
+ <tr>
+ <td>
+ <b>Publication</b>
+ {% if published_p == False %}
+ <sup><small>(unpublished)</small></sup>
+ {% endif %}
+ </td>
+ <td>
+ <i>
+ {% if metadata.references.title %}
+ {{ metadata.references.title }}.
+ {% endif %}
+ </i>
+ {% if metadata.references.creator %}
+ {{ ', '.join(metadata.references.creator) }}.
+ {% endif %}
+ {{ metadata.references.year }}
+ {{ metadata.references.month }}
+ {% if metadata.references.volume and metadata.references.page %}
+ {{ metadata.references.volume }}:{{ metadata.references.page }}
+ {% endif %}
+
+ <sup>
+ <a href="{{ metadata.references.id }}" target="_blank"><small>
+ {% if published_p %}
+ PubMed
+ {% else %}
+ GN RDF Page
+ {% endif %}
+ <sup>&#32;<span class="glyphicon glyphicon-new-window"></span></sup></small></a>
+ </sup>
+ </td>
+ </tr>
+ {% endif %}
+
+ <tr>
+ <td><b>Database</b></td>
+ <td>
+ {% for database in metadata.dataset %}
+ {% set dataset_url = url_for('get_dataset', name=database.identifier)%}
+ <a href="{{ dataset_url }}" target="blank">{{ database.prefLabel }}</a> <br/>
+ {% endfor %}
+ </td>
+ </tr>
+
+ <tr>
+ <td><b>Mean</b></td>
+ <td>{{ metadata.mean or "N/A"}}</td>
+ </tr>
+
+ <tr>
+ <td><b>Peak -logP</b></td>
+ <td>{{ metadata.lodScore or "N/A"}}</td>
+ </tr>
+
+ <tr>
+ <td><b>Effect Size</b></td>
+ <td>{{ metadata.additive or "N/A"}}</td>
+ </tr>
+ {% if metadata.locus %}
+ <tr>
+ <td><b>Peak Location</b></td>
+ <td>Chr{{ metadata.locus.chromosome }}: {{ metadata.locus.mb }}</td>
+ </tr>
+ {% endif %}
+ {% if metadata.references.id %}
+ <tr>
+ <td><b>Resource Links</b></td>
+ <td>
+ <a href="{{ metadata.references.id }}" target="_blank">
+ {% if published_p %}
+ PubMed
+ {% else %}
+ GN RDF Page
+ {% endif %}
+ </a>
+ </td>
+ </tr>
+ {% endif %}
+ </table>
+</div>
+
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/policies.html b/gn2/wqflask/templates/policies.html
new file mode 100644
index 00000000..e36c9e08
--- /dev/null
+++ b/gn2/wqflask/templates/policies.html
@@ -0,0 +1,23 @@
+{% extends "base.html" %}
+
+{% block title %}Links{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+
+{% block content %}
+
+ <div class="github-btn-container">
+ <div class="github-btn ">
+ <a href="https://github.com/genenetwork/gn-docs/blob/master/general/policies/policies.md">
+ Edit Text
+ <img src="/static/images/edit.png">
+ </a>
+ </div>
+</div>
+<div id="markdown" class="container">
+ {{ rendered_markdown|safe }}
+
+</div>
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/publication.html b/gn2/wqflask/templates/publication.html
new file mode 100644
index 00000000..556d184f
--- /dev/null
+++ b/gn2/wqflask/templates/publication.html
@@ -0,0 +1,62 @@
+{% extends "base.html" %}
+
+{% block css %}
+<style type="text/css">
+ .page-header {
+ text-underline-offset: 0.5rem;
+ padding: 1em;
+ }
+
+ .panel-metadata {
+ display: inline-block;
+ width: fit-content;
+ height: fit-content;
+ padding: 0;
+ }
+
+ .panel-metadata dt {
+ color: green;
+ }
+
+ .panel-metadata dt::after {
+ content: ":";
+ }
+
+</style>
+{% endblock %}
+
+{% block title %}Title: {{metadata.title}}{% endblock %}
+
+{% block content %}
+
+<header class="page-header text-justify">
+ <h1>
+ {% if metadata.title %}
+ <u><a href="{{ metadata.id }}">{{ metadata.title}}</a></u>
+ {% else %}
+ {{ name }}
+ {% endif %}
+ </h1>
+</header>
+
+<div class="container">
+ {% if metadata == {} %}
+ <p class="lead">We appreciate your interest, but unfortunately, we don't have any additional information available for: <strong>{{ name }}</strong>. If you have any other questions or need assistance with something else, please feel free to reach out to us.</p>
+ {% else %}
+ <div class="panel-about panel panel-info panel-metadata text-muted{{ float_p }}">
+ <div class="panel-heading"><strong><span class="glyphicon glyphicon-info-sign aria-hidden=true"></span> Details</strong> </div>
+ <div class="panel-body">
+ <dl class="dl-horizontal">
+ <dt>Abstract</dt> <dd>{{ metadata.abstract or "N/A" }}</dd>
+ <dt>Journal</dt> <dd>{{ metadata.journal or "N/A" }}</dd>
+ <dt>Month</dt> <dd>{{ metadata.month or "N/A" }}</dd>
+ <dt>Page</dt> <dd>{{ metadata.pages or "N/A" }}</dd>
+ <dt>Year</dt> <dd>{{ metadata.year or "N/A" }}</dd>
+ </dl>
+ </div>
+ </div>
+ {% endif %}
+
+</div>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/references.html b/gn2/wqflask/templates/references.html
new file mode 100644
index 00000000..04e60361
--- /dev/null
+++ b/gn2/wqflask/templates/references.html
@@ -0,0 +1,19 @@
+{% extends "base.html" %}
+{% block title %}Reference{% endblock %}
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" />
+{% endblock %}
+{% block content %}
+<div class="github-btn-container">
+ <div class="github-btn">
+ <a href="https://github.com/genenetwork/gn-docs/blob/master/general/references/references.md">
+ Edit Text
+ <img src="/static/images/edit.png">
+ </a>
+ </div>
+</div>
+<div id="markdown" class="container">
+ {{ rendered_markdown|safe }}
+</div>
+
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/search_autocomplete.html b/gn2/wqflask/templates/search_autocomplete.html
new file mode 100644
index 00000000..b8d0514e
--- /dev/null
+++ b/gn2/wqflask/templates/search_autocomplete.html
@@ -0,0 +1,249 @@
+<<!DOCTYPE html>
+ <html>
+
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <title></title>
+ <link rel="stylesheet" href="">
+ </head>
+ <style type="text/css">
+ * {
+ box-sizing: border-box;
+ }
+
+ body {
+ font: 16px Arial;
+ }
+
+ .autocomplete {
+ /*the container must be positioned relative:*/
+ position: relative;
+ display: inline-block;
+ }
+
+ input {
+ border: 1px solid transparent;
+ background-color: #f1f1f1;
+ padding: 10px;
+ font-size: 16px;
+ }
+
+ input[type=text] {
+ background-color: #f1f1f1;
+ width: 100%;
+ }
+
+ input[type=submit] {
+ background-color: DodgerBlue;
+ color: #fff;
+ }
+
+
+ .search-item,
+ .autocomplete-items {
+ position: absolute;
+ border: 1px solid #d4d4d4;
+ border-bottom: none;
+ border-top: none;
+ z-index: 99;
+ /*position the autocomplete items to be the same width as the container:*/
+ top: 100%;
+ left: 0;
+ right: 0;
+ }
+
+
+ .search-item div {
+
+ background-color: red;
+
+ }
+
+ .autocomplete-items div {
+ padding: 10px;
+ cursor: pointer;
+ background-color: #fff;
+ border-bottom: 1px solid #d4d4d4;
+ }
+
+ .autocomplete-items div:hover {
+ /*when hovering an item:*/
+ background-color: #e9e9e9;
+ }
+
+ .autocomplete-active {
+ /*when navigating through the items using the arrow keys:*/
+ background-color: DodgerBlue !important;
+ color: #ffffff;
+ }
+ </style>
+
+ <body>
+ <div>
+ <h2>hello there</h2>
+ <form autocomplete="off" action="/action_page.php">
+ <div class="autocomplete" style="width:300px;">
+ <input id="myInput" type="text" name="myCountry" placeholder="search for a country">
+ </div>
+ <input type="submit">
+ </form>
+ </div>
+ <script type="text/javascript">
+ //replace with gn search hints
+ var trial_hints = ["Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Anguilla", "Antigua &amp; Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia &amp; Herzegovina", "Botswana", "Brazil", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central Arfrican Republic", "Chad", "Chile", "China", "Colombia", "Congo", "Cook Islands", "Costa Rica", "Cote D Ivoire", "Croatia", "Cuba", "Curacao", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France", "French Polynesia", "French West Indies", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guam", "Guatemala", "Guernsey"]
+
+
+ let x = document.getElementById("myInput");
+
+ x.addEventListener("focus", function() {
+
+ //recentSearches(searches)
+ });
+
+
+ function recentSearches(arr) {
+
+ console.log("calling this funciton")
+
+ let x = document.getElementById("myInput");
+
+ x.addEventListener("focus", function(e) {
+
+
+ a = document.createElement("DIV")
+
+ a.setAttribute("id", "searchitem_x");
+
+ a.setAttribute("class", "autocomplete-items");
+
+
+
+ this.parentNode.appendChild(a)
+
+ for (i = 0; i < arr.length; i++) {
+
+ console.log(arr[i])
+ b = document.createElement("DIV")
+ b.innerHTML = "<strong>" + arr[i] + "</strong>";
+ b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
+
+ b.addEventListener("click", function(e) {
+ x.value = b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
+
+ })
+
+ a.appendChild(b)
+
+
+
+
+ }
+ })
+ }
+
+ function autocomplete(inp, arr) {
+ /*the autocomplete function takes two arguments,
+ the text field element and an array of possible autocompleted values:*/
+ var currentFocus;
+ /*execute a function when someone writes in the text field:*/
+ inp.addEventListener("input", function(e) {
+ var a, b, i, val = this.value;
+ /*close any already open lists of autocompleted values*/
+ closeAllLists();
+ if (!val) { return false; }
+ currentFocus = -1;
+ /*create a DIV element that will contain the items (values):*/
+ a = document.createElement("DIV");
+ a.setAttribute("id", this.id + "autocomplete-list");
+ a.setAttribute("class", "autocomplete-items");
+ /*append the DIV element as a child of the autocomplete container:*/
+ this.parentNode.appendChild(a);
+ /*for each item in the array...*/
+ for (i = 0; i < arr.length; i++) {
+ /*check if the item starts with the same letters as the text field value:*/
+ if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
+ /*create a DIV element for each matching element:*/
+ b = document.createElement("DIV");
+ /*make the matching letters bold:*/
+ b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
+ b.innerHTML += arr[i].substr(val.length);
+ /*insert a input field that will hold the current array item's value:*/
+ b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
+ /*execute a function when someone clicks on the item value (DIV element):*/
+ b.addEventListener("click", function(e) {
+ /*insert the value for the autocomplete text field:*/
+ inp.value = this.getElementsByTagName("input")[0].value;
+ /*close the list of autocompleted values,
+ (or any other open lists of autocompleted values:*/
+ closeAllLists();
+ });
+ a.appendChild(b);
+ }
+ }
+ });
+ /*execute a function presses a key on the keyboard:*/
+ inp.addEventListener("keydown", function(e) {
+ var x = document.getElementById(this.id + "autocomplete-list");
+ if (x) x = x.getElementsByTagName("div");
+ if (e.keyCode == 40) {
+ /*If the arrow DOWN key is pressed,
+ increase the currentFocus variable:*/
+ currentFocus++;
+ /*and and make the current item more visible:*/
+ addActive(x);
+ } else if (e.keyCode == 38) { //up
+ /*If the arrow UP key is pressed,
+ decrease the currentFocus variable:*/
+ currentFocus--;
+ /*and and make the current item more visible:*/
+ addActive(x);
+ } else if (e.keyCode == 13) {
+ /*If the ENTER key is pressed, prevent the form from being submitted,*/
+ e.preventDefault();
+ if (currentFocus > -1) {
+ /*and simulate a click on the "active" item:*/
+ if (x) x[currentFocus].click();
+ }
+ }
+ });
+
+ function addActive(x) {
+ /*a function to classify an item as "active":*/
+ if (!x) return false;
+ /*start by removing the "active" class on all items:*/
+ removeActive(x);
+ if (currentFocus >= x.length) currentFocus = 0;
+ if (currentFocus < 0) currentFocus = (x.length - 1);
+ /*add class "autocomplete-active":*/
+ x[currentFocus].classList.add("autocomplete-active");
+ }
+
+ function removeActive(x) {
+ /*a function to remove the "active" class from all autocomplete items:*/
+ for (var i = 0; i < x.length; i++) {
+ x[i].classList.remove("autocomplete-active");
+ }
+ }
+
+ function closeAllLists(elmnt) {
+ /*close all autocomplete lists in the document,
+ except the one passed as an argument:*/
+ var x = document.getElementsByClassName("autocomplete-items");
+ for (var i = 0; i < x.length; i++) {
+ if (elmnt != x[i] && elmnt != inp) {
+ x[i].parentNode.removeChild(x[i]);
+ }
+ }
+ }
+ /*execute a function when someone clicks in the document:*/
+ document.addEventListener("click", function(e) {
+ closeAllLists(e.target);
+ });
+ }
+
+ autocomplete(document.getElementById("myInput"), trial_hints);
+ </script>
+ </body>
+
+ </html> \ No newline at end of file
diff --git a/gn2/wqflask/templates/search_error.html b/gn2/wqflask/templates/search_error.html
new file mode 100644
index 00000000..df8d9dff
--- /dev/null
+++ b/gn2/wqflask/templates/search_error.html
@@ -0,0 +1,20 @@
+{% extends "base.html" %}
+{% block title %}Search Results{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ {{ header("Error") }}
+
+ <div class="container">
+ <input type="hidden" name="uc_id" id="uc_id" value="{{ uc_id }}">
+ <p>You entered at least one incorrect search command, or your search term was not applicable to the dataset type.</p>
+ <p><i>Some search terms may not be applicable to Phenotype or Genotype datasets (RIF, etc)</i></p>
+ </div>
+
+ <div id="myModal"></div>
+
+<!-- End of body -->
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/search_history.html b/gn2/wqflask/templates/search_history.html
new file mode 100644
index 00000000..11586c0a
--- /dev/null
+++ b/gn2/wqflask/templates/search_history.html
@@ -0,0 +1,297 @@
+<<!DOCTYPE html>
+ <html>
+
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <title></title>
+ <link rel="stylesheet" href="">
+ </head>
+ <style type="text/css">
+ .autocomplete {
+ /*the container must be positioned relative:*/
+ position: relative;
+ display: inline-block;
+
+ /*width: 30vw; */
+ }
+
+ .search_box {
+
+ background: #Ececec;
+
+ width: 50vw;
+ /*padding:15px 20px; */
+ border-radius: 50%;
+ border: 1px solid grey;
+ /* text-align: center; */
+
+ font-size: 18px;
+
+ flex-grow: 2;
+ border: none;
+ border-radius: 50px;
+
+ height: 40px;
+
+ padding: 2px 5px;
+
+ padding-left: 40px;
+
+
+
+
+ }
+
+ .search_box:focus {
+ border: 1px solid grey;
+ }
+
+
+
+ .hint-items {
+
+ position: absolute;
+
+ border: 1px solid #d4d4d4;
+
+ z-index: 99;
+ /*position the autocomplete items to be the same width as the container:*/
+ top: 100%;
+ left: 0;
+ right: 0;
+
+ background: white;
+
+ padding: 10px;
+
+ border-radius: 40px;
+
+ padding: 10px 20px;
+
+ /*border-bottom: none; */
+
+
+ }
+
+ .search_box_hint {
+ position: absolute;
+
+ border: 1px solid #d4d4d4;
+ border-bottom: none;
+ border-top: none;
+ z-index: 99;
+ /*position the autocomplete items to be the same width as the container:*/
+ top: 100%;
+ left: 0;
+ right: 0;
+
+ background: red;
+
+ padding: 10px;
+
+ border-radius: 40px;
+
+
+ }
+
+
+ .hint_area {
+ height: px;
+
+ width: 50vw;
+
+ border-radius: 40px;
+ background: red;
+ }
+
+
+
+ .search_box_hint_input {
+ display: block;
+
+ color: white;
+
+ width: 100%;
+
+ padding: 10px 20px;
+
+ /*border-radius:20px;*/
+ border: none;
+
+ color: #000;
+
+ font-weight: bold;
+
+ font-size: 18px;
+
+ }
+
+ .search_box_hint_input {
+ border: none;
+ background-color: transparent;
+
+ text-align: inherit;
+
+ color: #101691;
+ }
+
+ .search_box_hint_input:focus,
+ .search_box_hint_input:active {
+ box-shadow: none !important;
+ -moz-box-shadow: none !important;
+ -webkit-box-shadow: none !important;
+ outline: none !important;
+ }
+
+ .search_box_hint_input:hover {
+ background-color: #dedad9;
+ }
+ </style>
+
+ <body>
+ <div>
+ <div>
+ <h3>
+ this is the title
+ </h3>
+ </div>
+ <form id="form_1">
+ <div class="autocomplete" id="autocompleteForm">
+ <input class="search_box" id="search_box_input" type="text" name="" placeholder="search value" autocomplete="off" value="">
+ </div>
+ </form>
+ </div>
+ <script type="text/javascript">
+ let cache_countries;
+
+ const search = document.getElementById("search_box_input");
+
+ const form = document.getElementById("autocompleteForm");
+
+ search.addEventListener("focus", function(event) {
+
+ console.log("hello there")
+
+
+ a = document.createElement("DIV")
+
+ a.setAttribute("class", "hint-items");
+
+
+ this.parentNode.appendChild(a)
+
+ cache_countries = retrieveSearchHistory()
+
+
+ for (let i = 0; i < cache_countries.length; i++) {
+
+ console.log(i)
+ var textfieldSelector = document.createElement("input");
+
+ textfieldSelector.type = "button";
+
+ textfieldSelector.value = `${cache_countries[i]}`;
+
+ //textfieldSelector.classList.add("search_box_hint");
+
+ textfieldSelector.classList.add("search_box_hint_input");
+
+ textfieldSelector.addEventListener("click", function(event) {
+
+ console.log("clicked this country")
+
+ search.value = cache_countries[i] // remove child element
+
+ let parent = document.getElementById("search_box_input").parentNode
+
+ parent.removeChild(this.parentNode)
+
+
+ })
+
+ a.appendChild(textfieldSelector);
+ }
+
+ document.addEventListener('click', (event) => {
+ if (!event.target.matches('#autocompleteForm, #autocompleteForm *')) {
+
+
+ const collection = document.getElementsByClassName("hint-items");
+
+ console.log(collection)
+
+ if (collection.length > 0) {
+ let parent = document.getElementById("search_box_input").parentNode
+
+ parent.removeChild(collection[0])
+ } else {
+
+ //ju
+ }
+
+ }
+ })
+
+ })
+
+ formElement = document.getElementById("form_1");
+
+ function setPlaceHolderValue() {
+ document.getElementById("search_box_input").
+ }
+
+ function onFocusHandler(event) {
+
+ }
+
+ function searchHistoryClick(event) {
+
+ }
+
+ function removeSearchHintOnclick(element) {
+
+ parentELement = document.createElement("DIV")
+ parentELement.setAttribute("class", "hint-items");
+ element.parentNode.appendChild(a)
+ searchHistory = retrieveSearchHistory()
+ }
+
+ function saveBeforeSubmit(form) {
+
+ form.addEventListener("keydown", (event) => {
+
+ if (event.keyCode === 13) {
+ event.preventDefault()
+ if (search.value) {
+ dumpSearch(search.value)
+ form.submit()
+ }
+ return;
+ }
+ })
+
+ }
+ saveBeforeSubmit(formElement)
+
+ function retrieveSearchHistory() {
+ let results = JSON.parse(localStorage.getItem("gn_search_history"))
+ return results ? results : []
+ }
+
+ function dumpSearch(search_item) {
+
+ let currentSearch = retrieveSearchHistory()
+ currentSearch.unshift(search_item)
+
+ console.log(currentSearch)
+
+ localStorage.setItem("gn_search_history", JSON.stringify(currentSearch.slice(0, 5)));
+
+ return currentSearch
+
+ }
+ </script>
+ </body>
+
+ </html> \ No newline at end of file
diff --git a/gn2/wqflask/templates/search_result_page.html b/gn2/wqflask/templates/search_result_page.html
new file mode 100644
index 00000000..cade198a
--- /dev/null
+++ b/gn2/wqflask/templates/search_result_page.html
@@ -0,0 +1,453 @@
+{% extends "base.html" %}
+{% block title %}Search Results{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/font-awesome.min.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}">
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/all.min.css') }}"/>
+ <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+ <link rel="stylesheet" type="text/css" href="static/new/css/trait_list.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div style="margin-left: 20px;">
+ <input type="hidden" name="uc_id" id="uc_id" value="{{ uc_id }}">
+
+ <div style="padding-top: 10px; padding-bottom: 10px; font-size: 16px;">
+ <!-- Need to customize text more for other types of searches -->
+
+ <p>We searched <a href="http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&{% if dataset.accession_id %}GN_AccessionId={{dataset.accession_id }}{% else %}InfoPageName={{ dataset.name }}{% endif %}">{{ dataset.fullname }}</a>
+ <br>
+ to find all records
+ {% if go_term is not none %}
+ with <span style="font-family: Courier New"><b>Gene Ontology ID</b></span> <strong>GO:{{ go_term }}</strong>.
+ {% else %}
+ {% for word in search_terms %}
+ {% if word.key|lower == "rif" %}
+ with <span style="font-family: Courier New"><b>GeneRIF</b></span> containing <strong>{{ word.search_term[0] }}</strong>{% if loop.last %}{% else %} and {% endif %}
+ {% elif word.key|lower == "go" %}
+ with <span style="font-family: Courier New"><b>Gene Ontology ID</b></span> <strong>{{ word.search_term[0] }}</strong>{% if loop.last %}{% else %} and {% endif %}
+ {% elif word.key|lower == "wiki" %}
+ with <span style="font-family: Courier New"><b>GeneWiki</b></span> containing <strong>{{ word.search_term[0] }}</strong>{% if loop.last %}{% else %} and {% endif %}
+ {% elif word.key|lower == "mean" %}
+ with <span style="font-family: Courier New"><b>mean</b></span> between <strong>{{ word.search_term[0] }}</strong> and <strong>{{ word.search_term[1] }}</strong>{% if loop.last %}{% else %} and {% endif %}
+ {% elif word.key|lower == "range" %}
+ with <span style="font-family: Courier New"><b>RANGE</b></span> between <strong>{{ word.search_term[0] }}</strong> and <strong>{{ word.search_term[1] }}</strong>{% if loop.last %}{% else %} and {% endif %}
+ {% elif word.key|lower == "lrs" or word.key|lower == "lod" or word.key|lower == "translrs" or word.key|lower == "cislrs" or word.key|lower == "translod" or word.key|lower == "cislod" %}
+ {% if word.search_term|length == 1 %}
+ with {% if word.key|lower == "translrs" %}trans{% elif word.key|lower == "cislrs" %}cis{% endif %}LRS {% if word.separator == ">" %} greater than {% elif word.separator == "<" %} less than {% elif word.separator == ">=" %} greater than or equal to {% elif word.separator == "<=" %} less than or equal to {% endif %} <strong>{{ word.search_term[0] }}</strong>{% if loop.last %}{% else %} and {% endif %}
+ {% elif word.search_term|length == 2 %}
+ with <span style="font-family: Courier New"><b>{{ word.key|upper }}</b></span> between <strong>{{ word.search_term[0] }}</strong> and <strong>{{ word.search_term[1] }}</strong>{% if loop.last %}{% else %} and {% endif %}
+ {% elif word.search_term|length == 3 %}
+ with <span style="font-family: Courier New"><b>{{ word.key|upper }}</b></span> between <strong>{{ word.search_term[0] }}</strong> and <strong>{{ word.search_term[1] }}</strong> on chromosome <strong>{{ word.search_term[2] }}</strong>{% if loop.last %}{% else %} and {% endif %}
+ {% elif word.search_term|length == 4 %}
+ with <span style="font-family: Courier New"><b>{{ word.key|upper }}</b></span> between <strong>{{ word.search_term[0] }}</strong> and <strong>{{ word.search_term[1] }}</strong> on chromosome <strong>{{ word.search_term[3] }}</strong> with an exclusion zone of <strong>{{ word.search_term[2] }}</strong> Mb
+ {% elif word.search_term|length == 5 %}
+ with <span style="font-family: Courier New"><b>{{ word.key|upper }}</b></span> between <strong>{{ word.search_term[0] }}</strong> and <strong>{{ word.search_term[1] }}</strong> on chromosome <strong>{{ word.search_term[2] }}</strong> between <strong>{{ word.search_term[3] }}</strong> and <strong>{{ word.search_term[4] }}</strong> Mb{% if loop.last %}{% else %} and {% endif %}
+ {% endif %}
+ {% elif word.key|lower == "position" or word.key|lower == "mb" %}
+ with <u>target genes</u> on chromosome <strong>{% if (word.search_term[0]|lower).split('chr')|length > 1 %}{{ (word.search_term[0]|lower).split('chr')[1] }}{% else %}{{ word.search_term[0] }}{% endif %}</strong> between <strong>{{ word.search_term[1] }}</strong> and <strong>{{ word.search_term[2] }}</strong> Mb{% if loop.last %}{% else %} and {% endif %}
+ {% else %}
+ {% if word.search_term[0] == "*" %} in the dataset.{% else %}{% if loop.first %}that match: {% endif %}<b>{{ word.search_term[0] }}</b>{% if loop.last %}{% else %} and {% endif %}{% endif %}
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+ <br>
+ {% if results|count > 0 %}
+ <b>{{ results|count }}</b> record{% if results|count > 1 %}s{% else %}{% endif %} found
+ {% else %}
+ No (<b>0</b>) records found for this search. Modify your search, check target dataset, or use <b>Search All</b> above.
+ {% endif %}
+ </p>
+
+ {% if results|count > 0 %}
+ {% if go_term is not none %}
+ <p><b>The associated genes include:</b><br><br>{% for word in search_terms %}{{ word.search_term[0] }}{% endfor %}</p>
+ {% endif %}
+
+ </div>
+ {% if too_many_results %}
+ <p>Your search generated over 50000 results. Please modify your search to generate 50000 or fewer matches.</p>
+ {% else %}
+ <div style="min-width: 1050px;">
+ <form id="trait_submission_form" target="_blank" action="/corr_matrix" method="post">
+ <input type="hidden" name="tool_used" value="" />
+ <input type="hidden" name="form_url" value="" />
+ <input type="hidden" name="trait_list" id="trait_list" value= "
+ {% for this_trait in trait_list %}
+ {{ this_trait.name }}:{{ this_trait.dataset }},
+ {% endfor %}" >
+
+ {% include 'tool_buttons.html' %}
+
+ </form>
+ </div>
+
+ <div>
+ <br />
+ <form id="export_form" method="POST" action="/export_traits_csv" style="display: inline;">
+ <div style="min-width: 950px;">
+ <input type="hidden" name="headers" id="headers" value="{% for field in header_fields %}{{ field }},{% endfor %}">
+ <input type="hidden" name="search_string" id="search_string" value="{{ original_search_string }}">
+ <input type="hidden" name="database_name" id="database_name" value="{{ dataset.fullname }}">
+ <input type="hidden" name="file_name" id="file_name" value="search_results">
+ <input type="hidden" name="filter_term" id="filter_term" value="None">
+ {% if dataset.accession_id %}
+ <input type="hidden" name="accession_id" id="accession_id" value="{{ dataset.accession_id }}">
+ {% endif %}
+ <input type="hidden" name="export_data" id="export_data" value="">
+ <input type="text" id="searchbox" class="form-control" style="width: 200px; display: inline;" placeholder="Search For...">
+ <button class="btn btn-success" id="add" type="button" disabled><span class="glyphicon glyphicon-plus-sign"></span> Add</button>
+ <button class="btn btn-default" id="select_all" type="button"><span class="glyphicon glyphicon-ok"></span> Select All</button>
+ <input type="text" id="select_top" class="form-control" style="width: 200px; display: inline;" placeholder="Select Rows (1-5, 11)">
+ <button class="btn btn-default" id="export_traits"><span class="glyphicon glyphicon-download-alt"></span> Download</button>
+ <button class="btn btn-default" id="invert" type="button"><span class="glyphicon glyphicon-adjust"></span> Invert</button>
+ <button class="btn btn-default" id="deselect_all" type="button"><span class="glyphicon glyphicon-remove"></span> Deselect</button>
+ </div>
+ <div id="select_samples_invalid" class="alert alert-error" style="display:none;">
+ Please check that your syntax includes only a combination of integers, dashes, and commas of a format
+ similar to <strong>1,5,10</strong> or <strong>2, 5-10, 15</strong>, etc.
+ </div>
+ </form>
+ {% if dataset.type != 'Geno' %}
+ <div class="show-hide-container">
+ <b>Show/Hide Columns:&nbsp;&nbsp;</b>
+ {% if dataset.type == 'ProbeSet' %}
+ <button class="toggle-vis" data-column="3">Symbol</button>
+ <button class="toggle-vis" data-column="4">Description</button>
+ <button class="toggle-vis" data-column="5">Location</button>
+ <button class="toggle-vis" data-column="6">Mean</button>
+ <button class="toggle-vis" data-column="7">Peak -logP</button>
+ <button class="toggle-vis" data-column="8">Peak Location</button>
+ <button class="toggle-vis" data-column="9">Effect Size</button>
+ {% elif dataset.type == 'Publish' %}
+ <button class="toggle-vis" data-column="3">Description</button>
+ <button class="toggle-vis" data-column="4">Mean</button>
+ <button class="toggle-vis" data-column="5">Authors</button>
+ <button class="toggle-vis" data-column="6">Year</button>
+ <button class="toggle-vis" data-column="7">Peak -logP</button>
+ <button class="toggle-vis" data-column="8">Peak Location</button>
+ <button class="toggle-vis" data-column="9">Effect Size</button>
+ {% endif %}
+ </div>
+ {% endif %}
+ <div id="trait_table_container" style="{% if dataset.type == 'Geno' %}width: 450px;{% else %}width: 90%; min-width: 1250px;{% endif %}">
+ <table class="table-hover table-striped cell-border" id='trait_table' style="float: left;">
+ <tbody>
+ <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endif %}
+ {% else %}
+ <br>
+ <button type="button" onclick="window.location.href='/'">Return To Search</button>
+ {% endif %}
+ </div>
+ <div id="myModal"></div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/buttons.colVis.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='fontawesome/js/all.min.js') }}"></script>
+
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/partial_correlations.js"></script>
+
+ <script type='text/javascript'>
+ var traitsJson = {{ trait_list|safe }};
+ </script>
+
+ <script type="text/javascript" charset="utf-8">
+ $(document).ready( function () {
+
+ var getParams = function(url) {
+ let parser = document.createElement('a');
+ parser.href = url;
+ let params = parser.search.substring(1);
+ if(params.length > 0) {
+ return ('?'+params);
+ }
+ return params;
+ };
+
+ {% if results|count > 0 and not too_many_results %}
+ var tableId = "trait_table";
+
+ var widthChange = 0; //ZS: For storing the change in width so overall table width can be adjusted by that amount
+
+ columnDefs = [
+ {
+ 'data': null,
+ 'width': "5px",
+ 'orderDataType': "dom-checkbox",
+ 'targets': 0,
+ 'render': function(data) {
+ return '<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + data.hmac + '" data-trait-info="' + data.trait_info_str + '">'
+ }
+ },
+ {
+ 'title': "Index",
+ 'type': "natural",
+ 'width': "35px",
+ "searchable": false,
+ "orderable": false,
+ 'targets': 1,
+ 'data': "index"
+ }
+ {% if dataset.type == 'ProbeSet' %},
+ {
+ 'title': "Record",
+ 'type': "natural-minus-na",
+ 'data': null,
+ 'width': "{{ max_widths.display_name * 8 }}px",
+ 'targets': 2,
+ 'render': function(data) {
+ return '<a target="_blank" href="/show_trait?trait_id=' + data.display_name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>'
+ }
+ },
+ {
+ 'title': "Symbol",
+ 'type': "natural",
+ 'width': "{{ max_widths.symbol * 8 }}px",
+ 'targets': 3,
+ 'data': "symbol"
+ },
+ {
+ 'title': "Description",
+ 'type': "natural",
+ 'data': null,
+ 'targets': 4,
+ 'render': function(data) {
+ description = data.description
+ if (data.description.length > 200) {
+ description = data.description.slice(0, 200) + '...'
+ }
+ try {
+ return decodeURIComponent(escape(description))
+ } catch(err){
+ return escape(description)
+ }
+ }
+ },
+ {
+ 'title': "<div style='text-align: right;'>Location</div>",
+ 'type': "natural-minus-na",
+ 'width': "130px",
+ 'targets': 5,
+ 'data': "location"
+ },
+ {
+ 'title': "<div style='text-align: right;'>Mean</div>",
+ 'type': "natural-minus-na",
+ 'width': "40px",
+ 'data': "mean",
+ 'targets': 6,
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Peak</div> <div style='text-align: right;'>-logP <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>",
+ 'type': "natural-minus-na",
+ 'data': "lod_score",
+ 'width': "60px",
+ 'targets': 7,
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "<div style='text-align: right;'>Peak Location</div>",
+ 'type': "natural-minus-na",
+ 'width': "130px",
+ 'targets': 8,
+ 'data': "lrs_location"
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Effect</div> <div style='text-align: right;'>Size <a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>",
+ 'type': "natural-minus-na",
+ 'data': "additive",
+ 'width': "65px",
+ 'targets': 9,
+ 'orderSequence': [ "desc", "asc"]
+ }{% elif dataset.type == 'Publish' %},
+ {
+ 'title': "Record",
+ 'type': "natural-minus-na",
+ 'width': "{{ max_widths.display_name * 9 }}px",
+ 'data': null,
+ 'targets': 2,
+ 'render': function(data) {
+ return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>'
+ }
+ },
+ {
+ 'title': "Description",
+ 'type': "natural",
+ 'data': null,
+ 'targets': 3,
+ 'render': function(data) {
+ description = data.description
+ if (data.description.length > 200) {
+ description = data.description.slice(0, 200) + '...'
+ }
+ try {
+ return decodeURIComponent(escape(description))
+ } catch(err){
+ return escape(description)
+ }
+ }
+ },
+ {
+ 'title': "<div style='text-align: right;'>Mean</div>",
+ 'type': "natural-minus-na",
+ 'width': "60px",
+ 'data': "mean",
+ 'targets': 4,
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "Authors",
+ 'type': "natural",
+ {% if (max_widths.authors * 5) < 500 %}
+ 'width': "{{ max_widths.authors * 5 }}px",
+ {% else %}
+ 'width': "500px",
+ {% endif %}
+ 'data': "authors_display",
+ 'targets': 5
+ },
+ {
+ 'title': "<div style='text-align: right;'>Year</div>",
+ 'type': "natural-minus-na",
+ 'data': null,
+ 'width': "50px",
+ 'targets': 6,
+ 'render': function(data) {
+ if (data.pubmed_id != "N/A"){
+ return '<a href="' + data.pubmed_link + '">' + data.pubmed_text + '</a>'
+ } else {
+ return data.pubmed_text
+ }
+ },
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Peak</div> <div style='text-align: right;'>-logP <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>",
+ 'type': "natural-minus-na",
+ 'data': "lod_score",
+ 'targets': 7,
+ 'width': "60px",
+ 'orderSequence': [ "desc", "asc"]
+ },
+ {
+ 'title': "<div style='text-align: right;'>Peak Location</div>",
+ 'type': "natural-minus-na",
+ 'width': "125px",
+ 'targets': 8,
+ 'data': "lrs_location"
+ },
+ {
+ 'title': "<div style='text-align: right; padding-right: 10px;'>Effect</div> <div style='text-align: right;'>Size <a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>",
+ 'type': "natural-minus-na",
+ 'width': "60px",
+ 'data': "additive",
+ 'targets': 9,
+ 'orderSequence': [ "desc", "asc"]
+ }{% elif dataset.type == 'Geno' %},
+ {
+ 'title': "Record",
+ 'type': "natural-minus-na",
+ 'width': "{{ max_widths.display_name * 9 }}px",
+ 'data': null,
+ 'targets': 2,
+ 'render': function(data) {
+ return '<a target="_blank" href="/show_trait?trait_id=' + data.display_name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>'
+ }
+ },
+ {
+ 'title': "<div style='text-align: right;'>Location</div>",
+ 'type': "natural-minus-na",
+ 'width': "125px",
+ 'targets': 2,
+ 'data': "location"
+ }{% endif %}
+ ];
+
+ tableSettings = {
+ "createdRow": function ( row, data, index ) {
+ $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;");
+ $('td', row).eq(1).attr("align", "right");
+ $('td', row).eq(1).attr('data-export', index+1);
+ $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text());
+ {% if dataset.type == 'ProbeSet' %}
+ $('td', row).eq(3).attr('title', $('td', row).eq(3).text());
+ $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text());
+ if ($('td', row).eq(3).text().length > 20) {
+ $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 20));
+ $('td', row).eq(3).text($('td', row).eq(3).text() + '...')
+ }
+ $('td', row).eq(4).attr('title', $('td', row).eq(4).text());
+ $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text());
+ if ($('td', row).eq(4).text().length > 500) {
+ $('td', row).eq(4).text($('td', row).eq(4).text().substring(0, 500));
+ $('td', row).eq(4).text($('td', row).eq(4).text() + '...')
+ }
+ $('td', row).slice(5,10).attr("align", "right");
+ $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text());
+ $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text());
+ $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text());
+ $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text());
+ $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text());
+ {% elif dataset.type == 'Publish' %}
+ $('td', row).eq(3).attr('title', $('td', row).eq(3).text());
+ $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text());
+ if ($('td', row).eq(3).text().length > 500) {
+ $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 500));
+ $('td', row).eq(3).text($('td', row).eq(3).text() + '...')
+ }
+ $('td', row).eq(4).attr('title', $('td', row).eq(4).text());
+ $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text());
+ $('td', row).eq(4).attr('align', 'right');
+ $('td', row).slice(6,10).attr("align", "right");
+ $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text());
+ $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text());
+ $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text());
+ $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text());
+ $('td', row).eq(9).attr('data-export', $('td', row).eq(8).text());
+ {% elif dataset.type == 'Geno' %}
+ $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text());
+ {% endif %}
+ },
+ "order": [[1, "asc" ]],
+ "autoWidth": true,
+ {% if trait_list|length > 10 %}
+ "scrollY": "1000px",
+ "scroller": true,
+ "scrollCollapse":true
+ {% else %}
+ "scroller": false
+ {% endif %}
+ }
+
+ create_table(tableId, traitsJson, columnDefs, tableSettings)
+ {% endif %}
+
+ submit_special = function(url) {
+ $("#trait_submission_form").attr("action", url);
+ return $("#trait_submission_form").submit();
+ };
+
+ });
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/set_group_privileges.html b/gn2/wqflask/templates/set_group_privileges.html
new file mode 100644
index 00000000..a0a53292
--- /dev/null
+++ b/gn2/wqflask/templates/set_group_privileges.html
@@ -0,0 +1,77 @@
+{% extends "base.html" %}
+{% block title %}Set Group Privileges{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <div class="container">
+ <h1>Group Privileges</h1>
+ <br>
+ <form id="set_group_privileges">
+ <input type="hidden" name="resource_id" value="{{ resource_id }}">
+ <div style="min-width: 600px; max-width: 800px;">
+ <button type="submit" class="btn btn-primary" style="margin-bottom: 40px;">Add Group</button>
+ <hr>
+ <h2>Data and Metadata Privileges</h2>
+ <table id="data_privileges_table" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>No-Access</th>
+ <th>View</th>
+ <th>Edit</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Data:</td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="data_privilege" VALUE="no-access" checked></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="data_privilege" VALUE="view"></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="data_privilege" VALUE="edit"></td>
+ </tr>
+ <tr>
+ <td>Metadata:</td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="metadata_privilege" VALUE="no-access" checked></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="metadata_privilege" VALUE="view"></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="metadata_privilege" VALUE="edit"></td>
+ </tr>
+ </tbody>
+ </table>
+ <hr>
+ <h2>Admin Privileges</h2>
+ <table id="admin_privileges_table" class="table-hover table-striped cell-border" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Not Admin</th>
+ <th>Edit Access</th>
+ <th>Edit Admins</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Admin:</td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="admin_privilege" VALUE="not-admin" checked></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="admin_privilege" VALUE="edit-access"></td>
+ <td align="center" style="padding: 0px;"><input type="radio" name="admin_privilege" VALUE="edit-admins"></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </form>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script>
+ $('#data_privileges_table').dataTable();
+ $('#admin_privileges_table').dataTable();
+ </script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/show_image.html b/gn2/wqflask/templates/show_image.html
new file mode 100644
index 00000000..521f5414
--- /dev/null
+++ b/gn2/wqflask/templates/show_image.html
@@ -0,0 +1,5 @@
+<img alt="Embedded Image" src="data:image/png;base64,
+{% for elem in img_base64 -%}
+ {% print("%c"|format(elem)) %}
+{%- endfor %}
+" /> \ No newline at end of file
diff --git a/gn2/wqflask/templates/show_trait.html b/gn2/wqflask/templates/show_trait.html
new file mode 100644
index 00000000..dd054ffc
--- /dev/null
+++ b/gn2/wqflask/templates/show_trait.html
@@ -0,0 +1,276 @@
+{% extends "base.html" %}
+{%from "oauth2/display_error.html" import display_error%}
+
+{% block title %}Trait Data and Analysis{% endblock %}
+
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="/static/new/css/bar_chart.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/box_plot.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/prob_plot.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/scatter-matrix.css" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='nouislider/nouislider.min.css') }}" />
+ <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+
+{% endblock %}
+
+{% block content %} <!-- Start of body -->
+
+ {{flash_me()}}
+ {%if "group:resource:view-resource" in trait_privileges or "system:resource:public-read" in trait_privileges%}
+ <div class="container">
+ <h2>Trait Data and Analysis for <b>{{ this_trait.display_name }}</b></h2>
+ {% if this_trait.dataset.type != 'Publish' %}
+ <h3>
+ {% set trait_description = this_trait.description_fmt[0]|upper + this_trait.description_fmt[1:]|safe %}
+ {% if trait_description|length < 100 %}
+ {{ trait_description }}
+ {% else %}
+ <span class="truncDesc" style="display: block;">{{ trait_description[:99] }}... (<a onclick="toggleDescription()" href="#">Show More</a>)</span><span class="fullDesc" style="display: none;">{{ trait_description }} (<a onclick="toggleDescription()" href="#">Show Less</a>)</span>
+ {% endif %}
+ </h3>
+ {% endif %}
+
+ <form method="post" action="" target="_blank" name="trait_page" id="trait_data_form" class="form-horizontal">
+ <div id="hidden_inputs">
+ <input type="hidden" name="trait_hmac" value="{{ data_hmac('{}:{}'.format(this_trait.name, dataset.name)) }}">
+ {% for key in hddn %}
+ <input type="hidden" name="{{ key }}" value="{{ hddn[key] }}">
+ {% endfor %}
+ </div>
+
+ <input type="hidden" name="temp_uuid" id="temp_uuid" value="{{ temp_uuid }}">
+ <input type="hidden" name="tool_used" value="">
+ <input type="hidden" name="form_url" value="">
+ <input type="hidden" name="wanted_inputs" value="">
+ <input type="hidden" name="genofile" value="">
+ <input type="hidden" name="covariates" value="">
+ <input type="hidden" name="transform" value="">
+ <input type="hidden" name="sample_vals" value="">
+
+ <div class="container">
+ <div class="panel-group" id="accordion">
+ <div class="panel panel-default">
+ <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseOne" aria-expanded="true">
+ <h3 class="panel-title">
+ <span class="glyphicon glyphicon-chevron-down"></span> Details and Links
+ </h3>
+ </div>
+ <div id="collapseOne" class="panel-collapse collapse" aria-expanded="true">
+ <div class="panel-body">
+ {% include 'show_trait_details.html' %}
+ </div>
+ </div>
+ </div>
+ <div class="panel panel-default">
+ <div class="panel-heading stats_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapseTwo">
+ <h3 class="panel-title">
+ <span class="glyphicon glyphicon-chevron-down"></span> Statistics
+ </h3>
+ </div>
+ <div id="collapseTwo" class="panel-collapse collapse in">
+ <div class="panel-body">
+ {% include 'show_trait_statistics.html' %}
+ </div>
+ </div>
+ </div>
+ <div class="panel panel-default">
+ <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseThree">
+ <h3 class="panel-title">
+ <span class="glyphicon glyphicon-chevron-down"></span> Transform and Filter Data
+ </h3>
+ </div>
+ <div id="collapseThree" class="panel-collapse collapse in">
+ <div class="panel-body">
+ {% include 'show_trait_transform_and_filter.html' %}
+ </div>
+ <div id="transform_alert_placeholder"><div id="transform_alert" style="display: none;"class="alert alert-success outlier-alert"><a href="#" class="close" data-dismiss="alert">�</a><span>Because there are some values between 0 and 1, log2 and log10 transforms will add 1 to each value.</span></div></div>
+ </div>
+ </div>
+ <div class="panel panel-default">
+ <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseFour">
+ <h3 class="panel-title">
+ <span class="glyphicon glyphicon-chevron-down"></span> Calculate Correlations
+ </h3>
+ </div>
+ <div id="collapseFour" class="panel-collapse collapse in">
+ <div class="panel-body">
+ {% include 'show_trait_calculate_correlations.html' %}
+ </div>
+ </div>
+ </div>
+ <div class="panel panel-default">
+ <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseFive">
+ <h3 class="panel-title">
+ <span class="glyphicon glyphicon-chevron-down"></span> Mapping Tools
+ </h3>
+ </div>
+ <div id="collapseFive" class="panel-collapse collapse in">
+ <div class="panel-body">
+ {% include 'show_trait_mapping_tools.html' %}
+ </div>
+ <div id="outlier_alert_placeholder"></div>
+ </div>
+ </div>
+ <div class="panel panel-default" {%if (trait_table_width|int > 1100)%}style="min-width: {{trait_table_width|int + 30}}px;"{% endif %}>
+ <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseSix" aria-expanded="true">
+ <h3 class="panel-title">
+ <span class="glyphicon glyphicon-chevron-up"></span> Review and Edit Data
+ </h3>
+ </div>
+ <div id="collapseSix" class="panel-collapse collapse" aria-expanded="true">
+ <div class="panel-body">
+ {% include 'show_trait_edit_data.html' %}
+ </div>
+ </div>
+ </div>
+ </div>
+ {% include 'show_trait_progress_bar.html' %}
+ </div>
+ </form>
+ </div>
+ {%else%}
+ {%if user.name == "Anonymous User"%}
+ {{display_error("Access Denied", {"error": "AuthorisationError", "error_description": "This trait is not accessible for the general public yet. Please log in."})}}
+ {%else%}
+ {{display_error("Access Denied", {"error": "AuthorisationError", "error_description": "The user '" + user.name + "', does not currently possess the appropriate privileges to view this trait. If you know the owner of this trait, please request that they grant you access, or wait until it is made public."})}}
+ {%endif%}
+ {%endif%}
+
+ <!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script>
+ js_data = {{ js_data | safe }}
+ $('.collapse').collapse()
+ </script>
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='underscore-string/underscore.string.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/jstat.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='shapiro-wilk/shapiro-wilk.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/colorbrewer.js"></script>
+
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/stats.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/scatter-matrix.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/plotly_probability_plot.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/compare_traits_scatterplot.js"></script>
+
+
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='nouislider/nouislider.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/initialize_show_trait_tables.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/show_trait_mapping_tools.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/show_trait.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/validation.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/get_covariates_from_collection.js"></script>
+
+ <script type="text/javascript" charset="utf-8">
+
+ $.fn.dataTable.ext.order['dom-checkbox'] = function ( settings, col )
+ {
+ return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
+ return $('input', td).prop('checked') ? '1' : '0';
+ } );
+ };
+
+ function getValue(x) {
+ if (x == 'x') {
+ return "x";
+ }
+ else {
+ return parseFloat(x);
+ }
+ }
+
+ $.fn.dataTable.ext.order['dom-input'] = function (settings, col) {
+ return this.api().column(col, { order: 'index' }).nodes().map(function (td, i) {
+ return $('input', td).val();
+ });
+ }
+
+ $.fn.dataTableExt.oSort['cust-txt-asc'] = function (a, b) {
+ var x = getValue(a);
+ var y = getValue(b);
+
+ if (x == 'x' || x === '') {
+ return 1;
+ }
+ else if (y == 'x' || y === '') {
+ return -1;
+ }
+ else {
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+ }
+ };
+
+ $.fn.dataTableExt.oSort['cust-txt-desc'] = function (a, b) {
+ var x = getValue(a);
+ var y = getValue(b);
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
+ };
+
+ $(document).ready( function () {
+ $('.panel-heading').click(function () {
+ if ($(this).hasClass('collapsed')){
+ $(this).find('.glyphicon-chevron-down').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-up');
+ }
+ else {
+ $(this).find('.glyphicon-chevron-up').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
+ }
+ });
+
+ $('#samples_primary, #samples_other').find("tr.outlier").css('background-color', 'orange')
+
+ $('.edit_sample_checkbox:checkbox').change(function() {
+ if ($(this).is(":checked")) {
+ if (!$(this).closest('tr').hasClass('selected')) {
+ $(this).closest('tr').addClass('selected')
+ }
+ }
+ else {
+ if ($(this).closest('tr').hasClass('selected')) {
+ $(this).closest('tr').removeClass('selected')
+ }
+ }
+ });
+
+ var slider = document.getElementById('p_range_slider');
+ noUiSlider.create(slider, {
+ start: [-1.0, 1.0],
+ range: {
+ 'min': [-1.0],
+ 'max': [1.0]
+ }
+ });
+
+ var slider_display = [
+ document.getElementById('p_range_lower'),
+ document.getElementById('p_range_upper')
+ ];
+ var slider_values = [
+ $('input[name=p_range_lower]'),
+ $('input[name=p_range_upper]')
+ ];
+
+ slider.noUiSlider.on('update', function( values, handle ) {
+ slider_display[handle].innerHTML = values[handle];
+ slider_values[handle].val(values[handle]);
+ });
+ });
+ </script>
+
+{% endblock %}
diff --git a/gn2/wqflask/templates/show_trait_calculate_correlations.html b/gn2/wqflask/templates/show_trait_calculate_correlations.html
new file mode 100644
index 00000000..22fe6142
--- /dev/null
+++ b/gn2/wqflask/templates/show_trait_calculate_correlations.html
@@ -0,0 +1,165 @@
+<div class="main">
+ <div class="col-xs-3 options">
+ <div class="form-horizontal section-form-div">
+
+ <div class="form-group">
+ <label for="corr_type" class="col-xs-2 control-label">Method</label>
+ <div class="col-xs-3 controls">
+ <select name="corr_type" class="form-control">
+ <option value="sample">Sample r</option>
+ {% if dataset.type == 'ProbeSet' %}
+ <option value="lit">Literature r</option>
+ <option value="tissue">Tissue r</option>
+ {% endif %}
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="corr_dataset" class="col-xs-2 control-label">Database</label>
+ <div class="col-xs-10 controls">
+ <select name="corr_dataset" class="form-control">
+ {% for tissue in corr_tools.dataset_menu %}
+ {% if tissue.tissue %}
+ <optgroup label="{{ tissue.tissue }} ------">
+ {% endif %}
+ {% for dataset in tissue.datasets %}
+ <option data-type="{% if tissue.tissue %}mrna_assay{% elif dataset[1][-4:] == 'Geno' %}geno{% else %}pheno{% endif %}" value="{{ dataset[1] }}"
+ {% if corr_tools.dataset_menu_selected == dataset[1] %}
+ selected
+ {% endif %}>
+ {{ dataset[0] }}
+ </option>
+ {% endfor %}
+ {% if tissue.tissue %}
+ </optgroup>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="corr_return_results" class="col-xs-2 control-label">Limit to</label>
+ <div class="col-xs-4 controls">
+ <select name="corr_return_results" class="form-control">
+ {% for return_result in corr_tools.return_results_menu %}
+ <option value="{{ return_result }}"
+ {% if corr_tools.return_results_menu_selected == return_result %}
+ selected
+ {% endif %}>
+ Top {{ return_result }}
+ </option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="corr_samples_group" class="col-xs-2 control-label">Samples</label>
+ <div class="col-xs-4 controls">
+ <select name="corr_samples_group" class="form-control">
+ {% for group, pretty_group in sample_group_types.items() %}
+ <option value="{{ group }}">{{ pretty_group }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+
+ <div id="corr_sample_method" class="form-group">
+ <label for="corr_sample_method" class="col-xs-2 control-label">Type</label>
+ <div class="col-xs-4 controls">
+ <select name="corr_sample_method" class="form-control">
+ <option value="pearson">Pearson</option>
+ <option value="spearman">Spearman Rank</option>
+ </select>
+ </div>
+ </div>
+ <div id="min_expr_filter" class="form-group" style="display: {% if dataset.type != 'Geno' %}block{% else %}none{% endif %};">
+ <label class="col-xs-2 control-label">Min Expr</label>
+ <div class="col-xs-4 controls">
+ <input name="min_expr" value="" type="text" class="form-control min-expr-field">
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="location_type" class="col-xs-2 control-label">Location Type</label>
+ <div class="col-xs-4 controls">
+ <select name="location_type" class="form-control">
+ <option value="gene" {% if dataset.type == 'Publish' %}disabled{% endif %}>Gene</option>
+ <option value="highest_lod">Highest LOD</option>
+ </select>
+ </div>
+ </div>
+ <div id="location_filter" class="form-group">
+ <label class="col-xs-2 control-label">Location</label>
+ <div class="col-xs-10 controls">
+ <span>
+ Chr: <input name="loc_chr" value="" type="text" class="form-control corr-location">&nbsp;&nbsp;&nbsp;
+ Mb: <input name="min_loc_mb" value="" type="text" class="form-control corr-location"> &nbsp;to&nbsp; <input name="max_loc_mb" value="" type="text" class="form-control corr-location">
+ </span>
+ <br>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-xs-2 control-label">Range</label>
+ <div class="col-xs-5 controls">
+ <input name="p_range_lower" value="" type="hidden">
+ <input name="p_range_upper" value="" type="hidden">
+ <span class="inline-div">
+ <div id="p_range_slider" class="p-range-slider"></div>
+ <span id="p_range_lower" class="p-range-lower"></span>
+ <span id="p_range_upper" class="p-range-upper"></span>
+ </span>
+ </div>
+ </div>
+
+
+ <div class="form-group">
+ <label class="col-xs-2 control-label" >Use Cache</label>
+ <div class="col-xs-5 controls">
+ <input id="use_cache" name="use_cache" type="checkbox" checked>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="corr_sample_method" class="col-xs-2 control-label"></label>
+ <div class="col-xs-3 controls">
+ <input type="button" class="btn corr_compute submit_special btn-success" data-url="/corr_compute" title="Compute Correlation" value="Compute">
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="descriptions">
+ <div class="section-form-div">
+ <dl>
+ <dt class="map-method-text">Sample Correlation</dt>
+ <dd>The <a href="http://genenetwork.org/correlationAnnotation.html#genetic_r">Sample Correlation</a>
+ is computed
+ between trait data and any
+ other traits in the sample database selected above. Use
+ <a href="{{ url_for('glossary_blueprint.glossary') }}#Correlations">Spearman
+ Rank</a>
+ when the sample size is small (&lt;20) or when there are influential outliers.</dd>
+ <dt class="map-method-text">Literature Correlation</dt>
+ <dd>The <a href="http://genenetwork.org/correlationAnnotation.html#literatureCorr">Literature Correlation</a>
+ (Lit r) between
+ this gene and all other genes is computed<br>
+ using the <span class="broken_link" href="https://grits.eecs.utk.edu/sgo/sgo.html">
+ Semantic Gene Organizer</span>
+ and human, rat, and mouse data from PubMed.
+ Values are ranked by Lit r, but Sample r and Tissue r are also displayed.<br>
+ <a href="http://genenetwork.org/glossary.html#Literature">More on using Lit r</a></dd>
+ <dt class="map-method-text">Tissue Correlation</dt>
+ <dd>The <a href="http://genenetwork.org/webqtl/main.py?FormID=tissueCorrelation">Tissue Correlation</a>
+ (Tissue r)
+ estimates the similarity of expression of two genes
+ or transcripts across different cells, tissues, or organs
+ (<a href="http://genenetwork.org/correlationAnnotation.html#tissueCorr">glossary</a>).
+ Tissue correlations
+ are generated by analyzing expression in multiple samples usually taken from single cases.<br>
+ <strong>Pearson</strong> and <strong>Spearman Rank</strong> correlations have been
+ computed for all pairs of genes using data from mouse samples.<br></dd>
+ </dl>
+ </div>
+ </div>
+ </div>
diff --git a/gn2/wqflask/templates/show_trait_details.html b/gn2/wqflask/templates/show_trait_details.html
new file mode 100644
index 00000000..9c12393d
--- /dev/null
+++ b/gn2/wqflask/templates/show_trait_details.html
@@ -0,0 +1,255 @@
+<table class="table">
+ <tr>
+ <td><b>Group</b></td>
+ <td>{{ this_trait.dataset.group.species[0]|upper }}{{ this_trait.dataset.group.species[1:] }}: {{ this_trait.dataset.group.name }} group</td>
+ </tr>
+ {% if this_trait.dataset.type == 'Publish' %}
+ <tr>
+ <td><b>Phenotype</b></td>
+ <td><div>{{ this_trait.description_fmt }}</div></td>
+ </tr>
+ <tr>
+ <td><b>Authors</b></td>
+ <td><div>{{ this_trait.authors }}</div></td>
+ </tr>
+ <tr>
+ <td><b>Title</b></td>
+ <td><div>{{ this_trait.title }}</div></td>
+ </tr>
+ <tr>
+ <td><b>Journal</b></td>
+ <td>{{ this_trait.journal }} ({% if this_trait.pubmed_id %}<a href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids={{ this_trait.pubmed_id }}&dop=Abstract" target="_blank" title="PubMed">{{ this_trait.year }}</a>{% else %}{{ this_trait.year }}{% endif %})</td>
+ </tr>
+ {% elif this_trait.dataset.type == 'ProbeSet' %}
+ <tr>
+ <td><b>Tissue</b></td>
+ <td>{{ this_trait.dataset.tissue }}</td>
+ </tr>
+ {% endif %}
+ {% if this_trait.dataset.type == 'ProbeSet' %}
+ {% if this_trait.symbol != None %}
+ <tr>
+ <td><b>Gene Symbol</b></td>
+ <td>{{ this_trait.symbol }}</td>
+ </tr>
+ {% endif %}
+ <tr>
+ <td><b>Aliases</b></td>
+ <td>Wikidata: {{ this_trait.wikidata_alias_fmt|replace(",",";") }}</td>
+ </tr>
+ {% if this_trait.alias_fmt != "Not Available" %}
+ <tr>
+ <td></td>
+ <td>GeneNetwork: {{ this_trait.alias_fmt|replace(",",";") }}</td>
+ </tr>
+ {% endif %}
+ {% endif %}
+ {% if this_trait.dataset.type != 'Publish' %}
+ <tr>
+ <td><b>Location</b></td>
+ <td>{{ this_trait.location_fmt }}</td>
+ </tr>
+ {% endif %}
+ {% if ncbi_summary != None and ncbi_summary != "" %}
+ <tr>
+ <td><b>Summary</b></td>
+ <td>{{ ncbi_summary }}</td>
+ </tr>
+ {% endif %}
+ <tr>
+ <td><b>Database</b></td>
+ <td>
+ <a href="http://gn1.genenetwork.org/webqtl/main.py?FormID=sharinginfo&InfoPageName={{ dataset.name }}" target="_blank">
+ {{ dataset.fullname }}
+ </a>
+ <br/>
+ <a href="{{ url_for('get_dataset', name=dataset.name) }}" target="_blank">
+ GN2 Link: {{ dataset.fullname }}
+ </a>
+ </td>
+ </tr>
+ {% if this_trait.probe_set_specificity %}
+ <tr>
+ <td><b>Target Score</b></td>
+ <td>
+ <a href="http://gn1.genenetwork.org/blatInfo.html" target="_blank" title="Values higher than 2 for the specificity are good">
+ BLAT Specificity
+ </a>:
+ {{ "%0.3f" | format(this_trait.probe_set_specificity|float) }}
+ &nbsp;&nbsp;
+ {% if this_trait.probe_set_blat_score %}
+ Score: {{ "%0.3f" | format(this_trait.probe_set_blat_score|float) }}
+ {% endif %}
+ </td>
+ </tr>
+ {% endif %}
+ {% if this_trait.pubmed_id or this_trait.geneid or this_trait.omim or this_trait.symbol %}
+ <tr>
+ <td><b>Resource Links</b></td>
+ <td>
+ {% if pubmed_link %}
+ <a href="{{ pubmed_link }}" target="_blank" title="PubMed">
+ PubMed
+ </a>
+ {% endif %}
+ {% if ncbi_gene_link %}
+ <a href="{{ ncbi_gene_link }}" target="_blank" title="Info from NCBI Entrez Gene">
+ Gene
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if omim_link %}
+ <a href="{{ omim_link }}" target="_blank" title="Summary from On Mendelion Inheritance in Man">
+ OMIM
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if genemania_link %}
+ <a href="{{ genemania_link }}" target="_blank" title="GeneMANIA">
+ GeneMANIA
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if protein_atlas_link %}
+ <a href="{{ protein_atlas_link }}" target="_blank" title="Human Protein Atlas">
+ Protein Atlas
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if open_targets_link %}
+ <a href="{{ open_targets_link }}" target="_blank" title="Open Targets">
+ Open Targets
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if homologene_link %}
+ <a href="{{ homologene_link }}" target="_blank" title="Find similar genes in other species">
+ HomoloGene
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if this_trait.symbol %}
+ <!--
+ <a href="{{ genotation_link }}" target="_blank" title="Related descriptive, genomic, clinical, functional and drug-therapy information">
+ Genotation
+ </a>
+ &nbsp;&nbsp;
+ -->
+ {% if rgd_link %}
+ <a href="{{ rgd_link }}" target="_blank">
+ Rat Genome DB
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ <a href="{{ gtex_link }}" target="_blank" title="GTEx Portal">
+ GTEx Portal
+ </a>
+ &nbsp;&nbsp;
+ {% if phenogen_link %}
+ <a href="{{ phenogen_link }}" target="_blank">
+ PhenoGen
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if genebridge_link %}
+ <a href="{{ genebridge_link }}" target="_blank">
+ GeneBridge
+ </a>
+ {% endif %}
+ {% endif %}
+ <br>
+ {% if ucsc_blat_link %}
+ <a href="{{ ucsc_blat_link }}" target="_blank" title="Info from UCSC Genome Browser">
+ UCSC
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if biogps_link %}
+ <a href="{{ biogps_link }}" target="_blank" title="Expression across many tissues and cell types">
+ BioGPS
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if string_link %}
+ <a href="{{ string_link }}" target="_blank" title="Protein interactions: known and inferred">
+ STRING
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if panther_link %}
+ <a href="{{ panther_link }}" target="_blank" title="Gene and protein data resources from Celera-ABI">
+ PANTHER
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if gemma_link %}
+ <a href="{{ gemma_link }}" target="_blank" title="Meta-analysis of gene expression data">
+ Gemma
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if aba_link %}
+ <a href="{{ aba_link }}" target="_blank" title="Allen Brain Atlas">
+ ABA
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if ebi_gwas_link %}
+ <a href="{{ ebi_gwas_link }}" target="_blank" title="EBI GWAS">
+ EBI GWAS
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if wiki_pi_link %}
+ <a href="{{ wiki_pi_link }}" target="_blank" title="Wiki-Pi">
+ Wiki-Pi
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ {% if uniprot_link %}
+ <a href="{{ uniprot_link }}" target="_blank" title="UniProt">
+ UniProt
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
+ </td>
+ </tr>
+ {% endif %}
+</table>
+
+<div class="btn-toolbar">
+ <div class="btn-group">
+ <button type="button" id="add_to_collection" class="btn btn-success" title="Add to Collection">Add</button>
+ {% if this_trait.dataset.type == 'ProbeSet' or this_trait.dataset.type == 'Geno' %}
+ {% if this_trait.symbol != None %}
+ <button type="button" class="btn btn-default" title="Find similar expression data" onclick="window.open('http://gn1.genenetwork.org/webqtl/main.py?cmd=sch&amp;gene={{ this_trait.symbol }}&amp;alias=1&amp;species={{ dataset.group.species }}', '_blank')">Find</button>
+ {% endif %}
+ {% if UCSC_BLAT_URL != "" %}
+ <button type="button" class="btn btn-default" title="Check probe locations at UCSC" onclick="window.open('{{ UCSC_BLAT_URL }}', '_blank')">Verify</button>
+ {% endif %}
+ {% if this_trait.symbol != None %}
+ <button type="button" class="btn btn-default" title="Write or review comments about this gene" onclick="window.open('http://gn1.genenetwork.org/webqtl/main.py?FormID=geneWiki&symbol={{ this_trait.symbol }}', '_blank')">(GN1) GeneWiki</button>
+ {% if dataset.group.species == "mouse" or dataset.group.species == "rat" %}
+ <button type="button" class="btn btn-default" title="View SNPs and Indels" onclick="window.open('/snp_browser?first_run=true&species={{ dataset.group.species }}&gene_name={{ this_trait.symbol }}&limit_strains=on', '_blank')">SNPs</button>
+ {% endif %}
+ {% endif %}
+ {% if show_probes == "True" %}
+ <button type="button" class="btn btn-default" title="Check sequence of probes" onclick="window.open('http://gn1.genenetwork.org/webqtl/main.py?FormID=showProbeInfo&database={{ this_trait.dataset.name }}&ProbeSetID={{ this_trait.name }}&CellID={{ this_trait.cellid }}&RISet={{ dataset.group.name }}&incparentsf1=ON', '_blank')">Probes</button>
+ {% endif %}
+ {% endif %}
+ <button type="button" id="view_in_gn1" class="btn btn-primary" title="View Trait in GN1" onclick="window.open('http://gn1.genenetwork.org/webqtl/main.py?cmd=show&db={{ this_trait.dataset.name }}&probeset={{ this_trait.name }}', '_blank')">Go to GN1</button>
+ {% if this_trait.dataset.type == 'Publish' %}
+ <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/datasets/{{ this_trait.dataset.group.id }}/traits/{{ this_trait.name }}?resource-id={{ resource_id }}&dataset_name={{this_trait.dataset.name}}', '_blank')">Edit</button>
+ {% endif %}
+
+ {% if this_trait.dataset.type == 'ProbeSet' %}
+ <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/datasets/traits/{{ this_trait.name }}?resource-id={{ resource_id }}&dataset_name={{this_trait.dataset.name}}', '_blank')">Edit</button>
+ {% endif %}
+ </div>
+ {%if "group:resource:edit-resource" in trait_privileges%}
+ <div class="btn-group">
+ <button type="button" id="edit_resource" class="btn btn-success" title="Edit Privileges" onclick="window.open('{{url_for('oauth2.resource.view_resource', resource_id=resource_id)}}', '_blank')">Edit Privileges</button>
+ </div>
+ {% endif %}
+</div>
+
diff --git a/gn2/wqflask/templates/show_trait_edit_data.html b/gn2/wqflask/templates/show_trait_edit_data.html
new file mode 100644
index 00000000..91cbdb6e
--- /dev/null
+++ b/gn2/wqflask/templates/show_trait_edit_data.html
@@ -0,0 +1,75 @@
+<div>
+ {% for sample_type in sample_groups %}
+ <div class="sample-table-container">
+ {% if loop.index == 1 and (sample_groups[0].se_exists or has_num_cases or sample_groups[0].attributes|length > 0) %}
+ <b>Show/Hide Columns:</b>
+ <br>
+ {% if sample_groups[0].se_exists %}
+ <button class="toggle-vis" data-column="4,5">SE</button>
+ {% if has_num_cases %}
+ <button class="toggle-vis" data-column="6">N</button>
+ {% set attr_start_pos = 7 %}
+ {% else %}
+ {% set attr_start_pos = 6 %}
+ {% endif %}
+ {% else %}
+ {% if has_num_cases %}
+ <button class="toggle-vis" data-column="4">N</button>
+ {% set attr_start_pos = 5 %}
+ {% else %}
+ {% set attr_start_pos = 4 %}
+ {% endif %}
+ {% endif %}
+ {% if sample_groups[0].attributes %}
+ {% for attribute in sample_groups[0].attributes %}
+ <button class="toggle-vis" data-column="{{ loop.index + attr_start_pos - 1 }}">{{ sample_groups[0].attributes[attribute].name }}</button>
+ {% endfor %}
+ {% endif %}
+ <br>
+ <br>
+ {% endif %}
+ <div class="sample-table-search-container">
+ <input type="text" id="{{ sample_type.sample_group_type }}_searchbox" class="form-control sample-table-search" placeholder="Search This Table For ...">
+ </div>
+ <div class="sample-table-export-container">
+ <button class="btn btn-default export"><span class="glyphicon glyphicon-download-alt"></span> Export</button>
+ <select class="select optional span2 export_format">
+ <option value="excel">Excel</option>
+ <option value="csv">CSV</option>
+ </select>
+ <button type="button" class="btn btn-success reset"><span class="glyphicon glyphicon-repeat"></span> Reset</button>
+ </div>
+ <div id="export_code" class="export-code-container">
+ <pre class="export-code_field">
+ <code>
+ # read into R
+ trait <- read.csv("{{ this_trait.display_name}}.csv", header = TRUE, comment.char = "#")
+
+ # read into python
+ import pandas as pd
+ trait = pd.read_csv("{{ this_trait.display_name}}.csv", header = 0, comment = "#")
+ </code>
+ </pre>
+ </div>
+ </div>
+ <a href="{{url_for('edit_case_attributes', inbredset_id=dataset.group.id)}}"
+ title="Edit case attributes for group."
+ target="_blank"
+ class="btn btn-info">Edit CaseAttributes</a>
+ {% set outer_loop = loop %}
+ <div class="sample_group">
+ <div style="position: relative;">
+ <div class="inline-div"><h3 style="float: left;">{{ sample_type.header }}<span name="transform_text"></span></h3></div>
+ </div>
+ <div id="{{ sample_type.sample_group_type }}_container" style="width: {{ trait_table_width }}px;">
+ <table class="table-hover table-striped cell-border" id="samples_{{ sample_type.sample_group_type }}">
+ <tbody>
+ <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <br>
+ {% endfor %}
+ <input type="hidden" name="Default_Name">
+</div>
diff --git a/gn2/wqflask/templates/show_trait_error.html b/gn2/wqflask/templates/show_trait_error.html
new file mode 100644
index 00000000..c924d1f1
--- /dev/null
+++ b/gn2/wqflask/templates/show_trait_error.html
@@ -0,0 +1,20 @@
+{%extends "base.html"%}
+{%block title%}Trait Data and Analysis{%endblock%}
+{%block css%}
+<link rel="stylesheet" type="text/css" href="/static/new/css/bar_chart.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/box_plot.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/prob_plot.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/scatter-matrix.css" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='nouislider/nouislider.min.css') }}" />
+<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+
+{%endblock%}
+{%block content%} <!-- Start of body -->
+<div class="container">
+ {{flash_me()}}
+</div>
+{%endblock%} <!-- End of body -->
diff --git a/gn2/wqflask/templates/show_trait_mapping_tools.html b/gn2/wqflask/templates/show_trait_mapping_tools.html
new file mode 100755
index 00000000..f1ed8922
--- /dev/null
+++ b/gn2/wqflask/templates/show_trait_mapping_tools.html
@@ -0,0 +1,436 @@
+<div class="main">
+ {% if dataset.group.mapping_names|length > 0 %}
+ <div class="options">
+ <div class="tabbable"> <!-- Only required for left/right tabs -->
+
+ <ul class="nav nav-pills">
+ {% for mapping_method in dataset.group.mapping_names %}
+ {% if mapping_method == "GEMMA" %}
+ <li class="gemma-tab mapping-tab {% if dataset.group.mapping_id == '1' or dataset.group.mapping_id == '2' %}active{% endif %}">
+ <a href="#gemma" data-toggle="tab">GEMMA</a>
+ </li>
+ {% elif mapping_method == "R/qtl" %}
+ <li class="rqtl-geno-tab mapping-tab {% if dataset.group.mapping_id == '3' %}active{% endif %}">
+ <a href="#rqtl_geno" data-toggle="tab">R/qtl</a>
+ </li>
+ <li class="rqtl-pair-tab mapping-tab">
+ <a href="#rqtl_pair" data-toggle="tab">Pair Scan</a>
+ </li>
+ {% elif mapping_method == "QTLReaper" %}
+ <li class="reaper-tab mapping-tab">
+ <a href="#interval_mapping" data-toggle="tab">Haley-Knott Regression</a>
+ </li>
+ {% endif %}
+ {% endfor %}
+ </ul>
+
+ <div class="tab-content">
+ {% for mapping_method in dataset.group.mapping_names %}
+ {% if mapping_method == "GEMMA" %}
+ <div class="tab-pane {% if dataset.group.mapping_id == '1' or dataset.group.mapping_id == '2' %}active{% endif %}" id="gemma">
+ <div class="form-horizontal section-form-div">
+ <div class="mapping_method_fields form-group">
+ <label for="chr_select" class="col-xs-3 control-label">Chromosome</label>
+ <div class="col-xs-2 controls">
+ <select id="chr_gemma" class="form-control chr-select">
+ {% for item in chr_list %}
+ <option value="{{ item[1] }}">{{ item[0] }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% if genofiles and genofiles|length>0 %}
+ <div class="mapping_method_fields form-group">
+ <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
+ <div class="col-xs-6 controls">
+ <select id="genofile_gemma" class="form-control">
+ {% for item in genofiles %}
+ <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% endif %}
+ <div class="mapping_method_fields form-group">
+ <label for="maf_gemma" class="col-xs-3 control-label">Minor Allele ≥</label>
+ <div class="col-xs-4 controls">
+ <input name="maf_gemma" value="{{ maf }}" type="text" class="form-control maf-select">
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label">Use LOCO</label>
+ <div class="col-xs-6 controls">
+ <label class="radio-inline">
+ <input type="radio" name="use_loco" value="True" checked="">
+ Yes
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="use_loco" value="False">
+ No
+ </label>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label">Covariates<br><span class="covar-text">Select covariate(s) from a collection</span></label>
+ <div class="col-xs-8 covar-options">
+ <div class="select-covar-div">
+ <button type="button" class="btn btn-success select-covar-button select_covariates">Select</button>
+ <button type="button" class="btn btn-default select-covar-button remove_covariates">Remove</button>
+ <button type="button" class="btn btn-danger select-covar-button remove_all_covariates">Clear</button>
+ </div>
+ <select size="2" name="selected_covariates_gemma" class="form-control selected-covariates" multiple>
+ <option value="">No covariates selected</option>
+ </select>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label"></label>
+ <div class="col-xs-6">
+ <button id="gemma_compute" type="button" class="btn submit_special btn-success" title="Compute Marker Regression" value="Compute" disabled>Loading...</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ {% elif mapping_method == "QTLReaper" %}
+ <div class="tab-pane" id="interval_mapping">
+ <div class="form-horizontal section-form-div">
+ <div class="mapping_method_fields form-group">
+ <label for="chr_select" class="col-xs-3 control-label">Chromosome</label>
+ <div class="col-xs-2 controls">
+ <select id="chr_reaper" class="form-control chr-select">
+ {% for item in chr_list %}
+ <option value="{{ item[1] }}">{{ item[0] }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% if genofiles and genofiles|length>0 %}
+ <div class="mapping_method_fields form-group">
+ <label for="scale_select" class="col-xs-3 control-label">Map Scale</label>
+ <div class="col-xs-2 controls">
+ <select id="scale_reaper" class="form-control scale-select">
+ {% for item in scales_in_geno[genofiles[0]['location']] %}
+ <option value="{{ item[0] }}">{{ item[1] }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
+ <div class="col-xs-6 controls">
+ <select id="genofile_reaper" class="form-control">
+ {% for item in genofiles %}
+ <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% else %}
+ <div class="mapping_method_fields form-group">
+ <label for="scale_select" class="col-xs-3 control-label">Map Scale</label>
+ <div class="col-xs-2 controls">
+ <select id="scale_reaper" class="form-control scale-select">
+ {% for item in scales_in_geno[dataset.group.name + ".geno"] %}
+ <option value="{{ item[0] }}">{{ item[1] }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% endif %}
+ <div class="mapping_method_fields form-group">
+ <label for="mapping_permutations" class="col-xs-3 control-label">Permutations</label>
+ <div class="col-xs-4 controls">
+ <input name="num_perm_reaper" value="1000" type="text" class="form-control">
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label for="mapping_bootstraps" class="col-xs-3 control-label">Bootstraps</label>
+ <div class="col-xs-4 controls">
+ <input name="num_bootstrap" value="0" type="text" class="form-control">
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label for="control_for" class="col-xs-3 control-label">Control&nbsp;for<br>Cofactors</label>
+ <div class="col-xs-6 controls">
+ <input name="control_reaper" value="{% if dataset.type == 'ProbeSet' and this_trait.locus_chr != '' %}{{ nearest_marker }}{% endif %}" type="text" class="form-control cofactor-input" />
+ <br>
+ <label class="radio-inline">
+ <input type="radio" name="do_control_reaper" value="true">
+ Yes
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="do_control_reaper" value="false" checked="">
+ No
+ </label>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label">Interval Map</label>
+ <div class="col-xs-6 controls">
+ <label class="radio-inline">
+ <input type="radio" name="manhattan_plot_reaper" value="false" checked="">
+ Yes
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="manhattan_plot_reaper" value="true">
+ No
+ </label>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label"></label>
+ <div class="col-xs-6">
+ <button id="interval_mapping_compute" type="button" class="btn submit_special btn-success" title="Compute Interval Mapping" value="Compute" disabled>Loading...</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ {% elif mapping_method == "R/qtl" %}
+ <div class="tab-pane {% if dataset.group.mapping_id == '3' %}active{% endif %}" id="rqtl_geno">
+ <div class="form-horizontal section-form-div">
+ <div class="mapping_method_fields form-group">
+ <label for="chr_select" class="col-xs-3 control-label">Chromosome</label>
+ <div class="col-xs-2 controls">
+ <select id="chr_rqtl_geno" class="form-control chr-select">
+ {% for item in chr_list %}
+ <option value="{{ item[1] }}">{{ item[0] }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% if genofiles and genofiles|length > 0 %}
+ <div class="mapping_method_fields form-group">
+ <label for="scale_select" class="col-xs-3 control-label">Map Scale</label>
+ <div class="col-xs-2 controls">
+ <select id="scale_rqtl_geno" class="form-control scale-select">
+ {% for item in scales_in_geno[genofiles[0]['location']] %}
+ <option value="{{ item[0] }}">{{ item[1] }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
+ <div class="col-xs-6 controls">
+ <select id="genofile_rqtl_geno" class="form-control">
+ {% for item in genofiles %}
+ <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% else %}
+ <div class="mapping_method_fields form-group">
+ <label for="scale_select" class="col-xs-3 control-label">Map Scale</label>
+ <div class="col-xs-2 controls">
+ <select id="scale_rqtl_geno" class="form-control scale-select">
+ {% for item in scales_in_geno[dataset.group.name + ".geno"] %}
+ <option value="{{ item[0] }}">{{ item[1] }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% endif %}
+ <div class="mapping_method_fields form-group">
+ <label for="mapping_permutations" class="col-xs-3 control-label">Permutations</label>
+ <div class="col-xs-4 controls">
+ <input name="num_perm_rqtl_geno" value="200" type="text" class="form-control">
+ </div>
+ </div>
+ {% if sample_groups[0].attributes|length > 0 %}
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label">Stratified</label>
+ <div class="col-xs-6 controls">
+ <label class="radio-inline">
+ <input type="radio" name="perm_strata" value="True" checked="">
+ Yes
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="perm_strata" value="False" >
+ No
+ </label>
+ </div>
+ </div>
+ {% endif %}
+ <div class="mapping_method_fields form-group">
+ <label for="mapmodel_rqtl_geno" class="col-xs-3 control-label">Model</label>
+ <div class="col-xs-4 controls">
+ <select id="mapmodel_rqtl_geno" name="mapmodel_rqtl_geno" class="form-control">
+ <option value="normal">Normal</option>
+ {% if binary == "true" %}<option value="binary">Binary</option>{% endif %}
+ <!--<option value="2part">2-part</option>-->
+ <option value="np">Non-parametric</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="mapping_method_fields form-group">
+ <label for="mapmethod_rqtl_geno" class="col-xs-3 control-label">Method</label>
+ <div class="col-xs-6 controls">
+ <select id="mapmethod_rqtl_geno" name="mapmethod_rqtl_geno" class="form-control">
+ <option value="hk" selected>Haley-Knott</option>
+ <option value="ehk">Extended Haley-Knott</option>
+ <option value="mr">Marker Regression</option>
+ <option value="em">Expectation-Maximization</option>
+ <option value="imp">Imputation</option>
+ </select>
+ </div>
+ </div>
+ <div id="missing_geno_div" class="mapping_method_fields form-group" style="display: none;">
+ <label for="missing_genotypes" class="col-xs-3 control-label"></label>
+ <div class="col-xs-6 controls">
+ <select id="missing_genotype" name="missing_genotypes" class="form-control">
+ <option value="mr">Remove Samples w/o Genotypes</option>
+ <option value="mr-imp">Single Imputation</option>
+ <option value="mr-argmax">Imputation w/ Viterbi Algorithm</option>
+ </select>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label">Manhattan<br>Plot</label>
+ <div class="col-xs-6 controls">
+ <label class="radio-inline">
+ <input type="radio" name="manhattan_plot_rqtl" value="True">
+ Yes
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="manhattan_plot_rqtl" value="False" checked="">
+ No
+ </label>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label">Covariates<br><span class="covar-text">Select covariate(s) from a collection</span></label>
+ <div class="col-xs-8 covar-options">
+ <div class="select-covar-div">
+ <button type="button" class="btn btn-success select-covar-button select_covariates">Select</button>
+ <button type="button" class="btn btn-default select-covar-button remove_covariates">Remove</button>
+ <button type="button" class="btn btn-danger select-covar-button remove_all_covariates">Clear</button>
+ </div>
+ <select size="2" name="selected_covariates_rqtl" class="form-control selected-covariates" multiple>
+ <option value="">No covariates selected</option>
+ </select>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label"></label>
+ <div class="col-xs-6 controls">
+ <button id="rqtl_geno_compute" type="button" class="btn submit_special btn-success" title="Compute Marker Regression" value="Compute" disabled>Loading...</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="tab-pane" id="rqtl_pair">
+ <div class="form-horizontal section-form-div">
+ {% if genofiles and genofiles|length > 0 %}
+ <div class="mapping_method_fields form-group">
+ <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
+ <div class="col-xs-6 controls">
+ <select id="genofile_rqtl_pair" class="form-control">
+ {% for item in genofiles %}
+ <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% endif %}
+ <div class="mapping_method_fields form-group">
+ <label for="control_for" class="col-xs-3 control-label">Control&nbsp;for</label>
+ <div class="col-xs-6 controls">
+ <input name="control_rqtl_pair" value="{% if dataset.type == 'ProbeSet' and this_trait.locus_chr != '' %}{{ nearest_marker }}{% endif %}" type="text" class="form-control cofactor-input" />
+ <label class="radio-inline">
+ <input type="radio" name="do_control_rqtl" value="true">
+ Yes
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="do_control_rqtl" value="false" checked="">
+ No
+ </label>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label for="mapmodel_rqtl_pair" class="col-xs-3 control-label">Model</label>
+ <div class="col-xs-4 controls">
+ <select id="mapmodel_rqtl_pair" name="mapmodel_rqtl_pair" class="form-control">
+ <option value="normal">Normal</option>
+ {% if binary == "true" %}<option value="binary">Binary</option>{% endif %}
+ <!--<option value="2part">2-part</option>-->
+ <option value="np">Non-parametric</option>
+ </select>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label for="mapmethod_rqtl_pair" class="col-xs-3 control-label">Method</label>
+ <div class="col-xs-6 controls">
+ <select id="mapmethod_rqtl_pair" name="mapmethod_rqtl_pair" class="form-control">
+ <option value="hk" selected>Haley-Knott</option>
+ <option value="ehk">Extended Haley-Knott</option>
+ <option value="mr">Marker Regression</option>
+ <option value="em">Expectation-Maximization</option>
+ <option value="imp">Imputation</option>
+ </select>
+ </div>
+ </div>
+ <div id="missing_geno_pair_div" class="mapping_method_fields form-group" style="display: none;">
+ <label for="missing_genotypes_pair" class="col-xs-3 control-label"></label>
+ <div class="col-xs-6 controls">
+ <select id="missing_genotype_pair" name="missing_genotypes" class="form-control">
+ <option value="mr">Remove Samples w/o Genotypes</option>
+ <option value="mr-imp">Single Imputation</option>
+ <option value="mr-argmax">Imputation w/ Viterbi Algorithm</option>
+ </select>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label">Covariates<br><span class="covar-text">Select covariate(s) from a collection</span></label>
+ <div class="col-xs-8 covar-options">
+ <div class="select-covar-div">
+ <button type="button" class="btn btn-default select-covar-button select_covariates">Select</button>
+ <button type="button" class="btn btn-default select-covar-button remove_covariates">Remove</button>
+ </div>
+ <textarea rows="3" cols="50" readonly placeholder="No covariates selected" class="selected-covariates"></textarea>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label"></label>
+ <div class="col-xs-6 controls">
+ <button id="rqtl_pair_compute" type="button" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Pair Scan" value="Compute" disabled>Loading...</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ {% endif %}
+ {% endfor %}
+ </div>
+ </div>
+ </div>
+ <div class="descriptions">
+ <div class="section-form-div">
+ <dl>
+ {% for mapping_method in dataset.group.mapping_names %}
+ {% if mapping_method == "GEMMA" %}
+ <dt>GEMMA</dt>
+ <dd>GEMMA maps with correction for kinship using a linear mixed model and can include covariates such as sex and age. Defaults include a minor allele frequency of 0.05 and the leave-one-chromosome-out method (<a href="https://www.ncbi.nlm.nih.gov/pubmed/24531419">PMID: 2453419</a>, and <a href="https://github.com/genetics-statistics/GEMMA"> GitHub code</a>).</dd>
+ {% elif mapping_method == "R/qtl" %}
+ <dt class="map-method-text">R/qtl (version 1.44.9)</dt>
+ <dd><a href="https://www.ncbi.nlm.nih.gov/pubmed/12724300">R/qtl</a> maps using several models and uniquely support 4-way intercrosses such as the "Aging Mouse Lifespan Studies" (NIA UM-HET3). We will add support for R/qtl2 (<a href="https://www.ncbi.nlm.nih.gov/pubmed/30591514">PMID: 30591514</a>) in 2023—a version that handles complex populations with admixture and many haplotypes.</dd>
+ <dt class="map-method-text">Pair Scan (R/qtl v 1.44.9)</dt>
+ <dd>The Pair Scan mapping tool performs a search for joint effects of two separate loci that may influence a trait. This search typically requires large sample sizes. Pair Scans can included covariates such as age and sex. For more on this function by K. Broman and colleagues see www.rdocumentation.org/packages/qtl/versions/1.60/topics/scantwo</dd>
+ {% elif mapping_method == "QTLReaper" %}
+ <dt class="map-method-text">Haley-Knott Regression</dt>
+ <dd>HK regression (QTL Reaper) is a fast mapping method with permutation that works well with F2 intercrosses and backcrosses (<a href="https://www.ncbi.nlm.nih.gov/pubmed/16718932">PMID 16718932</a>), but is not recommended for admixed populations, advanced intercrosses, or strain families such as the BXDs (<a href="https://github.com/pjotrp/QTLReaper">QTL Reaper code</a>).</dd>
+ {% endif %}
+ {% endfor %}
+ </dl>
+ <div class="rqtl-description">
+ More information on R/qtl mapping models and methods can be found <a href="http://www.rqtl.org/tutorials/rqtltour.pdf">here</a>.
+ </div>
+ </div>
+ </div>
+ <div id="mapping_result_holder_wrapper" style="display:none;">
+ <div id="mapping_result_holder"></div>
+ </div>
+ {% else %}
+ Mapping options are disabled for data not matched with genotypes.
+ {% endif %}
+</div>
diff --git a/gn2/wqflask/templates/show_trait_progress_bar.html b/gn2/wqflask/templates/show_trait_progress_bar.html
new file mode 100644
index 00000000..f9a34070
--- /dev/null
+++ b/gn2/wqflask/templates/show_trait_progress_bar.html
@@ -0,0 +1,35 @@
+<div id="progress_bar_container" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="progress_bar" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h3 id="progress_bar">Loading...</h3>
+ </div>
+ <div class="modal-body">
+ <div class="progress">
+ <div id="marker_regression_progress" class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%;">
+ </div>
+ </div>
+ <div id="time_remaining">
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+<div id="static_progress_bar_container" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="progress_bar" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h3 id="progress_bar">Loading... (Estimated time ~10-15m)</h3>
+ </div>
+ <div class="modal-body">
+ <div class="progress progress-striped active">
+ <div id="marker_regression_progress" class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:100%;">
+ </div>
+ </div>
+ <div id="time_remaining">
+ </div>
+ </div>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/gn2/wqflask/templates/show_trait_statistics.html b/gn2/wqflask/templates/show_trait_statistics.html
new file mode 100644
index 00000000..9ee0de5c
--- /dev/null
+++ b/gn2/wqflask/templates/show_trait_statistics.html
@@ -0,0 +1,106 @@
+<div>
+ <div class="tabbable"> <!-- Only required for left/right tabs -->
+ <ul class="nav nav-pills">
+ <li class="active">
+ <a href="#stats_tab" data-toggle="tab">Basic Statistics</a>
+ </li>
+ <li>
+ <a href="#histogram_tab" class="histogram_tab" data-toggle="tab">Histogram</a>
+ </li>
+ {% if num_values < 256 %}
+ <li>
+ <a href="#bar_chart_tab" class="bar_chart_tab" data-toggle="tab">Bar Chart</a>
+ </li>
+ {% endif %}
+ <li>
+ <a href="#probability_plot" class="prob_plot_tab" data-toggle="tab">Probability Plot</a>
+ </li>
+ <li>
+ <a href="#violin_plot_tab" class="violin_plot_tab" data-toggle="tab">Violin Plot</a>
+ </li>
+ </ul>
+ <div class="tab-content">
+ <div class="tab-pane active" id="stats_tab">
+ <div class="form-horizontal section-form-div">
+ <table id="stats_table" style="width: {{ stats_table_width }}px;" class="table table-hover table-striped table-bordered left-float"></table>
+ </div>
+ </div>
+ <div class="tab-pane" id="histogram_tab">
+ <div class="form-horizontal section-form-div">
+ {% if sample_groups|length != 1 %}
+ Select Group:
+ <select class="histogram_samples_group">
+ {% for group, pretty_group in sample_group_types.items() %}
+ <option value="{{ group }}">{{ pretty_group }}</option>
+ {% endfor %}
+ </select>
+ <br><br>
+ {% endif %}
+ <div id="histogram_container">
+ <div id="histogram" class="barchart"></div>
+ </div>
+ </div>
+ </div>
+ {% if num_values < 256 %}
+ <div class="tab-pane" id="bar_chart_tab">
+ <div class="form-horizontal section-form-div">
+ {% if sample_groups|length != 1 %}
+ Select Group:
+ <select class="bar_chart_samples_group">
+ {% for group, pretty_group in sample_group_types.items() %}
+ <option value="{{ group }}">{{ pretty_group }}</option>
+ {% endfor %}
+ </select>
+ {% endif %}
+
+ <div id="update_bar_chart" class="btn-group">
+ <button type="button" class="btn btn-default sort_by_name" value="name">
+ <i class="icon-resize-horizontal"></i> Sort By Name
+ </button>
+ <button type="button" class="btn btn-default sort_by_value" value="value">
+ <i class="icon-signal"></i> Sort By Value
+ </button>
+ </div>
+ <div id="bar_chart_container">
+ <div id="bar_chart"></div>
+ </div>
+ </div>
+ </div>
+ {% endif %}
+ <div class="tab-pane" id="probability_plot">
+ <div class="form-horizontal section-form-div">
+ {% if sample_groups|length != 1 %}
+ Select Group:
+ <select class="prob_plot_samples_group">
+ {% for group, pretty_group in sample_group_types.items() %}
+ <option value="{{ group }}">{{ pretty_group }}</option>
+ {% endfor %}
+ </select>
+ <br>
+ <br>
+ {% endif %}
+
+ <div id="prob_plot_container">
+ <div id="prob_plot_div"></div>
+ </div>
+ <div id="shapiro_wilk_text"></div>
+ <br>
+ <div>
+ More about <a href="http://en.wikipedia.org/wiki/Normal_probability_plot">Normal Probability Plots</a> and more
+ about interpreting these plots from the <a href="http://genenetwork.org/glossary.html#normal_probability">glossary</a>
+ </div>
+ </div>
+ </div>
+ <div class="tab-pane" id="violin_plot_tab">
+ <div class="form-horizontal section-form-div">
+ <div id="violin_plot_container">
+ <div id="violin_plot"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="collections_holder_wrapper" style="display:none;">
+ <div id="collections_holder"></div>
+ </div>
+</div>
diff --git a/gn2/wqflask/templates/show_trait_transform_and_filter.html b/gn2/wqflask/templates/show_trait_transform_and_filter.html
new file mode 100644
index 00000000..0706f64d
--- /dev/null
+++ b/gn2/wqflask/templates/show_trait_transform_and_filter.html
@@ -0,0 +1,140 @@
+<div>
+ <div class="form-horizontal">
+ <p>Edit or delete values in the Trait Data boxes, and use the
+ <strong>Reset</strong> option as
+ needed.
+ </p>
+ <div id="blockMenuSpan" class="input-append block-div">
+ <label for="remove_samples_field">Block samples by index:</label>
+ <input type="text" id="remove_samples_field" placeholder="Example: 3, 5-10, 12">
+ <select id="block_group" size="1">
+ <option value="primary">
+ {{ sample_group_types['samples_primary'] }}
+ </option>
+ <option value="other">
+ {{ sample_group_types['samples_other'] }}
+ </option>
+ </select>
+ <input type="button" id="block_by_index" class="btn btn-danger" value="Block">
+ </div>
+ <div id="remove_samples_invalid" class="alert alert-error" style="display:none;">
+ Please check that your input is formatted correctly, e.g. <strong>3, 5-10, 12</strong>
+ </div>
+ {% if categorical_attr_exists == "true" %}
+ <div class="input-append block-div-2">
+ <label for="exclude_column">Block samples by group:</label>
+ <select id="exclude_column" size=1>
+ {% for attribute in sample_groups[0].attributes %}
+ {% if sample_groups[0].attributes[attribute].distinct_values|length <= 500 and sample_groups[0].attributes[attribute].distinct_values|length > 1 %}
+ <option value="{{ loop.index }}">
+ {{ sample_groups[0].attributes[attribute].name }}
+ </option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ <select id="attribute_values" size=1>
+ </select>
+ <select id="exclude_by_attr_group" size="1">
+ <option value="primary">
+ {{ sample_group_types['samples_primary'] }}
+ </option>
+ <option value="other">
+ {{ sample_group_types['samples_other'] }}
+ </option>
+ </select>
+ <input type="button" id="exclude_by_attr" class="btn btn-danger" value="Block">
+ </div>
+ {% endif %}
+ {% if study_samplelists|length > 0 %}
+ <div id="filterMenuSpan" class="input-append block-div-2">
+ <label for="filter_study_select">Filter samples by study: </label>
+ <select id="filter_study">
+ {% for study in study_samplelists %}
+ <option value="{{ loop.index - 1 }}">{{ study }}</option>
+ {% endfor %}
+ </select>
+ {% if sample_groups|length != 1 %}
+ <select id="filter_study_group" size="1">
+ <option value="primary">
+ {{ sample_group_types['samples_primary'] }}
+ </option>
+ <option value="other">
+ {{ sample_group_types['samples_other'] }}
+ </option>
+ </select>
+ {% endif %}
+ <input type="button" id="filter_by_study" class="btn btn-danger" value="Filter">
+ </div>
+ {% endif %}
+ <div id="filterMenuSpan" class="input-append block-div-2">
+ <label for="filter_samples_field">Filter samples by {% if (numerical_var_list|length == 0) and (not js_data.se_exists) %}value{% endif %} </label>
+ {% if (numerical_var_list|length > 0) or js_data.se_exists %}
+ <select id="filter_column">
+ <option value="value">Value</option>
+ {% if js_data.se_exists %}
+ <option value="stderr">SE</option>
+ {% endif %}
+ {% for attribute in sample_groups[0].attributes %}
+ {% if sample_groups[0].attributes[attribute].name in numerical_var_list %}
+ <option value="{{ loop.index }}">
+ {{ sample_groups[0].attributes[attribute].name }}
+ </option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ {% endif %}
+ <select id="filter_logic" size="1">
+ <option value="greater_than">></option>
+ <option value="less_than"><</option>
+ <option value="greater_or_equal">≥</option>
+ <option value="less_or_equal">≤</option>
+ </select>
+ <input type="text" id="filter_value" placeholder="Example: 3, 10, 15">
+ <select id="filter_group" size="1">
+ <option value="primary">
+ {{ sample_group_types['samples_primary'] }}
+ </option>
+ <option value="other">
+ {{ sample_group_types['samples_other'] }}
+ </option>
+ </select>
+ <input type="button" id="filter_by_value" class="btn btn-danger" value="Filter">
+ </div>
+ <div>
+ <input data-active="false" type="button" id="hide_no_value" class="btn btn-default" value="Hide No Value">
+ <input type="button" id="block_outliers" class="btn btn-default" value="Block Outliers">
+ <button type="button" class="btn btn-success reset"><span class="glyphicon glyphicon-repeat"></span> Reset</button>
+ <span class="input-append">
+ <button class="btn btn-default export"><span class="glyphicon glyphicon-download-alt"></span> Export</button>
+ <select class="select optional span2 export_format">
+ <option value="excel">Excel</option>
+ <option value="csv">CSV</option>
+ </select>
+ </span>
+ <br>
+ <div class="normalize-div">
+ <input type="button" id="normalize" class="btn btn-success" value="Normalize">
+ <select id="norm_method" class="select optional span2">
+ {% if negative_vals_exist == "false" %}
+ <option value="log2">Log2</option>
+ <option value="log10">Log10</option>
+ <option value="sqrt">Square Root</option>
+ {% endif %}
+ <option value="zscore">Z-score</option>
+ <option value="qnorm">Quantile</option>
+ <option value="invert">Invert +/-</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <br>
+ <div>
+ <p>Outliers highlighted in
+ <strong style="background-color:orange;">orange</strong>
+ can be hidden using
+ the <strong>Hide Outliers</strong> button.
+ </p>
+
+ <p>Samples with no value (x) can be hidden by clicking<strong>Hide No Value</strong> button.</p>
+ </div>
+</div>
diff --git a/gn2/wqflask/templates/snp_browser.html b/gn2/wqflask/templates/snp_browser.html
new file mode 100644
index 00000000..b9aea570
--- /dev/null
+++ b/gn2/wqflask/templates/snp_browser.html
@@ -0,0 +1,582 @@
+{% extends "base.html" %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonsBootstrap/css/buttons.bootstrap.css') }}" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/typeahead-bootstrap.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/snp_browser.css" />
+{% endblock %}
+{% block content %}
+
+ <div class="container-fluid">
+ <h2>Variant Browser <a class="btn btn-primary" href="http://genenetwork.org/snpbrowser.html" role="button">Info</a></h2>
+ <hr style="height: 1px; background-color: #A9A9A9;">
+ <div class="container" style="border-style: double; position: relative; width: 950px; padding-top: 10px; padding-right: 40px;">
+ <form id="snp_browser_form" method="get" action="/snp_browser">
+ <input type="hidden" name="first_run" value="{{ first_run }}">
+ <input type="hidden" name="chosen_strains_mouse" value="{{ chosen_strains_mouse|join(",") }}">
+ <input type="hidden" name="chosen_strains_rat" value="{{ chosen_strains_rat|join(",") }}">
+ <div class="col-xs-4" style="width: 260px; padding-left: 30px; padding-right: 0px;">
+ <div class="form-group row" style="margin-bottom: 5px;">
+ <label for="snp_or_indel" style="text-align: right;" class="col-xs-4 col-form-label"><b>Type:</b></label>
+ <div class="col-xs-8">
+ <select name="variant">
+ <option value="SNP" {% if variant_type == "SNP" %}selected{% endif %}>SNP</option>
+ <option value="InDel" {% if variant_type == "InDel" %}selected{% endif %}>InDel</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row" style="margin-bottom: 5px;">
+ <label for="species" style="text-align: right;" class="col-xs-4 col-form-label"><b>Species:</b></label>
+ <div class="col-xs-8">
+ <select id="species_select" name="species">
+ <option value="Mouse" {% if species_name == "Mouse" %}selected{% endif %}>Mouse</option>
+ <option value="Rat" {% if species_name == "Rat" %}selected{% endif %}>Rat</option>
+ <option value="Human" disabled>Human</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row" style="margin-bottom: 5px;">
+ <label for="gene_or_id" style="text-align: right;" class="col-xs-4 col-form-label"><b>Gene or ID:</b></label>
+ <div class="col-xs-8">
+ <input type="text" name="gene_name" size="12" value="{{ gene_name }}">
+ </div>
+ </div>
+ <div class="form-group row">
+ <div style="text-align: center;"><b><font color="red">Or select</font></b></div>
+ </div>
+ <div class="form-group row" style="margin-bottom: 5px;">
+ <label for="chr" style="text-align: right;" class="col-xs-4 col-form-label"><b>Chr:</b></label>
+ <div class="col-xs-8">
+ <select id="chr_select" name="chr">
+ {% for item in this_chr_list %}
+ <option value="{{ item }}" {% if item == chr %}selected{% endif %}>{{ item }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ <div class="form-group row" style="margin-bottom: 5px;">
+ <label for="start_mb" style="text-align: right;" class="col-xs-4 col-form-label"><b>Mb:</b></label>
+ <div class="col-xs-8">
+ <input type="text" name="start_mb" size="10" value="{{ start_mb }}">
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="end_mb" style="text-align: right;" class="col-xs-4 col-form-label">to</label>
+ <div class="col-xs-8">
+ <input type="text" name="end_mb" size="10" value="{{ end_mb }}">
+ </div>
+ </div>
+ <hr>
+ <div class="form-group row">
+ <label class="col-xs-4 col-form-label"></label>
+ <div class="col-xs-8">
+ <button class="btn btn-primary" type="submit">Search</button>
+ </div>
+ </div>
+ </div>
+ <div class="col-xs-4" style="width: 310px; padding-left: 0px; padding-right: 20px;">
+ <div class="form-group row" style="margin-bottom: 10px;">
+ <label for="strains" style="text-align: right;" class="col-xs-4 col-form-label"><b>Strains:</b></label>
+ <div class="col-xs-8">
+ <select id="strain_select" name="strains" style="width: 70%;">
+ {% if species_name == "Mouse" %}
+ {% for strain in strain_lists['mouse'] %}
+ <option value="{{ strain }}" {% if loop.index == 1 %}selected{% endif %}>{{ strain }}</option>
+ {% endfor %}
+ {% elif species_name == "Rat" %}
+ {% for strain in strain_lists['rat'] %}
+ <option value="{{ strain }}" {% if loop.index == 1 %}selected{% endif %}>{{ strain }}</option>
+ {% endfor %}
+ {% endif %}
+ </select>
+ <div style="float: right; line-height: 20px;">
+ <input class="btn btn-primary" type="button" name="add_strain" value="Add" style="vertical-align: middle;">
+ </div>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="chosen_strains_select" style="text-align: right;" class="col-xs-4 col-form-label"><b><font color="red">Limit to:</font></b> <input type="checkbox" name="limit_strains" {% if limit_strains == "true" %}checked{% endif %} size="100"></label>
+ <div class="col-xs-8">
+ <select id="chosen_strains_select" size="11" style="width: 70%;">
+ {% for strain in chosen_strains %}
+ <option value="{{ strain }}">{{ strain }}</option>
+ {% endfor %}
+ </select>
+ <div style="float: right; line-height: 189px;">
+ <input class="btn btn-primary" type="button" name="remove_strain" value="Cut" style="vertical-align: middle;">
+ </div>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label class="col-xs-4 col-form-label"></label>
+ <div class="col-xs-8" style="margin-top: 65px;">
+ <input class="btn btn-primary" type="button" name="export_csv" value="Export to CSV">
+ </div>
+ </div>
+ </div>
+ <div class="col-xs-4" style="width: 310px; padding-left: 20px;">
+ <div class="form-group row" style="margin-bottom: 5px;">
+ <label for="domain" style="text-align: right;" class="col-xs-4 col-form-label"><b>Domain:</b></label>
+ <div class="col-xs-8">
+ <select name="domain" size="4">
+ <option value="All" {% if domain == "All" %}selected{% endif %}>All</option>
+ <option value="Exon" {% if domain == "Exon" %}selected{% endif %}>Exon</option>
+ <option value="5' UTR" {% if domain == "5' UTR" %}selected{% endif %}>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5' UTR</option>
+ <option value="Coding" {% if domain == "Coding" %}selected{% endif %}>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Coding Region</option>
+ <option value="3' UTR" {% if domain == "3' UTR" %}selected{% endif %}>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3' UTR</option>
+ <option value="Intron" {% if domain == "Intron" %}selected{% endif %}>Intron</option>
+ <option value="Splice Site" {% if domain == "Splice Site" %}selected{% endif %}>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Splice Site</option>
+ <option value="Nonsplice Site" {% if domain == "Nonsplice Site" %}selected{% endif %}>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nonsplice Site</option>
+ <option value="Upstream" {% if domain == "Upstream" %}selected{% endif %}>Upstream</option>
+ <option value="Downstream" {% if domain == "Downstream" %}selected{% endif %}>Downstream</option>
+ <option value="Intergenic" {% if domain == "Intergenic" %}selected{% endif %}>Intergenic</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row" style="margin-bottom: 5px;">
+ <label for="function" style="text-align: right;" class="col-xs-4 col-form-label"><b>Function:</b></label>
+ <div class="col-xs-8">
+ <select name="function" size="3">
+ <option value="All" {% if function == "All" %}selected{% endif %}>All</option>
+ <option value="Nonsynonymous" {% if function == "Nonsynonymous" %}selected{% endif %}>Nonsynonymous</option>
+ <option value="Synonymous" {% if function == "Synonymous" %}selected{% endif %}>Synonymous</option>
+ <option value="Start Gained" {% if function == "Start Gained" %}selected{% endif %}>Start Gained</option>
+ <option value="Start Lost" {% if function == "Start Lost" %}selected{% endif %}>Start Lost</option>
+ <option value="Stop Gained" {% if function == "Stop Gained" %}selected{% endif %}>Stop Gained</option>
+ <option value="Stop Lost" {% if function == "Stop Lost" %}selected{% endif %}>Stop Lost</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row" style="margin-bottom: 5px;">
+ <label for="source" style="text-align: right;" class="col-xs-4 col-form-label"><b>Source:</b></label>
+ <div class="col-xs-8">
+ <select name="source">
+ <option value="All" {% if source == "All" %}selected{% endif %}>All</option>
+ <option value="None" {% if source == "None" %}selected{% endif %}>None</option>
+ <option value="dbSNP" {% if source == "dbSNP" %}selected{% endif %}>dbSNP</option>
+ <option value="dbSNP (release 149)" {% if source == "dbSNP (release 149)" %}selected{% endif %}>dbSNP (release 149)</option>
+ <option value="Sanger/UCLA" {% if source == "Sanger/UCLA" %}selected{% endif %}>Sanger/UCLA</option>
+ <option value="UTHSC_CITG" {% if source == "UTHSC_CITG" %}selected{% endif %}>UTHSC_CITG</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="criteria" style="text-align: right;" class="col-xs-4 col-form-label"><b>ConScore:</b></label>
+ <div class="col-xs-8">
+ <select name="criteria" size="1">
+ <option value=">=" {% if criteria == ">=" %}selected{% endif %}>&gt;=</option>
+ <option value="==" {% if criteria == "==" %}selected{% endif %}>=</option>
+ <option value="<=" {% if criteria == "<=" %}selected{% endif %}>&lt;=</option>
+ </select>
+ <input type="text" name="score" value="{{ score }}" size="5">
+ </div>
+ </div>
+ <div class="form-group row" style="margin-bottom: 5px;">
+ <label style="text-align: right;" class="col-xs-4 col-form-label"><input type="checkbox" name="redundant" {% if redundant == "true" %}checked{% endif %}></label>
+ <div class="col-xs-8">
+ Non-redundant SNP Only
+ </div>
+ </div>
+ <div class="form-group row">
+ <label style="text-align: right;" class="col-xs-4 col-form-label"><input type="checkbox" name="diff_alleles" {% if diff_alleles == "true" %}checked{% endif %}></label>
+ <div class="col-xs-8">
+ Different Alleles Only
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+
+ <div style="margin-top: 20px;">
+ {% if table_rows is defined %}
+ <table class="dataTable cell-border nowrap" id="results_table" style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ {% if header_fields|length == 2 %}
+ {% for header in header_fields[0] %}
+ <th data-export="{{ header }}" name="{{ header }}">{{ header }}</th>
+ {% endfor %}
+ {% for strain in header_fields[1] %}
+ <th data-export="{{ strain }}" name="{{ strain }}" style="align: center; text-align: center; line-height: 12px;">{% for letter in strain|reverse %}<div style="transform: rotate(270deg);">{{ letter }}</div>{% endfor %}</th>
+ {% endfor %}
+ {% else %}
+ {% for header in header_fields %}
+ <th data-export="{{ header }}" name="{{ header }}">{{ header }}</th>
+ {% endfor %}
+ {% endif %}
+ </tr>
+ </thead>
+ <tbody>
+ <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td>
+ </tbody>
+ </table>
+ {% endif %}
+ </div>
+ </div>
+
+{% endblock %}
+{% block js %}
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='typeahead/typeahead.bundle.js') }}"></script>
+
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/typeahead_rn6.json"></script>
+
+ <script type='text/javascript'>
+ var empty_columns = {{ empty_columns|safe }};
+
+ var remain_field_count = 15 - {{ empty_field_count|safe }};
+ var total_field_count = 15 - {{ empty_field_count|safe }} + {{ allele_list|safe|length }};
+ </script>
+
+ <script language="javascript">
+
+ var getParams = function(url) {
+ let parser = document.createElement('a');
+ parser.href = url;
+ let params = parser.search.substring(1);
+ if(params.length > 0) {
+ return ('?'+params);
+ }
+ return params;
+ };
+
+ var substringMatcher = function(strs) {
+ return function findMatches(q, cb) {
+ var matches, substringRegex;
+
+ // an array that will be populated with substring matches
+ matches = [];
+
+ // regex used to determine if a string contains the substring `q`
+ substrRegex = new RegExp(q, 'i');
+
+ // iterate through the pool of strings and for any string that
+ // contains the substring `q`, add it to the `matches` array
+ $.each(strs, function(i, str) {
+ if (substrRegex.test(str)) {
+ matches.push(str);
+ }
+ });
+
+ cb(matches);
+ };
+ };
+
+ $('input[name=gene_name]').typeahead({
+ minLength: 2,
+ hint: true,
+ highlight: true
+ },
+ {
+ name: 'rn6-genes',
+ source: substringMatcher(rat_genes)
+ });
+
+ {% if table_rows is defined %}
+ $("#results_table").DataTable( {
+ {% if variant_type == "SNP" %}
+ 'columns': [
+ {
+ 'data': null,
+ 'className': 'dt-body-center',
+ 'orderable': false,
+ 'render': function(data, type, row, meta) {
+ return '<input type="checkbox" class="checkbox" id="variant_checkbox" onchange="onVarinatCheck(this)" name="trait_check">'
+ }
+ }, {
+ 'data': 'index',
+ 'className': 'dt-body-right'
+ }, {
+ 'data': null,
+ 'render': function(data, type, row, meta) {
+ if (data.rs != "") {
+ return '<b><a href="' + data.snp_url + '">' + data.snp_name + '</a></b>'
+ } else {
+ return '<a href="' + data.snp_url + '">' + data.snp_name + '</a>'
+ }
+ }
+ }, {
+ 'data': 'chr',
+ 'className': 'dt-body-center'
+ }, {
+ 'data': 'mb_formatted',
+ 'className': 'dt-body-right'
+ }, {
+ 'data': 'alleles'
+ }, {% if empty_columns['snp_source'] == "true" %}{
+ 'data': null,
+ 'render': function(data, type, row, meta) {
+ if (data.snp_source == "Sanger/UCLA") {
+ return '<a href="' + data.source_urls[0] + '">Sanger</a>, <a href="' + data.source_urls[1] + '">UCLA</a>'
+ } else {
+ return data.snp_source
+ }
+ }
+ }, {% endif %} {% if empty_columns['conservation_score'] == "true" %}{
+ 'data': 'conservation_score',
+ 'className': 'dt-body-right'
+ }, {% endif %} {% if empty_columns['gene_name'] == "true" %}{
+ 'data': null,
+ 'render': function(data, type, row, meta) {
+ if (data.gene_name != "") {
+ return '<i>' + data.gene_name + '</i>, <a href="' + data.gene_link + '">NCBI</a>'
+ } else {
+ return data.gene_name
+ }
+ }
+ }, {% endif %} {% if empty_columns['transcript'] == "true" %}{
+ 'data': null,
+ 'render': function(data, type, row, meta) {
+ if (data.transcript != "") {
+ return '<a href="' + data.transcript_link + '">' + data.transcript + '</a>'
+ } else {
+ return data.transcript
+ }
+ }
+ }, {% endif %} {% if empty_columns['exon'] == "true" %}{
+ 'data': 'exon'
+ }, {% endif %}{
+ 'data': 'domain_1'
+ }, {% if empty_columns['domain_2'] == "true" %}{
+ 'data': 'domain_2'
+ }, {% endif %} {% if empty_columns['function'] == "true" %}{
+ 'data': 'function'
+ }, {% endif %} {% if empty_columns['function_details'] == "true" %}{
+ 'data': 'function_details'
+ }, {% endif %} {% for item in allele_list %} {
+ 'data': null,
+ 'orderable': false,
+ 'className': 'dt-body-center',
+ 'render': function(data, type, row, meta) {
+ if (typeof data.allele_value_list[{{ loop.index - 1 }}][0] !== "undefined") {
+ return data.allele_value_list[{{ loop.index - 1 }}][0]
+ } else {
+ return ''
+ }
+ }
+ }{% if loop.index < allele_list|length %},{% endif %}{% endfor %}
+ ],
+ 'createdRow': function(row, data, dataIndex) {
+ for (i = remain_field_count; i < total_field_count; i++) {
+ var this_allele = $('td', row).eq(i).text();
+ switch (this_allele) {
+ case "A":
+ $('td', row).eq(i).addClass('A_allele_color');
+ break;
+ case "C":
+ $('td', row).eq(i).addClass('C_allele_color');
+ break;
+ case "T":
+ $('td', row).eq(i).addClass('T_allele_color');
+ break;
+ case "G":
+ $('td', row).eq(i).addClass('G_allele_color');
+ break;
+ case "t":
+ $('td', row).eq(i).addClass('t_allele_color');
+ break;
+ case "c":
+ $('td', row).eq(i).addClass('c_allele_color');
+ break;
+ case "a":
+ $('td', row).eq(i).addClass('a_allele_color');
+ break;
+ case "g":
+ $('td', row).eq(i).addClass('g_allele_color');
+ break;
+ default:
+ $('td', row).eq(i).addClass('default_allele_color');
+ }
+ }
+ },
+ {% else %}
+ 'columns': [
+ {
+ 'data': null,
+ 'render': function(data, type, row, meta) {
+ return '<input type="checkbox" class="checkbox" id="variant_checkbox" onchange="onVarinatCheck(this)" name="trait_check">'
+ }
+ }, {
+ 'data': 'index',
+ 'className': 'dt-body-right'
+ }, {
+ 'data': 'indel_name'
+ }, {
+ 'data': 'indel_type'
+ }, {
+ 'data': 'indel_chr',
+ 'className': 'dt-body-center'
+ }, {
+ 'data': 'indel_mb_s',
+ 'className': 'dt-body-right'
+ }, {
+ 'data': 'indel_mb_e',
+ 'className': 'dt-body-right'
+ }, {
+ 'data': 'indel_strand'
+ }, {
+ 'data': 'indel_size',
+ 'className': 'dt-body-right'
+ }, {
+ 'data': 'indel_sequence'
+ }, {
+ 'data': 'source_name'
+ }
+ ],
+ {% endif %}
+ 'order': [[1, "asc" ]],
+ 'sDom': "rtip",
+ 'iDisplayLength': 100,
+ 'bServerSide': true,
+ 'sAjaxSource': '/snp_browser_table'+getParams(window.location.href),
+ 'infoCallback': function(settings, start, end, max, total, pre) {
+ return "Showing " + start + " to " + (start + this.api().data().length - 1) + " of " + total + " entries";
+ }
+ });
+ {% endif %}
+
+ function onVarinatCheck(checkboxElem) {
+ if (checkboxElem.checked) {
+ if (!checkboxElem.parentElement.parentElement.classList.contains('selected')) {
+ checkboxElem.parentElement.parentElement.classList.add('selected')
+ }
+ }
+ else {
+ if (checkboxElem.parentElement.parentElement.classList.contains('selected')) {
+ checkboxElem.parentElement.parentElement.classList.remove('selected')
+ }
+ }
+ }
+
+ $("#species_select").change(function() {
+ this_species = $(this).val();
+ $("#strain_select").empty()
+ $("#chosen_strains_select").empty()
+ $("#chr_select").empty()
+
+ if (this_species == "Mouse") {
+ {% for strain in strain_lists["mouse"] %}
+ var option = $('<option></option>').attr("value", "{{ strain }}").text("{{ strain }}");
+ $("select[name=strains]").append(option);
+ {% endfor %}
+
+ {% for chr in mouse_chr_list %}
+ var option = $('<option></option>').attr("value", "{{ chr }}").text("{{ chr }}");
+ $("select[name=chr]").append(option);
+ {% endfor %}
+
+ chosen_strains = $("input[name=chosen_strains_mouse]").val().split(",")
+ } else if (this_species == "Rat") {
+ {% for strain in strain_lists["rat"] %}
+ var option = $('<option></option>').attr("value", "{{ strain }}").text("{{ strain }}");
+ $("select[name=strains]").append(option);
+ {% endfor %}
+
+ {% for chr in rat_chr_list %}
+ var option = $('<option></option>').attr("value", "{{ chr }}").text("{{ chr }}");
+ $("select[name=chr]").append(option);
+ {% endfor %}
+
+ chosen_strains = $("input[name=chosen_strains_rat]").val().split(",")
+ }
+
+ for (i=0; i < chosen_strains.length; i++) {
+ var option = $('<option></option>').attr("value", chosen_strains[i]).text(chosen_strains[i]);
+ $("#chosen_strains_select").append(option)
+ }
+ });
+
+ $("input[name=add_strain]").click(function() {
+ var selected_strain = $("select[name=strains] option:selected").val();
+
+ var current_species = $("#species_select").val();
+ if (current_species == "Mouse") {
+ stored_strains = $("input[name=chosen_strains_mouse]").val().split(",")
+ if (!(stored_strains.includes(selected_strain))){
+ stored_strains.push(selected_strain)
+ $("input[name=chosen_strains_mouse]").val(stored_strains.join(","))
+ $("#chosen_strains_select").append("<option value='" + selected_strain + "'>" + selected_strain + "</option>");
+ }
+ } else if (current_species == "Rat") {
+ stored_strains = $("input[name=chosen_strains_rat]").val().split(",")
+ if (!(stored_strains.includes(selected_strain))){
+ stored_strains.push(selected_strain)
+ $("input[name=chosen_strains_rat]").val(stored_strains.join(","))
+ $("#chosen_strains_select").append("<option value='" + selected_strain + "'>" + selected_strain + "</option>");
+ }
+ }
+ });
+
+ $("input[name=remove_strain]").click(function() {
+ var selected_strain = $("#chosen_strains_select option:selected").val();
+ $("#chosen_strains_select option[value='" + selected_strain + "']").remove();
+
+ var current_species = $("#species_select").val();
+
+ if (current_species == "Mouse") {
+ stored_strains = $("input[name=chosen_strains_mouse]").val().split(",")
+ for (i=0; i < stored_strains.length; i++) {
+ if (stored_strains[i] == selected_strain) {
+ stored_strains.splice(i, 1);
+ break;
+ }
+ }
+ $("input[name=chosen_strains_mouse]").val(stored_strains.join(","))
+ } else if (current_species == "Rat") {
+ stored_strains = $("input[name=chosen_strains_rat]").val().split(",")
+ for (i=0; i < stored_strains.length; i++) {
+ if (stored_strains[i] == selected_strain) {
+ stored_strains.splice(i, 1);
+ break;
+ }
+ }
+ $("input[name=chosen_strains_rat]").val(stored_strains.join(","))
+ }
+ });
+
+ $("#snp_browser_form").submit(function() {
+ var strain_list = [];
+ $("#chosen_strains_select option").each(function() {
+ strain_list.push($(this).val());
+ });
+ $("input[name=chosen_strains]").val(strain_list.join(","));
+ });
+
+
+
+ $("input[name=export_csv]").click(function() {
+ var csv = [];
+ var rows = document.querySelectorAll("table tr");
+
+ var headers = [];
+ var col_header = rows[0].querySelectorAll("th");
+ for(let i = 1; i < col_header.length; i++) {
+ headers.push(col_header[i].getAttribute("name"));
+ }
+ csv.push(headers.join(","));
+
+ for (let i = 1; i < rows.length; i++) {
+ var row = [], cols = rows[i].querySelectorAll("td");
+ var checkBox = rows[i].querySelector("input");
+
+ if(checkBox.checked == true) {
+ for (let j = 1; j < cols.length; j++)
+ row.push(cols[j].innerText);
+
+ csv.push(row.join(","));
+ }
+ }
+
+ var csvFile = new Blob([csv.join("\n")], {type: "text/csv"});
+ var downloadLink = document.createElement("a");
+ downloadLink.download = "variant_data.csv";
+ downloadLink.href = window.URL.createObjectURL(csvFile);
+ downloadLink.style.display = "none";
+ document.body.appendChild(downloadLink);
+ downloadLink.click();
+ });
+ </script>
+{% endblock %}
+
diff --git a/gn2/wqflask/templates/startup_errors.html b/gn2/wqflask/templates/startup_errors.html
new file mode 100644
index 00000000..82d85572
--- /dev/null
+++ b/gn2/wqflask/templates/startup_errors.html
@@ -0,0 +1,20 @@
+{%extends "base.html"%}
+{%block title%}Startup Error{%endblock%}
+{%block content %}
+{%if error_type == "MissingConfigurationError"%}
+
+<div class="container">
+ <h1>Startup Error</h1>
+
+ <p>
+ The application could not start due to the missing configuration settings
+ below:
+ <ul>
+ {%for setting in error_value.missing%}
+ <li class="text-danger"><strong>{{setting}}</strong></li>
+ {%endfor%}
+ </ul>
+ </p>
+</div>
+{%endif%}
+{%endblock%}
diff --git a/gn2/wqflask/templates/submit_trait.html b/gn2/wqflask/templates/submit_trait.html
new file mode 100644
index 00000000..10ddf69f
--- /dev/null
+++ b/gn2/wqflask/templates/submit_trait.html
@@ -0,0 +1,111 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ <form method="post" action="/show_temp_trait">
+ <div class="container-fluid">
+
+ {{ flash_me() }}
+
+ <div class="row" style="width: 1400px !important;">
+ <div class="col-xs-3">
+ <section id="description">
+ <div>
+ <h2 style="color: #5a5a5a;">Introduction</h2>
+ <hr>
+ <p>The trait values that you enter are statistically compared with verified genotypes collected at a set of microsatellite markers in each RI set. The markers are drawn from a set of over 750, but for each set redundant markers have been removed, preferentially retaining those that are most informative.</p>
+ <p>These error-checked RI mapping data match theoretical expectations for RI strain sets. The cumulative adjusted length of the RI maps are approximately 1400 cM, a value that matches those of both MIT maps and Chromosome Committee Report maps. See our <a target="_blank" href="http://www.nervenet.org/papers/BXN.html">full description</a> of the genetic data collected as part of the WebQTL project.</p>
+ </div>
+ </section>
+ <br>
+ <section id="description">
+ <div>
+ <h2 style="color: #5a5a5a;">About Your Data</h2>
+ <hr>
+ <p>You can open a separate window giving the number of strains for each data set and sample data.</p>
+ <p>None of your submitted data is copied or stored by this system except during the actual processing of your submission. By the time the reply page displays in your browser, your submission has been cleared from this system.</p>
+ </div>
+ </section>
+ </div>
+ <div style="padding-left:20px" class="col-xs-6" style="width: 600px !important;">
+ <section id="submission_form">
+ <div class="form-group">
+ <h2 style="color: #5a5a5a;">Trait Submission Form</h2>
+ <hr>
+ <div style="margin-bottom: 150px;" class="form-horizontal">
+ <h3>1. Choose Species and Group:</h3>
+ <br>
+ <div class="col-xs-2" style="min-height: 15vh; display: flex; align-items: center;">
+ <img src="/static/new/images/step1.gif">
+ </div>
+ <div class="col-xs-10">
+ <div class="form-group">
+ <label for="species" class="col-xs-2 control-label">Species: </label>
+ <div class="col-xs-4 controls">
+ <select name="species" id="species" class="form-control span3" style="width: 280px !important;"></select>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="group" class="col-xs-2 control-label">Group: </label>
+ <div class="col-xs-4 controls">
+ <select name="group" id="group" class="form-control span3" style="width: 280px !important;"></select>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div style="padding-bottom: 50px; margin-bottom:400px" class="form-horizontal">
+ <h3>2. Enter Trait Data:</h3>
+ <h4 style="color:red;">File uploading isn't enabled yet, but is coming soon.</h4>
+ <br>
+ <div class="col-xs-2" style="min-height: 50vh; max-height: 100vh; display: flex; align-items: center;">
+ <img src="/static/new/images/step2.gif">
+ </div>
+ <div class="col-xs-10">
+ <div class="form-group" style="padding-left: 15px;">
+ <p>
+ <b>Paste or Type Multiple Values:</b> You can enter data by pasting a series of numbers representing trait values into this area.
+ The values can be on one line separated by spaces or tabs, or they can be on separate lines. Include one value for each individual
+ or line. Use an "x" for missing values. If you have chosen a set of inbred strains, then your data will be displayed in a form in
+ which you can confirm and/or edit. If you enter a file name in the previous section,
+ any data that you paste here will be ignored. Check <a href="http://gn1.genenetwork.org/RIsample.html">sample data</a> for the correct format.
+ </p>
+ <textarea name="trait_paste" rows="6" cols="70"></textarea>
+ </div>
+ </div>
+ <div class="controls" style="display:block; margin-left: 40%; margin-right: 20%;">
+ <input type="submit" style="width: 110px; margin-right: 25px;" class="btn btn-primary form-control col-xs-2" value="Submit Trait">
+ <input type="reset" style="width: 110px;" class="btn btn-primary form-control col-xs-2" value="Reset">
+ </div>
+ </div>
+ <div style="padding-bottom: 50px;" class="form-horizontal">
+ <h3>3. Enable Use of Trait Variance:</h3>
+ <div class="col-xs-2" style=""display: flex; align-items: center;">
+ <img src="/static/new/images/step3.gif">
+ </div>
+ <div class="col-xs-10">
+ <div class="form-group" style="padding-left: 15px;">
+ <p>
+ <b>Name Your Trait:</b> <span style="color:red;">(optional)</span>
+ </p>
+ <textarea name="trait_name" rows="1" cols="30"></textarea>
+ </div>
+ </div>
+ <div class="controls" style="display:block; margin-left: 40%; margin-right: 20%;">
+ <input type="submit" style="width: 110px; margin-right: 25px;" class="btn btn-primary form-control col-xs-2" value="Submit Trait">
+ <input type="reset" style="width: 110px;" class="btn btn-primary form-control col-xs-2" value="Reset">
+ </div>
+ </div>
+ </section>
+ </div>
+ </div>
+ </div>
+ </form>
+
+{%endblock%}
+
+{% block js %}
+ <script>
+ gn_server_url = "{{ gn_server_url }}";
+ </script>
+ <script src="/static/new/javascript/dataset_select_menu_orig.js"></script>
+{% endblock %}
diff --git a/gn2/wqflask/templates/test_correlation_page.html b/gn2/wqflask/templates/test_correlation_page.html
new file mode 100644
index 00000000..991773a2
--- /dev/null
+++ b/gn2/wqflask/templates/test_correlation_page.html
@@ -0,0 +1,159 @@
+{% extends "base.html" %}
+{% block title %}Correlation Results{% endblock %}
+{% block css %}
+ <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonsBootstrap/css/buttons.bootstrap.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}">
+ <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
+ <link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+
+ <style type="text/css">
+ .td-styles{
+ height: 40px;
+ text-align: center;
+ }
+ .trait_col {
+ font-weight:bolder;
+ text-align: center;
+ color:#036ffc;
+ /*font-size: 1.1em;*/
+ }
+ table th {
+ font-weight: bolder;
+ text-transform: uppercase;
+ }
+ .correlation-title {
+ padding:25px 10px;
+ }
+ .correlation-title h3 span {
+ font-weight: bolder;
+ }
+ .header-toggle-vis {
+ padding:10px 5px;
+ }
+ .header-toggle-vis button {
+ border-radius: 5px;
+
+ }
+ </style>
+{% endblock %}
+
+{% block content %}
+
+<div class="correlation-title">
+ <h3>Correlation Results for <span>{{target_dataset}}</span> against <span><a href="">{{this_trait}}</a></span> for the top <span>{{return_results}}</span> Results</h3>
+</div>
+<div class="header-toggle-vis">
+ <h4 style="font-weight: bolder;padding: 5px 3px;">Toggle Columns</h4>
+ <button class="toggle-vis" data-column="1">Index</button>
+ <button class="toggle-vis" data-column="2">Trait Name</button>
+ <button class="toggle-vis" data-column="3">Sample r</button>
+ <button class="toggle-vis" data-column="4">Sample P(r)</button>
+ <button class="toggle-vis" data-column="5">Num overlap</button>
+</div>
+ <table id="example" class="display" width="100%">
+ <thead>
+ <tr >
+ <th></th>
+ <th>index</th>
+ <th>trait_name</th>
+ <th>Sample r</th>
+ <th>Sample r(p)</th>
+ <th>N</th>
+ <th>Tissue r</th>
+ <th>Tissue r(p)</th>
+ <th>Lit r</th>
+ </tr>
+ </thead>
+ </table>
+
+{% endblock %}
+
+{% block js %}
+<script type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
+<script type="text/javascript" src="/static/new/javascript/search_results.js"></script>
+
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/buttons.html5.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+<script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/js/all.min.js"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+<script type="text/javascript">
+ let correlationResults = {{correlation_results|safe}}
+ // document.querySelector(".content").innerHTML =correlationResults
+ // parse the data
+ let counter = 0;
+ let corr_type = "tissue";
+ correlationResults =correlationResults.map((trait_object)=>{
+ let trait_name = Object.keys(trait_object)[0]
+
+ let new_dict = {
+ "index":counter,
+ "trait_name":trait_name,
+ ...trait_object[trait_name]
+ }
+ counter++;
+ return new_dict;
+ })
+
+console.log(correlationResults)
+
+</script>
+
+<script type="text/javascript">
+ $(document).ready(function() {
+ let table = $('#example').DataTable( {
+ "data": correlationResults,
+ "columns": [
+ {"data":corr_type=="sample"?null:"fd","width":"25px"},
+ { "data": "index","width":"120px","title":"Index" },
+ { "data": "trait_name","title":"TraitName"},
+ { "data": "corr_coefficient","defaultContent": "--"},
+ { "data": "p_value","defaultContent":"--"},
+ { "data": "num_overlap","defaultContent":"--"},
+ {"data":"tissue_corr","defaultContent":"--","title":"Tissue r"},
+ {"data":"tissue_p_val","defaultContent":"--","title":"Tissue r(p)"},
+ {"data":"lit_corr","defaultContent":"--","title":"Lit rho"}
+ ],
+ "columnDefs": [
+ {
+ targets:0,
+ data:null,
+ defaultContent: '',
+ orderable: false,
+ className: 'select-checkbox',
+ "render":(data,type,row)=>{
+ return `<input type="checkbox" class="checkbox trait_checkbox" value="other">`
+ }
+
+ },
+ {className:"trait_col",targets:2},
+ {className: "td-styles", targets: "_all"},
+ {
+ "targets":2,
+ "render":(data,type,row)=>{
+ // should use a dynamic dataset name
+ let urlLink = `/show_trait?trait_id=${data}&dataset=HC_M2_0606_P`
+ let traitLink = `<a href=${urlLink}>${data}</a>`
+ return traitLink
+ },
+ }
+
+ ]
+ } );
+
+ $(":button.toggle-vis").on("click",function(e){
+ e.preventDefault()
+ let column = table.column($(this).attr("data-column"));
+ column.visible(!column.visible())
+ console.log($(this).attr("data-column"))
+ })
+} );
+</script>
+
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/tool_buttons.html b/gn2/wqflask/templates/tool_buttons.html
new file mode 100644
index 00000000..c6d1476c
--- /dev/null
+++ b/gn2/wqflask/templates/tool_buttons.html
@@ -0,0 +1,38 @@
+<button id="corr_matrix" class="btn btn-primary submit_special" data-url="/corr_matrix" title="Correlation Matrix" >
+ Correlations
+</button>
+
+<button id="network_graph" class="btn btn-primary submit_special" data-url="/network_graph" title="Network Graph" >
+ Networks
+</button>
+
+<button id="send_to_webgestalt" class="btn btn-primary submit_special" data-url="/webgestalt_page" title="WebGestalt" >
+ WebGestalt
+</button>
+
+<button id="send_to_geneweaver" class="btn btn-primary submit_special" data-url="/geneweaver_page" title="GeneWeaver" >
+ GeneWeaver
+</button>
+
+<button id="send_to_bnw" class="btn btn-primary submit_special" data-url="/bnw_page" title="Bayesian network software for causal modeling and reasoning, with an intuitive interface to incorporate biological knowledge and a complete pipeline from data to model to prediction" >
+ BNW
+</button>
+
+<button id="wgcna_setup" class="btn btn-primary submit_special" data-url="/wgcna_setup" title="WGCNA Analysis" >
+ WGCNA
+</button>
+
+<button id="ctl_setup" class="btn btn-primary submit_special" data-url="/ctl_setup" title="CTL Analysis" >
+ CTL Maps
+</button>
+
+<button id="heatmap" class="btn btn-primary submit_special" data-url="/heatmap" title="Heatmap" >
+ MultiMap
+</button>
+
+<button id="partial-correlations"
+ class="btn btn-primary submit_special"
+ data-url="{{url_for('partial_correlations')}}"
+ title="Run partial correlations with the selected traits">
+ Partial Correlations
+</button>
diff --git a/gn2/wqflask/templates/tutorials.html b/gn2/wqflask/templates/tutorials.html
new file mode 100644
index 00000000..74c84726
--- /dev/null
+++ b/gn2/wqflask/templates/tutorials.html
@@ -0,0 +1,256 @@
+{% extends "base.html" %}
+{% block title %}Tutorials/Primers{% endblock %}
+{% block content %}
+
+<head>
+ <title>GeneNetwork Webinar Series, Tutorials and Short Video Tours</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+<!-- <link rel="stylesheet" href="uikit-3/css/uikit.min.css" />-->
+<!-- <script src="uikit-3/js/uikit.min.js"></script>-->
+<!-- <script src="uikit-3/js/uikit-icons.min.js"></script>-->
+ <!-- UIkit CSS -->
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.5.4/dist/css/uikit.min.css" />
+
+ <!-- UIkit JS -->
+ <script src="https://cdn.jsdelivr.net/npm/uikit@3.5.4/dist/js/uikit.min.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/uikit@3.5.4/dist/js/uikit-icons.min.js"></script>
+
+ <!-- DataTables-->
+ <!-- <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.21/cr-1.5.2/datatables.min.css"/> -->
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css"/>
+
+ <script type="text/javascript" src="https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.21/cr-1.5.2/datatables.min.js"></script>
+ <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script>
+ <script type="text/javascript" src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
+
+</head>
+<body>
+<div class="uk-margin-small uk-card uk-card-default uk-card-body">
+ <!-- <div class="row">-->
+ <!-- <div class="col-lg-12">
+ <p>Primary Sponsor</p>
+ <img class="img-responsive" src="images/illumina_logo.jpg" alt=""> <h2 class="page-header">Program (Preliminary)</h2>
+ </div>-->
+ <div class="col-lg-12">
+
+ <ul id="myTab" class="nav nav-tabs nav-justified">
+ <li class="active"><a href="#service-one" data-toggle="tab"><i class="fa fa-file-text-o"></i>Webinars</a>
+ </li>
+ <li class=""><a href="#service-two" data-toggle="tab"><i class="fa fa-file-text-o"></i>Short Video Tours</a>
+ </li>
+ <li class=""><a href="#service-three" data-toggle="tab"><i class="fa fa-file-text-o"></i>Tutorials</a>
+ </li>
+ <li class=""><a href="#service-four" data-toggle="tab"><i class="fa fa-file-text-o"></i>Documentation</a>
+ </li>
+ </ul>
+<p></p>
+ <div id="myTabContent" class="tab-content">
+ <div class="tab-pane fade active in" id="service-one">
+ <table id="myTable" class="display">
+ <thead>
+ <tr>
+ <th>Title/Description</th>
+ <th>Presentation</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><p><h3>Introduction to Quantitative Trait Loci (QTL) Analysis</h3>
+ <p>Goals of this webinar (trait variance to QTL):</p>
+ <ul>
+ <li>Define quantitative trait locus (QTL)</li>
+ <li>Explain how genome scans can help find QTL</li>
+ </ul>
+ <p>Presented by:<br>
+Dr. Saunak Sen<br>
+Professor and Chief of Biostatistics<br>
+Department of Preventative Medicine<br>
+University of Tennessee Health Science Center
+</p>
+<p><a href="https://github.com/OSGA-OPAR/quant-genetics-webinars/blob/master/2020-05-08/README.md">Link to course material</a>
+</p></td>
+ <td>
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/leY3kPmnLaI" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></td>
+ </tr>
+ <tr>
+ <td><p><h3>Mapping Addiction and Behavioral Traits and Getting at Causal Gene Variants with GeneNetwork</h3>
+ <p>Goals of this webinar (QTL to gene variant):</p>
+ <ul>
+ <li>Demonstrate mapping a quantitative trait using GeneNetwork (GN)</li>
+ <li>Explore GN tools to identify genes and genetics variants related to a QTL</li>
+ </ul>
+ <p>Presented by:<br>
+Dr. Rob Williams<br>
+Professor and Chair<br>
+Department of Genetics, Genomics, and Informatics<br>
+University of Tennessee Health Science Center
+</p><p><a href="https://github.com/OSGA-OPAR/quant-genetics-webinars/blob/master/2020-05-22/README.md">Link to course material</a>
+</p></td>
+ <td><iframe width="560" height="315" src="https://www.youtube.com/embed/LwpXzLHX9aM" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></td>
+ </tr>
+
+ <!--NEW WEBINAR STARTS HERE-->
+ <tr>
+ <td><p><h3>Data structure, disease risk, GXE, and causal modeling</h3>
+
+ <p>Human disease is mainly due to complex interactions between genetic and environmental factors (GXE). We need to acquire the right "smart" data types—coherent and multiplicative data—required to make accurate predictions about risk and outcome for n = 1 individuals—a daunting task. We have developed large families of fully sequenced mice that mirror the genetic complexity of humans. We are using these Reference Populations to generate multiplicatively useful data and to build and test causal quantitative models of disease mechanisms with a special focus on diseases of aging, addiction, and neurological and psychiatric disease.
+
+<p>Speaker Bio: Robert (Rob) W. Williams received a BA in neuroscience from UC Santa Cruz (1975) and a Ph.D. in system physiology at UC Davis with Leo M. Chalupa (1983). He did postdoctoral work in developmental neurobiology at Yale School of Medicine with Pasko Rakic where he developed novel stereological methods to estimate cell populations in brain. In 2013 Williams established the Department of Genetics, Genomics and Informatics at UTHSC. He holds the UT Oak Ridge National Laboratory Governor’s Chair in Computational Genomics. Williams is director of the Complex Trait Community (www.complextrait.org) and editor-in-chief of Frontiers in Neurogenomics. One of Williams’ more notable contributions is in the field of systems neurogenetics and experimental precision medicine. He and his research collaborators have built GeneNetwork (www.genenetwork.org), an online resource of data and analysis code that is used as a platform for experimental precision medicine.</p>
+
+ <p>Presented by:<br>
+Dr. Rob Williams<br>
+Professor and Chair<br>
+Department of Genetics, Genomics, and Informatics<br>
+University of Tennessee Health Science Center
+</p>
+<!--<p>There is no fee associated with this webinar, but users are asked to register to receive the Zoom link and password.
+Registration: <a href="https://bit.ly/osga_2020-11-20">https://bit.ly/osga_2020-11-20</a>-->
+<!--<p>This webinar series is sponsored by the NIDA Center of Excellence in Omics, Systems Genetics, and the Addictome (P30 DA044223). -->
+</td>
+ <!--<td><strong>After the presentation, the recording will be made available here.</strong></td>-->
+ <td><iframe width="560" height="315" src="https://www.youtube.com/embed/4ZhnXU8gV44" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+ </tr>
+ <!--WEBINAR ENDS HERE-->
+
+ </tbody>
+ </table>
+
+<script>
+$('#myTable').dataTable( {
+ "lengthMenu": [ 50, 75, 100 ]
+} );
+</script>
+ </div>
+ <div class="tab-pane fade" id="service-two">
+ <table id="myTable2" class="display">
+ <thead>
+ <tr>
+ <th>Title/Description</th>
+ <th>Presentation</th>
+ </tr>
+ </thead>
+ <tbody>
+
+ <!--NEW WEBINAR STARTS HERE-->
+ <tr>
+ <td><p><h3>Introduction to Gene Network</h3>
+ <p><i>Please note that this tutorial is based on GeneNetwork v1</i>
+
+<p>GeneNetwork is a group of linked data sets and tools used to study complex networks of genes, molecules, and higher order gene function and phenotypes. GeneNetwork combines more than 25 years of legacy data generated by hundreds of scientists together with sequence data (SNPs) and massive transcriptome data sets (expression genetic or eQTL data sets). The quantitative trait locus (QTL) mapping module that is built into GN is optimized for fast on-line analysis of traits that are controlled by combinations of gene variants and environmental factors. GeneNetwork can be used to study humans, mice (BXD, AXB, LXS, etc.), rats (HXB), Drosophila, and plant species (barley and Arabidopsis). Most of these population data sets are linked with dense genetic maps (genotypes) that can be used to locate the genetic modifiers that cause differences in expression and phenotypes, including disease susceptibility.
+
+<p>Users are welcome to enter their own private data directly into GeneNetwork to exploit the full range of analytic tools and to map modulators in a powerful environment. This combination of data and fast analytic functions enable users to study relations between sequence variants, molecular networks, and function.</p>
+
+ <p>Presented by:<br>
+Dr. Rob Williams<br>
+Professor and Chair<br>
+Department of Genetics, Genomics, and Informatics<br>
+University of Tennessee Health Science Center
+</p>
+<!--<p>There is no fee associated with this webinar, but users are asked to register to receive the Zoom link and password.
+Registration: <a href="https://bit.ly/osga_2020-11-20">https://bit.ly/osga_2020-11-20</a>-->
+<!--<p>This webinar series is sponsored by the NIDA Center of Excellence in Omics, Systems Genetics, and the Addictome (P30 DA044223). -->
+</td>
+ <!--<td><strong>After the presentation, the recording will be made available here.</strong></td>-->
+ <td>
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/B3g_0q-ldJ8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+ </tr>
+ <!--WEBINAR ENDS HERE-->
+
+ <!--NEW WEBINAR STARTS HERE-->
+ <tr>
+ <td><p><h3>How to search in GeneNetwork</h3><br>Presented by Rob Williams University of Tennessee Health Science Center</td>
+ <!--<td><p><h3>How to search in GeneNetwork</h3>
+</td>-->
+ <td>
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/5exnkka5Tso" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </td>
+ </tr>
+ <!--WEBINAR ENDS HERE-->
+
+ <!--NEW WEBINAR STARTS HERE-->
+ <tr>
+ <td><p><h3>GeneNetwork.org: genetic analysis for all neuroscientists</h3><br>Presented by David G. Ashbrook Assistant Professor University of Tennessee Health Science Center
+</td>
+ <td>
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/JmlVLki09Q8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></td>
+ </tr>
+ <!--WEBINAR ENDS HERE-->
+ </tbody>
+ </table>
+
+<script>
+$('#myTable2').dataTable( {
+ "lengthMenu": [ 50, 75, 100 ]
+} );
+</script>
+ </div>
+ <div class="tab-pane fade" id="service-three">
+ <table id="myTable3" class="display">
+ <thead>
+ <tr>
+ <th>Title</th>
+ <th>Speaker</th>
+ <th>Video link</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td>Diallel Crosses, Artificial Intelligence, and Mouse Models of Alzheimer’s Disease</td>
+ <td>David G. Ashbrook<br>Assistant Professor<br>University of Tennessee Health Science Center</td>
+ <td><a href="https://www.youtube.com/watch?v=HKfYc8CJwqM">YouTube link</a></td>
+ </tr>
+
+
+ </tbody>
+ </table>
+ <script>
+$('#myTable3').dataTable( {
+ "lengthMenu": [ 50, 75, 100 ]
+} );
+</script>
+ </div>
+
+ <div class="tab-pane fade" id="service-four">
+ <table id="myTable4" class="display">
+ <thead>
+ <tr>
+ <th>Title</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td><a href="https://www.biorxiv.org/content/10.1101/2020.12.23.424047v1">GeneNetwork: a continuously updated tool for systems genetics analyses</a></td></tr>
+ <tr><td><a href="https://doi.org/10.3390/genes13040614">New Insights on Gene by Environmental Effects of Drugs of Abuse in Animal Models Using GeneNetwork</a></td>
+ <tr><td><a href="https://www.opar.io/pdf/Rat_HRDP_Brain_Proteomics_Wang_WIlliams_08Oct2021.pdf">A Primer on Brain Proteomics and protein-QTL Analysis for Substance Use Disorders</a></td></tr>
+
+ </tbody>
+ </table>
+ <script>
+$('#myTable4').dataTable( {
+ "lengthMenu": [ 50, 75, 100 ]
+} );
+</script>
+ </div>
+ </div>
+
+ </div>
+ </div>
+
+</div>
+
+ <hr>
+
+
+
+ </div>
+ <!-- /.container -->
+
+ <!-- jQuery -->
+ <script src="js/jquery.js"></script>
+
+ <!-- Bootstrap Core JavaScript -->
+ <script src="js/bootstrap.min.js"></script>
+
+</body>
+
+
+{% endblock %}
+
diff --git a/gn2/wqflask/templates/view_case_attribute_diff.html b/gn2/wqflask/templates/view_case_attribute_diff.html
new file mode 100644
index 00000000..0b5c95f1
--- /dev/null
+++ b/gn2/wqflask/templates/view_case_attribute_diff.html
@@ -0,0 +1,117 @@
+{%extends "base.html"%}
+{%block title%}View Case Attribute Diff{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+
+<style>
+ .table-fixed-head {overflow-y: auto; height: 32em;}
+ .table-fixed-head thead th {position: sticky; top: 0;}
+ .diff-row {
+ display: grid;
+ grid-template-columns: 1rem 9rem;
+ column-gap: 0.5em;
+ padding: 0.5em;
+ background:#CCCCCC;
+ border-color:#FFFFFF;
+ border-style:solid;
+ border-radius: 10px;
+ }
+ .diff-indicator {
+ grid-column-start: 1;
+ grid-column-end: 2;
+ }
+ .diff-original {
+ grid-column-start: 2;
+ grid-column-end: 3;
+ }
+ .diff-current {
+ grid-column-start: 2;
+ grid-column-end: 3;
+ }
+ .diff-addition {color: green; font-weight: bold;}
+ .diff-deletion {color: red; font-weight: bold;}
+ form input[type="submit"] {
+ text-transform: capitalize;
+ }
+</style>
+{%endblock%}
+
+{%block content%}
+<div class="container">
+ <h1>View Diff</h1>
+
+ {{flash_me()}}
+
+ <div id="diff-display" class="panel panel-primary">
+ <div class="panel-heading">
+ <h3 class="panel-title">Changes</h3>
+ </div>
+ <div class="panel-body">
+ {%set the_diff = diff.json_diff_data.diff%}
+ {%if the_diff.Additions | length %}
+ <h4>Additions</h4>
+ <div class="diff-row">
+ <span class="diff-indicator"></span>
+ <span class="diff-original"></span>
+ <span class="diff-indicator diff-addition">+</span>
+ <span class="diff-current diff-addition">{{item.Current}}</span>
+ </div>
+ {%endif%}
+ {%if the_diff.Modifications | length %}
+ <h4>Modifications</h4>
+ {%for item in the_diff.Modifications%}
+ <div class="diff-row">
+ <span class="diff-indicator diff-deletion">-</span>
+ <span class="diff-original diff-deletion">{{item.Original}}</span>
+ <span class="diff-indicator diff-addition">+</span>
+ <span class="diff-current diff-addition">{{item.Current}}</span>
+ </div>
+ {%endfor%}
+ {%endif%}
+ {%if the_diff.Deletions | length %}
+ <h4>Deletions</h4>
+ <div class="diff-row">
+ <span class="diff-indicator diff-addition">+</span>
+ <span class="diff-original diff-addition">{{item.Original}}</span>
+ <span class="diff-indicator diff-deletion">-</span>
+ <span class="diff-current diff-deletion">{{item.Current}}</span>
+ </div>
+ {%endif%}
+ </div>
+ <div class="panel-footer">
+ <p>Edited by: {{diff.json_diff_data.user_id}}</p>
+ </div>
+ </div>
+
+
+
+ <form method="POST" action="{{url_for('approve_reject_diff')}}">
+ <input type="hidden"
+ name="diff_id"
+ value="{{diff.id}}" />
+ <input type="hidden"
+ name="diff_data"
+ value='{{diff.json_diff_data | tojson}}' />
+ <input type="submit"
+ name="action"
+ title="Approve the changes"
+ class="btn btn-warning"
+ value="approve" />
+ <input type="submit"
+ name="action"
+ title="Reject the changes"
+ class="btn btn-danger"
+ value="reject" />
+ </form>
+{%endblock%}
+
+{%block js%}
+<script language="javascript"
+ type="text/javascript"
+ src="{{url_for('js', filename='DataTables/js/jquery.js')}}"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/view_case_attribute_diff_error.html b/gn2/wqflask/templates/view_case_attribute_diff_error.html
new file mode 100644
index 00000000..a10f7ab9
--- /dev/null
+++ b/gn2/wqflask/templates/view_case_attribute_diff_error.html
@@ -0,0 +1,35 @@
+{%extends "base.html"%}
+{%block title%}View Case Attribute Diff{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+
+<style>
+ .table-fixed-head {overflow-y: auto; height: 32em;}
+ .table-fixed-head thead th {position: sticky; top: 0;}
+</style>
+{%endblock%}
+
+{%block content%}
+<div class="container">
+ <h1>View Diff</h1>
+
+ {{flash_me()}}
+
+ <p class="text-danger">
+ <span class="glyphicon glyphicon-exclamation-sign">
+ </span>
+ <strong>{{error.status_code}}: {{error["error"]}}</strong>
+ {{error.error_description}}
+ </p>
+{%endblock%}
+
+{%block js%}
+<script language="javascript"
+ type="text/javascript"
+ src="{{url_for('js', filename='DataTables/js/jquery.js')}}"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/webgestalt_page.html b/gn2/wqflask/templates/webgestalt_page.html
new file mode 100644
index 00000000..759e0251
--- /dev/null
+++ b/gn2/wqflask/templates/webgestalt_page.html
@@ -0,0 +1,35 @@
+{% extends "base.html" %}
+{% block title %}{% if wrong_input == "True" %}WebGestalt Error{% else %}Opening WebGestalt{% endif %}{% endblock %}
+{% block content %}
+ {% if wrong_input == "True" %}
+ {{ header("Error") }}
+
+ <div class="container">
+ {% if chip_name == "mixed" %}
+ <h3>Sorry, the analysis was interrupted because your selections from GeneNetwork apparently include data from more than one array platform (i.e., Affymetrix U74A and M430 2.0). Most WebGestalt analyses assume that you are using a single array type and compute statistical values on the basis of that particular array. Please reselect traits from a signle platform and submit again.</h3>
+ {% elif chip_name == "not_microarray" %}
+ <h3>You need to select at least one microarray trait to submit.</hr>
+ {% elif '_NA' in chip_name %}
+ <h3>Sorry, the analysis was interrupted because your selections from GeneNetwork apparently include data from platform {{ chip_name }} which is unknown by WebGestalt. Please reselect traits and submit again.</h3>
+ {% else %}
+ <h3>Sorry, an error occurred while submitting your traits to WebGestalt.</h3>
+ {% endif %}
+ </div>
+ {% else %}
+ <div class="container">
+ <h3>Opening WebGestalt...</h3>
+ </div>
+ <form method="post" action="https://www.webgestalt.org/option.php" name="WebGestalt">
+ {% for key in hidden_vars %}
+ <input type="hidden" name="{{ key }}" value="{{ hidden_vars[key] }}">
+ {% endfor %}
+ </form>
+ {% endif %}
+{% endblock %}
+{% block js %}
+{% if wrong_input == "False" %}
+<script type="text/javascript">
+ setTimeout('document.WebGestalt.submit()', 1000);
+</script>
+{% endif %}
+{% endblock %}
diff --git a/gn2/wqflask/templates/wgcna_results.html b/gn2/wqflask/templates/wgcna_results.html
new file mode 100644
index 00000000..0dc030b1
--- /dev/null
+++ b/gn2/wqflask/templates/wgcna_results.html
@@ -0,0 +1,76 @@
+{% extends "base.html" %}
+{% block title %}WCGNA results{% endblock %}
+
+{% block content %} <!-- Start of body -->
+ <div class="container">
+ <h1>WGCNA Results</h1>
+ Analysis found {{results['nmod']}} modules when scanning {{results['nphe']}} phenotypes, measured on {{results['nstr']}} strains.<br>
+ Additional parameters settings:
+ <ul>
+ <li>Soft thresholds checked = {{results['requestform']['SoftThresholds']}}</li>
+ <li>Power used for this analysis = {{results['Power']}}</li>
+ <li>TomType = {{results['requestform']['TOMtype']}}</li>
+ <li>Minimum module size = {{results['requestform']['MinModuleSize'] }}</li>
+ <li>mergeCutHeight = {{results['requestform']['mergeCutHeight'] }}</li>
+ </ul>
+
+ <h3>Soft threshold table</h3>
+ <table width="80%">
+ <tr><th>Power</th><th>SFT.R.sq</th><th>slope</th><th>truncated.R.sq</th><th>mean.k</th><th>median.k</th><th>max.k</th><th>Analysis</th></tr>
+ {% for r in range(powers[0][0]|length) %}
+ {% if powers[0][1][r] > 0.85 %}
+ <tr style="color: #00ff00;">
+ {% elif powers[0][1][r] > 0.75 %}
+ <tr style="color: #aaaa00;">
+ {% else %}
+ <tr style="color: #ff0000;">
+ {% endif %}
+ {% for c in range(powers[0]|length) %}
+ <td>{{powers[0][c][r]|round(3)}}</td>
+ {% endfor %}
+ <td style="color: #000000;">
+ {% if powers[0][1][r] > 0.75 %}
+ <input type="submit" value="Redo use power = {{powers[0][0][r]}}" /></td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+ </table>
+ <h3>WGCNA module plot</h3>
+ <a href="/tmp/{{ results['imgurl'] }}">
+ <img alt="Embedded Image" src="data:image/png;base64,
+ {% for elem in results['imgdata'] -%}
+ {% print("%c"|format(elem)) %}
+ {%- endfor %}
+ " /></a>
+
+
+ <h3>Phenotype / Module table</h3>
+ <table width="80%">
+ <tr><th>Phenotype</th><th>Module</th></tr>
+ {% for r in range(results['nphe']) %}
+ <tr>
+ <td>{{results['phenotypes'][r][0]}}</td>
+ <td>{{results['network'][0][r]}}</td>
+ </tr>
+ {% endfor %}
+ </table>
+
+ <h3>Module eigen genes</h3>
+ <table width="80%">
+ <tr><th>Phenotype</th>
+ {% for m in range(results['nmod']) %}
+ <th><input type="submit" value="Add module {{m}} to collection" /></th>
+ {% endfor %}
+ </tr>
+ {% for r in range(results['nstr']) %}
+ <tr>
+ <td>{{results['strains'][r][0]}}</td>
+ {% for m in range(results['nmod']) %}
+ <td>{{results['network'][2][m][r]}}</td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </table>
+ </div>
+{% endblock %}
+
diff --git a/gn2/wqflask/templates/wgcna_setup.html b/gn2/wqflask/templates/wgcna_setup.html
new file mode 100644
index 00000000..d7acd5f2
--- /dev/null
+++ b/gn2/wqflask/templates/wgcna_setup.html
@@ -0,0 +1,142 @@
+{% extends "base.html" %}
+{% block title %}WCGNA analysis{% endblock %}
+{% block content %}
+<!-- Start of body -->
+<style type="text/css">
+
+#terminal {
+ margin-top: 10px;
+}
+
+</style>
+
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='xterm/xterm.min.css') }}" />
+
+<div class="container">
+ <div class="col-md-5">
+ <h1 class="mx-3 my-2 "> WGCNA analysis parameters</h1>
+ {% if request.form['trait_list'].split(",")|length < 4 %} <div class="alert alert-danger" role="alert">
+ <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
+ <span class="sr-only">Error:</span>
+ <h2>Too few phenotypes as input</h2>
+ Please make sure you select enough phenotypes / genes to perform WGCNA. Your collection needs to contain at least 4 different phenotypes. You provided {{request.form['trait_list'].split(',')|length}} phenotypes as input.
+ </div>
+ {% else %}
+ <form class="col-md-12" action="/wgcna_results" method="post" class="form-horizontal" id="wgcna_form">
+ <input type="hidden" name="trait_list" id="trait_list" value="{{request.form['trait_list']}}">
+ <div class="form-group row ">
+ <label for="SoftThresholds" class="col-md-3 col-form-label col-form-label-sm">Soft threshhold</label>
+ <div class="col-md-9">
+ <input type="text" class="form-control form-control-md" value="1,2,3,4,5,6,7,8,9" id="SoftThresholds" name="SoftThresholds">
+ </div>
+ </div>
+ <div class="form-group row ">
+ <label for="MinModuleSize" class="col-md-3 col-form-label col-form-label-sm">Minimum module size:</label>
+ <div class="col-md-9">
+ <input type="text" class="form-control form-control-md" id="MinModuleSize" value="30" name="MinModuleSize">
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="TOMtype" class="col-md-3 col-form-label col-form-label-sm">TOMtype:</label>
+ <div class="col-md-9">
+ <select class="form-control" id="TOMtype" name="TOMtype">
+ <option value="unsigned">unsigned</option>
+ <option value="signed">signed</option>
+ </select>
+ </div>
+
+ </div>
+ <div class="form-group row ">
+ <label for="mergeCutHeight" class="col-md-3 col-form-label col-form-label-sm">mergeCutHeight:</label>
+ <div class="col-md-9">
+ <input type="text" class="form-control form-control-md" id="mergeCutHeight" value="0.25" name="mergeCutHeight">
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="corType" class="col-md-3 col-form-label col-form-label-sm">corType:</label>
+ <div class="col-md-9">
+ <select class="form-control col-md-9" id="corType" name="corType">
+ <option value="pearson">pearson</option>
+ <option value="bicor">bicor</option>
+ </select>
+ </div>
+
+ </div>
+ <div class="form-group">
+ <div class="text-center">
+ <input type="submit" class="btn btn-primary" value="Run WGCNA using these settings" />
+ </div>
+ </div>
+
+
+
+ </form>
+ {% endif %}
+</div>
+<div class="col-md-7">
+ <div id="terminal" class="mt-2">
+ </div>
+</div>
+</div>
+
+<script src="{{ url_for('js', filename='xterm/xterm.min.js') }}" type="text/javascript"></script>
+<script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script>
+<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js"></script>
+
+<script>
+document.addEventListener('DOMContentLoaded', function() {
+let term = new Terminal({
+ cursorBlink: true,
+ lineHeight: 1.3,
+ scrollback: true,
+ macOptionIsMeta: true
+});
+
+let termDebugs = {
+ general: "Computation process to be displayed here....",
+ success: "Computation in process ......",
+ fail: "Too few phenotypes as input must be >=4"
+}
+
+const fitAddon = new FitAddon.FitAddon()
+term.loadAddon(fitAddon)
+
+term.open(document.getElementById('terminal'));
+term.setOption('theme', {
+ background: '#300a24'
+});
+term.writeln(termDebugs.general)
+
+wgcnaForm = document.querySelector("#wgcna_form")
+
+fitAddon.fit()
+term.onData((data) => {
+ term.write(data)
+})
+
+
+if (wgcnaForm) {
+} else {
+ term.writeln(termDebugs.fail)
+}
+
+$(document).on('submit', '#wgcna_form', function(e) {
+ term.writeln(termDebugs.success)
+
+ e.preventDefault();
+ var form = $(this);
+ $.ajax({
+ type: 'POST',
+ url: '/wgcna_results',
+ data: form.serialize(),
+ success: function(data) {
+ document.write(data)
+ }
+ })
+})
+})
+
+</script>
+{% endblock %} \ No newline at end of file
diff --git a/gn2/wqflask/templates/with-trait-items.html b/gn2/wqflask/templates/with-trait-items.html
new file mode 100644
index 00000000..66d6fd22
--- /dev/null
+++ b/gn2/wqflask/templates/with-trait-items.html
@@ -0,0 +1,18 @@
+{%for trait in traits_list:%}
+<div class="with-trait">
+ <input type="{%if step=='select-primary':%}radio{%else:%}checkbox{%endif%}"
+ name="{%if step=='select-primary':%}primary_trait{%else:%}control_traits[]{%endif%}"
+ value="{{trait['name']}}:::{{trait['dataset']}}:::{{trait['symbol']}}:::{{trait['description']}}:::{{trait['location']}}:::{{trait['mean_expr']}}:::{{trait['max_lrs']}}:::{{trait['data_hmac']}}"
+ id="trait_{{trait['data_hmac']}}"
+ class="selector-element" />
+ <label for="trait_{{trait['data_hmac']}}" class="label-element">
+ <span class="trait-dataset" data-title="dataset">{{trait["dataset"]}}</span>
+ <span class="trait-name" data-title="name">{{trait["name"]}}</span>
+ <span class="trait-symbol" data-title="symbol">{{trait["symbol"]}}</span>
+ <span class="trait-description" data-title="description">{{trait["description"]}}</span>
+ <span class="trait-locatin" data-title="location">{{trait["location"]}}</span>
+ <span class="trait-mean-expr" data-title="mean">{{"%0.3f" % trait["mean_expr"]|float}}</span>
+ <span class="trait-max-lrs" data-title="max LRS">{{trait["max_lrs"]}}</span>
+ </label>
+</div>
+{%endfor%}