From ba0cb1d6058acc4347f751979c950795cb4e1c3b Mon Sep 17 00:00:00 2001 From: guerler Date: Fri, 28 Jul 2017 15:30:26 -0400 Subject: [PATCH] Only initialize router if passed --- client/galaxy/scripts/layout/page.js | 2 +- static/maps/layout/page.js.map | 2 +- static/scripts/bundled/admin.bundled.js.map | 2 +- static/scripts/bundled/analysis.bundled.js.map | 2 +- static/scripts/bundled/libs.bundled.js | 4 ++-- static/scripts/bundled/libs.bundled.js.map | 2 +- static/scripts/layout/page.js | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/galaxy/scripts/layout/page.js b/client/galaxy/scripts/layout/page.js index 232ae0abde3..57bb81a1f2c 100644 --- a/client/galaxy/scripts/layout/page.js +++ b/client/galaxy/scripts/layout/page.js @@ -49,7 +49,7 @@ define( [ 'layout/masthead', 'layout/panel', 'mvc/ui/ui-modal' ], function( Mast this.render(); // start the router - Backbone.history.start({ + this.router && Backbone.history.start({ root : Galaxy.root, pushState : true, }); diff --git a/static/maps/layout/page.js.map b/static/maps/layout/page.js.map index 24d968c481b..2f22488527d 100644 --- a/static/maps/layout/page.js.map +++ b/static/maps/layout/page.js.map @@ -1 +1 @@ -{"version":3,"file":"page.js","sources":["../../src/layout/page.js"],"names":["define","Masthead","Panel","Modal","View","Backbone","extend","el","className","_panelids","initialize","options","self","this","config","_","defaults","message_box_visible","message_box_content","message_box_class","show_inactivity_warning","inactivity_box_content","Galaxy","modal","display","view","center","router","Router","masthead","CenterPanel","$el","attr","html","_template","$","replaceWith","append","frame","$messagebox","$inactivebox","panels","each","panel_id","panel_class_name","charAt","toUpperCase","slice","panel_class","panel_instance","toString","SidePanel","id","render","history","start","root","pushState","remove","renderMessageBox","renderInactivityBox","renderPanels","_checkCommunicationServerOnline","content","level","addClass","toggle","show","removeClass","hide","verificationLink","text","panel","css","join","host","window","communication_server_host","port","communication_server_port","preferences","user","attributes","$chat_icon_element","indexOf","communication_server","ajax","url","success","error"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"page.js","sources":["../../src/layout/page.js"],"names":["define","Masthead","Panel","Modal","View","Backbone","extend","el","className","_panelids","initialize","options","self","this","config","_","defaults","message_box_visible","message_box_content","message_box_class","show_inactivity_warning","inactivity_box_content","Galaxy","modal","display","view","center","router","Router","masthead","CenterPanel","$el","attr","html","_template","$","replaceWith","append","frame","$messagebox","$inactivebox","panels","each","panel_id","panel_class_name","charAt","toUpperCase","slice","panel_class","panel_instance","toString","SidePanel","id","render","history","start","root","pushState","remove","renderMessageBox","renderInactivityBox","renderPanels","_checkCommunicationServerOnline","content","level","addClass","toggle","show","removeClass","hide","verificationLink","text","panel","css","join","host","window","communication_server_host","port","communication_server_port","preferences","user","attributes","$chat_icon_element","indexOf","communication_server","ajax","url","success","error"],"mappings":"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"} \ No newline at end of file diff --git a/static/scripts/bundled/admin.bundled.js.map b/static/scripts/bundled/admin.bundled.js.map index 84957093209..fd3095af12a 100644 --- a/static/scripts/bundled/admin.bundled.js.map +++ b/static/scripts/bundled/admin.bundled.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///admin.bundled.js","webpack:///./galaxy/scripts/apps/admin.js","webpack:///./galaxy/scripts/mvc/ui/ui-misc.js?fd98*","webpack:///./galaxy/scripts/mvc/ui/ui-buttons.js?4ced*","webpack:///./galaxy/scripts/mvc/grid/grid-view.js?be4f*","webpack:///./galaxy/scripts/mvc/ui/ui-options.js?405a*","webpack:///./galaxy/scripts/mvc/ui/popup-menu.js?a948*","webpack:///./galaxy/scripts/mvc/ui/ui-select-default.js?402d*","webpack:///./galaxy/scripts/mvc/grid/grid-model.js?e551*","webpack:///./galaxy/scripts/mvc/grid/grid-template.js?73e1*","webpack:///./galaxy/scripts/mvc/ui/ui-drilldown.js?de06*","webpack:///./galaxy/scripts/mvc/ui/ui-slider.js?93a7*","webpack:///./galaxy/scripts/layout/router.js?1c11","webpack:///./galaxy/scripts/apps/panels/admin-panel.js"],"names":["webpackJsonp","0","module","exports","__webpack_require__","_","jQuery","$","GalaxyApp","AdminPanel","GridView","Router","Page","window","app","options","bootstrapped","Galaxy","debug","params","config","AdminRouter","extend","routes","(/)admin(/)users","authenticate","args","name","user","id","get","show_users","this","page","display","url_base","root","dict_format","active_view","View","Left","call","7","__WEBPACK_AMD_DEFINE_ARRAY__","__WEBPACK_AMD_DEFINE_RESULT__","Backbone","Utils","Select","Slider","Options","Drilldown","Buttons","Modal","Label","tagName","initialize","model","Model","setElement","listenTo","render","title","new_title","set","value","$el","removeClass","addClass","html","Message","message","status","cls","persistent","fade","update","messageForDisplay","timeout","clearTimeout","self","setTimeout","fadeOut","escape","UnescapedMessage","Input","type","placeholder","disabled","readonly","visible","area","color","style","events","input","new_val","undefined","attr","css","datalist","isArray","length","autocomplete","source","request","response","change","_onchange","val","each","attr_name","removeAttr","Hidden","append","$info","$hidden","show","text","hide","Upload","$file","$text","$wait","on","e","_readFile","file","target","files","reader","FileReader","onload","wait","result","readAsText","Button","ButtonDefault","ButtonIcon","ButtonCheck","ButtonMenu","ButtonLink","RadioButton","Checkbox","Radio","apply","9","uid","floating","icon","wait_text","wait_cls","percentage","$icon","$title","$progress","$progress_bar","attributes","off","onclick","tooltip","placement","width","prop","disable","enable","unwait","setIcon","href","icons","onchange","total","$button","$menu","pull","onunload","tag","collection","Collection","$root","float","where","preventDefault","remove","submodel","suboptions","$link","divider","addMenu","add","merge","11","ajaxSettings","traditional","GridModel","Templates","PopupMenu","grid","grid_config","add_tag_to_grid_filter","tag_name","tag_value","advanced_search","is","slideToggle","add_filter_condition","items","url_data","filters","v","k","ajax","url","param","success","embedded","init_grid","use_panels","padding","overflow","handle_refresh","refresh_frames","inArray","top","currHistoryPanel","loadCurrentHistory","replace","find","header","body","footer","use_hide_message","init_grid_elements","init_grid_controls","init_refresh_on_change","click","submit_operation","select","keyup","set_sort_condition","submit","column_key","text_input_obj","text_input","parent","remove_filter_condition","set_categorical_filter","check_all_items","checkboxes","check_count","update_checked","filter","rating","set_page","execute","items_length","item","index","button","popup","operation","_add_operation","settings","operation_config","label","allowed","allow_popup","addItem","url_args","confirmation_text","confirm","func","encode_id","findItemByHtml","add_filter","t","filter_element","container","go_page_one","remove_filter","col_key","cur_sort","new_sort","indexOf","substring","sort_arrow","new_value","category_filter","cur_value","trim","filter_value","empty","new_page","page_num","parseInt","split","cur_page","children","operation_button","operation_name","number_of_checked_ids","findWhere","operations","item_ids","push","check","state","c","href_parts","href_parms_str","href_parms","toLowerCase","location","get_url_data","can_async_op","update_grid","go_to","async","$div","closest","load","method","data","error","alert","response_text","insert","json","parseJSON","complete","12","Base","error_text","multiple","optional","_changeValue","_changeWait","_changeData","_changeVisible","$message","$options","_template","all_button","_getValue","trigger","_templateOptions","option","_templateOption","_messageShow","_setValue","first","values","selected","isEmpty","BaseIcons","pair","prototype","15","menu","event","_renderAndShow","clickEvent","appendTo","_getShownPosition","_setUpCloseBehavior","position","template","i","li","join","map","checked","menuWidth","x","pageX","Math","min","document","scrollLeft","max","pageY","left","closePopup","err","contents","one","splice","removeItem","findIndexByHtml","has","toString","create","make_popupmenu","button_element","initial_options","convertedOptions","optionVal","optionKey","newOption","convertLinksToOptions","$parent","selector","elem","linkHref","linkTarget","confirmText","fromExistingDom","$buttonElement","$menuElement","menuElementLinkSelector","make_popup_menus","menuSelector","buttonSelectorBuildFn","popupMenusCreated","fromDom","16","data2","empty_text","searchable","selectall","pagesize","_changeDisabled","_renderSearchable","_renderClassic","$select","$dropdown","$resize","$resize_icon","currentY","currentHeight","height","minHeight","select2","prepend","_match","term","String","toUpperCase","order","tags","matched_tags","closeOnSelect","query","q","results","found","callback","slice","more","formatResult","reduce","memo","exists","d","sorter","keep","sort","setOnChange","a","b","25","defaults","async_ops","categorical_filters","sort_key","show_item_checkboxes","num_pages","op","key","cur_val","condition","condition_index","pairs","get_url","26","tmpl","grid_header","grid_table","info_text","global_actions","show_popup","action","grid_filters","columns","column","extra","num_rows_rendered","encoded_id","current_item_id","j","nowrap","column_settings","column_config","link","attach_popup","label_id_prefix","use_paging","num_page_links","cur_page_num","page_link_range","min_page","min_offset","max_range","max_page","max_offset","page_index","allow_multiple","found_global","global_operation","legend","default_filter_dict","advanced_search_display","show_advanced_search_link","filterable","f_key","d_key","standard_search_display","grid_column_filter","column_label","is_text","temp_column","JSON","stringify","column_filter","size","seperator","cf_label","cf","cf_key","cf_arg","filter_key","sanitize","27","header_index","list","element","_setState","header_id","is_expanded","$subgroup","attach","iterate","$tmpl","level","has_options","new_header","$group","29","step","precise","$slider","pressed","which","_isParameter","opts","has_slider","slider","ui","isNaN","round","43","QUERY_STRING","Ui","__identifer","random","substr","isEmptyObject","navigate","queryObj","parse","pop","access_denied","99","_l","categories","enabled","is_tool_shed_installed","enable_beta_ts_api_install","installing_repository_ids","is_repo_installed","allow_user_impersonation","enable_quotas","category","$section","_templateSection","$entries"],"mappings":"AAAAA,cAAc,IAERC,EACA,SAASC,EAAQC,EAASC,ICHhC,SAAAC,GAAA,GAAIC,GAASF,EAAS,GAClBG,EAAID,EACJE,EAAYJ,EAAS,IAAWI,UAChCC,EAAaL,EAAS,IACtBM,EAAWN,EAAS,IAEpBO,GADKP,EAAS,GACLA,EAAS,KAClBQ,EAAOR,EAAS,GAEpBS,QAAOC,IAAM,SAAcC,EAASC,GAChCH,OAAOI,OAAS,GAAIT,GAAWO,EAASC,GACxCC,OAAOC,MAAO,aACdD,OAAOE,OAASF,OAAOG,OAAOD,MAG9B,IAAIE,GAAcV,EAAOW,QACrBC,QACIC,mBAAqB,cAGzBC,aAAc,SAAUC,EAAMC,GAC1B,MAAOV,QAAOW,MAAQX,OAAOW,KAAKC,IAAMZ,OAAOW,KAAKE,IAAK,aAG7DC,WAAY,WACRC,KAAKC,KAAKC,QAAS,GAAIxB,IAAYyB,SAAUlB,OAAOmB,KAAO,mBAAoBC,aAAa,OAIpG9B,GAAE,WACEF,EAAEiB,OAAQP,EAAQK,QAAUkB,YAAc,UAC1CrB,OAAOgB,KAAO,GAAIrB,GAAK2B,KAAMlC,EAAEiB,OAAQP,GACnCyB,KAAU/B,EACVE,OAAUU,UDSQoB,KAAKtC,EAASC,EAAoB,KAI1DsC,EACA,SAASxC,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GEjDnC,SAAAC,EAAAtC,EAAAF,GAGAsC,GAAQvC,EAAA,GACJA,EAAA,IACAA,EAAA,IACAA,EAAA,IACAA,EAAA,IACAA,EAAA,GACAA,EAAA,IANJwC,EAOI,SAAUE,EAAOC,EAAQC,EAAQC,EAASC,EAAWC,EAASC,GAG9D,GAAIC,GAAQR,EAASN,KAAKjB,QACtBgC,QAAS,QACTC,WAAY,SAAUxC,GAClBiB,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,MAAO1C,GAC7DiB,KAAKsB,QAAUvC,EAAQuC,SAAWtB,KAAKsB,QACvCtB,KAAK0B,WAAYnD,EAAG,IAAMyB,KAAKsB,QAAU,OACzCtB,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK4B,UAETC,MAAO,SAAUC,GACb9B,KAAKwB,MAAMO,IAAK,QAASD,IAE7BE,MAAO,WACH,MAAOhC,MAAKwB,MAAM1B,IAAK,UAE3B8B,OAAQ,WAKJ,MAJA5B,MAAKiC,IAAIC,cACAC,SAAU,YACVA,SAAUnC,KAAKwB,MAAM1B,IAAK,QAC1BsC,KAAMpC,KAAKwB,MAAM1B,IAAK,UACxBE,QAKXqC,EAAUxB,EAASN,KAAKjB,QACxBiC,WAAY,SAAUxC,GAClBiB,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClDa,QAAc,KACdC,OAAc,OACdC,IAAc,GACdC,YAAc,EACdC,MAAc,IACfX,IAAKhD,GACRiB,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK4B,UAETe,OAAQ,SAAU5D,GACdiB,KAAKwB,MAAMO,IAAKhD,IAEpB6C,OAAQ,WACJ5B,KAAKiC,IAAIC,cAAcC,SAAU,cAAeA,SAAUnC,KAAKwB,MAAM1B,IAAK,OAC1E,IAAIyC,GAASvC,KAAKwB,MAAM1B,IAAK,SAQ7B,IAPKE,KAAKwB,MAAM1B,IAAK,SACjBE,KAAKiC,IAAIE,UAAsB,WAAVI,GAAuB,QACb,UAAVA,GAAsB,SACtBA,GAAW,gBAEhCvC,KAAKiC,IAAIE,SAAU,SAAUA,SAAU,SAAWI,GAEjDvC,KAAKwB,MAAM1B,IAAK,YAIjB,GAHAE,KAAKiC,IAAIG,KAAMpC,KAAK4C,qBACpB5C,KAAKiC,IAAKjC,KAAKwB,MAAM1B,IAAK,QAAW,SAAW,UAChDE,KAAK6C,SAAWhE,OAAOiE,aAAc9C,KAAK6C,UACpC7C,KAAKwB,MAAM1B,IAAK,cAAiB,CACnC,GAAIiD,GAAO/C,IACXA,MAAK6C,QAAUhE,OAAOmE,WAAY,WAC9BD,EAAKvB,MAAMO,IAAK,UAAW,KAC5B,UAGP/B,MAAKiC,IAAIgB,SAEb,OAAOjD,OAEX4C,kBAAmB,WACf,MAAOvE,GAAE6E,OAAQlD,KAAKwB,MAAM1B,IAAK,eAIrCqD,EAAmBd,EAAQ/C,QAC3BsD,kBAAmB,WACf,MAAO5C,MAAKwB,MAAM1B,IAAK,cAK3BsD,EAAQvC,EAASN,KAAKjB,QACtBiC,WAAY,SAAUxC,GAClBiB,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClD4B,KAAkB,OAClBC,YAAkB,GAClBC,UAAkB,EAClBC,UAAkB,EAClBC,SAAkB,EAClBjB,IAAkB,GAClBkB,MAAkB,EAClBC,MAAkB,KAClBC,MAAkB,OACnB7B,IAAKhD,GACRiB,KAAKsB,QAAUtB,KAAKwB,MAAM1B,IAAK,QAAW,WAAa,QACvDE,KAAK0B,WAAYnD,EAAG,IAAMyB,KAAKsB,QAAU,OACzCtB,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK4B,UAETiC,QACIC,MAAS,aAEb9B,MAAO,SAAU+B,GAEb,MADYC,UAAZD,GAAyB/D,KAAKwB,MAAMO,IAAK,QAA4B,gBAAZgC,GAAuBA,EAAU,IACnF/D,KAAKwB,MAAM1B,IAAK,UAE3B8B,OAAQ,WACJ,GAAImB,GAAO/C,IACXA,MAAKiC,IAAIC,cACAC,SAAU,MAAQnC,KAAKsB,SACvBa,SAAUnC,KAAKwB,MAAM1B,IAAK,QAC1BqC,SAAUnC,KAAKwB,MAAM1B,IAAK,UAC1BmE,KAAM,KAAMjE,KAAKwB,MAAM3B,IACvBoE,KAAM,OAAQjE,KAAKwB,MAAM1B,IAAK,SAC9BmE,KAAM,cAAejE,KAAKwB,MAAM1B,IAAK,gBACrCoE,IAAK,QAASlE,KAAKwB,MAAM1B,IAAK,UAAa,IAC3CoE,IAAK,eAAgBlE,KAAKwB,MAAM1B,IAAK,UAAa,GAC3D,IAAIqE,GAAWnE,KAAKwB,MAAM1B,IAAK,WAY/B,OAXKvB,GAAE6F,QAASD,IAAcA,EAASE,OAAS,GAC5CrE,KAAKiC,IAAIqC,cAAgBC,OAAS,SAAUC,EAASC,GAAaA,EAAU1B,EAAKvB,MAAM1B,IAAK,cACnE4E,OAAS,WAAa3B,EAAK4B,eAEnD3E,KAAKwB,MAAM1B,IAAK,WAAcE,KAAKiC,IAAI2C,OACxC5E,KAAKiC,IAAI2C,IAAK5E,KAAKwB,MAAM1B,IAAK,UAElCzB,EAAEwG,MAAQ,WAAY,YAAc,SAAUC,GAC1C/B,EAAKvB,MAAM1B,IAAKgF,GAAc/B,EAAKd,IAAIgC,KAAMa,GAAW,GAAS/B,EAAKd,IAAI8C,WAAYD,KAE1F9E,KAAKiC,IAAKjC,KAAKwB,MAAM1B,IAAK,WAAc,OAAS,UAC1CE,MAEX2E,UAAW,WACP3E,KAAKgC,MAAOhC,KAAKiC,IAAI2C,OACrB5E,KAAKwB,MAAM1B,IAAK,aAAgBE,KAAKwB,MAAM1B,IAAK,YAAcE,KAAKwB,MAAM1B,IAAK,aAKlFkF,EAASnE,EAASN,KAAKjB,QACvBiC,WAAY,SAAUxC,GAClBiB,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,MAAO1C,GAC7DiB,KAAK0B,WAAYnD,EAAI,UAAW0G,OAAQjF,KAAKkF,MAAQ3G,EAAG,WACxB0G,OAAQjF,KAAKmF,QAAU5G,EAAG,YAC1DyB,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK4B,UAETI,MAAO,SAAU+B,GAEb,MADYC,UAAZD,GAAyB/D,KAAKwB,MAAMO,IAAK,QAASgC,GAC3C/D,KAAKwB,MAAM1B,IAAK,UAE3B8B,OAAQ,WAIJ,MAHA5B,MAAKiC,IAAIgC,KAAM,KAAMjE,KAAKwB,MAAM3B,IAChCG,KAAKmF,QAAQP,IAAK5E,KAAKwB,MAAM1B,IAAK,UAClCE,KAAKwB,MAAM1B,IAAK,QAAWE,KAAKkF,MAAME,OAAOC,KAAMrF,KAAKwB,MAAM1B,IAAK,SAAaE,KAAKkF,MAAMI,OACpFtF,QAKXuF,EAAS1E,EAASN,KAAKjB,QACvBiC,WAAY,SAAUxC,GAClB,GAAIgE,GAAO/C,IACXA,MAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,MAAO1C,GAC7DiB,KAAK0B,WAAYnD,EAAI,UAAW0G,OAAQjF,KAAKkF,MAAQ3G,EAAG,WACxB0G,OAAQjF,KAAKwF,MAAQjH,EAAG,YAAa0F,KAAM,OAAQ,QAAS9B,SAAU,qBACtE8C,OAAQjF,KAAKyF,MAAQlH,EAAG,eAAgB4D,SAAU,eAAgB8B,KAAM,YAAY,IACpFgB,OAAQjF,KAAK0F,MAAQnH,EAAG,QAAS4D,SAAU,2BAC3EnC,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAKwF,MAAMG,GAAI,SAAU,SAAUC,GAAM7C,EAAK8C,UAAWD,KACzD5F,KAAK4B,UAETI,MAAO,SAAU+B,GAEb,MADYC,UAAZD,GAAyB/D,KAAKwB,MAAMO,IAAK,QAASgC,GAC3C/D,KAAKwB,MAAM1B,IAAK,UAE3B8B,OAAQ,WAKJ,MAJA5B,MAAKiC,IAAIgC,KAAM,KAAMjE,KAAKwB,MAAM3B,IAChCG,KAAKwB,MAAM1B,IAAK,QAAWE,KAAKkF,MAAME,OAAOC,KAAMrF,KAAKwB,MAAM1B,IAAK,SAAaE,KAAKkF,MAAMI,OAC3FtF,KAAKwB,MAAM1B,IAAK,SAAYE,KAAKyF,MAAMJ,KAAMrF,KAAKwB,MAAM1B,IAAK,UAAYsF,OAASpF,KAAKyF,MAAMH,OAC7FtF,KAAKwB,MAAM1B,IAAK,QAAWE,KAAK0F,MAAMN,OAASpF,KAAK0F,MAAMJ,OACnDtF,MAEX6F,UAAW,SAAUD,GACjB,GAAI7C,GAAO/C,KACP8F,EAAOF,EAAEG,OAAOC,OAASJ,EAAEG,OAAOC,MAAO,EAC7C,IAAKF,EAAO,CACR,GAAIG,GAAS,GAAIC,WACjBD,GAAOE,OAAS,WACZpD,EAAKvB,MAAMO,KAAOqE,MAAM,EAAOpE,MAAOhC,KAAKqG,UAE/CrG,KAAKwB,MAAMO,KAAOqE,MAAM,EAAMpE,MAAO,OACrCiE,EAAOK,WAAYR,MAK/B,QACIS,OAAmBpF,EAAQqF,cAC3BC,WAAmBtF,EAAQsF,WAC3BC,YAAmBvF,EAAQuF,YAC3BC,WAAmBxF,EAAQwF,WAC3BC,WAAmBzF,EAAQyF,WAC3BxD,MAAmBA,EACnB/B,MAAmBA,EACnBgB,QAAmBA,EACnBc,iBAAmBA,EACnBoC,OAAmBA,EACnBnE,MAAmBA,EACnByF,YAAmB5F,EAAQ4F,YAC3BC,SAAmB7F,EAAQ6F,SAC3BC,MAAmB9F,EAAQ8F,MAC3BhG,OAAmBA,EACnBiE,OAAmBA,EACnBhE,OAAmBA,EACnBE,UAAmBA,IA5N3B8F,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,MF8P8BH,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,GAAIA,EAAoB,KAI1G6I,EACA,SAAS/I,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GGxQnC,SAAAC,EAAAtC,GACAoC,GAAUvC,EAAA,IAAVwC,EAA2B,SAAUE,GAEjC,GAAI0F,GAAgB3F,EAASN,KAAKjB,QAC9BiC,WAAY,SAAUxC,GAClBiB,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClD5B,GAAciB,EAAMoG,MACpBrF,MAAc,GACdsF,SAAc,QACdC,KAAc,GACd5E,IAAc,kBACd4D,MAAc,EACdiB,UAAc,aACdC,SAAc,eACd/D,UAAc,EACdgE,YAAc,IACfxF,IAAKhD,GACRiB,KAAK0B,WAAYnD,EAAG,aAAc0F,KAAM,OAAQ,UACdgB,OAAQjF,KAAKwH,MAAejJ,EAAG,SAC/B0G,OAAQjF,KAAKyH,OAAelJ,EAAG,YAC/B0G,OAAQjF,KAAK0H,UAAenJ,EAAG,UAAW0G,OAAQjF,KAAK2H,cAAgBpJ,EAAG,aAC5GyB,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK4B,UAGTA,OAAQ,WACJ,GAAImB,GAAO/C,KACPjB,EAAUiB,KAAKwB,MAAMoG,UACzB5H,MAAKiC,IAAIC,cACAC,SAAU,qBACVA,SAAUpD,EAAQwE,UAAY,YAC9BU,KAAM,KAAMlF,EAAQc,IACpBoE,KAAM,WAAYlF,EAAQwE,UAC1BW,IAAK,QAASnF,EAAQoI,UACtBU,IAAK,SAAUlC,GAAI,QAAU,WAC1BpH,EAAG,YAAa+G,OAChBvG,EAAQ+I,UAAY/E,EAAKQ,UAAYxE,EAAQ+I,YAEhDC,SAAWlG,MAAO9C,EAAQgJ,QAASC,UAAW,WACvDhI,KAAK0H,UAAUvF,SAAU,YAAa+B,IAAK,UAAWnF,EAAQwI,cAAe,EAAK,QAAU,QAC5FvH,KAAK2H,cAAcxF,SAAU,gBAAiB+B,KAAO+D,MAAQlJ,EAAQwI,WAAa,MAClFvH,KAAKwH,MAAMtF,cAAcC,SAAU,WACnCnC,KAAKyH,OAAOvF,cAAcC,SAAU,SAC/BpD,EAAQqH,MACTpG,KAAKiC,IAAIE,SAAUpD,EAAQuI,UAAWY,KAAM,YAAY,GACxDlI,KAAKwH,MAAMrF,SAAU,sCACrBnC,KAAKyH,OAAOrF,KAAMrD,EAAQsI,aAE1BrH,KAAKiC,IAAIE,SAAUpD,EAAQyD,KAC3BxC,KAAKwH,MAAMrF,SAAUpD,EAAQqI,MAC7BpH,KAAKyH,OAAOrF,KAAMrD,EAAQ8C,OAC1B9C,EAAQqI,MAAQrI,EAAQ8C,OAAS7B,KAAKwH,MAAMrF,SAAU,qBAK9DiD,KAAM,WACFpF,KAAKiC,IAAImD,QAIbE,KAAM,WACFtF,KAAKiC,IAAIqD,QAIb6C,QAAS,WACLnI,KAAKwB,MAAMO,IAAK,YAAY,IAIhCqG,OAAQ,WACJpI,KAAKwB,MAAMO,IAAK,YAAY,IAIhCqE,KAAM,WACFpG,KAAKwB,MAAMO,IAAK,QAAQ,IAI5BsG,OAAQ,WACJrI,KAAKwB,MAAMO,IAAK,QAAQ,IAI5BuG,QAAS,SAAUlB,GACfpH,KAAKwB,MAAMO,IAAK,OAAQqF,MAK5BR,EAAaJ,EAAclH,QAC3BiC,WAAY,SAAUxC,GAClBiB,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClD5B,GAAciB,EAAMoG,MACpBrF,MAAc,GACduF,KAAc,GACd5E,IAAc,KACfT,IAAKhD,GACRiB,KAAK0B,WAAYnD,EAAG,QAAS0G,OAAQjF,KAAKwH,MAASjJ,EAAG,aACtDyB,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK4B,UAGTA,OAAQ,WACJ,GAAI7C,GAAUiB,KAAKwB,MAAMoG,UACzB5H,MAAKiC,IAAIC,cACAC,SAAUpD,EAAQyD,KAClByB,MAAQpE,GAAad,EAAQc,GACrB0I,KAAaxJ,EAAQwJ,MAAQ,qBAC7B1G,MAAa9C,EAAQ8C,MACrBkE,OAAahH,EAAQgH,QAAU,OAC/BxC,SAAaxE,EAAQwE,WAC7BwE,SAAWC,UAAW,WACtBH,IAAK,SAAUlC,GAAI,QAAU,WAC1B5G,EAAQ+I,UAAY/I,EAAQwE,UAAYxE,EAAQ+I,YAE5D9H,KAAKwH,MAAMtF,cAAcC,SAAUpD,EAAQqI,SAK/CV,EAAc7F,EAASN,KAAKjB,QAC5BiC,WAAY,SAAUxC,GAClBiB,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClD5B,GAAciB,EAAMoG,MACpBrF,MAAc,sBACd2G,OAAgB,cAAe,oBAAqB,qBACpDxG,MAAc,EACdyG,SAAc,eACf1G,IAAKhD,GACRiB,KAAK0B,WAAYnD,EAAG,UAAW0G,OAAQjF,KAAKwH,MAAUjJ,EAAG,YAC1B0G,OAAQjF,KAAKyH,OAAUlJ,EAAG,aACzDyB,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK4B,UAGTA,OAAQ,SAAU7C,GACd,GAAIgE,GAAO/C,KACPjB,EAAUiB,KAAKwB,MAAMoG,UACzB5H,MAAKiC,IAAIE,SAAU,mBACV0F,IAAK,SAAUlC,GAAG,QAAS,WACxB5C,EAAKvB,MAAMO,IAAK,QAAyC,IAA9BgB,EAAKvB,MAAM1B,IAAK,UAAmB,GAAO,GACrEf,EAAQ+I,SAAW/I,EAAQ+I,YAEvC9H,KAAKyH,OAAOrF,KAAMrD,EAAQ8C,OAC1B7B,KAAKwH,MAAMtF,cACAC,SAAU,2BACVA,SAAUpD,EAAQyJ,MAAOzJ,EAAQiD,SAShDA,MAAO,SAAW+B,EAAS2E,GAQvB,MAPiB1E,UAAZD,IACI2E,GAAqB,IAAZ3E,IACVA,EAAYA,IAAY2E,GAAW,GAAK,GAE5C1I,KAAKwB,MAAMO,IAAK,QAASgC,GACzB/D,KAAKwB,MAAM1B,IAAK,YAAcE,KAAKwB,MAAM1B,IAAK,WAE3CE,KAAKwB,MAAM1B,IAAK,YAK3B2G,EAAaD,EAAclH,QAC3BiC,WAAY,SAAUxC,GAClBiB,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClD5B,GAAciB,EAAMoG,MACpBrF,MAAc,GACdsF,SAAc,QACdC,KAAc,GACd5E,IAAc,iBACde,UAAc,IACfxB,IAAKhD,GACRiB,KAAK0B,WAAYnD,EAAG,UAAW0G,OAAQjF,KAAK2I,QAAUpK,EAAG,UAAW0G,OAAQjF,KAAKwH,MAASjJ,EAAG,SACzB0G,OAAQjF,KAAKyH,OAASlJ,EAAG,cAC7FyB,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK4B,UAGTA,OAAS,SAAU7C,GACf,GACIA,GAAUiB,KAAKwB,MAAMoG,UACzB5H,MAAKiC,IAAIC,cACAC,SAAUpD,EAAQyD,KAClBL,SAAUpD,EAAQwE,UAAY,YAC9BU,KAAM,WAAYlF,EAAQwE,UAC1BU,KAAM,KAAMlF,EAAQc,IACpBqE,IAAK,QAASnF,EAAQoI,UACtBU,IAAK,SAAUlC,GAAI,QAAS,WACzBpH,EAAG,YAAa+G,QACfvG,EAAQwE,UAAYxE,EAAQ+I,SAAW/I,EAAQ+I,YAE5D9H,KAAK2I,QAAQxG,SAAU,UAAW4F,SAAWlG,MAAO9C,EAAQgJ,QAASC,UAAW,WAChFhI,KAAKwH,MAAMtF,cAAcC,SAAU,WAAYA,SAAUpD,EAAQqI,MACjEpH,KAAKyH,OAAOtF,SAAU,SAAUC,KAAMrD,EAAQ8C,OAC9C9C,EAAQqI,MAAQrI,EAAQ8C,OAAS7B,KAAKwH,MAAMrF,SAAU,sBAK1DwE,EAAaH,EAAclH,QAC3BsJ,MAAO,KACPrH,WAAY,SAAWxC,GACnBiB,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClD5B,GAAkB,GAClBgC,MAAkB,GAClBsF,SAAkB,QAClB0B,KAAkB,QAClBzB,KAAkB,KAClBU,QAAkB,KAClBtF,IAAkB,gCAClBuF,QAAkB,GAClBhC,OAAkB,GAClBwC,KAAkB,GAClBO,SAAkB,KAClBrF,SAAkB,EAClBsF,IAAkB,KACnBhH,IAAKhD,GACRiB,KAAKgJ,WAAa,GAAInI,GAASoI,WAC/BjJ,KAAK0B,WAAYnD,EAAG,UAAW0G,OAAQjF,KAAKkJ,MAAQ3K,EAAG,UAAW0G,OAAQjF,KAAKwH,MAASjJ,EAAG,SACzB0G,OAAQjF,KAAKyH,OAASlJ,EAAG,cAC3FyB,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK2B,SAAU3B,KAAKgJ,WAAY,0BAA2BhJ,KAAK4B,OAAQ5B,MACxEA,KAAK4B,UAGTA,OAAQ,WACJ,GAAImB,GAAO/C,KACPjB,EAAUiB,KAAKwB,MAAMoG,UACzB5H,MAAKiC,IAAIC,cACAC,SAAU,YACVA,SAAUpD,EAAQyD,KAClByB,KAAM,KAAMlF,EAAQc,IACpBqE,KAAOiF,MAAUpK,EAAQoI,SAClBjH,QAAUnB,EAAQ0E,SAAWzD,KAAKgJ,WAAWI,OAAS3F,SAAS,IAASY,OAAS,EAAI,QAAU,SAC/GrE,KAAKkJ,MAAM/G,SAAU,+BACV8B,KAAM,cAAe,YACrB8D,SAAWlG,MAAO9C,EAAQgJ,QAASC,UAAW,WAC9CH,IAAK,SAAUlC,GAAI,QAAS,SAAUC,GACjCrH,EAAG,YAAa+G,OAChBM,EAAEyD,iBACFtK,EAAQ+I,SAAW/I,EAAQ+I,YAE3C9H,KAAKwH,MAAMtF,cAAcC,SAAU,WAAYA,SAAUpD,EAAQqI,MACjEpH,KAAKyH,OAAOvF,cAAcC,SAAU,SAAUC,KAAMrD,EAAQ8C,OAC5D9C,EAAQqI,MAAQrI,EAAQ8C,OAAS7B,KAAKwH,MAAMrF,SAAU,mBACtDnC,KAAK4I,OAAS5I,KAAK4I,MAAMU,SACpBtJ,KAAKgJ,WAAW3E,OAAS,IAC1BrE,KAAK4I,MAAQrK,EAAG,SAAU4D,SAAU,sBACVA,SAAU,QAAUY,EAAKvB,MAAM1B,IAAK,SACpCmE,KAAM,OAAQ,QACxCjE,KAAKiC,IAAIgD,OAAQjF,KAAK4I,QAE1B5I,KAAKgJ,WAAWnE,KAAM,SAAU0E,GAC5B,GAAIC,GAAaD,EAAS3B,UAC1B,IAAK4B,EAAW/F,QAAU,CACtB,GAAIgG,GAAQlL,EAAG,QAAS4D,SAAU,iBACV8B,MAAQsE,KAAOiB,EAAWjB,KAAMxC,OAASyD,EAAWzD,SACpDd,OAAQ1G,EAAG,QAAS4D,SAAU,MACVA,SAAUqH,EAAWpC,MACrBlD,IAAK,UAAWsF,EAAWpC,KAAO,eAAiB,SACvEnC,OAAQuE,EAAW3H,OACnB8D,GAAI,QAAS,SAAUC,GACd4D,EAAW1B,UACZlC,EAAEyD,iBACFG,EAAW1B,YAG3C/E,GAAK6F,MAAM3D,OAAQ1G,EAAG,SAAU0G,OAAQwE,IACxCD,EAAWE,SAAW3G,EAAK6F,MAAM3D,OAAQ1G,EAAG,SAAU4D,SAAU,gBAM5EwH,QAAS,SAAW5K,GAChBiB,KAAKgJ,WAAWY,IAAK9I,EAAM+I,MAAO9K,GAC9B8C,MAAc,GACdkE,OAAc,GACdwC,KAAc,GACdT,QAAc,KACd4B,SAAc,EACdjG,SAAc,EACd2D,KAAc,KACd5E,IAAc,6BAK1B,QACIgE,cAAkBA,EAClBI,WAAkBA,EAClBH,WAAkBA,EAClBC,YAAkBA,EAClBC,WAAkBA,IA7S1BK,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,MH+gB8BH,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,KAIlF0L,GACA,SAAS5L,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GIvhBnC,SAAAtC,EAAAuC,EAAAtC,EAAAF,GAEAC,EAAOyL,aAAaC,aAAc,EAGlCrJ,GACIvC,EAAA,GACAA,EAAA,IACAA,EAAA,IACAA,EAAA,KAJJwC,EAKG,SAASE,EAAOmJ,EAAWC,EAAWC,GAGzC,MAAOtJ,GAASN,KAAKjB,QAGjB8K,KAAM,KAGN7I,WAAY,SAAS8I,GACjBrK,KAAKK,YAAcgK,EAAYhK,WAC/B,IAAI0C,GAAO/C,IAaX,IAZAnB,OAAOyL,uBAAyB,SAAUC,EAAUC,GAEhD,GAAIzB,GAAMwB,GAA2BvG,SAAdwG,GAAyC,KAAdA,EAAmB,IAAMA,EAAY,IACnFC,EAAkBlM,EAAG,oBAAoBmM,GAAG,WAC3CD,KACDlM,EAAE,oBAAoBoM,YAAY,QAClCpM,EAAE,oBAAoBoM,YAAY,SAEtC5H,EAAK6H,qBAAsB,OAAQ7B,IAIlC/I,KAAKK,YAEN,GADAL,KAAK0B,WAAW,UACX2I,EAAYlK,WAAakK,EAAYQ,MAAQ,CAC9C,GAAIC,KACJzM,GAAEwG,KAAKwF,EAAYU,QAAS,SAASC,EAAGC,GACpCH,EAAS,KAAOG,GAAKD,IAEzBzM,EAAE2M,MACEC,IAAUd,EAAYlK,SAAW,IAAM5B,EAAE6M,MAAON,GAChDO,QAAU,SAAU5G,GAChBA,EAAS6G,SAAWjB,EAAYiB,SAChC7G,EAASsG,QAAWV,EAAYU,QAChChI,EAAKwI,UAAW9G,UAIxBzE,MAAKuL,UAAUlB,OAGnBrK,MAAK0B,WAAW,mBAChB1B,KAAKuL,UAAUlB,EAIfA,GAAYmB,YACZjN,EAAE,WAAW2F,KACTuH,QAAc,OACdC,SAAc,UAM1BC,eAAgB,SAAUC,GAClBA,GACIrN,EAAEsN,QAAQ,UAAWD,IAAkB,GACnCE,IAAI7M,QAAU6M,IAAI7M,OAAO8M,kBACzBD,IAAI7M,OAAO8M,iBAAiBC,sBAO5CT,UAAW,SAASlB,GAEhBrK,KAAKoK,KAAO,GAAIH,GAAUI,EAG1B,IAAItL,GAAUiB,KAAKoK,KAAKxC,UAGxB5H,MAAK2L,eAAe5M,EAAQ6M,eAG5B,IAAIT,GAAMnL,KAAKoK,KAAKtK,IAAI,WAaxB,IAZAqL,EAAMA,EAAIc,QAAQ,gBAAiB,IACnCjM,KAAKoK,KAAKrI,IAAI,WAAYoJ,GAG1BnL,KAAKiC,IAAIG,KAAK8H,EAAUE,KAAKrL,IAG7BiB,KAAKiC,IAAIiK,KAAK,sBAAsB9J,KAAK8H,EAAUiC,OAAOpN,IAC1DiB,KAAKiC,IAAIiK,KAAK,oBAAoB9J,KAAK8H,EAAUkC,KAAKrN,IACtDiB,KAAKiC,IAAIiK,KAAK,sBAAsB9J,KAAK8H,EAAUmC,OAAOtN,IAGtDA,EAAQuD,QAAS,CACjBtC,KAAKiC,IAAIiK,KAAK,iBAAiB9J,KAAK8H,EAAU5H,QAAQvD,GACtD,IAAIgE,GAAO/C,IACPjB,GAAQuN,kBACRtJ,WAAY,WAAaD,EAAKd,IAAIiK,KAAK,iBAAiB9J,KAAK,KAAQ,KAK7EpC,KAAKuM,qBACLvM,KAAKwM,qBAILC,0BAIJD,mBAAoB,WAGhB,GAAIzJ,GAAO/C,IAGXA,MAAKiC,IAAIiK,KAAK,qBAAqBrH,KAAK,WACpCtG,EAAEyB,MAAM6H,MACRtJ,EAAEyB,MAAM0M,MAAM,WAEV,MADA3J,GAAK4J,iBAAiB3M,OACf,MAKfA,KAAKiC,IAAIiK,KAAK,oBAAoBrH,KAAK,WACnCtG,EAAEyB,MAAM6H,MACRtJ,EAAEyB,MAAM0M,MAAM,WAAanO,EAAEyB,MAAM4M,WAC3BC,MAAM,WAActO,EAAEyB,MAAMkE,IAAI,aAAc,cAI1DlE,KAAKiC,IAAIiK,KAAK,cAAcrH,KAAM,WAC9BtG,EAAEyB,MAAM6H,MACRtJ,EAAEyB,MAAM0M,MAAO,WAEZ,MADA3J,GAAK+J,mBAAoBvO,EAAEyB,MAAMiE,KAAK,cAC/B,MAKdjE,KAAKiC,IAAIiK,KAAK,qBAAqBrH,KAAM,WACrCtG,EAAEyB,MAAM6H,MACRtJ,EAAEyB,MAAM+M,OAAQ,WACZ,GAAIC,GAAazO,EAAEyB,MAAMiE,KAAK,cAC1BgJ,EAAiB1O,EAAE,UAAYyO,EAAa,WAC5CE,EAAaD,EAAerI,KAGhC,OAFAqI,GAAerI,IAAI,IACnB7B,EAAK6H,qBAAqBoC,EAAYE,IAC/B,MAKflN,KAAKiC,IAAIiK,KAAK,wBAAwBrH,KAAM,WACxCtG,EAAEyB,MAAM6H,MACRtJ,EAAEyB,MAAM0M,MAAO,WAQX,MANAnO,GAAEyB,MAAMmN,SAAS7D,SAGjBvG,EAAKqK,wBAAyB7O,EAAEyB,MAAMiE,KAAK,cAAe1F,EAAEyB,MAAMiE,KAAK,gBAGhE,MAKfjE,KAAKiC,IAAIiK,KAAK,2BAA2BrH,KAAM,WAC3CtG,EAAEyB,MAAM6H,MACRtJ,EAAEyB,MAAM0M,MAAO,WAEX,MADA3J,GAAKsK,uBAAwB9O,EAAEyB,MAAMiE,KAAK,cAAe1F,EAAEyB,MAAMiE,KAAK,gBAC/D,MAKfjE,KAAKiC,IAAIiK,KAAK,2BAA2BrH,KAAM,WAC3CtG,EAAEyB,MAAM6H,MACRtJ,EAAEyB,MAAM0M,MAAO,WAGX,MAFA3J,GAAKd,IAAIiK,KAAK,oBAAoBvB,YAAY,QAC9C5H,EAAKd,IAAIiK,KAAK,oBAAoBvB,YAAY,SACvC,MAKf3K,KAAKiC,IAAIiK,KAAK,cAAcrE,MAC5B7H,KAAKiC,IAAIiK,KAAK,cAAcvG,GAAG,QAAS,WACpC5C,EAAKuK,qBAKbf,mBAAqB,WAEjBvM,KAAKiC,IAAIiK,KAAK,SAASrH,KAAM,WACzB,GAAI0I,GAAahP,EAAEyB,MAAMkM,KAAK,kCAC1BsB,EAAcjP,EAAEyB,MAAMkM,KAAK,4BAC3BuB,EAAiB,WACjBD,EAAYnI,KAAM9G,EAAEgP,GAAYG,OAAO,YAAYrJ,QAGvD9F,GAAEgP,GAAY1I,KAAM,WAChBtG,EAAEyB,MAAM0E,OAAO+I,KAEnBA,MAImD,IAAnDzN,KAAKiC,IAAIiK,KAAK,0BAA0B7H,QACxCrE,KAAKiC,IAAIiK,KAAK,0BAA0ByB,UAG5C,IAAI5O,GAAUiB,KAAKoK,KAAKxC,WACpB7E,EAAO/C,IAKXA,MAAKiC,IAAIiK,KAAK,kBAAkBrH,KAAM,WAClCtG,EAAEyB,MAAM0M,MAAO,WAEZ,MADA3J,GAAK6K,SAAUrP,EAAEyB,MAAMiE,KAAK,cACrB,MAOdjE,KAAKiC,IAAIiK,KAAK,eAAerH,KAAM,WAC/BtG,EAAEyB,MAAM0M,MAAO,SAAS9G,GAKpB,MAJA7C,GAAK8K,SACDtF,KAAOhK,EAAEyB,MAAMiE,KAAK,QACpB8B,OAASxH,EAAEyB,MAAMiE,KAAK,aAEnB,KAMf,IAAI6J,GAAe/O,EAAQ8L,MAAMxG,MACb,IAAhByJ,GAKJzP,EAAEwG,KAAM9F,EAAQ8L,MAAO,SAAUkD,EAAMC,GACnC,GAAIC,GAASlL,EAAKxE,EAAG,SAAWyP,EAAQ,UAAWnG,MAC/CqG,EAAQ,GAAI/D,GAAW8D,EAC3B5P,GAAEwG,KAAM9F,EAAA,WAAyB,SAAUoP,GACvCpL,EAAKqL,eAAgBF,EAAOC,EAAWJ,QAMnDK,eAAgB,SAAUF,EAAOC,EAAWJ,GACxC,GAAIhL,GAAO/C,KACPqO,EAAWN,EAAKO,iBAAkBH,EAAUI,MAC3CF,GAASG,SAAWL,EAAUM,aAC/BP,EAAMQ,SACFtM,KAAsB+L,EAAUI,MAChChG,KAAsB8F,EAASM,SAC/B5I,OAAsBsI,EAAStI,OAC/B6I,kBAAsBT,EAAUU,QAChCC,KAAsB,SAAUlJ,GAC5BA,EAAEyD,gBACF,IAAIkF,GAAQhQ,EAAGqH,EAAEG,QAAS3D,MACrB+L,GAAUrG,QACXqG,EAAUrG,QAASiG,EAAKgB,WAExBhM,EAAK8K,QAAS7N,KAAKgP,eAAgBT,QAQvD3D,qBAAsB,SAAUjL,EAAMqC,GAElC,GAAc,KAAVA,EACA,OAAO,CAIXhC,MAAKoK,KAAK6E,WAAWtP,EAAMqC,GAAO,EAGlC,IAAIkN,GAAI3Q,EAAE2L,EAAUiF,eAAexP,EAAMqC,IACrCe,EAAO/C,IACXkP,GAAExC,MAAM,WAEJnO,EAAEyB,MAAMsJ,SAGRvG,EAAKqK,wBAAwBzN,EAAMqC,IAIvC,IAAIoN,GAAYpP,KAAKiC,IAAIiK,KAAK,IAAMvM,EAAO,sBAC3CyP,GAAUnK,OAAOiK,GAGjBlP,KAAKqP,cACLrP,KAAK6N,WAITT,wBAAyB,SAAUzN,EAAMqC,GAErChC,KAAKoK,KAAKkF,cAAc3P,EAAMqC,GAG9BhC,KAAKqP,cACLrP,KAAK6N,WAITf,mBAAoB,SAAUyC,GAG1B,GAAIC,GAAWxP,KAAKoK,KAAKtK,IAAI,YACzB2P,EAAWF,CACXC,GAASE,QAAQH,MAAa,GAEG,MAA7BC,EAASG,UAAU,EAAG,KACtBF,EAAW,IAAMF,GAKzBvP,KAAKiC,IAAIiK,KAAK,eAAe5C,QAG7B,IAAIsG,GAAyC,KAA3BH,EAASE,UAAU,EAAE,GAAa,SAAW,SAC3DT,EAAI3Q,EAAE,SAAWqR,EAAa,WAAWzN,SAAS,aAGtDnC,MAAKiC,IAAIiK,KAAK,IAAMqD,EAAU,WAAWtK,OAAOiK,GAGhDlP,KAAKoK,KAAKrI,IAAI,WAAY0N,GAC1BzP,KAAKqP,cACLrP,KAAK6N,WAITR,uBAAwB,SAAU1N,EAAMkQ,GAEpC,GAAIC,GAAkB9P,KAAKoK,KAAKtK,IAAI,uBAAuBH,GACvDoQ,EAAY/P,KAAKoK,KAAKtK,IAAI,WAAWH,GACrCoD,EAAO/C,IACXA,MAAKiC,IAAIiK,KAAK,IAAMvM,EAAO,WAAWkF,KAAM,WACxC,GAAIQ,GAAO9G,EAAEyR,KAAMzR,EAAEyB,MAAMqF,QACvBqI,EAASoC,EAAgBzK,GACzB4K,EAAevC,EAAO/N,EAC1B,IAAIsQ,GAAgBJ,EAGhBtR,EAAEyB,MAAMkQ,QACR3R,EAAEyB,MAAMmC,SAAS,kBACjB5D,EAAEyB,MAAMiF,OAAOI,OACZ,IAAI4K,GAAgBF,EAAW,CAGlCxR,EAAEyB,MAAMkQ,OACR,IAAIhB,GAAI3Q,EAAE,eAAiB8G,EAAO,OAClC6J,GAAExC,MAAM,WACJ3J,EAAKsK,uBAAwB1N,EAAMsQ,KAEvC1R,EAAEyB,MAAMkC,YAAY,kBACpB3D,EAAEyB,MAAMiF,OAAOiK,MAKvBlP,KAAKoK,KAAK6E,WAAWtP,EAAMkQ,GAC3B7P,KAAKqP,cACLrP,KAAK6N,WAITD,SAAU,SAAUuC,GAEhB,GAAIpN,GAAO/C,IACXA,MAAKiC,IAAIiK,KAAK,cAAcrH,KAAM,WAC9B,GAGIQ,GAHAxF,EAAKtB,EAAEyB,MAAMiE,KAAK,MAClBmM,EAAWC,SAAUxQ,EAAGyQ,MAAM,KAAK,GAAI,IACvCC,EAAWxN,EAAKqH,KAAKtK,IAAI,WAE7B,IAAIsQ,IAAaD,EAGb9K,EAAO9G,EAAEyB,MAAMwQ,WAAWnL,OAC1B9G,EAAEyB,MAAMkQ,QACR3R,EAAEyB,MAAMmC,SAAS,iBACjB5D,EAAEyB,MAAMqF,KAAKA,OAEZ,IAAI+K,IAAaG,EAAU,CAG5BlL,EAAO9G,EAAEyB,MAAMqF,OACf9G,EAAEyB,MAAMkQ,QACR3R,EAAEyB,MAAMkC,YAAY,gBACpB,IAAIgN,GAAI3Q,EAAE,eAAiB8G,EAAO,OAClC6J,GAAExC,MAAM,WACJ3J,EAAK6K,SAASwC,KAElB7R,EAAEyB,MAAMiF,OAAOiK,MAIN,QAAbiB,EACAnQ,KAAKoK,KAAKrI,IAAI,WAAYoO,GAE1BnQ,KAAKoK,KAAKrI,IAAI,WAAYsO,SAASF,EAAU,KAEjDnQ,KAAK6N,WAITlB,iBAAkB,SAAU8D,EAAkB7B,GAE1C,GAAI8B,GAAiBnS,EAAEkS,GAAkB7L,MAGrC+L,EAAwB3Q,KAAKiC,IAAIiK,KAAK,4BAA4B7H,MACtE,KAAKsM,EAAwB,EACzB,OAAO,CAIX,IAAIxC,GAAY9P,EAAEuS,UAAU5Q,KAAKoK,KAAKxC,WAAWiJ,YAAatC,MAAOmC,GACjEvC,KAAcS,IACdA,EAAoBT,EAAUU,SAAW,GAI7C,IAAIiC,KACJ9Q,MAAKiC,IAAIiK,KAAK,0BAA0BrH,KAAK,WACzCiM,EAASC,KAAMxS,EAAEyB,MAAM4E,QAI3B,IAAI7F,IACIoP,UAAsBuC,EACtB7Q,GAAsBiR,EACtBlC,kBAAsBA,EAS9B,OAPyB,OAApBT,EAAUpI,SACXhH,EAAUV,EAAEiB,OAAQP,GAChBwJ,KAAS4F,EAAU5F,KACnBxC,OAASoI,EAAUpI,UAG3B/F,KAAK6N,QAAS9O,IACP,GAGXuO,gBAAiB,WACb,GAAI0D,GAAQhR,KAAKzB,EAAE,6BACf0S,EAAQjR,KAAKzB,EAAG,cAAe2J,KAAM,UACzC7J,GAAEwG,KAAMmM,EAAO,SAAUE,GACrB3S,EAAG2S,GAAIhJ,KAAM,UAAW+I,KAE5BjR,KAAKuM,sBAIT8C,YAAa,WAET,GAAIkB,GAAWvQ,KAAKoK,KAAKtK,IAAI,WACZ,QAAbyQ,GAAkCvM,SAAbuM,GAAuC,QAAbA,GAC/CvQ,KAAKoK,KAAKrI,IAAI,WAAY,IAOlC8L,QAAS,SAAU9O,GAEf,GAAIc,GAAK,KACL0I,EAAO,KACP4F,EAAY,KACZS,EAAoB,KACpB7I,EAAS,IAGb,IAAIhH,IAEAwJ,EAAOxJ,EAAQwJ,KACf4F,EAAYpP,EAAQoP,UACpBtO,EAAKd,EAAQc,GACb+O,EAAoB7P,EAAQ6P,kBAC5B7I,EAAShH,EAAQgH,OAGJ/B,SAATuE,GAAsBA,EAAKmH,QAAQ,gBAAiB,GAAI,CAExD,GAAIyB,GAAa5I,EAAK+H,MAAM,IAC5B,IAAIa,EAAW9M,OAAS,EAGpB,IAAK,GAFD+M,GAAiBD,EAAW,GAC5BE,EAAaD,EAAed,MAAM,KAC7BtC,EAAQ,EAAGA,EAAQqD,EAAWhN,OAAQ2J,IACvCqD,EAAWrD,GAAO0B,QAAQ,eAAgB,GAE1CvB,EAAYkD,EAAWrD,GAAOsC,MAAM,KAAK,GACzCnC,EAAYA,EAAUlC,QAAS,MAAO,MAC/BoF,EAAWrD,GAAO0B,QAAQ,QAAS,IAE1C7P,EAAKwR,EAAWrD,GAAOsC,MAAM,KAAK,IAQtD,MAAInC,IAAatO,IAET+O,GAA0C,IAArBA,GAAgD,QAArBA,GAAoD,QAArBA,IAC3EC,QAAQD,MAIhBT,EAAYA,EAAUmD,cAGtBtR,KAAKoK,KAAKrI,KACNoM,UAAWA,EACX2C,SAAUjR,IAIC,OAAVkG,EACDlH,OAAOiN,IAAIyF,SAAWhJ,EAAO,IAAMhK,EAAE6M,MAAOpL,KAAKoK,KAAKoH,gBAC9CxR,KAAKoK,KAAKqH,aAAatD,IAAcnO,KAAKK,YAClDL,KAAK0R,cAEL1R,KAAK2R,MAAM5L,EAAQwC,IAIhB,GAIPA,GACAvI,KAAK2R,MAAM5L,EAAQwC,IACZ,IAIPvI,KAAKoK,KAAKtK,IAAI,UAAYE,KAAKK,YAC/BL,KAAK0R,cAEL1R,KAAK2R,MAAM5L,EAAQwC,IAIhB,IAIXoJ,MAAO,SAAU5L,EAAQwC,GAErB,GAAIqJ,GAAQ5R,KAAKoK,KAAKtK,IAAI,QAkB1B,QAjBAE,KAAKoK,KAAKrI,IAAI,SAAS,GAGvB0I,gBAAkBzK,KAAKiC,IAAIiK,KAAK,oBAAoBxB,GAAG,YACvD1K,KAAKoK,KAAKrI,IAAI,kBAAmB0I,iBAG7BlC,IACAA,EAAOvI,KAAKoK,KAAKtK,IAAI,YAAc,IAAMvB,EAAE6M,MAAMpL,KAAKoK,KAAKoH,iBAI/DxR,KAAKoK,KAAKrI,KACNoM,UAAWnK,OACX8M,SAAU9M,OACV4N,MAAOA,IAEH7L,GACJ,IAAK,UAED,GAAI8L,GAAOtT,EAAE,gBAAgBuT,QAAQ,WACrC,IAAoB,IAAhBD,EAAKxN,OAEL,WADAwN,GAAKE,KAAKxJ,EAGd,MACJ,KAAK,MACD1J,OAAOiN,IAAIyF,SAAWhJ,CACtB,MACJ,SACI1J,OAAO0S,SAAWhJ,IAK9BmJ,YAAa,WAET,GAAIM,GAAUhS,KAAKoK,KAAKtK,IAAI,aAAe,OAAS,KAGpDE,MAAKiC,IAAIiK,KAAK,wBAAwB9G,MACtC,IAAIrC,GAAO/C,IACXzB,GAAE2M,MACE7H,KAAM2O,EACN7G,IAAKpI,EAAKqH,KAAKtK,IAAI,YACnBmS,KAAMlP,EAAKqH,KAAKoH,eAChBU,MAAO,SAASzN,GAAY0N,MAAO,wBACnC9G,QAAS,SAAS+G,GAGd,GAAI9G,GAAWvI,EAAKqH,KAAKtK,IAAI,YACzBuS,EAAStP,EAAKqH,KAAKtK,IAAI,UAGvBwS,EAAOvP,EAAK1C,YAAc+R,EAAgB7T,EAAEgU,UAAUH,EAG1DE,GAAKhH,SAAWA,EAChBgH,EAAKD,OAASA,EAGdtP,EAAKwI,UAAU+G,GAGfvP,EAAKd,IAAIiK,KAAK,wBAAwB5G,QAE1CkN,SAAU,WAENzP,EAAKqH,KAAKrI,KACNoM,UAAWnK,OACX8M,SAAU9M,gBAvoB9BgD,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,MJmqC8BH,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,GAAIA,EAAoB,GAAIA,EAAoB,KAIlIqU,GACA,SAASvU,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GK/qCnC,SAAAC,EAAAtC,EAAAF,GACAsC,GAASvC,EAAA,GAAeA,EAAA,IAAxBwC,EAA+C,SAAUE,EAAOK,GAChE,GAAIuR,GAAO7R,EAASN,KAAKjB,QACrBiC,WAAY,SAAUxC,GAClB,GAAIgE,GAAO/C,IACXA,MAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClDgC,SAAc,EACdwO,QACApS,GAAciB,EAAMoG,MACpByL,WAAc,wBACdtL,UAAc,iBACduL,UAAc,EACdC,UAAc,EACdpK,SAAc,eACf1G,IAAKhD,GACRiB,KAAK2B,SAAU3B,KAAKwB,MAAO,eAAgBxB,KAAK8S,aAAc9S,MAC9DA,KAAK2B,SAAU3B,KAAKwB,MAAO,cAAexB,KAAK+S,YAAa/S,MAC5DA,KAAK2B,SAAU3B,KAAKwB,MAAO,cAAexB,KAAKgT,YAAahT,MAC5DA,KAAK2B,SAAU3B,KAAKwB,MAAO,iBAAkBxB,KAAKiT,eAAgBjT,MAClEA,KAAK2F,GAAI,SAAU,WAAa5C,EAAKvB,MAAM1B,IAAK,YAAciD,EAAKf,WACnEhC,KAAK4B,UAGTA,OAAQ,WACJ,GAAImB,GAAO/C,IACXA,MAAKiC,IAAIiO,QACAhO,cACAC,SAAU,cACV8C,OAAQjF,KAAKkT,SAAa3U,EAAG,WAC7B0G,OAAQjF,KAAK4I,MAAarK,EAAG,UAAW4D,SAAU,oBAClD8C,OAAQjF,KAAKmT,SAAa5U,EAAGyB,KAAKoT,cAG3CpT,KAAKqT,WAAa,KACbrT,KAAKwB,MAAM1B,IAAK,cACjBE,KAAKqT,WAAa,GAAIlS,GAAQuF,aAC1BoB,QAAS,WACL/E,EAAKxE,EAAG,SAAU2J,KAAM,UAAuC,IAA5BnF,EAAKsQ,WAAWrR,SACnDe,EAAKf,MAAOe,EAAKuQ,aACjBvQ,EAAKwQ,QAAS,aAGtBvT,KAAK4I,MAAM3D,OAAQjF,KAAKqT,WAAWpR,MAIvCjC,KAAKgT,cACLhT,KAAK+S,cACL/S,KAAKiT,kBAITtQ,OAAQ,SAAU5D,GACdiB,KAAKwB,MAAMO,IAAK,OAAQhD,IAG5BiU,YAAa,WACT,GAAIjQ,GAAO/C,IACXA,MAAKmT,SAASjD,QACTlQ,KAAKwT,iBACNxT,KAAKmT,SAASlO,OAAQjF,KAAKwT,iBAAkBxT,KAAKwB,MAAM1B,IAAK,UAE7DzB,EAAEwG,KAAM7E,KAAKwB,MAAM1B,IAAK,QAAU,SAAU2T,GACxC1Q,EAAKoQ,SAASlO,OAAQ1G,EAAGwE,EAAK2Q,gBAAiBD,IACtBtR,SAAU,aACV4F,SAAWlG,MAAO4R,EAAO1L,QAASC,UAAW,aAG9E,IAAIjF,GAAO/C,IACXA,MAAKzB,EAAG,SAAUoH,GAAI,SAAU,WAC5B5C,EAAKf,MAAOe,EAAKuQ,aACjBvQ,EAAKwQ,QAAS,YAElBvT,KAAK8S,eACL9S,KAAK+S,eAGTE,eAAgB,WACZjT,KAAKiC,IAAKjC,KAAKwB,MAAM1B,IAAK,WAAc,OAAS,WAGrDiT,YAAa,WACJ/S,KAAKwB,MAAM1B,IAAK,QACM,IAAlBE,KAAKqE,WACNrE,KAAK2T,aAAc3T,KAAKwB,MAAM1B,IAAK,aAAe,QAClDE,KAAKmT,SAAS7N,OACdtF,KAAK4I,MAAMtD,QAGQ,IAAlBtF,KAAKqE,UACNrE,KAAK2T,aAAc3T,KAAKwB,MAAM1B,IAAK,cAAgB,UACnDE,KAAKmT,SAAS7N,OACdtF,KAAK4I,MAAMtD,SAEXtF,KAAKkT,SAAS5N,OACdtF,KAAKmT,SAASjP,IAAK,UAAW,gBAC9BlE,KAAK4I,MAAMxD,SAKvB0N,aAAc,WACV9S,KAAK4T,UAAW5T,KAAKwB,MAAM1B,IAAK,UACN,OAArBE,KAAKsT,aAAyBtT,KAAKwB,MAAM1B,IAAK,aAAiBE,KAAKwB,MAAM1B,IAAK,aAChFE,KAAK4T,UAAW5T,KAAK6T,SAEzB7T,KAAKqT,YAAcrT,KAAKqT,WAAWrR,MAAOzD,EAAE6F,QAASpE,KAAKsT,aAAgBtT,KAAKsT,YAAYjP,OAAS,EAAGrE,KAAKqE,WAIhHrC,MAAO,SAAW6N,GAEd,MADc7L,UAAd6L,GAA2B7P,KAAKwB,MAAMO,IAAK,QAAS8N,GAC7C7P,KAAKsT,aAIhBO,MAAO,WACH,GAAI9U,GAAUiB,KAAKzB,EAAG,SAAUsV,OAChC,OAAO9U,GAAQsF,OAAS,EAAItF,EAAQ6F,MAAQ,MAIhDwB,KAAM,WACFpG,KAAKwB,MAAMO,IAAK,QAAQ,IAI5BsG,OAAQ,WACJrI,KAAKwB,MAAMO,IAAK,QAAQ,IAI5BsC,OAAQ,WACJ,MAAOrE,MAAKzB,EAAG,cAAe8F,QAIlCuP,UAAW,SAAU/D,GACjB,GAAI9M,GAAO/C,IACX,IAAmBgE,SAAd6L,IACD7P,KAAKzB,EAAG,SAAU2J,KAAM,WAAW,GAChB,OAAd2H,GAAqB,CACtB,GAAIiE,GAASvV,EAAE6F,QAASyL,GAAcA,GAAcA,EACpDxR,GAAEwG,KAAMiP,EAAQ,SAAU9I,GACtBjI,EAAKxE,EAAG,gBAAkByM,EAAI,MAAO6I,QAAQ3L,KAAM,WAAW,OAO9EoL,UAAW,WACP,GAAIS,KAIJ,OAHA/T,MAAKzB,EAAG,YAAasG,KAAM,WACvBkP,EAAShD,KAAMxS,EAAGyB,MAAO4E,SAExB9D,EAAMkT,QAASD,GACT,KAEJ/T,KAAKwB,MAAM1B,IAAK,YAAeiU,EAAWA,EAAU,IAI/DJ,aAAc,SAAUtO,EAAM9C,GAC1BvC,KAAKkT,SAAS9N,OACAlD,cACAC,SAAU,0BAA4BI,GACtCH,KAAMiD,IAIxB+N,UAAW,WACP,MAAO7U,GAAG,UAAW4D,SAAU,sBAKnC8R,EAAYvB,EAAKpT,QACjBoU,gBAAiB,SAAUQ,GACvB,GAAIrU,GAAKiB,EAAMoG,KACf,OAAQ3I,GAAG,UAAW4D,SAAU,aACnB8C,OAAQ1G,EAAG,YAAa0F,MACrBpE,GAAUA,EACVwD,KAAUrD,KAAKwB,MAAM1B,IAAK,QAC1BH,KAAUK,KAAKwB,MAAM3B,GACrBmC,MAAUkS,EAAKlS,SAClBiD,OAAQ1G,EAAG,YAAa4D,SAAU,oBACV8B,KAAM,MAAOpE,GACbuC,KAAM8R,EAAK3F,WAKpDxH,IACJA,GAAMxG,KAAO0T,EAAU3U,QACnBiC,WAAY,SAAUxC,GAClBA,EAAQsE,KAAO,QACf4Q,EAAUE,UAAU5S,WAAWd,KAAMT,KAAMjB,KAKnD,IAAI+H,KACJA,GAASvG,KAAO0T,EAAU3U,QACtBiC,WAAY,SAAUxC,GAClBA,EAAQsE,KAAO,WACftE,EAAQ6T,UAAW,EACnBqB,EAAUE,UAAU5S,WAAWd,KAAMT,KAAMjB,KAKnD,IAAI8H,KA8BJ,OA7BAA,GAAYtG,KAAOmS,EAAKpT,QACpBiC,WAAY,SAAUxC,GAClB2T,EAAKyB,UAAU5S,WAAWd,KAAMT,KAAMjB,IAI1C6U,UAAW,SAAW/D,GACC7L,SAAd6L,IACD7P,KAAKzB,EAAG,SAAU2J,KAAM,WAAW,GACnClI,KAAKzB,EAAG,SAAU2D,YAAa,UAC/BlC,KAAKzB,EAAG,WAAasR,EAAY,MAAO3H,KAAM,WAAW,GAAO4J,QAAS,SAAU3P,SAAU,YAKrGuR,gBAAiB,SAAUQ,GACvB,GAAIjS,GAAO1D,EAAG,YAAa4D,SAAU,kBAIrC,OAHA+R,GAAK9M,MAAQnF,EAAIgD,OAAQ1G,EAAG,QAAS4D,SAAU,MAAOA,SAAU+R,EAAK9M,MAAOjF,UAAW+R,EAAK3F,OAAS,eACrGtM,EAAIgD,OAAQ1G,EAAG,YAAa0F,MAAQZ,KAAM,QAAS1D,KAAMK,KAAKwB,MAAM3B,GAAImC,MAAOkS,EAAKlS,SACpFkS,EAAK3F,OAAStM,EAAIgD,OAAQiP,EAAK3F,OACxBtM,GAIXmR,UAAW,WACP,MAAO7U,GAAG,UAAW4D,SAAU,4BAA6B8B,KAAM,cAAe,eAKrFyO,KAAcA,EACduB,UAAcA,EACdlN,MAAcA,EACdF,YAAcA,EACdC,SAAcA,IAtPlBE,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,ML45C8BH,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,GAAIA,EAAoB,KAI1GgW,GACA,SAASlW,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GAA0D,SAASC,EAAUtC,EAAGF,EAAGC,GMp6CtHqC,KAAAC,EAGG,WAKH,GAAIuJ,GAAYtJ,EAASN,KAAKjB,QAK1BiC,WAAY,SAAUoH,EAAS5J,GAE3BiB,KAAK2I,QAAUA,EACV3I,KAAK2I,QAAQtE,SACdrE,KAAK2I,QAAUpK,EAAG,WAEtByB,KAAKjB,QAAUA,MACfiB,KAAK2I,QAAQsJ,KAAM,YAAajS,KAGhC,IAAIqU,GAAOrU,IACXA,MAAK2I,QAAQ+D,MAAO,SAAU4H,GAI1B,MAFA/V,GAAG,oBAAqB+K,SACxB+K,EAAKE,eAAgBD,IACd,KAKfC,eAAgB,SAAUC,GACtBxU,KAAK4B,SACL5B,KAAKiC,IAAIwS,SAAU,QAASvQ,IAAKlE,KAAK0U,kBAAmBF,IAAcpP,OACvEpF,KAAK2U,uBAKT/S,OAAQ,WAOJ,GALA5B,KAAKiC,IAAIE,SAAU,mBAAoBmD,OAClCpB,KAAM0Q,SAAW,aACjBxS,KAAMpC,KAAK6U,SAAU7U,KAAK2I,QAAQ1E,KAAM,MAAQjE,KAAKjB,UAGtDiB,KAAKjB,QAAQsF,OAAQ,CACrB,GAAIgQ,GAAOrU,IAEXA,MAAKiC,IAAIiK,KAAM,MAAOrH,KAAM,SAAUiQ,EAAGC,GACrC,GAAItB,GAASY,EAAKtV,QAAQ+V,EAGtBrB,GAAO3E,MACPvQ,EAAGyB,MAAOwQ,SAAU,sBAAuB9D,MAAO,SAAU4H,GACxDb,EAAO3E,KAAKrO,KAAM4T,EAAMC,EAAOb,GAI/Ba,EAAMjL,qBAMtB,MAAOrJ,OAGX6U,SAAW,SAAUhV,EAAId,GACrB,OACI,WAAYc,EAAI,gCAAiCG,KAAKwT,iBAAkBzU,GAAW,SACrFiW,KAAM,KAGZxB,iBAAmB,SAAUzU,GACzB,MAAKA,GAAQsF,OAGNhG,EAAE4W,IAAKlW,EAAS,SAAU0U,GAC7B,GAAIA,EAAO/J,QACP,MAAO,2BACJ,IAAI+J,EAAOtH,OACd,OAAS,kDAAmDsH,EAAOrR,KAAM,aAAc4S,KAAM,GAEjG,IAAIzM,GAASkL,EAAOlL,MAAQ,sBACxBxC,EAAW0N,EAAO1N,OAAY,YAAc0N,EAAO1N,OAAS,IAAQ,GACpEiL,EAAWyC,EAAOyB,QAAY,oCAAwC,EAC1E,QACI,yCAA0C3M,EAAM,IAAKxC,EAAQ,IACzDiL,EAAOyC,EAAOrR,KAClB,aACF4S,KAAM,MACTA,KAAM,IAhBE,yBAoBfN,kBAAoB,SAAUF,GAG1B,GAAIW,GAAYnV,KAAKiC,IAAIgG,QACrBmN,EAAIZ,EAAWa,MAAQF,EAAY,CAKvC,OAFAC,GAAIE,KAAKC,IAAKH,EAAG7W,EAAGiX,UAAWC,aAAelX,EAAGM,QAASoJ,QAAUkN,EAAY,GAChFC,EAAIE,KAAKI,IAAKN,EAAG7W,EAAGiX,UAAWC,aAAe,IAE1C3J,IAAK0I,EAAWmB,MAChBC,KAAMR,IAMdT,oBAAqB,WAKjB,QAASkB,GAAYvB,GAEjB,GADA/V,EAAGiX,UAAW3N,IAAK,qBACfhJ,QAAUA,OAAOsO,SAAWtO,OAC5B,IACIN,EAAGM,OAAOsO,OAAOqI,UAAW3N,IAAK,qBACnC,MAAOiO,QAET,KACIvX,EAAG,sBAAuBwX,WAAWlO,IAAK,qBAC5C,MAAOiO,IAEbzB,EAAK/K,SAfT,GAAI+K,GAAOrU,IAmBX,IADAzB,EAAG,QAASyX,IAAK,oBAAqBH,GAClChX,QAAUA,OAAOsO,SAAWtO,OAC5B,IACIN,EAAGM,OAAOsO,OAAOqI,UAAWtJ,KAAM,QAAS8J,IAAK,oBAAqBH,GACvE,MAAOC,QAET,KACIvX,EAAG,sBAAuBwX,WAAWC,IAAK,oBAAqBH,GACjE,MAAOC,MAKjBpH,QAAS,SAAUX,EAAMC,GAIrB,MAFAA,GAAUA,GAAS,EAAMA,EAAQhO,KAAKjB,QAAQsF,OAC9CrE,KAAKjB,QAAQkX,OAAQjI,EAAO,EAAGD,GACxB/N,MAIXkW,WAAY,SAAUlI,GAIlB,MAHIA,IAAQ,GACRhO,KAAKjB,QAAQkX,OAAQjI,EAAO,GAEzBhO,MAIXmW,gBAAiB,SAAU/T,GACvB,IAAK,GAAI0S,GAAI,EAAGA,EAAI9U,KAAKjB,QAAQsF,OAAQyQ,IACrC,GAAIzW,EAAE+X,IAAKpW,KAAKjB,QAAQ+V,GAAI,SAAc9U,KAAKjB,QAAQ+V,GAAG1S,OAASA,EAC/D,MAAO0S,EAGf,OAAO,OAIX9F,eAAgB,SAAU5M,GACtB,MAAOpC,MAAKjB,QAAUiB,KAAKmW,gBAAiB/T,KAIhDiU,SAAU,WACN,MAAO,cAqIX,OAjIJlM,GAAUmM,OAAS,SAAkB3N,EAAS5J,GAC1C,MAAO,IAAIoL,GAAWxB,EAAS5J,IAcnCoL,EAAUoM,eAAiB,SAAUC,EAAgBC,GACjD,GAAIC,KAgBJ,OAfArY,GAAEwG,KAAM4R,EAAiB,SAAUE,EAAWC,GAC1C,GAAIC,IAAczU,KAAMwU,EAGN,QAAdD,EACAE,EAAU1K,QAAS,EAGiB,aAA7B7N,EAAO+E,KAAMsT,KACpBE,EAAU/H,KAAO6H,GAIrBD,EAAiB3F,KAAM8F,KAEpB,GAAI1M,GAAW5L,EAAGiY,GAAkBE,IAS/CvM,EAAU2M,sBAAwB,SAAUC,EAASC,GACjDD,EAAUxY,EAAGwY,GACbC,EAAWA,GAAY,GACvB,IAAIjY,KAoCJ,OAnCAgY,GAAQ7K,KAAM8K,GAAWnS,KAAM,SAAUoS,EAAMnC,GAC3C,GAAIrB,MAAahK,EAAQlL,EAAG0Y,EAI5B,IADAxD,EAAOrR,KAAOqH,EAAMpE,OAChBoE,EAAMxF,KAAM,QAAU,CACtB,GAAIiT,GAAczN,EAAMxF,KAAM,QAC1BkT,EAAc1N,EAAMxF,KAAM,UAC1BmT,EAAc3N,EAAMxF,KAAM,UAE9BwP,GAAO3E,KAAO,WAGV,IAAMsI,GAAoBvI,QAASuI,GAGnC,OAAQD,GAEJ,IAAK,UACDtY,OAAOsO,OAAOoE,SAAW2F,CACzB,MAGJ,KAAK,OACDrY,OAAOiN,IAAIyF,SAAW2F,CACtB,MAGJ,SACIrY,OAAO0S,SAAW2F,IAIlCnY,EAAQgS,KAAM0C,KAEX1U,GASXoL,EAAUkN,gBAAkB,SAAUC,EAAgBC,EAAcC,GAChEF,EAAiB/Y,EAAG+Y,GACpBC,EAAehZ,EAAGgZ,EAClB,IAAIxY,GAAUoL,EAAU2M,sBAAuBS,EAAcC,EAG7D,OADAD,GAAajO,SACN,GAAIa,GAAWmN,EAAgBvY,IAW1CoL,EAAUsN,iBAAmB,SAAUtK,EAAQuK,EAAcC,GACzDxK,EAASA,GAAUqI,SAGnBkC,EAAeA,GAAgB,iBAE/BC,EAAwBA,GAAyB,SAAUJ,EAAcpK,GACrE,MAAO,IAAMoK,EAAatT,KAAM,aAIpC,IAAI2T,KAOJ,OANArZ,GAAG4O,GAASjB,KAAMwL,GAAe7S,KAAM,WACnC,GAAI0S,GAAkBhZ,EAAGyB,MACrBsX,EAAkB/Y,EAAG4O,GAASjB,KAAMyL,EAAuBJ,EAAcpK,GAC7EyK,GAAkB7G,KAAM5G,EAAU0N,QAASP,EAAgBC,IAC3DD,EAAenV,SAAU,WAEtByV,GAKAzN,GAxTXnD,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,MNytD8BH,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,GAAIA,EAAoB,GAAIA,EAAoB,KAIlI0Z,GACA,SAAS5Z,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GOhuDnC,SAAAC,EAAAtC,EAAAF,GAGAsC,GAASvC,EAAA,GAAeA,EAAA,IAAxBwC,EAA+C,SAAUE,EAAOK,GAChE,GAAIZ,GAAOM,EAASN,KAAKjB,QACrBiC,WAAY,SAAUxC,GAClB,GAAIgE,GAAO/C,IACXA,MAAKiS,QACLjS,KAAK+X,SACL/X,KAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClD5B,GAAciB,EAAMoG,MACpB1E,IAAc,YACdmQ,WAAc,uBACdqF,WAAc,mBACdvU,SAAc,EACd2C,MAAc,EACdwM,UAAc,EACdqF,YAAc,EACdpF,UAAc,EACdtP,UAAc,EACdkF,SAAc,aACdzG,MAAc,KACdkW,WAAc,EACdC,SAAc,KACfpW,IAAKhD,GACRiB,KAAK2F,GAAI,SAAU,WAAa5C,EAAKvB,MAAM1B,IAAK,aAAgBiD,EAAKvB,MAAM1B,IAAK,YAAciD,EAAKf,WACnGhC,KAAK2B,SAAU3B,KAAKwB,MAAO,cAAexB,KAAKgT,YAAahT,MAC5DA,KAAK2B,SAAU3B,KAAKwB,MAAO,kBAAmBxB,KAAKoY,gBAAiBpY,MACpEA,KAAK2B,SAAU3B,KAAKwB,MAAO,cAAexB,KAAK+S,YAAa/S,MAC5DA,KAAK2B,SAAU3B,KAAKwB,MAAO,iBAAkBxB,KAAKiT,eAAgBjT,MAClEA,KAAK2B,SAAU3B,KAAKwB,MAAO,eAAgBxB,KAAK8S,aAAc9S,MAC9DA,KAAK2B,SAAU3B,KAAKwB,MAAO,yDAA0DxB,KAAK4B,OAAQ5B,MAClGA,KAAK4B,UAGTA,OAAQ,WACJ,GAAImB,GAAO/C,IACXA,MAAKwB,MAAM1B,IAAK,cAAiBE,KAAKqY,oBAAsBrY,KAAKsY,iBACjEtY,KAAKiC,IAAIE,SAAUnC,KAAKwB,MAAM1B,IAAK,QAC1BmE,KAAM,KAAMjE,KAAKwB,MAAM1B,IAAK,OACrCE,KAAKuY,QAAQrI,QAAQ/N,SAAU,UAClB8B,KAAM,KAAMjE,KAAKwB,MAAM1B,IAAK,MAAS,WACrCoI,KAAM,WAAYlI,KAAKwB,MAAM1B,IAAK,aAClC6F,GAAI,SAAU,WACX5C,EAAKf,MAAOe,EAAKuQ,aACjBvQ,EAAKwQ,QAAS,YAE9BvT,KAAKgT,cACLhT,KAAK+S,cACL/S,KAAKiT,iBACLjT,KAAKoY,mBAITE,eAAgB,WACZ,GAAIvV,GAAO/C,IACXA,MAAKiC,IAAIE,SAAUnC,KAAKwB,MAAM1B,IAAK,YAAe,qBAAuB,aAChEmF,OAAQjF,KAAKuY,QAAeha,EAAG,cAC/B0G,OAAQjF,KAAKwY,UAAeja,EAAG,WAC/B0G,OAAQjF,KAAKyY,QAAela,EAAG,UAC/B0G,OAAQjF,KAAK0Y,aAAena,EAAG,UACnCyB,KAAKwB,MAAM1B,IAAK,aACjBE,KAAKwY,UAAUlT,OACftF,KAAK0Y,aAAavW,SAAU,yCAA0CiD,OACtEpF,KAAKyY,QAAQvW,cACAC,SAAU,eACViD,OACAyC,IAAK,aAAclC,GAAI,YAAa,SAAU2O,GAC3C,GAAIqE,GAAWrE,EAAMqB,MACjBiD,EAAgB7V,EAAKwV,QAAQM,QACjC9V,GAAK+V,UAAY/V,EAAK+V,WAAaF,EACnCra,EAAG,cAAe6G,OAAOO,GAAI,YAAa,SAAU2O,GAChDvR,EAAKwV,QAAQM,OAAQvD,KAAKI,IAAKkD,GAAkBtE,EAAMqB,MAAQgD,GAAY5V,EAAK+V,cACjFnT,GAAI,qBAAsB,WACzBpH,EAAG,cAAe+G,OAAOuC,YAI7C7H,KAAKwY,UAAUpT,OACfpF,KAAKyY,QAAQnT,OACbtF,KAAK0Y,aAAapT,SAK1B+S,kBAAmB,WACf,GAAItV,GAAO/C,IACXA,MAAKiC,IAAIgD,OAAQjF,KAAKuY,QAAYha,EAAG,WAC5B0G,OAAQjF,KAAKwY,UAAYja,EAAG,WACrCyB,KAAKwY,UAAUlT,OACTtF,KAAKwB,MAAM1B,IAAK,aAClBE,KAAKwY,UAAUpT,OAAOO,GAAI,QAAS,WAC/B5C,EAAKwV,QAAQQ,SAAWhW,EAAKwV,QAAQQ,QAAS,UAGtD/Y,KAAKqT,WAAa,KACbrT,KAAKwB,MAAM1B,IAAK,aAAgBE,KAAKwB,MAAM1B,IAAK,eACjDE,KAAKqT,WAAa,GAAIlS,GAAQuF,aAC1BoB,QAAS,WACL,GAAI+H,KACwB,KAA5B9M,EAAKsQ,WAAWrR,SAAiB3D,EAAEwG,KAAM9B,EAAKvB,MAAM1B,IAAK,QAAU,SAAU2T,GACzE5D,EAAUkB,KAAM0C,EAAOzR,SAE3Be,EAAKf,MAAO6N,GACZ9M,EAAKwQ,QAAS,aAGtBvT,KAAKiC,IAAI+W,QAAShZ,KAAKqT,WAAWpR,OAK1CgX,OAAQ,SAAUC,EAAM7T,GACpB,OAAQ6T,GAAgB,IAARA,GAAcC,OAAQ9T,GAAO+T,cAAc1J,QAASwJ,EAAKE,gBAAmB,GAIhGpG,YAAa,WACT,GAAIjQ,GAAO/C,IACXA,MAAKiS,SACCjS,KAAKwB,MAAM1B,IAAK,aAAgBE,KAAKwB,MAAM1B,IAAK,aAClDE,KAAKiS,KAAKlB,MAAQ/O,MAAO,WAAYuM,MAAOxL,EAAKvB,MAAM1B,IAAK,gBAEhEzB,EAAEwG,KAAM7E,KAAKwB,MAAM1B,IAAK,QAAU,SAAU2T,GACxC1Q,EAAKkP,KAAKlB,KAAM0C,KAEE,GAAjBzT,KAAKqE,UACNrE,KAAKiS,KAAKlB,MAAQ/O,MAAO,WAAYuM,MAAOvO,KAAKwB,MAAM1B,IAAK,gBAE3DE,KAAKwB,MAAM1B,IAAK,eACjBE,KAAK+X,SACL1Z,EAAEwG,KAAM7E,KAAKiS,KAAM,SAAUwB,EAAQzF,GACjCjL,EAAKgV,MAAMhH,MAAQsI,MAAOrL,EAAOnO,GAAI4T,EAAOzR,MAAOqD,KAAMoO,EAAOlF,MAAO+K,KAAM7F,EAAO6F,SAExFtZ,KAAKuY,QAAQtG,KAAM,YAAejS,KAAKuY,QAAQQ,QAAS,WACxD/Y,KAAKuZ,gBACLvZ,KAAKuY,QAAQQ,SACT9G,KAAkBlP,EAAKgV,MACvByB,eAAmBxZ,KAAKwB,MAAM1B,IAAK,YACnC8S,SAAkB5S,KAAKwB,MAAM1B,IAAK,YAClC2Z,MAAkB,SAAUC,GACxB3W,EAAKwW,eACL,IAAIpB,GAAWpV,EAAKvB,MAAM1B,IAAK,YAC3B6Z,EAAUtb,EAAEqP,OAAQ3K,EAAKgV,MAAO,SAAWnS,GAC3C,GAAIgU,IAAQ,CAMZ,OALAvb,GAAEwG,KAAMe,EAAE0T,KAAM,SAAUvQ,GACjBhG,EAAKkW,OAAQS,EAAER,KAAMnQ,KACtB6Q,EAAQ7W,EAAKwW,aAAcxQ,IAAQ;GAGpC6Q,GAAS7W,EAAKkW,OAAQS,EAAER,KAAMtT,EAAEP,OAE3CqU,GAAEG,UACEF,QAASA,EAAQG,OAASJ,EAAEzZ,KAAO,GAAMkY,EAAUuB,EAAEzZ,KAAOkY,GAC5D4B,KAASJ,EAAQtV,QAAUqV,EAAEzZ,KAAOkY,KAG5C6B,aAAkB,SAAU3T,GACxB,MAAOhI,GAAE6E,OAAQmD,EAAOhB,MACpB,wBACIhH,EAAE4b,OAAQ5T,EAAOiT,KAAM,SAAUY,EAAMnR,GACnC,MAAKhG,GAAKwW,aAAcxQ,GACbmR,EAAO,uCAEN7b,EAAE6E,OAAQ6F,GACd,SAEDmR,GACR,IACP,YAGZla,KAAKzB,EAAG,4CAA6CsJ,IAAK,UAE1D7H,KAAKuY,QAAQrM,KAAM,UAAW5C,SAC9BjL,EAAEwG,KAAM7E,KAAKiS,KAAM,SAAUwB,GACzB1Q,EAAKwV,QAAQtT,OAAQ1G,EAAG,aAAc0F,KAAM,QAASwP,EAAOzR,OAAQI,KAAM/D,EAAE6E,OAAQuQ,EAAOlF,YAGnGvO,KAAKwB,MAAMO,IAAK,WAA6B,GAAjB/B,KAAKqE,UACjCrE,KAAK8S,gBAITsF,gBAAiB,WACRpY,KAAKwB,MAAM1B,IAAK,cACjBE,KAAKuY,QAAQQ,QAAS/Y,KAAKwB,MAAM1B,IAAK,YAAe,UAAY,UAEjEE,KAAKuY,QAAQrQ,KAAM,WAAYlI,KAAKwB,MAAM1B,IAAK,cAKvDiT,YAAa,WACT/S,KAAKwY,UAAUtW,cACAC,SAAU,oBACVA,SAAUnC,KAAKwB,MAAM1B,IAAK,QAAW,qBAAuB,kBAI/EmT,eAAgB,WACZjT,KAAKiC,IAAKjC,KAAKwB,MAAM1B,IAAK,WAAc,OAAS,UACjDE,KAAKuY,QAASvY,KAAKwB,MAAM1B,IAAK,WAAc,OAAS,WAIzDgT,aAAc,WAEV,GADA9S,KAAK4T,UAAW5T,KAAKwB,MAAM1B,IAAK,UAC3BE,KAAKwB,MAAM1B,IAAK,aACjB,GAAKE,KAAKqT,WAAa,CACnB,GAAIrR,GAAQhC,KAAKsT,WACjBtT,MAAKqT,WAAWrR,MAAOzD,EAAE6F,QAASpC,GAAUA,EAAMqC,OAAS,EAAGrE,KAAKqE,eAE1C,QAArBrE,KAAKsT,aAAyBtT,KAAKwB,MAAM1B,IAAK,aACtDE,KAAK4T,UAAW5T,KAAK6T,UAK7B7R,MAAO,SAAW6N,GAEd,MADc7L,UAAd6L,GAA2B7P,KAAKwB,MAAMO,IAAK,QAAS8N,GAC7C7P,KAAKsT,aAIhBO,MAAO,WACH,MAAO7T,MAAKiS,KAAK5N,OAAS,EAAIrE,KAAKiS,KAAM,GAAIjQ,MAAQ,MAIzDmY,OAAQ,SAAUnY,GACd,MAAO3D,GAAEuS,UAAW5Q,KAAKiS,MAAQjQ,MAAOA,KAI5CqD,KAAM,WACF,GAAI2F,GAAIhL,KAAKsT,YACT8G,EAAIpa,KAAKma,OAAQ5b,EAAE6F,QAAS4G,GAAMA,EAAG,GAAMA,EAC/C,OAAOoP,GAAIA,EAAE7L,MAAQ,IAIzBnJ,KAAM,WACFpF,KAAKwB,MAAMO,IAAK,WAAW,IAI/BuD,KAAM,WACFtF,KAAKwB,MAAMO,IAAK,WAAW,IAI/BqE,KAAM,WACFpG,KAAKwB,MAAMO,IAAK,QAAQ,IAI5BsG,OAAQ,WACJrI,KAAKwB,MAAMO,IAAK,QAAQ,IAI5BwB,SAAU,WACN,MAAOvD,MAAKwB,MAAM1B,IAAK,aAI3BsI,OAAQ,WACJpI,KAAKwB,MAAMO,IAAK,YAAY,IAIhCoG,QAAS,WACLnI,KAAKwB,MAAMO,IAAK,YAAY,IAIhC6H,IAAK,SAAU7K,EAASsb,GACpBhc,EAAEwG,KAAM7E,KAAKwB,MAAM1B,IAAK,QAAU,SAAUkL,GACxCA,EAAEsP,OAASjc,EAAEuS,UAAW7R,GAAWiD,MAAOgJ,EAAEhJ,SAAajD,EAAQgS,KAAM/F,KAE3EqP,GAAUtb,GAAWA,EAAQwb,KAAMF,GACnCra,KAAKwB,MAAMO,IAAK,OAAQhD,IAI5B4D,OAAQ,SAAU5D,GACdiB,KAAKwB,MAAMO,IAAK,OAAQhD,IAI5Byb,YAAa,SAAUX,GACnB7Z,KAAKwB,MAAMO,IAAK,WAAY8X,IAIhCxV,OAAQ,WACJ,MAAO9F,GAAE6F,QAASpE,KAAKwB,MAAM1B,IAAK,SAAaE,KAAKwB,MAAM1B,IAAK,QAASuE,OAAS,GAIrFuP,UAAW,SAAU/D,GACjB,GAAI9M,GAAO/C,IAaX,IAZkB,OAAd6P,GAAoC7L,SAAd6L,IACtBA,EAAY,YAEX7P,KAAKwB,MAAM1B,IAAK,YACjB+P,EAAYtR,EAAE6F,QAASyL,GAAcA,GAAcA,GAC3CtR,EAAE6F,QAASyL,KAEfA,EADCA,EAAUxL,OAAS,EACRwL,EAAW,GAEX,YAGf7P,KAAKwB,MAAM1B,IAAK,cAAiB,CAClC,GAAKvB,EAAE6F,QAASyL,GACZjL,OACAvG,EAAEwG,KAAMgL,EAAW,SAAU7E,GACzB,GAAIoP,GAAI/b,EAAEuS,UAAW7N,EAAKgV,OAASlY,GAAImL,GACvCoP,IAAKxV,IAAImM,KAAMqJ,KAEnBvK,EAAYjL,QACT,CACH,GAAIwV,GAAI/b,EAAEuS,UAAW5Q,KAAK+X,OAASlY,GAAIgQ,GACvCA,GAAYuK,EAEhBpa,KAAKuY,QAAQQ,QAAS,OAAQlJ,OAE9B7P,MAAKuY,QAAQ3T,IAAKiL,IAK1ByD,UAAW,WACP,GAAI1O,GAAM,IACV,IAAK5E,KAAKwB,MAAM1B,IAAK,cAAiB,CAClC,GAAIiU,GAAW/T,KAAKuY,QAAQQ,QAAS,OAChChF,KACIxV,EAAE6F,QAAS2P,IACZnP,KACAmP,EAASwG,KAAM,SAAUE,EAAGC,GAAM,MAAOD,GAAEpB,MAAQqB,EAAErB,QACrDhb,EAAEwG,KAAMkP,EAAU,SAAU/I,GAAMpG,EAAImM,KAAM/F,EAAEnL,OAE9C+E,EAAMmP,EAASlU,QAIvB+E,GAAM5E,KAAKuY,QAAQ3T,KAEvB,OAAO9D,GAAMkT,QAASpP,GAAQ,KAAOA,IAI7C,QACIrE,KAAMA,IAhWVyG,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,MPqjE8BH,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,GAAIA,EAAoB,KAI1Guc,GACA,SAASzc,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GQ/jEnC,SAAAC,EAAAxC,EAAAE,GACAoC,KAAAC,EAAW,WAGX,MAAOC,GAASY,MAAMnC,QAClBsb,UACIza,SAAU,GACVyR,OAAO,EACPiJ,aACAC,uBACA/P,WACAgQ,SAAU,KACVC,sBAAsB,EACtBvQ,iBAAiB,EACjB8F,SAAU,EACV0K,UAAW,EACX9M,UAAWnK,OACX8M,SAAU9M,QAMdyN,aAAc,SAASyJ,GACnB,MAAO7c,GAAEqR,QAAQ1P,KAAK4H,WAAWiT,UAAWK,MAAQ,GAMxDjM,WAAY,SAASkM,EAAKnZ,EAAOiD,GAE7B,GAAIA,EAAQ,CAER,GACIlB,GADAqX,EAAUpb,KAAK4H,WAAWmD,QAAQoQ,EAEtC,IAAgB,OAAZC,GAAgCpX,SAAZoX,EACpBrX,EAAU/B,MAET,IAAuB,gBAAZoZ,GACZ,GAAe,OAAXA,EACArX,EAAU/B,MACP,CAEH,GAAI8R,KACJA,GAAO,GAAKsH,EACZtH,EAAO,GAAK9R,EACZ+B,EAAU+P,MAKd/P,GAAUqX,EACVrX,EAAQgN,KAAK/O,EAEjBhC,MAAK4H,WAAWmD,QAAQoQ,GAAOpX,MAI/B/D,MAAK4H,WAAWmD,QAAQoQ,GAAOnZ,GAOvCsN,cAAe,SAAS6L,EAAKE,GACzB,GAAID,GAAUpb,KAAK4H,WAAWmD,QAAQoQ,EACtC,IAAgB,OAAZC,GAAgCpX,SAAZoX,EACpB,OAAO,CAGX,IAAwB,gBAAbA,GAEPpb,KAAK4H,WAAWmD,QAAQoQ,GAAO,OAC5B,CAEH,GAAIG,GAAkBjd,EAAEqR,QAAQ0L,EAASC,EACrCC,MAAoB,IACpBF,EAAQE,GAAmB,MAQvC9J,aAAc,WACV,GAAI1G,IACA8G,MAAO5R,KAAK4H,WAAWgK,MACvB2I,KAAMva,KAAK4H,WAAWmT,SACtB9a,KAAMD,KAAK4H,WAAW2I,SACtByK,qBAAsBhb,KAAK4H,WAAWoT,qBACtCvQ,gBAAiBzK,KAAK4H,WAAW6C,gBAIjCzK,MAAK4H,WAAWuG,YAChBrD,EAASqD,UAAYnO,KAAK4H,WAAWuG,WAErCnO,KAAK4H,WAAWkJ,WAChBhG,EAASjL,GAAKG,KAAK4H,WAAWkJ,SAIlC,IAAI/N,GAAO/C,IAIX,OAHA3B,GAAEwG,KAAKxG,EAAEkd,MAAMxY,EAAK6E,WAAWmD,SAAU,SAASE,GAC9CH,EAAS,KAAOG,EAAE,IAAMA,EAAE,KAEvBH,GAIX0Q,QAAS,SAAU9b,GACf,MAAOM,MAAKF,IAAI,YAAc,IAAMvB,EAAE6M,MAAMpL,KAAKwR,gBAAkB,IAAMjT,EAAE6M,MAAM1L,OAjHzFsH,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,MRkrE8BH,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,GAAIA,EAAoB,KAI1Gqd,GACA,SAASvd,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GS1rEnC,SAAAtC,GACAqC,GAAQvC,EAAA,IAARwC,EAAwB,SAASE,GAGjC,OAEIsJ,KAAM,SAASrL,GACX,GAAI2c,GAAO,EA4BX,OA1BIA,GADA3c,EAAQuM,SACDtL,KAAK2b,YAAY5c,GAAWiB,KAAK4b,WAAW7c,GAE5C,qEAIaiB,KAAK2b,YAAY5c,GACrB,uHAURiB,KAAK4b,WAAW7c,GAIxBA,EAAQ8c,YACRH,GAAQ,uDAAyD3c,EAAQ8c,UAAY,UAIlFH,GAIXE,WAAY,SAAS7c,GACjB,MAAQ,oNAUZ4c,YAAa,SAAS5c,GAClB,GAAI2c,GAAQ,2BAIZ,IAHK3c,EAAQuM,WACToQ,GAAY,OAAS3c,EAAQ8C,MAAQ,SAErC9C,EAAQ+c,eAAgB,CACxBJ,GAAY,mCACZ,IAAIK,GAAchd,EAAQ+c,eAAezX,QAAU,CAC/C0X,KACAL,GAAY,mIAGhB,KAAK5G,IAAK/V,GAAQ+c,eAAgB,CAC9B,GAAIE,GAASjd,EAAQ+c,eAAehH,EACpC4G,IAAgB,mDACqDM,EAAOjW,OAAS,WAAaiW,EAAOrN,SAAW,8BAAgCqN,EAAOzN,MAAQ,YAGnKwN,IACAL,GAAY,UAEhBA,GAAY,QAWhB,MATI3c,GAAQsT,SACRqJ,GAAY3c,EAAQsT,QAIxBqJ,GAAY1b,KAAKic,aAAald,GAC9B2c,GAAQ,UAOZvP,OAAQ,SAASpN,GAGb,GAAI2c,GAAY,MAGZ3c,GAAQic,uBACRU,GAAgB,OACZ3c,EAAQ8L,MAAMxG,OAAS,IACvBqX,GAAgB,2IAGpBA,GAAgB,QAIpB,KAAK,GAAI5G,KAAK/V,GAAQmd,QAAS,CAC3B,GAAIC,GAASpd,EAAQmd,QAAQpH,EACzBqH,GAAO1Y,UACPiY,GAAY,WAAaS,EAAOhB,IAAM,YAElCO,GADAS,EAAO5T,KACK,YAAc4T,EAAO5T,KAAO,iCAAmC4T,EAAOhB,IAAM,KAAOgB,EAAO5N,MAAQ,OAElG4N,EAAO5N,MAEvBmN,GAAgB,4BAA8BS,EAAOC,MAAQ,gBASrE,MAHAV,IAAe,SAOnBtP,KAAM,SAASrN,GAEX,GAAI2c,GAAO,GACPW,EAAoB,EACpBvO,EAAe/O,EAAQ8L,MAAMxG,MAGb,IAAhByJ,IAEA4N,GAAQ,oDACRW,EAAoB,EAIxB,KAAK,GAAIvH,KAAK/V,GAAQ8L,MAAO,CAGzB,GAAIkD,GAAOhP,EAAQ8L,MAAMiK,GACrBwH,EAAavO,EAAKgB,SAItB2M,IAAQ,OACJ3c,EAAQwd,iBAAmBxO,EAAKlO,KAChC6b,GAAQ,mBAEZA,GAAQ,IAGJ3c,EAAQic,uBACRU,GAAQ,qEACiDY,EAAa,SAAWA,EAAa,6CAKlG,KAAKE,IAAKzd,GAAQmd,QAAS,CACvB,GAAIC,GAASpd,EAAQmd,QAAQM,EAC7B,IAAIL,EAAO1Y,QAAS,CAEhB,GAAIgZ,GAAS,EACTN,GAAOM,SACPA,EAAS,8BAIb,IAAIC,GAAkB3O,EAAK4O,cAAcR,EAAO5N,OAG5CqO,EAAOF,EAAgBE,KACvB5a,EAAQ0a,EAAgB1a,MACxB+D,EAAS2W,EAAgB3W,MAGA,YAAzBzH,EAAO+E,KAAMrB,KACbA,EAAQA,EAAMiK,QAAQ,QAAS,KAInC,IAAIpM,GAAK,GACL2C,EAAM,EACN2Z,GAAOU,eACPhd,EAAK,QAAUiV,EAAI,SACnBtS,EAAM,aACM,IAARoa,IACApa,GAAO,UAEXA,GAAO,UAIXkZ,GAAQ,OAASe,EAAS,IAGtBG,GACiC,GAA7B7d,EAAQ8R,WAAWxM,SACnBqX,GAAQ,YAAc7b,EAAK,YAAc2C,EAAM,2BAEnDkZ,GAAQ,kDAAoD3V,EAAS,WAAa6W,EAAO,6BAA+B5a,EAAQ,OAC/F,GAA7BjD,EAAQ8R,WAAWxM,SACnBqX,GAAQ,WAGZA,GAAQ,YAAc7b,EAAK,YAAc2C,EAAM,gBAAkB2Z,EAAOW,gBAAkBR,EAAa,UAAYA,EAAa,MAAQta,GAAS,IAAM,iBAE3J0Z,GAAQ,SAGhBA,GAAQ,QACRW,IAEJ,MAAOX,IAIXrP,OAAQ,SAAStN,GAGb,GAAI2c,GAAO,EAGX,IAAI3c,EAAQge,YAAche,EAAQkc,UAAY,EAAG,CAE7C,GAAI+B,GAAsBje,EAAQie,eAC9BC,EAAsBle,EAAQke,aAC9BhC,EAAsBlc,EAAQkc,UAG9BiC,EAAsBF,EAAiB,EACvCG,EAAsBF,EAAeC,EACrCE,EAAsB,CACtBD,IAAY,IAEZA,EAAW,EACXC,EAAaF,GAAoBD,EAAeE,GAIpD,IAAIE,GAAYH,EAAkBE,EAC9BE,EAAWL,EAAeI,CAC1BC,IAAYrC,EAEZsC,WAAa,GAGbD,EAAWrC,EAEXsC,WAAaF,GAAcC,EAAW,EAAIL,IAK5B,GAAdM,aACAJ,GAAYI,WACRJ,EAAW,IACXA,EAAW,IAKnBzB,GAAQ,2BACJ3c,EAAQic,uBACRU,GAAQ,aAEZA,GAAY,yDAIRyB,EAAW,IACXzB,GAAgB,+HAIpB,KAAK,GAAI8B,GAAaL,EAAUK,EAAaF,EAAW,EAAGE,IAGnD9B,GADA8B,GAAcze,EAAQke,aACV,uDAAyDO,EAAa,KAAOA,EAAa,UAE1F,yCAA2CA,EAAa,qEAAuEA,EAAa,KAAOA,EAAa,aAKhLF,GAAWrC,IACPS,GAAY,4CAC2CT,EAAY,qEAAuEA,EAAY,KAAOA,EAAY,eAEjLS,GAAgB,UAGhBA,GAAgB,wJAMpB,GAAI3c,EAAQic,qBAAsB,CAE9BU,GAAQ,6JAOR,KAAK5G,IAAK/V,GAAQ8R,WAAY,CAC1B,GAAI1C,GAAYpP,EAAQ8R,WAAWiE,EAC/B3G,GAAUsP,iBACV/B,GAAQ,+BAAiCvN,EAAUI,MAAQ,mDAKnEmN,GAAY,aAKhB,GAAIgC,IAAe,CACnB,KAAK5I,IAAK/V,GAAQ8R,WACd,GAAI9R,EAAQ8R,WAAWiE,GAAG6I,iBAAkB,CACxCD,GAAe,CACf,OAKR,GAAIA,EAAc,CACdhC,GAAQ,wBAER,KAAK5G,IAAK/V,GAAQ8R,WAAY,CAC1B,GAAI1C,GAAYpP,EAAQ8R,WAAWiE,EAC/B3G,GAAUwP,mBACVjC,GAAQ,kCAAoCvN,EAAUwP,iBAAmB,KAAOxP,EAAUI,MAAQ,QAG1GmN,GAAY,aAYhB,MAPI3c,GAAQ6e,SACRlC,GAAQ,yBAC2B3c,EAAQ6e,OAAS,cAKjDlC,GAIXpZ,QAAS,SAASvD,GACd,MAAQ,kBACqBA,EAAQwD,OAAS,8BAAgCxD,EAAQuD,QAAU,6CAMpG2Z,aAAc,SAAUld,GAGpB,GAAI8e,GAAsB9e,EAAQ8e,oBAC9B9S,EAAUhM,EAAQgM,QAGlB+S,EAA0B,MAC1B/e,GAAQ0L,kBACRqT,EAA0B,QAI9B,IAAIC,IAA4B,CAChC,KAAK,GAAIjJ,KAAK/V,GAAQmd,QAAS,CAC3B,GAAIC,GAASpd,EAAQmd,QAAQpH,EAC7B,IAAyB,YAArBqH,EAAO6B,WAA0B,CACjC,GAAIhR,GAAamP,EAAOhB,IACpB8C,EAAQlT,EAAQiC,GAChBkR,EAAQL,EAAoB7Q,EAC5BiR,IAASC,GAASD,GAASC,IAC3BJ,EAA0B,SAE9BC,GAA4B,GAKpC,GAAII,GAA0B,OACC,UAA3BL,IACAK,EAA0B,OAM9B,IAAIzC,GAAQ,6CAA+CyC,EAA0B,+CAOrF,KAAK,GAAIrJ,KAAK/V,GAAQmd,QAAS,CAC3B,GAAIC,GAASpd,EAAQmd,QAAQpH,EACJ,aAArBqH,EAAO6B,aACPtC,GAAoB1b,KAAKoe,mBAAmBrf,EAASod,IAK7DT,GAA4B,6BAOxBqC,IACArC,GAAwB,iEAI5BA,GAAwB,2BAQxBA,GAAY,6CAA+CoC,EAA0B,iLASrF,KAAK,GAAIhJ,KAAK/V,GAAQmd,QAAS,CAC3B,GAAIC,GAASpd,EAAQmd,QAAQpH,EACJ,aAArBqH,EAAO6B,aACPtC,GAAoB1b,KAAKoe,mBAAmBrf,EAASod,IAS7D,MAJAT,IAAgB,kBAQpB0C,mBAAoB,SAASrf,EAASod,GAGlC,GACIpR,IADsBhM,EAAQ8e,oBACpB9e,EAAQgM,SAClBsT,EAAelC,EAAO5N,MACtBvB,EAAamP,EAAOhB,GACC,aAArBgB,EAAO6B,aACPK,EAAeA,EAAa/M,cAIhC,IAAIoK,GAAY,MAMhB,IAJyB,YAArBS,EAAO6B,aACPtC,GAAgB,+CAAiD2C,EAAe,UAEpF3C,GAAoB,oCAChBS,EAAOmC,QAAS,CAChB5C,GAAoB,8CAAgD1O,EAAa,aAAejO,EAAQoM,IAAM,kBAE9G,KAAK2J,IAAK/V,GAAQmd,QAAS,CACvB,GAAIqC,GAAcxf,EAAQmd,QAAQpH,GAC9B7E,EAAelF,EAAQwT,EAAYpD,IACnClL,IACoB,OAAhBA,IACIsO,EAAYD,UACZrO,EAAeuO,KAAKC,UAAWxO,IAEnCyL,GAAY,4BAA8B6C,EAAYpD,IAAM,aAAeoD,EAAYpD,IAAM,YAAclL,EAAe,OAKtIyL,GAAwB,aAAe1O,EAAa,uBAGpD,IAAI0R,GAAgB3T,EAAQiC,EAC5B,IAAI0R,EAAe,CAEf,GAAIrb,GAAO/E,EAAO+E,KAAKqb,EAWvB,IARY,UAARrb,GACqB,OAAjBqb,IAEAhD,GAAgB1b,KAAKmP,eAAenC,EAAY0R,IAK5C,SAARrb,EACA,IAAK,GAAIyR,KAAK4J,GAAgB,CAE1B,GAAIhR,GAASgR,EAAc5J,GAGvB3V,EAASuf,CACbvf,GAASA,EAAO2a,MAAMhF,GAGtB4G,GAAgB1b,KAAKmP,eAAenC,EAAYU,IAM5DgO,GAAwB,SAGxB,IAAI1Z,GAAQ,EACZ,IAAyB,YAArBma,EAAO6B,WAA0B,CACjChc,EAAQma,EAAO5N,MAAM+C,aACrB,IAAIqN,GAAO3c,EAAMqC,MACbsa,GAAO,KACPA,EAAO,IAGXA,GAAc,EAIlBjD,GAAwB,sEACmD1O,EAAa,oBAAsBA,EAAa,8BAAgChL,EAAQ,WAAa2c,EAAO,6JAMpL,CAEHjD,GAAoB,aAAe1O,EAAa,uBAGhD,IAAI4R,IAAY,CAChB,KAAKC,WAAY9f,GAAQ+b,oBAAoB9N,GAAa,CAEtD,GAAI8R,GAAK/f,EAAQ+b,oBAAoB9N,GAAY6R,UAG7CE,EAAS,GACTC,EAAS,EACb,KAAK7D,MAAO2D,GACRC,EAAS5D,IACT6D,EAASF,EAAG3D,IAIZyD,KACAlD,GAAQ,OAEZkD,GAAY,CAGZ,IAAIlR,GAAS3C,EAAQiC,EAEjB0O,IADAhO,GAAUoR,EAAG9R,IAAeU,GAAUsR,EACtB,mCAAqChS,EAAa,2BAA6B6R,SAAW,UAE1F,mCAAqC7R,EAAa,sDACC+R,EAAS,iBAAmBC,EAAS,KAAOH,SAAW,cAIlInD,GAAoB,UAMxB,MAJAA,IAAoB,cAQxBvM,eAAgB,SAAS8P,EAAYhP,GAEjC,MADAA,GAAenP,EAAMoe,SAASjP,GACtB,iCAAmCA,EAC/B,6CAA+CgP,EAAa,iBAAmBhP,EAAe,2FAnlBlHjJ,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,MTwsF8BH,KAAKtC,EAASC,EAAoB,KAI1D+gB,GACA,SAASjhB,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GUhtFnC,SAAArC,EAAAF,GACAsC,GAASvC,EAAA,GAAeA,EAAA,KAAxBwC,EAA+C,SAAUE,EAAOG,GAEhE,GAAIV,GAAOU,EAAQgT,UAAU3U,QACzBiC,WAAY,SAAUxC,GAClBA,EAAQsE,KAAWtE,EAAQmB,SAAW,WACtCnB,EAAQ6T,SAA6B,YAAhB7T,EAAQsE,KAC7BpC,EAAQgT,UAAUE,UAAU5S,WAAWd,KAAMT,KAAMjB,IAIvD6U,UAAW,SAAW/D,GAElB,GADA5O,EAAQgT,UAAUE,UAAUP,UAAUnT,KAAMT,KAAM6P,GAC/B7L,SAAd6L,GAAyC,OAAdA,GAAsB7P,KAAKof,aAAe,CACtE,GAAIrc,GAAO/C,KACP8T,EAASvV,EAAE6F,QAASyL,GAAcA,GAAcA,EACpDxR,GAAEwG,KAAMiP,EAAQ,SAAU9I,GACtB,GAAIqU,GAAOtc,EAAKqc,aAAcpU,EAC9B3M,GAAEwG,KAAMwa,EAAM,SAAUC,GACpBvc,EAAKwc,UAAWD,GAAS,SAOzCC,UAAW,SAAWC,EAAWC,GAC7B,GAAI9W,GAAU3I,KAAKzB,EAAG,WAAaihB,GAC/BE,EAAY1f,KAAKzB,EAAG,aAAeihB,EACvC7W,GAAQsJ,KAAM,cAAewN,GACxBA,GACDC,EAAUta,OACVuD,EAAQzG,YAAa,kBAAmBC,SAAU,qBAElDud,EAAUpa,OACVqD,EAAQzG,YAAa,mBAAoBC,SAAU,oBAK3DqR,iBAAkB,WAKd,QAASmM,GAAQ1d,EAAKud,GAClB,GAAI7W,GAAU1G,EAAIiK,KAAM,WAAasT,EACrC7W,GAAQhD,GAAI,QAAS,WACjB5C,EAAKwc,UAAWC,GAAY7W,EAAQsJ,KAAM,kBAKlD,QAAS2N,GAAUC,EAAO9gB,EAASoN,GAC/BA,EAASA,KACT,KAAM2I,IAAK/V,GAAU,CACjB,GAAI+gB,GAAQ/gB,EAAS+V,GACjBiL,EAAcD,EAAM/gB,SAAW+gB,EAAM/gB,QAAQsF,OAAS,EACtD2b,EAAa7T,EAAO2N,MAAO,EAC/B/W,GAAKqc,aAAcU,EAAM9d,OAAUge,EAAWlG,MAAO,EACrD,IAAImG,GAAS1hB,EAAG,SAChB,IAAKwhB,EAAc,CACf,GAAIP,GAAY1e,EAAMoG,MAClByB,EAAUpK,EAAG,WAAY4D,SAAU,UAAYqd,GAAYrd,SAAU,yCACrEud,EAAYnhB,EAAG,UAAW4D,SAAU,YAAcqd,GAAYrd,SAAU,wBAC5E8d,GAAOhb,OAAQ1G,EAAG,UACG0G,OAAQ0D,GACR1D,OAAQlC,EAAK2Q,iBAAmBnF,MAAOuR,EAAMngB,KAAMqC,MAAO8d,EAAM9d,UACrFge,EAAWjP,KAAMyO,GACjBI,EAAUF,EAAWI,EAAM/gB,QAASihB,GACpCC,EAAOhb,OAAQya,GACfC,EAAQM,EAAQT,OAEhBS,GAAOhb,OAAQlC,EAAK2Q,iBAAmBnF,MAAOuR,EAAMngB,KAAMqC,MAAO8d,EAAM9d,QAE3E6d,GAAM5a,OAAQgb,IAlCtB,GAAIld,GAAO/C,IACXA,MAAKof,eAsCL,IAAIS,GAAQthB,EAAG,SAEf,OADAqhB,GAASC,EAAO7f,KAAKwB,MAAM1B,IAAK,SACzB+f,GAIXzM,UAAW,WACP,MAAO7U,GAAG,UAAW4D,SAAU,uCAAwC8B,KAAM,KAAMjE,KAAKwB,MAAM3B,MAItG,QACIU,KAAMA,IA3FVyG,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,MV4yF8BH,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,KAIlF8hB,GACA,SAAShiB,EAAQC,EAASC,GAE/B,GAAIuC,GAA8BC,GAA0D,SAASC,EAAUtC,GWpzFhHoC,GAASvC,EAAA,IAATwC,EAA0B,SAAUE,GAChC,GAAIP,GAAOM,EAASN,KAAKjB,QACrBiC,WAAa,SAAUxC,GACnB,GAAIgE,GAAO/C,IACXA,MAAKwB,MAAQzC,GAAWA,EAAQyC,OAAS,GAAIX,GAASY,OAClD5B,GAAWiB,EAAMoG,MACjBqO,IAAW,KACXG,IAAW,KACXyK,KAAW,KACXC,SAAW,EACX9P,MAAW,IACXtO,MAAW,KACXyG,SAAW,eACZ1G,IAAKhD,GAGRiB,KAAK0B,WAAY1B,KAAKoT,aACtBpT,KAAKiC,IAAIgC,KAAM,KAAMjE,KAAKwB,MAAM3B,IAChCG,KAAKyF,MAAUzF,KAAKzB,EAAG,wBACvByB,KAAKqgB,QAAUrgB,KAAKzB,EAAG,0BAGvB,IAAI+hB,KACJtgB,MAAKyF,MAAME,GAAI,SAAU,WACrB5C,EAAKf,MAAOzD,EAAGyB,MAAO4E,SACvBe,GAAI,QAAS,SAAUC,GACtB0a,EAAQ1a,EAAE2a,QAAS,IACpB5a,GAAI,UAAW,SAAWC,GACzB,GAAIoF,GAAIpF,EAAE2a,KACVD,GAAStV,IAAM,EACVjI,EAAKvB,MAAM1B,IAAK,gBAAmBwgB,EAAS,KAAa,IAALtV,GACrDjI,EAAKf,MAAO,KACZsS,MAAMjL,kBACS,GAAL2B,GAAe,GAALA,GAAe,IAALA,GAAgB,IAALA,GAAgB,IAALA,GAAaA,GAAK,IAAMA,GAAK,KAAOsV,EAAS,KAAYtV,GAAK,IAAMA,GAAK,MACjH,KAALA,GAAiB,KAALA,IAAczM,EAAGyB,MAAO4E,MAAM8K,QAAS,OAAS,GAAM3M,EAAKvB,MAAM1B,IAAK,aAC7E,KAALkL,GAAiB,KAALA,IAAczM,EAAGyB,MAAO4E,MAAM8K,QAAS,OAAS,GAChE3M,EAAKyd,aAAcjiB,EAAGyB,MAAO4E,QAC7B0b,EAAS,KAAQA,EAAS,KAC7BhM,MAAMjL,kBAKd,IAAIoX,GAAOzgB,KAAKwB,MAAMoG,UACtB5H,MAAK0gB,WAA0B,OAAbD,EAAK/K,KAA6B,OAAb+K,EAAKlL,KAAgBkL,EAAK/K,IAAM+K,EAAKlL,GAC5E,IAAI4K,GAAOM,EAAKN,IACVA,KAEEA,EADCM,EAAKL,SAAWpgB,KAAK0gB,YACbD,EAAK/K,IAAM+K,EAAKlL,KAAQkL,EAAKnQ,MAE/B,GAGVtQ,KAAK0gB,YACN1gB,KAAKyF,MAAMtD,SAAU,uBACrBnC,KAAKqgB,QAAQM,QAAUpL,IAAKkL,EAAKlL,IAAKG,IAAK+K,EAAK/K,IAAKyK,KAAMA,IAC9Cxa,GAAI,QAAS,SAAW2O,EAAOsM,GAAO7d,EAAKf,MAAO4e,EAAG5e,UAElEhC,KAAKqgB,QAAQ/a,OAIjBtF,KAAK2B,SAAU3B,KAAKwB,MAAO,SAAUxB,KAAK4B,OAAQ5B,MAClDA,KAAK4B,UAGTA,OAAQ,WACJ,GAAII,GAAQhC,KAAKwB,MAAM1B,IAAK,QAC5BE,MAAK0gB,YAAc1gB,KAAKqgB,QAAQM,OAAQ,QAAS3e,GACjDA,IAAUhC,KAAKyF,MAAMb,OAAS5E,KAAKyF,MAAMb,IAAK5C,IAIlDA,MAAQ,SAAW+B,GACf,GAAIhF,GAAUiB,KAAKwB,MAAMoG,UAYzB,OAXiB5D,UAAZD,IACgB,OAAZA,GAAgC,KAAZA,GAAmB/D,KAAKwgB,aAAczc,KAC3D8c,MAAO9c,KAAeA,EAAU,IAC/BhF,EAAQqhB,UAAarc,EAAUuR,KAAKwL,MAAO/c,IAC5B,OAAhBhF,EAAQ2W,MAAkB3R,EAAUuR,KAAKC,IAAKxR,EAAShF,EAAQ2W,MAC/C,OAAhB3W,EAAQwW,MAAkBxR,EAAUuR,KAAKI,IAAK3R,EAAShF,EAAQwW,OAEnEvV,KAAKwB,MAAMO,IAAK,QAASgC,GACzB/D,KAAKwB,MAAM+R,QAAS,UACpBxU,EAAQ0J,SAAU1E,IAEf/D,KAAKwB,MAAM1B,IAAK,UAI3B0gB,aAAc,SAAUxe,GACpB,MAAOhC,MAAKwB,MAAM1B,IAAK,gBAAyD,MAAtCqZ,OAAQnX,GAAQ2N,UAAW,EAAG,IAI5EyD,UAAW,WACP,MAAQ,4HAOhB,QACI7S,KAAOA,IAxGfyG,MAAA7I,EAAAwC,KAAAqD,SAAApD,IAAA1C,EAAAC,QAAAyC,MXy5F8BH,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,KAIlF2iB,GACA,SAAS7iB,EAAQC,EAASC,IY95FhC,SAAAyC,GAAA,GAAIvC,GAASF,EAAS,GAClBG,EAAID,EACJ0iB,EAAe5iB,EAAS,IACxB6iB,EAAK7iB,EAAS,GAEdO,EAASkC,EAASlC,OAAOW,QAGzBiC,WAAa,SAAUtB,EAAMlB,GACzBiB,KAAKC,KAAOA,EACZD,KAAKjB,QAAUA,GAInBgS,KAAM,SAAU5F,EAAK8G,GACjBA,EAAOA,MACPA,EAAKiP,YAAc5L,KAAK6L,SAAS9K,SAAU,IAAK+K,OAAQ,GAClD7iB,EAAE8iB,cAAepP,KACnB9G,GAAOA,EAAIuE,QAAS,OAAS,EAAK,IAAM,IACxCvE,GAAO5M,EAAE6M,MAAO6G,GAAO,IAE3BjS,KAAKshB,SAAUnW,GAAOoI,SAAW,KAIrC1F,QAAS,SAAUgM,EAAUna,EAAMC,GAC/BV,OAAOC,MAAO,kBAAmB2a,EAAUna,EAAMC,EACjD,IAAI4hB,GAAWP,EAAaQ,MAAO9hB,EAAK+hB,MACxC/hB,GAAKqR,KAAMwQ,GACP1H,IACK7Z,KAAKP,aAAcC,EAAMC,GAC1Bka,EAAS7S,MAAOhH,KAAMN,GAEtBM,KAAK0hB,kBAKjBjiB,aAAc,SAAUC,EAAMC,GAC1B,OAAO,GAGX+hB,cAAe,WACX1hB,KAAKC,KAAKC,QAAS,GAAI+gB,GAAG5e,SAAWE,OAAQ,SAAUD,QAAS,sEAAuEG,YAAY,OAI3JvE,GAAOC,QAAUQ,IZi6Fa8B,KAAKtC,EAASC,EAAoB,KAI1DujB,GACA,SAASzjB,EAAQC,EAASC,Iar9FhC,SAAAyC,EAAAtC,EAAAF,GAAA,GAAIujB,GAAKxjB,EAAS,GAEdK,EAAaoC,EAASN,KAAKjB,QAC3BiC,WAAY,SAAUtB,EAAMlB,GACxB,GAAIgE,GAAO/C,IACXA,MAAKC,KAAaA,EAClBD,KAAKI,KAAarB,EAAQqB,KAC1BJ,KAAKZ,OAAaL,EAAQK,OAC1BY,KAAKqO,SAAatP,EAAQsP,SAC1BrO,KAAKsC,QAAavD,EAAQuD,QAC1BtC,KAAKuC,OAAaxD,EAAQwD,OAC1BvC,KAAKwB,MAAQ,GAAIX,GAASY,OACtBI,MAAU+f,EAAI,oBAElB5hB,KAAK6hB,WAAa,GAAIhhB,GAASoI,aAC3BpH,MAAQ,SACRgJ,QACIhJ,MAAU,sBACVsJ,IAAU,kCAEVtJ,MAAU,uBACVsJ,IAAU,gCAEVtJ,MAAU,uBACVsJ,IAAU,+BAEVtJ,MAAU,cACVsJ,IAAU,iBAGdtJ,MAAQ,sBACRgJ,QACIhJ,MAAU,mBACVsJ,IAAU,mCACV2W,QAAU/e,EAAKsL,SAAS0T,yBAExBlgB,MAAU,0BACVsJ,IAAU,kCACV2W,QAAU/e,EAAKsL,SAAS0T,wBAA0Bhf,EAAK3D,OAAO4iB,6BAE9DngB,MAAU,kCACVsJ,IAAU,4EAA8EpI,EAAKsL,SAAS4T,0BACtGH,QAAU/e,EAAKsL,SAAS4T,4BAExBpgB,MAAU,yBACVsJ,IAAU,qCACV2W,QAAU/e,EAAKsL,SAAS6T,oBAExBrgB,MAAU,iBACVsJ,IAAU,mEACV2W,QAAU/e,EAAKsL,SAAS6T,oBAExBrgB,MAAU,sBACVsJ,IAAU,uBAEVtJ,MAAU,eACVsJ,IAAU,wBAEVtJ,MAAU,gCACVsJ,IAAU,sBAEVtJ,MAAU,+BACVsJ,IAAU,uCAEVtJ,MAAU,uBACVsJ,IAAU,sBAEVtJ,MAAU,2BACVsJ,IAAU,6BAEVtJ,MAAU,2BACVsJ,IAAU,qCAGdtJ,MAAQ,kBACRgJ,QACIhJ,MAAU,QACVsJ,IAAU,cACVpF,OAAU,QAEVlE,MAAU,SACVsJ,IAAU,iBAEVtJ,MAAU,QACVsJ,IAAU,gBAEVtJ,MAAU,WACVsJ,IAAU,wBAEVtJ,MAAU,qBACVsJ,IAAU,oBACV2W,QAAU/e,EAAK3D,OAAO+iB,6BAG1BtgB,MAAQ,OACRgJ,QACIhJ,MAAU,SACVsJ,IAAU,eACV2W,QAAU/e,EAAK3D,OAAOgjB,gBAEtBvgB,MAAU,iBACVsJ,IAAU,mCAEVtJ,MAAU,QACVsJ,IAAU,gBAEVtJ,MAAU,aACVsJ,IAAU,mBAGdtJ,MAAQ,mBACRgJ,QACIhJ,MAAU,mBACVsJ,IAAU,oCAGdtJ,MAAQ,kBACRgJ,QACIhJ,MAAU,mCACVsJ,IAAU,8CAEVtJ,MAAU,gBACVsJ,IAAU,sCAEVtJ,MAAU,sBACVsJ,IAAU,mCAEVtJ,MAAU,eACVsJ,IAAU,4DAGlBnL,KAAK0B,WAAY1B,KAAKoT,cAG1BxR,OAAS,WACL,GAAImB,GAAO/C,IACXA,MAAKiC,IAAIiO,QACTlQ,KAAK6hB,WAAWhd,KAAM,SAAUwd,GAC5B,GAAIC,GAAW/jB,EAAGwE,EAAKwf,iBAAkBF,EAASza,aAC9C4a,EAAWF,EAASpW,KAAM,wBAC9B7N,GAAEwG,KAAMwd,EAASviB,IAAK,SAAW,SAAUiO,IACjB/J,SAAjB+J,EAAK+T,SAAyB/T,EAAK+T,UACpCU,EAASvd,OAAQ1G,EAAG,UAAW4D,SAAU,8BACV8C,OAAQ1G,EAAG,QAAS0F,MACPsE,KAAUxF,EAAK3C,KAAO2N,EAAK5C,IAC3BpF,OAAUgI,EAAKhI,QAAU,gBAAiBV,KAAMuc,EAAI7T,EAAKlM,YAG7GkB,EAAKd,IAAIgD,OAAQqd,KAErBtiB,KAAKC,KAAK1B,EAAG,gBAAiB2J,KAAM,MAAOlI,KAAKI,KAAO,wBAA0BJ,KAAKsC,QAAU,WAAatC,KAAKuC,SAGtHggB,iBAAmB,SAAUxjB,GACzB,OACI,QACI,sCAAwC6iB,EAAI7iB,EAAQ8C,OAAU,SAC9D,sCACJ,UACFmT,KAAK,KAGX5B,UAAY,WACR,MAAO,gCAGXiD,SAAW,WAAa,MAAO,eAGnCnY,GAAOC,QAAUM,Ibo9FagC,KAAKtC,EAASC,EAAoB,GAAIA,EAAoB,GAAIA,EAAoB","file":"admin.bundled.js","sourcesContent":["webpackJsonp([4],{\n\n/***/ 0:\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(_) {var jQuery = __webpack_require__(1),\n\t $ = jQuery,\n\t GalaxyApp = __webpack_require__(40).GalaxyApp,\n\t AdminPanel = __webpack_require__(99),\n\t GridView = __webpack_require__(11),\n\t Ui = __webpack_require__(7),\n\t Router = __webpack_require__(43),\n\t Page = __webpack_require__(41);\n\t\n\twindow.app = function app(options, bootstrapped) {\n\t window.Galaxy = new GalaxyApp(options, bootstrapped);\n\t Galaxy.debug('admin app');\n\t Galaxy.params = Galaxy.config.params;\n\t\n\t /** Routes */\n\t var AdminRouter = Router.extend({\n\t routes: {\n\t '(/)admin(/)users': 'show_users'\n\t },\n\t\n\t authenticate: function (args, name) {\n\t return Galaxy.user && Galaxy.user.id && Galaxy.user.get('is_admin');\n\t },\n\t\n\t show_users: function () {\n\t this.page.display(new GridView({ url_base: Galaxy.root + 'admin/users_list', dict_format: true }));\n\t }\n\t });\n\t\n\t $(function () {\n\t _.extend(options.config, { active_view: 'admin' });\n\t Galaxy.page = new Page.View(_.extend(options, {\n\t Left: AdminPanel,\n\t Router: AdminRouter\n\t }));\n\t });\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2)))\n\n/***/ },\n\n/***/ 7:\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, $, _) {/**\n\t * This class contains backbone wrappers for basic ui elements such as Images, Labels, Buttons, Input fields etc.\n\t */\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(4), __webpack_require__(16), __webpack_require__(29), __webpack_require__(12), __webpack_require__(27), __webpack_require__(9), __webpack_require__(8)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Utils, Select, Slider, Options, Drilldown, Buttons, Modal) {\n\t\n\t /** Label wrapper */\n\t var Label = Backbone.View.extend({\n\t tagName: 'label',\n\t initialize: function (options) {\n\t this.model = options && options.model || new Backbone.Model(options);\n\t this.tagName = options.tagName || this.tagName;\n\t this.setElement($('<' + this.tagName + '/>'));\n\t this.listenTo(this.model, 'change', this.render, this);\n\t this.render();\n\t },\n\t title: function (new_title) {\n\t this.model.set('title', new_title);\n\t },\n\t value: function () {\n\t return this.model.get('title');\n\t },\n\t render: function () {\n\t this.$el.removeClass().addClass('ui-label').addClass(this.model.get('cls')).html(this.model.get('title'));\n\t return this;\n\t }\n\t });\n\t\n\t /** Displays messages used e.g. in the tool form */\n\t var Message = Backbone.View.extend({\n\t initialize: function (options) {\n\t this.model = options && options.model || new Backbone.Model({\n\t message: null,\n\t status: 'info',\n\t cls: '',\n\t persistent: false,\n\t fade: true\n\t }).set(options);\n\t this.listenTo(this.model, 'change', this.render, this);\n\t this.render();\n\t },\n\t update: function (options) {\n\t this.model.set(options);\n\t },\n\t render: function () {\n\t this.$el.removeClass().addClass('ui-message').addClass(this.model.get('cls'));\n\t var status = this.model.get('status');\n\t if (this.model.get('large')) {\n\t this.$el.addClass((status == 'success' && 'done' || status == 'danger' && 'error' || status) + 'messagelarge');\n\t } else {\n\t this.$el.addClass('alert').addClass('alert-' + status);\n\t }\n\t if (this.model.get('message')) {\n\t this.$el.html(this.messageForDisplay());\n\t this.$el[this.model.get('fade') ? 'fadeIn' : 'show']();\n\t this.timeout && window.clearTimeout(this.timeout);\n\t if (!this.model.get('persistent')) {\n\t var self = this;\n\t this.timeout = window.setTimeout(function () {\n\t self.model.set('message', '');\n\t }, 3000);\n\t }\n\t } else {\n\t this.$el.fadeOut();\n\t }\n\t return this;\n\t },\n\t messageForDisplay: function () {\n\t return _.escape(this.model.get('message'));\n\t }\n\t });\n\t\n\t var UnescapedMessage = Message.extend({\n\t messageForDisplay: function () {\n\t return this.model.get('message');\n\t }\n\t });\n\t\n\t /** Renders an input element used e.g. in the tool form */\n\t var Input = Backbone.View.extend({\n\t initialize: function (options) {\n\t this.model = options && options.model || new Backbone.Model({\n\t type: 'text',\n\t placeholder: '',\n\t disabled: false,\n\t readonly: false,\n\t visible: true,\n\t cls: '',\n\t area: false,\n\t color: null,\n\t style: null\n\t }).set(options);\n\t this.tagName = this.model.get('area') ? 'textarea' : 'input';\n\t this.setElement($('<' + this.tagName + '/>'));\n\t this.listenTo(this.model, 'change', this.render, this);\n\t this.render();\n\t },\n\t events: {\n\t 'input': '_onchange'\n\t },\n\t value: function (new_val) {\n\t new_val !== undefined && this.model.set('value', typeof new_val === 'string' ? new_val : '');\n\t return this.model.get('value');\n\t },\n\t render: function () {\n\t var self = this;\n\t this.$el.removeClass().addClass('ui-' + this.tagName).addClass(this.model.get('cls')).addClass(this.model.get('style')).attr('id', this.model.id).attr('type', this.model.get('type')).attr('placeholder', this.model.get('placeholder')).css('color', this.model.get('color') || '').css('border-color', this.model.get('color') || '');\n\t var datalist = this.model.get('datalist');\n\t if ($.isArray(datalist) && datalist.length > 0) {\n\t this.$el.autocomplete({ source: function (request, response) {\n\t response(self.model.get('datalist'));\n\t },\n\t change: function () {\n\t self._onchange();\n\t } });\n\t }\n\t if (this.model.get('value') !== this.$el.val()) {\n\t this.$el.val(this.model.get('value'));\n\t }\n\t _.each(['readonly', 'disabled'], function (attr_name) {\n\t self.model.get(attr_name) ? self.$el.attr(attr_name, true) : self.$el.removeAttr(attr_name);\n\t });\n\t this.$el[this.model.get('visible') ? 'show' : 'hide']();\n\t return this;\n\t },\n\t _onchange: function () {\n\t this.value(this.$el.val());\n\t this.model.get('onchange') && this.model.get('onchange')(this.model.get('value'));\n\t }\n\t });\n\t\n\t /** Creates a hidden element input field used e.g. in the tool form */\n\t var Hidden = Backbone.View.extend({\n\t initialize: function (options) {\n\t this.model = options && options.model || new Backbone.Model(options);\n\t this.setElement($('
').append(this.$info = $('
')).append(this.$hidden = $('
')));\n\t this.listenTo(this.model, 'change', this.render, this);\n\t this.render();\n\t },\n\t value: function (new_val) {\n\t new_val !== undefined && this.model.set('value', new_val);\n\t return this.model.get('value');\n\t },\n\t render: function () {\n\t this.$el.attr('id', this.model.id);\n\t this.$hidden.val(this.model.get('value'));\n\t this.model.get('info') ? this.$info.show().text(this.model.get('info')) : this.$info.hide();\n\t return this;\n\t }\n\t });\n\t\n\t /** Creates a upload element input field */\n\t var Upload = Backbone.View.extend({\n\t initialize: function (options) {\n\t var self = this;\n\t this.model = options && options.model || new Backbone.Model(options);\n\t this.setElement($('
').append(this.$info = $('
')).append(this.$file = $('').attr('type', 'file').addClass('ui-margin-bottom')).append(this.$text = $('', '
', '
'].join('');\n\t }\n\t });\n\t\n\t //==============================================================================\n\t return {\n\t CitationView: CitationView,\n\t CitationListView: CitationListView\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))\n\n/***/ },\n/* 46 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(_, $, jQuery) {!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(58), __webpack_require__(49), __webpack_require__(6), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (LIST_ITEM, DATASET_LI, BASE_MVC, _l) {\n\t\n\t 'use strict';\n\t //==============================================================================\n\t\n\t var FoldoutListItemView = LIST_ITEM.FoldoutListItemView,\n\t ListItemView = LIST_ITEM.ListItemView;\n\t /** @class Read only view for DatasetCollection.\n\t */\n\t var DCListItemView = FoldoutListItemView.extend(\n\t /** @lends DCListItemView.prototype */{\n\t\n\t className: FoldoutListItemView.prototype.className + \" dataset-collection\",\n\t id: function () {\n\t return ['dataset_collection', this.model.get('id')].join('-');\n\t },\n\t\n\t /** override to add linkTarget */\n\t initialize: function (attributes) {\n\t this.linkTarget = attributes.linkTarget || '_blank';\n\t this.hasUser = attributes.hasUser;\n\t FoldoutListItemView.prototype.initialize.call(this, attributes);\n\t },\n\t\n\t /** event listeners */\n\t _setUpListeners: function () {\n\t FoldoutListItemView.prototype._setUpListeners.call(this);\n\t this.listenTo(this.model, 'change', function (model, options) {\n\t // if the model has changed deletion status render it entirely\n\t if (_.has(model.changed, 'deleted')) {\n\t this.render();\n\t\n\t // if the model has been decorated after the fact with the element count,\n\t // render the subtitle where the count is displayed\n\t } else if (_.has(model.changed, 'element_count')) {\n\t this.$('> .title-bar .subtitle').replaceWith(this._renderSubtitle());\n\t }\n\t });\n\t },\n\t\n\t // ......................................................................... rendering\n\t /** render a subtitle to show the user what sort of collection this is */\n\t _renderSubtitle: function () {\n\t return $(this.templates.subtitle(this.model.toJSON(), this));\n\t },\n\t\n\t // ......................................................................... foldout\n\t /** override to add linktarget to sub-panel */\n\t _getFoldoutPanelOptions: function () {\n\t var options = FoldoutListItemView.prototype._getFoldoutPanelOptions.call(this);\n\t return _.extend(options, {\n\t linkTarget: this.linkTarget,\n\t hasUser: this.hasUser\n\t });\n\t },\n\t\n\t /** override to not catch sub-panel selectors */\n\t $selector: function () {\n\t return this.$('> .selector');\n\t },\n\t\n\t // ......................................................................... misc\n\t /** String representation */\n\t toString: function () {\n\t var modelString = this.model ? this.model + '' : '(no model)';\n\t return 'DCListItemView(' + modelString + ')';\n\t }\n\t });\n\t\n\t // ............................................................................ TEMPLATES\n\t /** underscore templates */\n\t DCListItemView.prototype.templates = function () {\n\t\n\t var warnings = _.extend({}, FoldoutListItemView.prototype.templates.warnings, {\n\t error: BASE_MVC.wrapTemplate([\n\t // error during index fetch - show error on dataset\n\t '<% if( model.error ){ %>', '
', _l('There was an error getting the data for this collection'), ': <%- model.error %>', '
', '<% } %>']),\n\t purged: BASE_MVC.wrapTemplate(['<% if( model.purged ){ %>', '
', _l('This collection has been deleted and removed from disk'), '
', '<% } %>']),\n\t deleted: BASE_MVC.wrapTemplate([\n\t // deleted not purged\n\t '<% if( model.deleted && !model.purged ){ %>', '
', _l('This collection has been deleted'), '
', '<% } %>'])\n\t });\n\t\n\t // use element identifier\n\t var titleBarTemplate = BASE_MVC.wrapTemplate(['
', '
', '<%- collection.element_identifier || collection.name %>', '
', '
', '
'], 'collection');\n\t\n\t // use element identifier\n\t var subtitleTemplate = BASE_MVC.wrapTemplate(['
', '<% var countText = collection.element_count? ( collection.element_count + \" \" ) : \"\"; %>', '<% if( collection.collection_type === \"list\" ){ %>', _l('a list of <%- countText %>datasets'), '<% } else if( collection.collection_type === \"paired\" ){ %>', _l('a pair of datasets'), '<% } else if( collection.collection_type === \"list:paired\" ){ %>', _l('a list of <%- countText %>dataset pairs'), '<% } else if( collection.collection_type === \"list:list\" ){ %>', _l('a list of <%- countText %>dataset lists'), '<% } %>', '
'], 'collection');\n\t\n\t return _.extend({}, FoldoutListItemView.prototype.templates, {\n\t warnings: warnings,\n\t titleBar: titleBarTemplate,\n\t subtitle: subtitleTemplate\n\t });\n\t }();\n\t\n\t //==============================================================================\n\t /** @class Read only view for DatasetCollectionElement.\n\t */\n\t var DCEListItemView = ListItemView.extend(\n\t /** @lends DCEListItemView.prototype */{\n\t\n\t /** add the DCE class to the list item */\n\t className: ListItemView.prototype.className + \" dataset-collection-element\",\n\t\n\t /** set up */\n\t initialize: function (attributes) {\n\t if (attributes.logger) {\n\t this.logger = this.model.logger = attributes.logger;\n\t }\n\t this.log('DCEListItemView.initialize:', attributes);\n\t ListItemView.prototype.initialize.call(this, attributes);\n\t },\n\t\n\t // ......................................................................... misc\n\t /** String representation */\n\t toString: function () {\n\t var modelString = this.model ? this.model + '' : '(no model)';\n\t return 'DCEListItemView(' + modelString + ')';\n\t }\n\t });\n\t\n\t // ............................................................................ TEMPLATES\n\t /** underscore templates */\n\t DCEListItemView.prototype.templates = function () {\n\t\n\t // use the element identifier here - since that will persist and the user will need it\n\t var titleBarTemplate = BASE_MVC.wrapTemplate(['
', '
', '<%- element.element_identifier %>', '
', '
', '
'], 'element');\n\t\n\t return _.extend({}, ListItemView.prototype.templates, {\n\t titleBar: titleBarTemplate\n\t });\n\t }();\n\t\n\t //==============================================================================\n\t /** @class Read only view for a DatasetCollectionElement that is also an DatasetAssociation\n\t * (a dataset contained in a dataset collection).\n\t */\n\t var DatasetDCEListItemView = DATASET_LI.DatasetListItemView.extend(\n\t /** @lends DatasetDCEListItemView.prototype */{\n\t\n\t className: DATASET_LI.DatasetListItemView.prototype.className + \" dataset-collection-element\",\n\t\n\t /** set up */\n\t initialize: function (attributes) {\n\t if (attributes.logger) {\n\t this.logger = this.model.logger = attributes.logger;\n\t }\n\t this.log('DatasetDCEListItemView.initialize:', attributes);\n\t DATASET_LI.DatasetListItemView.prototype.initialize.call(this, attributes);\n\t },\n\t\n\t /** In this override, only get details if in the ready state.\n\t * Note: fetch with no 'change' event triggering to prevent automatic rendering.\n\t */\n\t _fetchModelDetails: function () {\n\t var view = this;\n\t if (view.model.inReadyState() && !view.model.hasDetails()) {\n\t return view.model.fetch({ silent: true });\n\t }\n\t return jQuery.when();\n\t },\n\t\n\t // ......................................................................... misc\n\t /** String representation */\n\t toString: function () {\n\t var modelString = this.model ? this.model + '' : '(no model)';\n\t return 'DatasetDCEListItemView(' + modelString + ')';\n\t }\n\t });\n\t\n\t // ............................................................................ TEMPLATES\n\t /** underscore templates */\n\t DatasetDCEListItemView.prototype.templates = function () {\n\t\n\t // use the element identifier here and not the dataset name\n\t //TODO:?? can we steal the DCE titlebar?\n\t var titleBarTemplate = BASE_MVC.wrapTemplate(['
', '', '
', '<%- element.element_identifier %>', '
', '
'], 'element');\n\t\n\t return _.extend({}, DATASET_LI.DatasetListItemView.prototype.templates, {\n\t titleBar: titleBarTemplate\n\t });\n\t }();\n\t\n\t //==============================================================================\n\t /** @class Read only view for a DatasetCollectionElement that is also a DatasetCollection\n\t * (a nested DC).\n\t */\n\t var NestedDCDCEListItemView = DCListItemView.extend(\n\t /** @lends NestedDCDCEListItemView.prototype */{\n\t\n\t className: DCListItemView.prototype.className + \" dataset-collection-element\",\n\t\n\t /** In this override, add the state as a class for use with state-based CSS */\n\t _swapNewRender: function ($newRender) {\n\t DCListItemView.prototype._swapNewRender.call(this, $newRender);\n\t var state = this.model.get('state') || 'ok';\n\t this.$el.addClass('state-' + state);\n\t return this.$el;\n\t },\n\t\n\t // ......................................................................... misc\n\t /** String representation */\n\t toString: function () {\n\t var modelString = this.model ? this.model + '' : '(no model)';\n\t return 'NestedDCDCEListItemView(' + modelString + ')';\n\t }\n\t });\n\t\n\t //==============================================================================\n\t return {\n\t DCListItemView: DCListItemView,\n\t DCEListItemView: DCEListItemView,\n\t DatasetDCEListItemView: DatasetDCEListItemView,\n\t NestedDCDCEListItemView: NestedDCDCEListItemView\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2), __webpack_require__(1), __webpack_require__(1)))\n\n/***/ },\n/* 47 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(_, Backbone, jQuery) {!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(82), __webpack_require__(6), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (DATASET_MODEL, BASE_MVC, _l) {\n\t 'use strict';\n\t\n\t //==============================================================================\n\t /*\n\t Notes:\n\t \n\t Terminology:\n\t DatasetCollection/DC : a container of datasets or nested DatasetCollections\n\t Element/DatasetCollectionElement/DCE : an item contained in a DatasetCollection\n\t HistoryDatasetCollectionAssociation/HDCA: a DatasetCollection contained in a history\n\t \n\t \n\t This all seems too complex unfortunately:\n\t \n\t - Terminology collision between DatasetCollections (DCs) and Backbone Collections.\n\t - In the DatasetCollections API JSON, DC Elements use a 'Has A' stucture to *contain*\n\t either a dataset or a nested DC. This would make the hierarchy much taller. I've\n\t decided to merge the contained JSON with the DC element json - making the 'has a'\n\t relation into an 'is a' relation. This seems simpler to me and allowed a lot of\n\t DRY in both models and views, but may make tracking or tracing within these models\n\t more difficult (since DatasetCollectionElements are now *also* DatasetAssociations\n\t or DatasetCollections (nested)). This also violates the rule of thumb about\n\t favoring aggregation over inheritance.\n\t - Currently, there are three DatasetCollection subclasses: List, Pair, and ListPaired.\n\t These each should a) be usable on their own, b) be usable in the context of\n\t nesting within a collection model (at least in the case of ListPaired), and\n\t c) be usable within the context of other container models (like History or\n\t LibraryFolder, etc.). I've tried to separate/extract classes in order to\n\t handle those three situations, but it's proven difficult to do in a simple,\n\t readable manner.\n\t - Ideally, histories and libraries would inherit from the same server models as\n\t dataset collections do since they are (in essence) dataset collections themselves -\n\t making the whole nested structure simpler. This would be a large, error-prone\n\t refactoring and migration.\n\t \n\t Many of the classes and heirarchy are meant as extension points so, while the\n\t relations and flow may be difficult to understand initially, they'll allow us to\n\t handle the growth or flux dataset collection in the future (w/o actually implementing\n\t any YAGNI).\n\t \n\t */\n\t //_________________________________________________________________________________________________ ELEMENTS\n\t /** @class mixin for Dataset collection elements.\n\t * When collection elements are passed from the API, the underlying element is\n\t * in a sub-object 'object' (IOW, a DCE representing an HDA will have HDA json in element.object).\n\t * This mixin uses the constructor and parse methods to merge that JSON with the DCE attribtues\n\t * effectively changing a DCE from a container to a subclass (has a --> is a).\n\t */\n\t\n\t var DatasetCollectionElementMixin = {\n\t\n\t /** default attributes used by elements in a dataset collection */\n\t defaults: {\n\t model_class: 'DatasetCollectionElement',\n\t element_identifier: null,\n\t element_index: null,\n\t element_type: null\n\t },\n\t\n\t /** merge the attributes of the sub-object 'object' into this model */\n\t _mergeObject: function (attributes) {\n\t // if we don't preserve and correct ids here, the element id becomes the object id\n\t // and collision in backbone's _byId will occur and only\n\t _.extend(attributes, attributes.object, { element_id: attributes.id });\n\t delete attributes.object;\n\t return attributes;\n\t },\n\t\n\t /** override to merge this.object into this */\n\t constructor: function (attributes, options) {\n\t // console.debug( '\\t DatasetCollectionElement.constructor:', attributes, options );\n\t attributes = this._mergeObject(attributes);\n\t this.idAttribute = 'element_id';\n\t Backbone.Model.apply(this, arguments);\n\t },\n\t\n\t /** when the model is fetched, merge this.object into this */\n\t parse: function (response, options) {\n\t var attributes = response;\n\t attributes = this._mergeObject(attributes);\n\t return attributes;\n\t }\n\t };\n\t\n\t /** @class Concrete class of Generic DatasetCollectionElement */\n\t var DatasetCollectionElement = Backbone.Model.extend(BASE_MVC.LoggableMixin).extend(DatasetCollectionElementMixin).extend({ _logNamespace: 'collections' });\n\t\n\t //==============================================================================\n\t /** @class Base/Abstract Backbone collection for Generic DCEs. */\n\t var DCECollection = Backbone.Collection.extend(BASE_MVC.LoggableMixin).extend(\n\t /** @lends DCECollection.prototype */{\n\t _logNamespace: 'collections',\n\t\n\t model: DatasetCollectionElement,\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return ['DatasetCollectionElementCollection(', this.length, ')'].join('');\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** @class Backbone model for a dataset collection element that is a dataset (HDA).\n\t */\n\t var DatasetDCE = DATASET_MODEL.DatasetAssociation.extend(BASE_MVC.mixin(DatasetCollectionElementMixin,\n\t /** @lends DatasetDCE.prototype */{\n\t\n\t /** url fn */\n\t url: function () {\n\t // won't always be an hda\n\t if (!this.has('history_id')) {\n\t console.warn('no endpoint for non-hdas within a collection yet');\n\t // (a little silly since this api endpoint *also* points at hdas)\n\t return Galaxy.root + 'api/datasets';\n\t }\n\t return Galaxy.root + 'api/histories/' + this.get('history_id') + '/contents/' + this.get('id');\n\t },\n\t\n\t defaults: _.extend({}, DATASET_MODEL.DatasetAssociation.prototype.defaults, DatasetCollectionElementMixin.defaults),\n\t\n\t _downloadQueryParameters: function () {\n\t return '?to_ext=' + this.get('file_ext') + '&hdca_id=' + this.get('parent_hdca_id') + '&element_identifier=' + this.get('element_identifier');\n\t },\n\t\n\t // because all objects have constructors (as this hashmap would even if this next line wasn't present)\n\t // the constructor in hcontentMixin won't be attached by BASE_MVC.mixin to this model\n\t // - re-apply manually for now\n\t /** call the mixin constructor */\n\t constructor: function (attributes, options) {\n\t this.debug('\\t DatasetDCE.constructor:', attributes, options);\n\t //DATASET_MODEL.DatasetAssociation.prototype.constructor.call( this, attributes, options );\n\t DatasetCollectionElementMixin.constructor.call(this, attributes, options);\n\t },\n\t\n\t /** Does this model already contain detailed data (as opposed to just summary level data)? */\n\t hasDetails: function () {\n\t return this.elements && this.elements.length;\n\t },\n\t\n\t /** String representation. */\n\t toString: function () {\n\t var objStr = this.get('element_identifier');\n\t return ['DatasetDCE(', objStr, ')'].join('');\n\t }\n\t }));\n\t\n\t //==============================================================================\n\t /** @class DCECollection of DatasetDCE's (a list of datasets, a pair of datasets).\n\t */\n\t var DatasetDCECollection = DCECollection.extend(\n\t /** @lends DatasetDCECollection.prototype */{\n\t model: DatasetDCE,\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return ['DatasetDCECollection(', this.length, ')'].join('');\n\t }\n\t });\n\t\n\t //_________________________________________________________________________________________________ COLLECTIONS\n\t /** @class Backbone model for Dataset Collections.\n\t * The DC API returns an array of JSON objects under the attribute elements.\n\t * This model:\n\t * - removes that array/attribute ('elements') from the model,\n\t * - creates a bbone collection (of the class defined in the 'collectionClass' attribute),\n\t * - passes that json onto the bbone collection\n\t * - caches the bbone collection in this.elements\n\t */\n\t var DatasetCollection = Backbone.Model.extend(BASE_MVC.LoggableMixin).extend(BASE_MVC.SearchableModelMixin).extend( /** @lends DatasetCollection.prototype */{\n\t _logNamespace: 'collections',\n\t\n\t /** default attributes for a model */\n\t defaults: {\n\t /* 'list', 'paired', or 'list:paired' */\n\t collection_type: null,\n\t //??\n\t deleted: false\n\t },\n\t\n\t /** Which class to use for elements */\n\t collectionClass: DCECollection,\n\t\n\t /** set up: create elements instance var and (on changes to elements) update them */\n\t initialize: function (model, options) {\n\t this.debug(this + '(DatasetCollection).initialize:', model, options, this);\n\t this.elements = this._createElementsModel();\n\t this.on('change:elements', function () {\n\t this.log('change:elements');\n\t //TODO: prob. better to update the collection instead of re-creating it\n\t this.elements = this._createElementsModel();\n\t });\n\t },\n\t\n\t /** move elements model attribute to full collection */\n\t _createElementsModel: function () {\n\t this.debug(this + '._createElementsModel', this.collectionClass, this.get('elements'), this.elements);\n\t //TODO: same patterns as DatasetCollectionElement _createObjectModel - refactor to BASE_MVC.hasSubModel?\n\t var elements = this.get('elements') || [];\n\t this.unset('elements', { silent: true });\n\t var self = this;\n\t _.each(elements, function (element, index) {\n\t _.extend(element, { \"parent_hdca_id\": self.get(\"id\") });\n\t });\n\t this.elements = new this.collectionClass(elements);\n\t //this.debug( 'collectionClass:', this.collectionClass + '', this.elements );\n\t return this.elements;\n\t },\n\t\n\t // ........................................................................ common queries\n\t /** pass the elements back within the model json when this is serialized */\n\t toJSON: function () {\n\t var json = Backbone.Model.prototype.toJSON.call(this);\n\t if (this.elements) {\n\t json.elements = this.elements.toJSON();\n\t }\n\t return json;\n\t },\n\t\n\t /** Is this collection in a 'ready' state no processing (for the collection) is left\n\t * to do on the server.\n\t */\n\t inReadyState: function () {\n\t var populated = this.get('populated');\n\t return this.isDeletedOrPurged() || populated;\n\t },\n\t\n\t //TODO:?? the following are the same interface as DatasetAssociation - can we combine?\n\t /** Does the DC contain any elements yet? Is a fetch() required? */\n\t hasDetails: function () {\n\t return this.elements.length !== 0;\n\t },\n\t\n\t /** Given the filters, what models in this.elements would be returned? */\n\t getVisibleContents: function (filters) {\n\t // filters unused for now\n\t return this.elements;\n\t },\n\t\n\t // ........................................................................ ajax\n\t /** override to use actual Dates objects for create/update times */\n\t parse: function (response, options) {\n\t var parsed = Backbone.Model.prototype.parse.call(this, response, options);\n\t if (parsed.create_time) {\n\t parsed.create_time = new Date(parsed.create_time);\n\t }\n\t if (parsed.update_time) {\n\t parsed.update_time = new Date(parsed.update_time);\n\t }\n\t return parsed;\n\t },\n\t\n\t /** save this dataset, _Mark_ing it as deleted (just a flag) */\n\t 'delete': function (options) {\n\t if (this.get('deleted')) {\n\t return jQuery.when();\n\t }\n\t return this.save({ deleted: true }, options);\n\t },\n\t /** save this dataset, _Mark_ing it as undeleted */\n\t undelete: function (options) {\n\t if (!this.get('deleted') || this.get('purged')) {\n\t return jQuery.when();\n\t }\n\t return this.save({ deleted: false }, options);\n\t },\n\t\n\t /** Is this collection deleted or purged? */\n\t isDeletedOrPurged: function () {\n\t return this.get('deleted') || this.get('purged');\n\t },\n\t\n\t // ........................................................................ searchable\n\t /** searchable attributes for collections */\n\t searchAttributes: ['name', 'tags'],\n\t\n\t // ........................................................................ misc\n\t /** String representation */\n\t toString: function () {\n\t var idAndName = [this.get('id'), this.get('name') || this.get('element_identifier')];\n\t return 'DatasetCollection(' + idAndName.join(',') + ')';\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** Model for a DatasetCollection containing datasets (non-nested).\n\t */\n\t var ListDatasetCollection = DatasetCollection.extend(\n\t /** @lends ListDatasetCollection.prototype */{\n\t\n\t /** override since we know the collection will only contain datasets */\n\t collectionClass: DatasetDCECollection,\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return 'List' + DatasetCollection.prototype.toString.call(this);\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** Model for a DatasetCollection containing fwd/rev datasets (a list of 2).\n\t */\n\t var PairDatasetCollection = ListDatasetCollection.extend(\n\t /** @lends PairDatasetCollection.prototype */{\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return 'Pair' + DatasetCollection.prototype.toString.call(this);\n\t }\n\t });\n\t\n\t //_________________________________________________________________________________________________ NESTED COLLECTIONS\n\t // this is where things get weird, man. Weird.\n\t //TODO: it might be possible to compact all the following...I think.\n\t //==============================================================================\n\t /** @class Backbone model for a Generic DatasetCollectionElement that is also a DatasetCollection\n\t * (a nested collection). Currently only list:paired.\n\t */\n\t var NestedDCDCE = DatasetCollection.extend(BASE_MVC.mixin(DatasetCollectionElementMixin,\n\t /** @lends NestedDCDCE.prototype */{\n\t\n\t // because all objects have constructors (as this hashmap would even if this next line wasn't present)\n\t // the constructor in hcontentMixin won't be attached by BASE_MVC.mixin to this model\n\t // - re-apply manually it now\n\t /** call the mixin constructor */\n\t constructor: function (attributes, options) {\n\t this.debug('\\t NestedDCDCE.constructor:', attributes, options);\n\t DatasetCollectionElementMixin.constructor.call(this, attributes, options);\n\t },\n\t\n\t /** String representation. */\n\t toString: function () {\n\t var objStr = this.object ? '' + this.object : this.get('element_identifier');\n\t return ['NestedDCDCE(', objStr, ')'].join('');\n\t }\n\t }));\n\t\n\t //==============================================================================\n\t /** @class Backbone collection containing Generic NestedDCDCE's (nested dataset collections).\n\t */\n\t var NestedDCDCECollection = DCECollection.extend(\n\t /** @lends NestedDCDCECollection.prototype */{\n\t\n\t /** This is a collection of nested collections */\n\t model: NestedDCDCE,\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return ['NestedDCDCECollection(', this.length, ')'].join('');\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** @class Backbone model for a paired dataset collection within a list:paired dataset collection.\n\t */\n\t var NestedPairDCDCE = PairDatasetCollection.extend(BASE_MVC.mixin(DatasetCollectionElementMixin,\n\t /** @lends NestedPairDCDCE.prototype */{\n\t //TODO:?? possibly rename to NestedDatasetCollection?\n\t\n\t // because all objects have constructors (as this hashmap would even if this next line wasn't present)\n\t // the constructor in hcontentMixin won't be attached by BASE_MVC.mixin to this model\n\t // - re-apply manually it now\n\t /** This is both a collection and a collection element - call the constructor */\n\t constructor: function (attributes, options) {\n\t this.debug('\\t NestedPairDCDCE.constructor:', attributes, options);\n\t //DatasetCollection.constructor.call( this, attributes, options );\n\t DatasetCollectionElementMixin.constructor.call(this, attributes, options);\n\t },\n\t\n\t /** String representation. */\n\t toString: function () {\n\t var objStr = this.object ? '' + this.object : this.get('element_identifier');\n\t return ['NestedPairDCDCE(', objStr, ')'].join('');\n\t }\n\t }));\n\t\n\t //==============================================================================\n\t /** @class Backbone collection for a backbone collection containing paired dataset collections.\n\t */\n\t var NestedPairDCDCECollection = NestedDCDCECollection.extend(\n\t /** @lends PairDCDCECollection.prototype */{\n\t\n\t /** We know this collection is composed of only nested pair collections */\n\t model: NestedPairDCDCE,\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return ['NestedPairDCDCECollection(', this.length, ')'].join('');\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** @class Backbone Model for a DatasetCollection (list) that contains DatasetCollections (pairs).\n\t */\n\t var ListPairedDatasetCollection = DatasetCollection.extend(\n\t /** @lends ListPairedDatasetCollection.prototype */{\n\t\n\t /** list:paired is the only collection that itself contains collections */\n\t collectionClass: NestedPairDCDCECollection,\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return ['ListPairedDatasetCollection(', this.get('name'), ')'].join('');\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** @class Backbone model for a list dataset collection within a list:list dataset collection. */\n\t var NestedListDCDCE = ListDatasetCollection.extend(BASE_MVC.mixin(DatasetCollectionElementMixin,\n\t /** @lends NestedListDCDCE.prototype */{\n\t\n\t /** This is both a collection and a collection element - call the constructor */\n\t constructor: function (attributes, options) {\n\t this.debug('\\t NestedListDCDCE.constructor:', attributes, options);\n\t DatasetCollectionElementMixin.constructor.call(this, attributes, options);\n\t },\n\t\n\t /** String representation. */\n\t toString: function () {\n\t var objStr = this.object ? '' + this.object : this.get('element_identifier');\n\t return ['NestedListDCDCE(', objStr, ')'].join('');\n\t }\n\t }));\n\t\n\t //==============================================================================\n\t /** @class Backbone collection containing list dataset collections. */\n\t var NestedListDCDCECollection = NestedDCDCECollection.extend({\n\t\n\t /** We know this collection is composed of only nested pair collections */\n\t model: NestedListDCDCE,\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return ['NestedListDCDCECollection(', this.length, ')'].join('');\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** @class Backbone Model for a DatasetCollection (list) that contains other lists. */\n\t var ListOfListsDatasetCollection = DatasetCollection.extend({\n\t\n\t /** list:paired is the only collection that itself contains collections */\n\t collectionClass: NestedListDCDCECollection,\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return ['ListOfListsDatasetCollection(', this.get('name'), ')'].join('');\n\t }\n\t });\n\t\n\t //==============================================================================\n\t return {\n\t ListDatasetCollection: ListDatasetCollection,\n\t PairDatasetCollection: PairDatasetCollection,\n\t ListPairedDatasetCollection: ListPairedDatasetCollection,\n\t ListOfListsDatasetCollection: ListOfListsDatasetCollection\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2), __webpack_require__(3), __webpack_require__(1)))\n\n/***/ },\n/* 48 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, _, $, jQuery) {\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(54), __webpack_require__(14), __webpack_require__(6), __webpack_require__(79), __webpack_require__(8), __webpack_require__(97), __webpack_require__(5), __webpack_require__(94)], __WEBPACK_AMD_DEFINE_RESULT__ = function (HDCA, STATES, BASE_MVC, baseCreator, UI_MODAL, naturalSort, _l) {\n\t\n\t 'use strict';\n\t\n\t var logNamespace = 'collections';\n\t\n\t /*==============================================================================\n\t TODO:\n\t use proper Element model and not just json\n\t straighten out createFn, collection.createHDCA\n\t possibly stop using modals for this\n\t It would be neat to do a drag and drop\n\t \n\t ==============================================================================*/\n\t /** A view for both DatasetDCEs and NestedDCDCEs\n\t * (things that implement collection-model:DatasetCollectionElementMixin)\n\t */\n\t var DatasetCollectionElementView = Backbone.View.extend(BASE_MVC.LoggableMixin).extend({\n\t _logNamespace: logNamespace,\n\t\n\t //TODO: use proper class (DatasetDCE or NestedDCDCE (or the union of both))\n\t tagName: 'li',\n\t className: 'collection-element',\n\t\n\t initialize: function (attributes) {\n\t this.element = attributes.element || {};\n\t this.selected = attributes.selected || false;\n\t },\n\t\n\t render: function () {\n\t this.$el.attr('data-element-id', this.element.id).attr('draggable', true).html(this.template({ element: this.element }));\n\t if (this.selected) {\n\t this.$el.addClass('selected');\n\t }\n\t return this;\n\t },\n\t\n\t //TODO: lots of unused space in the element - possibly load details and display them horiz.\n\t template: _.template(['', '<%- element.name %>', '', ''].join('')),\n\t\n\t /** select this element and pub */\n\t select: function (toggle) {\n\t this.$el.toggleClass('selected', toggle);\n\t this.trigger('select', {\n\t source: this,\n\t selected: this.$el.hasClass('selected')\n\t });\n\t },\n\t\n\t /** animate the removal of this element and pub */\n\t discard: function () {\n\t var view = this,\n\t parentWidth = this.$el.parent().width();\n\t this.$el.animate({ 'margin-right': parentWidth }, 'fast', function () {\n\t view.trigger('discard', {\n\t source: view\n\t });\n\t view.destroy();\n\t });\n\t },\n\t\n\t /** remove the DOM and any listeners */\n\t destroy: function () {\n\t this.off();\n\t this.$el.remove();\n\t },\n\t\n\t events: {\n\t 'click': '_click',\n\t 'click .name': '_clickName',\n\t 'click .discard': '_clickDiscard',\n\t\n\t 'dragstart': '_dragstart',\n\t 'dragend': '_dragend',\n\t 'dragover': '_sendToParent',\n\t 'drop': '_sendToParent'\n\t },\n\t\n\t /** select when the li is clicked */\n\t _click: function (ev) {\n\t ev.stopPropagation();\n\t this.select(ev);\n\t },\n\t\n\t /** rename a pair when the name is clicked */\n\t _clickName: function (ev) {\n\t ev.stopPropagation();\n\t ev.preventDefault();\n\t var promptString = [_l('Enter a new name for the element'), ':\\n(', _l('Note that changing the name here will not rename the dataset'), ')'].join(''),\n\t response = prompt(_l('Enter a new name for the element') + ':', this.element.name);\n\t if (response) {\n\t this.element.name = response;\n\t this.render();\n\t }\n\t //TODO: cancelling with ESC leads to closure of the creator...\n\t },\n\t\n\t /** discard when the discard button is clicked */\n\t _clickDiscard: function (ev) {\n\t ev.stopPropagation();\n\t this.discard();\n\t },\n\t\n\t /** dragging pairs for re-ordering */\n\t _dragstart: function (ev) {\n\t if (ev.originalEvent) {\n\t ev = ev.originalEvent;\n\t }\n\t ev.dataTransfer.effectAllowed = 'move';\n\t ev.dataTransfer.setData('text/plain', JSON.stringify(this.element));\n\t\n\t this.$el.addClass('dragging');\n\t this.$el.parent().trigger('collection-element.dragstart', [this]);\n\t },\n\t\n\t /** dragging for re-ordering */\n\t _dragend: function (ev) {\n\t this.$el.removeClass('dragging');\n\t this.$el.parent().trigger('collection-element.dragend', [this]);\n\t },\n\t\n\t /** manually bubble up an event to the parent/container */\n\t _sendToParent: function (ev) {\n\t this.$el.parent().trigger(ev);\n\t },\n\t\n\t /** string rep */\n\t toString: function () {\n\t return 'DatasetCollectionElementView()';\n\t }\n\t });\n\t\n\t // ============================================================================\n\t /** An interface for building collections.\n\t */\n\t var ListCollectionCreator = Backbone.View.extend(BASE_MVC.LoggableMixin).extend(baseCreator.CollectionCreatorMixin).extend({\n\t _logNamespace: logNamespace,\n\t\n\t /** the class used to display individual elements */\n\t elementViewClass: DatasetCollectionElementView,\n\t /** the class this creator will create and save */\n\t collectionClass: HDCA.HistoryListDatasetCollection,\n\t className: 'list-collection-creator collection-creator flex-row-container',\n\t\n\t /** minimum number of valid elements to start with in order to build a collection of this type */\n\t minElements: 1,\n\t\n\t defaultAttributes: {\n\t //TODO: remove - use new collectionClass().save()\n\t /** takes elements and creates the proper collection - returns a promise */\n\t creationFn: function () {\n\t throw new TypeError('no creation fn for creator');\n\t },\n\t /** fn to call when the collection is created (scoped to this) */\n\t oncreate: function () {},\n\t /** fn to call when the cancel button is clicked (scoped to this) - if falsy, no btn is displayed */\n\t oncancel: function () {},\n\t /** distance from list edge to begin autoscrolling list */\n\t autoscrollDist: 24,\n\t /** Color passed to hoverhighlight */\n\t highlightClr: 'rgba( 64, 255, 255, 1.0 )'\n\t },\n\t\n\t footerSettings: {\n\t '.hide-originals': 'hideOriginals'\n\t },\n\t\n\t /** set up initial options, instance vars, behaviors */\n\t initialize: function (attributes) {\n\t this.metric('ListCollectionCreator.initialize', attributes);\n\t var creator = this;\n\t _.each(this.defaultAttributes, function (value, key) {\n\t value = attributes[key] || value;\n\t creator[key] = value;\n\t });\n\t\n\t /** unordered, original list - cache to allow reversal */\n\t creator.initialElements = attributes.elements || [];\n\t\n\t this._setUpCommonSettings(attributes);\n\t this._instanceSetUp();\n\t this._elementsSetUp();\n\t this._setUpBehaviors();\n\t },\n\t\n\t /** set up instance vars */\n\t _instanceSetUp: function () {\n\t /** Ids of elements that have been selected by the user - to preserve over renders */\n\t this.selectedIds = {};\n\t /** DOM elements currently being dragged */\n\t this.$dragging = null;\n\t /** Used for blocking UI events during ajax/operations (don't post twice) */\n\t this.blocking = false;\n\t },\n\t\n\t // ------------------------------------------------------------------------ process raw list\n\t /** set up main data */\n\t _elementsSetUp: function () {\n\t //this.debug( '-- _dataSetUp' );\n\t /** a list of invalid elements and the reasons they aren't valid */\n\t this.invalidElements = [];\n\t //TODO: handle fundamental problem of syncing DOM, views, and list here\n\t /** data for list in progress */\n\t this.workingElements = [];\n\t /** views for workingElements */\n\t this.elementViews = [];\n\t\n\t // copy initial list, sort, add ids if needed\n\t this.workingElements = this.initialElements.slice(0);\n\t this._ensureElementIds();\n\t this._validateElements();\n\t this._mangleDuplicateNames();\n\t this._sortElements();\n\t },\n\t\n\t /** add ids to dataset objs in initial list if none */\n\t _ensureElementIds: function () {\n\t this.workingElements.forEach(function (element) {\n\t if (!element.hasOwnProperty('id')) {\n\t element.id = _.uniqueId();\n\t }\n\t });\n\t return this.workingElements;\n\t },\n\t\n\t /** separate working list into valid and invalid elements for this collection */\n\t _validateElements: function () {\n\t var creator = this,\n\t existingNames = {};\n\t creator.invalidElements = [];\n\t\n\t this.workingElements = this.workingElements.filter(function (element) {\n\t var problem = creator._isElementInvalid(element);\n\t if (problem) {\n\t creator.invalidElements.push({\n\t element: element,\n\t text: problem\n\t });\n\t }\n\t return !problem;\n\t });\n\t return this.workingElements;\n\t },\n\t\n\t /** describe what is wrong with a particular element if anything */\n\t _isElementInvalid: function (element) {\n\t if (element.history_content_type !== 'dataset') {\n\t return _l(\"is not a dataset\");\n\t }\n\t var validState = element.state === STATES.OK || _.contains(STATES.NOT_READY_STATES, element.state);\n\t if (!validState) {\n\t return _l(\"has errored, is paused, or is not accessible\");\n\t }\n\t if (element.deleted || element.purged) {\n\t return _l(\"has been deleted or purged\");\n\t }\n\t return null;\n\t },\n\t\n\t /** mangle duplicate names using a mac-like '(counter)' addition to any duplicates */\n\t _mangleDuplicateNames: function () {\n\t var SAFETY = 900,\n\t counter = 1,\n\t existingNames = {};\n\t this.workingElements.forEach(function (element) {\n\t var currName = element.name;\n\t while (existingNames.hasOwnProperty(currName)) {\n\t currName = element.name + ' (' + counter + ')';\n\t counter += 1;\n\t if (counter >= SAFETY) {\n\t throw new Error('Safety hit in while loop - thats impressive');\n\t }\n\t }\n\t element.name = currName;\n\t existingNames[element.name] = true;\n\t });\n\t },\n\t\n\t /** sort a list of elements */\n\t _sortElements: function (list) {\n\t // // currently only natural sort by name\n\t // this.workingElements.sort( function( a, b ){ return naturalSort( a.name, b.name ); });\n\t // return this.workingElements;\n\t },\n\t\n\t // ------------------------------------------------------------------------ rendering\n\t // templates : ListCollectionCreator.templates,\n\t /** render the entire interface */\n\t render: function (speed, callback) {\n\t //this.debug( '-- _render' );\n\t if (this.workingElements.length < this.minElements) {\n\t return this._renderInvalid(speed, callback);\n\t }\n\t\n\t this.$el.empty().html(this.templates.main());\n\t this._renderHeader(speed);\n\t this._renderMiddle(speed);\n\t this._renderFooter(speed);\n\t this._addPluginComponents();\n\t this.$('.collection-name').focus();\n\t this.trigger('rendered', this);\n\t return this;\n\t },\n\t\n\t /** render a simplified interface aimed at telling the user why they can't move forward */\n\t _renderInvalid: function (speed, callback) {\n\t //this.debug( '-- _render' );\n\t this.$el.empty().html(this.templates.invalidInitial({\n\t problems: this.invalidElements,\n\t elements: this.workingElements\n\t }));\n\t if (typeof this.oncancel === 'function') {\n\t this.$('.cancel-create.btn').show();\n\t }\n\t this.trigger('rendered', this);\n\t return this;\n\t },\n\t\n\t /** render the header section */\n\t _renderHeader: function (speed, callback) {\n\t var $header = this.$('.header').empty().html(this.templates.header()).find('.help-content').prepend($(this.templates.helpContent()));\n\t //TODO: should only show once despite calling _renderHeader again\n\t if (this.invalidElements.length) {\n\t this._invalidElementsAlert();\n\t }\n\t return $header;\n\t },\n\t\n\t /** render the middle including the elements */\n\t _renderMiddle: function (speed, callback) {\n\t var $middle = this.$('.middle').empty().html(this.templates.middle());\n\t this._renderList(speed);\n\t return $middle;\n\t },\n\t\n\t /** add any jQuery/bootstrap/custom plugins to elements rendered */\n\t _addPluginComponents: function () {\n\t this.$('.help-content i').hoverhighlight('.collection-creator', this.highlightClr);\n\t },\n\t\n\t /** build and show an alert describing any elements that could not be included due to problems */\n\t _invalidElementsAlert: function () {\n\t this._showAlert(this.templates.invalidElements({ problems: this.invalidElements }), 'alert-warning');\n\t },\n\t\n\t _disableNameAndCreate: function (disable) {\n\t disable = !_.isUndefined(disable) ? disable : true;\n\t if (disable) {\n\t this.$('.collection-name').prop('disabled', true);\n\t this.$('.create-collection').toggleClass('disabled', true);\n\t // } else {\n\t // this.$( '.collection-name' ).prop( 'disabled', false );\n\t // this.$( '.create-collection' ).removeClass( 'disable' );\n\t }\n\t },\n\t\n\t // ------------------------------------------------------------------------ rendering elements\n\t /** conv. to the main list display DOM */\n\t $list: function () {\n\t return this.$('.collection-elements');\n\t },\n\t\n\t /** show or hide the clear selected control based on the num of selected elements */\n\t _renderClearSelected: function () {\n\t if (_.size(this.selectedIds)) {\n\t this.$('.collection-elements-controls > .clear-selected').show();\n\t } else {\n\t this.$('.collection-elements-controls > .clear-selected').hide();\n\t }\n\t },\n\t\n\t /** render the elements in order (or a warning if no elements found) */\n\t _renderList: function (speed, callback) {\n\t //this.debug( '-- _renderList' );\n\t var creator = this,\n\t $tmp = jQuery('
'),\n\t $list = creator.$list();\n\t\n\t _.each(this.elementViews, function (view) {\n\t view.destroy();\n\t creator.removeElementView(view);\n\t });\n\t\n\t // if( !this.workingElements.length ){\n\t // this._renderNoValidElements();\n\t // return;\n\t // }\n\t\n\t creator.workingElements.forEach(function (element) {\n\t var elementView = creator._createElementView(element);\n\t $tmp.append(elementView.$el);\n\t });\n\t\n\t creator._renderClearSelected();\n\t $list.empty().append($tmp.children());\n\t _.invoke(creator.elementViews, 'render');\n\t\n\t if ($list.height() > $list.css('max-height')) {\n\t $list.css('border-width', '1px 0px 1px 0px');\n\t } else {\n\t $list.css('border-width', '0px');\n\t }\n\t },\n\t\n\t /** create an element view, cache in elementViews, set up listeners, and return */\n\t _createElementView: function (element) {\n\t var elementView = new this.elementViewClass({\n\t //TODO: use non-generic class or not all\n\t // model : COLLECTION.DatasetDCE( element )\n\t element: element,\n\t selected: _.has(this.selectedIds, element.id)\n\t });\n\t this.elementViews.push(elementView);\n\t this._listenToElementView(elementView);\n\t return elementView;\n\t },\n\t\n\t /** listen to any element events */\n\t _listenToElementView: function (view) {\n\t var creator = this;\n\t creator.listenTo(view, {\n\t select: function (data) {\n\t var element = data.source.element;\n\t if (data.selected) {\n\t creator.selectedIds[element.id] = true;\n\t } else {\n\t delete creator.selectedIds[element.id];\n\t }\n\t creator.trigger('elements:select', data);\n\t },\n\t discard: function (data) {\n\t creator.trigger('elements:discard', data);\n\t }\n\t });\n\t },\n\t\n\t /** add a new element view based on the json in element */\n\t addElementView: function (element) {\n\t //TODO: workingElements is sorted, add element in appropo index\n\t // add element, sort elements, find element index\n\t // var view = this._createElementView( element );\n\t // return view;\n\t },\n\t\n\t /** stop listening to view and remove from caches */\n\t removeElementView: function (view) {\n\t delete this.selectedIds[view.element.id];\n\t this._renderClearSelected();\n\t\n\t this.elementViews = _.without(this.elementViews, view);\n\t this.stopListening(view);\n\t },\n\t\n\t /** render a message in the list that no elements remain to create a collection */\n\t _renderNoElementsLeft: function () {\n\t this._disableNameAndCreate(true);\n\t this.$('.collection-elements').append(this.templates.noElementsLeft());\n\t },\n\t\n\t // /** render a message in the list that no valid elements were found to create a collection */\n\t // _renderNoValidElements : function(){\n\t // this._disableNameAndCreate( true );\n\t // this.$( '.collection-elements' ).append( this.templates.noValidElements() );\n\t // },\n\t\n\t // ------------------------------------------------------------------------ API\n\t /** convert element into JSON compatible with the collections API */\n\t _elementToJSON: function (element) {\n\t // return element.toJSON();\n\t return element;\n\t },\n\t\n\t /** create the collection via the API\n\t * @returns {jQuery.xhr Object} the jquery ajax request\n\t */\n\t createList: function (name) {\n\t if (!this.workingElements.length) {\n\t var message = _l('No valid elements for final list') + '. ';\n\t message += '' + _l('Cancel') + ' ';\n\t message += _l('or');\n\t message += ' ' + _l('start over') + '.';\n\t this._showAlert(message);\n\t return;\n\t }\n\t\n\t var creator = this,\n\t elements = this.workingElements.map(function (element) {\n\t return creator._elementToJSON(element);\n\t });\n\t\n\t creator.blocking = true;\n\t return creator.creationFn(elements, name, creator.hideOriginals).always(function () {\n\t creator.blocking = false;\n\t }).fail(function (xhr, status, message) {\n\t creator.trigger('error', {\n\t xhr: xhr,\n\t status: status,\n\t message: _l('An error occurred while creating this collection')\n\t });\n\t }).done(function (response, message, xhr) {\n\t creator.trigger('collection:created', response, message, xhr);\n\t creator.metric('collection:created', response);\n\t if (typeof creator.oncreate === 'function') {\n\t creator.oncreate.call(this, response, message, xhr);\n\t }\n\t });\n\t },\n\t\n\t // ------------------------------------------------------------------------ events\n\t /** set up event handlers on self */\n\t _setUpBehaviors: function () {\n\t this.on('error', this._errorHandler);\n\t\n\t this.once('rendered', function () {\n\t this.trigger('rendered:initial', this);\n\t });\n\t\n\t this.on('elements:select', function (data) {\n\t this._renderClearSelected();\n\t });\n\t\n\t this.on('elements:discard', function (data) {\n\t var element = data.source.element;\n\t this.removeElementView(data.source);\n\t\n\t this.workingElements = _.without(this.workingElements, element);\n\t if (!this.workingElements.length) {\n\t this._renderNoElementsLeft();\n\t }\n\t });\n\t\n\t //this.on( 'all', function(){\n\t // this.info( arguments );\n\t //});\n\t return this;\n\t },\n\t\n\t /** handle errors with feedback and details to the user (if available) */\n\t _errorHandler: function (data) {\n\t this.error(data);\n\t\n\t var creator = this;\n\t content = data.message || _l('An error occurred');\n\t if (data.xhr) {\n\t var xhr = data.xhr,\n\t message = data.message;\n\t if (xhr.readyState === 0 && xhr.status === 0) {\n\t content += ': ' + _l('Galaxy could not be reached and may be updating.') + _l(' Try again in a few minutes.');\n\t } else if (xhr.responseJSON) {\n\t content += ':
' + JSON.stringify(xhr.responseJSON) + '
';\n\t } else {\n\t content += ': ' + message;\n\t }\n\t }\n\t creator._showAlert(content, 'alert-danger');\n\t },\n\t\n\t events: {\n\t // header\n\t 'click .more-help': '_clickMoreHelp',\n\t 'click .less-help': '_clickLessHelp',\n\t 'click .main-help': '_toggleHelp',\n\t 'click .header .alert button': '_hideAlert',\n\t\n\t 'click .reset': 'reset',\n\t 'click .clear-selected': 'clearSelectedElements',\n\t\n\t // elements - selection\n\t 'click .collection-elements': 'clearSelectedElements',\n\t\n\t // elements - drop target\n\t // 'dragenter .collection-elements': '_dragenterElements',\n\t // 'dragleave .collection-elements': '_dragleaveElements',\n\t 'dragover .collection-elements': '_dragoverElements',\n\t 'drop .collection-elements': '_dropElements',\n\t\n\t // these bubble up from the elements as custom events\n\t 'collection-element.dragstart .collection-elements': '_elementDragstart',\n\t 'collection-element.dragend .collection-elements': '_elementDragend',\n\t\n\t // footer\n\t 'change .collection-name': '_changeName',\n\t 'keydown .collection-name': '_nameCheckForEnter',\n\t 'change .hide-originals': '_changeHideOriginals',\n\t 'click .cancel-create': '_cancelCreate',\n\t 'click .create-collection': '_clickCreate' //,\n\t },\n\t\n\t // ........................................................................ elements\n\t /** reset all data to the initial state */\n\t reset: function () {\n\t this._instanceSetUp();\n\t this._elementsSetUp();\n\t this.render();\n\t },\n\t\n\t /** deselect all elements */\n\t clearSelectedElements: function (ev) {\n\t this.$('.collection-elements .collection-element').removeClass('selected');\n\t this.$('.collection-elements-controls > .clear-selected').hide();\n\t },\n\t\n\t //_dragenterElements : function( ev ){\n\t // //this.debug( '_dragenterElements:', ev );\n\t //},\n\t //TODO: if selected are dragged out of the list area - remove the placeholder - cuz it won't work anyway\n\t // _dragleaveElements : function( ev ){\n\t // //this.debug( '_dragleaveElements:', ev );\n\t // },\n\t\n\t /** track the mouse drag over the list adding a placeholder to show where the drop would occur */\n\t _dragoverElements: function (ev) {\n\t //this.debug( '_dragoverElements:', ev );\n\t ev.preventDefault();\n\t\n\t var $list = this.$list();\n\t this._checkForAutoscroll($list, ev.originalEvent.clientY);\n\t var $nearest = this._getNearestElement(ev.originalEvent.clientY);\n\t\n\t //TODO: no need to re-create - move instead\n\t this.$('.element-drop-placeholder').remove();\n\t var $placeholder = $('
');\n\t if (!$nearest.length) {\n\t $list.append($placeholder);\n\t } else {\n\t $nearest.before($placeholder);\n\t }\n\t },\n\t\n\t /** If the mouse is near enough to the list's top or bottom, scroll the list */\n\t _checkForAutoscroll: function ($element, y) {\n\t var AUTOSCROLL_SPEED = 2,\n\t offset = $element.offset(),\n\t scrollTop = $element.scrollTop(),\n\t upperDist = y - offset.top,\n\t lowerDist = offset.top + $element.outerHeight() - y;\n\t if (upperDist >= 0 && upperDist < this.autoscrollDist) {\n\t $element.scrollTop(scrollTop - AUTOSCROLL_SPEED);\n\t } else if (lowerDist >= 0 && lowerDist < this.autoscrollDist) {\n\t $element.scrollTop(scrollTop + AUTOSCROLL_SPEED);\n\t }\n\t },\n\t\n\t /** get the nearest element based on the mouse's Y coordinate.\n\t * If the y is at the end of the list, return an empty jQuery object.\n\t */\n\t _getNearestElement: function (y) {\n\t var WIGGLE = 4,\n\t lis = this.$('.collection-elements li.collection-element').toArray();\n\t for (var i = 0; i < lis.length; i++) {\n\t var $li = $(lis[i]),\n\t top = $li.offset().top,\n\t halfHeight = Math.floor($li.outerHeight() / 2) + WIGGLE;\n\t if (top + halfHeight > y && top - halfHeight < y) {\n\t return $li;\n\t }\n\t }\n\t return $();\n\t },\n\t\n\t /** drop (dragged/selected elements) onto the list, re-ordering the internal list */\n\t _dropElements: function (ev) {\n\t if (ev.originalEvent) {\n\t ev = ev.originalEvent;\n\t }\n\t // both required for firefox\n\t ev.preventDefault();\n\t ev.dataTransfer.dropEffect = 'move';\n\t\n\t // insert before the nearest element or after the last.\n\t var $nearest = this._getNearestElement(ev.clientY);\n\t if ($nearest.length) {\n\t this.$dragging.insertBefore($nearest);\n\t } else {\n\t // no nearest before - insert after last element\n\t this.$dragging.insertAfter(this.$('.collection-elements .collection-element').last());\n\t }\n\t // resync the creator's list based on the new DOM order\n\t this._syncOrderToDom();\n\t return false;\n\t },\n\t\n\t /** resync the creator's list of elements based on the DOM order */\n\t _syncOrderToDom: function () {\n\t var creator = this,\n\t newElements = [];\n\t //TODO: doesn't seem wise to use the dom to store these - can't we sync another way?\n\t this.$('.collection-elements .collection-element').each(function () {\n\t var id = $(this).attr('data-element-id'),\n\t element = _.findWhere(creator.workingElements, { id: id });\n\t if (element) {\n\t newElements.push(element);\n\t } else {\n\t console.error('missing element: ', id);\n\t }\n\t });\n\t this.workingElements = newElements;\n\t this._renderList();\n\t },\n\t\n\t /** drag communication with element sub-views: dragstart */\n\t _elementDragstart: function (ev, element) {\n\t // auto select the element causing the event and move all selected\n\t element.select(true);\n\t this.$dragging = this.$('.collection-elements .collection-element.selected');\n\t },\n\t\n\t /** drag communication with element sub-views: dragend - remove the placeholder */\n\t _elementDragend: function (ev, element) {\n\t $('.element-drop-placeholder').remove();\n\t this.$dragging = null;\n\t },\n\t\n\t // ------------------------------------------------------------------------ templates\n\t //TODO: move to require text plugin and load these as text\n\t //TODO: underscore currently unnecc. bc no vars are used\n\t //TODO: better way of localizing text-nodes in long strings\n\t /** underscore template fns attached to class */\n\t templates: _.extend({}, baseCreator.CollectionCreatorMixin._creatorTemplates, {\n\t\n\t /** the header (not including help text) */\n\t header: _.template(['', '
', '', '', '
'].join('')),\n\t\n\t /** the middle: element list */\n\t middle: _.template(['', '
', '
'].join('')),\n\t\n\t /** creation and cancel controls */\n\t footer: _.template(['
', '
', '', '
', '
', '', '
', _l('Name'), ':
', '
', '
', '
', '
', '', '
', '', '', '
', '
', '
', '', '
', '
'].join('')),\n\t\n\t /** help content */\n\t helpContent: _.template(['

', _l(['Collections of datasets are permanent, ordered lists of datasets that can be passed to tools and ', 'workflows in order to have analyses done on each member of the entire group. This interface allows ', 'you to create a collection and re-order the final collection.'].join('')), '

', '
    ', '
  • ', _l(['Rename elements in the list by clicking on ', 'the existing name.'].join('')), '
  • ', '
  • ', _l(['Discard elements from the final created list by clicking on the ', '\"Discard\" button.'].join('')), '
  • ', '
  • ', _l(['Reorder the list by clicking and dragging elements. Select multiple elements by clicking on ', 'them and you can then move those selected by dragging the ', 'entire group. Deselect them by clicking them again or by clicking the ', 'the \"Clear selected\" link.'].join('')), '
  • ', '
  • ', _l(['Click the \"Start over\" link to begin again as if you had just opened ', 'the interface.'].join('')), '
  • ', '
  • ', _l(['Click the \"Cancel\" button to exit the interface.'].join('')), '
  • ', '

', '

', _l(['Once your collection is complete, enter a name and ', 'click \"Create list\".'].join('')), '

'].join('')),\n\t\n\t /** shown in list when all elements are discarded */\n\t invalidElements: _.template([_l('The following selections could not be included due to problems:'), '
    <% _.each( problems, function( problem ){ %>', '
  • <%- problem.element.name %>: <%- problem.text %>
  • ', '<% }); %>
'].join('')),\n\t\n\t /** shown in list when all elements are discarded */\n\t noElementsLeft: _.template(['
  • ', _l('No elements left! '), _l('Would you like to '), '', _l('start over'), '?', '
  • '].join('')),\n\t\n\t /** a simplified page communicating what went wrong and why the user needs to reselect something else */\n\t invalidInitial: _.template(['
    ', '
    ', '', '<% if( _.size( problems ) ){ %>', _l('The following selections could not be included due to problems'), ':', '
      <% _.each( problems, function( problem ){ %>', '
    • <%- problem.element.name %>: <%- problem.text %>
    • ', '<% }); %>
    ', '<% } else if( _.size( elements ) < 1 ){ %>', _l('No datasets were selected'), '.', '<% } %>', '
    ', _l('At least one element is needed for the collection'), '. ', _l('You may need to '), '', _l('cancel'), ' ', _l('and reselect new elements'), '.', '
    ', '
    ', '
    ', '
    ', '
    ', '
    ', '',\n\t // _l( 'Create a different kind of collection' ),\n\t '
    ', '
    ', '
    '].join(''))\n\t }),\n\t\n\t // ------------------------------------------------------------------------ misc\n\t /** string rep */\n\t toString: function () {\n\t return 'ListCollectionCreator';\n\t }\n\t });\n\t\n\t //=============================================================================\n\t /** Create a modal and load its body with the given CreatorClass creator type\n\t * @returns {Deferred} resolved when creator has built a collection.\n\t */\n\t var collectionCreatorModal = function _collectionCreatorModal(elements, options, CreatorClass) {\n\t\n\t var deferred = jQuery.Deferred(),\n\t modal = Galaxy.modal || new UI_MODAL.View(),\n\t creator;\n\t\n\t options = _.defaults(options || {}, {\n\t elements: elements,\n\t oncancel: function () {\n\t modal.hide();\n\t deferred.reject('cancelled');\n\t },\n\t oncreate: function (creator, response) {\n\t modal.hide();\n\t deferred.resolve(response);\n\t }\n\t });\n\t\n\t creator = new CreatorClass(options);\n\t modal.show({\n\t title: options.title || _l('Create a collection'),\n\t body: creator.$el,\n\t width: '80%',\n\t height: '100%',\n\t closing_events: true\n\t });\n\t creator.render();\n\t window._collectionCreator = creator;\n\t\n\t //TODO: remove modal header\n\t return deferred;\n\t };\n\t\n\t /** List collection flavor of collectionCreatorModal. */\n\t var listCollectionCreatorModal = function _listCollectionCreatorModal(elements, options) {\n\t options = options || {};\n\t options.title = _l('Create a collection from a list of datasets');\n\t return collectionCreatorModal(elements, options, ListCollectionCreator);\n\t };\n\t\n\t //==============================================================================\n\t /** Use a modal to create a list collection, then add it to the given history contents.\n\t * @returns {Deferred} resolved when the collection is added to the history.\n\t */\n\t function createListCollection(contents, defaultHideSourceItems) {\n\t var elements = contents.toJSON(),\n\t promise = listCollectionCreatorModal(elements, {\n\t defaultHideSourceItems: defaultHideSourceItems,\n\t creationFn: function (elements, name, hideSourceItems) {\n\t elements = elements.map(function (element) {\n\t return {\n\t id: element.id,\n\t name: element.name,\n\t //TODO: this allows for list:list even if the filter above does not - reconcile\n\t src: element.history_content_type === 'dataset' ? 'hda' : 'hdca'\n\t };\n\t });\n\t return contents.createHDCA(elements, 'list', name, hideSourceItems);\n\t }\n\t });\n\t return promise;\n\t }\n\t\n\t //==============================================================================\n\t return {\n\t DatasetCollectionElementView: DatasetCollectionElementView,\n\t ListCollectionCreator: ListCollectionCreator,\n\t\n\t collectionCreatorModal: collectionCreatorModal,\n\t listCollectionCreatorModal: listCollectionCreatorModal,\n\t createListCollection: createListCollection\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(2), __webpack_require__(1), __webpack_require__(1)))\n\n/***/ },\n/* 49 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(_, jQuery, Backbone, $) {!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(58), __webpack_require__(14), __webpack_require__(22), __webpack_require__(6), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (LIST_ITEM, STATES, faIconButton, BASE_MVC, _l) {\n\t 'use strict';\n\t\n\t var logNamespace = 'dataset';\n\t /*==============================================================================\n\t TODO:\n\t straighten out state rendering and templates used\n\t inaccessible/STATES.NOT_VIEWABLE is a special case\n\t simplify button rendering\n\t \n\t ==============================================================================*/\n\t var _super = LIST_ITEM.ListItemView;\n\t /** @class Read only list view for either LDDAs, HDAs, or HDADCEs.\n\t * Roughly, any DatasetInstance (and not a raw Dataset).\n\t */\n\t var DatasetListItemView = _super.extend(\n\t /** @lends DatasetListItemView.prototype */{\n\t _logNamespace: logNamespace,\n\t\n\t className: _super.prototype.className + \" dataset\",\n\t //TODO:?? doesn't exactly match an hda's type_id\n\t id: function () {\n\t return ['dataset', this.model.get('id')].join('-');\n\t },\n\t\n\t /** Set up: instance vars, options, and event handlers */\n\t initialize: function (attributes) {\n\t if (attributes.logger) {\n\t this.logger = this.model.logger = attributes.logger;\n\t }\n\t this.log(this + '.initialize:', attributes);\n\t _super.prototype.initialize.call(this, attributes);\n\t\n\t /** where should pages from links be displayed? (default to new tab/window) */\n\t this.linkTarget = attributes.linkTarget || '_blank';\n\t },\n\t\n\t /** event listeners */\n\t _setUpListeners: function () {\n\t _super.prototype._setUpListeners.call(this);\n\t var self = this;\n\t\n\t // re-rendering on any model changes\n\t return self.listenTo(self.model, {\n\t 'change': function (model) {\n\t // if the model moved into the ready state and is expanded without details, fetch those details now\n\t if (self.model.changedAttributes().state && self.model.inReadyState() && self.expanded && !self.model.hasDetails()) {\n\t // normally, will render automatically (due to fetch -> change),\n\t // but! setting_metadata sometimes doesn't cause any other changes besides state\n\t // so, not rendering causes it to seem frozen in setting_metadata state\n\t self.model.fetch({ silent: true }).done(function () {\n\t self.render();\n\t });\n\t } else {\n\t if (_.has(model.changed, 'tags') && _.keys(model.changed).length === 1) {\n\t // If only the tags have changed, rerender specifically\n\t // the titlebar region. Otherwise default to the full\n\t // render.\n\t self.$('.nametags').html(self._renderNametags());\n\t } else {\n\t self.render();\n\t }\n\t }\n\t }\n\t });\n\t },\n\t\n\t // ......................................................................... expandable\n\t /** In this override, only get details if in the ready state, get rerunnable if in other states.\n\t * Note: fetch with no 'change' event triggering to prevent automatic rendering.\n\t */\n\t _fetchModelDetails: function () {\n\t var view = this;\n\t if (view.model.inReadyState() && !view.model.hasDetails()) {\n\t return view.model.fetch({ silent: true });\n\t }\n\t return jQuery.when();\n\t },\n\t\n\t // ......................................................................... removal\n\t /** Remove this view's html from the DOM and remove all event listeners.\n\t * @param {Number or String} speed jq effect speed\n\t * @param {Function} callback an optional function called when removal is done (scoped to this view)\n\t */\n\t remove: function (speed, callback) {\n\t var view = this;\n\t speed = speed || this.fxSpeed;\n\t this.$el.fadeOut(speed, function () {\n\t Backbone.View.prototype.remove.call(view);\n\t if (callback) {\n\t callback.call(view);\n\t }\n\t });\n\t },\n\t\n\t // ......................................................................... rendering\n\t /* TODO:\n\t dataset states are the issue primarily making dataset rendering complex\n\t each state should have it's own way of displaying/set of details\n\t often with different actions that can be applied\n\t throw in deleted/purged/visible and things get complicated easily\n\t I've considered (a couple of times) - creating a view for each state\n\t - but recreating the view during an update...seems wrong\n\t */\n\t /** In this override, add the dataset state as a class for use with state-based CSS */\n\t _swapNewRender: function ($newRender) {\n\t _super.prototype._swapNewRender.call(this, $newRender);\n\t if (this.model.has('state')) {\n\t this.$el.addClass('state-' + this.model.get('state'));\n\t }\n\t return this.$el;\n\t },\n\t\n\t // ................................................................................ titlebar\n\t /** In this override, add the dataset display button. */\n\t _renderPrimaryActions: function () {\n\t // render just the display for read-only\n\t return [this._renderDisplayButton()];\n\t },\n\t\n\t /** Render icon-button to display dataset data */\n\t _renderDisplayButton: function () {\n\t // don't show display if not viewable or not accessible\n\t var state = this.model.get('state');\n\t if (state === STATES.NOT_VIEWABLE || state === STATES.DISCARDED || !this.model.get('accessible')) {\n\t return null;\n\t }\n\t\n\t var displayBtnData = {\n\t target: this.linkTarget,\n\t classes: 'display-btn'\n\t };\n\t\n\t // show a disabled display if the data's been purged\n\t if (this.model.get('purged')) {\n\t displayBtnData.disabled = true;\n\t displayBtnData.title = _l('Cannot display datasets removed from disk');\n\t\n\t // disable if still uploading\n\t } else if (state === STATES.UPLOAD) {\n\t displayBtnData.disabled = true;\n\t displayBtnData.title = _l('This dataset must finish uploading before it can be viewed');\n\t\n\t // disable if still new\n\t } else if (state === STATES.NEW) {\n\t displayBtnData.disabled = true;\n\t displayBtnData.title = _l('This dataset is not yet viewable');\n\t } else {\n\t displayBtnData.title = _l('View data');\n\t\n\t // default link for dataset\n\t displayBtnData.href = this.model.urls.display;\n\t\n\t // add frame manager option onclick event\n\t var self = this;\n\t displayBtnData.onclick = function (ev) {\n\t if (Galaxy.frame && Galaxy.frame.active) {\n\t // Add dataset to frames.\n\t Galaxy.frame.addDataset(self.model.get('id'));\n\t ev.preventDefault();\n\t }\n\t };\n\t }\n\t displayBtnData.faIcon = 'fa-eye';\n\t return faIconButton(displayBtnData);\n\t },\n\t\n\t // ......................................................................... rendering details\n\t /** Render the enclosing div of the hda body and, if expanded, the html in the body\n\t * @returns {jQuery} rendered DOM\n\t */\n\t _renderDetails: function () {\n\t //TODO: generalize to be allow different details for each state\n\t\n\t // no access - render nothing but a message\n\t if (this.model.get('state') === STATES.NOT_VIEWABLE) {\n\t return $(this.templates.noAccess(this.model.toJSON(), this));\n\t }\n\t\n\t var $details = _super.prototype._renderDetails.call(this);\n\t $details.find('.actions .left').empty().append(this._renderSecondaryActions());\n\t $details.find('.summary').html(this._renderSummary()).prepend(this._renderDetailMessages());\n\t $details.find('.display-applications').html(this._renderDisplayApplications());\n\t\n\t this._setUpBehaviors($details);\n\t return $details;\n\t },\n\t\n\t /** Defer to the appropo summary rendering fn based on state */\n\t _renderSummary: function () {\n\t var json = this.model.toJSON(),\n\t summaryRenderFn = this.templates.summaries[json.state];\n\t summaryRenderFn = summaryRenderFn || this.templates.summaries.unknown;\n\t return summaryRenderFn(json, this);\n\t },\n\t\n\t /** Render messages to be displayed only when the details are shown */\n\t _renderDetailMessages: function () {\n\t var view = this,\n\t $warnings = $('
    '),\n\t json = view.model.toJSON();\n\t //TODO:! unordered (map)\n\t _.each(view.templates.detailMessages, function (templateFn) {\n\t $warnings.append($(templateFn(json, view)));\n\t });\n\t return $warnings;\n\t },\n\t\n\t /** Render the external display application links */\n\t _renderDisplayApplications: function () {\n\t if (this.model.isDeletedOrPurged()) {\n\t return '';\n\t }\n\t // render both old and new display apps using the same template\n\t return [this.templates.displayApplications(this.model.get('display_apps'), this), this.templates.displayApplications(this.model.get('display_types'), this)].join('');\n\t },\n\t\n\t // ......................................................................... secondary/details actions\n\t /** A series of links/buttons for less commonly used actions: re-run, info, etc. */\n\t _renderSecondaryActions: function () {\n\t this.debug('_renderSecondaryActions');\n\t switch (this.model.get('state')) {\n\t case STATES.NOT_VIEWABLE:\n\t return [];\n\t case STATES.OK:\n\t case STATES.FAILED_METADATA:\n\t case STATES.ERROR:\n\t return [this._renderDownloadButton(), this._renderShowParamsButton()];\n\t }\n\t return [this._renderShowParamsButton()];\n\t },\n\t\n\t /** Render icon-button to show the input and output (stdout/err) for the job that created this.\n\t * @returns {jQuery} rendered DOM\n\t */\n\t _renderShowParamsButton: function () {\n\t // gen. safe to show in all cases\n\t return faIconButton({\n\t title: _l('View details'),\n\t classes: 'params-btn',\n\t href: this.model.urls.show_params,\n\t target: this.linkTarget,\n\t faIcon: 'fa-info-circle',\n\t onclick: function (ev) {\n\t if (Galaxy.frame && Galaxy.frame.active) {\n\t Galaxy.frame.add({ title: 'Dataset details', url: this.href });\n\t ev.preventDefault();\n\t ev.stopPropagation();\n\t }\n\t }\n\t });\n\t },\n\t\n\t /** Render icon-button/popupmenu to download the data (and/or the associated meta files (bai, etc.)) for this.\n\t * @returns {jQuery} rendered DOM\n\t */\n\t _renderDownloadButton: function () {\n\t // don't show anything if the data's been purged\n\t if (this.model.get('purged') || !this.model.hasData()) {\n\t return null;\n\t }\n\t\n\t // return either: a popupmenu with links to download assoc. meta files (if there are meta files)\n\t // or a single download icon-button (if there are no meta files)\n\t if (!_.isEmpty(this.model.get('meta_files'))) {\n\t return this._renderMetaFileDownloadButton();\n\t }\n\t\n\t return $(['', '', ''].join(''));\n\t },\n\t\n\t /** Render the download button which opens a dropdown with links to download assoc. meta files (indeces, etc.) */\n\t _renderMetaFileDownloadButton: function () {\n\t var urls = this.model.urls;\n\t return $(['
    ', '', '', '', '', '
    '].join('\\n'));\n\t },\n\t\n\t _renderNametags: function () {\n\t var tpl = _.template(['<% _.each(_.sortBy(_.uniq(tags), function(x) { return x }), function(tag){ %>', '<% if (tag.indexOf(\"name:\") == 0){ %>', '<%- tag.slice(5) %>', '<% } %>', '<% }); %>'].join(''));\n\t return tpl({ tags: this.model.get('tags') });\n\t },\n\t\n\t // ......................................................................... misc\n\t events: _.extend(_.clone(_super.prototype.events), {\n\t 'click .display-btn': function (ev) {\n\t this.trigger('display', this, ev);\n\t },\n\t 'click .params-btn': function (ev) {\n\t this.trigger('params', this, ev);\n\t },\n\t 'click .download-btn': function (ev) {\n\t this.trigger('download', this, ev);\n\t }\n\t }),\n\t\n\t // ......................................................................... misc\n\t /** String representation */\n\t toString: function () {\n\t var modelString = this.model ? this.model + '' : '(no model)';\n\t return 'DatasetListItemView(' + modelString + ')';\n\t }\n\t });\n\t\n\t // ............................................................................ TEMPLATES\n\t /** underscore templates */\n\t DatasetListItemView.prototype.templates = function () {\n\t //TODO: move to require text! plugin\n\t\n\t var warnings = _.extend({}, _super.prototype.templates.warnings, {\n\t failed_metadata: BASE_MVC.wrapTemplate([\n\t // failed metadata is rendered as a warning on an otherwise ok dataset view\n\t '<% if( model.state === \"failed_metadata\" ){ %>', '
    ', _l('An error occurred setting the metadata for this dataset'), '
    ', '<% } %>']),\n\t error: BASE_MVC.wrapTemplate([\n\t // error during index fetch - show error on dataset\n\t '<% if( model.error ){ %>', '
    ', _l('There was an error getting the data for this dataset'), ': <%- model.error %>', '
    ', '<% } %>']),\n\t purged: BASE_MVC.wrapTemplate(['<% if( model.purged ){ %>', '
    ', _l('This dataset has been deleted and removed from disk'), '
    ', '<% } %>']),\n\t deleted: BASE_MVC.wrapTemplate([\n\t // deleted not purged\n\t '<% if( model.deleted && !model.purged ){ %>', '
    ', _l('This dataset has been deleted'), '
    ', '<% } %>'])\n\t\n\t //NOTE: hidden warning is only needed for HDAs\n\t });\n\t\n\t var detailsTemplate = BASE_MVC.wrapTemplate(['
    ', '
    ', '
    ', '
    ', '
    ', '
    ',\n\t\n\t // do not display tags, annotation, display apps, or peek when deleted\n\t '<% if( !dataset.deleted && !dataset.purged ){ %>', '
    ', '
    ', '
    ', '<% if( dataset.peek ){ %>', '
    <%= dataset.peek %>
    ', '<% } %>', '<% } %>', '
    '], 'dataset');\n\t\n\t var noAccessTemplate = BASE_MVC.wrapTemplate(['
    ', '
    ', _l('You do not have permission to view this dataset'), '
    ', '
    '], 'dataset');\n\t\n\t //TODO: still toooooooooooooo complex - rework\n\t var summaryTemplates = {};\n\t summaryTemplates[STATES.OK] = summaryTemplates[STATES.FAILED_METADATA] = BASE_MVC.wrapTemplate(['<% if( dataset.misc_blurb ){ %>', '
    ', '<%- dataset.misc_blurb %>', '
    ', '<% } %>', '<% if( dataset.file_ext ){ %>', '
    ', '', '<%- dataset.file_ext %>', '
    ', '<% } %>', '<% if( dataset.metadata_dbkey ){ %>', '
    ', '', '', '<%- dataset.metadata_dbkey %>', '', '
    ', '<% } %>', '<% if( dataset.misc_info ){ %>', '
    ', '<%- dataset.misc_info %>', '
    ', '<% } %>'], 'dataset');\n\t summaryTemplates[STATES.NEW] = BASE_MVC.wrapTemplate(['
    ', _l('This is a new dataset and not all of its data are available yet'), '
    '], 'dataset');\n\t summaryTemplates[STATES.NOT_VIEWABLE] = BASE_MVC.wrapTemplate(['
    ', _l('You do not have permission to view this dataset'), '
    '], 'dataset');\n\t summaryTemplates[STATES.DISCARDED] = BASE_MVC.wrapTemplate(['
    ', _l('The job creating this dataset was cancelled before completion'), '
    '], 'dataset');\n\t summaryTemplates[STATES.QUEUED] = BASE_MVC.wrapTemplate(['
    ', _l('This job is waiting to run'), '
    '], 'dataset');\n\t summaryTemplates[STATES.RUNNING] = BASE_MVC.wrapTemplate(['
    ', _l('This job is currently running'), '
    '], 'dataset');\n\t summaryTemplates[STATES.UPLOAD] = BASE_MVC.wrapTemplate(['
    ', _l('This dataset is currently uploading'), '
    '], 'dataset');\n\t summaryTemplates[STATES.SETTING_METADATA] = BASE_MVC.wrapTemplate(['
    ', _l('Metadata is being auto-detected'), '
    '], 'dataset');\n\t summaryTemplates[STATES.PAUSED] = BASE_MVC.wrapTemplate(['
    ', _l('This job is paused. Use the \"Resume Paused Jobs\" in the history menu to resume'), '
    '], 'dataset');\n\t summaryTemplates[STATES.ERROR] = BASE_MVC.wrapTemplate(['<% if( !dataset.purged ){ %>', '
    <%- dataset.misc_blurb %>
    ', '<% } %>', '', _l('An error occurred with this dataset'), ':', '
    <%- dataset.misc_info %>
    '], 'dataset');\n\t summaryTemplates[STATES.EMPTY] = BASE_MVC.wrapTemplate(['
    ', _l('No data'), ': <%- dataset.misc_blurb %>
    '], 'dataset');\n\t summaryTemplates.unknown = BASE_MVC.wrapTemplate(['
    Error: unknown dataset state: \"<%- dataset.state %>\"
    '], 'dataset');\n\t\n\t // messages to be displayed only within the details section ('below the fold')\n\t var detailMessageTemplates = {\n\t resubmitted: BASE_MVC.wrapTemplate([\n\t // deleted not purged\n\t '<% if( model.resubmitted ){ %>', '
    ', _l('The job creating this dataset has been resubmitted'), '
    ', '<% } %>'])\n\t };\n\t\n\t // this is applied to both old and new style display apps\n\t var displayApplicationsTemplate = BASE_MVC.wrapTemplate(['<% _.each( apps, function( app ){ %>', '
    ', '<%- app.label %> ', '', '<% _.each( app.links, function( link ){ %>', '\" href=\"<%- link.href %>\">', '<% print( _l( link.text ) ); %>', ' ', '<% }); %>', '', '
    ', '<% }); %>'], 'apps');\n\t\n\t return _.extend({}, _super.prototype.templates, {\n\t warnings: warnings,\n\t details: detailsTemplate,\n\t noAccess: noAccessTemplate,\n\t summaries: summaryTemplates,\n\t detailMessages: detailMessageTemplates,\n\t displayApplications: displayApplicationsTemplate\n\t });\n\t }();\n\t\n\t // ============================================================================\n\t return {\n\t DatasetListItemView: DatasetListItemView\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2), __webpack_require__(1), __webpack_require__(3), __webpack_require__(1)))\n\n/***/ },\n/* 50 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, $, _) {/**\n\t This class creates a form input element wrapper\n\t*/\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {\n\t return Backbone.View.extend({\n\t initialize: function (app, options) {\n\t this.app = app;\n\t this.app_options = app.model ? app.model.attributes : {};\n\t this.field = options && options.field || new Backbone.View();\n\t this.model = options && options.model || new Backbone.Model({\n\t text_enable: this.app_options.text_enable || 'Enable',\n\t text_disable: this.app_options.text_disable || 'Disable',\n\t cls_enable: this.app_options.cls_enable || 'fa fa-caret-square-o-down',\n\t cls_disable: this.app_options.cls_disable || 'fa fa-caret-square-o-up',\n\t always_refresh: this.app_options.always_refresh\n\t }).set(options);\n\t\n\t // set element and link components\n\t this.setElement(this._template());\n\t this.$field = this.$('.ui-form-field');\n\t this.$info = this.$('.ui-form-info');\n\t this.$preview = this.$('.ui-form-preview');\n\t this.$collapsible = this.$('.ui-form-collapsible');\n\t this.$collapsible_text = this.$('.ui-form-collapsible-text');\n\t this.$collapsible_icon = this.$('.ui-form-collapsible-icon');\n\t this.$title = this.$('.ui-form-title');\n\t this.$title_text = this.$('.ui-form-title-text');\n\t this.$error_text = this.$('.ui-form-error-text');\n\t this.$error = this.$('.ui-form-error');\n\t this.$backdrop = this.$('.ui-form-backdrop');\n\t\n\t // add field element\n\t this.$field.prepend(this.field.$el);\n\t\n\t // decide wether to expand or collapse fields\n\t var collapsible_value = this.model.get('collapsible_value');\n\t this.field.collapsed = collapsible_value !== undefined && JSON.stringify(this.model.get('value')) == JSON.stringify(collapsible_value);\n\t this.listenTo(this.model, 'change', this.render, this);\n\t this.render();\n\t\n\t // add click handler\n\t var self = this;\n\t this.$collapsible.on('click', function () {\n\t self.field.collapsed = !self.field.collapsed;\n\t app.trigger && app.trigger('change');\n\t self.render();\n\t });\n\t\n\t // hide error on value change\n\t if (this.field.model && !this.model.get('always_refresh')) {\n\t this.listenTo(this.field.model, 'change:value', function () {\n\t self.reset();\n\t });\n\t }\n\t },\n\t\n\t /** Set backdrop for input element */\n\t backdrop: function () {\n\t this.model.set('backdrop', true);\n\t },\n\t\n\t /** Set error text */\n\t error: function (text) {\n\t this.model.set('error_text', text);\n\t },\n\t\n\t /** Reset this view */\n\t reset: function () {\n\t !this.model.get('fixed') && this.model.set('error_text', null);\n\t },\n\t\n\t render: function () {\n\t // render help\n\t $('.tooltip').hide();\n\t var help_text = this.model.get('help', '');\n\t var help_argument = this.model.get('argument');\n\t if (help_argument && help_text.indexOf('(' + help_argument + ')') == -1) {\n\t help_text += ' (' + help_argument + ')';\n\t }\n\t this.$info.html(help_text);\n\t // render visibility\n\t this.$el[this.model.get('hidden') ? 'hide' : 'show']();\n\t // render preview view for collapsed fields\n\t this.$preview[this.field.collapsed && this.model.get('collapsible_preview') || this.model.get('disabled') ? 'show' : 'hide']().html(_.escape(this.model.get('text_value')));\n\t // render error messages\n\t var error_text = this.model.get('error_text');\n\t this.$error[error_text ? 'show' : 'hide']();\n\t this.$el[error_text ? 'addClass' : 'removeClass']('ui-error');\n\t this.$error_text.html(error_text);\n\t // render backdrop\n\t this.$backdrop[this.model.get('backdrop') ? 'show' : 'hide']();\n\t // render input field\n\t this.field.collapsed || this.model.get('disabled') ? this.$field.hide() : this.$field.show();\n\t // render input field color and style\n\t this.field.model && this.field.model.set({ 'color': this.model.get('color'), 'style': this.model.get('style') });\n\t // render collapsible options\n\t if (!this.model.get('disabled') && this.model.get('collapsible_value') !== undefined) {\n\t var collapsible_state = this.field.collapsed ? 'enable' : 'disable';\n\t this.$title_text.hide();\n\t this.$collapsible.show();\n\t this.$collapsible_text.text(this.model.get('label'));\n\t this.$collapsible_icon.removeClass().addClass('icon').addClass(this.model.get('cls_' + collapsible_state)).attr('data-original-title', this.model.get('text_' + collapsible_state)).tooltip({ placement: 'bottom' });\n\t } else {\n\t this.$title_text.show().text(this.model.get('label'));\n\t this.$collapsible.hide();\n\t }\n\t },\n\t\n\t _template: function () {\n\t return $('
    ').addClass('ui-form-element').append($('
    ').addClass('ui-form-error ui-error').append($('').addClass('fa fa-arrow-down')).append($('').addClass('ui-form-error-text'))).append($('
    ').addClass('ui-form-title').append($('
    ').addClass('ui-form-collapsible').append($('').addClass('ui-form-collapsible-icon')).append($('').addClass('ui-form-collapsible-text'))).append($('').addClass('ui-form-title-text'))).append($('
    ').addClass('ui-form-field').append($('').addClass('ui-form-info')).append($('
    ').addClass('ui-form-backdrop'))).append($('
    ').addClass('ui-form-preview'));\n\t }\n\t });\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(1), __webpack_require__(2)))\n\n/***/ },\n/* 51 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, _, $) {/**\n\t This class creates input elements. New input parameter types should be added to the types dictionary.\n\t*/\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(4), __webpack_require__(7), __webpack_require__(62), __webpack_require__(64), __webpack_require__(63), __webpack_require__(61)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Utils, Ui, SelectContent, SelectLibrary, SelectFtp, ColorPicker) {\n\t\n\t // create form view\n\t return Backbone.Model.extend({\n\t /** Available parameter types */\n\t types: {\n\t 'text': '_fieldText',\n\t 'password': '_fieldText',\n\t 'select': '_fieldSelect',\n\t 'data_column': '_fieldSelect',\n\t 'genomebuild': '_fieldSelect',\n\t 'data': '_fieldData',\n\t 'data_collection': '_fieldData',\n\t 'integer': '_fieldSlider',\n\t 'float': '_fieldSlider',\n\t 'boolean': '_fieldBoolean',\n\t 'drill_down': '_fieldDrilldown',\n\t 'color': '_fieldColor',\n\t 'hidden': '_fieldHidden',\n\t 'hidden_data': '_fieldHidden',\n\t 'baseurl': '_fieldHidden',\n\t 'library_data': '_fieldLibrary',\n\t 'ftpfile': '_fieldFtp',\n\t 'upload': '_fieldUpload'\n\t },\n\t\n\t /** Returns an input field for a given field type */\n\t create: function (input_def) {\n\t var fieldClass = this.types[input_def.type];\n\t var field = typeof this[fieldClass] === 'function' ? this[fieldClass].call(this, input_def) : null;\n\t if (!field) {\n\t field = input_def.options ? this._fieldSelect(input_def) : this._fieldText(input_def);\n\t Galaxy.emit.debug('form-parameters::_addRow()', 'Auto matched field type (' + input_def.type + ').');\n\t }\n\t input_def.value === undefined && (input_def.value = null);\n\t field.value(input_def.value);\n\t return field;\n\t },\n\t\n\t /** Data input field */\n\t _fieldData: function (input_def) {\n\t return new SelectContent.View({\n\t id: 'field-' + input_def.id,\n\t extensions: input_def.extensions,\n\t optional: input_def.optional,\n\t multiple: input_def.multiple,\n\t type: input_def.type,\n\t flavor: input_def.flavor,\n\t data: input_def.options,\n\t onchange: input_def.onchange\n\t });\n\t },\n\t\n\t /** Select/Checkbox/Radio options field */\n\t _fieldSelect: function (input_def) {\n\t // show text field e.g. in workflow editor\n\t if (input_def.is_workflow) {\n\t return this._fieldText(input_def);\n\t }\n\t\n\t // customize properties\n\t if (input_def.type == 'data_column') {\n\t input_def.error_text = 'Missing columns in referenced dataset.';\n\t }\n\t\n\t // identify available options\n\t var data = input_def.data;\n\t if (!data) {\n\t data = [];\n\t _.each(input_def.options, function (option) {\n\t data.push({ label: option[0], value: option[1] });\n\t });\n\t }\n\t\n\t // identify display type\n\t var SelectClass = Ui.Select;\n\t switch (input_def.display) {\n\t case 'checkboxes':\n\t SelectClass = Ui.Checkbox;\n\t break;\n\t case 'radio':\n\t SelectClass = Ui.Radio;\n\t break;\n\t case 'radiobutton':\n\t SelectClass = Ui.RadioButton;\n\t break;\n\t }\n\t\n\t // create select field\n\t return new SelectClass.View({\n\t id: 'field-' + input_def.id,\n\t data: data,\n\t error_text: input_def.error_text || 'No options available',\n\t multiple: input_def.multiple,\n\t optional: input_def.optional,\n\t onchange: input_def.onchange,\n\t searchable: input_def.flavor !== 'workflow'\n\t });\n\t },\n\t\n\t /** Drill down options field */\n\t _fieldDrilldown: function (input_def) {\n\t // show text field e.g. in workflow editor\n\t if (input_def.is_workflow) {\n\t return this._fieldText(input_def);\n\t }\n\t\n\t // create drill down field\n\t return new Ui.Drilldown.View({\n\t id: 'field-' + input_def.id,\n\t data: input_def.options,\n\t display: input_def.display,\n\t optional: input_def.optional,\n\t onchange: input_def.onchange\n\t });\n\t },\n\t\n\t /** Text input field */\n\t _fieldText: function (input_def) {\n\t // field replaces e.g. a select field\n\t if (input_def.options && input_def.data) {\n\t input_def.area = input_def.multiple;\n\t if (Utils.isEmpty(input_def.value)) {\n\t input_def.value = null;\n\t } else {\n\t if ($.isArray(input_def.value)) {\n\t var str_value = '';\n\t for (var i in input_def.value) {\n\t str_value += String(input_def.value[i]);\n\t if (!input_def.multiple) {\n\t break;\n\t }\n\t str_value += '\\n';\n\t }\n\t input_def.value = str_value;\n\t }\n\t }\n\t }\n\t // create input element\n\t return new Ui.Input({\n\t id: 'field-' + input_def.id,\n\t type: input_def.type,\n\t area: input_def.area,\n\t readonly: input_def.readonly,\n\t placeholder: input_def.placeholder,\n\t datalist: input_def.datalist,\n\t onchange: input_def.onchange\n\t });\n\t },\n\t\n\t /** Slider field */\n\t _fieldSlider: function (input_def) {\n\t return new Ui.Slider.View({\n\t id: 'field-' + input_def.id,\n\t precise: input_def.type == 'float',\n\t is_workflow: input_def.is_workflow,\n\t min: input_def.min,\n\t max: input_def.max,\n\t onchange: input_def.onchange\n\t });\n\t },\n\t\n\t /** Hidden field */\n\t _fieldHidden: function (input_def) {\n\t return new Ui.Hidden({\n\t id: 'field-' + input_def.id,\n\t info: input_def.info\n\t });\n\t },\n\t\n\t /** Boolean field */\n\t _fieldBoolean: function (input_def) {\n\t return new Ui.RadioButton.View({\n\t id: 'field-' + input_def.id,\n\t data: [{ label: 'Yes', value: 'true' }, { label: 'No', value: 'false' }],\n\t onchange: input_def.onchange\n\t });\n\t },\n\t\n\t /** Color picker field */\n\t _fieldColor: function (input_def) {\n\t return new ColorPicker({\n\t id: 'field-' + input_def.id,\n\t onchange: input_def.onchange\n\t });\n\t },\n\t\n\t /** Library dataset field */\n\t _fieldLibrary: function (input_def) {\n\t return new SelectLibrary.View({\n\t id: 'field-' + input_def.id,\n\t optional: input_def.optional,\n\t multiple: input_def.multiple,\n\t onchange: input_def.onchange\n\t });\n\t },\n\t\n\t /** FTP file field */\n\t _fieldFtp: function (input_def) {\n\t return new SelectFtp.View({\n\t id: 'field-' + input_def.id,\n\t optional: input_def.optional,\n\t multiple: input_def.multiple,\n\t onchange: input_def.onchange\n\t });\n\t },\n\t\n\t /** Upload file field */\n\t _fieldUpload: function (input_def) {\n\t return new Ui.Upload({\n\t id: 'field-' + input_def.id,\n\t onchange: input_def.onchange\n\t });\n\t }\n\t });\n\t\n\t return {\n\t View: View\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(2), __webpack_require__(1)))\n\n/***/ },\n/* 52 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, $, _) {/** This class creates a ui component which enables the dynamic creation of portlets */\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(4), __webpack_require__(10), __webpack_require__(7)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Utils, Portlet, Ui) {\n\t var View = Backbone.View.extend({\n\t initialize: function (options) {\n\t this.list = {};\n\t this.options = Utils.merge(options, {\n\t title: 'Repeat',\n\t empty_text: 'Not available.',\n\t max: null,\n\t min: null\n\t });\n\t this.button_new = new Ui.ButtonIcon({\n\t icon: 'fa-plus',\n\t title: 'Insert ' + this.options.title,\n\t tooltip: 'Add new ' + this.options.title + ' block',\n\t floating: 'clear',\n\t cls: 'ui-button-icon form-repeat-add',\n\t onclick: function () {\n\t options.onnew && options.onnew();\n\t }\n\t });\n\t this.setElement($('
    ').append(this.$list = $('
    ')).append($('
    ').append(this.button_new.$el)));\n\t },\n\t\n\t /** Number of repeat blocks */\n\t size: function () {\n\t return _.size(this.list);\n\t },\n\t\n\t /** Add new repeat block */\n\t add: function (options) {\n\t if (!options.id || this.list[options.id]) {\n\t Galaxy.emit.debug('form-repeat::add()', 'Duplicate or invalid repeat block id.');\n\t return;\n\t }\n\t var button_delete = new Ui.ButtonIcon({\n\t icon: 'fa-trash-o',\n\t tooltip: 'Delete this repeat block',\n\t cls: 'ui-button-icon-plain form-repeat-delete',\n\t onclick: function () {\n\t options.ondel && options.ondel();\n\t }\n\t });\n\t var portlet = new Portlet.View({\n\t id: options.id,\n\t title: 'placeholder',\n\t cls: options.cls || 'ui-portlet-repeat',\n\t operations: { button_delete: button_delete }\n\t });\n\t portlet.append(options.$el);\n\t portlet.$el.addClass('section-row').hide();\n\t this.list[options.id] = portlet;\n\t this.$list.append(portlet.$el.fadeIn('fast'));\n\t this.options.max > 0 && this.size() >= this.options.max && this.button_new.disable();\n\t this._refresh();\n\t },\n\t\n\t /** Delete repeat block */\n\t del: function (id) {\n\t if (!this.list[id]) {\n\t Galaxy.emit.debug('form-repeat::del()', 'Invalid repeat block id.');\n\t return;\n\t }\n\t this.$list.find('#' + id).remove();\n\t delete this.list[id];\n\t this.button_new.enable();\n\t this._refresh();\n\t },\n\t\n\t /** Remove all */\n\t delAll: function () {\n\t for (var id in this.list) {\n\t this.del(id);\n\t }\n\t },\n\t\n\t /** Hides add/del options */\n\t hideOptions: function () {\n\t this.button_new.$el.hide();\n\t _.each(this.list, function (portlet) {\n\t portlet.hideOperation('button_delete');\n\t });\n\t _.isEmpty(this.list) && this.$el.append($('
    ').addClass('ui-form-info').html(this.options.empty_text));\n\t },\n\t\n\t /** Refresh view */\n\t _refresh: function () {\n\t var index = 0;\n\t for (var id in this.list) {\n\t var portlet = this.list[id];\n\t portlet.title(++index + ': ' + this.options.title);\n\t portlet[this.size() > this.options.min ? 'showOperation' : 'hideOperation']('button_delete');\n\t }\n\t }\n\t });\n\t\n\t return {\n\t View: View\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(1), __webpack_require__(2)))\n\n/***/ },\n/* 53 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, $, _, jQuery) {/**\n\t This class creates a form section and populates it with input elements. It also handles repeat blocks and conditionals by recursively creating new sub sections.\n\t*/\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(4), __webpack_require__(7), __webpack_require__(10), __webpack_require__(52), __webpack_require__(50), __webpack_require__(51)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Utils, Ui, Portlet, Repeat, InputElement, Parameters) {\n\t var View = Backbone.View.extend({\n\t initialize: function (app, options) {\n\t this.app = app;\n\t this.inputs = options.inputs;\n\t this.parameters = new Parameters();\n\t this.setElement($('
    '));\n\t this.render();\n\t },\n\t\n\t /** Render section view */\n\t render: function () {\n\t var self = this;\n\t this.$el.empty();\n\t _.each(this.inputs, function (input) {\n\t self.add(input);\n\t });\n\t },\n\t\n\t /** Add a new input element */\n\t add: function (input) {\n\t var input_def = jQuery.extend(true, {}, input);\n\t input_def.id = input.id = Utils.uid();\n\t this.app.input_list[input_def.id] = input_def;\n\t switch (input_def.type) {\n\t case 'conditional':\n\t this._addConditional(input_def);\n\t break;\n\t case 'repeat':\n\t this._addRepeat(input_def);\n\t break;\n\t case 'section':\n\t this._addSection(input_def);\n\t break;\n\t default:\n\t this._addRow(input_def);\n\t }\n\t },\n\t\n\t /** Add a conditional block */\n\t _addConditional: function (input_def) {\n\t var self = this;\n\t input_def.test_param.id = input_def.id;\n\t this.app.model.get('sustain_conditionals') && (input_def.test_param.disabled = true);\n\t var field = this._addRow(input_def.test_param);\n\t\n\t // set onchange event for test parameter\n\t field.model && field.model.set('onchange', function (value) {\n\t var selectedCase = self.app.data.matchCase(input_def, value);\n\t for (var i in input_def.cases) {\n\t var case_def = input_def.cases[i];\n\t var section_row = self.$('#' + input_def.id + '-section-' + i);\n\t var nonhidden = false;\n\t for (var j in case_def.inputs) {\n\t if (!case_def.inputs[j].hidden) {\n\t nonhidden = true;\n\t break;\n\t }\n\t }\n\t if (i == selectedCase && nonhidden) {\n\t section_row.fadeIn('fast');\n\t } else {\n\t section_row.hide();\n\t }\n\t }\n\t self.app.trigger('change');\n\t });\n\t\n\t // add conditional sub sections\n\t for (var i in input_def.cases) {\n\t var sub_section = new View(this.app, { inputs: input_def.cases[i].inputs });\n\t this._append(sub_section.$el.addClass('ui-form-section'), input_def.id + '-section-' + i);\n\t }\n\t\n\t // trigger refresh on conditional input field after all input elements have been created\n\t field.trigger('change');\n\t },\n\t\n\t /** Add a repeat block */\n\t _addRepeat: function (input_def) {\n\t var self = this;\n\t var block_index = 0;\n\t\n\t // create repeat block element\n\t var repeat = new Repeat.View({\n\t title: input_def.title || 'Repeat',\n\t min: input_def.min,\n\t max: input_def.max,\n\t onnew: function () {\n\t create(input_def.inputs);self.app.trigger('change');\n\t }\n\t });\n\t\n\t // helper function to create new repeat blocks\n\t function create(inputs) {\n\t var sub_section_id = input_def.id + '-section-' + block_index++;\n\t var sub_section = new View(self.app, { inputs: inputs });\n\t repeat.add({ id: sub_section_id,\n\t $el: sub_section.$el,\n\t ondel: function () {\n\t repeat.del(sub_section_id);self.app.trigger('change');\n\t } });\n\t }\n\t\n\t //\n\t // add parsed/minimum number of repeat blocks\n\t //\n\t var n_cache = _.size(input_def.cache);\n\t for (var i = 0; i < Math.max(Math.max(n_cache, input_def.min || 0), input_def.default || 0); i++) {\n\t create(i < n_cache ? input_def.cache[i] : input_def.inputs);\n\t }\n\t\n\t // hide options\n\t this.app.model.get('sustain_repeats') && repeat.hideOptions();\n\t\n\t // create input field wrapper\n\t var input_element = new InputElement(this.app, {\n\t label: input_def.title || input_def.name,\n\t help: input_def.help,\n\t field: repeat\n\t });\n\t this._append(input_element.$el, input_def.id);\n\t },\n\t\n\t /** Add a customized section */\n\t _addSection: function (input_def) {\n\t var portlet = new Portlet.View({\n\t title: input_def.title || input_def.name,\n\t cls: 'ui-portlet-section',\n\t collapsible: true,\n\t collapsible_button: true,\n\t collapsed: !input_def.expanded\n\t });\n\t portlet.append(new View(this.app, { inputs: input_def.inputs }).$el);\n\t portlet.append($('
    ').addClass('ui-form-info').html(input_def.help));\n\t this.app.on('expand', function (input_id) {\n\t portlet.$('#' + input_id).length > 0 && portlet.expand();\n\t });\n\t this._append(portlet.$el, input_def.id);\n\t },\n\t\n\t /** Add a single input field element */\n\t _addRow: function (input_def) {\n\t var self = this;\n\t var id = input_def.id;\n\t input_def.onchange = input_def.onchange || function () {\n\t self.app.trigger('change', id);\n\t };\n\t var field = this.parameters.create(input_def);\n\t this.app.field_list[id] = field;\n\t var input_element = new InputElement(this.app, {\n\t name: input_def.name,\n\t label: input_def.hide_label ? '' : input_def.label || input_def.name,\n\t value: input_def.value,\n\t text_value: input_def.text_value,\n\t collapsible_value: input_def.collapsible_value,\n\t collapsible_preview: input_def.collapsible_preview,\n\t help: input_def.help,\n\t argument: input_def.argument,\n\t disabled: input_def.disabled,\n\t color: input_def.color,\n\t style: input_def.style,\n\t backdrop: input_def.backdrop,\n\t hidden: input_def.hidden,\n\t fixed: input_def.fixed,\n\t field: field\n\t });\n\t this.app.element_list[id] = input_element;\n\t this._append(input_element.$el, input_def.id);\n\t return field;\n\t },\n\t\n\t /** Append a new element to the form i.e. input element, repeat block, conditionals etc. */\n\t _append: function ($el, id) {\n\t this.$el.append($el.addClass('section-row').attr('id', id));\n\t }\n\t });\n\t\n\t return {\n\t View: View\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(1), __webpack_require__(2), __webpack_require__(1)))\n\n/***/ },\n/* 54 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(_) {!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(47), __webpack_require__(87), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (DC_MODEL, HISTORY_CONTENT, _l) {\n\t\n\t 'use strict';\n\t\n\t /*==============================================================================\n\t \n\t Models for DatasetCollections contained within a history.\n\t \n\t TODO:\n\t these might be compactable to one class if some duplication with\n\t collection-model is used.\n\t \n\t ==============================================================================*/\n\t\n\t var hcontentMixin = HISTORY_CONTENT.HistoryContentMixin,\n\t ListDC = DC_MODEL.ListDatasetCollection,\n\t PairDC = DC_MODEL.PairDatasetCollection,\n\t ListPairedDC = DC_MODEL.ListPairedDatasetCollection,\n\t ListOfListsDC = DC_MODEL.ListOfListsDatasetCollection;\n\t\n\t //==============================================================================\n\t /** Override to post to contents route w/o id. */\n\t function buildHDCASave(_super) {\n\t return function _save(attributes, options) {\n\t if (this.isNew()) {\n\t options = options || {};\n\t options.url = this.urlRoot + this.get('history_id') + '/contents';\n\t attributes = attributes || {};\n\t attributes.type = 'dataset_collection';\n\t }\n\t return _super.call(this, attributes, options);\n\t };\n\t }\n\t\n\t //==============================================================================\n\t /** @class Backbone model for List Dataset Collection within a History.\n\t */\n\t var HistoryListDatasetCollection = ListDC.extend(hcontentMixin).extend(\n\t /** @lends HistoryListDatasetCollection.prototype */{\n\t\n\t defaults: _.extend(_.clone(ListDC.prototype.defaults), {\n\t history_content_type: 'dataset_collection',\n\t collection_type: 'list',\n\t model_class: 'HistoryDatasetCollectionAssociation'\n\t }),\n\t\n\t /** Override to post to contents route w/o id. */\n\t save: buildHDCASave(ListDC.prototype.save),\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return 'History' + ListDC.prototype.toString.call(this);\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** @class Backbone model for Pair Dataset Collection within a History.\n\t * @constructs\n\t */\n\t var HistoryPairDatasetCollection = PairDC.extend(hcontentMixin).extend(\n\t /** @lends HistoryPairDatasetCollection.prototype */{\n\t\n\t defaults: _.extend(_.clone(PairDC.prototype.defaults), {\n\t history_content_type: 'dataset_collection',\n\t collection_type: 'paired',\n\t model_class: 'HistoryDatasetCollectionAssociation'\n\t }),\n\t\n\t /** Override to post to contents route w/o id. */\n\t save: buildHDCASave(PairDC.prototype.save),\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return 'History' + PairDC.prototype.toString.call(this);\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** @class Backbone model for List of Pairs Dataset Collection within a History. */\n\t var HistoryListPairedDatasetCollection = ListPairedDC.extend(hcontentMixin).extend({\n\t\n\t defaults: _.extend(_.clone(ListPairedDC.prototype.defaults), {\n\t history_content_type: 'dataset_collection',\n\t collection_type: 'list:paired',\n\t model_class: 'HistoryDatasetCollectionAssociation'\n\t }),\n\t\n\t /** Override to post to contents route w/o id. */\n\t save: buildHDCASave(ListPairedDC.prototype.save),\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return 'History' + ListPairedDC.prototype.toString.call(this);\n\t }\n\t });\n\t\n\t //==============================================================================\n\t /** @class Backbone model for List of Lists Dataset Collection within a History. */\n\t var HistoryListOfListsDatasetCollection = ListOfListsDC.extend(hcontentMixin).extend({\n\t\n\t defaults: _.extend(_.clone(ListOfListsDC.prototype.defaults), {\n\t history_content_type: 'dataset_collection',\n\t collection_type: 'list:list',\n\t model_class: 'HistoryDatasetCollectionAssociation'\n\t }),\n\t\n\t /** Override to post to contents route w/o id. */\n\t save: buildHDCASave(ListOfListsDC.prototype.save),\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return ['HistoryListOfListsDatasetCollection(', this.get('name'), ')'].join('');\n\t }\n\t });\n\t\n\t //==============================================================================\n\t return {\n\t HistoryListDatasetCollection: HistoryListDatasetCollection,\n\t HistoryPairDatasetCollection: HistoryPairDatasetCollection,\n\t HistoryListPairedDatasetCollection: HistoryListPairedDatasetCollection,\n\t HistoryListOfListsDatasetCollection: HistoryListOfListsDatasetCollection\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2)))\n\n/***/ },\n/* 55 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(_, jQuery, Backbone) {!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(78), __webpack_require__(85), __webpack_require__(54), __webpack_require__(57), __webpack_require__(6), __webpack_require__(148)], __WEBPACK_AMD_DEFINE_RESULT__ = function (CONTROLLED_FETCH_COLLECTION, HDA_MODEL, HDCA_MODEL, HISTORY_PREFS, BASE_MVC, AJAX_QUEUE) {\n\t 'use strict';\n\t\n\t //==============================================================================\n\t\n\t var _super = CONTROLLED_FETCH_COLLECTION.PaginatedCollection;\n\t /** @class Backbone collection for history content.\n\t * NOTE: history content seems like a dataset collection, but differs in that it is mixed:\n\t * each element can be either an HDA (dataset) or a DatasetCollection and co-exist on\n\t * the same level.\n\t * Dataset collections on the other hand are not mixed and (so far) can only contain either\n\t * HDAs or child dataset collections on one level.\n\t * This is why this does not inherit from any of the DatasetCollections (currently).\n\t */\n\t var HistoryContents = _super.extend(BASE_MVC.LoggableMixin).extend({\n\t _logNamespace: 'history',\n\t\n\t // ........................................................................ composite collection\n\t /** since history content is a mix, override model fn into a factory, creating based on history_content_type */\n\t model: function (attrs, options) {\n\t if (attrs.history_content_type === \"dataset\") {\n\t return new HDA_MODEL.HistoryDatasetAssociation(attrs, options);\n\t } else if (attrs.history_content_type === \"dataset_collection\") {\n\t switch (attrs.collection_type) {\n\t case 'list':\n\t return new HDCA_MODEL.HistoryListDatasetCollection(attrs, options);\n\t case 'paired':\n\t return new HDCA_MODEL.HistoryPairDatasetCollection(attrs, options);\n\t case 'list:paired':\n\t return new HDCA_MODEL.HistoryListPairedDatasetCollection(attrs, options);\n\t case 'list:list':\n\t return new HDCA_MODEL.HistoryListOfListsDatasetCollection(attrs, options);\n\t }\n\t // This is a hack inside a hack:\n\t // Raise a plain object with validationError to fake a model.validationError\n\t // (since we don't have a model to use validate with)\n\t // (the outer hack being the mixed content/model function in this collection)\n\t var msg = 'Unknown collection_type: ' + attrs.collection_type;\n\t console.warn(msg, attrs);\n\t return { validationError: msg };\n\t }\n\t return { validationError: 'Unknown history_content_type: ' + attrs.history_content_type };\n\t },\n\t\n\t // ........................................................................ set up\n\t limitPerPage: 500,\n\t\n\t /** @type {Integer} how many contents per call to fetch when using progressivelyFetchDetails */\n\t limitPerProgressiveFetch: 500,\n\t\n\t /** @type {String} order used here and when fetching from server */\n\t order: 'hid',\n\t\n\t /** root api url */\n\t urlRoot: Galaxy.root + 'api/histories',\n\t\n\t /** complete api url */\n\t url: function () {\n\t return this.urlRoot + '/' + this.historyId + '/contents';\n\t },\n\t\n\t /** Set up */\n\t initialize: function (models, options) {\n\t options = options || {};\n\t _super.prototype.initialize.call(this, models, options);\n\t\n\t this.history = options.history || null;\n\t this.setHistoryId(options.historyId || null);\n\t /** @type {Boolean} does this collection contain and fetch deleted elements */\n\t this.includeDeleted = options.includeDeleted || this.includeDeleted;\n\t /** @type {Boolean} does this collection contain and fetch non-visible elements */\n\t this.includeHidden = options.includeHidden || this.includeHidden;\n\t\n\t // backbonejs uses collection.model.prototype.idAttribute to determine if a model is *already* in a collection\n\t // and either merged or replaced. In this case, our 'model' is a function so we need to add idAttribute\n\t // manually here - if we don't, contents will not merge but be replaced/swapped.\n\t this.model.prototype.idAttribute = 'type_id';\n\t },\n\t\n\t setHistoryId: function (newId) {\n\t this.historyId = newId;\n\t this._setUpWebStorage();\n\t },\n\t\n\t /** Set up client side storage. Currently PersistanStorage keyed under 'history:' */\n\t _setUpWebStorage: function (initialSettings) {\n\t // TODO: use initialSettings\n\t if (!this.historyId) {\n\t return;\n\t }\n\t this.storage = new HISTORY_PREFS.HistoryPrefs({\n\t id: HISTORY_PREFS.HistoryPrefs.historyStorageKey(this.historyId)\n\t });\n\t this.trigger('new-storage', this.storage, this);\n\t\n\t this.on({\n\t 'include-deleted': function (newVal) {\n\t this.storage.includeDeleted(newVal);\n\t },\n\t 'include-hidden': function (newVal) {\n\t this.storage.includeHidden(newVal);\n\t }\n\t });\n\t\n\t this.includeDeleted = this.storage.includeDeleted() || false;\n\t this.includeHidden = this.storage.includeHidden() || false;\n\t return this;\n\t },\n\t\n\t // ........................................................................ common queries\n\t /** @type {Object} map of collection available sorting orders containing comparator fns */\n\t comparators: _.extend(_.clone(_super.prototype.comparators), {\n\t 'name': BASE_MVC.buildComparator('name', { ascending: true }),\n\t 'name-dsc': BASE_MVC.buildComparator('name', { ascending: false }),\n\t 'hid': BASE_MVC.buildComparator('hid', { ascending: false }),\n\t 'hid-asc': BASE_MVC.buildComparator('hid', { ascending: true })\n\t }),\n\t\n\t /** Get every model in this collection not in a 'ready' state (running). */\n\t running: function () {\n\t return this.filter(function (c) {\n\t return !c.inReadyState();\n\t });\n\t },\n\t\n\t /** return contents that are not ready and not deleted/hidden */\n\t runningAndActive: function () {\n\t return this.filter(function (c) {\n\t return !c.inReadyState() && c.get('visible')\n\t // TODO: deletedOrPurged?\n\t && !c.get('deleted');\n\t });\n\t },\n\t\n\t /** Get the model with the given hid\n\t * @param {Int} hid the hid to search for\n\t * @returns {HistoryDatasetAssociation} the model with the given hid or undefined if not found\n\t */\n\t getByHid: function (hid) {\n\t // note: there *can* be more than one content with a given hid, this finds the first based on order\n\t return this.findWhere({ hid: hid });\n\t },\n\t\n\t /** return true if all contents have details */\n\t haveDetails: function () {\n\t return this.all(function (c) {\n\t return c.hasDetails();\n\t });\n\t },\n\t\n\t // ........................................................................ hidden / deleted\n\t /** return a new contents collection of only hidden items */\n\t hidden: function () {\n\t return this.filter(function (c) {\n\t return c.hidden();\n\t });\n\t },\n\t\n\t /** return a new contents collection of only hidden items */\n\t deleted: function () {\n\t return this.filter(function (c) {\n\t return c.get('deleted');\n\t });\n\t },\n\t\n\t /** return a new contents collection of only hidden items */\n\t visibleAndUndeleted: function () {\n\t return this.filter(function (c) {\n\t return c.get('visible') &&\n\t // TODO: deletedOrPurged?\n\t !c.get('deleted');\n\t });\n\t },\n\t\n\t /** create a setter in order to publish the change */\n\t setIncludeDeleted: function (setting, options) {\n\t if (_.isBoolean(setting) && setting !== this.includeDeleted) {\n\t this.includeDeleted = setting;\n\t if (_.result(options, 'silent')) {\n\t return;\n\t }\n\t this.trigger('include-deleted', setting, this);\n\t }\n\t },\n\t\n\t /** create a setter in order to publish the change */\n\t setIncludeHidden: function (setting, options) {\n\t if (_.isBoolean(setting) && setting !== this.includeHidden) {\n\t this.includeHidden = setting;\n\t options = options || {};\n\t if (_.result(options, 'silent')) {\n\t return;\n\t }\n\t this.trigger('include-hidden', setting, this);\n\t }\n\t },\n\t\n\t // ........................................................................ ajax\n\t // ............ controlled fetch collection\n\t /** override to get expanded ids from sessionStorage and pass to API as details */\n\t fetch: function (options) {\n\t options = options || {};\n\t if (this.historyId && !options.details) {\n\t var prefs = HISTORY_PREFS.HistoryPrefs.get(this.historyId).toJSON();\n\t if (!_.isEmpty(prefs.expandedIds)) {\n\t options.details = _.values(prefs.expandedIds).join(',');\n\t }\n\t }\n\t return _super.prototype.fetch.call(this, options);\n\t },\n\t\n\t // ............. ControlledFetch stuff\n\t /** override to include the API versioning flag */\n\t _buildFetchData: function (options) {\n\t return _.extend(_super.prototype._buildFetchData.call(this, options), {\n\t v: 'dev'\n\t });\n\t },\n\t\n\t /** Extend to include details and version */\n\t _fetchParams: _super.prototype._fetchParams.concat([\n\t // TODO: remove (the need for) both\n\t /** version */\n\t 'v',\n\t /** dataset ids to get full details of */\n\t 'details']),\n\t\n\t /** override to add deleted/hidden filters */\n\t _buildFetchFilters: function (options) {\n\t var superFilters = _super.prototype._buildFetchFilters.call(this, options) || {};\n\t var filters = {};\n\t if (!this.includeDeleted) {\n\t filters.deleted = false;\n\t filters.purged = false;\n\t }\n\t if (!this.includeHidden) {\n\t filters.visible = true;\n\t }\n\t return _.defaults(superFilters, filters);\n\t },\n\t\n\t // ............ paginated collection\n\t getTotalItemCount: function () {\n\t return this.history.contentsShown();\n\t },\n\t\n\t // ............ history contents specific ajax\n\t /** override to filter requested contents to those updated after the Date 'since' */\n\t fetchUpdated: function (since, options) {\n\t if (since) {\n\t options = options || { filters: {} };\n\t options.remove = false;\n\t options.filters = {\n\t 'update_time-ge': since.toISOString(),\n\t // workflows will produce hidden datasets (non-output datasets) that still\n\t // need to be updated in the collection or they'll update forever\n\t // we can remove the default visible filter by using an 'empty' value\n\t visible: ''\n\t };\n\t }\n\t return this.fetch(options);\n\t },\n\t\n\t /** fetch all the deleted==true contents of this collection */\n\t fetchDeleted: function (options) {\n\t options = options || {};\n\t var self = this;\n\t options.filters = _.extend(options.filters, {\n\t // all deleted, purged or not\n\t deleted: true,\n\t purged: undefined\n\t });\n\t options.remove = false;\n\t\n\t self.trigger('fetching-deleted', self);\n\t return self.fetch(options).always(function () {\n\t self.trigger('fetching-deleted-done', self);\n\t });\n\t },\n\t\n\t /** fetch all the visible==false contents of this collection */\n\t fetchHidden: function (options) {\n\t options = options || {};\n\t var self = this;\n\t options.filters = _.extend(options.filters, {\n\t visible: false\n\t });\n\t options.remove = false;\n\t\n\t self.trigger('fetching-hidden', self);\n\t return self.fetch(options).always(function () {\n\t self.trigger('fetching-hidden-done', self);\n\t });\n\t },\n\t\n\t /** fetch detailed model data for all contents in this collection */\n\t fetchAllDetails: function (options) {\n\t options = options || {};\n\t var detailsFlag = { details: 'all' };\n\t options.data = _.extend(options.data || {}, detailsFlag);\n\t return this.fetch(options);\n\t },\n\t\n\t /** specialty fetch method for retrieving the element_counts of all hdcas in the history */\n\t fetchCollectionCounts: function (options) {\n\t options = options || {};\n\t options.keys = ['type_id', 'element_count'].join(',');\n\t options.filters = _.extend(options.filters || {}, {\n\t history_content_type: 'dataset_collection'\n\t });\n\t options.remove = false;\n\t return this.fetch(options);\n\t },\n\t\n\t // ............. quasi-batch ops\n\t // TODO: to batch\n\t /** helper that fetches using filterParams then calls save on each fetched using updateWhat as the save params */\n\t _filterAndUpdate: function (filterParams, updateWhat) {\n\t var self = this;\n\t var idAttribute = self.model.prototype.idAttribute;\n\t var updateArgs = [updateWhat];\n\t\n\t return self.fetch({ filters: filterParams, remove: false }).then(function (fetched) {\n\t // convert filtered json array to model array\n\t fetched = fetched.reduce(function (modelArray, currJson, i) {\n\t var model = self.get(currJson[idAttribute]);\n\t return model ? modelArray.concat(model) : modelArray;\n\t }, []);\n\t return self.ajaxQueue('save', updateArgs, fetched);\n\t });\n\t },\n\t\n\t /** using a queue, perform ajaxFn on each of the models in this collection */\n\t ajaxQueue: function (ajaxFn, args, collection) {\n\t collection = collection || this.models;\n\t return new AJAX_QUEUE.AjaxQueue(collection.slice().reverse().map(function (content, i) {\n\t var fn = _.isString(ajaxFn) ? content[ajaxFn] : ajaxFn;\n\t return function () {\n\t return fn.apply(content, args);\n\t };\n\t })).deferred;\n\t },\n\t\n\t /** fetch contents' details in batches of limitPerCall - note: only get searchable details here */\n\t progressivelyFetchDetails: function (options) {\n\t options = options || {};\n\t var deferred = jQuery.Deferred();\n\t var self = this;\n\t var limit = options.limitPerCall || self.limitPerProgressiveFetch;\n\t // TODO: only fetch tags and annotations if specifically requested\n\t var searchAttributes = HDA_MODEL.HistoryDatasetAssociation.prototype.searchAttributes;\n\t var detailKeys = searchAttributes.join(',');\n\t\n\t function _recursivelyFetch(offset) {\n\t offset = offset || 0;\n\t var _options = _.extend(_.clone(options), {\n\t view: 'summary',\n\t keys: detailKeys,\n\t limit: limit,\n\t offset: offset,\n\t reset: offset === 0,\n\t remove: false\n\t });\n\t\n\t _.defer(function () {\n\t self.fetch.call(self, _options).fail(deferred.reject).done(function (response) {\n\t deferred.notify(response, limit, offset);\n\t if (response.length !== limit) {\n\t self.allFetched = true;\n\t deferred.resolve(response, limit, offset);\n\t } else {\n\t _recursivelyFetch(offset + limit);\n\t }\n\t });\n\t });\n\t }\n\t _recursivelyFetch();\n\t return deferred;\n\t },\n\t\n\t /** does some bit of JSON represent something that can be copied into this contents collection */\n\t isCopyable: function (contentsJSON) {\n\t var copyableModelClasses = ['HistoryDatasetAssociation', 'HistoryDatasetCollectionAssociation'];\n\t return _.isObject(contentsJSON) && contentsJSON.id && _.contains(copyableModelClasses, contentsJSON.model_class);\n\t },\n\t\n\t /** copy an existing, accessible hda into this collection */\n\t copy: function (json) {\n\t // TODO: somehow showhorn all this into 'save'\n\t var id, type, contentType;\n\t if (_.isString(json)) {\n\t id = json;\n\t contentType = 'hda';\n\t type = 'dataset';\n\t } else {\n\t id = json.id;\n\t contentType = {\n\t 'HistoryDatasetAssociation': 'hda',\n\t 'LibraryDatasetDatasetAssociation': 'ldda',\n\t 'HistoryDatasetCollectionAssociation': 'hdca'\n\t }[json.model_class] || 'hda';\n\t type = contentType === 'hdca' ? 'dataset_collection' : 'dataset';\n\t }\n\t var collection = this,\n\t xhr = jQuery.ajax(this.url(), {\n\t method: 'POST',\n\t contentType: 'application/json',\n\t data: JSON.stringify({\n\t content: id,\n\t source: contentType,\n\t type: type\n\t })\n\t }).done(function (response) {\n\t collection.add([response], { parse: true });\n\t }).fail(function (error, status, message) {\n\t collection.trigger('error', collection, xhr, {}, 'Error copying contents', { type: type, id: id, source: contentType });\n\t });\n\t return xhr;\n\t },\n\t\n\t /** create a new HDCA in this collection */\n\t createHDCA: function (elementIdentifiers, collectionType, name, hideSourceItems, options) {\n\t // normally collection.create returns the new model, but we need the promise from the ajax, so we fake create\n\t //precondition: elementIdentifiers is an array of plain js objects\n\t // in the proper form to create the collectionType\n\t var hdca = this.model({\n\t history_content_type: 'dataset_collection',\n\t collection_type: collectionType,\n\t history_id: this.historyId,\n\t name: name,\n\t hide_source_items: hideSourceItems || false,\n\t // should probably be able to just send in a bunch of json here and restruct per class\n\t // note: element_identifiers is now (incorrectly) an attribute\n\t element_identifiers: elementIdentifiers\n\t // do not create the model on the client until the ajax returns\n\t });\n\t return hdca.save(options);\n\t },\n\t\n\t // ........................................................................ searching\n\t /** return true if all contents have the searchable attributes */\n\t haveSearchDetails: function () {\n\t return this.allFetched && this.all(function (content) {\n\t // null (which is a valid returned annotation value)\n\t // will return false when using content.has( 'annotation' )\n\t //TODO: a bit hacky - formalize\n\t return _.has(content.attributes, 'annotation');\n\t });\n\t },\n\t\n\t /** return a new collection of contents whose attributes contain the substring matchesWhat */\n\t matches: function (matchesWhat) {\n\t return this.filter(function (content) {\n\t return content.matches(matchesWhat);\n\t });\n\t },\n\t\n\t // ........................................................................ misc\n\t /** In this override, copy the historyId to the clone */\n\t clone: function () {\n\t var clone = Backbone.Collection.prototype.clone.call(this);\n\t clone.historyId = this.historyId;\n\t return clone;\n\t },\n\t\n\t /** String representation. */\n\t toString: function () {\n\t return ['HistoryContents(', [this.historyId, this.length].join(), ')'].join('');\n\t }\n\t });\n\t\n\t //==============================================================================\n\t return {\n\t HistoryContents: HistoryContents\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2), __webpack_require__(1), __webpack_require__(3)))\n\n/***/ },\n/* 56 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, jQuery, _, $) {\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(55), __webpack_require__(57), __webpack_require__(78), __webpack_require__(4), __webpack_require__(6), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (HISTORY_CONTENTS, HISTORY_PREFS, CONTROLLED_FETCH_COLLECTION, UTILS, BASE_MVC, _l) {\n\t 'use strict';\n\t\n\t //==============================================================================\n\t /** @class Model for a Galaxy history resource - both a record of user\n\t * tool use and a collection of the datasets those tools produced.\n\t * @name History\n\t * @augments Backbone.Model\n\t */\n\t\n\t var History = Backbone.Model.extend(BASE_MVC.LoggableMixin).extend(BASE_MVC.mixin(BASE_MVC.SearchableModelMixin, /** @lends History.prototype */{\n\t _logNamespace: 'history',\n\t\n\t /** ms between fetches when checking running jobs/datasets for updates */\n\t UPDATE_DELAY: 4000,\n\t\n\t // values from api (may need more)\n\t defaults: {\n\t model_class: 'History',\n\t id: null,\n\t name: 'Unnamed History',\n\t state: 'new',\n\t\n\t deleted: false,\n\t contents_active: {},\n\t contents_states: {}\n\t },\n\t\n\t urlRoot: Galaxy.root + 'api/histories',\n\t\n\t contentsClass: HISTORY_CONTENTS.HistoryContents,\n\t\n\t /** What model fields to search with */\n\t searchAttributes: ['name', 'annotation', 'tags'],\n\t\n\t /** Adding title and singular tag */\n\t searchAliases: {\n\t title: 'name',\n\t tag: 'tags'\n\t },\n\t\n\t // ........................................................................ set up/tear down\n\t /** Set up the model\n\t * @param {Object} historyJSON model data for this History\n\t * @param {Object} options any extra settings including logger\n\t */\n\t initialize: function (historyJSON, options) {\n\t options = options || {};\n\t this.logger = options.logger || null;\n\t this.log(this + \".initialize:\", historyJSON, options);\n\t\n\t /** HistoryContents collection of the HDAs contained in this history. */\n\t this.contents = new this.contentsClass([], {\n\t history: this,\n\t historyId: this.get('id'),\n\t order: options.order\n\t });\n\t\n\t this._setUpListeners();\n\t this._setUpCollectionListeners();\n\t\n\t /** cached timeout id for the dataset updater */\n\t this.updateTimeoutId = null;\n\t },\n\t\n\t /** set up any event listeners for this history including those to the contained HDAs\n\t * events: error:contents if an error occurred with the contents collection\n\t */\n\t _setUpListeners: function () {\n\t // if the model's id changes ('current' or null -> an actual id), update the contents history_id\n\t return this.on({\n\t 'error': function (model, xhr, options, msg, details) {\n\t this.clearUpdateTimeout();\n\t },\n\t 'change:id': function (model, newId) {\n\t if (this.contents) {\n\t this.contents.historyId = newId;\n\t }\n\t }\n\t });\n\t },\n\t\n\t /** event handlers for the contents submodels */\n\t _setUpCollectionListeners: function () {\n\t if (!this.contents) {\n\t return this;\n\t }\n\t // bubble up errors\n\t return this.listenTo(this.contents, {\n\t 'error': function () {\n\t this.trigger.apply(this, jQuery.makeArray(arguments));\n\t }\n\t });\n\t },\n\t\n\t // ........................................................................ derived attributes\n\t /** */\n\t contentsShown: function () {\n\t var contentsActive = this.get('contents_active');\n\t var shown = contentsActive.active || 0;\n\t shown += this.contents.includeDeleted ? contentsActive.deleted : 0;\n\t shown += this.contents.includeHidden ? contentsActive.hidden : 0;\n\t return shown;\n\t },\n\t\n\t /** convert size in bytes to a more human readable version */\n\t nice_size: function () {\n\t var size = this.get('size');\n\t return size ? UTILS.bytesToString(size, true, 2) : _l('(empty)');\n\t },\n\t\n\t /** override to add nice_size */\n\t toJSON: function () {\n\t return _.extend(Backbone.Model.prototype.toJSON.call(this), {\n\t nice_size: this.nice_size()\n\t });\n\t },\n\t\n\t /** override to allow getting nice_size */\n\t get: function (key) {\n\t if (key === 'nice_size') {\n\t return this.nice_size();\n\t }\n\t return Backbone.Model.prototype.get.apply(this, arguments);\n\t },\n\t\n\t // ........................................................................ common queries\n\t /** T/F is this history owned by the current user (Galaxy.user)\n\t * Note: that this will return false for an anon user even if the history is theirs.\n\t */\n\t ownedByCurrUser: function () {\n\t // no currUser\n\t if (!Galaxy || !Galaxy.user) {\n\t return false;\n\t }\n\t // user is anon or history isn't owned\n\t if (Galaxy.user.isAnonymous() || Galaxy.user.id !== this.get('user_id')) {\n\t return false;\n\t }\n\t return true;\n\t },\n\t\n\t /** Return the number of running jobs assoc with this history (note: unknown === 0) */\n\t numOfUnfinishedJobs: function () {\n\t var unfinishedJobIds = this.get('non_ready_jobs');\n\t return unfinishedJobIds ? unfinishedJobIds.length : 0;\n\t },\n\t\n\t /** Return the number of running hda/hdcas in this history (note: unknown === 0) */\n\t numOfUnfinishedShownContents: function () {\n\t return this.contents.runningAndActive().length || 0;\n\t },\n\t\n\t // ........................................................................ updates\n\t _fetchContentRelatedAttributes: function () {\n\t var contentRelatedAttrs = ['size', 'non_ready_jobs', 'contents_active', 'hid_counter'];\n\t return this.fetch({ data: $.param({ keys: contentRelatedAttrs.join(',') }) });\n\t },\n\t\n\t /** check for any changes since the last time we updated (or fetch all if ) */\n\t refresh: function (options) {\n\t // console.log( this + '.refresh' );\n\t options = options || {};\n\t var self = this;\n\t\n\t // note if there was no previous update time, all summary contents will be fetched\n\t var lastUpdateTime = self.lastUpdateTime;\n\t // if we don't flip this, then a fully-fetched list will not be re-checked via fetch\n\t this.contents.allFetched = false;\n\t var fetchFn = self.contents.currentPage !== 0 ? function () {\n\t return self.contents.fetchPage(self.contents.currentPage);\n\t } : function () {\n\t return self.contents.fetchUpdated(lastUpdateTime);\n\t };\n\t // note: if there was no previous update time, all summary contents will be fetched\n\t return fetchFn().done(function (response, status, xhr) {\n\t var serverResponseDatetime;\n\t try {\n\t serverResponseDatetime = new Date(xhr.getResponseHeader('Date'));\n\t } catch (err) {}\n\t self.lastUpdateTime = serverResponseDatetime || new Date();\n\t self.checkForUpdates(options);\n\t });\n\t },\n\t\n\t /** continuously fetch updated contents every UPDATE_DELAY ms if this history's datasets or jobs are unfinished */\n\t checkForUpdates: function (options) {\n\t // console.log( this + '.checkForUpdates' );\n\t options = options || {};\n\t var delay = this.UPDATE_DELAY;\n\t var self = this;\n\t if (!self.id) {\n\t return;\n\t }\n\t\n\t function _delayThenUpdate() {\n\t // prevent buildup of updater timeouts by clearing previous if any, then set new and cache id\n\t self.clearUpdateTimeout();\n\t self.updateTimeoutId = setTimeout(function () {\n\t self.refresh(options);\n\t }, delay);\n\t }\n\t\n\t // if there are still datasets in the non-ready state, recurse into this function with the new time\n\t var nonReadyContentCount = this.numOfUnfinishedShownContents();\n\t // console.log( 'nonReadyContentCount:', nonReadyContentCount );\n\t if (nonReadyContentCount > 0) {\n\t _delayThenUpdate();\n\t } else {\n\t // no datasets are running, but currently runnning jobs may still produce new datasets\n\t // see if the history has any running jobs and continue to update if so\n\t // (also update the size for the user in either case)\n\t self._fetchContentRelatedAttributes().done(function (historyData) {\n\t // console.log( 'non_ready_jobs:', historyData.non_ready_jobs );\n\t if (self.numOfUnfinishedJobs() > 0) {\n\t _delayThenUpdate();\n\t } else {\n\t // otherwise, let listeners know that all updates have stopped\n\t self.trigger('ready');\n\t }\n\t });\n\t }\n\t },\n\t\n\t /** clear the timeout and the cached timeout id */\n\t clearUpdateTimeout: function () {\n\t if (this.updateTimeoutId) {\n\t clearTimeout(this.updateTimeoutId);\n\t this.updateTimeoutId = null;\n\t }\n\t },\n\t\n\t // ........................................................................ ajax\n\t /** override to use actual Dates objects for create/update times */\n\t parse: function (response, options) {\n\t var parsed = Backbone.Model.prototype.parse.call(this, response, options);\n\t if (parsed.create_time) {\n\t parsed.create_time = new Date(parsed.create_time);\n\t }\n\t if (parsed.update_time) {\n\t parsed.update_time = new Date(parsed.update_time);\n\t }\n\t return parsed;\n\t },\n\t\n\t /** fetch this histories data (using options) then it's contents (using contentsOptions) */\n\t fetchWithContents: function (options, contentsOptions) {\n\t options = options || {};\n\t var self = this;\n\t\n\t // console.log( this + '.fetchWithContents' );\n\t // TODO: push down to a base class\n\t options.view = 'dev-detailed';\n\t\n\t // fetch history then use history data to fetch (paginated) contents\n\t return this.fetch(options).then(function getContents(history) {\n\t self.contents.history = self;\n\t self.contents.setHistoryId(history.id);\n\t return self.fetchContents(contentsOptions);\n\t });\n\t },\n\t\n\t /** fetch this histories contents, adjusting options based on the stored history preferences */\n\t fetchContents: function (options) {\n\t options = options || {};\n\t var self = this;\n\t\n\t // we're updating, reset the update time\n\t self.lastUpdateTime = new Date();\n\t return self.contents.fetchCurrentPage(options);\n\t },\n\t\n\t /** save this history, _Mark_ing it as deleted (just a flag) */\n\t _delete: function (options) {\n\t if (this.get('deleted')) {\n\t return jQuery.when();\n\t }\n\t return this.save({ deleted: true }, options);\n\t },\n\t /** purge this history, _Mark_ing it as purged and removing all dataset data from the server */\n\t purge: function (options) {\n\t if (this.get('purged')) {\n\t return jQuery.when();\n\t }\n\t return this.save({ deleted: true, purged: true }, options);\n\t },\n\t /** save this history, _Mark_ing it as undeleted */\n\t undelete: function (options) {\n\t if (!this.get('deleted')) {\n\t return jQuery.when();\n\t }\n\t return this.save({ deleted: false }, options);\n\t },\n\t\n\t /** Make a copy of this history on the server\n\t * @param {Boolean} current if true, set the copy as the new current history (default: true)\n\t * @param {String} name name of new history (default: none - server sets to: Copy of )\n\t * @fires copied passed this history and the response JSON from the copy\n\t * @returns {xhr}\n\t */\n\t copy: function (current, name, allDatasets) {\n\t current = current !== undefined ? current : true;\n\t if (!this.id) {\n\t throw new Error('You must set the history ID before copying it.');\n\t }\n\t\n\t var postData = { history_id: this.id };\n\t if (current) {\n\t postData.current = true;\n\t }\n\t if (name) {\n\t postData.name = name;\n\t }\n\t if (!allDatasets) {\n\t postData.all_datasets = false;\n\t }\n\t postData.view = 'dev-detailed';\n\t\n\t var history = this;\n\t var copy = jQuery.post(this.urlRoot, postData);\n\t // if current - queue to setAsCurrent before firing 'copied'\n\t if (current) {\n\t return copy.then(function (response) {\n\t var newHistory = new History(response);\n\t return newHistory.setAsCurrent().done(function () {\n\t history.trigger('copied', history, response);\n\t });\n\t });\n\t }\n\t return copy.done(function (response) {\n\t history.trigger('copied', history, response);\n\t });\n\t },\n\t\n\t setAsCurrent: function () {\n\t var history = this,\n\t xhr = jQuery.getJSON(Galaxy.root + 'history/set_as_current?id=' + this.id);\n\t\n\t xhr.done(function () {\n\t history.trigger('set-as-current', history);\n\t });\n\t return xhr;\n\t },\n\t\n\t // ........................................................................ misc\n\t toString: function () {\n\t return 'History(' + this.get('id') + ',' + this.get('name') + ')';\n\t }\n\t }));\n\t\n\t //==============================================================================\n\t var _collectionSuper = CONTROLLED_FETCH_COLLECTION.InfinitelyScrollingCollection;\n\t /** @class A collection of histories (per user)\n\t * that maintains the current history as the first in the collection.\n\t * New or copied histories become the current history.\n\t */\n\t var HistoryCollection = _collectionSuper.extend(BASE_MVC.LoggableMixin).extend({\n\t _logNamespace: 'history',\n\t\n\t model: History,\n\t /** @type {String} initial order used by collection */\n\t order: 'update_time',\n\t /** @type {Number} limit used for the first fetch (or a reset) */\n\t limitOnFirstFetch: 10,\n\t /** @type {Number} limit used for each subsequent fetch */\n\t limitPerFetch: 10,\n\t\n\t initialize: function (models, options) {\n\t options = options || {};\n\t this.log('HistoryCollection.initialize', models, options);\n\t _collectionSuper.prototype.initialize.call(this, models, options);\n\t\n\t /** @type {boolean} should deleted histories be included */\n\t this.includeDeleted = options.includeDeleted || false;\n\t\n\t /** @type {String} encoded id of the history that's current */\n\t this.currentHistoryId = options.currentHistoryId;\n\t\n\t this.setUpListeners();\n\t // note: models are sent to reset *after* this fn ends; up to this point\n\t // the collection *is empty*\n\t },\n\t\n\t urlRoot: Galaxy.root + 'api/histories',\n\t url: function () {\n\t return this.urlRoot;\n\t },\n\t\n\t /** set up reflexive event handlers */\n\t setUpListeners: function setUpListeners() {\n\t return this.on({\n\t // when a history is deleted, remove it from the collection (if optionally set to do so)\n\t 'change:deleted': function (history) {\n\t // TODO: this becomes complicated when more filters are used\n\t this.debug('change:deleted', this.includeDeleted, history.get('deleted'));\n\t if (!this.includeDeleted && history.get('deleted')) {\n\t this.remove(history);\n\t }\n\t },\n\t // listen for a history copy, setting it to current\n\t 'copied': function (original, newData) {\n\t this.setCurrent(new History(newData, []));\n\t },\n\t // when a history is made current, track the id in the collection\n\t 'set-as-current': function (history) {\n\t var oldCurrentId = this.currentHistoryId;\n\t this.trigger('no-longer-current', oldCurrentId);\n\t this.currentHistoryId = history.id;\n\t }\n\t });\n\t },\n\t\n\t /** override to change view */\n\t _buildFetchData: function (options) {\n\t return _.extend(_collectionSuper.prototype._buildFetchData.call(this, options), {\n\t view: 'dev-detailed'\n\t });\n\t },\n\t\n\t /** override to filter out deleted and purged */\n\t _buildFetchFilters: function (options) {\n\t var superFilters = _collectionSuper.prototype._buildFetchFilters.call(this, options) || {};\n\t var filters = {};\n\t if (!this.includeDeleted) {\n\t filters.deleted = false;\n\t filters.purged = false;\n\t } else {\n\t // force API to return both deleted and non\n\t //TODO: when the API is updated, remove this\n\t filters.deleted = null;\n\t }\n\t return _.defaults(superFilters, filters);\n\t },\n\t\n\t /** override to fetch current as well (as it may be outside the first 10, etc.) */\n\t fetchFirst: function (options) {\n\t var self = this;\n\t // TODO: batch?\n\t var xhr = $.when();\n\t if (this.currentHistoryId) {\n\t xhr = _collectionSuper.prototype.fetchFirst.call(self, {\n\t silent: true,\n\t limit: 1,\n\t filters: {\n\t // without these a deleted current history will return [] here and block the other xhr\n\t 'purged': '',\n\t 'deleted': '',\n\t 'encoded_id-in': this.currentHistoryId\n\t }\n\t });\n\t }\n\t return xhr.then(function () {\n\t options = options || {};\n\t options.offset = 0;\n\t return self.fetchMore(options);\n\t });\n\t },\n\t\n\t /** @type {Object} map of collection available sorting orders containing comparator fns */\n\t comparators: _.extend(_.clone(_collectionSuper.prototype.comparators), {\n\t 'name': BASE_MVC.buildComparator('name', { ascending: true }),\n\t 'name-dsc': BASE_MVC.buildComparator('name', { ascending: false }),\n\t 'size': BASE_MVC.buildComparator('size', { ascending: false }),\n\t 'size-asc': BASE_MVC.buildComparator('size', { ascending: true })\n\t }),\n\t\n\t /** override to always have the current history first */\n\t sort: function (options) {\n\t options = options || {};\n\t var silent = options.silent;\n\t var currentHistory = this.remove(this.get(this.currentHistoryId));\n\t _collectionSuper.prototype.sort.call(this, _.defaults({ silent: true }, options));\n\t this.unshift(currentHistory, { silent: true });\n\t if (!silent) {\n\t this.trigger('sort', this, options);\n\t }\n\t return this;\n\t },\n\t\n\t /** create a new history and by default set it to be the current history */\n\t create: function create(data, hdas, historyOptions, xhrOptions) {\n\t //TODO: .create is actually a collection function that's overridden here\n\t var collection = this,\n\t xhr = jQuery.getJSON(Galaxy.root + 'history/create_new_current');\n\t return xhr.done(function (newData) {\n\t collection.setCurrent(new History(newData, [], historyOptions || {}));\n\t });\n\t },\n\t\n\t /** set the current history to the given history, placing it first in the collection.\n\t * Pass standard bbone options for use in unshift.\n\t * @triggers new-current passed history and this collection\n\t */\n\t setCurrent: function (history, options) {\n\t options = options || {};\n\t // new histories go in the front\n\t this.unshift(history, options);\n\t this.currentHistoryId = history.get('id');\n\t if (!options.silent) {\n\t this.trigger('new-current', history, this);\n\t }\n\t return this;\n\t },\n\t\n\t toString: function toString() {\n\t return 'HistoryCollection(' + this.length + ',current:' + this.currentHistoryId + ')';\n\t }\n\t });\n\t\n\t //==============================================================================\n\t return {\n\t History: History,\n\t HistoryCollection: HistoryCollection\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(1), __webpack_require__(2), __webpack_require__(1)))\n\n/***/ },\n/* 57 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(_) {!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(6)], __WEBPACK_AMD_DEFINE_RESULT__ = function (BASE_MVC) {\n\t\n\t 'use strict';\n\t\n\t var logNamespace = 'history';\n\t\n\t // ============================================================================\n\t /** session storage for individual history preferences */\n\t var HistoryPrefs = BASE_MVC.SessionStorageModel.extend(\n\t /** @lends HistoryPrefs.prototype */{\n\t //TODO:?? move to user prefs?\n\t defaults: {\n\t //TODO:?? expandedIds to array?\n\t expandedIds: {},\n\t show_deleted: false,\n\t show_hidden: false\n\t },\n\t\n\t /** add an hda id to the hash of expanded hdas */\n\t addExpanded: function (model) {\n\t //TODO: use type_id and not model\n\t var current = this.get('expandedIds');\n\t current[model.id] = model.get('id');\n\t this.save('expandedIds', current);\n\t },\n\t\n\t /** remove an hda id from the hash of expanded hdas */\n\t removeExpanded: function (model) {\n\t var current = this.get('expandedIds');\n\t delete current[model.id];\n\t this.save('expandedIds', current);\n\t },\n\t\n\t isExpanded: function (contentId) {\n\t return _.result(this.get('expandedIds'), contentId, false);\n\t },\n\t\n\t allExpanded: function () {\n\t return _.values(this.get('expandedIds'));\n\t },\n\t\n\t clearExpanded: function () {\n\t this.set('expandedIds', {});\n\t },\n\t\n\t includeDeleted: function (val) {\n\t // moving the invocation here so other components don't need to know the key\n\t // TODO: change this key later\n\t if (!_.isUndefined(val)) {\n\t this.set('show_deleted', val);\n\t }\n\t return this.get('show_deleted');\n\t },\n\t\n\t includeHidden: function (val) {\n\t // TODO: change this key later\n\t if (!_.isUndefined(val)) {\n\t this.set('show_hidden', val);\n\t }\n\t return this.get('show_hidden');\n\t },\n\t\n\t toString: function () {\n\t return 'HistoryPrefs(' + this.id + ')';\n\t }\n\t\n\t }, {\n\t // ........................................................................ class vars\n\t // class lvl for access w/o instantiation\n\t storageKeyPrefix: 'history:',\n\t\n\t /** key string to store each histories settings under */\n\t historyStorageKey: function historyStorageKey(historyId) {\n\t if (!historyId) {\n\t throw new Error('HistoryPrefs.historyStorageKey needs valid id: ' + historyId);\n\t }\n\t // single point of change\n\t return HistoryPrefs.storageKeyPrefix + historyId;\n\t },\n\t\n\t /** return the existing storage for the history with the given id (or create one if it doesn't exist) */\n\t get: function get(historyId) {\n\t return new HistoryPrefs({ id: HistoryPrefs.historyStorageKey(historyId) });\n\t },\n\t\n\t /** clear all history related items in sessionStorage */\n\t clearAll: function clearAll(historyId) {\n\t for (var key in sessionStorage) {\n\t if (key.indexOf(HistoryPrefs.storageKeyPrefix) === 0) {\n\t sessionStorage.removeItem(key);\n\t }\n\t }\n\t }\n\t });\n\t\n\t //==============================================================================\n\t return {\n\t HistoryPrefs: HistoryPrefs\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2)))\n\n/***/ },\n/* 58 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, $, _, jQuery) {!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(6), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (BASE_MVC, _l) {\n\t\n\t 'use strict';\n\t\n\t var logNamespace = 'list';\n\t //==============================================================================\n\t /** A view which, when first rendered, shows only summary data/attributes, but\n\t * can be expanded to show further details (and optionally fetch those\n\t * details from the server).\n\t */\n\t var ExpandableView = Backbone.View.extend(BASE_MVC.LoggableMixin).extend({\n\t _logNamespace: logNamespace,\n\t\n\t //TODO: Although the reasoning behind them is different, this shares a lot with HiddenUntilActivated above: combine them\n\t //PRECONDITION: model must have method hasDetails\n\t //PRECONDITION: subclasses must have templates.el and templates.details\n\t\n\t initialize: function (attributes) {\n\t /** are the details of this view expanded/shown or not? */\n\t this.expanded = attributes.expanded || false;\n\t this.log('\\t expanded:', this.expanded);\n\t this.fxSpeed = attributes.fxSpeed !== undefined ? attributes.fxSpeed : this.fxSpeed;\n\t },\n\t\n\t // ........................................................................ render main\n\t /** jq fx speed */\n\t fxSpeed: 'fast',\n\t\n\t /** Render this content, set up ui.\n\t * @param {Number or String} speed the speed of the render\n\t */\n\t render: function (speed) {\n\t var $newRender = this._buildNewRender();\n\t this._setUpBehaviors($newRender);\n\t this._queueNewRender($newRender, speed);\n\t return this;\n\t },\n\t\n\t /** Build a temp div containing the new children for the view's $el.\n\t * If the view is already expanded, build the details as well.\n\t */\n\t _buildNewRender: function () {\n\t // create a new render using a skeleton template, render title buttons, render body, and set up events, etc.\n\t var $newRender = $(this.templates.el(this.model.toJSON(), this));\n\t if (this.expanded) {\n\t this.$details($newRender).replaceWith(this._renderDetails().show());\n\t }\n\t return $newRender;\n\t },\n\t\n\t /** Fade out the old el, swap in the new contents, then fade in.\n\t * @param {Number or String} speed jq speed to use for rendering effects\n\t * @fires rendered when rendered\n\t */\n\t _queueNewRender: function ($newRender, speed) {\n\t speed = speed === undefined ? this.fxSpeed : speed;\n\t var view = this;\n\t\n\t if (speed === 0) {\n\t view._swapNewRender($newRender);\n\t view.trigger('rendered', view);\n\t } else {\n\t $(view).queue('fx', [function (next) {\n\t view.$el.fadeOut(speed, next);\n\t }, function (next) {\n\t view._swapNewRender($newRender);\n\t next();\n\t }, function (next) {\n\t view.$el.fadeIn(speed, next);\n\t }, function (next) {\n\t view.trigger('rendered', view);\n\t next();\n\t }]);\n\t }\n\t },\n\t\n\t /** empty out the current el, move the $newRender's children in */\n\t _swapNewRender: function ($newRender) {\n\t return this.$el.empty().attr('class', _.isFunction(this.className) ? this.className() : this.className).append($newRender.children());\n\t },\n\t\n\t /** set up js behaviors, event handlers for elements within the given container\n\t * @param {jQuery} $container jq object that contains the elements to process (defaults to this.$el)\n\t */\n\t _setUpBehaviors: function ($where) {\n\t $where = $where || this.$el;\n\t // set up canned behavior on children (bootstrap, popupmenus, editable_text, etc.)\n\t //make_popup_menus( $where );\n\t $where.find('[title]').tooltip({ placement: 'bottom' });\n\t },\n\t\n\t // ......................................................................... details\n\t /** shortcut to details DOM (as jQ) */\n\t $details: function ($where) {\n\t $where = $where || this.$el;\n\t return $where.find('> .details');\n\t },\n\t\n\t /** build the DOM for the details and set up behaviors on it */\n\t _renderDetails: function () {\n\t var $newDetails = $(this.templates.details(this.model.toJSON(), this));\n\t this._setUpBehaviors($newDetails);\n\t return $newDetails;\n\t },\n\t\n\t // ......................................................................... expansion/details\n\t /** Show or hide the details\n\t * @param {Boolean} expand if true, expand; if false, collapse\n\t */\n\t toggleExpanded: function (expand) {\n\t expand = expand === undefined ? !this.expanded : expand;\n\t if (expand) {\n\t this.expand();\n\t } else {\n\t this.collapse();\n\t }\n\t return this;\n\t },\n\t\n\t /** Render and show the full, detailed body of this view including extra data and controls.\n\t * note: if the model does not have detailed data, fetch that data before showing the body\n\t * @fires expanded when a body has been expanded\n\t */\n\t expand: function () {\n\t var view = this;\n\t return view._fetchModelDetails().always(function () {\n\t view._expand();\n\t });\n\t },\n\t\n\t /** Check for model details and, if none, fetch them.\n\t * @returns {jQuery.promise} the model.fetch.xhr if details are being fetched, an empty promise if not\n\t */\n\t _fetchModelDetails: function () {\n\t if (!this.model.hasDetails()) {\n\t return this.model.fetch();\n\t }\n\t return jQuery.when();\n\t },\n\t\n\t /** Inner fn called when expand (public) has fetched the details */\n\t _expand: function () {\n\t var view = this,\n\t $newDetails = view._renderDetails();\n\t view.$details().replaceWith($newDetails);\n\t // needs to be set after the above or the slide will not show\n\t view.expanded = true;\n\t view.$details().slideDown(view.fxSpeed, function () {\n\t view.trigger('expanded', view);\n\t });\n\t },\n\t\n\t /** Hide the body/details of an HDA.\n\t * @fires collapsed when a body has been collapsed\n\t */\n\t collapse: function () {\n\t this.debug(this + '(ExpandableView).collapse');\n\t var view = this;\n\t view.expanded = false;\n\t this.$details().slideUp(view.fxSpeed, function () {\n\t view.trigger('collapsed', view);\n\t });\n\t }\n\t\n\t });\n\t\n\t //==============================================================================\n\t /** A view that is displayed in some larger list/grid/collection.\n\t * Inherits from Expandable, Selectable, Draggable.\n\t * The DOM contains warnings, a title bar, and a series of primary action controls.\n\t * Primary actions are meant to be easily accessible item functions (such as delete)\n\t * that are rendered in the title bar.\n\t *\n\t * Details are rendered when the user clicks the title bar or presses enter/space when\n\t * the title bar is in focus.\n\t *\n\t * Designed as a base class for history panel contents - but usable elsewhere (I hope).\n\t */\n\t var ListItemView = ExpandableView.extend(BASE_MVC.mixin(BASE_MVC.SelectableViewMixin, BASE_MVC.DraggableViewMixin, {\n\t\n\t tagName: 'div',\n\t className: 'list-item',\n\t\n\t /** Set up the base class and all mixins */\n\t initialize: function (attributes) {\n\t ExpandableView.prototype.initialize.call(this, attributes);\n\t BASE_MVC.SelectableViewMixin.initialize.call(this, attributes);\n\t BASE_MVC.DraggableViewMixin.initialize.call(this, attributes);\n\t this._setUpListeners();\n\t },\n\t\n\t /** event listeners */\n\t _setUpListeners: function () {\n\t // hide the primary actions in the title bar when selectable and narrow\n\t this.on('selectable', function (isSelectable) {\n\t if (isSelectable) {\n\t this.$('.primary-actions').hide();\n\t } else {\n\t this.$('.primary-actions').show();\n\t }\n\t }, this);\n\t return this;\n\t },\n\t\n\t // ........................................................................ rendering\n\t /** In this override, call methods to build warnings, titlebar and primary actions */\n\t _buildNewRender: function () {\n\t var $newRender = ExpandableView.prototype._buildNewRender.call(this);\n\t $newRender.children('.warnings').replaceWith(this._renderWarnings());\n\t $newRender.children('.title-bar').replaceWith(this._renderTitleBar());\n\t $newRender.children('.primary-actions').append(this._renderPrimaryActions());\n\t $newRender.find('> .title-bar .subtitle').replaceWith(this._renderSubtitle());\n\t return $newRender;\n\t },\n\t\n\t /** In this override, render the selector controls and set up dragging before the swap */\n\t _swapNewRender: function ($newRender) {\n\t ExpandableView.prototype._swapNewRender.call(this, $newRender);\n\t if (this.selectable) {\n\t this.showSelector(0);\n\t }\n\t if (this.draggable) {\n\t this.draggableOn();\n\t }\n\t return this.$el;\n\t },\n\t\n\t /** Render any warnings the item may need to show (e.g. \"I'm deleted\") */\n\t _renderWarnings: function () {\n\t var view = this,\n\t $warnings = $('
    '),\n\t json = view.model.toJSON();\n\t //TODO:! unordered (map)\n\t _.each(view.templates.warnings, function (templateFn) {\n\t $warnings.append($(templateFn(json, view)));\n\t });\n\t return $warnings;\n\t },\n\t\n\t /** Render the title bar (the main/exposed SUMMARY dom element) */\n\t _renderTitleBar: function () {\n\t return $(this.templates.titleBar(this.model.toJSON(), this));\n\t },\n\t\n\t /** Return an array of jQ objects containing common/easily-accessible item controls */\n\t _renderPrimaryActions: function () {\n\t // override this\n\t return [];\n\t },\n\t\n\t /** Render the title bar (the main/exposed SUMMARY dom element) */\n\t _renderSubtitle: function () {\n\t return $(this.templates.subtitle(this.model.toJSON(), this));\n\t },\n\t\n\t // ......................................................................... events\n\t /** event map */\n\t events: {\n\t // expand the body when the title is clicked or when in focus and space or enter is pressed\n\t 'click .title-bar': '_clickTitleBar',\n\t 'keydown .title-bar': '_keyDownTitleBar',\n\t 'click .selector': 'toggleSelect'\n\t },\n\t\n\t /** expand when the title bar is clicked */\n\t _clickTitleBar: function (event) {\n\t event.stopPropagation();\n\t if (event.altKey) {\n\t this.toggleSelect(event);\n\t if (!this.selectable) {\n\t this.showSelector();\n\t }\n\t } else {\n\t this.toggleExpanded();\n\t }\n\t },\n\t\n\t /** expand when the title bar is in focus and enter or space is pressed */\n\t _keyDownTitleBar: function (event) {\n\t // bail (with propagation) if keydown and not space or enter\n\t var KEYCODE_SPACE = 32,\n\t KEYCODE_RETURN = 13;\n\t if (event && event.type === 'keydown' && (event.keyCode === KEYCODE_SPACE || event.keyCode === KEYCODE_RETURN)) {\n\t this.toggleExpanded();\n\t event.stopPropagation();\n\t return false;\n\t }\n\t return true;\n\t },\n\t\n\t // ......................................................................... misc\n\t /** String representation */\n\t toString: function () {\n\t var modelString = this.model ? this.model + '' : '(no model)';\n\t return 'ListItemView(' + modelString + ')';\n\t }\n\t }));\n\t\n\t // ............................................................................ TEMPLATES\n\t /** underscore templates */\n\t ListItemView.prototype.templates = function () {\n\t\n\t var elTemplato = BASE_MVC.wrapTemplate(['
    ',\n\t // errors, messages, etc.\n\t '
    ',\n\t\n\t // multi-select checkbox\n\t '
    ', '', '
    ',\n\t // space for title bar buttons - gen. floated to the right\n\t '
    ', '
    ',\n\t\n\t // expandable area for more details\n\t '
    ', '
    ']);\n\t\n\t var warnings = {};\n\t\n\t var titleBarTemplate = BASE_MVC.wrapTemplate([\n\t // adding a tabindex here allows focusing the title bar and the use of keydown to expand the dataset display\n\t '
    ',\n\t //TODO: prob. belongs in dataset-list-item\n\t '', '
    ', '<%- element.name %>', '
    ', '
    ', '
    '], 'element');\n\t\n\t var subtitleTemplate = BASE_MVC.wrapTemplate([\n\t // override this\n\t '
    ']);\n\t\n\t var detailsTemplate = BASE_MVC.wrapTemplate([\n\t // override this\n\t '
    ']);\n\t\n\t return {\n\t el: elTemplato,\n\t warnings: warnings,\n\t titleBar: titleBarTemplate,\n\t subtitle: subtitleTemplate,\n\t details: detailsTemplate\n\t };\n\t }();\n\t\n\t //==============================================================================\n\t /** A view that is displayed in some larger list/grid/collection.\n\t * *AND* can display some sub-list of it's own when expanded (e.g. dataset collections).\n\t * This list will 'foldout' when the item is expanded depending on this.foldoutStyle:\n\t * If 'foldout': will expand vertically to show the nested list\n\t * If 'drilldown': will overlay the parent list\n\t *\n\t * Inherits from ListItemView.\n\t *\n\t * _renderDetails does the work of creating this.details: a sub-view that shows the nested list\n\t */\n\t var FoldoutListItemView = ListItemView.extend({\n\t\n\t /** If 'foldout': show the sub-panel inside the expanded item\n\t * If 'drilldown': only fire events and handle by pub-sub\n\t * (allow the panel containing this item to attach it, hide itself, etc.)\n\t */\n\t foldoutStyle: 'foldout',\n\t /** Panel view class to instantiate for the sub-panel */\n\t foldoutPanelClass: null,\n\t\n\t /** override to:\n\t * add attributes foldoutStyle and foldoutPanelClass for config poly\n\t * disrespect attributes.expanded if drilldown\n\t */\n\t initialize: function (attributes) {\n\t if (this.foldoutStyle === 'drilldown') {\n\t this.expanded = false;\n\t }\n\t this.foldoutStyle = attributes.foldoutStyle || this.foldoutStyle;\n\t this.foldoutPanelClass = attributes.foldoutPanelClass || this.foldoutPanelClass;\n\t\n\t ListItemView.prototype.initialize.call(this, attributes);\n\t this.foldout = this._createFoldoutPanel();\n\t },\n\t\n\t /** in this override, attach the foldout panel when rendering details */\n\t _renderDetails: function () {\n\t if (this.foldoutStyle === 'drilldown') {\n\t return $();\n\t }\n\t var $newDetails = ListItemView.prototype._renderDetails.call(this);\n\t return this._attachFoldout(this.foldout, $newDetails);\n\t },\n\t\n\t /** In this override, handle collection expansion. */\n\t _createFoldoutPanel: function () {\n\t var model = this.model;\n\t var FoldoutClass = this._getFoldoutPanelClass(model),\n\t options = this._getFoldoutPanelOptions(model),\n\t foldout = new FoldoutClass(_.extend(options, {\n\t model: model\n\t }));\n\t return foldout;\n\t },\n\t\n\t /** Stub to return proper foldout panel class */\n\t _getFoldoutPanelClass: function () {\n\t // override\n\t return this.foldoutPanelClass;\n\t },\n\t\n\t /** Stub to return proper foldout panel options */\n\t _getFoldoutPanelOptions: function () {\n\t return {\n\t // propagate foldout style down\n\t foldoutStyle: this.foldoutStyle,\n\t fxSpeed: this.fxSpeed\n\t };\n\t },\n\t\n\t /** Render the foldout panel inside the view, hiding controls */\n\t _attachFoldout: function (foldout, $whereTo) {\n\t $whereTo = $whereTo || this.$('> .details');\n\t this.foldout = foldout.render(0);\n\t foldout.$('> .controls').hide();\n\t return $whereTo.append(foldout.$el);\n\t },\n\t\n\t /** In this override, branch on foldoutStyle to show expanded */\n\t expand: function () {\n\t var view = this;\n\t return view._fetchModelDetails().always(function () {\n\t if (view.foldoutStyle === 'foldout') {\n\t view._expand();\n\t } else if (view.foldoutStyle === 'drilldown') {\n\t view._expandByDrilldown();\n\t }\n\t });\n\t },\n\t\n\t /** For drilldown, set up close handler and fire expanded:drilldown\n\t * containing views can listen to this and handle other things\n\t * (like hiding themselves) by listening for expanded/collapsed:drilldown\n\t */\n\t _expandByDrilldown: function () {\n\t var view = this;\n\t // attachment and rendering done by listener\n\t view.listenTo(view.foldout, 'close', function () {\n\t view.trigger('collapsed:drilldown', view, view.foldout);\n\t });\n\t view.trigger('expanded:drilldown', view, view.foldout);\n\t }\n\t\n\t });\n\t\n\t // ............................................................................ TEMPLATES\n\t /** underscore templates */\n\t FoldoutListItemView.prototype.templates = function () {\n\t\n\t var detailsTemplate = BASE_MVC.wrapTemplate(['
    ',\n\t // override with more info (that goes above the panel)\n\t '
    '], 'collection');\n\t\n\t return _.extend({}, ListItemView.prototype.templates, {\n\t details: detailsTemplate\n\t });\n\t }();\n\t\n\t //==============================================================================\n\t return {\n\t ExpandableView: ExpandableView,\n\t ListItemView: ListItemView,\n\t FoldoutListItemView: FoldoutListItemView\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(1), __webpack_require__(2), __webpack_require__(1)))\n\n/***/ },\n/* 59 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, _) {!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(6), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (baseMVC, _l) {\n\t // =============================================================================\n\t /** A view on any model that has a 'tags' attribute (a list of tag strings)\n\t * Incorporates the select2 jQuery plugin for tags display/editing:\n\t * http://ivaynberg.github.io/select2/\n\t */\n\t var TagsEditor = Backbone.View.extend(baseMVC.LoggableMixin).extend(baseMVC.HiddenUntilActivatedViewMixin).extend({\n\t\n\t tagName: 'div',\n\t className: 'tags-display',\n\t\n\t /** Set up listeners, parse options */\n\t initialize: function (options) {\n\t //console.debug( this, options );\n\t // only listen to the model only for changes to tags - re-render\n\t if (options.usePrompt === false) {\n\t this.label = '';\n\t } else {\n\t this.label = '';\n\t }\n\t this.hiddenUntilActivated(options.$activator, options);\n\t },\n\t\n\t /** Build the DOM elements, call select to on the created input, and set up behaviors */\n\t render: function () {\n\t var self = this;\n\t this.$el.html(this._template());\n\t\n\t this.$input().select2({\n\t placeholder: 'Add tags',\n\t width: '100%',\n\t tags: function () {\n\t // initialize possible tags in the dropdown based on all the tags the user has used so far\n\t return self._getTagsUsed();\n\t }\n\t });\n\t\n\t this._setUpBehaviors();\n\t return this;\n\t },\n\t\n\t _hashToName: function (tag) {\n\t if (tag.startsWith('#')) {\n\t return 'name:' + tag.slice(1);\n\t }\n\t return tag;\n\t },\n\t\n\t _nameToHash: function (tag) {\n\t if (tag.startsWith('name:')) {\n\t tag = '#' + tag.slice(5);\n\t }\n\t return tag;\n\t },\n\t\n\t /** @returns {String} the html text used to build the view's DOM */\n\t _template: function () {\n\t return [this.label,\n\t // set up initial tags by adding as CSV to input vals (necc. to init select2)\n\t ''].join('');\n\t },\n\t\n\t /** @returns {String} the sorted, comma-separated tags from the model */\n\t tagsToCSV: function () {\n\t var self = this;\n\t var tagsArray = this.model.get('tags');\n\t if (!_.isArray(tagsArray) || _.isEmpty(tagsArray)) {\n\t return '';\n\t }\n\t return tagsArray.map(function (tag) {\n\t return _.escape(self._nameToHash(tag));\n\t }).sort().join(',');\n\t },\n\t\n\t /** @returns {jQuery} the input for this view */\n\t $input: function () {\n\t return this.$el.find('input.tags-input');\n\t },\n\t\n\t /** @returns {String[]} all tags used by the current user */\n\t _getTagsUsed: function () {\n\t //TODO: global\n\t var self = this;\n\t return _.map(Galaxy.user.get('tags_used'), self._nameToHash);\n\t },\n\t\n\t /** set up any event listeners on the view's DOM (mostly handled by select2) */\n\t _setUpBehaviors: function () {\n\t var self = this;\n\t this.$input().on('change', function (event) {\n\t // Modify any 'hashtag' 'nametags'\n\t event.val = _.map(event.val, self._hashToName);\n\t // save the model's tags in either remove or added event\n\t self.model.save({ tags: event.val });\n\t // if it's new, add the tag to the users tags\n\t if (event.added) {\n\t //??: solve weird behavior in FF on test.galaxyproject.org where\n\t // event.added.text is string object: 'String{ 0=\"o\", 1=\"n\", 2=\"e\" }'\n\t self._addNewTagToTagsUsed(event.added.text + '');\n\t }\n\t });\n\t },\n\t\n\t /** add a new tag (if not already there) to the list of all tags used by the user\n\t * @param {String} newTag the tag to add to the list of used\n\t */\n\t _addNewTagToTagsUsed: function (newTag) {\n\t //TODO: global\n\t var tagsUsed = Galaxy.user.get('tags_used');\n\t if (!_.contains(tagsUsed, newTag)) {\n\t tagsUsed.push(newTag);\n\t tagsUsed.sort();\n\t Galaxy.user.set('tags_used', tagsUsed);\n\t }\n\t },\n\t\n\t /** shut down event listeners and remove this view's DOM */\n\t remove: function () {\n\t this.$input.off();\n\t this.stopListening(this.model);\n\t Backbone.View.prototype.remove.call(this);\n\t },\n\t\n\t /** string rep */\n\t toString: function () {\n\t return ['TagsEditor(', this.model + '', ')'].join('');\n\t }\n\t });\n\t\n\t // =============================================================================\n\t return {\n\t TagsEditor: TagsEditor\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(2)))\n\n/***/ },\n/* 60 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, $) {/**\n\t * Model, view, and controller objects for Galaxy tools and tool panel.\n\t */\n\t\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(2), __webpack_require__(23), __webpack_require__(13), __webpack_require__(34)], __WEBPACK_AMD_DEFINE_RESULT__ = function (_, util, data, ToolForm) {\n\t 'use strict';\n\t\n\t /**\n\t * Mixin for tracking model visibility.\n\t */\n\t\n\t var VisibilityMixin = {\n\t hidden: false,\n\t\n\t show: function () {\n\t this.set(\"hidden\", false);\n\t },\n\t\n\t hide: function () {\n\t this.set(\"hidden\", true);\n\t },\n\t\n\t toggle: function () {\n\t this.set(\"hidden\", !this.get(\"hidden\"));\n\t },\n\t\n\t is_visible: function () {\n\t return !this.attributes.hidden;\n\t }\n\t\n\t };\n\t\n\t /**\n\t * A tool parameter.\n\t */\n\t var ToolParameter = Backbone.Model.extend({\n\t defaults: {\n\t name: null,\n\t label: null,\n\t type: null,\n\t value: null,\n\t html: null,\n\t num_samples: 5\n\t },\n\t\n\t initialize: function (options) {\n\t this.attributes.html = unescape(this.attributes.html);\n\t },\n\t\n\t copy: function () {\n\t return new ToolParameter(this.toJSON());\n\t },\n\t\n\t set_value: function (value) {\n\t this.set('value', value || '');\n\t }\n\t });\n\t\n\t var ToolParameterCollection = Backbone.Collection.extend({\n\t model: ToolParameter\n\t });\n\t\n\t /**\n\t * A data tool parameter.\n\t */\n\t var DataToolParameter = ToolParameter.extend({});\n\t\n\t /**\n\t * An integer tool parameter.\n\t */\n\t var IntegerToolParameter = ToolParameter.extend({\n\t set_value: function (value) {\n\t this.set('value', parseInt(value, 10));\n\t },\n\t\n\t /**\n\t * Returns samples from a tool input.\n\t */\n\t get_samples: function () {\n\t return d3.scale.linear().domain([this.get('min'), this.get('max')]).ticks(this.get('num_samples'));\n\t }\n\t });\n\t\n\t var FloatToolParameter = IntegerToolParameter.extend({\n\t set_value: function (value) {\n\t this.set('value', parseFloat(value));\n\t }\n\t });\n\t\n\t /**\n\t * A select tool parameter.\n\t */\n\t var SelectToolParameter = ToolParameter.extend({\n\t /**\n\t * Returns tool options.\n\t */\n\t get_samples: function () {\n\t return _.map(this.get('options'), function (option) {\n\t return option[0];\n\t });\n\t }\n\t });\n\t\n\t // Set up dictionary of parameter types.\n\t ToolParameter.subModelTypes = {\n\t 'integer': IntegerToolParameter,\n\t 'float': FloatToolParameter,\n\t 'data': DataToolParameter,\n\t 'select': SelectToolParameter\n\t };\n\t\n\t /**\n\t * A Galaxy tool.\n\t */\n\t var Tool = Backbone.Model.extend({\n\t // Default attributes.\n\t defaults: {\n\t id: null,\n\t name: null,\n\t description: null,\n\t target: null,\n\t inputs: [],\n\t outputs: []\n\t },\n\t\n\t urlRoot: Galaxy.root + 'api/tools',\n\t\n\t initialize: function (options) {\n\t\n\t // Set parameters.\n\t this.set('inputs', new ToolParameterCollection(_.map(options.inputs, function (p) {\n\t var p_class = ToolParameter.subModelTypes[p.type] || ToolParameter;\n\t return new p_class(p);\n\t })));\n\t },\n\t\n\t /**\n\t *\n\t */\n\t toJSON: function () {\n\t var rval = Backbone.Model.prototype.toJSON.call(this);\n\t\n\t // Convert inputs to JSON manually.\n\t rval.inputs = this.get('inputs').map(function (i) {\n\t return i.toJSON();\n\t });\n\t return rval;\n\t },\n\t\n\t /**\n\t * Removes inputs of a particular type; this is useful because not all inputs can be handled by\n\t * client and server yet.\n\t */\n\t remove_inputs: function (types) {\n\t var tool = this,\n\t incompatible_inputs = tool.get('inputs').filter(function (input) {\n\t return types.indexOf(input.get('type')) !== -1;\n\t });\n\t tool.get('inputs').remove(incompatible_inputs);\n\t },\n\t\n\t /**\n\t * Returns object copy, optionally including only inputs that can be sampled.\n\t */\n\t copy: function (only_samplable_inputs) {\n\t var copy = new Tool(this.toJSON());\n\t\n\t // Return only samplable inputs if flag is set.\n\t if (only_samplable_inputs) {\n\t var valid_inputs = new Backbone.Collection();\n\t copy.get('inputs').each(function (input) {\n\t if (input.get_samples()) {\n\t valid_inputs.push(input);\n\t }\n\t });\n\t copy.set('inputs', valid_inputs);\n\t }\n\t\n\t return copy;\n\t },\n\t\n\t apply_search_results: function (results) {\n\t _.indexOf(results, this.attributes.id) !== -1 ? this.show() : this.hide();\n\t return this.is_visible();\n\t },\n\t\n\t /**\n\t * Set a tool input's value.\n\t */\n\t set_input_value: function (name, value) {\n\t this.get('inputs').find(function (input) {\n\t return input.get('name') === name;\n\t }).set('value', value);\n\t },\n\t\n\t /**\n\t * Set many input values at once.\n\t */\n\t set_input_values: function (inputs_dict) {\n\t var self = this;\n\t _.each(_.keys(inputs_dict), function (input_name) {\n\t self.set_input_value(input_name, inputs_dict[input_name]);\n\t });\n\t },\n\t\n\t /**\n\t * Run tool; returns a Deferred that resolves to the tool's output(s).\n\t */\n\t run: function () {\n\t return this._run();\n\t },\n\t\n\t /**\n\t * Rerun tool using regions and a target dataset.\n\t */\n\t rerun: function (target_dataset, regions) {\n\t return this._run({\n\t action: 'rerun',\n\t target_dataset_id: target_dataset.id,\n\t regions: regions\n\t });\n\t },\n\t\n\t /**\n\t * Returns input dict for tool's inputs.\n\t */\n\t get_inputs_dict: function () {\n\t var input_dict = {};\n\t this.get('inputs').each(function (input) {\n\t input_dict[input.get('name')] = input.get('value');\n\t });\n\t return input_dict;\n\t },\n\t\n\t /**\n\t * Run tool; returns a Deferred that resolves to the tool's output(s).\n\t * NOTE: this method is a helper method and should not be called directly.\n\t */\n\t _run: function (additional_params) {\n\t // Create payload.\n\t var payload = _.extend({\n\t tool_id: this.id,\n\t inputs: this.get_inputs_dict()\n\t }, additional_params);\n\t\n\t // Because job may require indexing datasets, use server-side\n\t // deferred to ensure that job is run. Also use deferred that\n\t // resolves to outputs from tool.\n\t var run_deferred = $.Deferred(),\n\t ss_deferred = new util.ServerStateDeferred({\n\t ajax_settings: {\n\t url: this.urlRoot,\n\t data: JSON.stringify(payload),\n\t dataType: \"json\",\n\t contentType: 'application/json',\n\t type: \"POST\"\n\t },\n\t interval: 2000,\n\t success_fn: function (response) {\n\t return response !== \"pending\";\n\t }\n\t });\n\t\n\t // Run job and resolve run_deferred to tool outputs.\n\t $.when(ss_deferred.go()).then(function (result) {\n\t run_deferred.resolve(new data.DatasetCollection(result));\n\t });\n\t return run_deferred;\n\t }\n\t });\n\t _.extend(Tool.prototype, VisibilityMixin);\n\t\n\t /**\n\t * Tool view.\n\t */\n\t var ToolView = Backbone.View.extend({});\n\t\n\t /**\n\t * Wrap collection of tools for fast access/manipulation.\n\t */\n\t var ToolCollection = Backbone.Collection.extend({\n\t model: Tool\n\t });\n\t\n\t /**\n\t * Label or section header in tool panel.\n\t */\n\t var ToolSectionLabel = Backbone.Model.extend(VisibilityMixin);\n\t\n\t /**\n\t * Section of tool panel with elements (labels and tools).\n\t */\n\t var ToolSection = Backbone.Model.extend({\n\t defaults: {\n\t elems: [],\n\t open: false\n\t },\n\t\n\t clear_search_results: function () {\n\t _.each(this.attributes.elems, function (elt) {\n\t elt.show();\n\t });\n\t\n\t this.show();\n\t this.set(\"open\", false);\n\t },\n\t\n\t apply_search_results: function (results) {\n\t var all_hidden = true,\n\t cur_label;\n\t _.each(this.attributes.elems, function (elt) {\n\t if (elt instanceof ToolSectionLabel) {\n\t cur_label = elt;\n\t cur_label.hide();\n\t } else if (elt instanceof Tool) {\n\t if (elt.apply_search_results(results)) {\n\t all_hidden = false;\n\t if (cur_label) {\n\t cur_label.show();\n\t }\n\t }\n\t }\n\t });\n\t\n\t if (all_hidden) {\n\t this.hide();\n\t } else {\n\t this.show();\n\t this.set(\"open\", true);\n\t }\n\t }\n\t });\n\t _.extend(ToolSection.prototype, VisibilityMixin);\n\t\n\t /**\n\t * Tool search that updates results when query is changed. Result value of null\n\t * indicates that query was not run; if not null, results are from search using\n\t * query.\n\t */\n\t var ToolSearch = Backbone.Model.extend({\n\t defaults: {\n\t search_hint_string: \"search tools\",\n\t min_chars_for_search: 3,\n\t clear_btn_url: \"\",\n\t visible: true,\n\t query: \"\",\n\t results: null,\n\t // ESC (27) will clear the input field and tool search filters\n\t clear_key: 27\n\t },\n\t\n\t urlRoot: Galaxy.root + 'api/tools',\n\t\n\t initialize: function () {\n\t this.on(\"change:query\", this.do_search);\n\t },\n\t\n\t /**\n\t * Do the search and update the results.\n\t */\n\t do_search: function () {\n\t var query = this.attributes.query;\n\t\n\t // If query is too short, do not search.\n\t if (query.length < this.attributes.min_chars_for_search) {\n\t this.set(\"results\", null);\n\t return;\n\t }\n\t\n\t // Do search via AJAX.\n\t var q = query;\n\t // Stop previous ajax-request\n\t if (this.timer) {\n\t clearTimeout(this.timer);\n\t }\n\t // Start a new ajax-request in X ms\n\t $(\"#search-clear-btn\").hide();\n\t $(\"#search-spinner\").show();\n\t var self = this;\n\t this.timer = setTimeout(function () {\n\t // log the search to analytics if present\n\t if (typeof ga !== 'undefined') {\n\t ga('send', 'pageview', Galaxy.root + '?q=' + q);\n\t }\n\t $.get(self.urlRoot, { q: q }, function (data) {\n\t self.set(\"results\", data);\n\t $(\"#search-spinner\").hide();\n\t $(\"#search-clear-btn\").show();\n\t }, \"json\");\n\t }, 400);\n\t },\n\t\n\t clear_search: function () {\n\t this.set(\"query\", \"\");\n\t this.set(\"results\", null);\n\t }\n\t\n\t });\n\t _.extend(ToolSearch.prototype, VisibilityMixin);\n\t\n\t /**\n\t * Tool Panel.\n\t */\n\t var ToolPanel = Backbone.Model.extend({\n\t\n\t initialize: function (options) {\n\t this.attributes.tool_search = options.tool_search;\n\t this.attributes.tool_search.on(\"change:results\", this.apply_search_results, this);\n\t this.attributes.tools = options.tools;\n\t this.attributes.layout = new Backbone.Collection(this.parse(options.layout));\n\t },\n\t\n\t /**\n\t * Parse tool panel dictionary and return collection of tool panel elements.\n\t */\n\t parse: function (response) {\n\t // Recursive function to parse tool panel elements.\n\t var self = this,\n\t\n\t // Helper to recursively parse tool panel.\n\t parse_elt = function (elt_dict) {\n\t var type = elt_dict.model_class;\n\t // There are many types of tools; for now, anything that ends in 'Tool'\n\t // is treated as a generic tool.\n\t if (type.indexOf('Tool') === type.length - 4) {\n\t return self.attributes.tools.get(elt_dict.id);\n\t } else if (type === 'ToolSection') {\n\t // Parse elements.\n\t var elems = _.map(elt_dict.elems, parse_elt);\n\t elt_dict.elems = elems;\n\t return new ToolSection(elt_dict);\n\t } else if (type === 'ToolSectionLabel') {\n\t return new ToolSectionLabel(elt_dict);\n\t }\n\t };\n\t\n\t return _.map(response, parse_elt);\n\t },\n\t\n\t clear_search_results: function () {\n\t this.get('layout').each(function (panel_elt) {\n\t if (panel_elt instanceof ToolSection) {\n\t panel_elt.clear_search_results();\n\t } else {\n\t // Label or tool, so just show.\n\t panel_elt.show();\n\t }\n\t });\n\t },\n\t\n\t apply_search_results: function () {\n\t var results = this.get('tool_search').get('results');\n\t if (results === null) {\n\t this.clear_search_results();\n\t return;\n\t }\n\t\n\t var cur_label = null;\n\t this.get('layout').each(function (panel_elt) {\n\t if (panel_elt instanceof ToolSectionLabel) {\n\t cur_label = panel_elt;\n\t cur_label.hide();\n\t } else if (panel_elt instanceof Tool) {\n\t if (panel_elt.apply_search_results(results)) {\n\t if (cur_label) {\n\t cur_label.show();\n\t }\n\t }\n\t } else {\n\t // Starting new section, so clear current label.\n\t cur_label = null;\n\t panel_elt.apply_search_results(results);\n\t }\n\t });\n\t }\n\t });\n\t\n\t /**\n\t * View classes for Galaxy tools and tool panel.\n\t *\n\t * Views use the templates defined below for rendering. Views update as needed\n\t * based on (a) model/collection events and (b) user interactions; in this sense,\n\t * they are controllers are well and the HTML is the real view in the MVC architecture.\n\t */\n\t\n\t /**\n\t * Base view that handles visibility based on model's hidden attribute.\n\t */\n\t var BaseView = Backbone.View.extend({\n\t initialize: function () {\n\t this.model.on(\"change:hidden\", this.update_visible, this);\n\t this.update_visible();\n\t },\n\t update_visible: function () {\n\t this.model.attributes.hidden ? this.$el.hide() : this.$el.show();\n\t }\n\t });\n\t\n\t /**\n\t * Link to a tool.\n\t */\n\t var ToolLinkView = BaseView.extend({\n\t tagName: 'div',\n\t\n\t render: function () {\n\t // create element\n\t var $link = $('
    ');\n\t $link.append(templates.tool_link(this.model.toJSON()));\n\t\n\t var formStyle = this.model.get('form_style', null);\n\t // open upload dialog for upload tool\n\t if (this.model.id === 'upload1') {\n\t $link.find('a').on('click', function (e) {\n\t e.preventDefault();\n\t Galaxy.upload.show();\n\t });\n\t } else if (formStyle === 'regular') {\n\t // regular tools\n\t var self = this;\n\t $link.find('a').on('click', function (e) {\n\t e.preventDefault();\n\t Galaxy.router.push('/', { tool_id: self.model.id, version: self.model.get('version') });\n\t });\n\t }\n\t\n\t // add element\n\t this.$el.append($link);\n\t return this;\n\t }\n\t });\n\t\n\t /**\n\t * Panel label/section header.\n\t */\n\t var ToolSectionLabelView = BaseView.extend({\n\t tagName: 'div',\n\t className: 'toolPanelLabel',\n\t\n\t render: function () {\n\t this.$el.append($(\"\").text(this.model.attributes.text));\n\t return this;\n\t }\n\t });\n\t\n\t /**\n\t * Panel section.\n\t */\n\t var ToolSectionView = BaseView.extend({\n\t tagName: 'div',\n\t className: 'toolSectionWrapper',\n\t\n\t initialize: function () {\n\t BaseView.prototype.initialize.call(this);\n\t this.model.on(\"change:open\", this.update_open, this);\n\t },\n\t\n\t render: function () {\n\t // Build using template.\n\t this.$el.append(templates.panel_section(this.model.toJSON()));\n\t\n\t // Add tools to section.\n\t var section_body = this.$el.find(\".toolSectionBody\");\n\t _.each(this.model.attributes.elems, function (elt) {\n\t if (elt instanceof Tool) {\n\t var tool_view = new ToolLinkView({ model: elt, className: \"toolTitle\" });\n\t tool_view.render();\n\t section_body.append(tool_view.$el);\n\t } else if (elt instanceof ToolSectionLabel) {\n\t var label_view = new ToolSectionLabelView({ model: elt });\n\t label_view.render();\n\t section_body.append(label_view.$el);\n\t } else {\n\t // TODO: handle nested section bodies?\n\t }\n\t });\n\t return this;\n\t },\n\t\n\t events: {\n\t 'click .toolSectionTitle > a': 'toggle'\n\t },\n\t\n\t /**\n\t * Toggle visibility of tool section.\n\t */\n\t toggle: function () {\n\t this.model.set(\"open\", !this.model.attributes.open);\n\t },\n\t\n\t /**\n\t * Update whether section is open or close.\n\t */\n\t update_open: function () {\n\t this.model.attributes.open ? this.$el.children(\".toolSectionBody\").slideDown(\"fast\") : this.$el.children(\".toolSectionBody\").slideUp(\"fast\");\n\t }\n\t });\n\t\n\t var ToolSearchView = Backbone.View.extend({\n\t tagName: 'div',\n\t id: 'tool-search',\n\t className: 'bar',\n\t\n\t events: {\n\t 'click': 'focus_and_select',\n\t 'keyup :input': 'query_changed',\n\t 'change :input': 'query_changed',\n\t 'click #search-clear-btn': 'clear'\n\t },\n\t\n\t render: function () {\n\t this.$el.append(templates.tool_search(this.model.toJSON()));\n\t if (!this.model.is_visible()) {\n\t this.$el.hide();\n\t }\n\t\n\t // Adjust top for issue 2907 depending on whether the messagebox is visible.\n\t if ($(\"#messagebox\").is(\":visible\")) {\n\t this.$el.css(\"top\", \"95px\");\n\t }\n\t\n\t this.$el.find('[title]').tooltip();\n\t return this;\n\t },\n\t\n\t focus_and_select: function () {\n\t this.$el.find(\":input\").focus().select();\n\t },\n\t\n\t clear: function () {\n\t this.model.clear_search();\n\t this.$el.find(\":input\").val('');\n\t this.focus_and_select();\n\t return false;\n\t },\n\t\n\t query_changed: function (evData) {\n\t // check for the 'clear key' (ESC) first\n\t if (this.model.attributes.clear_key && this.model.attributes.clear_key === evData.which) {\n\t this.clear();\n\t return false;\n\t }\n\t this.model.set(\"query\", this.$el.find(\":input\").val());\n\t }\n\t });\n\t\n\t /**\n\t * Tool panel view. Events triggered include:\n\t * tool_link_click(click event, tool_model)\n\t */\n\t var ToolPanelView = Backbone.View.extend({\n\t tagName: 'div',\n\t className: 'toolMenu',\n\t\n\t /**\n\t * Set up view.\n\t */\n\t initialize: function () {\n\t this.model.get('tool_search').on(\"change:results\", this.handle_search_results, this);\n\t },\n\t\n\t render: function () {\n\t var self = this;\n\t\n\t // Render search.\n\t var search_view = new ToolSearchView({ model: this.model.get('tool_search') });\n\t search_view.render();\n\t self.$el.append(search_view.$el);\n\t\n\t // Render panel.\n\t this.model.get('layout').each(function (panel_elt) {\n\t if (panel_elt instanceof ToolSection) {\n\t var section_title_view = new ToolSectionView({ model: panel_elt });\n\t section_title_view.render();\n\t self.$el.append(section_title_view.$el);\n\t } else if (panel_elt instanceof Tool) {\n\t var tool_view = new ToolLinkView({ model: panel_elt, className: \"toolTitleNoSection\" });\n\t tool_view.render();\n\t self.$el.append(tool_view.$el);\n\t } else if (panel_elt instanceof ToolSectionLabel) {\n\t var label_view = new ToolSectionLabelView({ model: panel_elt });\n\t label_view.render();\n\t self.$el.append(label_view.$el);\n\t }\n\t });\n\t\n\t // Setup tool link click eventing.\n\t self.$el.find(\"a.tool-link\").click(function (e) {\n\t // Tool id is always the first class.\n\t var tool_id = $(this).attr('class').split(/\\s+/)[0],\n\t tool = self.model.get('tools').get(tool_id);\n\t\n\t self.trigger(\"tool_link_click\", e, tool);\n\t });\n\t\n\t return this;\n\t },\n\t\n\t handle_search_results: function () {\n\t var results = this.model.get('tool_search').get('results');\n\t if (results && results.length === 0) {\n\t $(\"#search-no-results\").show();\n\t } else {\n\t $(\"#search-no-results\").hide();\n\t }\n\t }\n\t });\n\t\n\t /**\n\t * View for working with a tool: setting parameters and inputs and executing the tool.\n\t */\n\t var ToolFormView = Backbone.View.extend({\n\t className: 'toolForm',\n\t\n\t render: function () {\n\t this.$el.children().remove();\n\t this.$el.append(templates.tool_form(this.model.toJSON()));\n\t }\n\t });\n\t\n\t /**\n\t * Integrated tool menu + tool execution.\n\t */\n\t var IntegratedToolMenuAndView = Backbone.View.extend({\n\t className: 'toolMenuAndView',\n\t\n\t initialize: function () {\n\t this.tool_panel_view = new ToolPanelView({ collection: this.collection });\n\t this.tool_form_view = new ToolFormView();\n\t },\n\t\n\t render: function () {\n\t // Render and append tool panel.\n\t this.tool_panel_view.render();\n\t this.tool_panel_view.$el.css(\"float\", \"left\");\n\t this.$el.append(this.tool_panel_view.$el);\n\t\n\t // Append tool form view.\n\t this.tool_form_view.$el.hide();\n\t this.$el.append(this.tool_form_view.$el);\n\t\n\t // On tool link click, show tool.\n\t var self = this;\n\t this.tool_panel_view.on(\"tool_link_click\", function (e, tool) {\n\t // Prevents click from activating link:\n\t e.preventDefault();\n\t // Show tool that was clicked on:\n\t self.show_tool(tool);\n\t });\n\t },\n\t\n\t /**\n\t * Fetch and display tool.\n\t */\n\t show_tool: function (tool) {\n\t var self = this;\n\t tool.fetch().done(function () {\n\t self.tool_form_view.model = tool;\n\t self.tool_form_view.render();\n\t self.tool_form_view.$el.show();\n\t $('#left').width(\"650px\");\n\t });\n\t }\n\t });\n\t\n\t // TODO: move into relevant views\n\t var templates = {\n\t // the search bar at the top of the tool panel\n\t tool_search: _.template(['\" autocomplete=\"off\" type=\"text\" />', ' ',\n\t //TODO: replace with icon\n\t ''].join('')),\n\t\n\t // the category level container in the tool panel (e.g. 'Get Data', 'Text Manipulation')\n\t panel_section: _.template(['
    \">', '<%- name %>', '
    ', '
    \" class=\"toolSectionBody\" style=\"display: none;\">', '
    ', '
    '].join('')),\n\t\n\t // a single tool's link in the tool panel; will load the tool form in the center panel\n\t tool_link: _.template(['', '<% _.each( labels, function( label ){ %>', '\">', '<%- label %>', '', '<% }); %>', '', ' tool-link\" href=\"<%= link %>\" target=\"<%- target %>\" minsizehint=\"<%- min_width %>\">', '<%- name %>', '', ' <%- description %>'].join('')),\n\t\n\t // the tool form for entering tool parameters, viewing help and executing the tool\n\t // loaded when a tool link is clicked in the tool panel\n\t tool_form: _.template(['
    <%- tool.name %> (version <%- tool.version %>)
    ', '
    ', '<% _.each( tool.inputs, function( input ){ %>', '
    ', '', '
    ', '<%= input.html %>', '
    ', '
    ', '<%- input.help %>', '
    ', '
    ', '
    ', '<% }); %>', '
    ', '
    ', '', '
    ', '
    ', '
    <% tool.help %>
    ', '
    '].join(''), { variable: 'tool' })\n\t };\n\t\n\t // Exports\n\t return {\n\t ToolParameter: ToolParameter,\n\t IntegerToolParameter: IntegerToolParameter,\n\t SelectToolParameter: SelectToolParameter,\n\t Tool: Tool,\n\t ToolCollection: ToolCollection,\n\t ToolSearch: ToolSearch,\n\t ToolPanel: ToolPanel,\n\t ToolPanelView: ToolPanelView,\n\t ToolFormView: ToolFormView\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(1)))\n\n/***/ },\n/* 61 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, $) {/** Renders the color picker used e.g. in the tool form **/\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(4)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Utils) {\n\t return Backbone.View.extend({\n\t colors: {\n\t standard: ['c00000', 'ff0000', 'ffc000', 'ffff00', '92d050', '00b050', '00b0f0', '0070c0', '002060', '7030a0'],\n\t base: ['ffffff', '000000', 'eeece1', '1f497d', '4f81bd', 'c0504d', '9bbb59', '8064a2', '4bacc6', 'f79646'],\n\t theme: [['f2f2f2', '7f7f7f', 'ddd9c3', 'c6d9f0', 'dbe5f1', 'f2dcdb', 'ebf1dd', 'e5e0ec', 'dbeef3', 'fdeada'], ['d8d8d8', '595959', 'c4bd97', '8db3e2', 'b8cce4', 'e5b9b7', 'd7e3bc', 'ccc1d9', 'b7dde8', 'fbd5b5'], ['bfbfbf', '3f3f3f', '938953', '548dd4', '95b3d7', 'd99694', 'c3d69b', 'b2a2c7', '92cddc', 'fac08f'], ['a5a5a5', '262626', '494429', '17365d', '366092', '953734', '76923c', '5f497a', '31859b', 'e36c09'], ['7f7f7e', '0c0c0c', '1d1b10', '0f243e', '244061', '632423', '4f6128', '3f3151', '205867', '974806']]\n\t },\n\t\n\t initialize: function (options) {\n\t this.options = Utils.merge(options, {});\n\t this.setElement(this._template());\n\t this.$panel = this.$('.ui-color-picker-panel');\n\t this.$view = this.$('.ui-color-picker-view');\n\t this.$value = this.$('.ui-color-picker-value');\n\t this.$header = this.$('.ui-color-picker-header');\n\t this._build();\n\t this.visible = false;\n\t this.value(this.options.value);\n\t this.$boxes = this.$('.ui-color-picker-box');\n\t var self = this;\n\t this.$boxes.on('click', function () {\n\t self.value($(this).css('background-color'));\n\t self.$header.trigger('click');\n\t });\n\t this.$header.on('click', function () {\n\t self.visible = !self.visible;\n\t if (self.visible) {\n\t self.$view.fadeIn('fast');\n\t } else {\n\t self.$view.fadeOut('fast');\n\t }\n\t });\n\t },\n\t\n\t /** Get/set value */\n\t value: function (new_val) {\n\t if (new_val !== undefined && new_val !== null) {\n\t this.$value.css('background-color', new_val);\n\t this.$('.ui-color-picker-box').empty();\n\t this.$(this._getValue()).html(this._templateCheck());\n\t this.options.onchange && this.options.onchange(new_val);\n\t }\n\t return this._getValue();\n\t },\n\t\n\t /** Get value from dom */\n\t _getValue: function () {\n\t var rgb = this.$value.css('background-color');\n\t rgb = rgb.match(/^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$/);\n\t if (rgb) {\n\t function hex(x) {\n\t return ('0' + parseInt(x).toString(16)).slice(-2);\n\t }\n\t return '#' + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);\n\t } else {\n\t return null;\n\t }\n\t },\n\t\n\t /** Build color panel */\n\t _build: function () {\n\t this._content({ colors: this.colors.base });\n\t for (var i in this.colors.theme) {\n\t var line_def = {};\n\t if (i == 0) {\n\t line_def['bottom'] = true;\n\t } else if (i != this.colors.theme.length - 1) {\n\t line_def['top'] = true;\n\t line_def['bottom'] = true;\n\t } else {\n\t line_def['top'] = true;\n\t }\n\t line_def['colors'] = this.colors.theme[i];\n\t this._content(line_def);\n\t }\n\t this._content({ colors: this.colors.standard });\n\t },\n\t\n\t /** Create content */\n\t _content: function (options) {\n\t var colors = options.colors;\n\t var $content = $(this._templateContent());\n\t var $line = $content.find('.line');\n\t this.$panel.append($content);\n\t for (var i in colors) {\n\t var $box = $(this._templateBox(colors[i]));\n\t if (options.top) {\n\t $box.css('border-top', 'none');\n\t $box.css('border-top-left-radius', '0px');\n\t $box.css('border-top-right-radius', '0px');\n\t }\n\t if (options.bottom) {\n\t $box.css('border-bottom', 'none');\n\t $box.css('border-bottom-left-radius', '0px');\n\t $box.css('border-bottom-right-radius', '0px');\n\t }\n\t $line.append($box);\n\t }\n\t return $content;\n\t },\n\t\n\t /** Check icon */\n\t _templateCheck: function () {\n\t return '
    ';\n\t },\n\t\n\t /** Content template */\n\t _templateContent: function () {\n\t return '
    ' + '
    ' + '
    ';\n\t },\n\t\n\t /** Box template */\n\t _templateBox: function (color) {\n\t return '
    ';\n\t },\n\t\n\t /** Main template */\n\t _template: function () {\n\t return '
    ' + '
    ' + '
    ' + '
    Select a color
    ' + '
    ' + '
    ' + '
    ' + '
    ';\n\t '
    ';\n\t }\n\t });\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(1)))\n\n/***/ },\n/* 62 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, $, _) {!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(4), __webpack_require__(7), __webpack_require__(16)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Utils, Ui, Select) {\n\t\n\t /** Batch mode variations */\n\t var Batch = { DISABLED: 'disabled', ENABLED: 'enabled', LINKED: 'linked' };\n\t\n\t /** List of available content selectors options */\n\t var Configurations = {\n\t data: [{ src: 'hda', icon: 'fa-file-o', tooltip: 'Single dataset', multiple: false, batch: Batch.DISABLED }, { src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', multiple: true, batch: Batch.LINKED }, { src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.LINKED }],\n\t data_multiple: [{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', multiple: true, batch: Batch.DISABLED }, { src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collections', multiple: true, batch: Batch.DISABLED }],\n\t data_collection: [{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.DISABLED }],\n\t workflow_data: [{ src: 'hda', icon: 'fa-file-o', tooltip: 'Single dataset', multiple: false, batch: Batch.DISABLED }],\n\t workflow_data_multiple: [{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', multiple: true, batch: Batch.DISABLED }],\n\t workflow_data_collection: [{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.DISABLED }],\n\t module_data: [{ src: 'hda', icon: 'fa-file-o', tooltip: 'Single dataset', multiple: false, batch: Batch.DISABLED }, { src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', multiple: true, batch: Batch.ENABLED }],\n\t module_data_collection: [{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.DISABLED }, { src: 'hdca', icon: 'fa-folder', tooltip: 'Multiple collections', multiple: true, batch: Batch.ENABLED }]\n\t };\n\t\n\t /** View for hda and hdca content selector ui elements */\n\t var View = Backbone.View.extend({\n\t initialize: function (options) {\n\t var self = this;\n\t this.model = options && options.model || new Backbone.Model({\n\t src_labels: { 'hda': 'dataset', 'hdca': 'dataset collection' },\n\t pagelimit: 100,\n\t statustimer: 1000\n\t }).set(options);\n\t this.setElement($('
    ').addClass('ui-select-content'));\n\t this.button_product = new Ui.RadioButton.View({\n\t value: 'false',\n\t data: [{ icon: 'fa fa-chain', value: 'false',\n\t tooltip: 'Linked inputs will be run in matched order with other datasets e.g. use this for matching forward and reverse reads.' }, { icon: 'fa fa-chain-broken', value: 'true',\n\t tooltip: 'Unlinked dataset inputs will be run against *all* other inputs.' }] });\n\t var $batch_div = $('
    ').addClass('ui-form-info').append($('').addClass('fa fa-sitemap')).append($('').html('This is a batch mode input field. Separate jobs will be triggered for each dataset selection.'));\n\t this.$batch = {\n\t linked: $batch_div.clone(),\n\t enabled: $batch_div.clone().append($('
    ').append($('
    ').addClass('ui-form-title').html('Batch options:')).append(this.button_product.$el)).append($('
    ').css('clear', 'both'))\n\t };\n\t\n\t // add drag-drop event handlers\n\t this.$el.on('dragenter', function (e) {\n\t this.lastenter = e.target;self.$el.addClass('ui-dragover');\n\t }).on('dragover', function (e) {\n\t e.preventDefault();\n\t }).on('dragleave', function (e) {\n\t this.lastenter === e.target && self.$el.removeClass('ui-dragover');\n\t }).on('drop', function (e) {\n\t self._handleDrop(e);\n\t });\n\t\n\t // track current history elements\n\t this.history = {};\n\t\n\t // add listeners\n\t this.listenTo(this.model, 'change:data', this._changeData, this);\n\t this.listenTo(this.model, 'change:wait', this._changeWait, this);\n\t this.listenTo(this.model, 'change:current', this._changeCurrent, this);\n\t this.listenTo(this.model, 'change:value', this._changeValue, this);\n\t this.listenTo(this.model, 'change:type change:optional change:multiple change:extensions', this._changeType, this);\n\t this.render();\n\t\n\t // add change event\n\t this.on('change', function () {\n\t options.onchange && options.onchange(self.value());\n\t });\n\t },\n\t\n\t render: function () {\n\t this._changeType();\n\t this._changeValue();\n\t this._changeWait();\n\t },\n\t\n\t /** Indicate that select fields are being updated */\n\t wait: function () {\n\t this.model.set('wait', true);\n\t },\n\t\n\t /** Indicate that the options update has been completed */\n\t unwait: function () {\n\t this.model.set('wait', false);\n\t },\n\t\n\t /** Update data representing selectable options */\n\t update: function (options) {\n\t this.model.set('data', options);\n\t },\n\t\n\t /** Return the currently selected dataset values */\n\t value: function (new_value) {\n\t new_value !== undefined && this.model.set('value', new_value);\n\t var current = this.model.get('current');\n\t if (this.config[current]) {\n\t var id_list = this.fields[current].value();\n\t if (id_list !== null) {\n\t id_list = $.isArray(id_list) ? id_list : [id_list];\n\t if (id_list.length > 0) {\n\t var result = this._batch({ values: [] });\n\t for (var i in id_list) {\n\t var details = this.history[id_list[i] + '_' + this.config[current].src];\n\t if (details) {\n\t result.values.push(details);\n\t } else {\n\t Galaxy.emit.debug('ui-select-content::value()', 'Requested details not found for \\'' + id_list[i] + '\\'.');\n\t return null;\n\t }\n\t }\n\t result.values.sort(function (a, b) {\n\t return a.hid - b.hid;\n\t });\n\t return result;\n\t }\n\t }\n\t } else {\n\t Galaxy.emit.debug('ui-select-content::value()', 'Invalid value/source \\'' + new_value + '\\'.');\n\t }\n\t return null;\n\t },\n\t\n\t /** Change of current select field */\n\t _changeCurrent: function () {\n\t var self = this;\n\t _.each(this.fields, function (field, i) {\n\t if (self.model.get('current') == i) {\n\t field.$el.show();\n\t _.each(self.$batch, function ($batchfield, batchmode) {\n\t $batchfield[self.config[i].batch == batchmode ? 'show' : 'hide']();\n\t });\n\t self.button_type.value(i);\n\t } else {\n\t field.$el.hide();\n\t }\n\t });\n\t },\n\t\n\t /** Change of type */\n\t _changeType: function () {\n\t var self = this;\n\t\n\t // identify selector type identifier i.e. [ flavor ]_[ type ]_[ multiple ]\n\t var config_id = (this.model.get('flavor') ? this.model.get('flavor') + '_' : '') + String(this.model.get('type')) + (this.model.get('multiple') ? '_multiple' : '');\n\t if (Configurations[config_id]) {\n\t this.config = Configurations[config_id];\n\t } else {\n\t this.config = Configurations['data'];\n\t Galaxy.emit.debug('ui-select-content::_changeType()', 'Invalid configuration/type id \\'' + config_id + '\\'.');\n\t }\n\t\n\t // prepare extension component of error message\n\t var data = self.model.get('data');\n\t var extensions = Utils.textify(this.model.get('extensions'));\n\t var src_labels = this.model.get('src_labels');\n\t\n\t // build views\n\t this.fields = [];\n\t this.button_data = [];\n\t _.each(this.config, function (c, i) {\n\t self.button_data.push({\n\t value: i,\n\t icon: c.icon,\n\t tooltip: c.tooltip\n\t });\n\t self.fields.push(new Select.View({\n\t optional: self.model.get('optional'),\n\t multiple: c.multiple,\n\t searchable: !c.multiple || data && data[c.src] && data[c.src].length > self.model.get('pagelimit'),\n\t selectall: false,\n\t error_text: 'No ' + (extensions ? extensions + ' ' : '') + (src_labels[c.src] || 'content') + ' available.',\n\t onchange: function () {\n\t self.trigger('change');\n\t }\n\t }));\n\t });\n\t this.button_type = new Ui.RadioButton.View({\n\t value: this.model.get('current'),\n\t data: this.button_data,\n\t onchange: function (value) {\n\t self.model.set('current', value);\n\t self.trigger('change');\n\t }\n\t });\n\t\n\t // append views\n\t this.$el.empty();\n\t var button_width = 0;\n\t if (this.fields.length > 1) {\n\t this.$el.append(this.button_type.$el);\n\t button_width = Math.max(0, this.fields.length * 36) + 'px';\n\t }\n\t _.each(this.fields, function (field) {\n\t self.$el.append(field.$el.css({ 'margin-left': button_width }));\n\t });\n\t _.each(this.$batch, function ($batchfield, batchmode) {\n\t self.$el.append($batchfield.css({ 'margin-left': button_width }));\n\t });\n\t this.model.set('current', 0);\n\t this._changeCurrent();\n\t this._changeData();\n\t },\n\t\n\t /** Change of wait flag */\n\t _changeWait: function () {\n\t var self = this;\n\t _.each(this.fields, function (field) {\n\t field[self.model.get('wait') ? 'wait' : 'unwait']();\n\t });\n\t },\n\t\n\t /** Change of available options */\n\t _changeData: function () {\n\t var options = this.model.get('data');\n\t var self = this;\n\t var select_options = {};\n\t _.each(options, function (items, src) {\n\t select_options[src] = [];\n\t _.each(items, function (item) {\n\t select_options[src].push({\n\t hid: item.hid,\n\t keep: item.keep,\n\t label: item.hid + ': ' + item.name,\n\t value: item.id,\n\t tags: item.tags\n\t });\n\t self.history[item.id + '_' + src] = item;\n\t });\n\t });\n\t _.each(this.config, function (c, i) {\n\t select_options[c.src] && self.fields[i].add(select_options[c.src], function (a, b) {\n\t return b.hid - a.hid;\n\t });\n\t });\n\t },\n\t\n\t /** Change of incoming value */\n\t _changeValue: function () {\n\t var new_value = this.model.get('value');\n\t if (new_value && new_value.values && new_value.values.length > 0) {\n\t // create list with content ids\n\t var list = [];\n\t _.each(new_value.values, function (value) {\n\t list.push(value.id);\n\t });\n\t // sniff first suitable field type from config list\n\t var src = new_value.values[0].src;\n\t var multiple = new_value.values.length > 1;\n\t for (var i = 0; i < this.config.length; i++) {\n\t var field = this.fields[i];\n\t var c = this.config[i];\n\t if (c.src == src && [multiple, true].indexOf(c.multiple) !== -1) {\n\t this.model.set('current', i);\n\t field.value(list);\n\t break;\n\t }\n\t }\n\t } else {\n\t _.each(this.fields, function (field) {\n\t field.value(null);\n\t });\n\t }\n\t },\n\t\n\t /** Handles drop events e.g. from history panel */\n\t _handleDrop: function (ev) {\n\t try {\n\t var data = this.model.get('data');\n\t var current = this.model.get('current');\n\t var config = this.config[current];\n\t var field = this.fields[current];\n\t var drop_data = JSON.parse(ev.originalEvent.dataTransfer.getData('text'))[0];\n\t var new_id = drop_data.id;\n\t var new_src = drop_data.history_content_type == 'dataset' ? 'hda' : 'hdca';\n\t var new_value = { id: new_id, src: new_src };\n\t if (data && _.findWhere(data[new_src], new_value)) {\n\t if (config.src == new_src) {\n\t var current_value = field.value();\n\t if (current_value && config.multiple) {\n\t if (current_value.indexOf(new_id) == -1) {\n\t current_value.push(new_id);\n\t }\n\t } else {\n\t current_value = new_id;\n\t }\n\t field.value(current_value);\n\t } else {\n\t this.model.set('value', { values: [new_value] });\n\t this.model.trigger('change:value');\n\t }\n\t this.trigger('change');\n\t this._handleDropStatus('success');\n\t } else {\n\t this._handleDropStatus('danger');\n\t }\n\t } catch (e) {\n\t this._handleDropStatus('danger');\n\t }\n\t },\n\t\n\t /** Highlight drag result */\n\t _handleDropStatus: function (status) {\n\t var self = this;\n\t this.$el.removeClass('ui-dragover').addClass('ui-dragover-' + status);\n\t setTimeout(function () {\n\t self.$el.removeClass('ui-dragover-' + status);\n\t }, this.model.get('statustimer'));\n\t },\n\t\n\t /** Assists in identifying the batch mode */\n\t _batch: function (result) {\n\t result['batch'] = false;\n\t var current = this.model.get('current');\n\t var config = this.config[current];\n\t if (config.src == 'hdca' && !config.multiple) {\n\t var hdca = this.history[this.fields[current].value() + '_hdca'];\n\t if (hdca && hdca.map_over_type) {\n\t result['batch'] = true;\n\t }\n\t }\n\t if (config.batch == Batch.LINKED || config.batch == Batch.ENABLED) {\n\t result['batch'] = true;\n\t if (config.batch == Batch.ENABLED && this.button_product.value() === 'true') {\n\t result['product'] = true;\n\t }\n\t }\n\t return result;\n\t }\n\t });\n\t\n\t return {\n\t View: View\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(1), __webpack_require__(2)))\n\n/***/ },\n/* 63 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone) {// dependencies\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(4), __webpack_require__(28)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Utils, List) {\n\t\n\t /**\n\t * FTP file selector\n\t */\n\t var View = Backbone.View.extend({\n\t // initialize\n\t initialize: function (options) {\n\t // link this\n\t var self = this;\n\t\n\t // create ui-list view to keep track of selected ftp files\n\t this.ftpfile_list = new List.View({\n\t name: 'file',\n\t optional: options.optional,\n\t multiple: options.multiple,\n\t onchange: function () {\n\t options.onchange && options.onchange(self.value());\n\t }\n\t });\n\t\n\t // create elements\n\t this.setElement(this.ftpfile_list.$el);\n\t\n\t // initial fetch of ftps\n\t Utils.get({\n\t url: Galaxy.root + 'api/remote_files',\n\t success: function (response) {\n\t var data = [];\n\t for (var i in response) {\n\t data.push({\n\t value: response[i]['path'],\n\t label: response[i]['path']\n\t });\n\t }\n\t self.ftpfile_list.update(data);\n\t }\n\t });\n\t },\n\t\n\t /** Return/Set currently selected ftp datasets */\n\t value: function (val) {\n\t return this.ftpfile_list.value(val);\n\t }\n\t });\n\t\n\t return {\n\t View: View\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))\n\n/***/ },\n/* 64 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone) {// dependencies\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(4), __webpack_require__(7), __webpack_require__(36), __webpack_require__(28)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Utils, Ui, Table, List) {\n\t\n\t // collection of libraries\n\t var Libraries = Backbone.Collection.extend({\n\t url: Galaxy.root + 'api/libraries?deleted=false'\n\t });\n\t\n\t // collection of dataset\n\t var LibraryDatasets = Backbone.Collection.extend({\n\t initialize: function () {\n\t var self = this;\n\t this.config = new Backbone.Model({ library_id: null });\n\t this.config.on('change', function () {\n\t self.fetch({ reset: true });\n\t });\n\t },\n\t url: function () {\n\t return Galaxy.root + 'api/libraries/' + this.config.get('library_id') + '/contents';\n\t }\n\t });\n\t\n\t // hda/hdca content selector ui element\n\t var View = Backbone.View.extend({\n\t // initialize\n\t initialize: function (options) {\n\t // link this\n\t var self = this;\n\t\n\t // collections\n\t this.libraries = new Libraries();\n\t this.datasets = new LibraryDatasets();\n\t\n\t // link app and options\n\t this.options = options;\n\t\n\t // select field for the library\n\t // TODO: Remove this once the library API supports searching for library datasets\n\t this.library_select = new Ui.Select.View({\n\t onchange: function (value) {\n\t self.datasets.config.set('library_id', value);\n\t }\n\t });\n\t\n\t // create ui-list view to keep track of selected data libraries\n\t this.dataset_list = new List.View({\n\t name: 'dataset',\n\t optional: options.optional,\n\t multiple: options.multiple,\n\t onchange: function () {\n\t self.trigger('change');\n\t }\n\t });\n\t\n\t // add reset handler for fetched libraries\n\t this.libraries.on('reset', function () {\n\t var data = [];\n\t self.libraries.each(function (model) {\n\t data.push({\n\t value: model.id,\n\t label: model.get('name')\n\t });\n\t });\n\t self.library_select.update(data);\n\t });\n\t\n\t // add reset handler for fetched library datasets\n\t this.datasets.on('reset', function () {\n\t var data = [];\n\t var library_current = self.library_select.text();\n\t if (library_current !== null) {\n\t self.datasets.each(function (model) {\n\t if (model.get('type') === 'file') {\n\t data.push({\n\t value: model.id,\n\t label: model.get('name')\n\t });\n\t }\n\t });\n\t }\n\t self.dataset_list.update(data);\n\t });\n\t\n\t // add change event. fires on trigger\n\t this.on('change', function () {\n\t options.onchange && options.onchange(self.value());\n\t });\n\t\n\t // create elements\n\t this.setElement(this._template());\n\t this.$('.library-select').append(this.library_select.$el);\n\t this.$el.append(this.dataset_list.$el);\n\t\n\t // initial fetch of libraries\n\t this.libraries.fetch({\n\t reset: true,\n\t success: function () {\n\t self.library_select.trigger('change');\n\t if (self.options.value !== undefined) {\n\t self.value(self.options.value);\n\t }\n\t }\n\t });\n\t },\n\t\n\t /** Return/Set currently selected library datasets */\n\t value: function (val) {\n\t return this.dataset_list.value(val);\n\t },\n\t\n\t /** Template */\n\t _template: function () {\n\t return '
    ' + '
    ' + 'Select Library' + '' + '
    ' + '
    ';\n\t }\n\t });\n\t\n\t return {\n\t View: View\n\t };\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))\n\n/***/ },\n/* 65 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Backbone, $) {/**\n\t * Renders tabs e.g. used in the charts editor, behaves similar to repeat and section rendering\n\t */\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(4)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Utils) {\n\t var View = Backbone.View.extend({\n\t initialize: function (options) {\n\t var self = this;\n\t this.collection = new Backbone.Collection();\n\t this.model = options && options.model || new Backbone.Model({\n\t onchange: null,\n\t visible: true\n\t }).set(options);\n\t this.setElement($(this._template()));\n\t this.$nav = this.$('.tab-navigation');\n\t this.$content = this.$('.tab-content');\n\t this.$el.on('click', function () {\n\t $('.tooltip').hide();\n\t });\n\t this.render();\n\t this.listenTo(this.model, 'change', this.render, this);\n\t this.listenTo(this.collection, 'add', this._add, this);\n\t this.listenTo(this.collection, 'remove', this._remove, this);\n\t this.listenTo(this.collection, 'change', this._change, this);\n\t this.listenTo(this.collection, 'reset', this._reset, this);\n\t this.listenTo(this.collection, 'add remove reset', this.render, this);\n\t },\n\t\n\t render: function () {\n\t var id = this.model.get('current');\n\t id = this.$('#' + id).length > 0 ? id : this.first();\n\t if (id) {\n\t this.$nav.children().removeClass('active');\n\t this.$content.children().removeClass('active');\n\t this.$('#tab-' + id).addClass('active');\n\t this.$('#' + id).addClass('active');\n\t }\n\t this.$el[this.model.get('visible') ? 'fadeIn' : 'fadeOut']('fast');\n\t this.$nav[this.size() > 1 ? 'show' : 'hide']();\n\t },\n\t\n\t /** Returns tab id for currently shown tab */\n\t current: function () {\n\t return this.model.get('current');\n\t },\n\t\n\t /** Show tab view and highlight a tab by id */\n\t show: function (id) {\n\t if (id) {\n\t this.model.set({ 'current': id, 'visible': true });\n\t this.model.get('onchange') && this.model.get('onchange')(id);\n\t }\n\t },\n\t\n\t /** Hide tab view */\n\t hide: function () {\n\t this.model.set('visible', false);\n\t },\n\t\n\t /** Returns first tab */\n\t first: function () {\n\t var model = this.collection.first();\n\t return model && model.id;\n\t },\n\t\n\t /** Returns current number of tabs */\n\t size: function () {\n\t return this.collection.length;\n\t },\n\t\n\t /** Adds a new tab */\n\t add: function (options) {\n\t this.collection.add(options);\n\t },\n\t\n\t /** Delete tab */\n\t del: function (id) {\n\t this.collection.remove(id);\n\t },\n\t\n\t /** Delete all tabs */\n\t delAll: function () {\n\t this.collection.reset();\n\t },\n\t\n\t /** Show tab */\n\t showTab: function (id) {\n\t this.collection.get(id).set('hidden', false);\n\t },\n\t\n\t /** Hide tab */\n\t hideTab: function (id) {\n\t this.collection.get(id).set('hidden', true);\n\t },\n\t\n\t /** Adds a new tab */\n\t _add: function (tab_model) {\n\t var self = this;\n\t var options = tab_model.attributes;\n\t this.$content.append($('
    ').attr('id', options.id).addClass('tab-pane').append(options.$el));\n\t this.$nav.append($(this._template_tab(options)).show().tooltip({ title: options.tooltip, placement: 'bottom', container: self.$el }).on('click', function (e) {\n\t e.preventDefault();\n\t self.show(options.id);\n\t }));\n\t if (this.size() == 1) {\n\t this.show(options.id);\n\t }\n\t },\n\t\n\t /** Delete tab */\n\t _remove: function (tab_model) {\n\t this.$('#tab-' + tab_model.id).remove();\n\t this.$('#' + tab_model.id).remove();\n\t },\n\t\n\t /** Reset collection */\n\t _reset: function () {\n\t this.$nav.empty();\n\t this.$content.empty();\n\t },\n\t\n\t /** Change tab */\n\t _change: function (tab_model) {\n\t this.$('#tab-' + tab_model.id)[tab_model.get('hidden') ? 'hide' : 'show']();\n\t },\n\t\n\t /** Main template */\n\t _template: function () {\n\t return $('
    ').addClass('ui-tabs tabbable tabs-left').append($('