[tryton-debian-vcs] tryton-sao branch debian updated. debian/4.2.3-1-2-g5f268ea

Mathias Behrle tryton-debian-vcs at alioth.debian.org
Wed Jun 7 13:30:42 UTC 2017


The following commit has been merged in the debian branch:
https://alioth.debian.org/plugins/scmgit/cgi-bin/gitweb.cgi/?p=tryton/tryton-sao.git;a=commitdiff;h=debian/4.2.3-1-2-g5f268ea

commit 5f268eaaf2472c32b102a349f7ffe0d9643f7c69
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Wed Jun 7 15:27:37 2017 +0200

    Merging upstream version 4.4.1.

diff --git a/CHANGELOG b/CHANGELOG
index d03a883..5153e03 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+Version 4.4.1 - 2017-06-05
+* Bug fixes (see mercurial logs for details)
+
 Version 4.4.0 - 2017-05-01
 * Bug fixes (see mercurial logs for details)
 * Manage help attribute on tree views
diff --git a/dist/tryton-sao.js b/dist/tryton-sao.js
index 764bfe1..371722b 100644
--- a/dist/tryton-sao.js
+++ b/dist/tryton-sao.js
@@ -6451,7 +6451,7 @@ var Sao = {};
             }
             var prm = jQuery.when();
             if (this.current_view.view_type == 'calendar') {
-                var selected_date = this.current_view.date;
+                var selected_date = this.current_view.get_selected_date();
                 prm = this.switch_view('form');
             }
             if (this.current_view &&
@@ -13827,7 +13827,8 @@ function eval_pyson(value){
             var model_access = Sao.common.MODELACCESS.get(
                 this.screen.model_name);
             if (model_access.create) {
-                this.date = date;
+                // Set the calendar date to the clicked date
+                this.el.fullCalendar('gotoDate', date);
                 this.screen.set_current_record(null);
                 this.screen.new_();
             }
@@ -13857,11 +13858,11 @@ function eval_pyson(value){
         },
         set_default_date: function(record, selected_date){
             var dtstart = this.attributes.dtstart;
-            if (record.model.fields[dtstart].description.type == 'datetime') {
-                selected_date = Sao.DateTime(selected_date.format()).utc();
-            }
-            record.field_set_client(dtstart, selected_date);
+            record.field_set(dtstart, selected_date);
         },
+        get_selected_date: function(){
+            return this.el.fullCalendar('getDate');
+        }
     });
 
 }());
@@ -13917,7 +13918,7 @@ function eval_pyson(value){
         var name_prm;
         switch (action.type) {
             case 'ir.action.act_window':
-                params.view_ids = false;
+                params.view_ids = [];
                 params.mode = null;
                 if (!jQuery.isEmptyObject(action.views)) {
                     params.view_ids = [];
@@ -13939,18 +13940,16 @@ function eval_pyson(value){
                     active_ids: data.ids
                 };
                 ctx = jQuery.extend(ctx, session.context);
-                var eval_ctx = jQuery.extend({}, ctx);
-                eval_ctx._user = session.user_id;
+                ctx._user = session.user_id;
+                var decoder = new Sao.PYSON.Decoder(ctx);
                 params.context = jQuery.extend(
-                        {}, context, new Sao.PYSON.Decoder(eval_ctx).decode(
-                            action.pyson_context || '{}'));
+                    {}, context,
+                    decoder.decode( action.pyson_context || '{}'));
                 ctx = jQuery.extend(ctx, params.context);
                 ctx = jQuery.extend(ctx, context);
 
-                var domain_context = jQuery.extend({}, ctx);
-                domain_context.context = ctx;
-                domain_context._user = session.user_id;
-                var decoder = new Sao.PYSON.Decoder(domain_context);
+                ctx.context = ctx;
+                decoder = new Sao.PYSON.Decoder(ctx);
                 params.domain = decoder.decode(action.pyson_domain);
                 params.order = decoder.decode(action.pyson_order);
                 params.search_value = decoder.decode(
diff --git a/dist/tryton-sao.min.js b/dist/tryton-sao.min.js
index ce489cd..6d1e800 100644
--- a/dist/tryton-sao.min.js
+++ b/dist/tryton-sao.min.js
@@ -1,14 +1,14 @@
-/*! tryton-sao-4.4.0 | GPL-3
+/*! tryton-sao-4.4.1 | GPL-3
 This file is part of Tryton.  The COPYRIGHT file at the top level of
 this repository contains the full copyright notices and license terms. */
-function eval_pyson(value){with(Sao.PYSON.eval)return eval(value)}var Sao={};!function(){"use strict";function a(){var a=1040;jQuery(".modal.in").each(function(b){var c=jQuery(this);a++,c.css("zIndex",a),c.next(".modal-backdrop.in").addClass("hidden").css("zIndex",a-1)}),jQuery(".modal.in:visible:last").focus().next(".modal-backdrop.in").removeClass("hidden")}"contains"in String.prototype||(String.prototype.contains=function(a,b){return-1!==String.prototype.indexOf.call(this,a,b)}),String.prototype.startsWith||Object.defineProperty(String.prototype,"startsWith",{enumerable:!1,configurable:!1,writable:!1,value:function(a,b){return b=b||0,this.indexOf(a,b)===b}}),String.prototype.endsWith||Object.defineProperty(String.prototype,"endsWith",{enumerable:!1,configurable:!1,writable:!1,value:function(a,b){b=b||this.length,b-=a.length;var c=this.lastIndexOf(a);return-1!==c&&c===b}}),Array.prototype.some||(Array.prototype.some=function(a){if(null===this)throw new TypeError;var b,c,d=Object(this),e=d.length>>>0;if("function"!=typeof a)throw new TypeError;for(b=arguments[1],c=0;e>c;c++)if(c in d&&a.call(b,d[c],c,d))return!0;return!1});try{document.execCommand("styleWithCSS",!1,!1)}catch(b){}try{document.execCommand("useCSS",!1,!0)}catch(b){}jQuery.fn.extend({uniqueId:function(){var a=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})}}()}),Sao.class_=function(a,b){var c=function(){if(!(this instanceof c))throw new Error("Constructor function requires new operator");this.Class=c,this.init&&this.init.apply(this,arguments)};if(c.prototype=Object.create(a.prototype),c._super=a.prototype,b)for(var d in b)c.prototype[d]=b[d];return c},Sao.Decimal=Number,Sao.Date=function(a,b,c){var d=moment();return d.year(a),d.month(b),d.date(c),d.set({hour:0,minute:0,second:0,millisecond:0}),d.isDate=!0,d},Sao.Date.min=moment(new Date(-864e13)),Sao.Date.min.set({hour:0,minute:0,second:0,millisecond:0}),Sao.Date.min.isDate=!0,Sao.Date.max=moment(new Date(864e13)),Sao.Date.max.set({hour:0,minute:0,second:0,millisecond:0}),Sao.Date.max.isDate=!0,Sao.DateTime=function(a,b,c,d,e,f,g,h){var i;return void 0===b?(i=moment(a),a=void 0):i=moment(),h&&i.utc(),i.year(a),i.month(b),i.date(c),void 0!==b&&(i.hour(d||0),i.minute(e||0),i.second(f||0),i.milliseconds(g||0)),i.isDateTime=!0,i.local(),i},Sao.DateTime.combine=function(a,b){var c=a.clone();return c.set({hour:b.hour(),minute:b.minute(),second:b.second(),millisecond:b.millisecond()}),c.isDateTime=!0,c},Sao.DateTime.min=moment(new Date(-864e13)).local(),Sao.DateTime.min.isDateTime=!0,Sao.DateTime.max=moment(new Date(864e13)).local(),Sao.DateTime.max.isDateTime=!0,Sao.Time=function(a,b,c,d){var e=moment({hour:a,minute:b,second:c,millisecond:d||0});return e.isTime=!0,e},Sao.TimeDelta=function(a,b,c,d,e,f){var g=moment.duration({days:a,seconds:b,milliseconds:c,minutes:d,hours:e,weeks:f});return g.isTimeDelta=!0,g},Sao.config={},Sao.config.limit=1e3,Sao.config.display_size=20,Sao.config.roundup={},Sao.config.roundup.url="http://bugs.tryton.org/roundup/",Sao.config.title="Tryton",Sao.i18n=i18n(),Sao.i18n.setlang=function(a){return a||(a=(navigator.language||navigator.browserLanguage||navigator.userLanguage||"en").replace("-","_")),Sao.i18n.setLocale(a),moment.locale(a.slice(0,2)),jQuery.getJSON("locale/"+a+".json",function(b){b[""].language||(b[""].language=a),b[""]["plural-forms"]||(b[""]["plural-forms"]="nplurals=2; plural=(n!=1);");for(var c in b)""!==c&&(b[c]=2==b[c].length?b[c][1]:b[c].slice(1));Sao.i18n.loadJSON(b)})},Sao.i18n.getlang=function(){return Sao.i18n.getLocale()},Sao.i18n.setlang(),Sao.get_preferences=function(){var a=Sao.Session.current_session;return a.reload_context().then(function(){return Sao.rpc({method:"model.res.user.get_preferences",params:[!1,{}]},a).then(function(a){var b=[];return b.push(Sao.common.MODELACCESS.load_models()),b.push(Sao.common.ICONFACTORY.load_icons()),b.push(Sao.common.MODELHISTORY.load_history()),b.push(Sao.common.VIEW_SEARCH.load_searches()),jQuery.when.apply(jQuery,b).then(function(){(a.actions||[]).forEach(function(a){Sao.Action.execute(a,{},null,{})});var b=Sao.config.title;jQuery.isEmptyObject(a.status_bar)||(b+=" - "+a.status_bar),document.title=b;var c=a.language!=Sao.i18n.getLocale(),d=jQuery.Deferred();return Sao.i18n.setlang(a.language).always(function(){c&&Sao.user_menu(a),d.resolve(a)}),d})})})},Sao.login=function(){Sao.Session.get_credentials().then(function(a){return Sao.Session.current_session=a,a.reload_context()}).then(Sao.get_preferences).then(function(a){Sao.menu(a),Sao.user_menu(a)})},Sao.logout=function(){var a=Sao.Session.current_session;Sao.Tab.tabs.close(!0).done(function(){jQuery("#user-preferences").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#menu").children().remove(),document.title=Sao.config.title,a.do_logout().always(Sao.login)})},Sao.preferences=function(){Sao.Tab.tabs.close(!0).done(function(){jQuery("#user-preferences").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#menu").children().remove(),new Sao.Window.Preferences(function(){Sao.get_preferences().then(function(a){Sao.menu(a),Sao.user_menu(a)})})})},Sao.favorites_menu=function(){var a=function(){e&&e.remove()};if(jQuery(window).click(function(){a()}),0!==jQuery("#user-favorites").children(".dropdown-menu").length)a();else{var b=Sao.main_menu_screen.model_name+".favorite",c=Sao.Session.current_session,d={method:"model."+b+".get"},e=jQuery("<ul/>",{"class":"dropdown-menu","aria-expanded":"false"});jQuery("#user-favorites").append(e),Sao.rpc(d,c).then(function(b){b.forEach(function(b){var c=jQuery("<a/>",{href:"#"}),d=b[0],f=jQuery("<li/>",{role:"presentation"}),g=jQuery("<img/>",{"class":"favorite-icon"});c.append(g),f.append(c),g.attr("src",Sao.common.ICONFACTORY.get_icon_url(b[2])),c.append(b[1]),c.click(function(){a(),Sao.Action.exec_keyword("tree_open",{model:Sao.main_menu_screen.model_name,id:d,ids:[d]})}),e.append(f)}),e.append(jQuery("<li/>",{"class":"divider"})),jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{href:"#"}).click(function(){a(),Sao.Tab.create({model:Sao.main_menu_screen.model_name+".favorite",mode:["tree","form"],name:Sao.i18n.gettext("Manage favorites")})}).text(Sao.i18n.gettext("Manage favorites"))).appendTo(e)})}},Sao.user_menu=function(a){jQuery("#user-preferences").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#user-preferences").append(jQuery("<a/>",{href:"#"}).click(Sao.preferences).append(a.status_bar)),jQuery("#user-logout").append(jQuery("<a/>",{href:"#"}).click(Sao.logout).append(Sao.i18n.gettext("Logout"))),jQuery("#user-favorites").append(jQuery("<a/>",{href:"#","data-toggle":"dropdown"}).click(Sao.favorites_menu).append(Sao.i18n.gettext("Favorites")))},Sao.menu=function(a){var b=new Sao.PYSON.Decoder,d=b.decode(a.pyson_menu),e=!1;jQuery.isEmptyObject(d.views)?d.view_id&&(e=[d.view_id[0]]):e=d.views.map(function(a){return a[0]}),b=new Sao.PYSON.Decoder(Sao.Session.current_session.context);var f=b.decode(d.pyson_context||"{}"),g=b.decode(d.pyson_domain),h=new Sao.Tab.Form(d.res_model,{mode:["tree"],view_ids:e,domain:g,context:f,selection_mode:Sao.common.SELECTION_NONE,limit:null});Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(h),1),h.view_prm.done(function(){Sao.main_menu_screen=h.screen;var a=h.screen.current_view;a.table.find("thead").hide(),jQuery("#menu").children().remove();var b=new Sao.GlobalSearch;jQuery("#menu").append(b.el),jQuery("#menu").append(h.screen.screen_container.content_box.detach()),h.screen.views[0].columns.push(new c(h.screen.model.fields.favorite))})},Sao.main_menu_screen=null;var c=Sao.class_(Object,{init:function(a){this.field=a,this.header=jQuery("<th/>"),this.attributes=jQuery.extend({},this.field.description),this.attributes.name=this.field.name},get_cell:function(){var a=jQuery("<span/>",{tabindex:0});return a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.field.name).done(function(){if(null!==a._values.favorite){var c="glyphicon glyphicon-star";a._values.favorite||(c+="-empty"),b.addClass(c),b.click({record:a,button:b},this.favorite_click)}}.bind(this)),b},favorite_click:function(a){a.stopImmediatePropagation();var b,c=a.data.button;c.hasClass("glyphicon-star-empty")?(c.removeClass("glyphicon-star-empty"),c.addClass("glyphicon-star"),b="set"):(c.removeClass("glyphicon-star"),c.addClass("glyphicon-star-empty"),b="unset");var d=Sao.main_menu_screen.model_name+".favorite",e=Sao.Session.current_session,f={method:"model."+d+"."+b,params:[a.data.record.id,e.context]};Sao.rpc(f,e)}});Sao.Dialog=Sao.class_(Object,{init:function(a,b,c){c=c||"sm",this.modal=jQuery("<div/>",{"class":b+" modal fade",role:"dialog","data-backdrop":"static"}),this.content=jQuery("<form/>",{"class":"modal-content"}).appendTo(jQuery("<div/>",{"class":"modal-dialog modal-"+c}).appendTo(this.modal)),this.header=jQuery("<div/>",{"class":"modal-header"}).appendTo(this.content),a&&this.add_title(a),this.body=jQuery("<div/>",{"class":"modal-body"}).appendTo(this.content),this.footer=jQuery("<div/>",{"class":"modal-footer"}).appendTo(this.content)},add_title:function(a){this.header.append(jQuery("<h4/>",{"class":"modal-title"}).append(a))}}),Sao.GlobalSearch=Sao.class_(Object,{init:function(){this.el=jQuery("<div/>",{"class":"global-search-container"}),this.search_entry=jQuery("<input>",{"class":"form-control",placeholder:Sao.i18n.gettext("Search...")}),this.el.append(this.search_entry);new Sao.common.InputCompletion(this.search_entry,this.update.bind(this),this.match_selected.bind(this),this.format.bind(this))},format:function(a){var b=jQuery("<div/>"),c=jQuery("<img/>",{"class":"global-search-icon"}).appendTo(b);return Sao.common.ICONFACTORY.register_icon(a.icon).then(function(a){c.attr("src",a)}),jQuery("<span/>",{"class":"global-search-text"}).text(a.record_name).appendTo(b),b},update:function(a){var b=new Sao.Model("ir.model");return b.execute("global_search",[a,Sao.config.limit,Sao.main_menu_screen.model_name],Sao.main_menu_screen.context).then(function(a){for(var b=[],c=0,d=a.length;d>c;c++)b.push({model:a[c][1],model_name:a[c][2],record_id:a[c][3],record_name:a[c][4],icon:a[c][5]});return b}.bind(this))},match_selected:function(a){if(a.model==Sao.main_menu_screen.model_name)Sao.Action.exec_keyword("tree_open",{model:a.model,id:a.record_id,ids:[a.record_id]},Sao.main_menu_screen.context);else{var b={model:a.model,res_id:a.record_id,mode:["form","tree"],name:a.model_name};Sao.Tab.create(b)}this.search_entry.val("")}}),jQuery(document).on("show.bs.modal",".modal",function(a){jQuery(this).appendTo(jQuery("body"))}).on("shown.bs.modal",".modal.in",function(b){a()}).on("hidden.bs.modal",".modal",function(b){a()})}(),function(){"use strict";Sao.rpc=function(a,b){var c=jQuery.Deferred();b||(b=new Sao.Session);var d=jQuery.extend([],a.params);d.push(jQuery.extend({},b.context,d.pop()));var e=Sao.common.processing.show(),f=jQuery.ajax({headers:{Authorization:"Session "+b.get_auth()},contentType:"application/json",data:JSON.stringify(Sao.rpc.prepareObject({id:Sao.rpc.id++,method:a.method,params:d})),dataType:"json",url:"/"+(b.database||"")+"/",type:"post",complete:[function(){Sao.common.processing.hide(e)}]}),g=function(d){if(null===d)Sao.common.warning.run("",Sao.i18n.gettext("Unable to reach the server")),c.reject();else if(d.error){var e,f,g;if("UserWarning"==d.error[0])return e=d.error[1][0],f=d.error[1][1],g=d.error[1][2],void Sao.common.userwarning.run(f,g).done(function(d){return~["always","ok"].indexOf(d)?void Sao.rpc({method:"model.res.user.warning.create",params:[[{user:b.user_id,name:e,always:"always"==d}],{}]},b).done(function(){Sao.rpc(a,b).then(c.resolve,c.reject)}):void c.reject()});if("UserError"==d.error[0])return f=d.error[1][0],g=d.error[1][1],void Sao.common.warning.run(g,f).always(c.reject);if("ConcurrencyException"==d.error[0]){if(a.method.startsWith("model.")&&(a.method.endsWith(".write")||a.method.endsWith(".delete"))){var h=a.method.split(".").slice(1,-1).join(".");return void Sao.common.concurrency.run(h,a.params[0][0],a.params.slice(-1)[0]).then(function(){delete a.params.slice(-1)[0]._timestamp,Sao.rpc(a,b).then(c.resolve,c.reject)},c.reject)}return void Sao.common.message.run("Concurrency Exception","glyphicon-alert").always(c.reject)}Sao.common.error.run(d.error[0],d.error[1]),c.reject()}else c.resolve(d.result)},h=function(d,e,f){return 403==d.status?void Sao.Session.renew(b).then(function(){Sao.rpc(a,b).then(c.resolve,c.reject)},c.reject):(Sao.common.error.run(e,f),void c.reject())};return f.success(g),f.error(h),c.promise()},Sao.rpc.id=0,Sao.rpc.convertJSONObject=function(a,b,c){if(a instanceof Array)for(var d=0,e=a.length;e>d;d++)Sao.rpc.convertJSONObject(a[d],d,a);else if("string"!=typeof a&&"number"!=typeof a&&null!==a)if(a&&a.__class__){switch(a.__class__){case"datetime":a=Sao.DateTime(a.year,a.month-1,a.day,a.hour,a.minute,a.second,a.microsecond/1e3,!0);break;case"date":a=Sao.Date(a.year,a.month-1,a.day);break;case"time":a=Sao.Time(a.hour,a.minute,a.second,a.microsecond/1e3);break;case"timedelta":a=Sao.TimeDelta(null,a.seconds);break;case"bytes":for(var f=atob(a.base64.replace(/\s/g,"")),g=new ArrayBuffer(f.length),h=new Uint8Array(g),i=0;i<f.length;i++)h[i]=f.charCodeAt(i);a=h;break;case"Decimal":a=new Sao.Decimal(a.decimal)}c&&(c[b]=a)}else for(var j in a)Sao.rpc.convertJSONObject(a[j],j,a);return c||a},Sao.rpc.prepareObject=function(a,b,c){if(a instanceof Array){a=jQuery.extend([],a);for(var d=0,e=a.length;e>d;d++)Sao.rpc.prepareObject(a[d],d,a)}else if("string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a&&null!==a&&void 0!==a)if(a.isDate)a={__class__:"date",year:a.year(),month:a.month()+1,day:a.date()};else if(a.isDateTime)a=a.clone(),a={__class__:"datetime",year:a.utc().year(),month:a.utc().month()+1,day:a.utc().date(),hour:a.utc().hour(),minute:a.utc().minute(),second:a.utc().second(),microsecond:1e3*a.utc().millisecond()};else if(a.isTime)a={__class__:"time",hour:a.hour(),minute:a.minute(),second:a.second(),microsecond:1e3*a.millisecond()};else if(a.isTimeDelta)a={__class__:"timedelta",seconds:a.asSeconds()};else if(a instanceof Sao.Decimal)a={__class__:"Decimal",decimal:a.toString()};else if(a instanceof Uint8Array){for(var f=[],g=65535,h=0;h*g<a.length;h++)f.push(String.fromCharCode.apply(null,a.subarray(h*g,(h+1)*g)));a={__class__:"bytes",base64:btoa(f.join(""))}}else{a=jQuery.extend({},a);for(var i in a)Sao.rpc.prepareObject(a[i],i,a)}return c&&(c[b]=a),c||a},jQuery.ajaxSetup({converters:{"text json":function(a){return Sao.rpc.convertJSONObject(jQuery.parseJSON(a))}}})}(),function(){"use strict";Sao.PYSON={},Sao.PYSON.eval={},Sao.PYSON.PYSON=Sao.class_(Object,{init:function(){},pyson:function(){throw"NotImplementedError"},types:function(){throw"NotImplementedError"},toString:function(){var a=this.pyson().__class__,b=this.__string_params__().map(function(a){return a instanceof Sao.PYSON.PYSON?a.toString():JSON.stringify(a)});return a+"("+b.join(", ")+")"},__string_params__:function(){throw"NotImplementedError"}}),Sao.PYSON.PYSON.eval_=function(a,b){throw"NotImplementedError"},Sao.PYSON.PYSON.init_from_object=function(a){throw"NotImplementedError"},Sao.PYSON.Encoder=Sao.class_(Object,{prepare:function(a,b,c){if(null!==a&&void 0!==a)if(a instanceof Array){a=jQuery.extend([],a);for(var d=0,e=a.length;e>d;d++)this.prepare(a[d],d,a)}else a._isAMomentObject&&(a=a.isDate?new Sao.PYSON.Date(a.year(),a.month()+1,a.date()).pyson():new Sao.PYSON.DateTime(a.year(),a.month()+1,a.date(),a.hours(),a.minutes(),a.seconds(),1e3*a.milliseconds()).pyson());return c&&(c[b]=a),c||a},encode:function(a){return a=this.prepare(a),JSON.stringify(a,function(a,b){return b instanceof Sao.PYSON.PYSON?b.pyson():null===b||void 0===b?null:b})}}),Sao.PYSON.Decoder=Sao.class_(Object,{init:function(a,b){this.__context=a||{},this.noeval=b||!1},decode:function(a){var b=function(a,b){if("object"==typeof b&&null!==b){var c=Sao.PYSON[b.__class__];if(c){if(this.noeval){var d=jQuery.extend({},b);return delete d.__class__,Sao.PYSON[b.__class__].init_from_object(d)}return c.eval_(b,this.__context)}}return b};return JSON.parse(a,b.bind(this))}}),Sao.PYSON.eval.Eval=function(a,b){return new Sao.PYSON.Eval(a,b)},Sao.PYSON.Eval=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){void 0===b&&(b=""),Sao.PYSON.Eval._super.init.call(this),this._value=a,this._default=b},pyson:function(){return{__class__:"Eval",v:this._value,d:this._default}},types:function(){return this._default instanceof Sao.PYSON.PYSON?this._default.types():[typeof this._default]},__string_params__:function(){return[this._value,this._default]}}),Sao.PYSON.Eval.eval_=function(a,b){return a.v in b?b[a.v]:a.d},Sao.PYSON.Eval.init_from_object=function(a){return new Sao.PYSON.Eval(a.v,a.d)},Sao.PYSON.eval.Not=function(a){return new Sao.PYSON.Not(a)},Sao.PYSON.Not=Sao.class_(Sao.PYSON.PYSON,{init:function(a){if(Sao.PYSON.Not._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["boolean","object"]).length||jQuery(["boolean"]).not(a.types()).length)throw"value must be boolean"}else if("boolean"!=typeof a)throw"value must be boolean";this._value=a},pyson:function(){return{__class__:"Not",v:this._value}},types:function(){return["boolean"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Not.eval_=function(a,b){return!a.v},Sao.PYSON.Not.init_from_object=function(a){return new Sao.PYSON.Not(a.v)},Sao.PYSON.eval.Bool=function(a){return new Sao.PYSON.Bool(a)},Sao.PYSON.Bool=Sao.class_(Sao.PYSON.PYSON,{init:function(a){Sao.PYSON.Bool._super.init.call(this),this._value=a},pyson:function(){return{__class__:"Bool",v:this._value}},types:function(){return["boolean"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Bool.eval_=function(a,b){return moment.isMoment(a.v)&&a.v.isTime?Boolean(a.v.hour()||a.v.minute()||a.v.second()||a.v.millisecond()):moment.isDuration(a.v)?Boolean(a.v.valueOf()):a.v instanceof Object?!jQuery.isEmptyObject(a.v):Boolean(a.v)},Sao.PYSON.Bool.init_from_object=function(a){return new Sao.PYSON.Bool(a.v)},Sao.PYSON.eval.And=function(a){return new Sao.PYSON.And(a)},Sao.PYSON.And=Sao.class_(Sao.PYSON.PYSON,{init:function(a){void 0===a&&(a=[]),Sao.PYSON.And._super.init.call(this);for(var b=0,c=a.length;c>b;b++){var d=a[b];if(d instanceof Sao.PYSON.PYSON){if(jQuery(d.types()).not(["boolean"]).length||jQuery(["boolean"]).not(d.types()).length)throw"statement must be boolean"}else if("boolean"!=typeof d)throw"statement must be boolean"}if(a.length<2)throw"must have at least 2 statements";this._statements=a},pyson:function(){return{__class__:"And",s:this._statements}},types:function(){return["boolean"]},__string_params__:function(){return this._statements}}),Sao.PYSON.And.eval_=function(a,b){for(var c=!0,d=0,e=a.s.length;e>d;d++){var f=a.s[d];c=c&&f}return c},Sao.PYSON.And.init_from_object=function(a){return new Sao.PYSON.And(a.s)},Sao.PYSON.eval.Or=function(a){return new Sao.PYSON.Or(a)},Sao.PYSON.Or=Sao.class_(Sao.PYSON.And,{pyson:function(){var a=Sao.PYSON.Or._super.pyson.call(this);return a.__class__="Or",a}}),Sao.PYSON.Or.eval_=function(a,b){for(var c=!1,d=0,e=a.s.length;e>d;d++){var f=a.s[d];c=c||f}return c},Sao.PYSON.Or.init_from_object=function(a){return new Sao.PYSON.Or(a.s)},Sao.PYSON.eval.Equal=function(a,b){return new Sao.PYSON.Equal(a,b)},Sao.PYSON.Equal=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){Sao.PYSON.Equal._super.init.call(this);var c,d;if(c=a instanceof Sao.PYSON.PYSON?a.types():[typeof a],d=b instanceof Sao.PYSON.PYSON?b.types():[typeof b],jQuery(c).not(d).length||jQuery(d).not(c).length)throw"statements must have the same type";this._statement1=a,this._statement2=b},pyson:function(){return{__class__:"Equal",s1:this._statement1,s2:this._statement2}},types:function(){return["boolean"]},__string_params__:function(){return[this._statement1,this._statement2]}}),Sao.PYSON.Equal.eval_=function(a,b){return a.s1 instanceof Array&&a.s2 instanceof Array?Sao.common.compare(a.s1,a.s2):a.s1==a.s2},Sao.PYSON.Equal.init_from_object=function(a){return new Sao.PYSON.Equal(a.s1,a.s2)},Sao.PYSON.eval.Greater=function(a,b,c){return new Sao.PYSON.Greater(a,b,c)},Sao.PYSON.Greater=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){Sao.PYSON.Greater._super.init.call(this);for(var d=[a,b],e=0;2>e;e++){var f=d[e];if(f instanceof Sao.PYSON.PYSON){if(jQuery(f).not(["number"]).length)throw"statement must be an integer or a float"}else if(!~["number","object"].indexOf(typeof f))throw"statement must be an integer or a float"}if(void 0===c&&(c=!1),c instanceof Sao.PYSON.PYSON){if(jQuery(c.types()).not(["boolean"]).length||jQuery(["boolean"]).not(c.types()).length)throw"equal must be boolean"}else if("boolean"!=typeof c)throw"equal must be boolean";this._statement1=a,this._statement2=b,this._equal=c},pyson:function(){return{__class__:"Greater",s1:this._statement1,s2:this._statement2,e:this._equal}},types:function(){return["boolean"]},__string_params__:function(){return[this._statement1,this._statement2,this._equal]}}),Sao.PYSON.Greater._convert=function(a){return a=jQuery.extend({},a),a.s1=Number(a.s1),a.s2=Number(a.s2),a},Sao.PYSON.Greater.eval_=function(a,b){return a=Sao.PYSON.Greater._convert(a),a.e?a.s1>=a.s2:a.s1>a.s2},Sao.PYSON.Greater.init_from_object=function(a){return new Sao.PYSON.Greater(a.s1,a.s2,a.e)},Sao.PYSON.eval.Less=function(a,b,c){return new Sao.PYSON.Less(a,b,c)},Sao.PYSON.Less=Sao.class_(Sao.PYSON.Greater,{pyson:function(){var a=Sao.PYSON.Less._super.pyson.call(this);return a.__class__="Less",a}}),Sao.PYSON.Less._convert=Sao.PYSON.Greater._convert,Sao.PYSON.Less.eval_=function(a,b){return a=Sao.PYSON.Less._convert(a),a.e?a.s1<=a.s2:a.s1<a.s2},Sao.PYSON.Less.init_from_object=function(a){return new Sao.PYSON.Less(a.s1,a.s2,a.e)},Sao.PYSON.eval.If=function(a,b,c){return new Sao.PYSON.If(a,b,c)},Sao.PYSON.If=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){if(Sao.PYSON.If._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["boolean"]).length||jQuery(["boolean"]).not(a.types()).length)throw"condition must be boolean"}else if("boolean"!=typeof a)throw"condition must be boolean";var d,e;if(d=b instanceof Sao.PYSON.PYSON?b.types():[typeof b],void 0===c&&(c=null),e=c instanceof Sao.PYSON.PYSON?c.types():[typeof c],jQuery(d).not(e).length||jQuery(e).not(d).length)throw"then and else statements must be the same type";this._condition=a,this._then_statement=b,this._else_statement=c},pyson:function(){return{__class__:"If",c:this._condition,t:this._then_statement,e:this._else_statement}},types:function(){return this._then_statement instanceof Sao.PYSON.PYSON?this._then_statement.types():[typeof this._then_statement]},__string_params__:function(){return[this._condition,this._then_statement,this._else_statement]}}),Sao.PYSON.If.eval_=function(a,b){return a.c?a.t:a.e},Sao.PYSON.If.init_from_object=function(a){return new Sao.PYSON.If(a.c,a.t,a.e)},Sao.PYSON.eval.Get=function(a,b,c){return new Sao.PYSON.Get(a,b,c)},Sao.PYSON.Get=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){if(Sao.PYSON.Get._super.init.call(this),void 0===c&&(c=null),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["object"]).length||jQuery(["object"]).not(a.types()).length)throw"obj must be a dict"}else if(!(a instanceof Object))throw"obj must be a dict";if(this._obj=a,b instanceof Sao.PYSON.PYSON){if(jQuery(b.types()).not(["string"]).length||jQuery(["string"]).not(b.types()).length)throw"key must be a string"}else if("string"!=typeof b)throw"key must be a string";this._key=b,this._default=c},pyson:function(){return{__class__:"Get",v:this._obj,k:this._key,d:this._default}},types:function(){return this._default instanceof Sao.PYSON.PYSON?this._default.types():[typeof this._default]},__string_params__:function(){return[this._obj,this._key,this._default]}}),Sao.PYSON.Get.eval_=function(a,b){return a.k in a.v?a.v[a.k]:a.d},Sao.PYSON.Get.init_from_object=function(a){return new Sao.PYSON.Get(a.v,a.k,a.d)},Sao.PYSON.eval.In=function(a,b){return new Sao.PYSON.In(a,b)},Sao.PYSON.In=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){if(Sao.PYSON.In._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["string","number"]).length)throw"key must be a string or a number"}else if(!~["string","number"].indexOf(typeof a))throw"key must be a string or a number";if(b instanceof Sao.PYSON.PYSON){if(jQuery(b.types()).not(["object"]).length||jQuery(["object"]).not(b.types()).length)throw"obj must be a dict or a list"}else if(!(b instanceof Object))throw"obj must be a dict or a list";this._key=a,this._obj=b},pyson:function(){return{__class__:"In",k:this._key,v:this._obj}},types:function(){return["boolean"]},__string_params__:function(){return[this._key,this._obj]}}),Sao.PYSON.In.eval_=function(a,b){return a.v.indexOf?Boolean(~a.v.indexOf(a.k)):!!a.v[a.k]},Sao.PYSON.In.init_from_object=function(a){return new Sao.PYSON.In(a.k,a.v)},Sao.PYSON.eval.Date=function(a,b,c,d,e,f){return new Sao.PYSON.Date(a,b,c,d,e,f)},Sao.PYSON.Date=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c,d,e,f){Sao.PYSON.Date._super.init.call(this),void 0===a&&(a=null),void 0===b&&(b=null),void 0===c&&(c=null),void 0===d&&(d=0),void 0===e&&(e=0),void 0===f&&(f=0),this._test(a,"year"),this._test(b,"month"),this._test(c,"day"),this._test(d,"delta_years"),this._test(f,"delta_days"),this._test(e,"delta_months"),this._year=a,this._month=b,this._day=c,this._delta_years=d,this._delta_months=e,this._delta_days=f},pyson:function(){return{__class__:"Date",y:this._year,M:this._month,d:this._day,dy:this._delta_years,dM:this._delta_months,dd:this._delta_days}},types:function(){return["object"]},_test:function(a,b){if(a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["number","object"]).length)throw b+" must be an integer or None"}else if("number"!=typeof a&&null!==a)throw b+" must be an integer or None"},__string_params__:function(){return[this._year,this._month,this._day,this._delta_years,this._delta_months,this._delta_days]}}),Sao.PYSON.Date.eval_=function(a,b){var c=Sao.Date(a.y,a.M&&a.M-1,a.d);return a.dy&&c.add(a.dy,"y"),a.dM&&c.add(a.dM,"M"),a.dd&&c.add(a.dd,"d"),c},Sao.PYSON.Date.init_from_object=function(a){return new Sao.PYSON.Date(a.y,a.M,a.d,a.dy,a.dM,a.dd)},Sao.PYSON.eval.DateTime=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){return new Sao.PYSON.DateTime(a,b,c,d,e,f,g,h,i,j,k,l,m,n)},Sao.PYSON.DateTime=Sao.class_(Sao.PYSON.Date,{init:function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){Sao.PYSON.DateTime._super.init.call(this,a,b,c,h,i,j),void 0===d&&(d=null),void 0===e&&(e=null),void 0===f&&(f=null),void 0===g&&(g=null),void 0===k&&(k=0),void 0===l&&(l=0),void 0===m&&(m=0),void 0===n&&(n=0),this._test(d,"hour"),this._test(e,"minute"),this._test(f,"second"),this._test(g,"microsecond"),this._test(k,"delta_hours"),this._test(l,"delta_minutes"),this._test(m,"delta_seconds"),this._test(n,"delta_microseconds"),this._hour=d,this._minute=e,this._second=f,this._microsecond=g,this._delta_hours=k,this._delta_minutes=l,this._delta_seconds=m,this._delta_microseconds=n},pyson:function(){var a=Sao.PYSON.DateTime._super.pyson.call(this);return a.__class__="DateTime",a.h=this._hour,a.m=this._minute,a.s=this._second,a.ms=this._microsecond,a.dh=this._delta_hours,a.dm=this._delta_minutes,a.ds=this._delta_seconds,a.dms=this._delta_microseconds,a},__string_params__:function(){var a=Sao.PYSON.DateTime._super.__string_params__.call(this);return[a[0],a[1],a[2],this._hour,this._minute,this._second,this._microsecond,a[3],a[4],a[5],this._delta_hours,this._delta_minutes,this._delta_seconds,this._delta_microseconds]}}),Sao.PYSON.DateTime.eval_=function(a,b){var c=Sao.DateTime(a.y,a.M&&a.M-1,a.d,a.h,a.m,a.s,a.ms&&a.ms/1e3);return a.dy&&c.add(a.dy,"y"),a.dM&&c.add(a.dM,"M"),a.dd&&c.add(a.dd,"d"),a.dh&&c.add(a.dh,"h"),a.dm&&c.add(a.dm,"m"),a.ds&&c.add(a.ds,"s"),a.dms&&c.add(a.dms/1e3,"ms"),c},Sao.PYSON.DateTime.init_from_object=function(a){return new Sao.PYSON.DateTime(a.y,a.M,a.d,a.h,a.m,a.s,a.ms,a.dy,a.dM,a.dd,a.dh,a.dm,a.ds,a.dms)},Sao.PYSON.eval.Len=function(a){return new Sao.PYSON.Len(a)},Sao.PYSON.Len=Sao.class_(Sao.PYSON.PYSON,{init:function(a){if(Sao.PYSON.Len._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["object","string"]).length||jQuery(["object","string"]).not(a.types()).length)throw"value must be an object or a string"}else if("object"!=typeof a&&"string"!=typeof a)throw"value must be an object or a string";this._value=a},pyson:function(){return{__class__:"Len",v:this._value}},types:function(){return["integer"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Len.eval_=function(a,b){return"object"==typeof a.v?Object.keys(a.v).length:a.v.length},Sao.PYSON.Len.init_from_object=function(a){return new Sao.PYSON.Len(a.v)}}(),function(){"use strict";Sao.Session=Sao.class_(Object,{init:function(a,b){this.user_id=null,this.session=null,this.prm=jQuery.when(),this.database=a,this.login=b,this.context={},Sao.Session.current_session||(Sao.Session.current_session=this)},get_auth:function(){return btoa(this.login+":"+this.user_id+":"+this.session)},do_login:function(a,b){var c=jQuery.Deferred(),d=function(b){return{method:"common.db.login",params:[a,b,Sao.i18n.getlang()]}};return new Sao.Login(d,this).run().then(function(a){this.user_id=a[0],this.session=a[1],c.resolve()}.bind(this),function(){this.user_id=null,this.session=null,c.reject()}),c.promise()},do_logout:function(){if(!this.user_id||!this.session)return jQuery.when();var a={id:0,method:"common.db.logout",params:[]},b=jQuery.ajax({headers:{Authorization:"Session "+this.get_auth()},contentType:"application/json",data:JSON.stringify(a),dataType:"json",url:"/"+this.database+"/",type:"post"});return this.database=null,this.login=null,this.user_id=null,this.session=null,Sao.Session.current_session===this&&(Sao.Session.current_session=null),b},reload_context:function(){var a={method:"model.res.user.get_preferences",params:[!0,{}]},b=jQuery.extend({},this);b.context={};var c=Sao.rpc(a,b);return c.then(function(a){this.context=a}.bind(this))}}),Sao.Session.login_dialog=function(){var a=new Sao.Dialog(Sao.i18n.gettext("Login"),"lg");return a.database_select=jQuery("<select/>",{"class":"form-control",id:"login-database"}).hide(),a.database_input=jQuery("<input/>",{"class":"form-control",id:"login-database"}).hide(),a.login_input=jQuery("<input/>",{"class":"form-control",id:"login-login",placeholder:Sao.i18n.gettext("User name")}),a.body.append(jQuery("<div/>",{"class":"form-group"}).append(jQuery("<label/>",{"class":"control-label","for":"login-database"}).append(Sao.i18n.gettext("Database"))).append(a.database_select).append(a.database_input)).append(jQuery("<div/>",{"class":"form-group"}).append(jQuery("<label/>",{"class":"control-label","for":"login-login"}).append(Sao.i18n.gettext("User name"))).append(a.login_input)),a.button=jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Login")).appendTo(a.footer),a},Sao.Session.get_credentials=function(){var a=jQuery.Deferred(),b=window.location.hash.replace(/^(#(!|))/,"")||null,c=Sao.Session.login_dialog(),d=function(){return c.modal.find("input,select").filter(":visible").filter(function(){return!jQuery(this).val()})},e=function(){var b=c.login_input.val(),e=e||c.database_select.val()||c.database_input.val();if(c.modal.find(".has-error").removeClass("has-error"),!b||!e)return void d().closest(".form-group").addClass("has-error");c.button.focus(),c.button.prop("disabled",!0),c.modal.modal("hide");var f=new Sao.Session(e,b);f.do_login(b).then(function(){a.resolve(f),c.modal.remove()},function(){c.button.prop("disabled",!1),c.modal.modal("show"),d().closest(".form-group").addClass("has-error"),d().first().focus()})};return c.modal.modal({backdrop:!1,keyboard:!1}),c.modal.find("form").unbind().submit(function(a){e(),a.preventDefault()}),jQuery.when(Sao.DB.list()).then(function(a){
-var e;a=a||[],a.length<=1?(b=a[0],e=c.database_input):(e=c.database_select,a.forEach(function(a){e.append(jQuery("<option/>",{value:a,text:a}))})),e.prop("readonly",1==a.length),e.show(),e.val(b||""),d().first().focus()}),a.promise()},Sao.Session.renew=function(a){if("pending"==a.prm.state())return a.prm;var b=jQuery.Deferred();return a.prm=b.promise(),a.login?(a.do_login(a.login).then(b.resolve,b.reject),a.prm):(b.reject(),a.prm)},Sao.Session.current_session=null,Sao.Login=Sao.class_(Object,{init:function(a,b){this.func=a,this.session=b||Sao.Session.current_session},run:function(a){void 0===a&&(a={});var b=jQuery.Deferred(),c=Sao.common.processing.show(),d=this.func(a);d.id=0;var e={contentType:"application/json",data:JSON.stringify(d),dataType:"json",url:"/"+this.session.database+"/",type:"post",complete:[function(){Sao.common.processing.hide(c)}]};this.session.user_id&&this.session.session&&(e.headers={Authorization:"Session "+this.session.get_auth()});var f=jQuery.ajax(e),g=function(c){if(null===c)Sao.common.warning.run("",Sao.i18n.gettext("Unable to reach the server.")),b.reject();else if(c.error){if(c.error[0].startsWith("403"))return this.run({}).then(b.resolve,b.reject);if(c.error[0].startsWith("404"))b.reject();else if("LoginException"!=c.error[0])Sao.common.error.run(c.error[0],c.error[1]),b.reject();else{var d=c.error[1],e=d[0],f=d[1],g=d[2];this["get_"+g](f).then(function(c){return a[e]=c,this.run(a).then(b.resolve,b.reject)}.bind(this),b.reject)}}else b.resolve(c.result)};return f.success(g.bind(this)),f.error(b.reject),b.promise()},get_char:function(a){return Sao.common.ask.run(a)},get_password:function(a){return Sao.common.ask.run(a,!1)}}),Sao.DB={},Sao.DB.list=function(){var a=Sao.common.processing.show();return jQuery.ajax({contentType:"application/json",data:JSON.stringify({id:0,method:"common.db.list",params:[]}),dataType:"json",url:"/",type:"post",complete:[function(){Sao.common.processing.hide(a)}]}).then(function(a){return a.result})}}(),function(){"use strict";Sao.Model=Sao.class_(Object,{init:function(a,b){b=b||{},this.name=a,this.session=Sao.Session.current_session,this.fields={}},add_fields:function(a){var b=[];for(var c in a)if(a.hasOwnProperty(c)&&!(c in this.fields)){var d=a[c],e=Sao.field.get(d.type);this.fields[c]=new e(d),b.push(c)}return b},execute:function(a,b,c){void 0===c&&(c={});var d={method:"model."+this.name+"."+a,params:b.concat(c)};return Sao.rpc(d,this.session)},find:function(a,b,c,d,e){b||(b=0);var f=this,g=this.execute("search",[a,b,c,d],e),h=function(a){return Sao.Group(f,e,a.map(function(a){return new Sao.Record(f,a)}))};return g.pipe(h)},delete_:function(a){if(jQuery.isEmptyObject(a))return jQuery.when();var b=a[0],c=b.group.root_group();console.assert(a.every(function(a){return a.model.name==b.model.name}),"records not from the same model"),console.assert(a.every(function(a){return a.group.root_group()==b.group.root_group()}),"records not from the same root group"),a=a.filter(function(a){return a.id>=0});var d={};d._timestamp={},a.forEach(function(a){jQuery.extend(d._timestamp,a.get_timestamp())});var e=a.map(function(a){return a.id});return c.on_write_ids(e).then(function(a){return a=a.filter(function(a){return!~e.indexOf(a)}),this.execute("delete",[e],d).then(function(){c.reload(a)})}.bind(this))},copy:function(a,b){if(jQuery.isEmptyObject(a))return jQuery.when();var c=a.map(function(a){return a.id});return this.execute("copy",[c,{}],b)}}),Sao.Group=function(a,b,c){return c.prm=jQuery.when(),c.model=a,c._context=b,c.on_write=[],c.parent=void 0,c.screens=[],c.parent_name="",c.children=[],c.child_name="",c.parent_datetime_field=void 0,c.record_removed=[],c.record_deleted=[],c.__readonly=!1,c.skip_model_access=!1,c.forEach(function(a,b,c){a.group=c}),c.get_readonly=function(){var a=Sao.common.MODELACCESS.get(this.model.name);return this.context._datetime||!a.write&&!a.create&&!this.skip_model_access?!0:this.__readonly},c.set_readonly=function(a){this.__readonly=a},c.load=function(a,b){var c,d,e=[];for(c=0,d=a.length;d>c;c++){var f=a[c],g=this.get(f);g||(g=new Sao.Record(this.model,f),g.group=this,this.push(g)),e.push(g)}var h,i=[];for(c=0,d=this.record_removed.length;d>c;c++)h=this.record_removed[c],~a.indexOf(h.id)||i.push(h);this.record_removed=i;var j=[];for(c=0,d=this.record_deleted.length;d>c;c++)h=this.record_deleted[c],~a.indexOf(h.id)||j.push(h);this.record_deleted=j,e.length&&b&&this.changed()},c.get=function(a){for(var b=0,c=this.length;c>b;b++){var d=this[b];if(d.id==a)return d}},c.new_=function(a,b,c){var d=new Sao.Record(this.model,b);return d.group=this,a&&d.default_get(c),d},c.add=function(a,b,c){void 0!==b&&-1!=b||(b=this.length),void 0===c&&(c=!0),a.group!=this&&(a.group=this),this.splice(b,0,a);for(var d in this.record_removed)d.id==a.id&&this.record_removed.splice(this.record_removed.indexOf(d),1);for(var e in this.record_deleted)e.id==a.id&&this.record_deleted.splice(this.record_deleted.indexOf(e),1);if(a._changed.id=!0,c&&(this.changed(),this.parent&&this.model.fields[this.parent_name])){var f=this.model.fields[this.parent_name];if(f instanceof Sao.field.Many2One||f instanceof Sao.field.Reference){var g=[this.parent.id,""];f instanceof Sao.field.Reference&&(g=[this.parent.model.name,g]),f.set_client(a,g)}}return a},c.remove=function(a,b,c,d){void 0===c&&(c=!0);this.indexOf(a);a.id>=0&&(b?(~this.record_deleted.indexOf(a)&&this.record_deleted.splice(this.record_deleted.indexOf(a),1),this.record_removed.push(a)):(~this.record_removed.indexOf(a)&&this.record_removed.splice(this.record_removed.indexOf(a),1),this.record_deleted.push(a))),a.group.parent&&(a.group.parent._changed.id=!0),c&&(a._changed.id=!0),(a.id<0||d)&&this._remove(a),a.group.changed(),a.group.root_group().screens.forEach(function(a){a.display()})},c._remove=function(a){var b=this.indexOf(a);this.splice(b,1)},c.unremove=function(a){this.record_removed.splice(this.record_removed.indexOf(a),1),this.record_deleted.splice(this.record_deleted.indexOf(a),1),a.group.changed(),a.group.root_group().screens.forEach(function(a){a.display()})},c.changed=function(){if(!this.parent)return jQuery.when();this.parent._changed[this.child_name]=!0;var a=jQuery.Deferred(),b=this.parent.model.fields[this.child_name].changed(this.parent);return b?b.then(function(){this.parent.validate(null,!0).done(function(){this.parent.group.changed().done(a.resolve)}.bind(this))}.bind(this)):a.resolve(),a},c.root_group=function(){for(var a=this,b=this.parent;b;)a=b.group,b=b.parent;return a},c.save=function(){var a=[];return this.forEach(function(b){a.push(b.save())}),jQuery.isEmptyObject(this.record_deleted)||(this.record_deleted.forEach(function(a){this._remove(a)}.bind(this)),a.push(this.model.delete_(this.record_deleted)),this.record_deleted.splice(0,this.record_deleted.length)),jQuery.when.apply(jQuery,a)},c.written=function(a){return"number"==typeof a&&(a=[a]),this.on_write_ids(a).then(function(b){b=b.filter(function(b){return!~a.indexOf(b)}),this.root_group().reload(b)}.bind(this))},c.reload=function(a){this.children.forEach(function(b){b.reload(a)}),a.forEach(function(a){var b=this.get(a);b&&jQuery.isEmptyObject(b._changed)&&b.cancel()}.bind(this))},c.on_write_ids=function(a){var b=[],c=[];return this.on_write.forEach(function(d){var e=this.model.execute(d,[a],this._context).then(function(a){jQuery.extend(c,a)});b.push(e)}.bind(this)),jQuery.when.apply(jQuery,b).then(function(){return c.filter(function(a,b,c){return b==c.indexOf(a)})})},c.set_parent=function(a){this.parent=a,a&&a.model.name==this.model.name&&this.parent.group.children.push(this)},c.add_fields=function(a){var b=this.model.add_fields(a);if(!jQuery.isEmptyObject(this)){var c=[];this.forEach(function(a){a.id<0&&c.push(a)}),c.length&&b.length&&this.model.execute("default_get",[b,this.context()]).then(function(a){c.forEach(function(b){b.set_default(a)})})}},c.destroy=function(){if(this.parent){var a=this.parent.group.children.indexOf(this);~a&&this.parent.group.children.splice(a,1)}this.parent=null},c.domain=function(){var a=[];if(this.screens.forEach(function(b){b.attributes.domain&&a.push(b.attributes.domain)}),this.parent&&this.child_name){var b=this.parent.model.fields[this.child_name];return[a,b.get_domain(this.parent)]}return a},c.context=function(){var a=jQuery.extend({},this._context);if(this.parent&&(jQuery.extend(a,this.parent.get_context()),this.child_name in this.parent.model.fields)){var b=this.parent.model.fields[this.child_name];jQuery.extend(a,b.get_context(this.parent))}return jQuery.extend(a,this._context),this.parent_datetime_field&&(a._datetime=this.parent.get_eval()[this.parent_datetime_field]),a},c.set_context=function(a){this._context=jQuery.extend({},a)},c.clean4inversion=function(a){if(jQuery.isEmptyObject(a))return[];var b=new Sao.common.DomainInversion,c=a[0],d=a.slice(1);if(~["AND","OR"].indexOf(c));else if(b.is_leaf(c)){var e=c[0];e in this.model.fields&&this.model.fields[e].description.readonly&&(c=[])}else c=this.clean4inversion(c);return[c].concat(this.clean4inversion(d))},c.domain4inversion=function(){var a=this.domain();return this.__domain4inversion&&Sao.common.compare(this.__domain4inversion[0],a)||(this.__domain4inversion=[a,this.clean4inversion(a)]),this.__domain4inversion[1]},c.get_by_path=function(a){a=jQuery.extend([],a);var b=null,c=this,d=function(){if(jQuery.isEmptyObject(a))return b;var e=a[0][0],f=a[0][1];return a.splice(0,1),b=c.get(f),b?e?b.load(e).then(function(){return c=b._values[e],c?d():null}):d():null};return jQuery.when().then(d)},c.sort=function(a){var b={};this.forEach(function(a){b[a.id]=a}),a.forEach(function(a,c){this[c]=b[a.id]}.bind(this))},c},Sao.Record=Sao.class_(Object,{id_counter:-1,init:function(a,b){this.model=a,this.group=Sao.Group(a,{},[]),this.id=b||Sao.Record.prototype.id_counter--,this._values={},this._changed={},this._loaded={},this.fields={},this._timestamp=null,this.attachment_count=-1,this.unread_note=-1,this.button_clicks={},this.state_attrs={},this.autocompletion={},this.exception=!1},has_changed:function(){return!jQuery.isEmptyObject(this._changed)},save:function(a){void 0===a&&(a=!1);var b=this.get_context(),c=jQuery.when(),d=this.get();if(this.id<0||!jQuery.isEmptyObject(d)){if(this.id<0){c=this.model.execute("create",[[d]],b);var e=function(a){this.id=a[0]};c.done(e.bind(this))}else jQuery.isEmptyObject(d)||(b._timestamp=this.get_timestamp(),c=this.model.execute("write",[[this.id],d],b));c=c.done(function(){return this.cancel(),a?this.reload():void 0}.bind(this)),this.group&&(c=c.done(function(){return this.group.written(this.id)}.bind(this)))}return this.group.parent&&(delete this.group.parent._changed[this.group.child_name],c=c.done(function(){return this.group.parent.save(a)}.bind(this))),c},reload:function(a){if(this.id<0)return jQuery.when();if(a){var b=a.map(function(a){return this.load(a)}.bind(this));return jQuery.when.apply(jQuery,b)}return this.load("*")},load:function(a){var b,c;if(this.id<0||a in this._loaded)return jQuery.when();if("pending"==this.group.prm.state())return c=jQuery.Deferred(),this.group.prm.then(function(){this.load(a).then(c.resolve,c.reject)}.bind(this)),c;var d={};d[this.id]=this;var e;if("*"==a){e="eager";for(b in this.model.fields)if(this.model.fields.hasOwnProperty(b)){var f=this.model.fields[b].description.loading||"eager";if("eager"!=f){e="lazy";break}}}else e=this.model.fields[a].description.loading||"eager";var g=[];if("eager"==e)for(b in this.model.fields)this.model.fields.hasOwnProperty(b)&&"eager"==(this.model.fields[b].description.loading||"eager")&&g.push(b);else g=Object.keys(this.model.fields);g=g.filter(function(a,b,c){return!(a in this._loaded)}.bind(this));var h=g.slice(),i=["many2one","one2one","reference"];for(var j in g){b=g[j];var k=this.model.fields[b].description;~i.indexOf(k.type)&&h.push(b+".rec_name")}~g.indexOf("rec_name")||h.push("rec_name"),h.push("_timestamp");var l=jQuery.extend({},this.get_context());if("eager"==e){var m,n,o=parseInt(Sao.config.limit/h.length,10),p=function(b){return!(a in b._loaded)&&b.id>=0},q=function(a){return p(a)&&void 0===d[a.id]&&(a.group===this.group||JSON.stringify(a.get_context())===JSON.stringify(l))}.bind(this);this.group.parent&&this.group.parent.model.name==this.model.name?(m=[],m=m.concat.apply(m,this.group.parent.group.children),n=q):(m=this.group,n=p);var r=m.indexOf(this);if(~r)for(var s=m.length,t=1;Object.keys(d).length<o&&(r-t>=0||s>r+t)&&2*o>t;){var u;r-t>=0&&(u=m[r-t],n(u)&&(d[u.id]=u)),s>r+t&&(u=m[r+t],n(u)&&(d[u.id]=u)),t++}}for(b in this.model.fields)this.model.fields.hasOwnProperty(b)&&"binary"==this.model.fields[b].description.type&&~h.indexOf(b,h)&&(l[this.model.name+"."+b]="size");c=this.model.execute("read",[Object.keys(d).map(function(a){return parseInt(a,10)}),h],l);var v=function(a,b){void 0===b&&(b=!1);var c={},e=[];a.forEach(function(a,b,d){c[a.id]=a});for(var f in d)if(d.hasOwnProperty(f)){var g=d[f];g.exception||(g.exception=b);var h=c[f];if(g&&h){for(var i in this._changed)this._changed.hasOwnProperty(i)&&delete h[i];e.push(g.set(h))}}return jQuery.when.apply(jQuery,e)}.bind(this),w=function(){var a,b=[];for(var c in d){a={id:c};for(var e in h)a[h[e]]=null;b.push(a)}return v(b,!0)};return this.group.prm=c.then(v,w),this.group.prm},set:function(a,b){void 0===b&&(b=!0);var c,d,e={},f=[];for(c in a)if(a.hasOwnProperty(c))if(d=a[c],"_timestamp"!=c)if(c in this.model.fields){if(this.model.fields[c]instanceof Sao.field.One2Many&&(e[c]=d),this.model.fields[c]instanceof Sao.field.Many2One||this.model.fields[c]instanceof Sao.field.Reference){var g=c+".rec_name";a.hasOwnProperty(g)?this._values[g]=a[g]:this._values.hasOwnProperty(g)&&delete this._values[g]}this.model.fields[c].set(this,d),this._loaded[c]=!0,f.push(c)}else"rec_name"==c&&(this._values[c]=d);else this._timestamp||(this._timestamp=d);for(c in e)d=e[c],this.model.fields[c].set(this,d),this._loaded[c]=!0;return b?this.validate(f,!0):jQuery.when()},get:function(){var a={};for(var b in this.model.fields)if(this.model.fields.hasOwnProperty(b)){var c=this.model.fields[b];(!c.description.readonly||c instanceof Sao.field.One2Many)&&(void 0===this._changed[b]&&this.id>=0||(a[b]=c.get(this)))}return a},invalid_fields:function(){var a={};for(var b in this.model.fields){var c=this.model.fields[b],d=c.get_state_attrs(this).invalid;d&&(a[b]=d)}return a},get_context:function(){return this.group.context()},field_get:function(a){return this.model.fields[a].get(this)},field_set:function(a,b){this.model.fields[a].set(this,b)},field_get_client:function(a){return this.model.fields[a].get_client(this)},field_set_client:function(a,b,c){this.model.fields[a].set_client(this,b,c)},default_get:function(a){if(!jQuery.isEmptyObject(this.model.fields)){var b=this.get_context();void 0===b.default_rec_name&&(b.default_rec_name=a);var c=this.model.execute("default_get",[Object.keys(this.model.fields)],b);return c.then(function(a){if(this.group.parent&&this.group.parent_name in this.group.model.fields){var b=this.group.model.fields[this.group.parent_name];b instanceof Sao.field.Reference?a[this.group.parent_name]=[this.group.parent.model.name,this.group.parent.id]:b.description.relation==this.group.parent.model.name&&(a[this.group.parent_name]=this.group.parent.id)}return this.set_default(a)}.bind(this))}return jQuery.when()},set_default:function(a,b){void 0===b&&(b=!0);var c=[],d=[];for(var e in a)if(a.hasOwnProperty(e)){var f=a[e];if(e in this.model.fields){if(this.model.fields[e]instanceof Sao.field.Many2One||this.model.fields[e]instanceof Sao.field.Reference){var g=e+".rec_name";a.hasOwnProperty(g)?this._values[g]=a[g]:this._values.hasOwnProperty(g)&&delete this._values[g]}c.push(this.model.fields[e].set_default(this,f)),this._loaded[e]=!0,d.push(e)}}return jQuery.when.apply(jQuery,c).then(function(){return this.on_change(d).then(function(){return this.on_change_with(d).then(function(){var a=function(){return this.group.root_group().screens.forEach(function(a){return a.display()})}.bind(this);return b?this.validate(null,!0).then(a):a()}.bind(this))}.bind(this))}.bind(this))},get_timestamp:function(){var a={};a[this.model.name+","+this.id]=this._timestamp;for(var b in this.model.fields)this.model.fields.hasOwnProperty(b)&&b in this._loaded&&jQuery.extend(a,this.model.fields[b].get_timestamp(this));return a},get_eval:function(){var a={};for(var b in this.model.fields)!this.model.fields.hasOwnProperty(b)&&this.id>=0||(a[b]=this.model.fields[b].get_eval(this));return a},get_on_change_value:function(a){var b={};for(var c in this.model.fields)a&&~a.indexOf(c)||(!(this.id>=0)||this._loaded[c]&&this._changed[c])&&(b[c]=this.model.fields[c].get_on_change_value(this));return b.id=this.id,b},_get_on_change_args:function(a){var b={},c=Sao.common.EvalEnvironment(this,"on_change");return a.forEach(function(a){var d=c;a.split(".").forEach(function(a){void 0!==d&&(d=d[a])}),b[a]=d}),b.id=this.id,b},on_change:function(a){var b={};if(a.forEach(function(a){var c=this.model.fields[a].description.on_change;jQuery.isEmptyObject(c)||(b=jQuery.extend(b,this._get_on_change_args(c)))}.bind(this)),jQuery.isEmptyObject(b))return jQuery.when();var c=this.model.execute("on_change",[b,a],this.get_context());return c.then(function(a){a.forEach(this.set_on_change.bind(this))}.bind(this))},on_change_with:function(a){var b,c,d={},e={},f={};for(b in this.model.fields)if(this.model.fields.hasOwnProperty(b)&&(c=this.model.fields[b].description.on_change_with,!jQuery.isEmptyObject(c))){for(var g=0;g<a.length&&!~c.indexOf(a[g]);g++);g>=a.length||(jQuery.isEmptyObject(Sao.common.intersect(Object.keys(d).sort(),c.sort()))?(d[b]=!0,e=jQuery.extend(e,this._get_on_change_args(c)),(this.model.fields[b]instanceof Sao.field.Many2One||this.model.fields[b]instanceof Sao.field.Reference)&&delete this._values[b+".rec_name"]):f[b]=!0)}var h,i=[];jQuery.isEmptyObject(d)||(h=this.model.execute("on_change_with",[e,Object.keys(d)],this.get_context()),i.push(h.then(this.set_on_change.bind(this))));var j=function(a){return function(b){this.model.fields[a].set_on_change(this,b)}};for(b in f)f.hasOwnProperty(b)&&(c=this.model.fields[b].description.on_change_with,e=this._get_on_change_args(c),h=this.model.execute("on_change_with_"+b,[e],this.get_context()),i.push(h.then(j(b).bind(this))));return jQuery.when.apply(jQuery,i)},set_on_change:function(a){var b,c;for(b in a)if(a.hasOwnProperty(b)&&(c=a[b],b in this.model.fields)){if(this.model.fields[b]instanceof Sao.field.Many2One||this.model.fields[b]instanceof Sao.field.Reference){var d=b+".rec_name";a.hasOwnProperty(d)?this._values[d]=a[d]:this._values.hasOwnProperty(d)&&delete this._values[d]}this.model.fields[b].set_on_change(this,c)}},autocomplete_with:function(a){var b=[];for(var c in this.model.fields){var d=this.model.fields[c],e=d.description.autocomplete||[];~e.indexOf(a)&&b.push(this.do_autocomplete(c))}return jQuery.when.apply(jQuery,b)},do_autocomplete:function(a){this.autocompletion[a]=[];var b=this.model.fields[a],c=b.description.autocomplete,d=this._get_on_change_args(c),e=this.model.execute("autocomplete_"+a,[d],this.get_context());return e.then(function(b){this.autocompletion[a]=b}.bind(this))},expr_eval:function(a){if("string"!=typeof a)return a;var b=jQuery.extend({},this.model.session.context);if(b.context=jQuery.extend({},b),jQuery.extend(b.context,this.get_context()),jQuery.extend(b,this.get_eval()),b.active_model=this.model.name,b.active_id=this.id,b._user=this.model.session.user_id,this.group.parent&&this.group.parent_name){var c=Sao.common.EvalEnvironment(this.group.parent);b["_parent_"+this.group.parent_name]=c}return new Sao.PYSON.Decoder(b).decode(a)},rec_name:function(){var a=this.model.execute("read",[[this.id],["rec_name"]],this.get_context());return a.then(function(a){return a[0].rec_name})},validate:function(a,b,c,d){var e=function(){var e=!0,f=[];this.group.screens.forEach(function(a){a.exclude_field&&f.push(a.exclude_field)});for(var g in this.model.fields)if((!(d&&this.id>=0)||g in this._loaded)&&this.model.fields.hasOwnProperty(g)){var h=this.model.fields[g];a&&!~a.indexOf(g)||h.description.readonly||~f.indexOf(g)||h.validate(this,b,c)||(e=!1)}return e}.bind(this);return d?e():this._check_load(a).then(e)},pre_validate:function(){if(jQuery.isEmptyObject(this._changed))return jQuery.Deferred().resolve(!0);var a=this._get_on_change_args(Object.keys(this._changed));return this.model.execute("pre_validate",[a],this.get_context()).then(function(){return!0},function(){return!1})},cancel:function(){this._loaded={},this._changed={},this._timestamp=null,this.button_clicks={}},_check_load:function(a){return this.get_loaded(a)?jQuery.when():this.reload(a)},get_loaded:function(a){if(!jQuery.isEmptyObject(a)){var b=!0;return a.forEach(function(a){a in this._loaded||a in this._changed||(b=!1)}.bind(this)),b}return Sao.common.compare(Object.keys(this.model.fields).sort(),Object.keys(this._loaded).sort())},root_parent:function(){for(var a=this;a.group.parent;)a=a.group.parent;return a},get_path:function(a){for(var b=[],c=this,d="";c&&(b.push([d,c.id]),c.group!==a);)d=c.group.child_name,c=c.group.parent;return b.reverse(),b},deleted:function(){return Boolean(~this.group.record_deleted.indexOf(this))},removed:function(){return Boolean(~this.group.record_removed.indexOf(this))},readonly:function(){return this.deleted()||this.removed()||this.exception},set_field_context:function(){for(var a in this.model.fields)if(this.model.fields.hasOwnProperty(a)){var b=this.model.fields[a],c=this._values[a];if(c&&c.set_context){var d=b.description.context;d&&c.set_context(this.expr_eval(d))}}},get_attachment_count:function(a){var b=jQuery.Deferred();return this.id<0?(b.resolve(0),b):(this.attachment_count<0||a?b=Sao.rpc({method:"model.ir.attachment.search_count",params:[[["resource","=",this.model.name+","+this.id]],this.get_context()]},this.model.session).then(function(a){return this.attachment_count=a,a}.bind(this)):b.resolve(this.attachment_count),b)},get_unread_note:function(a){var b=jQuery.Deferred();return this.id<0?(b.resolve(0),b):(this.unread_note<0||a?b=Sao.rpc({method:"model.ir.note.search_count",params:[[["resource","=",this.model.name+","+this.id],["unread","=",!0]],this.get_context()]},this.model.session).then(function(a){return this.unread_note=a,a}.bind(this)):b.resolve(this.unread_note),b)},get_button_clicks:function(a){if(this.id<0)return jQuery.when();var b=this.button_clicks[a];return void 0!==b?jQuery.when(b):Sao.rpc({method:"model.ir.model.button.click.get_click",params:[this.model.name,a,this.id,{}]},this.model.session).then(function(b){return this.button_clicks[a]=b,b}.bind(this))}}),Sao.field={},Sao.field.get=function(a){switch(a){case"char":return Sao.field.Char;case"selection":return Sao.field.Selection;case"datetime":return Sao.field.DateTime;case"date":return Sao.field.Date;case"time":return Sao.field.Time;case"timedelta":return Sao.field.TimeDelta;case"float":return Sao.field.Float;case"numeric":return Sao.field.Numeric;case"integer":return Sao.field.Integer;case"boolean":return Sao.field.Boolean;case"many2one":return Sao.field.Many2One;case"one2one":return Sao.field.One2One;case"one2many":return Sao.field.One2Many;case"many2many":return Sao.field.Many2Many;case"reference":return Sao.field.Reference;case"binary":return Sao.field.Binary;case"dict":return Sao.field.Dict;default:return Sao.field.Char}},Sao.field.Field=Sao.class_(Object,{_default:null,init:function(a){this.description=a,this.name=a.name},set:function(a,b){a._values[this.name]=b},get:function(a){var b=a._values[this.name];return void 0===b&&(b=this._default),b},set_client:function(a,b,c){var d=this.get(a);this.set(a,b),JSON.stringify(d)!=JSON.stringify(this.get(a))?(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.changed().done(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})})})):c&&(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})}))},get_client:function(a){return this.get(a)},set_default:function(a,b){a._values[this.name]=b,a._changed[this.name]=!0},set_on_change:function(a,b){a._values[this.name]=b,a._changed[this.name]=!0},changed:function(a){var b=[];return b.push(a.on_change([this.name])),b.push(a.on_change_with([this.name])),b.push(a.autocomplete_with(this.name)),a.set_field_context(),jQuery.when.apply(jQuery,b)},get_timestamp:function(a){return{}},get_context:function(a){var b=jQuery.extend({},a.get_context());return a.group.parent&&jQuery.extend(b,a.group.parent.get_context()),jQuery.extend(b,a.expr_eval(this.description.context||{})),b},get_domains:function(a,b){var c=new Sao.common.DomainInversion,d=c.domain_inversion([a.group.domain4inversion(),b||[]],this.name,Sao.common.EvalEnvironment(a));"boolean"!=typeof d||d?"boolean"==typeof d&&d&&(d=[]):d=[["id","=",null]];var e=a.expr_eval(this.description.domain||[]);return[d,e]},get_domain:function(a){var b=this.get_domains(a),c=b[0],d=b[1],e=new Sao.common.DomainInversion;return e.concat([e.localize_domain(c),d])},validation_domains:function(a,b){var c=new Sao.common.DomainInversion;return c.concat(this.get_domains(a,b))},get_eval:function(a){return this.get(a)},get_on_change_value:function(a){return this.get_eval(a)},set_state:function(a,b){void 0===b&&(b=["readonly","required","invisible"]);var c=a.expr_eval(this.description.states||{});b.forEach(function(b){"readonly"==b&&this.description.readonly||(void 0!==c[b]?this.get_state_attrs(a)[b]=c[b]:void 0!==this.description[b]&&(this.get_state_attrs(a)[b]=this.description[b]))}.bind(this)),(a.group.get_readonly()||this.get_state_attrs(a).domain_readonly)&&(this.get_state_attrs(a).readonly=!0)},get_state_attrs:function(a){return this.name in a.state_attrs||(a.state_attrs[this.name]=jQuery.extend({},this.description)),(a.group.get_readonly()||a.readonly())&&(a.state_attrs[this.name].readonly=!0),a.state_attrs[this.name]},check_required:function(a){var b=this.get_state_attrs(a);return!(1==b.required&&!this.get(a)&&1!=b.readonly)},validate:function(a,b,c){if(this.description.readonly)return!0;var d=!1;this.get_state_attrs(a).domain_readonly=!1;var e=new Sao.common.DomainInversion,f=e.simplify(this.validation_domains(a,c));if(b||this.check_required(a)||(d="required"),"boolean"==typeof f)f||(d="domain");else if(Sao.common.compare(f,[["id","=",null]]))d="domain";else{var g=e.unique_value(f),h=g[0],i=g[1],j=g[2];if(h){j===!1&&(j=null);var k,l=!0;k=jQuery.isEmptyObject(a.group.domain())?e.merge(f):e.merge(a.group.domain());var m="AND"==k[0];if(i.contains(".")){var n=i.split(".",1)[0],o=i.split(".",1)[1],p=[];m&&e.localize_domain(k.slice(1)).forEach(function(a){p.push(a)}),"id"==o&&~p.indexOf(n)||(l=!1)}l&&!c&&(this.set_client(a,j),this.get_state_attrs(a).domain_readonly=m)}e.eval_domain(f,Sao.common.EvalEnvironment(a))||(d=f)}return this.get_state_attrs(a).invalid=d,!d}}),Sao.field.Char=Sao.class_(Sao.field.Field,{_default:"",get:function(a){return Sao.field.Char._super.get.call(this,a)||this._default}}),Sao.field.Selection=Sao.class_(Sao.field.Field,{_default:null}),Sao.field.DateTime=Sao.class_(Sao.field.Field,{_default:null,time_format:function(a){return a.expr_eval(this.description.format)},set_client:function(a,b,c){var d;b&&(b.isTime?(d=this.get(a),b=d?Sao.DateTime.combine(d,b):null):b.isDate&&(d=this.get(a),d&&(b=Sao.DateTime.combine(b,d)))),Sao.field.DateTime._super.set_client.call(this,a,b,c)},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)}}),Sao.field.Date=Sao.class_(Sao.field.Field,{_default:null,set_client:function(a,b,c){b&&!b.isDate&&(b.isDate=!0,b.isDateTime=!1),Sao.field.Date._super.set_client.call(this,a,b,c)},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)}}),Sao.field.Time=Sao.class_(Sao.field.Field,{_default:null,time_format:function(a){return a.expr_eval(this.description.format)},set_client:function(a,b,c){b&&(b.isDate||b.isDateTime)&&(b=Sao.Time(b.hour(),b.minute(),b.second(),b.millisecond())),Sao.field.Time._super.set_client.call(this,a,b,c)}}),Sao.field.TimeDelta=Sao.class_(Sao.field.Field,{_default:null,converter:function(a){return a.model.session.context[this.description.converter]},set_client:function(a,b,c){"string"==typeof b&&(b=Sao.common.timedelta.parse(b,this.converter(a))),Sao.field.TimeDelta._super.set_client.call(this,a,b,c)},get_client:function(a){var b=Sao.field.TimeDelta._super.get_client.call(this,a);return Sao.common.timedelta.format(b,this.converter(a))}}),Sao.field.Float=Sao.class_(Sao.field.Field,{_default:null,digits:function(a,b){void 0===b&&(b=1);var c=a.expr_eval(this.description.digits);if(c&&c.every(function(a){return null!==a})){var d=Math.round(Math.log(Math.abs(b))/Math.LN10);return[c[0]+d,c[1]-d]}},check_required:function(a){var b=this.get_state_attrs(a);return 1!=b.required||null!==this.get(a)||1==b.readonly},convert:function(a){return a?(a=Number(a),isNaN(a)&&(a=this._default),a):null},apply_factor:function(a,b){return null!==a&&(a/=b),a},set_client:function(a,b,c,d){void 0===d&&(d=1),b=this.apply_factor(this.convert(b),d),Sao.field.Float._super.set_client.call(this,a,b,c)},get_client:function(a,b){void 0===b&&(b=1);var c=this.get(a);if(null!==c){var d=this.digits(a,b);return d?(c*b).toFixed(d[1]):""+c*b}return""}}),Sao.field.Numeric=Sao.class_(Sao.field.Float,{convert:function(a){return a?(a=new Sao.Decimal(a),isNaN(a.valueOf())&&(a=this._default),a):null},apply_factor:function(a,b){return a=Sao.field.Numeric._super.apply_factor(a,b),null!==a&&(a=new Sao.Decimal(a)),a}}),Sao.field.Integer=Sao.class_(Sao.field.Float,{convert:function(a){return a=parseInt(a,10),isNaN(a)&&(a=this._default),a}}),Sao.field.Boolean=Sao.class_(Sao.field.Field,{_default:!1,set_client:function(a,b,c){b=Boolean(b),Sao.field.Boolean._super.set_client.call(this,a,b,c)},get:function(a){return Boolean(a._values[this.name])},get_client:function(a){return Boolean(a._values[this.name])}}),Sao.field.Many2One=Sao.class_(Sao.field.Field,{_default:null,check_required:function(a){var b=this.get_state_attrs(a);return 1!=b.required||null!==this.get(a)||1==b.readonly},get_client:function(a){var b=a._values[this.name+".rec_name"];return void 0===b&&(this.set(a,this.get(a)),b=a._values[this.name+".rec_name"]||""),b},set:function(a,b){var c=a._values[this.name+".rec_name"]||"",d=function(b){a._values[this.name+".rec_name"]=b[0].rec_name};if(!c&&b>=0&&null!==b){var e=a.model.fields[this.name].description.relation;Sao.rpc({method:"model."+e+".read",params:[[b],["rec_name"],a.get_context()]},a.model.session).done(d.bind(this)).done(function(){a.group.root_group().screens.forEach(function(a){a.display()})})}else d.call(this,[{rec_name:c}]);a._values[this.name]=b},set_client:function(a,b,c){var d;b instanceof Array?(d=b[1],b=b[0]):d=b==this.get(a)?a._values[this.name+".rec_name"]||"":"",a._values[this.name+".rec_name"]=d,Sao.field.Many2One._super.set_client.call(this,a,b,c)},get_context:function(a){var b=Sao.field.Many2One._super.get_context.call(this,a);return this.description.datetime_field&&(b._datetime=a.get_eval()[this.description.datetime_field]),b},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=this.get_domains(a),c=b[0],d=b[1],e=new Sao.common.DomainInversion;return e.concat([e.localize_domain(e.inverse_leaf(c),this.name),d])},get_on_change_value:function(a){return a.group.parent_name==this.name&&a.group.parent?a.group.parent.get_on_change_value([a.group.child_name]):Sao.field.Many2One._super.get_on_change_value.call(this,a)}}),Sao.field.One2One=Sao.class_(Sao.field.Many2One,{}),Sao.field.One2Many=Sao.class_(Sao.field.Field,{init:function(a){Sao.field.One2Many._super.init.call(this,a)},_default:null,_set_value:function(a,b,c){this._set_default_value(a);var d=a._values[this.name],e=jQuery.when();jQuery.isEmptyObject(b)&&(b=[]);var f;if(f=jQuery.isEmptyObject(b)||!isNaN(parseInt(b[0],10))?"list ids":"list values",
-"list values"==f){var g=this.get_context(a),h={};if(b.forEach(function(a){for(var b in a)a.hasOwnProperty(b)&&(b in d.model.fields||~b.indexOf(".")||(h[b]=!0))}),!jQuery.isEmptyObject(h)){var i={method:"model."+this.description.relation+".fields_get",params:[Object.keys(h),g]};e=Sao.rpc(i,a.model.session)}}var j=function(e){var g=[];if(jQuery.isEmptyObject(e)||d.add_fields(e),a._values[this.name]=d,"list ids"==f){for(var h=0,i=d.length;i>h;h++){var j=d[h];~b.indexOf(j.id)||d.remove(j,!0)}d.load(b)}else b.forEach(function(a){var b=d.new_(!1);c?(g.push(b.set_default(a,!1)),d.add(b)):(g.push(b.set(a)),d.push(b))});return jQuery.when.apply(jQuery,g)};return e.then(j)},set:function(a,b,c){void 0===c&&(c=!1);var d,e=a._values[this.name];return void 0!==e?(d=e.model,e.destroy()):d=a.model.name==this.description.relation?a.model:new Sao.Model(this.description.relation),a._values[this.name]=void 0,this._set_default_value(a,d),this._set_value(a,b,c)},get:function(a){var b=a._values[this.name];if(void 0===b)return[];for(var c=b.record_removed,d=b.record_deleted,e=[],f=this.description.relation_field||"",g=[],h=[],i=[],j=0,k=b.length;k>j;j++){var l=b[j];if(!~c.indexOf(l)&&!~d.indexOf(l)){var m;l.id>=0?(m=l.get(),delete m[f],l.has_changed()&&!jQuery.isEmptyObject(m)&&(i.push([l.id]),i.push(m)),g.push(l.id)):(m=l.get(),delete m[f],h.push(m))}}return jQuery.isEmptyObject(g)||e.push(["add",g]),jQuery.isEmptyObject(h)||e.push(["create",h]),jQuery.isEmptyObject(i)||e.push(["write"].concat(i)),jQuery.isEmptyObject(c)||e.push(["remove",c.map(function(a){return a.id})]),jQuery.isEmptyObject(d)||e.push(["delete",d.map(function(a){return a.id})]),e},set_client:function(a,b,c){null===b&&(b=[]),"number"==typeof b&&(b=[b]);var d=this.get_eval(a);this._set_value(a,b),Sao.common.compare(d.sort(),b.sort())?c&&(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})})):(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.changed().done(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})})}))},get_client:function(a){return this._set_default_value(a),a._values[this.name]},set_default:function(a,b){return a._changed[this.name]=!0,this.set(a,b,!0)},set_on_change:function(a,b){if(a._changed[this.name]=!0,this._set_default_value(a),b instanceof Array)return void this._set_value(a,b);var c=jQuery.when();if(b.add||b.update){var d=this.get_context(a),e=a._values[this.name].model.fields,f={},g=[];if(b.add)for(var h=0;h<b.add.length;h++)g.push(b.add[h][1]);if([g,b.update].forEach(function(a){jQuery.isEmptyObject(a)||a.forEach(function(a){Object.keys(a).forEach(function(a){a in e||"id"==a||(f[a]=!0)})})}),!jQuery.isEmptyObject(f)){var i={method:"model."+this.description.relation+".fields_get",params:[Object.keys(f),d]};c=Sao.rpc(i,a.model.session)}}var j=[],k=a._values[this.name];k.forEach(function(a){a.id||j.push(a)}),b.remove&&b.remove.forEach(function(a){var b=k.get(a);b&&j.push(b)}.bind(this)),j.forEach(function(a){k.remove(a,!1,!0,!1)}.bind(this)),(b.add||b.update)&&c.then(function(a){k.add_fields(a),b.add&&b.add.forEach(function(a){var b=a[0],c=a[1],d=k.new_(!1);k.add(d,b,!1),d.set_on_change(c)}),b.update&&b.update.forEach(function(a){if(a.id){var b=k.get(a.id);b&&b.set_on_change(a)}})}.bind(this))},_set_default_value:function(a,b){if(void 0===a._values[this.name]){b||(b=new Sao.Model(this.description.relation)),a.model.name==this.description.relation&&(b=a.model);var c=a.expr_eval(this.description.context||{}),d=Sao.Group(b,c,[]);d.set_parent(a),d.parent_name=this.description.relation_field,d.child_name=this.name,a._values[this.name]=d}},get_timestamp:function(a){var b=a._values[this.name];if(void 0===b)return{};for(var c,d={},e=0,f=b.length;f>e;e++)c=b[e],jQuery.extend(d,c.get_timestamp());return d},get_eval:function(a){var b=[],c=a._values[this.name];if(void 0===c)return b;for(var d=c.record_removed,e=c.record_deleted,f=0,g=a._values[this.name].length;g>f;f++){var h=c[f];~d.indexOf(h)||~e.indexOf(h)||b.push(h.id)}return b},get_on_change_value:function(a){var b=[],c=a._values[this.name];if(void 0===c)return b;for(var d=0,e=a._values[this.name].length;e>d;d++){var f=c[d];f.deleted()&&f.removed()||b.push(f.get_on_change_value([this.description.relation_field||""]))}return b},get_removed_ids:function(a){return a._values[this.name].record_removed.map(function(a){return a.id})},get_domain:function(a){var b=this.get_domains(a),c=b[1];return c},validation_domains:function(a,b){return this.get_domains(a,b)[0]},validate:function(a,b,c){var d=!1,e=new Sao.common.DomainInversion,f=e.localize_domain(e.domain_inversion(a.group.clean4inversion(c||[]),this.name,Sao.common.EvalEnvironment(a)),this.name);"boolean"==typeof f&&(f=f?[]:[["id","=",null]]);for(var g=0,h=(a._values[this.name]||[]).length;h>g;g++){var i=a._values[this.name][g];!i.get_loaded()&&i.id>=0&&!c||i.validate(null,b,f,!0)||(d="children")}var j=Sao.field.One2Many._super.validate.call(this,a,b,c);return j&&d?(this.get_state_attrs(a).invalid=d,!1):j},set_state:function(a,b){this._set_default_value(a),Sao.field.One2Many._super.set_state.call(this,a,b)}}),Sao.field.Many2Many=Sao.class_(Sao.field.One2Many,{get_on_change_value:function(a){return this.get_eval(a)}}),Sao.field.Reference=Sao.class_(Sao.field.Field,{_default:null,get_client:function(a){if(a._values[this.name]){var b=a._values[this.name][0],c=a._values[this.name+".rec_name"]||"";return[b,c]}return null},get:function(a){return a._values[this.name]&&a._values[this.name][0]&&a._values[this.name][1]>=-1?a._values[this.name].join(","):null},set_client:function(a,b,c){if(b){"string"==typeof b&&(b=b.split(","));var d,e=b[0],f=b[1];f instanceof Array?(d=f[1],f=f[0]):(f&&!isNaN(parseInt(f,10))&&(f=parseInt(f,10)),d=[e,f].join(",")==this.get(a)?a._values[this.name+".rec_name"]||"":""),a._values[this.name+".rec_name"]=d,b=[e,f]}Sao.field.Reference._super.set_client.call(this,a,b,c)},set:function(a,b){if(!b)return void(a._values[this.name]=this._default);var c,d;"string"==typeof b?(c=b.split(",")[0],d=b.split(",")[1],d?isNaN(parseInt(d,10))||(d=parseInt(d,10)):d=null):(c=b[0],d=b[1]);var e=a._values[this.name+".rec_name"]||"",f=function(b){a._values[this.name+".rec_name"]=b}.bind(this);c&&null!==d&&d>=0?!e&&d>=0&&Sao.rpc({method:"model."+c+".read",params:[[d],["rec_name"],a.get_context()]},a.model.session).done(function(a){f(a[0].rec_name)}):e=c?"":d,a._values[this.name]=[c,d],f(e)},get_on_change_value:function(a){return a.group.parent_name==this.name&&a.group.parent?[a.group.parent.model.name,a.group.parent.get_on_change_value([a.group.child_name])]:Sao.field.Reference._super.get_on_change_value.call(this,a)},get_context:function(a){var b=Sao.field.Reference._super.get_context.call(this,a);return this.description.datetime_field&&(b._datetime=a.get_eval()[this.description.datetime_field]),b},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=null;a._values[this.name]&&(b=a._values[this.name][0]);var c=this.get_domains(a),d=c[0],e=c[1],f=new Sao.common.DomainInversion;return f.concat([f.localize_domain(f.filter_leaf(d,this.name,b),!0),e])}}),Sao.field.Binary=Sao.class_(Sao.field.Field,{_default:null,get_size:function(a){var b=a._values[this.name]||0;return b instanceof Uint8Array?b.length:b},get_data:function(a){var b=a._values[this.name]||[],c=jQuery.when(b);if(!(b instanceof Uint8Array)){if(a.id<0)return c;var d=a.get_context();c=a.model.execute("read",[[a.id],[this.name]],d).then(function(a){return a[0][this.name]}.bind(this))}return c}}),Sao.field.Dict=Sao.class_(Sao.field.Field,{_default:{},set:function(a,b){if(b){var c=[];for(var d in b)c.push(d);c.sort();var e={};for(var f in c)d=c[f],e[d]=b[d];b=e}Sao.field.Dict._super.set.call(this,a,b)},get:function(a){return Sao.field.Dict._super.get.call(this,a)||this._default},get_client:function(a){return Sao.field.Dict._super.get_client.call(this,a)||this._default},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=new Sao.common.DomainInversion,c=this.get_domains(a),d=c[0],e=c[1];return b.concat([b.localize_domain(b.inverse_leaf(d)),e])},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)},time_format:function(a){return"%X"}})}(),function(){"use strict";Sao.Tab=Sao.class_(Object,{init:function(){Sao.Tab.tabs.push(this),this.buttons={},this.id="tab-"+Sao.Tab.counter++,this.name="",this.name_el=jQuery("<span/>")},create_tabcontent:function(){this.el=jQuery("<div/>",{"class":this.class_});var a=this.create_toolbar().appendTo(this.el);this.title=a.find(".title"),this.content=jQuery("<div/>").appendTo(this.el),this.info_bar&&this.el.append(this.info_bar.el)},set_menu:function(a){this.menu_def().forEach(function(b){var c=b[0],d=b[1],e=b[2],f=jQuery("<li/>",{role:"presentation"}).appendTo(a),g=jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(jQuery("<span/>",{"class":"glyphicon "+c,"aria-hidden":"true"})).append(" "+d).appendTo(f);e?g.click(function(){this[e]()}.bind(this)):f.addClass("disabled")}.bind(this))},create_toolbar:function(){var a=jQuery("<nav/>",{"class":"toolbar navbar navbar-default",role:"toolbar"}).append(jQuery("<div/>",{"class":"container-fluid"}).append(jQuery("<div/>",{"class":"dropdown navbar-header navbar-left"}).append(jQuery("<a/>",{href:"#","class":"navbar-brand dropdown-toggle","data-toggle":"dropdown",role:"button","aria-expanded":!1,"aria-haspopup":!0}).append(jQuery("<span/>",{"class":"title"})).append(jQuery("<span/>",{"class":"caret"}))).append(jQuery("<ul/>",{"class":"dropdown-menu",role:"menu"})).append(jQuery("<button/>",{type:"button","class":"close visible-xs visible-sm","aria-label":Sao.i18n.gettext("Close")}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).click(function(){this.close()}.bind(this)))).append(jQuery("<div/>",{"class":"btn-toolbar navbar-right",role:"toolbar"}))),b=jQuery("<div/>",{"class":"toolbar-wrapper"}).append(a);this.set_menu(a.find('ul[role*="menu"]'));var c,d=function(b){return b?(c||(c=jQuery("<div/>",{"class":"btn-group",role:"group"}).appendTo(a.find(".btn-toolbar"))),this.buttons[b[0]]=jQuery("<button/>",{type:"button","class":"btn btn-default navbar-btn",title:b[2],id:b[0]}).append(jQuery("<span/>",{"class":"glyphicon "+b[1],"aria-hidden":"true"})).appendTo(c).data("toggle","tooltip").data("placement","bottom").tooltip(),void(b[3]?this.buttons[b[0]].click(this[b[3]].bind(this)):item.addClass("disabled"))):void(c=null)};this.toolbar_def().forEach(d.bind(this)),a.find(".btn-toolbar > .btn-group").last().addClass("hidden-xs");var e=jQuery("#tabs");return a.affix({target:e.parent(),offset:{top:function(){return jQuery("#main_navbar").height()}}}),a.on("affix.bs.affix",function(){b.height(jQuery("#main_navbar").height())}),a.on("affix-top.bs.affix affix-bottom.bs.affix",function(){b.height("")}),a.on("affixed.bs.affix",function(){Sao.Tab.affix_set_with(a)}),a.on("affixed-top.bs.affix affixed-bottom.bs.affix",function(){Sao.Tab.affix_unset_width(a)}),b},close:function(){var a=jQuery("#tabs"),b=jQuery("#tablist"),c=b.find("#nav-"+this.id),d=a.find("#"+this.id);return b.find('a[href="#'+this.id+'"]').tab("show"),this._close_allowed().then(function(){var b=c.nextAll("li").first();b.length||(b=c.prevAll("li").first()),c.tooltip("destroy").remove(),d.remove(),Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(this),1),b&&b.find("a").tab("show"),a.trigger("ready")}.bind(this))},_close_allowed:function(){return jQuery.when()},set_name:function(a){this.name=a,this.name_el.text(Sao.common.ellipsize(a,20)),this.name_el.parents("li").first().attr("title",a).tooltip()}}),Sao.Tab.affix_set_with=function(a){var b=jQuery(a.parent()).width();a.css("width",b)},Sao.Tab.affix_unset_width=function(a){a.css("width","")},jQuery(window).resize(function(){jQuery(".toolbar").each(function(a,b){b=jQuery(b),b.affix("checkPosition"),b.hasClass("affix")?Sao.Tab.affix_set_with(b):Sao.Tab.affix_unset_width(b)})}),Sao.Tab.counter=0,Sao.Tab.tabs=[],Sao.Tab.tabs.close=function(a){if(a&&Sao.Tab.tabs.length)return Sao.common.sur.run(Sao.i18n.gettext("The following action requires to close all tabs.\nDo you want to continue?")).then(function(){return Sao.Tab.tabs.close(!1)});if(Sao.Tab.tabs.length){var b=Sao.Tab.tabs[0];return b.close().then(function(){return~Sao.Tab.tabs.indexOf(b)?jQuery.Deferred().reject():Sao.Tab.tabs.close()})}return Sao.main_menu_screen?Sao.main_menu_screen.save_tree_state().then(function(){Sao.main_menu_screen=null}):jQuery.when()},Sao.Tab.tabs.get_current=function(){var a=jQuery("#tablist"),b=a.find("li").index(a.find("li.active"));return Sao.Tab.tabs[b]},Sao.Tab.tabs.close_current=function(){var a=this.get_current();a.close()},Sao.Tab.create=function(a){void 0===a.context&&(a.context={});var b;b=a.model?new Sao.Tab.Form(a.model,a):new Sao.Tab.Board(a),Sao.Tab.add(b)},Sao.Tab.add=function(a){var b=jQuery("#tabs"),c=jQuery("#tablist"),d=jQuery("#tabcontent"),e=jQuery("<a/>",{"aria-controls":a.id,role:"tab","data-toggle":"tab",href:"#"+a.id}).append(jQuery("<button/>",{"class":"close"}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Close"))).click(function(){a.close()})).append(a.name_el);jQuery("<li/>",{role:"presentation","data-toggle":"tooltip","data-placement":"bottom",id:"nav-"+a.id}).append(e).appendTo(c),jQuery("<div/>",{role:"tabpanel","class":"tab-pane",id:a.id}).html(a.el).appendTo(d),e.on("shown.bs.tab",function(){Sao.View.resize(a.el)}),e.tab("show"),b.trigger("ready")},Sao.Tab.Form=Sao.class_(Sao.Tab,{class_:"tab-form",init:function(a,b){Sao.Tab.Form._super.init.call(this);var c=new Sao.Screen(a,b);c.tab=this,this.screen=c,this.attributes=jQuery.extend({},b),this.info_bar=new Sao.Window.InfoBar,this.create_tabcontent(),this.set_buttons_sensitive(),this.view_prm=this.screen.switch_view().done(function(){this.set_name(b.name||""),this.content.append(c.screen_container.el),b.res_id?(jQuery.isArray(b.res_id)||(b.res_id=[b.res_id]),c.group.load(b.res_id),c.set_current_record(c.group.get(b.res_id)),c.display()):("form"==c.current_view.view_type&&c.new_(),~["tree","graph","calendar"].indexOf(c.current_view.view_type)&&c.search_filter()),this.update_revision()}.bind(this))},toolbar_def:function(){return[["new","glyphicon-edit",Sao.i18n.gettext("Create a new record"),"new_"],["save","glyphicon-save",Sao.i18n.gettext("Save this record"),"save"],["switch","glyphicon-list-alt",Sao.i18n.gettext("Switch view"),"switch_"],["reload","glyphicon-refresh",Sao.i18n.gettext("Reload"),"reload"],null,["previous","glyphicon-chevron-left",Sao.i18n.gettext("Previous Record"),"previous"],["next","glyphicon-chevron-right",Sao.i18n.gettext("Next Record"),"next"],null,["attach","glyphicon-paperclip",Sao.i18n.gettext("Add an attachment to the record"),"attach"],["note","glyphicon-comment",Sao.i18n.gettext("Add a note to the record"),"note"]]},menu_def:function(){return[["glyphicon-edit",Sao.i18n.gettext("New"),"new_"],["glyphicon-save",Sao.i18n.gettext("Save"),"save"],["glyphicon-list-alt",Sao.i18n.gettext("Switch"),"switch_"],["glyphicon-refresh",Sao.i18n.gettext("Reload/Undo"),"reload"],["glyphicon-duplicate",Sao.i18n.gettext("Duplicate"),"copy"],["glyphicon-trash",Sao.i18n.gettext("Delete"),"delete_"],["glyphicon-chevron-left",Sao.i18n.gettext("Previous"),"previous"],["glyphicon-chevron-right",Sao.i18n.gettext("Next"),"next"],["glyphicon-search",Sao.i18n.gettext("Search"),"search"],["glyphicon-time",Sao.i18n.gettext("View Logs..."),"logs"],["glyphicon-time",Sao.i18n.gettext("Show revisions..."),Sao.common.MODELHISTORY.contains(this.screen.model_name)?"revision":null],["glyphicon-remove",Sao.i18n.gettext("Close Tab"),"close"],["glyphicon-paperclip",Sao.i18n.gettext("Attachment"),"attach"],["glyphicon-comment",Sao.i18n.gettext("Note"),"note"],["glyphicon-cog",Sao.i18n.gettext("Action"),"action"],["glyphicon-share-alt",Sao.i18n.gettext("Relate"),"relate"],["glyphicon-print",Sao.i18n.gettext("Print"),"print"],["glyphicon-export",Sao.i18n.gettext("Export"),"export"],["glyphicon-import",Sao.i18n.gettext("Import"),"import"]]},create_toolbar:function(){var a=Sao.Tab.Form._super.create_toolbar.call(this),b=this.screen,c=this.buttons,d=b.model.execute("view_toolbar_get",[],b.context);return d.done(function(d){[["action","glyphicon-cog",Sao.i18n.gettext("Launch action")],["relate","glyphicon-share-alt",Sao.i18n.gettext("Open related records")],["print","glyphicon-print",Sao.i18n.gettext("Print report")]].forEach(function(e){var f=jQuery("<div/>",{"class":"btn-group",role:"group"}).append(jQuery("<button/>",{type:"button","class":"btn btn-default navbar-btn dropdown-toggle","data-toggle":"dropdown","aria-expanded":!1,"aria-haspopup":!0,title:e[2],id:e[0],disabled:!d[e[0]].length}).append(jQuery("<span/>",{"class":"glyphicon "+e[1],"aria-hidden":"true"})).append(jQuery("<span/>",{"class":"caret"})).data("toggle","tooltip").data("placement","bottom").tooltip()).append(jQuery("<ul/>",{"class":"dropdown-menu",role:"menu","aria-labelledby":e[0]})).appendTo(a.find(".btn-toolbar > .btn-group").last());c[e[0]]=f;var g=(f.on("show.bs.dropdown",function(){jQuery(this).parents(".btn-group").removeClass("hidden-xs")}).on("hide.bs.dropdown",function(){jQuery(this).parents(".btn-group").addClass("hidden-xs")}),f.find('ul[role*="menu"]'));"action"==e[0]&&f.click(function(){g.find(".action_button").remove();var a=b.get_buttons();a.forEach(function(a){jQuery("<li/>",{role:"presentation","class":"action_button"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(a.attributes.string||"")).click(function(){b.button(a.attributes)}).appendTo(g)})}),d[e[0]].forEach(function(a){jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(a.name)).click(function(){b.save_current().then(function(){var c=jQuery.extend({},a),d=null;b.current_record&&(d=b.current_record.id);var f=b.current_view.selected_records().map(function(a){return a.id});c=Sao.Action.evaluate(c,e[0],b.current_record);var g={model:b.model_name,id:d,ids:f};Sao.Action.exec_action(c,g,b.context)})}).appendTo(g)})})}),a},_close_allowed:function(){return this.modified_save()},modified_save:function(){return this.screen.save_tree_state(),this.screen.current_view.set_value(),this.screen.modified()?Sao.common.sur_3b.run(Sao.i18n.gettext("This record has been modified\ndo you want to save it?")).then(function(a){switch(a){case"ok":return this.save();case"ko":return this.reload(!1);default:return jQuery.Deferred().reject()}}.bind(this)):jQuery.when()},new_:function(){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.modified_save().done(function(){this.screen.new_().then(function(){this.info_bar.message()}.bind(this))}.bind(this))},save:function(){var a=Sao.common.MODELACCESS.get(this.screen.model_name);return a.write||a.create?this.screen.save_current().then(function(){this.info_bar.message(Sao.i18n.gettext("Record saved."),"info"),this.screen.count_tab_domain()}.bind(this),function(){this.info_bar.message(this.screen.invalid_message(),"danger")}.bind(this)):jQuery.when()},switch_:function(){this.modified_save().done(function(){this.screen.switch_view()}.bind(this))},reload:function(a){void 0===a&&(a=!0);var b=function(){return this.screen.cancel_current().then(function(){return this.screen.save_tree_state(!1),"form"!=this.screen.current_view.view_type&&this.screen.search_filter(this.screen.screen_container.search_entry.val()),this.screen.count_tab_domain(),this.screen.display().then(function(){this.info_bar.message()}.bind(this))}.bind(this))}.bind(this);return a?this.modified_save().then(b):b()},copy:function(){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.modified_save().done(function(){this.screen.copy().then(function(){this.info_bar.message(Sao.i18n.gettext("Working now on the duplicated record(s)."),"info"),this.screen.count_tab_domain()}.bind(this))}.bind(this))},delete_:function(){if(Sao.common.MODELACCESS.get(this.screen.model_name)["delete"]){var a;a="form"==this.screen.current_view.view_type?Sao.i18n.gettext("Are you sure to remove this record?"):Sao.i18n.gettext("Are you sure to remove those records?"),Sao.common.sur.run(a).done(function(){this.screen.remove(!0,!1,!0).then(function(){this.info_bar.message(Sao.i18n.gettext("Records removed."),"info"),this.screen.count_tab_domain()}.bind(this),function(){this.info_bar.message(Sao.i18n.gettext("Records not removed."),"danger")}.bind(this))}.bind(this))}},previous:function(){this.modified_save().done(function(){this.screen.display_previous(),this.info_bar.message()}.bind(this))},next:function(){this.modified_save().done(function(){this.screen.display_next(),this.info_bar.message()}.bind(this))},search:function(){var a=this.screen.screen_container.search_entry;a.is(":visible")&&window.setTimeout(function(){a.focus()},0)},logs:function(){var a=this.screen.current_record;if(!a||a.id<0)return void this.info_bar.message(Sao.i18n.gettext("You have to select one record."),"info");var b=[["id",Sao.i18n.gettext("ID:")],["create_uid.rec_name",Sao.i18n.gettext("Creation User:")],["create_date",Sao.i18n.gettext("Creation Date:")],["write_uid.rec_name",Sao.i18n.gettext("Latest Modification by:")],["write_date",Sao.i18n.gettext("Latest Modification Date:")]];this.screen.model.execute("read",[[a.id],b.map(function(a){return a[0]})],this.screen.context).then(function(a){a=a[0];var c="";b.forEach(function(b){var d=b[0],e=b[1],f=a[d]||"/";a[d]&&~["create_date","write_date"].indexOf(d)&&(f=Sao.common.format_datetime(Sao.common.date_format(),"%H:%M:%S",f)),c+=e+" "+f+"\n"}),c+=Sao.i18n.gettext("Model: ")+this.screen.model.name,Sao.common.message.run(c)}.bind(this))},revision:function(){var a=null;this.screen.current_record&&(a=this.screen.current_record.id);var b=function(b){return function(c){c&&c.add(1,"milliseconds"),"form"==this.screen.current_view.view_type&&c<b[b.length-1][0]&&(c=b[b.length-1][0]),c!=this.screen.context._datetime&&(this.screen.context._datetime=c,"form"!=this.screen.current_view.view_type?this.screen.search_filter(this.screen.screen_container.search_entry.val()):this.screen.new_group([a]),this.screen.display(!0),this.update_revision())}.bind(this)}.bind(this);this.modified_save().done(function(){var a=this.screen.current_view.selected_records().map(function(a){return a.id});this.screen.model.execute("history_revisions",[a],this.screen.context).then(function(a){new Sao.Window.Revision(a,b(a))})}.bind(this))},update_revision:function(){var a,b=this.screen.context._datetime;if(b){var c=Sao.common.date_format(),d="%H:%M:%S.%f";b=Sao.common.format_datetime(c,d,b),a=this.name+" @ "+b}else a=this.name;this.title.html(a),this.set_buttons_sensitive(b)},set_buttons_sensitive:function(a){if(a)["new","save"].forEach(function(a){this.buttons[a].parent().addClass("disabled")}.bind(this));else{var b=Sao.common.MODELACCESS.get(this.screen.model_name);[["new",b.create],["save",b.create||b.write]].forEach(function(a){var b=a[0],c=a[1];c?this.buttons[b].parent().removeClass("disabled"):this.buttons[b].parent().addClass("disabled")}.bind(this))}},attach:function(){var a=this.screen.current_record;!a||a.id<0||new Sao.Window.Attachment(a,function(){this.update_attachment_count(!0)}.bind(this))},update_attachment_count:function(a){var b=this.screen.current_record;b?b.get_attachment_count(a).always(this.attachment_count.bind(this)):this.attachment_count(0)},attachment_count:function(a){var b=this.buttons.attach.find(".badge");b.length||(b=jQuery("<span/>",{"class":"badge"}).appendTo(this.buttons.attach)),b.text(a);var c=this.screen.get_id();this.buttons.attach.prop("disabled",0>c||null===c)},note:function(){var a=this.screen.current_record;!a||a.id<0||new Sao.Window.Note(a,function(){this.update_unread_note(!0)}.bind(this))},update_unread_note:function(a){var b=this.screen.current_record;b?b.get_unread_note(a).always(this._unread_note.bind(this)):this._unread_note(0)},_unread_note:function(a){var b=this.buttons.note.find(".badge");b.length||(b=jQuery("<span/>",{"class":"badge"}).appendTo(this.buttons.note)),b.text(a);var c=this.screen.get_id();this.buttons.note.prop("disabled",0>c||null===c)},record_message:function(){this.info_bar.message()},action:function(){window.setTimeout(function(){this.buttons.action.find("button").click()}.bind(this))},relate:function(){window.setTimeout(function(){this.buttons.relate.find("button").click()}.bind(this))},print:function(){window.setTimeout(function(){this.buttons.print.find("button").click()}.bind(this))},"export":function(){new Sao.Window.Export(this.screen,this.screen.current_view.selected_records().map(function(a){return a.id}),this.screen.current_view.get_fields(),this.screen.context)},"import":function(){new Sao.Window.Import(this.screen)}}),Sao.Tab.Board=Sao.class_(Sao.Tab,{class_:"tab-board",init:function(a){var b,c;Sao.Tab.Board._super.init.call(this),this.model=a.model,this.view_id=a.view_ids.length>0?a.view_ids[0]:null,this.context=a.context,this.name=a.name||"",this.dialogs=[],this.board=null,b=new Sao.Model("ir.ui.view"),c=b.execute("read",[[this.view_id],["arch"]],this.context),c.done(function(a){var b;b=jQuery(jQuery.parseXML(a[0].arch)),this.board=new Sao.View.Board(b,this.context),this.board.actions_prms.done(function(){var a,b,c;for(a=0,b=this.board.actions.length;b>a;a++)c=this.board.actions[a],c.screen.tab=this}.bind(this)),this.el.append(this.board.el)}.bind(this)),this.create_tabcontent(),this.set_name(this.name),this.title.html(this.name_el.text())},toolbar_def:function(){return[["reload","glyphicon-refresh",Sao.i18n.gettext("Reload"),"reload"]]},menu_def:function(){return[["glyphicon-refresh",Sao.i18n.gettext("Reload/Undo"),"reload"]]},reload:function(){this.board.reload()},record_message:function(){var a,b,c;for(b=this.board.actions.length,a=0,b=b;b>a;a++)c=this.board.actions[a],c.update_domain(this.board.actions)},attachment_count:function(){},note:function(){},update_unread_note:function(){}}),Sao.Tab.Wizard=Sao.class_(Sao.Tab,{class_:"tab-wizard",init:function(a){Sao.Tab.Wizard._super.init.call(this),this.wizard=a,this.set_name(a.name),a.tab=this,this.create_tabcontent(),this.title.html(this.name_el.text()),this.el.append(a.form)},create_toolbar:function(){return jQuery("<span/>")},_close_allowed:function(){var a=this.wizard,b=jQuery.when();a.state!==a.end_state&&a.end_state in a.states&&(b=a.response(a.end_state));var c=jQuery.Deferred();return b.always(function(){a.state===a.end_state?c.resolve():c.reject()}),c.promise()}})}(),function(){"use strict";Sao.ScreenContainer=Sao.class_(Object,{init:function(a){this.alternate_viewport=jQuery("<div/>",{"class":"screen-container"}),this.alternate_view=!1,this.search_modal=null,this.search_form=null,this.last_search_text="",this.tab_domain=a||[],this.tab_counter=[],this.el=jQuery("<div/>",{"class":"screen-container"}),this.filter_box=jQuery("<form/>",{"class":"filter-box"}).submit(function(a){this.do_search(),a.preventDefault()}.bind(this));var b=jQuery("<div/>",{"class":"row"}).appendTo(this.filter_box);this.el.append(this.filter_box),this.filter_button=jQuery("<button/>",{type:"button","class":"btn btn-default"}).append(Sao.i18n.gettext("Filters")),this.filter_button.click(this.search_box.bind(this)),this.search_entry=jQuery("<input/>",{"class":"form-control",placeholder:Sao.i18n.gettext("Search")}),this.search_list=jQuery("<datalist/>"),this.search_list.uniqueId(),this.search_entry.attr("list",this.search_list.attr("id")),this.search_entry.keypress(this.key_press.bind(this)),this.search_entry.on("input",this.update.bind(this));var c=jQuery("<button/>",{type:"submit","class":"btn btn-default","aria-label":Sao.i18n.gettext("Search")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-search"}));this.but_bookmark=jQuery("<button/>",{type:"button","class":"btn btn-default dropdown-toggle","data-toggle":"dropdown","aria-expanded":!1,"aria-label":Sao.i18n.gettext("Bookmarks"),id:"bookmarks"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-bookmark","aria-hidden":!0}));var d=jQuery("<ul/>",{"class":"dropdown-menu",role:"menu","aria-labelledby":"bookmarks"});if(this.but_bookmark.click(function(){d.children().remove();for(var a=this.bookmarks(),b=0;b<a.length;b++){var c=a[b][1],e=a[b][2];jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(c).click(e,this.bookmark_activate.bind(this))).appendTo(d)}}.bind(this)),this.but_star=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon","aria-hidden":!0})).click(this.star_click.bind(this)),this.set_star(),jQuery("<div/>",{"class":"input-group"}).append(jQuery("<span/>",{"class":"input-group-btn"}).append(this.filter_button)).append(this.search_entry).append(this.search_list).append(jQuery("<span/>",{"class":"input-group-btn"}).append(c).append(this.but_star).append(this.but_bookmark).append(d)).appendTo(jQuery("<div/>",{"class":"col-sm-10 col-xs-12"}).appendTo(b)),this.but_prev=jQuery("<button/>",{type:"button","class":"btn btn-default","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-menu-left","aria-hidden":!0})),this.but_prev.click(this.search_prev.bind(this)),this.but_next=jQuery("<button/>",{type:"button","class":"btn btn-default","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-menu-right","aria-hidden":!0})),this.but_next.click(this.search_next.bind(this)),jQuery("<div/>",{"class":"btn-group",role:"group"}).append(this.but_prev).append(this.but_next).appendTo(jQuery("<div/>",{"class":"col-sm-2 pull-right"}).appendTo(b)),this.content_box=jQuery("<div/>",{"class":"content-box"}),jQuery.isEmptyObject(this.tab_domain))this.tab=null;else{this.tab=jQuery("<div/>",{"class":"tab-domain"}).appendTo(this.el);var e=jQuery("<ul/>",{"class":"nav nav-tabs",role:"tablist"}).appendTo(this.tab);jQuery("<div/>",{"class":"tab-content"}).appendTo(this.tab);this.tab_domain.forEach(function(a,b){var c=a[0],d=jQuery("<span/>",{"class":"badge"});jQuery("<li/>",{role:"presentation",id:"nav-"+b}).append(jQuery("<a/>",{"aria-controls":b,role:"tab","data-toggle":"tab",href:"#"+b}).append(c+" ").append(d)).appendTo(e);this.tab_counter.push(d)}.bind(this)),e.find("a:first").tab("show");var f=this;e.find("a").click(function(a){a.preventDefault(),jQuery(this).tab("show"),f.do_search(),f.screen.count_tab_domain()})}this.el.append(this.content_box)},set_text:function(a){this.search_entry.val(a),this.bookmark_match()},update:function(){var a=this.screen.domain_parser().completion(this.get_text());this.search_list.children().remove(),a.forEach(function(a){jQuery("<option/>",{value:a.trim()}).appendTo(this.search_list)},this)},set_star:function(a){var b=this.but_star.children("span.glyphicon");a?(b.removeClass("glyphicon-star-empty"),b.addClass("glyphicon-star"),this.but_star.attr("aria-label",Sao.i18n.gettext("Remove this bookmark"))):(b.removeClass("glyphicon-star"),b.addClass("glyphicon-star-empty"),this.but_star.attr("aria-label",Sao.i18n.gettext("Bookmark this filter")))},get_star:function(){var a=this.but_star.children("span.glyphicon");return a.hasClass("glyphicon-star")},star_click:function(){var a=this.get_star(),b=this.screen.model_name,c=function(){this.bookmark_match(),this.but_bookmark.prop("disabled",jQuery.isEmptyObject(this.bookmarks()))}.bind(this);if(a){var d=this.bookmark_match();Sao.common.VIEW_SEARCH.remove(b,d).then(function(){c()})}else{var e=this.get_text();if(!e)return;Sao.common.ask.run(Sao.i18n.gettext("Bookmark Name:")).then(function(a){if(a){var d=this.screen.domain_parser().parse(e);Sao.common.VIEW_SEARCH.add(b,a,d).then(function(){c()}),this.set_text(this.screen.domain_parser().string(d))}}.bind(this))}},bookmarks:function(){
-var a=Sao.common.VIEW_SEARCH.get(this.screen.model_name);return a.filter(function(a){return this.screen.domain_parser().stringable(a[2])}.bind(this))},bookmark_activate:function(a){var b=a.data;this.set_text(this.screen.domain_parser().string(b)),this.do_search()},bookmark_match:function(){var a=this.get_text();if(a){var b=this.screen.domain_parser().parse(a);this.but_star.prop("disabled",!a);for(var c=(this.get_star(),this.bookmarks()),d=0;d<c.length;d++){var e=c[d][0],f=(c[d][1],c[d][2]),g=this.screen.domain_parser().string(f);if(g===a||Sao.common.compare(f,b))return this.set_star(!0),e}}this.set_star(!1)},search_prev:function(){this.screen.search_prev(this.get_text())},search_next:function(){this.screen.search_next(this.get_text())},get_tab_domain:function(){if(!this.tab)return[];var a=this.tab.find("li").index(this.tab.find("li.active"));return this.tab_domain[a][1]},set_tab_counter:function(a,b){if(!jQuery.isEmptyObject(this.tab_counter)&&this.tab&&(void 0!==b&&null!==b||(b=this.tab.find("li").index(this.tab.find("li.active"))),!(0>b))){var c=this.tab_counter[b];if(c.data("toggle","tooltip"),null===a)c.attr("title",""),c.text("");else{c.attr("title",a);var d=a;a>99&&(d="99+"),c.text(d)}c.tooltip()}},do_search:function(){return this.screen.search_filter(this.get_text())},key_press:function(a){window.setTimeout(function(){this.bookmark_match()}.bind(this))},set_screen:function(a){this.screen=a,this.but_bookmark.prop("disabled",jQuery.isEmptyObject(this.bookmarks())),this.bookmark_match()},show_filter:function(){this.filter_box.show(),this.tab&&this.tab.show()},hide_filter:function(){this.filter_box.hide(),this.tab&&this.tab.hide()},set:function(a){this.alternate_view?(this.alternate_viewport.children().detach(),this.alternate_viewport.append(a)):(this.content_box.children().detach(),this.content_box.append(a))},get_text:function(){return this.search_entry.val()},search_box:function(){var a=this.screen.domain_parser(),b=function(){this.search_modal.modal("hide");for(var b="",c=a.quote.bind(a),d=0;d<this.search_form.fields.length;d++){var e,f=this.search_form.fields[d][0],g=this.search_form.fields[d][1];switch(g.type){case"selection":case"date":case"datetime":case"time":e=g.get_value(c);break;default:e=c(g.val())}e&&(b+=c(f)+": "+e+" ")}this.set_text(b),this.do_search().then(function(){this.last_search_text=this.get_text()}.bind(this))}.bind(this);if(!this.search_modal){var c=new Sao.Dialog(Sao.i18n.gettext("Filters"),"","lg");this.search_modal=c.modal,this.search_form=c.content,this.search_form.addClass("form-horizontal"),this.search_form.submit(function(a){b(),a.preventDefault()});var d,e=[];for(var f in a.fields)d=a.fields[f],(d.searchable||void 0===d.searchable)&&e.push(d);var g=function(a){return function(b){jQuery("<option/>",{value:b,text:b}).appendTo(a)}},h="filter-"+this.screen.model_name+"-";this.search_form.fields=[];for(var i=0;i<e.length;i++){d=e[i];var j,k,l=jQuery("<div/>",{"class":"form-group form-group-sm"}).append(jQuery("<label/>",{"class":"col-sm-4 control-label","for":h+d.name,text:d.string})).appendTo(c.body);switch(d.type){case"boolean":k=j=jQuery("<select/>",{"class":"form-control input-sm",id:h+d.name}),["",Sao.i18n.gettext("True"),Sao.i18n.gettext("False")].forEach(g(j));break;case"selection":k=new Sao.ScreenContainer.Selection(d.selection,h+d.name),j=k.el;break;case"date":case"datetime":case"time":var m,n=Sao.common.date_format();if("date"==d.type)m=n;else{var o=new Sao.PYSON.Decoder({}).decode(d.format);o=Sao.common.moment_format(o),"time"==d.type?m=o:"datetime"==d.type&&(m=n+" "+o)}k=new Sao.ScreenContainer.DateTimes(m,h+d.name),j=k.el;break;default:k=j=jQuery("<input/>",{"class":"form-control input-sm",type:"text",placeholder:d.string,id:h+d.name})}jQuery("<div/>",{"class":"col-sm-8"}).append(j).appendTo(l),this.search_form.fields.push([d.string,k,j])}jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Find")).click(b).appendTo(c.footer)}if(this.search_modal.modal("show"),this.last_search_text.trim()!==this.get_text().trim()){for(var p=0;p<this.search_form.fields.length;p++){var q=this.search_form.fields[p][1];switch(q.type){case"selection":q.set_value([]);break;case"date":case"datetime":case"time":q.set_value(null,null);break;default:q.val("")}}this.search_form.fields[0][2].focus()}}}),Sao.ScreenContainer.DateTimes=Sao.class_(Object,{type:"date",init:function(a,b){this.el=jQuery("<div/>",{"class":"row",id:b});var c=function(c){var d=jQuery("<div/>",{"class":"input-group input-group-sm"});return jQuery("<input/>",{"class":"form-control input-sm",type:"text",placeholder:c,id:b+"-from"}).appendTo(d),jQuery("<span/>",{"class":"input-group-btn"}).append(jQuery("<button/>",{"class":"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-calendar"}))).appendTo(d),d.datetimepicker({locale:moment.locale()}),d.data("DateTimePicker").format(a),d};this.from=c("From").appendTo(jQuery("<div/>",{"class":"col-md-5"}).appendTo(this.el)),jQuery("<p/>",{"class":"text-center"}).append("..").appendTo(jQuery("<div/>",{"class":"col-md-1"}).appendTo(this.el)),this.to=c("To").appendTo(jQuery("<div/>",{"class":"col-md-5"}).appendTo(this.el))},_get_value:function(a){return a.find("input").val()},get_value:function(a){var b=this._get_value(this.from),c=this._get_value(this.to);return b&&c?b!==c?a(b)+".."+a(c):a(b):b?">="+a(b):c?"<="+a(c):void 0},set_value:function(a,b){this.from.data("DateTimePicker").date(a),this.to.data("DateTimePicker").date(b)}}),Sao.ScreenContainer.Selection=Sao.class_(Object,{type:"selection",init:function(a,b){this.el=jQuery("<select/>",{"class":"form-control input-sm",multiple:!0,id:b}),a.forEach(function(a){jQuery("<option/>",{value:a[1],text:a[1]}).appendTo(this.el)}.bind(this))},get_value:function(a){var b=this.el.val();return b&&(b=jQuery.map(b,a).reduce(function(a,b){return a&&(a+=";"),a+b})),b},set_value:function(a){this.el.val(a)}}),Sao.Screen=Sao.class_(Object,{init:function(a,b){this.model_name=a,this.model=new Sao.Model(a,b),this.attributes=jQuery.extend({},b),this.view_ids=jQuery.extend([],b.view_ids),this.view_to_load=jQuery.extend([],b.mode||["tree","form"]),this.views=[],this.views_preload=b.views_preload||{},this.exclude_field=b.exclude_field,this.context=b.context||{},this.new_group(),this.current_view=null,this.current_record=null,this.domain=b.domain||[],this.context_domain=b.context_domain,this.size_limit=null,void 0===this.attributes.limit?this.limit=Sao.config.limit:this.limit=b.limit,this.offset=0,this.order=this.default_order=b.order;var c=Sao.common.MODELACCESS.get(a);c.write||c.create||(this.attributes.readonly=!0),this.search_count=0,this.screen_container=new Sao.ScreenContainer(b.tab_domain),this.context_screen=null,b.context_model&&(this.context_screen=new Sao.Screen(b.context_model,{mode:["form"],context:b.context}),this.context_screen_prm=this.context_screen.switch_view().then(function(){return jQuery("<div/>",{"class":"row"}).append(jQuery("<div/>",{"class":"col-md-12"}).append(this.context_screen.screen_container.el)).prependTo(this.screen_container.filter_box),this.context_screen.new_(!1).then(function(a){return a.default_get()})}.bind(this))),b.row_activate?this.row_activate=b.row_activate:this.row_activate=this.default_row_activate,this.tree_states={},this.tree_states_done=[],this.fields_view_tree={},this._domain_parser={},this.pre_validate=!1,this.tab=null,this.count_tab_domain()},load_next_view:function(){if(!jQuery.isEmptyObject(this.view_to_load)){var a;jQuery.isEmptyObject(this.view_ids)||(a=this.view_ids.shift());var b=this.view_to_load.shift();return this.add_view_id(a,b)}return jQuery.when()},add_view_id:function(a,b){var c;if(a&&this.views_preload[String(a)])c=this.views_preload[String(a)];else{if(a||!this.views_preload[b]){var d=this.model.execute("fields_view_get",[a,b],this.context);return d.pipe(this.add_view.bind(this))}c=this.views_preload[b]}return this.add_view(c),jQuery.when()},add_view:function(a){var b=a.arch,c=a.fields,d=a.view_id,e=jQuery(jQuery.parseXML(b));"tree"==e.children().prop("tagName")&&(this.fields_view_tree[d]=a);var f="eager";"form"==e.children().prop("tagName")&&(f="lazy");for(var g in c)g in this.model.fields&&"eager"!=f?c[g].loading=this.model.fields[g].description.loading:c[g].loading=f;this.group.add_fields(c);var h=Sao.View.parse(this,e,a.field_childs);return h.view_id=d,this.views.push(h),h},number_of_views:function(){return this.views.length+this.view_to_load.length},switch_view:function(a){if(this.current_view){this.current_view.set_value(),this.current_record&&!~this.current_record.group.indexOf(this.current_record)&&(this.current_record=null);var b=this.current_view.get_fields();if(this.current_record&&this.current_view.editable&&!this.current_record.validate(b,!1,!1,!0))return this.screen_container.set(this.current_view.el),this.current_view.display().done(function(){this.set_cursor()}.bind(this))}var c=function(){if(!a||!this.current_view||this.current_view.view_type!=a)for(var b=function(){return this.current_view=this.views[this.views.length-1],c()}.bind(this),d=0;d<this.number_of_views();d++){if(this.view_to_load.length)return a||(a=this.view_to_load[0]),this.load_next_view().then(b);if(this.current_view=this.views[(this.views.indexOf(this.current_view)+1)%this.views.length],!a)break;if(this.current_view.view_type==a)break}return this.screen_container.set(this.current_view.el),this.display().done(function(){this.set_cursor()}.bind(this))}.bind(this);return c()},search_filter:function(a,b){if(b=b||!1,this.context_screen){if("pending"==this.context_screen_prm.state())return this.context_screen_prm.then(function(){return this.search_filter(a)}.bind(this));var c=this.context_screen.current_record;if(c&&!c.validate(null,!1,null,!0))return this.new_group([]),this.context_screen.display(!0),jQuery.when();this.context=jQuery.extend({},this.context,this.context_screen.get_on_change_value())}var d=this.search_domain(a,!0);if(this.context_domain){var e=new Sao.PYSON.Decoder(this.context);d=["AND",d,e.decode(this.context_domain)]}var f=this.screen_container.get_tab_domain();jQuery.isEmptyObject(f)||(d=["AND",d,f]);var g=this.model.find(d,this.offset,this.limit,this.order,this.context),h=jQuery.when(this.search_count);return b||(h=this.model.execute("search_count",[d],this.context)),h.done(function(a){this.search_count=a}.bind(this)),g.done(this.set_group.bind(this)),g.done(this.display.bind(this)),jQuery.when(g,h).done(function(a,b){this.screen_container.but_next.prop("disabled",!(void 0!==this.limit&&a.length==this.limit&&b>this.limit+this.offset))}.bind(this)),this.screen_container.but_prev.prop("disabled",this.offset<=0),this.count_tab_domain(),g},search_domain:function(a,b){b=b||!1;var c=[];if(!this.group.parent&&this.domain_parser()){var d=this.domain_parser();c=a||""===a?d.parse(a):this.attributes.search_value,b&&this.screen_container.set_text(d.string(c))}else c=[["id","in",this.group.map(function(a){return a.id})]];return jQuery.isEmptyObject(c)?c=this.attributes.domain||[]:jQuery.isEmptyObject(this.attributes.domain)||(c=["AND",c,this.attributes.domain]),this.current_view&&"calendar"==this.current_view.view_type&&(c=jQuery.isEmptyObject(c)?this.current_view.current_domain():["AND",c,this.current_view.current_domain()]),c},count_tab_domain:function(){var a=this.search_domain(this.screen_container.get_text());this.screen_container.tab_domain.forEach(function(b,c){if(b[2]){var d=["AND",b[1],a];this.screen_container.set_tab_counter(null,c),this.group.model.execute("search_count",[d],this.context).then(function(a){this.screen_container.set_tab_counter(a,c)}.bind(this))}}.bind(this))},set_group:function(a){var b={};if(this.group){for(var c in this.group.model.fields)this.group.model.fields.hasOwnProperty(c)&&(b[c]=this.group.model.fields[c].description);this.group.screens.splice(this.group.screens.indexOf(this),1),jQuery.extend(a.on_write,this.group.on_write),a.on_write=a.on_write.filter(function(a,b,c){return b==c.indexOf(a)}),this.group.parent&&!a.parent&&(a.parent=this.group.parent)}a.screens.push(this),this.tree_states_done=[],this.group=a,this.model=a.model,a&&a.length?this.set_current_record(a[0]):this.set_current_record(null),this.group.add_fields(b)},new_group:function(a){var b=new Sao.Group(this.model,this.context,[]);b.set_readonly(this.attributes.readonly||!1),a&&b.load(a),this.set_group(b)},set_current_record:function(a){this.current_record=a,this.tab&&(a?(a.get_attachment_count().always(this.tab.attachment_count.bind(this.tab)),a.get_unread_note().always(this.tab.update_unread_note.bind(this.tab))):(this.tab.attachment_count(0),this.tab.update_unread_note(0)),this.tab.record_message())},display:function(a){var b=[];if(this.current_record&&~this.current_record.group.indexOf(this.current_record)||(this.group&&this.group.length&&"calendar"!=this.current_view.view_type?this.current_record=this.group[0]:this.current_record=null),this.views){var c=this.search_active(~["tree","graph","calendar"].indexOf(this.current_view.view_type));b.push(c);for(var d=0;d<this.views.length;d++)this.views[d]&&b.push(this.views[d].display())}return jQuery.when.apply(jQuery,b).then(function(){this.set_tree_state(),this.set_current_record(this.current_record),a&&this.set_cursor(!1,!1)}.bind(this))},display_next:function(){var a=this.current_view;if(a.set_value(),this.set_cursor(!1,!1),~["tree","form"].indexOf(a.view_type)&&this.current_record&&this.current_record.group){for(var b=this.current_record.group,c=this.current_record;b;){var d=b.indexOf(c);if(d<b.length-1){c=b[d+1];break}if(!b.parent||c.group.model_name!=b.parent.group.model_name)break;c=b.parent,b=b.parent.group}this.set_current_record(c)}else this.set_current_record(this.group[0]);this.set_cursor(!1,!1),a.display()},display_previous:function(){var a=this.current_view;if(a.set_value(),this.set_cursor(!1,!1),~["tree","form"].indexOf(a.view_type)&&this.current_record&&this.current_record.group){for(var b=this.current_record.group,c=this.current_record;b;){var d=b.indexOf(c);if(d>0){c=b[d-1];break}if(!b.parent||c.group.model_name!=b.parent.group.model_name)break;c=b.parent,b=b.parent.group}this.set_current_record(c)}else this.set_current_record(this.group[0]);this.set_cursor(!1,!1),a.display()},default_row_activate:function(){"tree"==this.current_view.view_type&&1==this.current_view.attributes.keyword_open?Sao.Action.exec_keyword("tree_open",{model:this.model_name,id:this.get_id(),ids:[this.get_id()]},jQuery.extend({},this.context),!1):this.modified()||this.switch_view("form")},get_id:function(){return this.current_record?this.current_record.id:void 0},new_:function(a,b){var c=this.current_view;void 0===a&&(a=!0);var d=jQuery.when();if("calendar"==this.current_view.view_type){var e=this.current_view.date;d=this.switch_view("form")}return this.current_view&&("tree"==this.current_view.view_type&&!this.current_view.editable||"graph"==this.current_view.view_type)&&(d=this.switch_view("form")),d.then(function(){var d;d=this.current_record?this.current_record.group:this.group;var f,g=d.new_(!1,void 0,b);return f=a?g.default_get(b):jQuery.when(),f.then(function(){return d.add(g,this.new_model_position()),this.set_current_record(g),"calendar"==c.view_type&&c.set_default_date(g,e),this.display().done(function(){this.set_cursor(!0,!0)}.bind(this)),g}.bind(this))}.bind(this))},new_model_position:function(){var a=-1;return this.current_view&&"tree"==this.current_view.view_type&&"top"==this.current_view.attributes.editable&&(a=0),a},set_on_write:function(a){a&&(~this.group.on_write.indexOf(a)||this.group.on_write.push(a))},cancel_current:function(){var a=[];return this.current_record&&(this.current_record.cancel(),this.current_record.id<0&&a.push(this.remove(!1,!1,!1,[this.current_record]))),jQuery.when.apply(jQuery,a)},save_current:function(){var a=this.current_record;if(!a){if("tree"!=this.current_view.view_type||!this.group||!this.group.length)return jQuery.when();this.set_current_record(this.group[0])}this.current_view.set_value();var b=this.current_view.get_fields(),c=a.get_path(this.group),d=jQuery.Deferred();"tree"==this.current_view.view_type?d=this.group.save().then(function(){return this.current_record}.bind(this)):a.validate(b).then(function(b){b?a.save().then(function(){d.resolve(a)},d.reject):(this.current_view.display().done(this.set_cursor.bind(this)),d.reject())}.bind(this));var e=jQuery.Deferred();return d.then(function(a){return c&&a&&a.id&&c.splice(-1,1,[c[c.length-1][0],a.id]),this.group.get_by_path(c).then(function(a){this.set_current_record(a)}.bind(this))}.bind(this)).then(function(){this.display().always(e.resolve)}.bind(this),function(){this.display().always(e.reject)}.bind(this)),e.promise()},set_cursor:function(a,b){this.current_view&&~["tree","form"].indexOf(this.current_view.view_type)&&this.current_view.set_cursor(a,b)},modified:function(){var a=function(a){return a.has_changed()||a.id<0};if("tree"!=this.current_view.view_type){if(this.current_record&&a(this.current_record))return!0}else if(this.group.some(a))return!0;return!1},unremove:function(){var a=this.current_view.selected_records();a.forEach(function(a){a.group.unremove(a)})},remove:function(a,b,c,d){var e=jQuery.when();if(d=d||this.current_view.selected_records(),jQuery.isEmptyObject(d))return e;a&&(e=this.model.delete_(d));var f=d[0],g=f.group,h=g.indexOf(f),i=f.get_path(this.group);return e.then(function(){d.forEach(function(a){a.group.remove(a,b,!0,c)});var e=[];if(a&&d.forEach(function(a){a.group.parent&&e.push(a.group.parent.save(!1)),~a.group.record_deleted.indexOf(a)&&a.group.record_deleted.splice(a.group.record_deleted.indexOf(a),1),~a.group.record_removed.indexOf(a)&&a.group.record_removed.splice(a.group.record_removed.indexOf(a),1)}),h>0){var f=g[h-1];i.splice(-1,1,[i[i.length-1][0],f.id])}else i.splice(-1,1);return jQuery.isEmptyObject(i)?this.group.length&&this.set_current_record(this.group[0]):e.push(this.group.get_by_path(i).then(function(a){this.set_current_record(a)}.bind(this))),jQuery.when.apply(jQuery,e).then(function(){this.display().done(function(){this.set_cursor()}.bind(this))}.bind(this))}.bind(this))},copy:function(){var a=jQuery.Deferred(),b=this.current_view.selected_records();return this.model.copy(b,this.context).then(function(b){this.group.load(b),jQuery.isEmptyObject(b)||this.set_current_record(this.group.get(b[0])),this.display().always(a.resolve)}.bind(this),a.reject),a.promise()},search_active:function(a){return a&&!this.group.parent?(this.screen_container.set_screen(this),this.screen_container.show_filter()):this.screen_container.hide_filter(),jQuery.when()},domain_parser:function(){var a,b,c;if(a=this.current_view?this.current_view.view_id:null,a in this._domain_parser)return this._domain_parser[a];a in this.fields_view_tree?b=this.fields_view_tree[a]:(this.model.execute("fields_view_get",[!1,"tree"],this.context).then(function(b){this.fields_view_tree[a]=b,c.update_fields(b.fields)}.bind(this)),b={},b.fields={});var d=jQuery.extend({},b.fields),e=function(a){return function(b){a.selection=b}};for(var f in d){var g=d[f];"selection"!=g.type&&"reference"!=g.type||g.selection instanceof Array||this.get_selection(g).then(e(g))}if("arch"in b){var h=jQuery(jQuery.parseXML(b.arch)),i=h.find("tree").children().filter(function(a,b){return"field"==b.tagName}).map(function(a,b){return b.getAttribute("name")}),j={};i.each(function(a,b){j[b]=d[b]}),d=j}[["id",Sao.i18n.gettext("ID"),"integer"],["create_uid",Sao.i18n.gettext("Creation User"),"many2one"],["create_date",Sao.i18n.gettext("Creation Date"),"datetime"],["write_uid",Sao.i18n.gettext("Modification User"),"many2one"],["write_date",Sao.i18n.gettext("Modification Date"),"datetime"]].forEach(function(a){var b=a[0],c=a[1],e=a[2];b in d||(d[b]={string:c,name:b,type:e},"datetime"==e&&(d[b].format='"%H:%M:%S"'))});var k=jQuery.extend({},this.model.session.context,this.context);return c=new Sao.common.DomainParser(d,k),this._domain_parser[a]=c,c},get_selection:function(a){var b,c=a.selection_change_with;if(jQuery.isEmptyObject(c))b=this.model.execute(a.selection,[]);else{var d={};c.forEach(function(a){d[a]=null}),b=this.model.execute(a.selection,[d])}return b.then(function(a){return a.sort(function(a,b){return a[1].localeCompare(b[1])})})},search_prev:function(a){this.limit&&(this.offset-=this.limit),this.search_filter(a)},search_next:function(a){this.limit&&(this.offset+=this.limit),this.search_filter(a)},invalid_message:function(a){a||(a=this.current_record);var b={};for(var c in a.model.fields){var d=a.model.fields[c];b[c]=d.description}var e=new Sao.common.DomainParser(b),f=[],g=a.invalid_fields();return Object.keys(g).sort().forEach(function(b){var c=g[b],d=a.model.fields[b].description.string;"required"==c||Sao.common.compare(c,[[b,"!=",null]])?f.push(Sao.i18n.gettext('"%1" is required',d)):"domain"==c?f.push(Sao.i18n.gettext('"%1" is not valid according to its domain',d)):"children"==c?f.push(Sao.i18n.gettext('The values of "%1" are not valid',d)):e.stringable(c)?f.push(e.string(c)):f.push(Sao.i18n.gettext('"%1" is not valid according to its domain'),d)}),f.length>5&&(f.splice(5,f.length),f.push("...")),f.join("\n")},get:function(){return this.current_record?(this.current_view.set_value(),this.current_record.get()):null},get_on_change_value:function(){return this.current_record?(this.current_view.set_value(),this.current_record.get_on_change_value()):null},reload:function(a,b){this.group.reload(a),b&&this.group.written(a),this.group.parent&&this.group.parent.root_parent().reload(),this.display()},get_buttons:function(){var a=this.current_view.selected_records();if(jQuery.isEmptyObject(a))return[];var b=this.current_view.get_buttons();return a.forEach(function(a){b=b.filter(function(b){if(a.group.get_readonly()||a.readonly())return!1;if("instance"===b.attributes.type)return!1;var c=a.expr_eval(b.attributes.states||{});return!(c.invisible||c.readonly)})}),b},button:function(a){var b,c=function(a){this.reload(b,!0),"string"==typeof a?this.client_action(a):a&&Sao.Action.execute(a,{model:this.model_name,id:this.current_record.id,ids:b},null,this.context,!0)},d=this.current_view.selected_records();this.current_view.set_value();for(var e=this.current_view.get_fields(),f=[],g=function(a){return function(){this.display(!0),a.validate(e)}.bind(this)}.bind(this),h=0;h<d.length;h++){var i=d[h],j=i.expr_eval(a.states||{}).pre_validate||[];f.push(i.validate(e,!1,j))}jQuery.when.apply(jQuery,f).then(function(){for(var e,f=0;f<d.length;f++){e=d[f];var h=arguments[f];if(!h)return void Sao.common.warning.run(this.invalid_message(e),Sao.i18n.gettext("Pre-validation")).then(g(e))}var i=jQuery.when();void 0!==a.confirm&&(i=Sao.common.sur.run(a.confirm)),i.then(function(){var e=this.current_record;if("instance"===a.type){var g=e.expr_eval(a.change||[]),h=e._get_on_change_args(g);e.model.execute(a.name,[h],this.context).then(function(a){e.set_on_change(a),e.group.root_group().screens.forEach(function(a){a.display()})})}else e.save(!1).done(function(){var g=jQuery.extend({},this.context);for(g._timestamp={},b=[],f=0;f<d.length;f++)e=d[f],jQuery.extend(g._timestamp,e.get_timestamp()),b.push(e.id);e.model.execute(a.name,[b],g).then(c.bind(this))}.bind(this))}.bind(this))}.bind(this))},client_action:function(a){var b=Sao.common.MODELACCESS.get(this.model_name);if("new"==a)b.create&&this.new_();else if("delete"==a)b["delete"]&&this.remove(!this.group.parent,!1,!this.group.parent);else if("remove"==a)b.write&&b.read&&this.group.parent&&this.remove(!1,!0,!1);else if("copy"==a)b.create&&this.copy();else if("next"==a)this.display_next();else if("previous"==a)this.display_previous();else if("close"==a)Sao.Tab.close_current();else if(a.startsWith("switch")){var c=a.split(" ")[1];this.switch_view(c)}else"reload"==a?~["tree","graph","calendar"].indexOf(this.current_view.view_type)&&!this.group.parent&&this.search_filter():"reload menu"==a?Sao.get_preferences().then(function(a){Sao.menu(a)}):"reload context"==a&&Sao.get_preferences()},save_tree_state:function(a){var b,c=[];a=void 0===a?!0:a;var d,e,f,g,h,i,j=this.group.parent?this.group.parent.id:null,k=this.group.parent?this.group.parent._timestamp:null;for(d=0,e=this.views.length;e>d;d++)if(f=this.views[d],"form"==f.view_type){for(var l in f.widgets)if(f.widgets.hasOwnProperty(l))for(g=f.widgets[l],h=0,i=g.length;i>h;h++)g[h].screen&&(b=g[h].screen.save_tree_state(a),c.push(b));1==this.views.length&&this.current_record&&(j in this.tree_states||(this.tree_states[j]={}),this.tree_states[j][f.children_field||null]=[k,[],[[this.current_record.id]]])}else if("tree"==f.view_type){var m=f.get_expanded_paths(),n=f.get_selected_paths();if(j in this.tree_states||(this.tree_states[j]={}),this.tree_states[j][f.children_field||null]=[k,m,n],a&&f.attributes.tree_state){var o=new Sao.Model("ir.ui.view_tree_state");b=o.execute("set",[this.model_name,this.get_tree_domain(j),f.children_field,JSON.stringify(m),JSON.stringify(n)],{}),c.push(b)}}return jQuery.when.apply(jQuery,c)},get_tree_domain:function(a){var b;return b=a?(this.domain||[]).concat([[this.exclude_field,"=",a]]):this.domain,JSON.stringify(Sao.rpc.prepareObject(b))},set_tree_state:function(){var a,b,c,d,e,f=this.current_view;~["tree","form"].indexOf(f.view_type)&&(~this.tree_states_done.indexOf(f)||("form"!=f.view_type||jQuery.isEmptyObject(this.tree_states_done))&&("tree"!=f.view_type||f.attributes.tree_state)&&(a=this.group.parent?this.group.parent.id:null,0>a||(b=parent?parent._timestamp:null,a in this.tree_states||(this.tree_states[a]={}),c=this.tree_states[a][f.children_field||null],c&&b!=c[0]&&(c=void 0),void 0===c?(e=new Sao.Model("ir.ui.view_tree_state"),d=e.execute("get",[this.model_name,this.get_tree_domain(a),f.children_field],{}).then(function(a){return[b,JSON.parse(a[0]),JSON.parse(a[1])]})):d=jQuery.when(c),d.done(function(b){var c,d,e;if(this.tree_states[a][f.children_field||null]=b,c=b[1],d=b[2],"tree"==f.view_type)f.display(d,c);else if(!jQuery.isEmptyObject(d)){for(var g=0;g<d[0].length;g++){var h=this.group.get(d[0][g]);if(!h)break;e=h}e&&e!=this.current_record&&(this.set_current_record(e),f.display())}}.bind(this)),this.tree_states_done.push(f))))}})}(),function(){"use strict";Sao.View=Sao.class_(Object,{init:function(a,b){this.screen=a,this.view_type=null,this.el=null,this.view_id=null,this.fields={};var c=b.children()[0].attributes;this.attributes={};for(var d=0,e=c.length;e>d;d++){var f=c[d];this.attributes[f.name]=f.value}a.set_on_write(this.attributes.on_write)},set_value:function(){},get_fields:function(){return Object.keys(this.fields)},selected_records:function(){return[]},get_buttons:function(){return[]}}),Sao.View.idpath2path=function(a,b){var c,d=[];if(!b)return[];for(var e=0,f=a.rows.length;f>e;e++)if(a.rows[e].record.id==b[0]){d.push(e),c=Sao.View.idpath2path(a.rows[e],b.slice(1,b.length)),d=d.concat(c);break}return d},Sao.View.parse=function(a,b,c){switch(b.children().prop("tagName")){case"tree":return new Sao.View.Tree(a,b,c);case"form":return new Sao.View.Form(a,b);case"graph":return new Sao.View.Graph(a,b);case"calendar":return new Sao.View.Calendar(a,b)}},Sao.View.resize=function(a){a||(a=jQuery(document)),a.find(".treeview").each(function(){var a=jQuery(this);a.css("width","100%"),a.children(".tree").css("table-layout","fixed")}),a.find(".treeview").each(function(){var a=jQuery(this);a.width()&&(a.css("width",a.width()),a.children(".tree").css("table-layout","auto"))})},jQuery(window).resize(function(){Sao.View.resize()})}(),function(){"use strict";Sao.View.Form=Sao.class_(Sao.View,{editable:!0,init:function(a,b){Sao.View.Form._super.init.call(this,a,b),this.view_type="form",this.el=jQuery("<div/>",{"class":"form"}),this.widgets={},this.widget_id=0,this.state_widgets=[],this.containers=[],this.notebooks=[];var c=b.children()[0],d=this.parse(a.model,c);this.el.append(d.el)},_parse_node:function(a,b,c,d,e){var f;switch(b.tagName){case"image":this._parse_image(a,b,c,d);break;case"separator":this._parse_separator(a,b,c,d);break;case"label":f=this._parse_label(a,b,c,d),d.name&&f&&(e[d.name]=f);break;case"newline":c.add_row();break;case"button":this._parse_button(b,c,d);break;case"notebook":this._parse_notebook(a,b,c,d);break;case"page":this._parse_page(a,b,c,d);break;case"field":if(f=this._parse_field(a,b,c,d),d.name in e&&f&&f.labelled){var g=e[d.name];g.el.uniqueId(),f.labelled.uniqueId(),f.labelled.attr("aria-labelledby",g.el.attr("id")),g.el.attr("for",f.labelled.attr("id"))}break;case"group":this._parse_group(a,b,c,d);break;case"hpaned":this._parse_paned(a,b,c,d,"horizontal");break;case"vpaned":this._parse_paned(a,b,c,d,"vertical");break;case"child":this._parse_child(a,b,c,d)}},parse:function(a,b,c){void 0===c&&(c=new Sao.View.Form.Container(Number(b.getAttribute("col")||4)),this.containers.push(c));var d={},e=function(b,e){for(var f={},g=0,h=e.attributes.length;h>g;g++){var i=e.attributes[g];f[i.name]=i.value}["readonly","invisible"].forEach(function(a){f[a]&&(f[a]=1==f[a])}),["yexpand","yfill","xexpand","xfill","colspan"].forEach(function(a){f[a]&&(f[a]=Number(f[a]))}),this._parse_node(a,e,c,f,d)};return jQuery(b).children().each(e.bind(this)),c},_parse_image:function(a,b,c,d){var e=new Sao.View.Form.Image_(d);this.state_widgets.push(e),c.add(d,e)},_parse_separator:function(a,b,c,d){var e=d.name,f=d.string;e in a.fields&&(!d.states&&e in a.fields&&(d.states=a.fields[e].description.states),f||(f=a.fields[e].description.string));var g=new Sao.View.Form.Separator(f,d);this.state_widgets.push(g),c.add(d,g)},_parse_label:function(a,b,c,d){var e=d.name,f=d.string;if(void 0===d.xexpand&&(d.xexpand=0),e in a.fields){if(e==this.screen.exclude_field)return void c.add(d);!d.states&&e in a.fields&&(d.states=a.fields[e].description.states),f||(f=a.fields[e].description.string+": "),void 0===d.xalign&&(d.xalign=1)}var g;return f&&(g=new Sao.View.Form.Label(f,d),this.state_widgets.push(g)),c.add(d,g),g},_parse_button:function(a,b,c){var d=new Sao.common.Button(c);this.state_widgets.push(d),b.add(c,d),d.el.click(d,this.button_clicked.bind(this))},_parse_notebook:function(a,b,c,d){void 0===d.colspan&&(d.colspan=4);var e=new Sao.View.Form.Notebook(d);this.notebooks.push(e),this.state_widgets.push(e),c.add(d,e),this.parse(a,b,e)},_parse_page:function(a,b,c,d){d.string;if(d.name in a.fields){var e=a.fields[d.name];if(d.name==this.screen.exclude_field)return;["states","string"].forEach(function(a){void 0===d[a]&&void 0!==e.description[a]&&(d[a]=e.description[a])})}var f=this.parse(a,b);f=new Sao.View.Form.Page(c.add(f.el,d.string),d),this.state_widgets.push(f)},_parse_field:function(a,b,c,d){var e=d.name;if(!(e in a.fields)||e==this.screen.exclude_field)return void c.add(d);d.widget||(d.widget=a.fields[e].description.type);var f=["relation","domain","selection","help","relation_field","string","views","add_remove","sort","context","size","filename","autocomplete","translate","create","delete","selection_change_with","schema_model"];for(var g in f){var h=f[g];h in a.fields[e].description&&null===b.getAttribute(h)&&(d[h]=a.fields[e].description[h])}var i=Sao.View.form_widget_get(d.widget);if(!i)return void c.add(d);var j=new i(e,a,d);return j.position=this.widget_id+=1,j.view=this,c.add(d,j),void 0===this.widgets[e]&&(this.widgets[e]=[]),this.widgets[e].push(j),this.fields[e]=!0,j},_parse_group:function(a,b,c,d){var e=new Sao.View.Form.Group(d);e.add(this.parse(a,b)),this.state_widgets.push(e),c.add(d,e)},_parse_paned:function(a,b,c,d,e){void 0===d.yexpand&&(d.yexpand=!0),void 0===d.yfill&&(d.yfill=!0);var f=new Sao.common.Paned(e);c.add(d,f),this.parse(a,b,f)},_parse_child:function(a,b,c,d){var e,f=this.parse(a,b);e=c.get_child1().children().length?c.get_child2():c.get_child1(),e.append(f.el)},get_buttons:function(){var a=[];for(var b in this.state_widgets){var c=this.state_widgets[b];c instanceof Sao.common.Button&&a.push(c)}return a},display:function(){var a,b,c=this.screen.current_record,d={};if(c){var e=[];for(b in c.model.fields)a=c.model.fields[b],
-e.push([b,a.description.loading||"eager"]);e.sort(function(a,b){return a[1].localeCompare(b[1])}),e.forEach(function(a){var b=a[0];d[b]=c.load(b)})}var f=function(a,b,c){var e=jQuery.when();c in d&&(e=d[c]),e.done(function(){b.set_state(a)})},g=function(a,b,c){return function(e){var f=jQuery.when();c in d&&(f=d[c]),f.done(function(){e.display(a,b)})}};for(b in this.widgets){var h=this.widgets[b];a=null,c&&(a=c.model.fields[b]),a&&f(c,a,b),h.forEach(g(c,a,b))}return jQuery.when.apply(jQuery,jQuery.map(d,function(a){return a})).done(function(){var a;for(a in this.state_widgets){var b=this.state_widgets[a];b.set_state(c)}for(a in this.containers){var d=this.containers[a];d.resize()}Sao.View.resize(this.el)}.bind(this))},set_value:function(){var a=this.screen.current_record;if(a){var b=function(b){b.set_value(a,this)};for(var c in this.widgets)if(c in a.model.fields){var d=this.widgets[c],e=a.model.fields[c];d.forEach(b,e)}}},button_clicked:function(a){var b=a.data;b.el.prop("disabled",!0);try{this.screen.button(b.attributes)}finally{b.el.prop("disabled",!1)}},selected_records:function(){return this.screen.current_record?[this.screen.current_record]:[]},set_cursor:function(a,b){var c,d,e,f,g,h,i,j,k,l,m=jQuery(document.activeElement),n=m.closest(this.el)>0;if(b||n){if(b)for(c=0;c<this.notebooks.length;c++)g=this.notebooks[c],g.set_current_page(0);this.attributes.cursor in this.widgets?f=Sao.common.find_focusable_child(this.widgets[this.attributes.cursor][0].el):(h=Sao.common.find_focusable_child(this.el),h&&h.focus())}var o=this.screen.current_record;if(o){var p=[],q=this.el.find(".has-error"),r=o.invalid_fields();for(d in r)for(i=this.widgets[d],c=0;c<q.length;c++)for(j=jQuery(q[c]),e=0;e<i.length;e++)if(j.closest(i[e].el).length>0){p.push(j);break}p.length>0&&(f=Sao.common.find_first_focus_widget(this.el,p))}if(f){for(c=0;c<this.notebooks.length;c++)for(g=this.notebooks[c],k=g.get_n_pages(),e=0;k>e;e++)if(h=g.get_nth_page(e),l=jQuery(f).closest(h).length>0){g.set_current_page(e);break}jQuery(f).find("input,select,textarea").focus()}}}),Sao.View.Form.Container=Sao.class_(Object,{init:function(a){void 0===a&&(a=4),0>a&&(a=0),this.col=a,this.el=jQuery("<table/>",{"class":"form-container responsive responsive-noheader"}),this.add_row()},add_row:function(){this.el.append(jQuery("<tr/>"))},rows:function(){return this.el.children().children("tr")},row:function(){return this.rows().last()},add:function(a,b){var c=a.colspan;void 0===c&&(c=1);var d=a.xfill;void 0===d&&(d=1);var e=a.xexpand;void 0===e&&(e=1);var f=this.row();if(this.col>0){var g=0;f.children().map(function(a,b){g+=Number(jQuery(b).attr("colspan")||1)}),g+c>this.col&&(this.add_row(),f=this.row())}var h;b&&(h=b.el);var i=jQuery("<td/>",{colspan:c,"class":b?b.class_||"":""}).append(h);f.append(i),b&&(a.yfill&&i.css("vertical-align","top"),void 0!==a.xalign&&i.css("text-align",a.xalign>=.5?"right":"left"),e&&(i.addClass("xexpand"),i.css("width","100%")),d&&(i.addClass("xfill"),e&&h.css("width","100%")),a.help&&(b.el.data("toggle","tooltip"),b.el.attr("title",a.help),b.el.tooltip()))},resize:function(){var a,b,c=this.rows().toArray(),d=[],e=this.col,f=!1,g=function(b){b=jQuery(b);var c=[];return a=0,b.children().map(function(){var b=jQuery(this),d=Math.min(Number(b.attr("colspan")),e);b.hasClass("xexpand")&&!jQuery.isEmptyObject(b.children())&&"none"!=b.children(":not(.tooltip)").css("display")&&c.push([b,a]),a+=d}),c};c.sort(function(a,b){if(a=g(a),b=g(b),a.length==b.length){var c=function(a,b){var c=b[0],d=Math.min(Number(c.attr("colspan")),e);return a+d};return a.reduce(c,0)-b.reduce(c,0)}return b.length-a.length}),c.forEach(function(c){c=jQuery(c);var h=g(c),i=100/h.length;h.forEach(function(c){var f=c[0];a=c[1];var g=Math.min(Number(f.attr("colspan")),e),h=0;for(b=0;g>b;b++)h+=d[a+b]||0;for(b=0;g>b;b++)if(h){if(h>i){var j=h-i;d[a+b]&&(d[a+b]-=j/(h/d[a+b]))}}else d[a+b]=i/g}),jQuery.isEmptyObject(h)||(f=!0)}),c.forEach(function(c){c=jQuery(c),a=0,c.children().map(function(){var c=jQuery(this),f=Math.min(Number(c.attr("colspan")),e);if(c.hasClass("xexpand")&&"none"!=c.children(":not(.tooltip)").css("display")){var g=0;for(b=0;f>b;b++)g+=d[a+b]||0;c.css("width",g+"%")}else c.css("width","");"none"==c.children().css("display")?c.css("visibility","collapse"):c.css("visibility","visible"),a+=f})}),f?this.el.css("width","100%"):this.el.css("width","")}}),Sao.View.Form.StateWidget=Sao.class_(Object,{init:function(a){this.attributes=a},set_state:function(a){var b;b=a?a.expr_eval(this.attributes.states||{}):{};var c=b.invisible;void 0===c&&(c=this.attributes.invisible),c?this.hide():this.show()},show:function(){this.el.show()},hide:function(){this.el.hide()}}),Sao.View.Form.LabelMixin=Sao.class_(Sao.View.Form.StateWidget,{set_state:function(a){Sao.View.Form.LabelMixin._super.set_state.call(this,a);var b;if(this.attributes.name&&a&&(b=a.model.fields[this.attributes.name]),void 0===this.attributes.string&&b){var c="";a&&(c=b.get_client(a)||""),this.label_el.val(c)}var d;d=a?a.expr_eval(this.attributes.states||{}):{},b&&b.description.readonly||d.readonly,Sao.common.apply_label_attributes(this.label_el,b&&b.description.readonly||d.readonly,b&&b.description.required||d.required)}}),Sao.View.Form.Separator=Sao.class_(Sao.View.Form.LabelMixin,{init:function(a,b){Sao.View.Form.Separator._super.init.call(this,b),this.el=jQuery("<div/>",{"class":"form-separator"}),this.label_el=jQuery("<label/>"),a&&this.label_el.text(a),this.el.append(this.label_el),this.el.append(jQuery("<hr/>"))}}),Sao.View.Form.Label=Sao.class_(Sao.View.Form.LabelMixin,{class_:"form-label",init:function(a,b){Sao.View.Form.Label._super.init.call(this,b),this.el=this.label_el=jQuery("<label/>",{text:a,"class":this.class_})}}),Sao.View.Form.Notebook=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-notebook",init:function(a){Sao.View.Form.Notebook._super.init.call(this,a),this.el=jQuery("<div/>",{"class":this.class_}),this.nav=jQuery("<ul/>",{"class":"nav nav-tabs",role:"tablist"}).appendTo(this.el),this.panes=jQuery("<div/>",{"class":"tab-content"}).appendTo(this.el),this.selected=!1},add:function(a,b){var c=jQuery("<div/>",{role:"tabpanel","class":"tab-pane"}).uniqueId(),d=c.attr("id"),e=jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{"aria-controls":d,role:"tab","data-toggle":"tab",href:"#"+d}).append(b).on("shown.bs.tab",function(){Sao.View.resize(a)})).appendTo(this.nav);return c.html(a).appendTo(this.panes),this.selected||(e.addClass("active"),c.addClass("active"),this.selected=!0),e},set_current_page:function(a){var b=this.nav.find('li[role="presentation"]:eq('+a+") a");b.tab("show")},get_n_pages:function(){return this.nav.find("li[role='presentation']").length},get_nth_page:function(a){return jQuery(this.panes.find("div[role='tabpanel']")[a])}}),Sao.View.Form.Page=Sao.class_(Sao.View.Form.StateWidget,{init:function(a,b){Sao.View.Form.Page._super.init.call(this,b),this.el=a}}),Sao.View.Form.Group=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-group_",init:function(a){Sao.View.Form.Group._super.init.call(this,a),this.el=jQuery("<div/>",{"class":this.class_})},add:function(a){this.el.append(a.el)}}),Sao.View.Form.Image_=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-image_",init:function(a){Sao.View.Form.Image_._super.init.call(this,a),this.el=jQuery("<div/>",{class_:this.class_}),this.img=jQuery("<img/>",{"class":"center-block"}).appendTo(this.el),Sao.common.ICONFACTORY.register_icon(a.name).done(function(a){this.img.attr("src",a)}.bind(this))}}),Sao.View.form_widget_get=function(a){switch(a){case"char":return Sao.View.Form.Char;case"password":return Sao.View.Form.Password;case"date":return Sao.View.Form.Date;case"datetime":return Sao.View.Form.DateTime;case"time":return Sao.View.Form.Time;case"timedelta":return Sao.View.Form.TimeDelta;case"integer":case"biginteger":return Sao.View.Form.Integer;case"float":case"numeric":return Sao.View.Form.Float;case"selection":return Sao.View.Form.Selection;case"boolean":return Sao.View.Form.Boolean;case"text":return Sao.View.Form.Text;case"richtext":return Sao.View.Form.RichText;case"many2one":return Sao.View.Form.Many2One;case"one2one":return Sao.View.Form.One2One;case"reference":return Sao.View.Form.Reference;case"one2many":return Sao.View.Form.One2Many;case"many2many":return Sao.View.Form.Many2Many;case"binary":return Sao.View.Form.Binary;case"multiselection":return Sao.View.Form.MultiSelection;case"image":return Sao.View.Form.Image;case"url":return Sao.View.Form.URL;case"email":return Sao.View.Form.Email;case"callto":return Sao.View.Form.CallTo;case"sip":return Sao.View.Form.SIP;case"progressbar":return Sao.View.Form.ProgressBar;case"dict":return Sao.View.Form.Dict;case"pyson":return Sao.View.Form.PYSON}},Sao.View.Form.Widget=Sao.class_(Object,{init:function(a,b,c){this.field_name=a,this.model=b,this.view=null,this.attributes=c,this.el=null,this.position=0,this.visible=!0,this.labelled=null},display:function(a,b){var c=this.attributes.readonly,d=this.attributes.invisible,e=this.attributes.required;if(!b)return void 0===c&&(c=!0),void 0===d&&(d=!1),void 0===e&&(e=!1),this.set_readonly(c),this.set_invisible(d),void this.set_required(e);var f=b.get_state_attrs(a);void 0===c&&(c=f.readonly,void 0===c&&(c=!1)),void 0===e&&(e=f.required,void 0===e&&(e=!1)),this.view.screen.attributes.readonly&&(c=!0),this.set_readonly(c),this.set_required(e);var g=f.invalid;!c&&g?this.el.addClass("has-error"):this.el.removeClass("has-error"),void 0===d&&(d=b.get_state_attrs(a).invisible,void 0===d&&(d=!1)),this.set_invisible(d)},record:function(){return this.view&&this.view.screen?this.view.screen.current_record:void 0},field:function(){var a=this.record();return a?a.model.fields[this.field_name]:void 0},focus_out:function(){this.field()&&this.visible&&this.set_value(this.record(),this.field())},set_value:function(a,b){},set_readonly:function(a){this._readonly=a,this.el.prop("disabled",a)},set_required:function(a){},set_invisible:function(a){this.visible=!a,a?this.el.hide():this.el.show()}}),Sao.View.Form.TranslateDialog=Sao.class_(Object,{init:function(a,b){var c=new Sao.Dialog(Sao.i18n.gettext("Translate"),this.class_,this,a);c.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),this.languages=a,this.read(b,c),jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c)}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(this.write.bind(this,b,c)).appendTo(c.footer),c.content.submit(function(a){a.preventDefault(),c.footer.find("button.btn-primary").first().click()}),c.modal.modal("show"),c.modal.on("shown.bs.modal",function(){c.modal.find("input,select").filter(":visible").first().focus()})},close:function(a){a.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),a.modal.modal("hide")},read:function(a,b){this.languages.forEach(function(c){var d={};d.language=c.code;var e,f=[[a.record().id],[a.field_name],d],g={method:"model."+a.model.name+".read",params:f},h=jQuery("<div/>",{"class":"row form-group"}),i=a.translate_widget();i.attr("data-lang-id",c.id);var j=jQuery("<input/>",{type:"checkbox",title:Sao.i18n.gettext("Edit")});a._readonly&&j.attr("disabled",!0);var k=jQuery("<input/>",{type:"checkbox",disabled:!0,title:Sao.i18n.gettext("Fuzzy")}),l=Sao.rpc(g,a.model.session).then(function(b){e=b[0][a.field_name]}.bind(this));f=[[a.record().id],[a.field_name],d],d.fuzzy_translation=!0,g={method:"model."+a.model.name+".read",params:f},l.then(function(){Sao.rpc(g,a.model.session).then(function(b){e=b[0][a.field_name],a.translate_widget_set(i,e),k.attr("checked",b[0].name!=e)}.bind(this))}.bind(this)),j.click(function(){a.translate_widget_set_readonly(i)}),b.body.append(h),h.append(jQuery("<div/>",{"class":"col-sm-3"}).append(c.name)),h.append(jQuery("<div/>",{"class":"col-sm-6"}).append(i)),h.append(jQuery("<div/>",{"class":"col-sm-1"}).append(j)),h.append(jQuery("<div/>",{"class":"col-sm-1"}).append(k))}.bind(this))},write:function(a,b){var c=[];this.languages.forEach(function(b){var d=jQuery("[data-lang-id="+b.id+"]");if(!d.attr("readonly")){var e=a.model.session.context.language,f={};f.language=b.code,f.fuzzy_translation=!1;var g={};g[a.field_name]=d.val();var h=[[a.record().id],g,f],i={method:"model."+a.model.name+".write",params:h},j=Sao.rpc(i,a.model.session).then(function(){b.code==e&&a.view.display()});c.push(j)}}.bind(this)),this.close(b),jQuery.when.apply(jQuery,c).then(function(){a.record().cancel()})}}),Sao.View.Form.TranslateMixin={},Sao.View.Form.TranslateMixin.init=function(){this.translate=Sao.View.Form.TranslateMixin.translate.bind(this),this.translate_widget_set_readonly=Sao.View.Form.TranslateMixin.translate_widget_set_readonly.bind(this),this.translate_widget_set=Sao.View.Form.TranslateMixin.translate_widget_set.bind(this)},Sao.View.Form.TranslateMixin.translate=function(){if(this.record().id<0||this.record().has_changed()){var a=Sao.i18n.gettext("You need to save the record before adding translations.");return void Sao.common.message.run(a)}var b=this.model.session,c=[[["translatable","=","true"]]],d={method:"model.ir.lang.search",params:c.concat({})};Sao.rpc(d,b).then(function(a){if(jQuery.isEmptyObject(a))return void Sao.common.message.run(Sao.i18n.gettext("No other language available."));var c=[a,["code","name"]],d={method:"model.ir.lang.read",params:c.concat({})};Sao.rpc(d,b).then(function(a){new Sao.View.Form.TranslateDialog(a,this)}.bind(this))}.bind(this))},Sao.View.Form.TranslateMixin.translate_widget_set_readonly=function(a,b){a.attr("readonly")?a.removeAttr("readonly"):a.attr("readonly",!0)},Sao.View.Form.TranslateMixin.translate_widget_set=function(a,b){a.val(b||"")},Sao.View.Form.Char=Sao.class_(Sao.View.Form.Widget,{class_:"form-char",init:function(a,b,c){if(Sao.View.Form.Char._super.init.call(this,a,b,c),Sao.View.Form.TranslateMixin.init.call(this),this.el=jQuery("<div/>",{"class":this.class_}),this.group=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el),this.input=this.labelled=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(this.group),jQuery.isEmptyObject(c.autocomplete)||(this.datalist=jQuery("<datalist/>").appendTo(this.el),this.datalist.uniqueId(),this.input.attr("list",this.datalist.attr("id"))),this.el.change(this.focus_out.bind(this)),c.size||this.group.css("width","100%"),this.attributes.translate){var d=jQuery("<button/>",{"class":"btn btn-default btn-sm form-control",type:"button","aria-label":Sao.i18n.gettext("Translate")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-flag"})).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.group));d.click(this.translate.bind(this))}},get_client_value:function(a,b){var c="";return b&&(c=b.get_client(a)),c},display:function(a,b){if(Sao.View.Form.Char._super.display.call(this,a,b),this.datalist){this.datalist.children().remove();var c=function(){var b=[];a&&(b=a.autocompletion[this.field_name]||[]),b.forEach(function(a){jQuery("<option/>",{value:a}).appendTo(this.datalist)}.bind(this))}.bind(this);!a||this.field_name in a.autocompletion?c():a.do_autocomplete(this.field_name).done(c)}var d="",e="100%";a&&(d=a.expr_eval(this.attributes.size),d>0&&(e=null)),this.input.val(this.get_client_value(a,b)),this.input.attr("maxlength",d),this.input.attr("size",d),this.group.css("width",e)},set_value:function(a,b){b.set_client(a,this.input.val())},set_readonly:function(a){this.input.prop("readonly",a)},focus:function(){this.input.focus()},translate_widget:function(){return jQuery("<input/>",{"class":"form-control",readonly:"readonly"})}}),Sao.View.Form.Password=Sao.class_(Sao.View.Form.Char,{class_:"form-password",init:function(a,b,c){Sao.View.Form.Password._super.init.call(this,a,b,c),this.input.prop("type","password"),this.button=jQuery("<button/>",{"class":"btn btn-default btn-sm form-control",type:"button"}).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.group)),this._set_password_label(),this.button.click(this.toggle_visibility.bind(this))},toggle_visibility:function(){"password"==this.input.prop("type")?(this.input.prop("type","text"),this.input.attr("autocomplete","off")):(this.input.prop("type","password"),this.input.removeAttr("autocomplete")),this._set_password_label()},_set_password_label:function(){"password"==this.input.prop("type")?this.button.text(Sao.i18n.gettext("Show")):this.button.text(Sao.i18n.gettext("Hide"))}}),Sao.View.Form.Date=Sao.class_(Sao.View.Form.Widget,{class_:"form-date",_width:"12em",init:function(a,b,c){Sao.View.Form.Date._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.date=this.labelled=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el),this.input=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(this.date),jQuery("<span/>",{"class":"input-group-btn"}).append(jQuery("<button/>",{"class":"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-calendar"}))).appendTo(this.date),this.date.datetimepicker({locale:moment.locale()}),this.date.css("width",this._width),this.date.on("dp.change",this.focus_out.bind(this))},get_format:function(a,b){return b.date_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isDate=!0),c},display:function(a,b){a&&b&&this.date.data("DateTimePicker").format(Sao.common.moment_format(this.get_format(a,b))),Sao.View.Form.Date._super.display.call(this,a,b);var c;c=a?b.get_client(a):null,this.date.data("DateTimePicker").date(c)},focus:function(){this.input.focus()},set_value:function(a,b){b.set_client(a,this.get_value(a,b))},set_readonly:function(a){this.date.find("button").prop("disabled",a),this.date.find("input").prop("readonly",a)}}),Sao.View.Form.DateTime=Sao.class_(Sao.View.Form.Date,{class_:"form-datetime",_width:"25em",get_format:function(a,b){return b.date_format(a)+" "+b.time_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isDateTime=!0),c}}),Sao.View.Form.Time=Sao.class_(Sao.View.Form.Date,{class_:"form-time",_width:"10em",get_format:function(a,b){return b.time_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isTime=!0),c}}),Sao.View.Form.TimeDelta=Sao.class_(Sao.View.Form.Widget,{class_:"form-timedelta",init:function(a,b,c){Sao.View.Form.TimeDelta._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.input=this.labelled=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(this.el),this.el.change(this.focus_out.bind(this))},display:function(a,b){if(Sao.View.Form.TimeDelta._super.display.call(this,a,b),a){var c=a.field_get_client(this.field_name);this.input.val(c||"")}else this.input.val("")},focus:function(){this.input.focus()},set_value:function(a,b){b.set_client(a,this.input.val())},set_readonly:function(a){this.input.prop("readonly",a)}}),Sao.View.Form.Integer=Sao.class_(Sao.View.Form.Char,{class_:"form-integer",init:function(a,b,c){Sao.View.Form.Integer._super.init.call(this,a,b,c),this.input.attr("type","text"),this.input.attr("width",8),this.group.css("width",""),this.factor=Number(c.factor||1)},set_value:function(a,b){b.set_client(a,this.input.val(),void 0,this.factor)},get_client_value:function(a,b){var c="";return b&&(c=b.get_client(a,this.factor)),c}}),Sao.View.Form.Float=Sao.class_(Sao.View.Form.Integer,{class_:"form-float"}),Sao.View.Form.Selection=Sao.class_(Sao.View.Form.Widget,{class_:"form-selection",init:function(a,b,c){Sao.View.Form.Selection._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.select=this.labelled=jQuery("<select/>",{"class":"form-control input-sm"}),this.el.append(this.select),this.select.change(this.focus_out.bind(this)),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a,this.set_selection.bind(this))},update_selection:function(a,b,c){Sao.common.selection_mixin.update_selection.call(this,a,b,function(a){this.set_selection(a),c&&c()}.bind(this))},set_selection:function(a){var b=this.select;b.empty(),a.forEach(function(a){b.append(jQuery("<option/>",{value:JSON.stringify(a[0]),text:a[1]}))})},display_update_selection:function(a,b){this.update_selection(a,b,function(){if(!b)return void this.select.val("");for(var c,d=b.get(a),e=!1,f=0,g=this.selection.length;g>f;f++)if(this.selection[f][0]===d){e=!0;break}e?c=jQuery.when():(c=Sao.common.selection_mixin.get_inactive_selection.call(this,d),c.done(function(a){this.select.append(jQuery("<option/>",{value:JSON.stringify(a[0]),text:a[1],disabled:!0}))}.bind(this))),c.done(function(){this.select.val(JSON.stringify(d))}.bind(this))}.bind(this))},display:function(a,b){Sao.View.Form.Selection._super.display.call(this,a,b),this.display_update_selection(a,b)},focus:function(){this.select.focus()},value_get:function(){return JSON.parse(this.select.val())},set_value:function(a,b){var c=this.value_get();b.set_client(a,c)},set_readonly:function(a){this.select.prop("disabled",a)}}),Sao.View.Form.Boolean=Sao.class_(Sao.View.Form.Widget,{class_:"form-boolean",init:function(a,b,c){Sao.View.Form.Boolean._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.input=this.labelled=jQuery("<input/>",{type:"checkbox","class":"form-control input-sm"}).appendTo(this.el),this.input.change(this.focus_out.bind(this)),this.input.click(function(){return!jQuery(this).prop("readonly")})},display:function(a,b){Sao.View.Form.Boolean._super.display.call(this,a,b),a?this.input.prop("checked",a.field_get(this.field_name)):this.input.prop("checked",!1)},focus:function(){this.input.focus()},set_value:function(a,b){var c=this.input.prop("checked");b.set_client(a,c)},set_readonly:function(a){this.input.prop("readonly",a)}}),Sao.View.Form.Text=Sao.class_(Sao.View.Form.Widget,{class_:"form-text",init:function(a,b,c){if(Sao.View.Form.Text._super.init.call(this,a,b,c),Sao.View.Form.TranslateMixin.init.call(this),this.el=jQuery("<div/>",{"class":this.class_}),this.input=this.labelled=jQuery("<textarea/>",{"class":"form-control input-sm"}).appendTo(this.el),this.input.change(this.focus_out.bind(this)),this.attributes.translate){var d=jQuery("<button/>",{"class":"btn btn-default btn-sm form-control",type:"button","aria-label":Sao.i18n.gettext("Translate")}).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.el));d.append(jQuery("<span/>",{"class":"glyphicon glyphicon-flag"})),d.click(this.translate.bind(this))}},display:function(a,b){if(Sao.View.Form.Text._super.display.call(this,a,b),a){var c=a.field_get_client(this.field_name);this.input.val(c)}else this.input.val("")},focus:function(){this.input.focus()},set_value:function(a,b){var c=this.input.val()||"";b.set_client(a,c)},set_readonly:function(a){this.input.prop("readonly",a)},translate_widget:function(){return jQuery("<textarea/>",{"class":"form-control",readonly:"readonly"})}}),Sao.View.Form.RichText=Sao.class_(Sao.View.Form.Widget,{class_:"form-richtext",init:function(a,b,c){Sao.View.Form.RichText._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_+" panel panel-default"}),parseInt(c.toolbar||"1",10)&&this.get_toolbar().appendTo(this.el),this.input=this.labelled=jQuery("<div/>",{"class":"richtext",contenteditable:!0}).appendTo(jQuery("<div/>",{"class":"panel-body"}).appendTo(this.el)),this.el.focusout(this.focus_out.bind(this))},get_toolbar:function(){var a,b,c,d=jQuery("<div/>",{"class":"btn-toolbar",role:"toolbar"}).appendTo(jQuery("<div/>",{"class":"panel-heading"})),e=function(a){document.execCommand(a.data)},f=function(f){var g=jQuery("<div/>",{"class":"btn-group",role:"group"}).appendTo(d);for(a in f)b=f[a],c=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-"+b.icon})).appendTo(g),c.click(b.command,e)};f([{icon:"bold",command:"bold"},{icon:"italic",command:"italic"},{icon:"text-color",command:"underline"}]);var g=[{heading:Sao.i18n.gettext("Font"),options:["Normal","Serif","Sans","Monospace"],command:"fontname"},{heading:Sao.i18n.gettext("Size"),options:[1,2,3,4,5,6,7],command:"fontsize"}],h=function(a,b){return function(c){a.append(jQuery("<li/>").append(jQuery("<a/>",{href:"#"}).append(c).click(function(){document.execCommand(b.command,!1,c)})))}};for(a in g){b=g[a];var i=jQuery("<div/>",{"class":"btn-group",role:"group"}).appendTo(d);c=jQuery("<button/>",{"class":"btn btn-default dropdown-toggle",type:"button","data-toggle":"dropdown","aria-expanded":!1,"aria-haspopup":!0}).append(b.heading).append(jQuery("<span/>",{"class":"caret"})).appendTo(i);var j=jQuery("<ul/>",{"class":"dropdown-menu"}).appendTo(i);b.options.forEach(h(j,b))}return f([{icon:"align-left",command:"justifyLeft"},{icon:"align-center",command:"justifyCenter"},{icon:"align-right",command:"justifyRight"},{icon:"align-justify",command:"justifyFull"}]),[["foreColor","#000000"]].forEach(function(a){var b=a[0],c=a[1];jQuery("<input/>",{"class":"btn btn-default",type:"color"}).appendTo(d).change(function(){document.execCommand(b,!1,jQuery(this).val())}).focusin(function(){document.execCommand(b,!1,jQuery(this).val())}).val(c)}),d},focus_out:function(){window.setTimeout(function(){0===this.el.find(":focus").length&&Sao.View.Form.RichText._super.focus_out.call(this)}.bind(this),0)},display:function(a,b){Sao.View.Form.RichText._super.display.call(this,a,b);var c="";a&&(c=a.field_get_client(this.field_name)),this.input.html(c)},focus:function(){this.input.focus()},set_value:function(a,b){this.input.find("div").each(function(a,b){if(b=jQuery(b),b.css("text-align")){var c=b.css("text-align").split("-").pop();b.attr("align",c),b.css("text-align","")}"start"==b.attr("align")&&b.attr("align","left")});var c=this.input.html()||"";b.set_client(a,c)},set_readonly:function(a){this.input.prop("contenteditable",!a),this.toolbar&&this.toolbar.find("button,select").prop("disabled",a)}}),Sao.View.Form.Many2One=Sao.class_(Sao.View.Form.Widget,{class_:"form-many2one",init:function(a,b,c){Sao.View.Form.Many2One._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_});var d=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el);this.entry=this.labelled=jQuery("<input/>",{type:"input","class":"form-control input-sm"}).appendTo(d),this.entry.on("keydown",this.key_press.bind(this)),c.completion&&"1"!=c.completion||(Sao.common.get_completion(d,this._update_completion.bind(this),this._completion_match_selected.bind(this),this._completion_action_activated.bind(this)),this.wid_completion=!0),this.but_primary=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon"})).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).prependTo(d)),this.but_secondary=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon"})).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(d)),this.but_primary.click("primary",this.edit.bind(this)),this.but_secondary.click("secondary",this.edit.bind(this)),this.el.change(this.focus_out.bind(this)),this._readonly=!1},get_screen:function(){var a=this.field().get_domain(this.record()),b=this.field().get_context(this.record());return new Sao.Screen(this.get_model(),{context:b,domain:a,mode:["form"],view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views,readonly:this._readonly})},set_text:function(a){jQuery.isEmptyObject(a)&&(a=""),this.entry.val(a)},get_text:function(){var a=this.record();return a?a.field_get_client(this.field_name):""},focus_out:function(){(this.attributes.completion&&"1"!=this.attributes.completion||!this.el.find(".dropdown").hasClass("open"))&&Sao.View.Form.Many2One._super.focus_out.call(this)},set_value:function(a,b){b.get_client(a)!=this.entry.val()&&(b.set_client(a,this.value_from_id(null,"")),this.entry.val(""))},display:function(a,b){var c=this.record();if(!c||!a||c.id==a.id){var d;if(Sao.View.Form.Many2One._super.display.call(this,a,b),this._set_button_sensitive(),this._set_completion(),!a)return void this.entry.val("");this.set_text(b.get_client(a));var e,f;d=b.get(a),this.has_target(d)?(e="glyphicon-folder-open",f="glyphicon-erase"):(e=null,f="glyphicon-search"),this.entry.prop("readonly")&&(f=null),[[e,this.but_primary],[f,this.but_secondary]].forEach(function(a){var b=a[0],c=a[1],d=c.find(".glyphicon");d.removeClass().addClass("glyphicon"),b?(c.parent().css("display","table-cell"),d.addClass(b)):c.parent().css("display","none")})}},focus:function(){this.entry.focus()},set_readonly:function(a){this._readonly=a,this._set_button_sensitive()},_set_button_sensitive:function(){this.entry.prop("readonly",this._readonly),this.but_primary.prop("disabled",!this.read_access()),this.but_secondary.prop("disabled",this._readonly)},get_access:function(a){var b=this.get_model();return b?Sao.common.MODELACCESS.get(b)[a]:!0},read_access:function(){return this.get_access("read")},create_access:function(){return this.attributes.create&&this.get_access("create")},id_from_value:function(a){return a},value_from_id:function(a,b){return void 0===b&&(b=""),[a,b]},get_model:function(){return this.attributes.relation},has_target:function(a){return void 0!==a&&null!==a},edit:function(a){var b=this.get_model();if(b&&Sao.common.MODELACCESS.get(b).read){var c,d,e=this.record(),f=e.field_get(this.field_name);if(a&&"secondary"==a.data&&!this._readonly&&this.has_target(f))return this.record().field_set_client(this.field_name,this.value_from_id(null,"")),void this.entry.val("");if(this.has_target(f)){var g=this.get_screen(),h=this.id_from_value(e.field_get(this.field_name));return g.new_group([h]),d=function(a){if(a){var b=g.current_record.rec_name();b.done(function(a){var b=this.value_from_id(g.current_record.id,a);this.record().field_set_client(this.field_name,b,!0)}.bind(this))}},void(c=new Sao.Window.Form(g,d.bind(this),{save_current:!0,title:this.attributes.string}))}if(b){var i=this.field().get_domain(e),j=this.field().get_context(e),k=this.entry.val();d=function(a){if(!jQuery.isEmptyObject(a)){var b=this.value_from_id(a[0][0],a[0][1]);this.record().field_set_client(this.field_name,b,!0)}};var l=new Sao.common.DomainParser;return void(c=new Sao.Window.Search(b,d.bind(this),{sel_multi:!1,context:j,domain:i,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.create_access(),search_filter:l.quote(k),title:this.attributes.string}))}}},new_:function(a){var b=this.get_model();if(b&&Sao.common.MODELACCESS.get(b).create){var c=this.get_screen(),d=function(a){if(a){var b=c.current_record.rec_name();b.done(function(a){var b=this.value_from_id(c.current_record.id,a);this.record().field_set_client(this.field_name,b)}.bind(this))}};new Sao.Window.Form(c,d.bind(this),{new_:!0,save_current:!0,title:this.attributes.string,rec_name:this.entry.val()})}},key_press:function(a){var b=!this.entry.prop("readonly"),c=[Sao.common.TAB_KEYCODE],d=[Sao.common.BACKSPACE_KEYCODE,Sao.common.DELETE_KEYCODE];if(this.wid_completion||c.push(Sao.common.RETURN_KEYCODE),a.which==Sao.common.F3_KEYCODE&&b&&this.create_access())this.new_(),a.preventDefault();else if(a.which==Sao.common.F2_KEYCODE&&this.read_access())this.edit(),a.preventDefault();else if(~c.indexOf(a.which)&&b){if((!this.attributes.completion||"1"==this.attributes.completion)&&this.el.find(".dropdown").hasClass("open"))return;this.activate()}else if(this.has_target(this.record().field_get(this.field_name))&&b){var e=this.get_text();(e!=this.entry.val()||~d.indexOf(a.which))&&(this.entry.val(""),this.record().field_set_client(this.field_name,this.value_from_id(null,"")))}},activate:function(){var a=this.get_model();if(a&&Sao.common.MODELACCESS.get(a).read){var b=this.record(),c=b.field_get(this.field_name);
-new Sao.Model(a);if(a&&!this.has_target(c)){var d=this.entry.val();if(!this._readonly&&(d||this.field().get_state_attrs(this.record()).required)){var e=this.field().get_domain(b),f=this.field().get_context(b),g=function(a){if(jQuery.isEmptyObject(a))this.entry.val("");else{var b=this.value_from_id(a[0][0],a[0][1]);this.record().field_set_client(this.field_name,b,!0)}},h=new Sao.common.DomainParser;new Sao.Window.Search(a,g.bind(this),{sel_multi:!1,context:f,domain:e,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.create_access(),search_filter:h.quote(d),title:this.attributes.string})}}}},_set_completion:function(){var a=this.el.find(".action-search");this.read_access()?a.removeClass("disabled"):a.addClass("disabled");var b=this.el.find(".action-create");this.create_access()?b.removeClass("disabled"):b.addClass("disabled")},_update_completion:function(a){var b=this.record();if(b){var c=this.field(),d=c.get(b);if(this.has_target(d)){var e=this.id_from_value(d);if(void 0!==e&&e>0)return jQuery.when()}var f=this.get_model();return Sao.common.update_completion(this.entry,b,c,f)}},_completion_match_selected:function(a){this.record().field_set_client(this.field_name,this.value_from_id(a.id,a.rec_name),!0)},_completion_action_activated:function(a){"search"==a?this.edit():"create"==a&&this.new_()}}),Sao.View.Form.One2One=Sao.class_(Sao.View.Form.Many2One,{class_:"form-one2one"}),Sao.View.Form.Reference=Sao.class_(Sao.View.Form.Many2One,{class_:"form-reference",init:function(a,b,c){Sao.View.Form.Reference._super.init.call(this,a,b,c),this.el.addClass("form-inline"),this.select=jQuery("<select/>",{"class":"form-control input-sm","aria-label":c.string}),this.el.prepend(jQuery("<span/>").text("-")),this.el.prepend(this.select),this.select.change(this.select_changed.bind(this)),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a,this.set_selection.bind(this))},update_selection:function(a,b,c){Sao.common.selection_mixin.update_selection.call(this,a,b,function(a){this.set_selection(a),c&&c()}.bind(this))},set_selection:function(a){var b=this.select;b.empty(),a.forEach(function(a){b.append(jQuery("<option/>",{value:a[0],text:a[1]}))})},id_from_value:function(a){return parseInt(a.split(",")[1],10)},value_from_id:function(a,b){return b||(b=""),[this.get_model(),[a,b]]},get_text:function(){var a=this.record();return a?a.field_get_client(this.field_name)[1]:""},get_model:function(){return this.select.val()},has_target:function(a){if(null===a)return!1;var b=a.split(",")[0];return a=a.split(",")[1],jQuery.isEmptyObject(a)?a=null:(a=parseInt(a,10),isNaN(a)&&(a=null)),b==this.get_model()&&a>=0},_set_button_sensitive:function(){Sao.View.Form.Reference._super._set_button_sensitive.call(this),this.select.prop("disabled",this.entry.prop("readonly"))},select_changed:function(){this.entry.val("");var a,b=this.get_model();a=b?[b,[-1,""]]:["",""],this.record().field_set_client(this.field_name,a)},set_value:function(a,b){var c;if(this.get_model()){c=b.get_client(a,this.field_name);var d,e;c instanceof Array?(d=c[0],e=c[1]):(d="",e=""),d==this.get_model()&&e==this.entry.val()||(b.set_client(a,null),this.entry.val(""))}else c=this.entry.val(),jQuery.isEmptyObject(c)?b.set_client(a,null):b.set_client(a,["",c])},set_text:function(a){var b;a?(b=a[0],a=a[1]):(b=null,a=null),Sao.View.Form.Reference._super.set_text.call(this,a),b?this.select.val(b):this.select.val("")},display:function(a,b){this.update_selection(a,b,function(){Sao.View.Form.Reference._super.display.call(this,a,b)}.bind(this))},set_readonly:function(a){Sao.View.Form.Reference._super.set_readonly.call(this,a),this.select.prop("disabled",a)}}),Sao.View.Form.One2Many=Sao.class_(Sao.View.Form.Widget,{class_:"form-one2many",init:function(a,b,c){Sao.View.Form.One2Many._super.init.call(this,a,b,c),this._readonly=!0,this._required=!1,this.el=jQuery("<div/>",{"class":this.class_+" panel panel-default"}),this.menu=jQuery("<div/>",{"class":this.class_+"-menu panel-heading"}),this.el.append(this.menu),this.title=jQuery("<label/>",{"class":this.class_+"-string",text:c.string}),this.menu.append(this.title),this.title.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",this.title.attr("id")),this.title.attr("for",this.el.attr("id"));var d=jQuery("<div/>",{"class":this.class_+"-toolbar"});this.menu.append(d);var e=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(d);this.wid_text=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(e),this.wid_text.hide();var f=jQuery("<div/>",{"class":"input-group-btn"}).appendTo(e);c.add_remove&&(this.wid_text.show(),this.but_add=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-plus"})).appendTo(f),this.but_add.click(this.add.bind(this)),this.but_remove=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-minus"})).appendTo(f),this.but_remove.click(this.remove.bind(this))),this.but_new=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("New")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-edit"})).appendTo(f),this.but_new.click(this.new_.bind(this)),this.but_open=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Open")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-folder-open"})).appendTo(f),this.but_open.click(this.open.bind(this)),this.but_del=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Delete")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-trash"})).appendTo(f),this.but_del.click(this.delete_.bind(this)),this.but_undel=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Undelete")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-repeat"})).appendTo(f),this.but_undel.click(this.undelete.bind(this)),this.but_previous=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-chevron-left"})).appendTo(f),this.but_previous.click(this.previous.bind(this)),this.label=jQuery("<span/>",{"class":"btn"}).appendTo(f),this.label.text("(0, 0)"),this.but_next=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-chevron-right"})).appendTo(f),this.but_next.click(this.next.bind(this)),this.but_switch=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Switch")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-list-alt"})).appendTo(f),this.but_switch.click(this.switch_.bind(this)),this.content=jQuery("<div/>",{"class":this.class_+"-content panel-body"}),this.el.append(this.content);var g=(c.mode||"tree,form").split(",");this.screen=new Sao.Screen(c.relation,{mode:g,view_ids:(c.view_ids||"").split(","),views_preload:c.views||{},row_activate:this.activate.bind(this),exclude_field:c.relation_field||null,limit:null,pre_validate:c.pre_validate}),this.screen.pre_validate=1==c.pre_validate,this.prm=this.screen.switch_view(g[0]).done(function(){this.content.append(this.screen.screen_container.el)}.bind(this)),this.but_switch.prop("disabled",this.screen.number_of_views()<=0)},set_readonly:function(a){this._readonly=a,this._set_button_sensitive(),this._set_label_state()},set_required:function(a){this._required=a,this._set_label_state()},_set_label_state:function(){Sao.common.apply_label_attributes(this.title,this._readonly,this._required)},_set_button_sensitive:function(){var a,b,c=Sao.common.MODELACCESS.get(this.screen.model_name),d=this.record(),e=this.field();if(d&&e){var f=d.expr_eval(this.attributes.size);b=e.get_eval(d).length,a=void 0!==f&&null!==f&&b>=f>=0}else b=null,a=!1;var g=this.attributes.create;void 0===g&&(g=!0),this.but_new.prop("disabled",this._readonly||!g||a||!c.create);var h=this.attributes["delete"];void 0===h&&(h=!0),this.but_del.prop("disabled",this._readonly||!h||!c["delete"]),this.but_undel.prop("disabled",this._readonly||a),this.but_open.prop("disabled",!c.read),this.attributes.add_remove&&(this.wid_text.prop("disabled",this._readonly),this.but_add.prop("disabled",this._readonly||a||!c.write||!c.read),this.but_remove.prop("disabled",this._readonly||!c.write||!c.read))},display:function(a,b){Sao.View.Form.One2Many._super.display.call(this,a,b),this._set_button_sensitive(),this.prm.done(function(){if(a){if(void 0===b)return this.screen.new_group(),this.screen.set_current_record(null),this.screen.group.parent=null,void this.screen.display();var c=a.field_get_client(this.field_name);c!=this.screen.group&&(this.screen.set_group(c),"tree"==this.screen.current_view.view_type&&this.screen.current_view.editable&&this.screen.set_current_record(null));var d=[],e=null;a&&(d=b.get_domain(a),e=a.expr_eval(this.attributes.size)),this._readonly&&(e=null===e?this.screen.group.length:Math.min(e,this.screen.group.length)),Sao.common.compare(this.screen.domain,d)||(this.screen.domain=d),this.screen.size_limit=e,this.screen.display()}}.bind(this))},focus:function(){this.wid_text.is(":visible")&&this.wid_text.focus()},activate:function(a){this.edit()},add:function(a){var b=Sao.common.MODELACCESS.get(this.screen.model_name);if(b.write&&b.read){this.view.set_value();var c=this.field().get_domain(this.record()),d=this.field().get_context(this.record());c=[c,this.record().expr_eval(this.attributes.add_remove)];var e=this.field().get_removed_ids(this.record());c=["OR",c,["id","in",e]];var f=this.wid_text.val(),g=function(a){var b=jQuery.when();if(!jQuery.isEmptyObject(a)){var c,d,e=[];for(c=0,d=a.length;d>c;c++)e.push(a[c][0]);this.screen.group.load(e,!0),b=this.screen.display()}b.done(function(){this.screen.set_cursor()}.bind(this)),this.wid_text.val("")}.bind(this),h=new Sao.common.DomainParser;new Sao.Window.Search(this.attributes.relation,g,{sel_multi:!0,context:d,domain:c,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:!this.but_new.prop("disabled"),search_filter:h.quote(f),title:this.attributes.string})}},remove:function(a){var b=Sao.common.MODELACCESS.get(this.screen.model_name);b.write&&b.read&&this.screen.remove(!1,!0,!1)},new_:function(a){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.validate().done(function(){this.attributes.product?this.new_product():this.new_single()}.bind(this))},new_single:function(){var a=jQuery.extend({},this.field().get_context(this.record()));if("form"==this.screen.current_view.type||this.screen.current_view.editable)this.screen.new_(),this.screen.current_view.el.prop("disabled",!1);else{var b=this.record(),c=b.expr_eval(this.attributes.size)||-1;c-=this.field().get_eval(b);new Sao.Window.Form(this.screen,function(){},{new_:!0,many:c,context:a,title:this.attributes.string})}},new_product:function(){var a=this.attributes.product.split(","),b={},c=this.screen;c.new_(!1).then(function(d){d.default_get().then(function(e){d.set_default(e);var f=function(){if(jQuery.isEmptyObject(a))return g();var e=c.model.fields[a.pop()],h=e.description.relation;h||f();var i=e.get_domain(d),j=e.get_context(d),k=function(a){jQuery.isEmptyObject(a)||(b[e.name]=a),f()};new Sao.Window.Search(h,k,{sel_multi:!0,context:j,domain:i,search_filter:"",title:this.attributes.string})}.bind(this),g=function(){if(jQuery.isEmptyObject(b))return void c.group.remove(d,!0);var a=Object.keys(b),f=a.map(function(a){return b[a]});Sao.common.product(f).forEach(function(b){var f=function(c){var d=jQuery.extend({},e);a.forEach(function(a,c){d[a]=b[c][0],d[a+".rec_name"]=b[c][1]}),c.set_default(d)};d?(f(d),d=null):c.new_(!1).then(f)})};f()}.bind(this))}.bind(this))},open:function(a){this.edit()},delete_:function(a){Sao.common.MODELACCESS.get(this.screen.model_name)["delete"]&&this.screen.remove(!1,!1,!1)},undelete:function(a){this.screen.unremove()},previous:function(a){this.validate().done(function(){this.screen.display_previous()}.bind(this))},next:function(a){this.validate().done(function(){this.screen.display_next()}.bind(this))},switch_:function(a){this.screen.switch_view()},edit:function(){Sao.common.MODELACCESS.get(this.screen.model_name).read&&this.validate().done(function(){var a=this.screen.current_record;if(a){new Sao.Window.Form(this.screen,function(){},{title:this.attributes.string})}}.bind(this))},validate:function(){var a=jQuery.Deferred();this.view.set_value();var b=this.screen.current_record;if(b){var c=this.screen.current_view.get_fields();b.validate(c).then(function(c){return c?this.screen.pre_validate?b.pre_validate().then(function(b){return b?void a.resolve():void a.reject()}):void a.resolve():(this.screen.display(!0),void a.reject())}.bind(this))}else a.resolve();return a},set_value:function(a,b){this.screen.save_tree_state()}}),Sao.View.Form.Many2Many=Sao.class_(Sao.View.Form.Widget,{class_:"form-many2many",init:function(a,b,c){Sao.View.Form.Many2Many._super.init.call(this,a,b,c),this._readonly=!0,this._required=!1,this.el=jQuery("<div/>",{"class":this.class_+" panel panel-default"}),this.menu=jQuery("<div/>",{"class":this.class_+"-menu panel-heading"}),this.el.append(this.menu),this.title=jQuery("<label/>",{"class":this.class_+"-string",text:c.string}),this.menu.append(this.title),this.title.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",this.title.attr("id")),this.title.attr("for",this.el.attr("id"));var d=jQuery("<div/>",{"class":this.class_+"-toolbar"});this.menu.append(d);var e=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(d);this.entry=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(e),this.entry.on("keydown",this.key_press.bind(this));var f=jQuery("<div/>",{"class":"input-group-btn"}).appendTo(e);this.but_add=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-plus"})).appendTo(f),this.but_add.click(this.add.bind(this)),this.but_remove=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-minus"})).appendTo(f),this.but_remove.click(this.remove.bind(this)),this.content=jQuery("<div/>",{"class":this.class_+"-content panel-body"}),this.el.append(this.content),this.screen=new Sao.Screen(c.relation,{mode:["tree"],view_ids:(c.view_ids||"").split(","),views_preload:c.views||{},row_activate:this.activate.bind(this),limit:null}),this.prm=this.screen.switch_view("tree").done(function(){this.content.append(this.screen.screen_container.el)}.bind(this))},set_readonly:function(a){this._readonly=a,this._set_button_sensitive(),this._set_label_state()},set_required:function(a){this._required=a,this._set_label_state()},_set_label_state:function(){Sao.common.apply_label_attributes(this.title,this._readonly,this._required)},_set_button_sensitive:function(){var a=!1,b=this.record(),c=this.field();if(b&&c){var d=b.expr_eval(this.attributes.size),e=c.get_eval(b).length;a=void 0!==d&&null!==d&&e>=d>=0}this.entry.prop("disabled",this._readonly),this.but_add.prop("disabled",this._readonly||a),this.but_remove.prop("disabled",this._readonly)},display:function(a,b){Sao.View.Form.Many2Many._super.display.call(this,a,b),this.prm.done(function(){if(a){if(void 0===b)return this.screen.new_group(),this.screen.set_current_record(null),this.screen.group.parent=null,void this.screen.display();var c=a.field_get_client(this.field_name);c!=this.screen.group&&this.screen.set_group(c),this.screen.display()}}.bind(this))},focus:function(){this.entry.focus()},activate:function(){this.edit()},add:function(){var a=this.field().get_domain(this.record()),b=this.field().get_context(this.record()),c=this.entry.val(),d=function(a){if(!jQuery.isEmptyObject(a)){var b,c,d=[];for(b=0,c=a.length;c>b;b++)d.push(a[b][0]);this.screen.group.load(d,!0),this.screen.display()}this.entry.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(this.attributes.relation,d,{sel_multi:!0,context:b,domain:a,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.attributes.create,search_filter:e.quote(c),title:this.attributes.string})},remove:function(){this.screen.remove(!1,!0,!1)},key_press:function(a){var b=[Sao.common.TAB_KEYCODE];this.wid_completion||b.push(Sao.common.RETURN_KEYCODE),a.which==Sao.common.F3_KEYCODE?(this.new_(),a.preventDefault()):a.which==Sao.common.F2_KEYCODE?(this.add(),a.preventDefault()):~b.indexOf(a.which)&&this.entry.val()&&this.add()},_get_screen_form:function(){var a=this.field().get_domain(this.record()),b=this.record().expr_eval(this.attributes.add_remove);jQuery.isEmptyObject(b)||(a=[a,b]);var c=this.field().get_context(this.record()),d=(this.attributes.view_ids||"").split(",");return jQuery.isEmptyObject(d)||d.shift(),new Sao.Screen(this.attributes.relation,{domain:a,view_ids:d,mode:["form"],views_preload:this.attributes.views,context:c})},edit:function(){if(!jQuery.isEmptyObject(this.screen.current_record)){var a=this._get_screen_form();a.new_group([this.screen.current_record.id]);var b=function(b){b&&a.current_record.save().done(function(){this.screen.current_record.cancel()}.bind(this))}.bind(this);a.switch_view().done(function(){new Sao.Window.Form(a,b,{title:this.attributes.string})}.bind(this))}},new_:function(){var a=this._get_screen_form(),b=function(b){if(b){var c=a.current_record;this.screen.group.load([c.id],!0)}this.entry.val("")}.bind(this);a.switch_view().done(function(){new Sao.Window.Form(a,b,{new_:!0,save_current:!0,title:this.attributes.string,rec_name:this.entry.val()})}.bind(this))}}),Sao.View.Form.BinaryMixin=Sao.class_(Sao.View.Form.Widget,{init:function(a,b,c){Sao.View.Form.BinaryMixin._super.init.call(this,a,b,c),this.filename=c.filename||null},toolbar:function(a){var b=jQuery("<div/>",{"class":a,role:"group"});return this.but_select=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-search"})).appendTo(b),this.but_select.click(this.select.bind(this)),this.filename&&(this.but_open=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-folder-open"})).appendTo(b),this.but_open.click(this.open.bind(this))),this.but_save_as=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-save"})).appendTo(b),this.but_save_as.click(this.save_as.bind(this)),this.but_clear=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-erase"})).appendTo(b),this.but_clear.click(this.clear.bind(this)),b},filename_field:function(){var a=this.record();return a?a.model.fields[this.filename]:void 0},select:function(){var a=this.record(),b=function(){d.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),d.modal.modal("hide")},c=function(){var c=new FileReader;c.onload=function(b){var d,e=this.field(),f=new Uint8Array(c.result);d=e.get_size?f:String.fromCharCode.apply(null,f),e.set_client(a,d)}.bind(this),c.onloadend=function(a){b()};var d=e[0].files[0];c.readAsArrayBuffer(d),this.filename&&this.filename_field().set_client(a,d.name)}.bind(this),d=new Sao.Dialog(Sao.i18n.gettext("Select"),"file-dialog");d.footer.append(jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(b)).append(jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).click(c)),d.content.submit(function(a){c(),a.preventDefault()});var e=jQuery("<input/>",{type:"file"}).appendTo(d.body);d.modal.modal("show")},open:function(){var a={},b=this.filename_field();if(b){var c=b.get_client(this.record());a.mimetype=Sao.common.guess_mimetype(c)}this.save_as(a)},save_as:function(a){var b,c=(a.mimetype||"application/octet-binary",this.field()),d=this.record();b=c.get_data?c.get_data(d):jQuery.when(c.get(d)),b.done(function(a){var b,c=this.filename_field();c&&(b=c.get(this.record())),Sao.common.download_file(a,b)}.bind(this))},clear:function(){var a=this.filename_field();a&&a.set_client(this.record(),null),this.field().set_client(this.record(),null)}}),Sao.View.Form.Binary=Sao.class_(Sao.View.Form.BinaryMixin,{class_:"form-binary",blob_url:"",init:function(a,b,c){Sao.View.Form.Binary._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.filename&&c.filename_visible&&(this.text=jQuery("<input/>",{type:"input","class":"form-control input-sm"}).appendTo(this.el),this.text.change(this.focus_out.bind(this)),this.text.on("keydown",this.key_press.bind(this)));var d=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el);this.size=jQuery("<input/>",{type:"input","class":"form-control input-sm",readonly:!0}).appendTo(d),this.toolbar("input-group-btn").appendTo(d)},display:function(a,b){if(Sao.View.Form.Binary._super.display.call(this,a,b),!b)return this.size.val(""),this.filename&&this.but_open.button("disable"),this.text&&this.text.val(""),void this.but_save_as.button("disable");var c;c=b.get_size?b.get_size(a):b.get(a).length;var d;d=c?"enable":"disable",this.filename&&(this.text&&this.text.val(this.filename_field().get(a)||""),this.but_open.button(d)),this.size.val(Sao.common.humanize(c)),this.but_save_as.button(d)},key_press:function(a){var b=!this.wid_text.prop("readonly");a.which==Sao.common.F3_KEYCODE&&b?(this.new_(),a.preventDefault()):a.which==Sao.common.F2_KEYCODE&&(this.open(),a.preventDefault())},set_value:function(a,b){this.text&&this.filename_field().set_client(a,this.text.val()||"")},set_readonly:function(a){a?(this.but_select.hide(),this.but_clear.hide()):(this.but_select.show(),this.but_clear.show()),this.wid_text&&this.wid_text.prop("readonly",a)}}),Sao.View.Form.MultiSelection=Sao.class_(Sao.View.Form.Selection,{class_:"form-multiselection",expand:!0,init:function(a,b,c){this.nullable_widget=!1,Sao.View.Form.MultiSelection._super.init.call(this,a,b,c),this.select.prop("multiple",!0)},display_update_selection:function(a,b){var c,d,e;this.update_selection(a,b,function(){var f=this.attributes.yexpand;if(void 0===f&&(f=this.expand),f||this.select.prop("size",this.select.children().length),b){var g=[],h=a.field_get_client(this.field_name);for(c=0,d=h.length;d>c;c++)e=h[c],~h.record_removed.indexOf(e)||~h.record_deleted.indexOf(e)||g.push(e.id);this.select.val(g)}}.bind(this))},set_value:function(a,b){var c=this.select.val();c=c?c.map(function(a){return parseInt(a,10)}):[],b.set_client(a,c)}}),Sao.View.Form.Image=Sao.class_(Sao.View.Form.BinaryMixin,{class_:"form-image",init:function(a,b,c){Sao.View.Form.Image._super.init.call(this,a,b,c),this.height=parseInt(c.height||100,10),this.width=parseInt(c.width||300,10),this.el=jQuery("<div/>"),this.image=jQuery("<img/>",{"class":"center-block"}).appendTo(this.el),this.image.css("max-height",this.height),this.image.css("max-width",this.width),this.image.css("height","auto"),this.image.css("width","auto");var d=this.toolbar("btn-group");c.readonly||jQuery("<div/>",{"class":"text-center"}).append(d).appendTo(this.el),this.update_img()},set_readonly:function(a){[this.but_select,this.but_open,this.but_save_as,this.but_clear].forEach(function(b){b&&b.prop("disable",a)})},clear:function(){Sao.View.Form.Image._super.clear.call(this),this.update_img()},update_img:function(){var a,b=this.record();b&&(a=b.field_get_client(this.field_name)),a=a?a>Sao.common.BIG_IMAGE_SIZE?jQuery.when(null):b.model.fields[this.field_name].get_data(b):jQuery.when(null),a.done(function(a){var b,c;a?(c=new Blob([a]),b=window.URL.createObjectURL(c)):b=null,this.image.attr("src",b)}.bind(this))},display:function(a,b){Sao.View.Form.Image._super.display.call(this,a,b),this.update_img()}}),Sao.View.Form.URL=Sao.class_(Sao.View.Form.Char,{class_:"form-url",init:function(a,b,c){Sao.View.Form.URL._super.init.call(this,a,b,c),this.button=jQuery("<a/>",{"class":"btn btn-default",target:"_new"}).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.group)),this.icon=jQuery("<img/>").appendTo(this.button),this.set_icon()},display:function(a,b){Sao.View.Form.URL._super.display.call(this,a,b);var c="";if(a&&(c=a.field_get_client(this.field_name)),this.set_url(c),a&this.attributes.icon){var d,e=this.attributes.icon;d=e in a.model.fields?a.field_get_client(e):e,this.set_icon(d)}},set_icon:function(a){a=a||"tryton-web-browser",Sao.common.ICONFACTORY.register_icon(a).done(function(a){this.icon.attr("src",a)}.bind(this))},set_url:function(a){this.button.attr("href",a)},set_readonly:function(a){Sao.View.Form.URL._super.set_readonly.call(this,a),a?(this.input.hide(),this.button.removeClass("btn-default"),this.button.addClass("btn-link")):(this.input.show(),this.button.removeClass("btn-link"),this.button.addClass("btn-default"))}}),Sao.View.Form.Email=Sao.class_(Sao.View.Form.URL,{class_:"form-email",set_url:function(a){Sao.View.Form.Email._super.set_url.call(this,"mailto:"+a)}}),Sao.View.Form.CallTo=Sao.class_(Sao.View.Form.URL,{class_:"form-callto",set_url:function(a){Sao.View.Form.CallTo._super.set_url.call(this,"callto:"+a)}}),Sao.View.Form.SIP=Sao.class_(Sao.View.Form.URL,{class_:"form-sip",set_url:function(a){Sao.View.Form.SIP._super.set_url.call(this,"sip:"+a)}}),Sao.View.Form.ProgressBar=Sao.class_(Sao.View.Form.Widget,{class_:"form-char",init:function(a,b,c){Sao.View.Form.ProgressBar._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_+" progress"}),this.progressbar=jQuery("<div/>",{"class":"progress-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100}).appendTo(this.el),this.progressbar.css("min-width: 2em")},display:function(a,b){Sao.View.Form.ProgressBar._super.display.call(this,a,b);var c,d;b?(c=b.get(a),d=b.get_client(a,100),d&&(d=Sao.i18n.gettext("%1%",d))):(c=0,d=""),this.progressbar.attr("aria-valuenow",100*c),this.progressbar.css("width",100*c+"%"),this.progressbar.text(d)}}),Sao.View.Form.Dict=Sao.class_(Sao.View.Form.Widget,{class_:"form-dict",init:function(a,b,c){Sao.View.Form.Dict._super.init.call(this,a,b,c),this.schema_model=new Sao.Model(c.schema_model),this.keys={},this.fields={},this.rows={},this.el=jQuery("<div/>",{"class":this.class_+" panel panel-default"});var d=jQuery("<div/>",{"class":this.class_+"-heading panel-heading"}).appendTo(this.el),e=jQuery("<label/>",{"class":this.class_+"-string",text:c.string}).appendTo(d);e.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",e.attr("id")),e.attr("for",this.el.attr("id"));var f=jQuery("<div/>",{"class":this.class_+"-body panel-body"}).appendTo(this.el);this.container=jQuery("<div/>",{"class":this.class_+"-container"}).appendTo(f);var g=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(jQuery("<div>",{"class":"col-md-12"}).appendTo(jQuery("<div/>",{"class":"row"}).appendTo(jQuery("<div/>",{"class":"container-fluid"}).appendTo(f))));this.wid_text=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(g),this.but_add=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-plus"})).appendTo(jQuery("<div/>",{"class":"input-group-btn"}).appendTo(g)),this.but_add.click(this.add.bind(this)),this._readonly=!1,this._record_id=null},add:function(){var a=this.field().get_context(this.record()),b=this.wid_text.val(),c=this.field().get_domain(this.record()),d=function(a){if(!jQuery.isEmptyObject(a)){var b=a.map(function(a){return a[0]});this.add_new_keys(b)}this.wid_text.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(this.schema_model.name,d,{sel_multi:!0,context:a,domain:c,new_:!1,search_filter:e.quote(b),title:this.attributes.string})},add_new_keys:function(a){var b=this.field().get_context(this.record());this.schema_model.execute("get_keys",[a],b).then(function(a){var b=!1;a.forEach(function(a){this.fields[a.name]||(this.keys[a.name]=a,this.add_line(a.name),b||(this.fields[a.name].input.focus(),b=!0))}.bind(this))}.bind(this))},remove:function(a,b){void 0===b&&(b=!0),delete this.fields[a],this.rows[a].remove(),delete this.rows[a],b&&this.set_value(this.record(),this.field())},set_value:function(a,b){b.set_client(a,this.get_value())},get_value:function(){var a={};for(var b in this.fields){var c=this.fields[b];a[b]=c.get_value()}return a},set_readonly:function(a){this._readonly=a,this._set_button_sensitive();for(var b in this.fields){var c=this.fields[b];c.set_readonly(a)}this.wid_text.prop("disabled",a)},_set_button_sensitive:function(){var a=this.attributes.create;void 0===a&&(a=!0);var b=this.attributes["delete"];void 0===b&&(b=!0),this.but_add.prop("disabled",this._readonly||!a);for(var c in this.fields){var d=this.fields[c].button;d.prop("disabled",this._readonly||!b)}},add_line:function(a){var b,c;this.fields[a]=b=new(this.get_entries(this.keys[a].type_))(a,this),this.rows[a]=c=jQuery("<div/>",{"class":"row"});var d=this.keys[a].string+Sao.i18n.gettext(":"),e=jQuery("<label/>",{text:d}).appendTo(jQuery("<div/>",{"class":"dict-label col-md-4"}).appendTo(c));b.el.addClass("col-md-8").appendTo(c),e.uniqueId(),b.labelled.uniqueId(),b.labelled.attr("aria-labelledby",e.attr("id")),e.attr("for",b.labelled.attr("id")),b.button.click(function(){this.remove(a,!0)}.bind(this)),c.appendTo(this.container)},add_keys:function(a){var b=this.field().get_context(this.record()),c=this.field().get_domain(this.record()),d=Math.min(10,Sao.config.limit);a=jQuery.extend([],a);for(var e=function(a){return this.schema_model.execute("get_keys",[a],b).then(f)}.bind(this),f=function(a){for(var b=0,c=a.length;c>b;b++){var d=a[b];this.keys[d.name]=d}}.bind(this),g=[];a.length>0;){var h=a.splice(0,d);g.push(this.schema_model.execute("search",[[["name","in",h],c],0,Sao.config.limit,null],b).then(e))}return jQuery.when.apply(jQuery,g)},display:function(a,b){if(Sao.View.Form.Dict._super.display.call(this,a,b),b){var c,d=a?a.id:null;if(d!=this._record_id){for(c in this.fields)this.remove(c,!1);this._record_id=d}var e,f=b.get_client(a),g=Object.keys(f).filter(function(a){return!this.keys[a]}.bind(this));e=jQuery.isEmptyObject(g)?jQuery.when():this.add_keys(g),e.then(function(){var a,b,c,d=Object.keys(f).sort();for(a=0,b=d.length;b>a;a++){c=d[a];var e=f[c];if(this.keys[c]){this.fields[c]||this.add_line(c);var g=this.fields[c];g.set_value(e),g.set_readonly(this._readonly)}}var h=Object.keys(this.fields).filter(function(a){return!f[a]});for(a=0,b=h.length;b>a;a++)c=h[a],this.remove(c,!1)}.bind(this)),this._set_button_sensitive()}},get_entries:function(a){switch(a){case"char":return Sao.View.Form.Dict.Entry;case"boolean":return Sao.View.Form.Dict.Boolean;case"selection":return Sao.View.Form.Dict.Selection;case"integer":return Sao.View.Form.Dict.Integer;case"float":return Sao.View.Form.Dict.Float;case"numeric":return Sao.View.Form.Dict.Numeric;case"date":return Sao.View.Form.Dict.Date;case"datetime":return Sao.View.Form.Dict.DateTime}}}),Sao.View.Form.Dict.Entry=Sao.class_(Object,{class_:"dict-char",init:function(a,b){this.name=a,this.definition=b.keys[a],this.parent_widget=b,this.create_widget()},create_widget:function(){this.el=jQuery("<div/>",{"class":this.class_});var a=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el);this.input=this.labelled=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(a),this.button=jQuery("<button/>",{"class":"btn btn-default",type:"button","arial-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-minus"})).appendTo(jQuery("<div/>",{
-"class":"input-group-btn"}).appendTo(a)),this.el.change(this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){return this.input.val()},set_value:function(a){this.input.val(a||"")},set_readonly:function(a){this._readonly=a,this.input.prop("readonly",a)}}),Sao.View.Form.Dict.Boolean=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-boolean",create_widget:function(){Sao.View.Form.Dict.Boolean._super.create_widget.call(this),this.input.attr("type","checkbox"),this.input.change(this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){return this.input.prop("checked")},set_value:function(a){this.input.prop("checked",a)}}),Sao.View.Form.Dict.Selection=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-selection",create_widget:function(){Sao.View.Form.Dict.Selection._super.create_widget.call(this);var a=jQuery("<select/>",{"class":"form-control input-sm"});a.change(this.parent_widget.focus_out.bind(this.parent_widget)),this.input.replaceWith(a),this.input=this.labelled=a;var b=jQuery.extend([],this.definition.selection);b.splice(0,0,[null,""]),b.forEach(function(b){a.append(jQuery("<option/>",{value:JSON.stringify(b[0]),text:b[1]}))})},get_value:function(){return JSON.parse(this.input.val())},set_value:function(a){this.input.val(JSON.stringify(a))}}),Sao.View.Form.Dict.Integer=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-integer",get_value:function(){var a=parseInt(this.input.val(),10);return isNaN(a)?null:a}}),Sao.View.Form.Dict.Float=Sao.class_(Sao.View.Form.Dict.Integer,{class_:"dict-float",get_value:function(){var a=Number(this.input.val());return isNaN(a)?null:a}}),Sao.View.Form.Dict.Numeric=Sao.class_(Sao.View.Form.Dict.Float,{class_:"dict-numeric",get_value:function(){var a=new Sao.Decimal(this.input.val());return isNaN(a.valueOf())?null:a}}),Sao.View.Form.Dict.Date=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-date",format:"%x",create_widget:function(){Sao.View.Form.Dict.Date._super.create_widget.call(this);var a=this.button.parent();jQuery("<button/>",{"class":"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-calendar"})).prependTo(a),this.input.datetimepicker({format:Sao.common.moment_format(this.format),locale:moment.locale()}),this.input.on("dp.change",this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){var a=this.input.data("DateTimePicker").date();return a&&(a.isDate=!0),a},set_value:function(a){this.input.data("DateTimePicker").date(a)}}),Sao.View.Form.Dict.DateTime=Sao.class_(Sao.View.Form.Dict.Date,{class_:"dict-datetime",format:"%x %X",get_value:function(){var a=this.input.data("DateTimePicker").date();return a&&(a.isDateTime=!0),a}}),Sao.View.Form.PYSON=Sao.class_(Sao.View.Form.Char,{class_:"form-pyson",init:function(a,b,c){Sao.View.Form.PYSON._super.init.call(this,a,b,c),this.encoder=new Sao.PYSON.Encoder({}),this.decoder=new Sao.PYSON.Decoder({},!0),this.el.keyup(this.validate_pyson.bind(this));var d=jQuery("<button/>",{"class":"btn btn-default",type:"button"});this.icon=jQuery("<span/>",{"class":"glyphicon"}),d.append(this.icon),d.appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.group))},get_encoded_value:function(){var a=this.input.val();if(!a)return a;try{return this.encoder.encode(eval_pyson(a))}catch(b){return null}},set_value:function(a,b){b.set_client(a,this.get_encoded_value())},get_client_value:function(a,b){var c=Sao.View.Form.PYSON._super.get_client_value.call(this,a,b);return c&&(c=this.decoder.decode(c).toString()),c},validate_pyson:function(){var a="ok";null===this.get_encoded_value()&&(a="remove"),this.icon.removeClass().addClass("glyphicon").addClass(" glyphicon-"+a+"-sign")},focus_out:function(){this.validate_pyson(),Sao.View.Form.PYSON._super.focus_out.call(this)}})}(),function(){"use strict";function a(a,b,c){var d=Sao.config.display_size,e=jQuery.Deferred(),f=function(g){a.slice(g,g+d).forEach(function(a){a.redraw(b,c)}),g+=d,g<a.length?setTimeout(f,0,g):e.resolve()};return setTimeout(f,0,0),e}Sao.View.tree_column_get=function(a){switch(a){case"char":return Sao.View.Tree.CharColumn;case"text":return Sao.View.Tree.TextColum;case"many2one":return Sao.View.Tree.Many2OneColumn;case"one2one":return Sao.View.Tree.One2OneColumn;case"date":return Sao.View.Tree.DateColumn;case"time":return Sao.View.Tree.TimeColumn;case"timedelta":return Sao.View.Tree.TimeDeltaColumn;case"one2many":return Sao.View.Tree.One2ManyColumn;case"many2many":return Sao.View.Tree.Many2ManyColumn;case"selection":return Sao.View.Tree.SelectionColumn;case"reference":return Sao.View.Tree.ReferenceColumn;case"float":case"numeric":return Sao.View.Tree.FloatColumn;case"integer":case"biginteger":return Sao.View.Tree.IntegerColumn;case"boolean":return Sao.View.Tree.BooleanColumn;case"binary":return Sao.View.Tree.BinaryColumn;case"image":return Sao.View.Tree.ImageColumn;case"url":case"email":case"callto":case"sip":return Sao.View.Tree.URLColumn;case"progressbar":return Sao.View.Tree.ProgressBar}},Sao.View.Tree=Sao.class_(Sao.View,{init:function(a,b,c){Sao.View.Tree._super.init.call(this,a,b),this.view_type="tree",this.selection_mode=a.attributes.selection_mode||Sao.common.SELECTION_SINGLE,this.el=jQuery("<div/>",{"class":"treeview responsive"}),this.expanded={},this.children_field=c,this.editable=Boolean(this.attributes.editable),this.columns=[],this.create_columns(a.model,b),this.rows=[],this.table=jQuery("<table/>",{"class":"tree table table-hover table-striped"}),this.el.append(this.table),this.thead=jQuery("<thead/>").appendTo(this.table);var d=jQuery("<tr/>");if(this.selection_mode!=Sao.common.SELECTION_NONE){var e=jQuery("<th/>",{"class":"selection"});this.selection=jQuery("<input/>",{type:"checkbox","class":"selection"}),this.selection.change(this.selection_changed.bind(this)),e.append(this.selection),d.append(e)}this.thead.append(d),this.columns.forEach(function(a){e=jQuery("<th/>");var b=jQuery("<label/>").text(a.attributes.string);if(this.editable&&(a.attributes.required&&b.addClass("required"),a.attributes.readonly||b.addClass("editable")),a.attributes.help&&(b.data("toggle","tooltip"),b.attr("title",a.attributes.help),b.tooltip()),a.sortable){var c=jQuery("<span/>");b.append(c),a.arrow=c,e.click(a,this.sort_model.bind(this)),b.addClass("sortable")}d.append(e.append(b)),a.header=e},this),this.tbody=jQuery("<tbody/>"),this.table.append(this.tbody);var f=jQuery("<div/>",{"class":"treefooter"});this.more=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("More")).click(function(){this.display_size+=Sao.config.display_size,this.display()}.bind(this)),f.append(this.more),this.more.hide(),this.display_size=Sao.config.display_size,this.el.append(f)},create_columns:function(a,b){b.find("tree").children().each(function(b,c){for(var d,e,f={},g=0,h=c.attributes.length;h>g;g++)e=c.attributes[g],f[e.name]=e.value;if(["readonly","expand","completion"].forEach(function(a){f[a]&&(f[a]=1==f[a])}),"field"==c.tagName){var i=f.name;f.widget||(f.widget=a.fields[i].description.type);var j=["relation","domain","selection","relation_field","string","views","invisible","add_remove","sort","context","filename","autocomplete","translate","create","delete","selection_change_with","schema_model","required","readonly","help"];for(g in j){var k=j[g];k in a.fields[i].description&&null===c.getAttribute(k)&&(f[k]=a.fields[i].description[k])}var l=Sao.View.tree_column_get(f.widget);d=new l(a,f);~["url","email","callto","sip"].indexOf(f.widget)&&d.prefixes.push(new Sao.View.Tree.Affix(f,f.widget)),"icon"in f&&d.prefixes.push(new Sao.View.Tree.Affix(f));var m,n,o=c.childNodes;for(g=0;g<o.length;g++){for(m=o[g],n={},g=0,h=m.attributes.length;h>g;g++)e=m.attributes[g],n[e.name]=e.value;n.name||(n.name=i),"prefix"==m.tagName?d.prefixes.push(new Sao.View.Tree.Affix(n)):d.suffixes.push(new Sao.View.Tree.Affix(n))}this.attributes.sequence||this.children_field||a.fields[i].description.sortable===!1||(d.sortable=!0),this.fields[i]=!0}else"button"==c.tagName&&(d=new Sao.View.Tree.ButtonColumn(this.screen,f));this.columns.push(d)}.bind(this))},sort_model:function(a){var b=a.data,c=b.arrow,d="glyphicon glyphicon-triangle-top",e="glyphicon glyphicon-triangle-bottom";this.columns.forEach(function(a){a.arrow&&a!=b&&a.arrow.hasClass("glyphicon")&&a.arrow.removeClass(d+" "+e)}),this.screen.order=this.screen.default_order,c.hasClass(e)?(c.removeClass(e),c.addClass(d),this.screen.order=[[b.attributes.name,"DESC"]]):c.hasClass(d)?c.removeClass(d):(c.addClass(e),this.screen.order=[[b.attributes.name,"ASC"]]);var f=[];this.screen.group.forEach(function(a){a.id<0&&(f=a.group)});var g=this.screen.screen_container.get_text();!jQuery.isEmptyObject(f)||this.screen.search_count==this.screen.group.length||this.screen.parent?this.screen.search_filter(g,!0).then(function(a){this.screen.group.sort(a)}.bind(this)):this.screen.search_filter(g)},get_buttons:function(){var a=[];return this.columns.forEach(function(b){b instanceof Sao.View.Tree.ButtonColumn&&a.push(b)}),a},display:function(a,b){var c=this.screen.current_record;if(!a)if(a=this.get_selected_paths(),c){var d=c.get_path(this.screen.group);d=d.map(function(a){return a[1]}),Sao.common.contains(a,d)||(a=[d])}else c||(a=[]);b=b||[];var e=function(){return this.rows.map(function(a){return a.record})}.bind(this),f=Math.min(this.screen.group.length,this.display_size);this.children_field?this.construct(a,b):f>this.rows.length&&Sao.common.compare(this.screen.group.slice(0,this.rows.length),e())?this.construct(a,b,!0):f==this.rows.length&&Sao.common.compare(this.screen.group,e())||this.construct(a,b);var g=[];jQuery.isEmptyObject(this.screen.domain)||g.push(this.screen.domain);var h=this.screen.screen_container.get_tab_domain();jQuery.isEmptyObject(h)||g.push(h);var i=new Sao.common.DomainInversion;g=i.simplify(g);var j=new Sao.PYSON.Decoder(this.screen.context);return this.columns.forEach(function(a){var b=a.attributes.name;if(b)if(j.decode(a.attributes.tree_invisible||"0")||b===this.screen.exclude_field)a.header.hide(),a.header.addClass("invisible");else{var c=i.domain_inversion(g,b);"boolean"!=typeof c&&(c=i.simplify(c));var d=i.unique_value(c)[0];d&&jQuery.isEmptyObject(this.children_field)?(a.header.hide(),a.header.addClass("invisible")):(a.header.show(),a.header.removeClass("invisible"))}}.bind(this)),this.columns.filter(function(a){return a.header.is(":visible")}).length>1?(this.table.addClass("responsive"),this.table.addClass("responsive-header")):(this.table.removeClass("responsive"),this.table.removeClass("responsive-header")),this.redraw(a,b)},construct:function(a,b,c){var d=this.tbody;c||(this.rows=[],this.tbody=jQuery("<tbody/>"));var e=this.rows.length,f=function(c,d,e){var f;f=this.editable?Sao.View.Tree.RowEditable:Sao.View.Tree.Row;var g=new f(this,c,this.rows.length);this.rows.push(g),g.construct(a,b)};this.screen.group.slice(e,this.display_size).forEach(f.bind(this)),this.display_size>=this.screen.group.length?this.more.hide():this.more.show(),c||d.replaceWith(this.tbody)},redraw:function(b,c){return a(this.rows,b,c)},switch_:function(a){this.screen.row_activate()},select_changed:function(a){var b=this.screen.current_record;if(this.screen.set_current_record(a),this.editable&&b){var c=function(){this.screen.set_current_record(b),this.set_cursor()}.bind(this);this.screen.group.parent||b===a?b!==a&&this.screen.attributes.pre_validate&&b.pre_validate().then(function(a){a||c()}):b.validate(this.get_fields()).then(function(a){a?b.save().fail(c):c()})}},selected_records:function(){if(this.selection_mode==Sao.common.SELECTION_NONE)return[];var a=[],b=function(c){c.is_selected()&&a.push(c.record),c.rows.forEach(b)};return this.rows.forEach(b),this.selection.prop("checked")&&!this.selection.prop("indeterminate")&&this.screen.group.slice(this.rows.length).forEach(function(b){a.push(b)}),a},selection_changed:function(){var a=this.selection.prop("checked"),b=function(c){c.set_selection(a),c.rows.forEach(b)};this.rows.forEach(b),a&&this.rows[0]?this.select_changed(this.rows[0].record):this.select_changed(null)},update_selection:function(){if(!this.selection.prop("checked")){var a=this.selected_records();this.selection.prop("indeterminate",!1),jQuery.isEmptyObject(a)?this.selection.prop("checked",!1):a.length==this.tbody.children().length&&this.display_size>=this.screen.group.length?this.selection.prop("checked",!0):(this.selection.prop("indeterminate",!0),this.selection.prop("checked",!0))}},get_selected_paths:function(){function a(c,d){var e,f,g,h;for(e=0,g=c.rows.length;g>e;e++)f=c.rows[e],h=d.concat([f.record.id]),f.is_selected()&&b.push(h),a(f,h)}var b=[];return a(this,[]),b},get_expanded_paths:function(a,b){var c,d,e,f,g;void 0===a&&(a=[]),void 0===b&&(b=[]),d=[],e=this.find_row(a),f=e?e.rows:this.rows;for(var h=0,i=this.n_children(e);i>h;h++)g=a.concat([h]),e=f[h],e&&e.is_expanded()&&(c=b.concat(e.record.id),d.push(c),d=d.concat(this.get_expanded_paths(g,c)));return d},find_row:function(a){for(var b,c=null,d=this.rows,e=0,f=a.length;f>e;e++){if(b=a[e],!d||b>=d.length)return null;if(c=d[b],d=c.rows,!this.children_field)break}return c},n_children:function(a){return a&&this.children_field?a.record._values[this.children_field].length:this.rows.length},set_cursor:function(a,b){var c,d,e,f,g,h,i,j;if(this.screen.current_record){for(d=null,c=0;c<this.rows.length;c++)if(e=this.rows[c].record_to_path(this.screen.current_record)){e.unshift(c),d=e;break}f=null,d?(h=d[0],i=d.slice(1),i.length>0&&this.rows[h].expand_to_path(i),f=this.find_row(d)):this.rows.length>0&&(f=this.rows[0]),f&&(g=f.next_column(null,a),null!==g&&(j=f._get_column_td(g),this.editable?(j.triggerHandler("click"),a?j.triggerHandler("click"):j.find(":input,[tabindex=0]").focus()):j.find(":input,[tabindex=0]").focus()))}}}),Sao.View.Tree.Row=Sao.class_(Object,{init:function(a,b,c,d){this.tree=a,this.rows=[],this.record=b,this.parent_=d,this.children_field=a.children_field,this.expander=null;var e=[];d&&(e=jQuery.extend([],d.path.split("."))),e.push(c),this.path=e.join("."),this.el=jQuery("<tr/>")},is_expanded:function(){return this.path in this.tree.expanded},get_last_child:function(){return this.children_field&&this.is_expanded()&&!jQuery.isEmptyObject(this.rows)?this.rows[this.rows.length-1].get_last_child():this},get_id_path:function(){return this.parent_?this.parent_.get_id_path().concat([this.record.id]):[this.record.id]},build_widgets:function(){var a=jQuery("<table/>");a.css("width","100%");var b=jQuery("<tr/>");return a.append(b),[a,b]},construct:function(a,b){a=a||[],b=b||[];for(var c=this.el[0];c.firstChild;)c.removeChild(c.firstChild);var d;this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(d=jQuery("<td/>"),this.el.append(d),this.selection=jQuery("<input/>",{type:"checkbox","class":"selection"}),this.selection.change(this.selection_changed.bind(this)),d.append(this.selection));for(var e=this.path.split(".").length,f=0;f<this.tree.columns.length;f++){var g=this.tree.columns[f];d=jQuery("<td/>",{"data-title":g.attributes.string+Sao.i18n.gettext(": ")}).append(jQuery("<div/>",{"aria-hidden":!0})),d.css("overflow","hidden"),d.on("click keypress",{column:f,td:d},Sao.common.click_press(this.select_row.bind(this),!0)),this.tree.editable?(g.attributes.required&&d.addClass("required"),g.attributes.readonly||d.addClass("editable")):d.dblclick(this.switch_row.bind(this));var h=this.build_widgets(),i=h[0],j=h[1];if(d.append(i),0===f&&this.children_field){var k="glyphicon-plus";(this.is_expanded()||~b.indexOf(this.record.id))&&(k="glyphicon-minus"),this.expander=jQuery("<span/>",{"class":"glyphicon "+k,tabindex:0}),this.expander.html(" "),this.expander.css("margin-left",e-1+"em"),this.expander.css("float","left"),this.expander.on("click keypress",Sao.common.click_press(this.toggle_row.bind(this))),j.append(jQuery("<td/>",{"class":"expander"}).append(this.expander).css("width",1))}var l;if(g.prefixes)for(l=0;l<g.prefixes.length;l++){g.prefixes[l];j.append(jQuery("<td/>",{"class":"prefix"}).css("width",1))}if(j.append(jQuery("<td/>",{"class":"widget"})),g.suffixes)for(l=0;l<g.suffixes.length;l++){g.suffixes[l];j.append(jQuery("<td/>",{"class":"suffix"}).css("width",1))}this.el.append(d)}if(this.parent_){var m=this.parent_.get_last_child();m.el.after(this.el)}else this.tree.tbody.append(this.el);var n=this.get_id_path();(this.is_expanded()||Sao.common.contains(b,n))&&(this.tree.expanded[this.path]=this,this.expand_children(a,b))},_get_column_td:function(a,b){b=b||this.el;var c=0;return this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(c+=1),jQuery(b.children()[a+c])},redraw:function(b,c){b=b||[],c=c||[];for(var d=function(){jQuery.isEmptyObject(this.record.field_get(this.children_field))&&this.expander.css("visibility","hidden")},e=this.tree.thead.is(":visible"),f=0;f<this.tree.columns.length;f++){0===f&&this.children_field&&this.record.load(this.children_field).done(d.bind(this));var g,h=this.tree.columns[f],i=this._get_column_td(f),j=i.find("tr");if(h.prefixes)for(var k=0;k<h.prefixes.length;k++){var l=h.prefixes[k],m=jQuery(j.children(".prefix")[k]);g=m.children(),g.length?l.render(this.record,g):m.html(l.render(this.record))}var n=j.children(".widget");if(g=n.children(),g.length?h.render(this.record,g):n.html(h.render(this.record)),h.suffixes)for(var o=0;o<h.suffixes.length;o++){var p=h.suffixes[o],q=jQuery(j.children(".suffix")[o]);g=q.children(),g.length?p.render(this.record,g):q.html(p.render(this.record))}h.header.is(":hidden")&&e||"none"==h.header.css("display")?(i.hide(),i.addClass("invisible")):(i.show(),i.removeClass("invisible"))}var r=this.get_id_path();this.set_selection(Sao.common.contains(b,r)),this.is_expanded()||Sao.common.contains(c,r)?(this.tree.expanded[this.path]=this,!this.record._values[this.children_field]||this.record._values[this.children_field].length>0&&0===this.rows.length?this.expand_children(b,c):a(this.rows,b,c),this.expander&&this.update_expander(!0)):this.expander&&this.update_expander(!1),this.record.deleted()||this.record.removed()?this.el.css("text-decoration","line-through"):this.el.css("text-decoration","inherit")},toggle_row:function(){return this.is_expanded()?(this.update_expander(!1),delete this.tree.expanded[this.path],this.collapse_children()):(this.update_expander(!0),this.tree.expanded[this.path]=this,this.expand_children()),!1},update_expander:function(a){a?(this.expander.removeClass("glyphicon-plus"),this.expander.addClass("glyphicon-minus")):(this.expander.removeClass("glyphicon-minus"),this.expander.addClass("glyphicon-plus"))},collapse_children:function(){this.rows.forEach(function(a,b,c){a.collapse_children();var d=a.el[0];d.parentNode.removeChild(d)}),this.rows=[]},expand_children:function(b,c){var d=function(){if(jQuery.isEmptyObject(this.rows)){var d=[],e=function(a,e,f){var g=new this.Class(this.tree,a,e,this);g.construct(b,c),this.rows.push(g),d.push(g)},f=this.record.field_get_client(this.children_field);f.forEach(e.bind(this)),a(d,b,c)}};return this.record.load(this.children_field).done(d.bind(this))},switch_row:function(){window.getSelection?window.getSelection().empty?window.getSelection().empty():window.getSelection().removeAllRanges&&window.getSelection().removeAllRanges():document.selection&&document.selection.empty(),(this.tree.selection_mode==Sao.common.SELECTION_NONE||(this.set_selection(!0),this.selection_changed(),this.is_selected()))&&this.tree.switch_(this.path)},select_row:function(a){this.tree.selection_mode==Sao.common.SELECTION_NONE?(this.tree.select_changed(this.record),this.switch_row()):(a.ctrlKey||this.tree.selection_mode!=Sao.common.SELECTION_SINGLE||this.tree.rows.forEach(function(a){a.set_selection(!1)}.bind(this)),this.set_selection(!this.is_selected()),this.selection_changed());var b=a.data.td,c=a.data.column;b.on("click keypress",{column:c,td:b},Sao.common.click_press(this.select_row.bind(this),!0))},is_selected:function(){return this.tree.selection_mode==Sao.common.SELECTION_NONE?!1:this.selection.prop("checked")},set_selection:function(a){this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(this.selection.prop("checked",a),a||this.tree.selection.prop("checked",!1))},selection_changed:function(){var a=this.is_selected();this.set_selection(a),a?this.tree.select_changed(this.record):this.tree.select_changed(this.tree.selected_records()[0]||null),this.tree.update_selection()},record_to_path:function(a){var b,c;if(a==this.record)return[];for(b=0;b<this.rows.length;b++)if(c=this.rows[b].record_to_path(a))return c.unshift(b),c},expand_to_path:function(a){var b,c;b=a[0],c=a.slice(1),c.length>0&&this.rows[b].expand_children().done(function(){this.rows[b].expand_to_path(c)}.bind(this))},next_column:function(a,b,c){var d,e,f,g,h,i;for(c=c||1,null===a&&c>0?a=-1:null===a&&(a=0),h=0,d=0;d<this.tree.columns.length;d++)if(h=(a+c*(d+1))%this.tree.columns.length,0>h&&(h+=this.tree.columns.length),g=this.tree.columns[h],i=g.field.get_state_attrs(this.record),f=i.invisible,g.header.is(":hidden")&&(f=!0),e=b?g.attributes.readonly||i.readonly:!1,!f&&!e)return h}}),Sao.View.Tree.RowEditable=Sao.class_(Sao.View.Tree.Row,{init:function(a,b,c,d){Sao.View.Tree.RowEditable._super.init.call(this,a,b,c,d),this.edited_column=null},redraw:function(a,b){var c,d,e,f,g;for(Sao.View.Tree.RowEditable._super.redraw.call(this,a,b),c=0;c<this.tree.columns.length;c++)e=this._get_column_td(c),d=e.find("tr"),f=jQuery(d.children(".widget-editable")).data("widget"),f&&(g=this.record.model.fields[f.field_name],f.display(this.record,g))},select_row:function(a){function b(a,d){var e,f;for(e=0;e<a.length;e++)f=a[e],f.is_selected()&&(c=f),f!=d&&f.set_selection(!1),b(f.rows,d)}var c,d,e,f,g;b(this.tree.rows,this),this.selection_changed();var h;h=c&&c!=this&&!this.tree.screen.group.parent?c.record.save():jQuery.when(),h.done(function(){if(c&&null!==c.edited_column){d=c.get_active_td(),d.on("click keypress",{td:d,column:c.edited_column},Sao.common.click_press(c.select_row.bind(c),!0));var b=this.tree.columns[c.edited_column];c.get_static_el().html(b.render(c.record)).show(),c.empty_editable_el()}var h=this.is_selected(),i=a.data.column,j=this.tree.columns[i],k=j.field.get_state_attrs(this.record),l=j.attributes.readonly||k.readonly;if(h&&!l){this.edited_column=i,e=this.get_active_td();var m=j.attributes,n=Sao.View.editabletree_widget_get(m.widget);g=new n(m.name,this.tree.screen.model,m),g.view=this.tree,g.el.on("focusin",function(){jQuery(this).parents(".treeview td").css("overflow","visible")}),g.el.on("focusout",function(){jQuery(this).parents(".treeview td").css("overflow","hidden")});var o=this.get_editable_el();o.append(g.el),o.data("widget",g),g.el.on("keydown",this.key_press.bind(this)),f=this.record.model.fields[g.field_name],g.display(this.record,f),this.get_static_el().hide(),this.get_editable_el().show(),g.el.focus()}else if(!h){this.set_selection(!0),this.selection_changed();var p=a.data.td;p.on("click keypress",{column:i,td:p},Sao.common.click_press(this.select_row.bind(this),!0))}}.bind(this))},get_static_el:function(){var a=this.get_active_td();return a.find(".widget")},get_editable_el:function(){var a=this.get_active_td(),b=a.find(".widget-editable");return b.length||(b=jQuery("<td/>",{"class":"widget-editable"}).insertAfter(a.find(".widget"))),b},empty_editable_el:function(){var a;a=this.get_editable_el(),a.empty(),a.data("widget",null),this.edited_column=null},get_active_td:function(){return this._get_column_td(this.edited_column)},key_press:function(a){var b,c,d,e,f;if(a.which==Sao.common.TAB_KEYCODE||a.which==Sao.common.UP_KEYCODE||a.which==Sao.common.DOWN_KEYCODE||a.which==Sao.common.ESC_KEYCODE||a.which==Sao.common.RETURN_KEYCODE){var g=this.tree.columns[this.edited_column];if(g.field.validate(this.record))if(a.which==Sao.common.TAB_KEYCODE){var h=1;a.shiftKey&&(h=-1),a.preventDefault(),d=this.next_column(this.edited_column,!0,h),null!==d&&window.setTimeout(function(){var a=this._get_column_td(d);a.triggerHandler("click",{column:d,td:a})}.bind(this),0)}else if(a.which==Sao.common.UP_KEYCODE||a.which==Sao.common.DOWN_KEYCODE)f=a.which==Sao.common.UP_KEYCODE?this.el.prev("tr"):this.el.next("tr"),c=this.edited_column,this.record.validate(this.tree.get_fields()).then(function(a){if(a){if(this.tree.screen.attributes.pre_validate)return this.record.pre_validate().fail(function(){f=null});if(!this.tree.screen.model.parent)return this.record.save().fail(function(){f=null})}else{f=null;var b=this.record.invalid_fields();for(e=0;e<this.tree.columns.length;e++){var d=this.tree.columns[e];d.attributes.name in b&&(c=e)}}}.bind(this)).then(function(){window.setTimeout(function(){this._get_column_td(c,f).trigger("click").trigger("click")}.bind(this),0)}.bind(this));else if(a.which==Sao.common.ESC_KEYCODE)this.get_static_el().show(),b=this.get_active_td(),b.on("click keypress",{column:this.edited_column,td:b},Sao.common.click_press(this.select_row.bind(this),!0)),this.empty_editable_el();else if(a.which==Sao.common.RETURN_KEYCODE){var i=function(a){var b=this._get_column_td(this.edited_column,a);b.triggerHandler("click"),b.triggerHandler("click")}.bind(this);if(f="bottom"==this.tree.attributes.editable?this.el.next("tr"):this.el.prev("tr"),f.length)i(f);else{var j,k=this.tree.screen.group,l=Sao.common.MODELACCESS.get(this.tree.screen.model_name),m=null!==this.tree.screen.size_limit&&k.length>=this.tree.screen.size_limit;j=!l.create||m?jQuery.when():this.tree.screen.new_(),j.done(function(){var a,b=this.tree.tbody.children("tr");a="bottom"==this.tree.attributes.editable?b.last():b.first(),i(a)}.bind(this))}}}}}),Sao.View.Tree.Affix=Sao.class_(Object,{init:function(a,b){this.attributes=a,this.protocol=b||null,this.icon=a.icon,this.protocol&&!this.icon&&(this.icon="tryton-web-browser")},get_cell:function(){var a;return this.protocol?(a=jQuery("<a/>",{target:"_new"}),a.append(jQuery("<img/>")),a.click({cell:a},this.clicked.bind(this))):this.icon?a=jQuery("<img/>"):(a=jQuery("<span/>"),a.attr("tabindex",0)),a.addClass("column-affix"),a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){var c,d,e=a.model.fields[this.attributes.name],f=e.get_state_attrs(a).invisible;if(f?b.hide():b.show(),this.protocol){if(c=e.get(a),!jQuery.isEmptyObject(c))switch(this.protocol){case"email":c="mailto:"+c;break;case"callto":c="callto:"+c;break;case"sip":c="sip:"+c}b.attr("src",c)}if(this.icon){if(this.icon in a.model.fields){var g=a.model.fields[this.icon];c=g.get_client(a)}else c=this.icon;d=Sao.common.ICONFACTORY.register_icon(c),d.done(function(a){var c;c=b.children("img").length?b.children("img"):b,c.attr("src",a)}.bind(this))}else c=this.attributes.string||"",c||(c=e.get_client(a)||""),b.text(c)}.bind(this)),b},clicked:function(a){a.preventDefault(),window.open(a.data.cell.attr("src"),"_blank")}}),Sao.View.Tree.CharColumn=Sao.class_(Object,{class_:"column-char",init:function(a,b){this.type="field",this.model=a,this.field=a.fields[b.name],this.attributes=b,this.prefixes=[],this.suffixes=[],this.header=null},get_cell:function(){var a=jQuery("<div/>",{"class":this.class_,tabindex:0});return a},update_text:function(a,b){a.text(this.field.get_client(b))},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){this.update_text(b,a),this.field.set_state(a);var c=this.field.get_state_attrs(a);c.invisible?b.hide():b.show()}.bind(this)),b}}),Sao.View.Tree.TextColum=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-text"}),Sao.View.Tree.IntegerColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-integer",init:function(a,b){Sao.View.Tree.IntegerColumn._super.init.call(this,a,b),this.factor=Number(b.factor||1)},get_cell:function(){return Sao.View.Tree.IntegerColumn._super.get_cell.call(this)},update_text:function(a,b){a.text(this.field.get_client(b,this.factor))}}),Sao.View.Tree.FloatColumn=Sao.class_(Sao.View.Tree.IntegerColumn,{class_:"column-float"}),Sao.View.Tree.BooleanColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-boolean",get_cell:function(){return jQuery("<input/>",{type:"checkbox",disabled:!0,"class":this.class_,tabindex:0})},update_text:function(a,b){a.prop("checked",this.field.get(b))}}),Sao.View.Tree.Many2OneColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-many2one"}),Sao.View.Tree.One2OneColumn=Sao.class_(Sao.View.Tree.Many2OneColumn,{class_:"column-one2one"}),Sao.View.Tree.SelectionColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-selection",init:function(a,b){Sao.View.Tree.SelectionColumn._super.init.call(this,a,b),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a)},update_selection:function(a,b){Sao.common.selection_mixin.update_selection.call(this,a,this.field,b)},update_text:function(a,b){this.update_selection(b,function(){for(var c,d,e=this.field.get(b),f=!1,g=0,h=this.selection.length;h>g;g++)if(this.selection[g][0]===e){f=!0,d=this.selection[g][1];break}c=f?jQuery.when(d):Sao.common.selection_mixin.get_inactive_selection.call(this,e).then(function(a){return a[1]}),c.done(function(b){a.text(b)}.bind(this))}.bind(this))}}),Sao.View.Tree.ReferenceColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-reference",init:function(a,b){Sao.View.Tree.ReferenceColumn._super.init.call(this,a,b),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a)},update_selection:function(a,b){Sao.common.selection_mixin.update_selection.call(this,a,this.field,b)},update_text:function(a,b){this.update_selection(b,function(){var c,d,e=this.field.get_client(b);if(e?(c=e[0],d=e[1]):(c="",d=""),c){for(var f=0,g=this.selection.length;g>f;f++)if(this.selection[f][0]===c){c=this.selection[f][1];break}a.text(c+","+d)}else a.text(d)}.bind(this))}}),Sao.View.Tree.DateColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-date",update_text:function(a,b){var c=this.field.get_client(b),d=this.field.date_format(b);a.text(Sao.common.format_date(d,c))}}),Sao.View.Tree.TimeColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-time",update_text:function(a,b){var c=this.field.get_client(b);a.text(Sao.common.format_time(this.field.time_format(b),c))}}),Sao.View.Tree.TimeDeltaColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-timedelta"}),Sao.View.Tree.One2ManyColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-one2many",update_text:function(a,b){a.text("( "+this.field.get_client(b).length+" )")}}),Sao.View.Tree.Many2ManyColumn=Sao.class_(Sao.View.Tree.One2ManyColumn,{class_:"column-many2many"}),Sao.View.Tree.BinaryColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-binary",update_text:function(a,b){var c;c=this.field.get_size?this.field.get_size(b):this.field.get(b).length,a.text(Sao.common.humanize(c))}}),Sao.View.Tree.ImageColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-image",get_cell:function(){var a=jQuery("<img/>",{"class":this.class_,tabindex:0});return a.css("width","100%"),a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){var c=this.field.get_client(a);c=c?c>Sao.common.BIG_IMAGE_SIZE?jQuery.when(null):this.field.get_data(a):jQuery.when(null),c.done(function(a){var c,d;a?(d=new Blob([a]),c=window.URL.createObjectURL(d)):c=null,b.attr("src",c)}.bind(this))}.bind(this)),b}}),Sao.View.Tree.URLColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-url",render:function(a,b){b=Sao.View.Tree.URLColumn._super.render.call(this,a,b),this.field.set_state(a);var c=this.field.get_state_attrs(a);return c.readonly?b.hide():b.show(),b}}),Sao.View.Tree.ProgressBar=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-progressbar",get_cell:function(){var a=jQuery("<div/>",{"class":this.class_+" progress",tabindex:0}),b=jQuery("<div/>",{"class":"progress-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100}).appendTo(a);return b.css("min-width: 2em"),a},update_text:function(a,b){
-var c=this.field.get_client(b,100);c&&(c=Sao.i18n.gettext("%1%",c));var d=this.field.get(b)||0,e=a.find(".progress-bar");e.attr("aria-valuenow",100*d),e.css("width",100*d+"%"),e.text(c)}}),Sao.View.Tree.ButtonColumn=Sao.class_(Object,{init:function(a,b){this.screen=a,this.type="button",this.attributes=b},render:function(a,b){var c=new Sao.common.Button(this.attributes,b);b||c.el.click([a,c],this.button_clicked.bind(this));var d=jQuery.map(this.screen.model.fields,function(a,b){return"eager"==(a.description.loading||"eager")?b:void 0});return a.load(d[0]).done(function(){c.set_state(a)}),c.el},button_clicked:function(a){var b=a.data[0],c=a.data[1];if(b==this.screen.current_record){var d=b.expr_eval(this.attributes.states||{});if(!d.invisible&&!d.readonly){c.el.prop("disabled",!0);try{this.screen.button(this.attributes)}finally{c.el.prop("disabled",!1)}}}}}),Sao.View.editabletree_widget_get=function(a){switch(a){case"char":case"text":case"url":case"email":case"callto":case"sip":return Sao.View.EditableTree.Char;case"date":return Sao.View.EditableTree.Date;case"time":return Sao.View.EditableTree.Time;case"timedelta":return Sao.View.EditableTree.TimeDelta;case"integer":case"biginteger":return Sao.View.EditableTree.Integer;case"float":case"numeric":return Sao.View.EditableTree.Float;case"selection":return Sao.View.EditableTree.Selection;case"boolean":return Sao.View.EditableTree.Boolean;case"many2one":return Sao.View.EditableTree.Many2One;case"reference":return Sao.View.EditableTree.Reference;case"one2one":return Sao.View.EditableTree.One2One;case"one2many":case"many2many":return Sao.View.EditableTree.One2Many;case"binary":return Sao.View.EditableTree.Binary}},Sao.View.EditableTree={},Sao.View.EditableTree.editable_mixin=function(a){var b=function(a){a.which!=Sao.common.TAB_KEYCODE&&a.which!=Sao.common.UP_KEYCODE&&a.which!=Sao.common.DOWN_KEYCODE&&a.which!=Sao.common.ESC_KEYCODE&&a.which!=Sao.common.RETURN_KEYCODE||this.focus_out()};a.el.on("keydown",b.bind(a))},Sao.View.EditableTree.Char=Sao.class_(Sao.View.Form.Char,{class_:"editabletree-char",init:function(a,b,c){Sao.View.EditableTree.Char._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Date=Sao.class_(Sao.View.Form.Date,{class_:"editabletree-date",init:function(a,b,c){Sao.View.EditableTree.Date._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Time=Sao.class_(Sao.View.Form.Time,{class_:"editabletree-time",init:function(a,b,c){Sao.View.EditableTree.Time._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.TimeDelta=Sao.class_(Sao.View.Form.TimeDelta,{class_:"editabletree-timedelta",init:function(a,b,c){Sao.View.EditableTree.TimeDelta._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Integer=Sao.class_(Sao.View.Form.Integer,{class_:"editabletree-integer",init:function(a,b,c){Sao.View.EditableTree.Integer._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Float=Sao.class_(Sao.View.Form.Float,{class_:"editabletree-float",init:function(a,b,c){Sao.View.EditableTree.Float._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Selection=Sao.class_(Sao.View.Form.Selection,{class_:"editabletree-selection",init:function(a,b,c){Sao.View.EditableTree.Selection._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Boolean=Sao.class_(Sao.View.Form.Boolean,{class_:"editabletree-boolean",init:function(a,b,c){Sao.View.EditableTree.Boolean._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Many2One=Sao.class_(Sao.View.Form.Many2One,{class_:"editabletree-many2one",init:function(a,b,c){Sao.View.EditableTree.Many2One._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.Many2One._super.key_press.call(this,a)}}),Sao.View.EditableTree.Reference=Sao.class_(Sao.View.Form.Reference,{class_:"editabletree-reference",init:function(a,b,c){Sao.View.EditableTree.Reference._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.Reference._super.key_press.call(this,a)}}),Sao.View.EditableTree.One2One=Sao.class_(Sao.View.Form.One2One,{class_:"editabletree-one2one",init:function(a,b,c){Sao.View.EditableTree.One2One._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.One2One._super.key_press.call(this,a)}}),Sao.View.EditableTree.One2Many=Sao.class_(Sao.View.EditableTree.Char,{class_:"editabletree-one2many",init:function(a,b,c){Sao.View.EditableTree.One2Many._super.init.call(this,a,b,c)},display:function(a,b){a?this.el.val("("+b.get_client(a).length+")"):this.el.val("")},key_press:function(a){a.which==Sao.common.TAB_KEYCODE&&this.focus_out()},set_value:function(a,b){}}),Sao.View.EditableTree.Binary=Sao.class_(Sao.View.Form.Binary,{class_:"editabletree-binary",init:function(a,b,c){Sao.View.EditableTree.Binary._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}})}(),function(){"use strict";Sao.View.Graph=Sao.class_(Sao.View,{init:function(a,b){Sao.View.Graph._super.init.call(this,a,b),this.view_type="graph",this.el=jQuery("<div/>",{"class":"graph"}),this.widgets={},this.widget=this.parse(b.children()[0]),this.widgets.root=this.widget,this.el.append(this.widget.el)},parse:function(a){var b,c,d,e,f,g,h,i=null,j=[],k=function(a){for(var b,c={},d=0,e=a.attributes.length;e>d;d++)b=a.attributes[d],c[b.name]=b.value;return c};for(e=0,f=a.children.length;f>e;e++)switch(d=a.children[e],d.tagName){case"x":for(g=0,h=d.children.length;h>g;g++)i=k(d.children[g]),b=this.screen.model.fields[i.name],i.type=b.description.type,i.string||(i.string=b.description.string);break;case"y":for(g=0,h=d.children.length;h>g;g++)c=k(d.children[g]),c.string||"#"==c.name||(b=this.screen.model.fields[c.name],c.string=b.description.string),j.push(c)}var l;switch(this.attributes.type){case"hbar":l=Sao.View.Graph.HorizontalBar;break;case"line":l=Sao.View.Graph.Line;break;case"pie":l=Sao.View.Graph.Pie;break;default:l=Sao.View.Graph.VerticalBar}return new l(this,i,j)},display:function(){return this.widget.display(this.screen.group)}}),Sao.View.Graph.Chart=Sao.class_(Object,{_chart_type:void 0,init:function(a,b,c){this.view=a,this.xfield=b,this.yfields=c,this.el=jQuery("<div/>"),this.el.uniqueId()},update_data:function(a){var b,c,d,e,f,g,h,i={};this.ids={},i.columns=[["labels"]],i.names={};var j={},k=[this.xfield.name];for(e=0,f=this.yfields.length;f>e;e++)c=this.yfields[e],i.columns.push([c.name]),i.names[c.name]=c.string,j[c.key||c.name]=e+1,k.push(c.name);var l=[],m=function(e){return function(){b=a[e];var f=b.field_get_client(this.xfield.name);f&&(f.isDate||f.isDateTime)&&(f=f.toDate()),i.columns[0][e+1]=f,this._add_id(f,b.id);var k;for(g=0,h=this.yfields.length;h>g;g++){if(c=this.yfields[g],d=c.key||c.name,k=i.columns[j[d]],c.domain){var l=jQuery.extend({},Sao.session.current_session.context);l.context=l,l._user=Sao.session.current_session.user_id;for(var m in a.model.fields)l[m]=b.field_get(m);var n=new Sao.PYSON.Decoder(l);if(!n.decode(c.domain)){k[e+1]=0;continue}}if("#"==c.name)k[e+1]=1;else{var o=b.field_get(c.name);o&&o.isTimeDelta&&(o=o.asSeconds()),k[e+1]=o||0}}}.bind(this)}.bind(this),n=function(a){return function(b){l.push(a.load(b))}},o=[];for(e=0,f=a.length;f>e;e++){for(b=a[e],k.forEach(n(a[e])),g=0,h=i.columns.length;h>g;g++)i.columns[g].push(void 0);o.push(jQuery.when.apply(jQuery,l).then(m(e)))}return jQuery.when.apply(jQuery,o).then(function(){return i})},_add_id:function(a,b){a in this.ids||(this.ids[a]=[]),this.ids[a].push(b)},display:function(a){var b=this.update_data(a);return b.done(function(a){c3.generate(this._c3_config(a))}.bind(this)),b},_c3_config:function(a){var b={};b.bindto="#"+this.el.attr("id"),b.data=a,b.data.type=this._chart_type,b.data.x="labels",b.data.onclick=this.action.bind(this);var c=this.xfield.type;if("date"==c||"datetime"==c){var d,e,f;e=this.view.screen.context.date_format||"%x",f="%X",d="datetime"==c?function(a){return Sao.common.format_datetime(e,f,moment(a))}:function(a){return Sao.common.format_date(e,moment(a))},b.axis={x:{type:"timeseries",tick:{format:d}}}}else b.axis={x:{type:"category"}};for(var g={},h=0;h<this.yfields.length;h++){var i=this.yfields[h];i.color&&(g[i.name]=i.color)}return b.data.color=function(a,b){var c=b.id||b;return g[c]||a},b},action:function(a,b){var c=this.ids[this._action_key(a)],d=jQuery.extend({},this.view.screen.context);delete d.active_ids,delete d.active_id,Sao.Action.exec_keyword("graph_open",{model:this.view.screen.model_name,id:c[0],ids:c},d,!1)},_action_key:function(a){return a.x}}),Sao.View.Graph.VerticalBar=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"bar"}),Sao.View.Graph.HorizontalBar=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"bar",_c3_config:function(a){var b=Sao.View.Graph.HorizontalBar._super._c3_config.call(this,a);b.axis.rotated=!0}}),Sao.View.Graph.Line=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"line"}),Sao.View.Graph.Pie=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"pie",_c3_config:function(a){var b,c,d,e,f=Sao.View.Graph.Pie._super._c3_config.call(this,a),g=[],h={};for(b=0,c=a.columns.length;c>b;b++)"labels"==a.columns[b][0]?d=a.columns[b].slice(1):e=a.columns[b].slice(1);delete f.axis,delete f.data.x;var i,j=this.xfield.type;if("date"==j||"datetime"==j){var k=this.view.screen.context.date_format||"%x",l=k+" %X";i="datetime"==j?function(a){return Sao.common.format_datetime(l,a)}:function(a){return Sao.common.format_date(k,a)}}var m;for(b=0,c=d.length;c>b;b++)m=d[b],i&&(m=i(m)),g.push([b,e[b]]),h[b]=m;return f.data.columns=g,f.data.names=h,f},_add_id:function(a,b){var c=this.xfield.type;if("date"==c||"datetime"==c){var d=this.view.screen.context.date_format||"%x",e=d+" %X";a="datetime"==c?Sao.common.format_datetime(e,a):Sao.common.format_date(d,a)}Sao.View.Graph.Pie._super._add_id.call(this,a,b)},_action_key:function(a){return a.id}})}(),function(){"use strict";Sao.View.Calendar=Sao.class_(Sao.View,{init:function(a,b){Sao.View.Calendar._super.init.call(this,a,b),this.processing=!0,this.view_type="calendar",this.el=jQuery("<div/>",{"class":"calendar"});var c=Sao.i18n.getlang();c=c.slice(0,2);var d="month";"week"==this.attributes.mode&&(d=this.get_week_view()),this.el.fullCalendar({defaultView:d,header:{left:"prev,next",center:"title",right:" month,"+this.get_week_view()},timeFormat:"H:mm",events:this.get_events.bind(this),locale:c,buttonIcons:!1,eventRender:this.event_render.bind(this),eventResize:this.event_resize.bind(this),eventDrop:this.event_drop.bind(this),eventClick:this.event_click.bind(this),dayClick:this.day_click.bind(this)}),this.fields=[],b.find("calendar").children().each(function(a,b){"field"==b.tagName&&this.fields.push(b.attributes.name.value)}.bind(this)),this.el.fullCalendar("changeView",d)},get_colors:function(a){var b={};return b.text_color="black",this.attributes.color&&(b.text_color=a.field_get(this.attributes.color)),b.background_color="lightblue",this.attributes.background_color&&(b.background_color=a.field_get(this.attributes.background_color)),b},display:function(){this.el.fullCalendar("render"),this.processing||this.el.fullCalendar("refetchEvents")},insert_event:function(a){var b=this.screen.model.fields[this.fields[0]].get_client(a),c=a.field_get_client(this.attributes.dtstart),d=null;this.attributes.dtend&&(d=a.field_get_client(this.attributes.dtend));for(var e=!0,f=[],g=1;g<this.fields.length;g++)f.push(this.screen.model.fields[this.fields[g]].get_client(a));if(f=f.join("\n"),c){if(d&&d.isDateTime?e=!1:d&&!d.isSame(c)&&"calendar"==this.screen.current_view.view_type&&d.add(1,"day"),d&&c>d)return;var h=this.get_colors(a),i={title:b,start:c,end:d,allDay:e,editable:!0,color:h.background_color,textColor:h.text_color,record:a,description:f};this.events.push(i)}},get_events:function(a,b,c,d){this.processing=!0,this.start=Sao.DateTime(a.utc()),this.end=Sao.DateTime(b.utc());var e=jQuery.when();if("form"!=this.screen.current_view.view_type){var f=this.screen.screen_container.get_text();e=this.screen.search_filter(f)}this.events=[];var g=[];e.then(function(){return this.screen.group.forEach(function(a){var b=[];this.fields.forEach(function(c){b.push(a.load(c))});var c=jQuery.when.apply(jQuery,b).then(function(){this.insert_event(a)}.bind(this));g.push(c)}.bind(this)),jQuery.when.apply(jQuery,g).then(function(){d(this.events)}.bind(this)).always(function(){this.processing=!1}.bind(this))}.bind(this))},get_week_view:function(){return"datetime"==this.screen.model.fields[this.attributes.dtstart].description.type?"agendaWeek":"basicWeek"},event_click:function(a,b,c){this.clicked_event||(this.clicked_event=!0,this.screen.set_current_record(a.record),this.screen.switch_view().always(function(){this.clicked_event=!1}.bind(this)))},event_drop:function(a,b,c,d,e,f){var g=this.attributes.dtstart,h=this.attributes.dtend,i=a.record,j=(i.group,i.field_get(g)),k=j;h&&(k=i.field_get(h));var l=a.start,m=a.end;m!=j&&m||(m=l),j.isDateTime?(m=Sao.DateTime(m.format()).utc(),l=Sao.DateTime(l.format()).utc()):j.isSame(k)||(m.subtract(1,"day"),this.el.fullCalendar("refetchEvents")),l>=j?(h&&i.field_set_client(h,m),i.field_set_client(g,l)):(i.field_set_client(g,l),h&&i.field_set_client(h,m)),i.save()},event_resize:function(a,b,c,d,e,f){var g=this.attributes.dtend,h=a.record,i=(h.group,h.field_get(g)),j=a.end;i.isDateTime===!0?j=Sao.DateTime(j.format()).utc():(j.subtract(1,"day"),this.el.fullCalendar("refetchEvents")),j!=i&&j||(j=i),h.field_set_client(g,j),h.save()},event_render:function(a,b,c){this.screen.model.fields.date&&"calendar"==this.screen.view_name&&b.find(".fc-time").remove(),b.append(a.description),b.css("white-space","pre");var d=Sao.common.MODELACCESS.get(this.screen.model_name);d.write||(a.editable=!1)},day_click:function(a,b,c){var d=Sao.common.MODELACCESS.get(this.screen.model_name);d.create&&(this.date=a,this.screen.set_current_record(null),this.screen.new_())},current_domain:function(){if(!this.start&&!this.end)return[["id","=",-1]];var a=Sao.DateTime(this.start),b=Sao.DateTime(this.end),c=this.attributes.dtstart,d=this.attributes.dtend||c;return["OR",["AND",[c,">=",a],[c,"<",b]],["AND",[d,">=",a],[d,"<",b]],["AND",[c,"<",a],[d,">",b]]]},get_displayed_period:function(){var a=[];return this.start&&this.end&&a.push(this.start,this.end),a},set_default_date:function(a,b){var c=this.attributes.dtstart;"datetime"==a.model.fields[c].description.type&&(b=Sao.DateTime(b.format()).utc()),a.field_set_client(c,b)}})}(),function(){"use strict";Sao.Action={report_blob_url:void 0},Sao.Action.exec_action=function(a,b,c){function d(a){if(!b.model||!b.ids)return jQuery.when(a);var d=5,e=b.ids.slice(0,d);return Sao.rpc({method:"model."+b.model+".read",params:[e,["rec_name"],c]},Sao.Session.current_session).then(function(c){var e=c.map(function(a){return a.rec_name}).join(Sao.i18n.gettext(", "));return b.ids.length>d&&(e+=Sao.i18n.gettext(",…")),Sao.i18n.gettext("%1 (%2)",a,e)})}c=void 0===c?{}:jQuery.extend({},c);var e=Sao.Session.current_session;"date_format"in c||e.context.locale&&e.context.locale.date&&(c.date_format=e.context.locale.date),b=void 0===b?{}:jQuery.extend({},b),b.action_id=a.id;var f,g={};switch(a.type){case"ir.action.act_window":g.view_ids=!1,g.mode=null,jQuery.isEmptyObject(a.views)?jQuery.isEmptyObject(a.view_id)||(g.view_ids=[a.view_id[0]]):(g.view_ids=[],g.mode=[],a.views.forEach(function(a){g.view_ids.push(a[0]),g.mode.push(a[1])})),void 0===a.pyson_domain&&(a.pyson_domain="[]");var h={active_model:b.model||null,active_id:b.id||null,active_ids:b.ids};h=jQuery.extend(h,e.context);var i=jQuery.extend({},h);i._user=e.user_id,g.context=jQuery.extend({},c,new Sao.PYSON.Decoder(i).decode(a.pyson_context||"{}")),h=jQuery.extend(h,g.context),h=jQuery.extend(h,c);var j=jQuery.extend({},h);j.context=h,j._user=e.user_id;var k=new Sao.PYSON.Decoder(j);return g.domain=k.decode(a.pyson_domain),g.order=k.decode(a.pyson_order),g.search_value=k.decode(a.pyson_search_value||"[]"),g.tab_domain=[],a.domains.forEach(function(a,b){g.tab_domain.push([a[0],k.decode(a[1]),a[2]])}),f=jQuery.when(a.name),g.model=a.res_model||b.res_model,g.res_id=a.res_id||b.res_id,g.context_model=a.context_model,g.context_domain=a.context_domain,g.limit=a.limit,g.icon=a["icon.rec_name"]||"","form_relate"===(a.keyword||"")&&(f=d(a.name)),void f.then(function(a){g.name=a,Sao.Tab.create(g)});case"ir.action.wizard":return g.action=a.wiz_name,g.data=b,g.context=c,g.window=a.window,f=jQuery.when(a.name),"form_action"===(a.keyword||"form_action")&&(f=d(a.name)),void f.done(function(a){g.name=a,Sao.Wizard.create(g)});case"ir.action.report":return g.name=a.report_name,g.data=b,g.direct_print=a.direct_print,g.email_print=a.email_print,g.email=a.email,g.context=c,void Sao.Action.exec_report(g);case"ir.action.url":return void window.open(a.url,"_blank")}},Sao.Action.exec_keyword=function(a,b,c,d,e){void 0===d&&(d=!0),void 0===e&&(e=!1);var f=b.id,g={method:"model.ir.action.keyword.get_keyword",params:[a,[b.model,f],{}]},h=Sao.rpc(g,Sao.Session.current_session),i=function(a){var f={};for(var g in a){var h=a[g];f[h.name.replace(/_/g,"")]=h}var i=Sao.common.selection(Sao.i18n.gettext("Select your action"),f,e);return i.then(function(a){Sao.Action.exec_action(a,b,c)},function(){jQuery.isEmptyObject(f)&&d&&alert(Sao.i18n.gettext("No action defined."))})};return h.pipe(i)},Sao.Action.exec_report=function(a){a.context||(a.context={}),a.email||(a.email={});var b=jQuery.extend({},a.data),c=jQuery.extend({},Sao.Session.current_session.context);jQuery.extend(c,a.context),c.direct_print=a.direct_print,c.email_print=a.email_print,c.email=a.email;var d=Sao.rpc({method:"report."+a.name+".execute",params:[b.ids||[],b,c]},Sao.Session.current_session);d.done(function(a){var b=a[0],c=a[1],d=(a[2],a[3]),e=d+"."+b;Sao.common.download_file(c,e)})},Sao.Action.execute=function(a,b,c,d,e){c?Sao.rpc({method:"model."+c+".search_read",params:[[["action","=",a]],0,1,null,null,d]},Sao.Session.current_session).done(function(a){var f=a[0];if(e){var g={"ir.action.report":"form_report","ir.action.wizard":"form_action","ir.action.act_window":"form_relate"};f.keyword||(f.keyword=g[c])}Sao.Action.exec_action(f,b,d)}):Sao.rpc({method:"model.ir.action.read",params:[[a],["type"],d]},Sao.Session.current_session).done(function(c){Sao.Action.execute(a,b,c[0].type,d,e)})},Sao.Action.evaluate=function(a,b,c){a=jQuery.extend({},a);var d={};return"pyson_email"in a&&(d=c.expr_eval(a.pyson_email),jQuery.isEmptyObject(d)&&(d={})),"subject"in d||(d.subject=a.name.replace(/_/g,"")),a.email=d,a}}(),function(){"use strict";Sao.common={},Sao.common.BACKSPACE_KEYCODE=8,Sao.common.TAB_KEYCODE=9,Sao.common.RETURN_KEYCODE=13,Sao.common.ESC_KEYCODE=27,Sao.common.UP_KEYCODE=38,Sao.common.DOWN_KEYCODE=40,Sao.common.DELETE_KEYCODE=46,Sao.common.F2_KEYCODE=113,Sao.common.F3_KEYCODE=114,Sao.common.SELECTION_NONE=1,Sao.common.SELECTION_SINGLE=2,Sao.common.SELECTION_MULTIPLE=3,Sao.common.BIG_IMAGE_SIZE=Math.pow(10,6),Sao.common.compare=function(a,b){if(a.length!=b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]instanceof Array&&b[c]instanceof Array){if(!Sao.common.compare(a[c],b[c]))return!1}else if(a[c]!=b[c])return!1;return!0},Sao.common.contains=function(a,b){for(var c=0;c<a.length;c++)if(Sao.common.compare(a[c],b))return!0;return!1},Sao.common.intersect=function(a,b){for(var c=0,d=0,e=[];c<a.length&&d<b.length;)a[c]<b[d]?c++:a[c]>b[d]?d++:(e.push(a[c]),c++,d++);return e},Sao.common.click_press=function(a,b){return function c(d){return"keypress"!=d.type||d.which==Sao.common.RETURN_KEYCODE?(b&&jQuery(this).off("click keypress",null,c),a(d)):void 0}},Sao.common.product=function(a,b){b=b||1;for(var c=[],d=0;b>d;)c=c.concat(a),d++;var e=[[]];return c.forEach(function(a){var b=[];e.forEach(function(c){a.forEach(function(a){b.push(c.concat([a]))})}),e=b}),e},Sao.common.selection=function(a,b,c){void 0===c&&(c=!1);var d=jQuery.Deferred();if(jQuery.isEmptyObject(b))return d.fail(),d;var e=Object.keys(b).sort();if(1==e.length&&!c){var f=e[0];return d.resolve(b[f]),d}var g=new Sao.Dialog(a||Sao.i18n.gettext("Your selection:"),"selection-dialog");return e.forEach(function(a,b){jQuery("<div/>",{"class":"checkbox"}).append(jQuery("<label/>").append(jQuery("<input/>",{type:"radio",name:"selection",value:b})).append(" "+a)).appendTo(g.body)}),g.body.find("input").first().prop("checked",!0),jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){g.modal.modal("hide"),d.fail()}).appendTo(g.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){var a=g.body.find("input:checked").attr("value");g.modal.modal("hide"),d.resolve(b[e[a]])}).appendTo(g.footer),g.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),g.modal.modal("show"),d},Sao.common.moment_format=function(a){return a.replace("%a","ddd").replace("%A","dddd").replace("%w","d").replace("%d","DD").replace("%b","MMM").replace("%B","MMMM").replace("%m","MM").replace("%y","YY").replace("%Y","YYYY").replace("%H","HH").replace("%I","hh").replace("%p","A").replace("%M","mm").replace("%S","ss").replace("%f","SSS").replace("%z","ZZ").replace("%Z","zz").replace("%j","DDDD").replace("%U","ww").replace("%W","WW").replace("%c","llll").replace("%x","L").replace("%X","LTS").replace("%","%%")},Sao.common.date_format=function(a){if(jQuery.isEmptyObject(a)&&(a="%Y-%m-%d",Sao.Session.current_session)){var b=Sao.Session.current_session.context;b.locale&&b.locale.date&&(a=b.locale.date)}return Sao.common.moment_format(a)},Sao.common.format_time=function(a,b){return b?b.format(Sao.common.moment_format(a)):""},Sao.common.parse_time=function(a,b){if(jQuery.isEmptyObject(b))return null;var c=function(c){var d=a.indexOf(c);if(~d){var e=parseInt(b.slice(d,d+c.length),10);if(!isNaN(e))return e}return 0};return Sao.Time(c("%H"),c("%M"),c("%S"),c("%f"))},Sao.common.format_date=function(a,b){return b?b.format(Sao.common.moment_format(a)):""},Sao.common.parse_date=function(a,b){var c=moment(b,Sao.common.moment_format(a));return c=c.isValid()?Sao.Date(c.year(),c.month(),c.date()):null},Sao.common.format_datetime=function(a,b,c){return c?c.format(Sao.common.moment_format(a+" "+b)):""},Sao.common.parse_datetime=function(a,b,c){var d=moment(c,Sao.common.moment_format(a+" "+b));return d=d.isValid()?Sao.DateTime(d.year(),d.month(),d.date(),d.hour(),d.minute(),d.second(),d.millisecond()):null},Sao.common.timedelta={},Sao.common.timedelta.DEFAULT_CONVERTER={s:1},Sao.common.timedelta.DEFAULT_CONVERTER.m=60*Sao.common.timedelta.DEFAULT_CONVERTER.s,Sao.common.timedelta.DEFAULT_CONVERTER.h=60*Sao.common.timedelta.DEFAULT_CONVERTER.m,Sao.common.timedelta.DEFAULT_CONVERTER.d=24*Sao.common.timedelta.DEFAULT_CONVERTER.h,Sao.common.timedelta.DEFAULT_CONVERTER.w=7*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta.DEFAULT_CONVERTER.M=30*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta.DEFAULT_CONVERTER.Y=365*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta._get_separator=function(){return{Y:Sao.i18n.gettext("Y"),M:Sao.i18n.gettext("M"),w:Sao.i18n.gettext("w"),d:Sao.i18n.gettext("d"),h:Sao.i18n.gettext("h"),m:Sao.i18n.gettext("m"),s:Sao.i18n.gettext("s")}},Sao.common.timedelta.format=function(a,b){if(!a)return"";b||(b=Sao.common.timedelta.DEFAULT_CONVERTER);var c=[];a=a.asSeconds();var d="";0>a&&(d="-"),a=Math.abs(a),b=Object.keys(b).map(function(a){return[a,b[a]]}),b.sort(function(a,b){return b[1]-a[1]});for(var e,f,g=[],h=0;h<b.length;h++){e=b[h][0],f=b[h][1];var i=Math.floor(a/f);a-=i*f,g.push(i)}for(h=0;h<b.length-3;h++)e=b[h][0],f=g[h],f&&c.push(f+Sao.common.timedelta._get_separator()[e]);if(jQuery(g.slice(-3)).is(function(a,b){return b})||jQuery.isEmptyObject(c)){var j=g.slice(-3,-1);j=("00"+j[0]).slice(-2)+":"+("00"+j[1]).slice(-2),(g.slice(-1)[0]||a)&&(j+=":"+("00"+g.slice(-1)[0]).slice(-2)),c.push(j)}return c=d+c.reduce(function(a,b){return a?a+" "+b:b}),a&&(jQuery(g.slice(-3)).is(function(a,b){return b})||(c+=" "),c+=(""+a.toFixed(6)).slice(1)),c},Sao.common.timedelta.parse=function(a,b){if(!a)return null;b||(b=Sao.common.timedelta.DEFAULT_CONVERTER);var c,d=Sao.common.timedelta._get_separator();for(var e in d)c=d[e],a=a.replace(c,c+" ");for(var f,g=0,h=a.split(" "),i=0;i<h.length;i++){var j=h[i];if(j.contains(":"))for(var k=j.split(":"),l=[b.h,b.m,b.s],m=0;m<Math.min(k.length,l.length);m++){var n=k[m],o=l[m];f=Math.abs(Number(n))*o,isNaN(f)||(g+=f)}else{var p=!1;for(var q in d)if(c=d[q],j.endsWith(c)){j=j.slice(0,-c.length),f=Math.abs(parseInt(j,10))*b[q],isNaN(f)||(g+=f),p=!0;break}p||(f=Math.abs(Number(j)),isNaN(f)||(g+=f))}}return a.contains("-")&&(g*=-1),Sao.TimeDelta(null,g)},Sao.common.ModelAccess=Sao.class_(Object,{init:function(){this.batchnum=100,this._access={}},load_models:function(a){var b=jQuery.Deferred();return a||(this._access={}),Sao.rpc({method:"model.ir.model.list_models",params:[{}]},Sao.Session.current_session).then(function(a){for(var c=[],d=function(a){this._access=jQuery.extend(this._access,a)},e=0;e<a.length;e+=this.batchnum){var f=a.slice(e,e+this.batchnum);c.push(Sao.rpc({method:"model.ir.model.access.get_access",params:[f,{}]},Sao.Session.current_session).then(d.bind(this)))}jQuery.when.apply(jQuery,c).then(b.resolve,b.reject)}.bind(this)),b},get:function(a){return this._access[a]||{}}}),Sao.common.MODELACCESS=new Sao.common.ModelAccess,Sao.common.ModelHistory=Sao.class_(Object,{init:function(){this._models=[]},load_history:function(){return this._models=[],Sao.rpc({method:"model.ir.model.list_history",params:[{}]},Sao.Session.current_session).then(function(a){this._models=a}.bind(this))},contains:function(a){return~this._models.indexOf(a)}}),Sao.common.MODELHISTORY=new Sao.common.ModelHistory,Sao.common.ViewSearch=Sao.class_(Object,{load_searches:function(){return this.searches={},Sao.rpc({method:"model.ir.ui.view_search.get_search",params:[{}]},Sao.Session.current_session).then(function(a){this.searches=a}.bind(this))},get:function(a){return this.searches[a]||[]},add:function(a,b,c){return Sao.rpc({method:"model.ir.ui.view_search.create",params:[[{model:a,name:b,domain:(new Sao.PYSON.Encoder).encode(c)}],{}]},Sao.Session.current_session).then(function(d){var e=d[0];void 0===this.searches[a]&&(this.searches[a]=[]),this.searches[a].push([e,b,c])}.bind(this))},remove:function(a,b){return Sao.rpc({method:"model.ir.ui.view_search.delete",params:[[b],{}]},Sao.Session.current_session).then(function(){for(var c=0;c<this.searches[a].length;c++){var d=this.searches[a][c];if(d[0]===b){this.searches[a].splice(c,1);break}}}.bind(this))}}),Sao.common.VIEW_SEARCH=new Sao.common.ViewSearch,Sao.common.humanize=function(a){for(var b=["bytes","KB","MB","GB","TB","PB"],c=0,d=b.length;d>c;c++){if(1e3>a)return a.toPrecision(4)+" "+b[c];a/=1e3}},Sao.common.EvalEnvironment=function(a,b){void 0===b&&(b="eval");var c;if("eval"==b)c=a.get_eval();else{c={};for(var d in a.model.fields){var e=a.model.fields[d];c[d]=e.get_on_change_value(a)}}return c.id=a.id,a.group.parent&&Object.defineProperty(c,"_parent_"+a.group.parent_name,{enumerable:!0,get:function(){return Sao.common.EvalEnvironment(a.group.parent,b)}}),c.get=function(a,b){return this.hasOwnProperty(a)?this[a]:b},c},Sao.common.selection_mixin={},Sao.common.selection_mixin.init=function(){this.selection=null,this.inactive_selection=[],this._last_domain=null,this._values2selection={},this._domain_cache={},void 0===this.nullable_widget&&(this.nullable_widget=!0)},Sao.common.selection_mixin.init_selection=function(a,b){a||(a={},(this.attributes.selection_change_with||[]).forEach(function(b){a[b]=null}));var c,d=JSON.stringify(a),e=this.attributes.selection||[],f=function(a){a=jQuery.extend([],a),(void 0===this.attributes.sort||this.attributes.sort)&&a.sort(function(a,b){return a[1].localeCompare(b[1])}),this.selection=jQuery.extend([],a),b&&b(this.selection)};e instanceof Array||d in this._values2selection?(d in this._values2selection&&(e=this._values2selection[d]),f.call(this,e),c=jQuery.when()):(c=jQuery.isEmptyObject(this.attributes.selection_change_with)?this.model.execute(e,[]):this.model.execute(e,[a]),c=c.then(function(a){return this._values2selection[d]=a,a}.bind(this)),c=c.then(f.bind(this))),this.inactive_selection=[],this._selection_prm=c},Sao.common.selection_mixin.update_selection=function(a,b,c){var d=function(){if(!b)return void(c&&c(this.selection));var d=b.get_domain(a);if("reference"==b.description.type&&(d=[]),"relation"in this.attributes){var e=b.get_context(a),f=JSON.stringify([d,e]);if(f in this._domain_cache&&(this.selection=this._domain_cache[f],this._last_domain=[d,e]),null!==this._last_domain&&Sao.common.compare(d,this._last_domain[0])&&JSON.stringify(e)==JSON.stringify(this._last_domain[1]))return void(c&&c(this.selection));var g=Sao.rpc({method:"model."+this.attributes.relation+".search_read",params:[d,0,null,null,["rec_name"],e]},a.model.session);g.done(function(a){var b=[];a.forEach(function(a){b.push([a.id,a.rec_name])}),this.nullable_widget&&b.push([null,""]),this._last_domain=d,this._domain_cache[f]=b,this.selection=jQuery.extend([],b),c&&c(this.selection)}.bind(this)),g.fail(function(){this._last_domain=null,this.selection=[],c&&c(this.selection)}.bind(this))}else{var h=this.attributes.selection_change_with||[],i=a._get_on_change_args(h);delete i.id,Sao.common.selection_mixin.init_selection.call(this,i,function(){Sao.common.selection_mixin.filter_selection.call(this,d,a,b),c&&c(this.selection)}.bind(this))}};this._selection_prm.done(d.bind(this))},Sao.common.selection_mixin.filter_selection=function(a,b,c){if(!jQuery.isEmptyObject(a)){var d=new Sao.common.DomainInversion;this.selection=this.selection.filter(function(b){var c={};return c[this.field_name]=b[0],d.eval_domain(a,c)}.bind(this))}},Sao.common.selection_mixin.get_inactive_selection=function(a){if(!this.attributes.relation)return jQuery.when([]);for(var b=0,c=this.inactive_selection.length;c>b;b++)if(a==this.inactive_selection[b][0])return jQuery.when(this.inactive_selection[b]);var d=Sao.rpc({method:"model."+this.attributes.relation+".read",params:[[a],["rec_name"],{}]},Sao.Session.current_session);return d.then(function(a){return this.inactive_selection.push([a[0].id,a[0].rec_name]),[a[0].id,a[0].rec_name]}.bind(this))},Sao.common.Button=Sao.class_(Object,{init:function(a,b){this.attributes=a,b?this.el=b:(this.el=jQuery("<button/>"),this.el.append(a.string||""),this.attributes.rule&&this.el.append(" ").append(jQuery("<span/>",{"class":"badge"}))),this.icon=this.el.children("img"),this.icon.length||(this.icon=jQuery("<img/>").prependTo(this.el),this.icon.hide()),this.el.addClass("btn btn-default"),this.el.attr("type","button"),this.icon.addClass("icon"),this.icon.attr("aria-hidden",!0),this.set_icon(a.icon)},set_icon:function(a){if(!a)return this.icon.attr("src",""),void this.icon.hide();var b=Sao.common.ICONFACTORY.register_icon(a);b.done(function(a){this.icon.attr("src",a),this.icon.show()}.bind(this))},set_state:function(a){var b;if(b=a?a.expr_eval(this.attributes.states||{}):{},b.invisible?this.el.hide():this.el.show(),this.el.prop("disabled",b.readonly),this.set_icon(b.icon||this.attributes.icon),this.attributes.rule){var c;c=a?a.get_button_clicks(this.attributes.name):jQuery.when(),c.then(function(a){var b=this.el.children(".badge"),c=[],d="";if(!jQuery.isEmptyObject(a)){for(var e in a)c.push(a[e]);d=Sao.i18n.gettext("By: ")+c.join(Sao.i18n.gettext(", "))}b.data("toggle","tooltip"),b.text(c.length||""),b.attr("title",d),b.tooltip()}.bind(this))}if((void 0===this.attributes.type||"class"===this.attributes.type)&&a)for(var d=a.group.parent;d;){
-if(d.has_changed()){this.el.prop("disabled",!1);break}d=d.group.parent}}}),Sao.common.udlex=Sao.class_(Object,{init:function(a){var b=Sao.class_(Object,{init:function(a){this.stream=a.split(""),this.i=0},read:function(a){if(void 0===a&&(a=1),this.i>=this.stream.length)return null;var b=this.stream.slice(this.i,this.i+a).join();return this.i+=a,b}});this.instream=new b(a),this.eof=null,this.commenters="",this.nowordchars=[":",">","<","=","!",'"',";","(",")"],this.whitespace=" 	\r\n",this.whitespace_split=!1,this.quotes='"',this.escape="\\",this.escapedquotes='"',this.state=" ",this.pushback=[],this.token=""},get_token:function(){if(this.pushback.length>0)return this.pushback.shift();var a=this.read_token();return a},read_token:function(){for(var a=!1,b=" ";;){var c=this.instream.read(1);if(null===this.state){this.token="";break}if(" "==this.state){if(!c){this.state=null;break}if(this.whitespace.contains(c)){if(this.token||a)break;continue}if(this.commenters.contains(c));else if(this.escape.contains(c))b="a",this.state=c;else if(~this.nowordchars.indexOf(c))if(this.quotes.contains(c))this.state=c;else{if(!this.whitespace_split){if(this.token=c,this.token||a)break;continue}this.token=c,this.state="a"}else this.token=c,this.state="a"}else if(this.quotes.contains(this.state)){if(a=!0,!c)throw"no closing quotation";c==this.state?this.state="a":this.escape.contains(c)&&this.escapedquotes.contains(this.state)?(b=this.state,this.state=c):this.token=this.token+c}else if(this.escape.contains(this.state)){if(!c)throw"no escaped character";this.quotes.contains(b)&&c!=this.state&&c!=b&&(this.token=this.token+this.state),this.token=this.token+c,this.state=b}else if("a"==this.state){if(!c){this.state=null;break}if(this.whitespace.contains(c)){if(this.state=" ",this.token||a)break;continue}if(this.commenters.contains(c));else if(this.quotes.contains(c))this.state=c;else if(this.escape.contains(c))b="a",this.state=c;else{if(~this.nowordchars.indexOf(c)&&!this.quotes.contains(c)&&!this.whitespace_split){if(this.pushback.unshift(c),this.state=" ",this.token)break;continue}this.token=this.token+c}}}var d=this.token;return this.token="",a||""!==d||(d=null),d},next:function(){var a=this.get_token();return a==this.eof?null:a}}),Sao.common.DomainParser=Sao.class_(Object,{OPERATORS:["!=","<=",">=","=","!","<",">"],init:function(a,b){this.fields={},this.strings={},this.update_fields(a),this.context=b},update_fields:function(a){for(var b in a){var c=a[b];(c.searchable||void 0===c.searchable)&&(this.fields[b]=c,this.strings[c.string.toLowerCase()]=c)}},parse:function(a){try{for(var b=new Sao.common.udlex(a),c=[];;){var d=b.next();if(null===d)break;c.push(d)}return c=this.group_operator(c),c=this.parenthesize(c),c=this.group(c),c=this.operatorize(c,"or"),c=this.operatorize(c,"and"),c=this.parse_clause(c),this.simplify(c)}catch(e){if("no closing quotation"==e)return this.parse(a+'"');throw e}},stringable:function(a){var b=function(a){if(!a)return!0;var b=function(a){return a instanceof Array};return(~["AND","OR"].indexOf(a[0])||b(a[0]))&&a.slice(1).every(b)?this.stringable(a):a[0]in this.fields||"rec_name"==a[0]}.bind(this);return a?(~["AND","OR"].indexOf(a[0])&&(a=a.slice(1)),a.every(b)):!0},string:function(a){var b=function(a){if(jQuery.isEmptyObject(a))return"";if("string"!=typeof a[0]||~["AND","OR"].indexOf(a[0]))return"("+this.string(a)+")";var b,c=a[0],d=a[1],e=a[2];if(c.endsWith(".rec_name")&&(c=c.slice(0,-9)),!(c in this.fields))return b=e.replace("%%","__"),b.startsWith("%")&&b.endsWith("%")&&(e=e.slice(1,-1)),this.quote(e);var f=this.fields[c],g=null;a.length>3&&(g=a[3]),d.contains("ilike")&&(b=e.replace("%%","__"),b.startsWith("%")&&b.endsWith("%")?e=e.slice(1,-1):b.contains("%")||(d="ilike"==d?"=":"!",e=e.replace("%%","%")));var h=this.default_operator(f);h==d.trim()?(d="",~this.OPERATORS.indexOf(e)&&(d='"" ')):d.contains(h)&&(d.contains("not")||d.contains("!"))&&(d=d.replace(h,"").replace("not","!").trim()),d.endsWith("in")&&(d="not in"==d?"!":"");var i=this.format_value(f,e,g);return~this.OPERATORS.indexOf(d)&&~["char","text","selection"].indexOf(f.type)&&""===e&&(i='""'),this.quote(f.string)+": "+d+i};if(b=b.bind(this),jQuery.isEmptyObject(a))return"";var c=" ";return"AND"!=a[0]&&"OR"!=a[0]||("OR"==a[0]&&(c=" or "),a=a.slice(1)),a.map(b).join(c)},completion:function(a){var b,c,d=[],e=this.parse(a),f=0;for(b=a.length;b>0&&(")"!=a[b]&&" "!=a[b]);b--)")"==a[b]&&(f+=1);var g=this.ending_clause(e),h=g[0],i=g[1],j=i-f,k=this.string(e);j>0&&(k=k.substring(0,k.length-j)),k!=a&&d.push(k);var l,m,n=function(a,b){return b>0?a.substring(0,b):a};if(null!==h&&0===f){var o=this.complete(h);for(b=0,c=o.length;c>b;b++)l=o[b],m=this.string(this.replace_ending_clause(e,l)),d.push(n(m,j))}if(a.length>0){if(" "!=a.substr(a.length-1,1))return d;if(a.length>=2||":"==a.substr(a.length-2,1))return d}var p,q,r;for(var s in this.strings){p=this.strings[s],q=this.default_operator(p),r="","ilike"!=q&&"not ilike"!=q||(r=this.likify(r));var t=this.append_ending_clause(e,[p.name,q,r],j),u=this.string(t);d.push(n(u,j))}return d},complete:function(a){var b,c,d,e,f=[];1==a.length?b=a[0]:3==a.length?(b=a[0],c=a[1],d=a[2]):(b=a[0],c=a[1],d=a[2],e=a[3],b.endsWith(".rec_name")&&(b=b.substring(0,b.length-9)));var g;"rec_name"==b&&("ilike"==c&&(g=d.replace(/%%/g,"__"),g.startsWith("%")||g.endsWith("%")?d=g.substring(1,g.length-1):~g.indexOf("%")&&(d=d.replace(/%%/g,"%")),c=null),b=d,d=""),void 0!==b&&null!==b||(b="");var h;if(!(b.toLowerCase()in this.strings||b in this.fields)){for(var i in this.strings)h=this.strings[i],h.string.toLowerCase().startsWith(b.toLowerCase())&&(c=this.default_operator(h),d="","ilike"==c&&(d=this.likify(d)),f.push([h.name,c,d]));return f}if(h=b in this.fields?this.fields[b]:this.strings[b.toLowerCase()],c)for(var j=this.complete_value(h,d),k=0,l=j.length;l>k;k++)f.push([h.name,c,j[k]]);else c=this.default_operator(h),d="","ilike"!=c&&"not ilike"!=c||(d=this.likify(d)),f.push([h.name,c,d]);return f},is_leaf:function(a){return a instanceof Array&&a.clause},ending_clause:function(a,b){if(void 0===b&&(b=0),0===a.length)return[null,b];var c=a[a.length-1];return this.is_leaf(c)?[c,b]:this.ending_clause(c,b+1)},replace_ending_clause:function(a,b){var c,d,e=[];for(c=0,d=a.length-1;d>c;c++)e.push(a[c]);return this.is_leaf(a[c])?e.push(b):e=e.concat(this.replace_ending_clause(a[c],b)),e},append_ending_clause:function(a,b,c){if(0===a.length)return[b];var d=a.slice(0,-1),e=a[a.length-1];return this.is_leaf(e)?(d.push(e),0===c&&d.push(b)):d.push(this.append_ending_clause(e,b,c-1)),d},complete_value:function(a,b){var c=function(){return b?[!0]:[!1]},d=function(){var c=[],d=null!==b?b:"";b instanceof Array&&(d=b[b.length-1]),d=d.replace(/^%*|%*$/g,"");var e,f,g,h;for(e=0,f=a.selection.length;f>e;e++)g=a.selection[e][0],h=a.selection[e][1].toLowerCase(),h.startsWith(d.toLowerCase())&&(b instanceof Array?c.push(b.slice(0,-1).concat([g])):c.push(g));return c},e=function(){var c=[],d=null!==b?b:"";b instanceof Array&&(d=b[b.length-1]),d=d.replace(/^%*|%*$/g,"");var e,f,g,h;for(e=0,f=a.selection.length;f>e;e++)g=a.selection[e][0],h=a.selection[e][1].toLowerCase(),h.startsWith(d.toLowerCase())&&(b instanceof Array?c.push(b.slice(0,-1).concat([g])):c.push(this.likify(g)));return c}.bind(this),f=function(){return[Sao.Date(),Sao.DateTime().utc()]},g=function(){return[Sao.Date()]},h=function(){return[Sao.Time()]},i={"boolean":c,selection:d,reference:e,datetime:f,date:g,time:h};return a.type in i?i[a.type]():[]},group_operator:function(a){var b=a[0],c=[];return a.slice(1).forEach(function(a){"="==a&&b&&~this.OPERATORS.indexOf(b+a)?(c.push(b+a),b=null):(null!==b&&c.push(b),b=a)}.bind(this)),null!==b&&c.push(b),c},parenthesize:function(a){var b=[],c=b,d=[];return a.forEach(function(a,b){void 0!==c&&("("==a?(d.push(c),c=c[c.push([])-1]):")"==a?c=d.pop():c.push(a))}),b},group:function(a){var b=[],c=function(a){var b=[],d=function(a){b.push([a])},e=a.indexOf(":");if(!~e)return a.forEach(d),b.forEach(function(a){a.clause=!0}),b;for(var f=function(a,c){return function(d){if(jQuery.isEmptyObject(a))b.push(d);else{var e;jQuery.isEmptyObject(c)?(e=a.concat(d),e.clause=!0,b.push(e)):(null!==d[0]&&c.push(d[0]),e=a.concat([c]),e.clause=!0,b.push(e)),a.splice(0,a.length)}}},g=0;e>g;g++){var h=a.slice(g,e).join(" ");if(h.toLowerCase()in this.strings){jQuery.isEmptyObject(a.slice(0,g))?d(null):a.slice(0,g).forEach(d),h=[h];var i=[""].concat(this.OPERATORS);e+1<a.length&&~i.indexOf(a[e+1])?(h=h.concat([a[e+1]]),e+=1):h=h.concat([null]);for(var j=[];e+2<a.length&&";"==a[e+2];)j.push(a[e+1]),e+=2;if(c(a.slice(e+1)).forEach(f(h,j)),!jQuery.isEmptyObject(h)){var k;jQuery.isEmptyObject(j)?(k=h.concat([null]),k.clause=!0,b.push(k)):(k=h.concat([j]),k.clause=!0,b.push(k))}break}}return b};c=c.bind(this);var d=[];return a.forEach(function(a){this.is_generator(a)?(c(d).forEach(function(a){Sao.common.compare(a,[null])||b.push(a)}),d=[],b.push(this.group(a))):d.push(a)}.bind(this)),c(d).forEach(function(a){Sao.common.compare(a,[null])||b.push(a)}),b},is_generator:function(a){return a instanceof Array&&void 0===a.clause},operatorize:function(a,b){var c=[];b=b||"or",a=jQuery.extend([],a);for(var d=function(a){return a instanceof Array?Sao.common.compare(a,[b]):a==b},e=a.shift();d(e);)e=a.shift();if(void 0===e)return c;this.is_generator(e)&&(e=this.operatorize(e,b));for(var f=null;!jQuery.isEmptyObject(a);)if(f=a.shift(),this.is_generator(f)&&!d(f)&&(f=this.operatorize(f,b)),d(f)){for(f=a.shift();d(f);)f=a.shift();this.is_generator(f)&&(f=this.operatorize(f,b)),void 0!==f?e=[b.toUpperCase(),e,f]:d(e)||(c.push([b.toUpperCase(),e]),e=null),f=null}else d(e)||c.push(e),e=f;return jQuery.isEmptyObject(a)&&(null===f||d(f)?null===e||d(e)||c.push(e):c.push(f)),c},_clausify:function(a){return a.clause=!0,a},parse_clause:function(a){var b=[];return a.forEach(function(a){if(this.is_generator(a))jQuery.merge(b,this.parse_clause(a));else if("OR"==a||"AND"==a)b.push(a);else if(1!=a.length||a[0]instanceof Array){if(3==a.length&&a[0].toLowerCase()in this.strings){var c=(a[0],a[1]),d=a[2],e=this.strings[a[0].toLowerCase()],f=null;if("reference"==e.type){var g=this.split_target_value(e,d);f=g[0],d=g[1]}if(c||(c=this.default_operator(e)),d instanceof Array&&(c="!"==c?"not in":"in"),"!"==c&&(c=this.negate_operator(this.default_operator(e))),~["integer","float","numeric","datetime","date","time"].indexOf(e.type)&&d&&d.contains("..")){var h=d.split("..",2),i=this.convert_value(e,h[0]),j=this.convert_value(e,h[1]);return void b.push([this._clausify([e.name,">=",i]),this._clausify([e.name,"<=",j])])}d=d instanceof Array?d.map(function(a){return this.convert_value(e,a)}.bind(this)):this.convert_value(e,d),c.contains("like")&&(d=this.likify(d)),f?b.push(this._clausify([e.name+".rec_name",c,d,f])):b.push(this._clausify([e.name,c,d]))}}else b.push(this._clausify(["rec_name","ilike",this.likify(a[0])]))}.bind(this)),b},likify:function(a){if(!a)return"%";var b=a.replace("%%","__");return b.contains("%")?a:"%"+a+"%"},quote:function(a){if("string"!=typeof a)return a;a.contains("\\")&&(a=a.replace(new RegExp("\\\\","g"),"\\\\")),a.contains('"')&&(a=a.replace(new RegExp('"',"g"),'\\"'));for(var b=[":"," ","(",")"].concat(this.OPERATORS),c=0;c<b.length;c++){var d=b[c];if(a.contains(d))return'"'+a+'"'}return a},default_operator:function(a){return~["char","text","many2one","many2many","one2many","reference"].indexOf(a.type)?"ilike":"="},negate_operator:function(a){switch(a){case"ilike":return"not ilike";case"=":return"!=";case"in":return"not in"}},time_format:function(a){return new Sao.PYSON.Decoder({}).decode(a.format)},split_target_value:function(a,b){var c=null;if("string"==typeof b)for(var d=0;d<a.selection.length;d++){var e=a.selection[d],f=e[0],g=e[1];if(b.toLowerCase().startsWith(g.toLowerCase()+",")){c=f,b=b.slice(g.length+1);break}}return[c,b]},convert_value:function(a,b){var c=function(){if("string"==typeof b)for(var c=0;c<a.selection.length;c++){var d=a.selection[c],e=d[0],f=d[1];if(b.toLowerCase()==f.toLowerCase())return e}return b},d={"boolean":function(){return"string"==typeof b?[Sao.i18n.gettext("y"),Sao.i18n.gettext("Yes"),Sao.i18n.gettext("True"),Sao.i18n.gettext("t"),"1"].some(function(a){return a.toLowerCase().startsWith(b.toLowerCase())}):Boolean(b)},"float":function(){var a=Number(b);return isNaN(a)||""===b||null===b?null:a},integer:function(){var a=parseInt(b,10);return isNaN(a)?null:a},numeric:function(){var a=new Sao.Decimal(b);return isNaN(a.valueOf())||""===b||null===b?null:a},selection:c,reference:c,datetime:function(){var c=Sao.common.parse_datetime(Sao.common.date_format(),this.time_format(a),b);return c||(c=Sao.common.parse_date(Sao.common.date_format(),b)),c}.bind(this),date:function(){return Sao.common.parse_date(Sao.common.date_format(),b)},time:function(){try{return Sao.common.parse_time(this.time_format(a),b)}catch(c){return null}}.bind(this),timedelta:function(){var c=null;return a.converter&&(c=this.context[a.converter]),Sao.common.timedelta.parse(b,c)}.bind(this),many2one:function(){return""===b?null:b}},e=d[a.type];return e?e():b},format_value:function(a,b,c){void 0===c&&(c=null);var d=function(){if(!b&&0!==b&&b!==new Sao.Decimal(0))return"";var a=String(b).split(".")[1];return a=a?a.length:0,b.toFixed(a)},e=function(){for(var c=0;c<a.selection.length;c++)if(a.selection[c][0]==b)return a.selection[c][1];return b||""},f=function(){if(!c)return e();for(var d=0;d<a.selection.length;d++)if(a.selection[d][0]==c){c=a.selection[d][1];break}return c+","+b},g={"boolean":function(){return b?Sao.i18n.gettext("True"):Sao.i18n.gettext("False")},integer:function(){return b||0===b?""+parseInt(b,10):""},"float":d,numeric:d,selection:e,reference:f,datetime:function(){return b?b.isDate||!(b.hour()||b.minute()||b.second())?Sao.common.format_date(Sao.common.date_format(),b):Sao.common.format_datetime(Sao.common.date_format(),this.time_format(a),b):""}.bind(this),date:function(){return Sao.common.format_date(Sao.common.date_format(),b)},time:function(){return b?Sao.common.format_time(this.time_format(a),b):""}.bind(this),timedelta:function(){if(!b||!b.valueOf())return"";var c=null;return a.converter&&(c=this.context[a.converter]),Sao.common.timedelta.format(b,c)}.bind(this),many2one:function(){return null===b?"":b}};if(b instanceof Array)return b.map(function(b){return this.format_value(a,b)}.bind(this)).join(";");var h=g[a.type];return h?this.quote(h(b)):null===b?"":this.quote(b)},simplify:function(a){return a instanceof Array&&!this.is_leaf(a)?1==a.length&&a[0]instanceof Array&&("AND"==a[0][0]||"OR"==a[0][0]||a[0][0]instanceof Array)?this.simplify(a[0]):2==a.length&&("AND"==a[0]||"OR"==a[0])&&a[1]instanceof Array?this.simplify(a[1]):(3==a.length&&("AND"==a[0]||"OR"==a[0])&&a[1]instanceof Array&&a[0]==a[1][0]&&(a=this.simplify(a[1]).concat([a[2]])),a.map(this.simplify.bind(this))):a}}),Sao.common.DomainInversion=Sao.class_(Object,{and:function(a,b){return a&&b},or:function(a,b){return a||b},OPERATORS:{"=":function(a,b){return a instanceof Array&&b instanceof Array?Sao.common.compare(a,b):a===b},">":function(a,b){return a>b},"<":function(a,b){return b>a},"<=":function(a,b){return b>=a},">=":function(a,b){return a>=b},"!=":function(a,b){return a instanceof Array&&b instanceof Array?!Sao.common.compare(a,b):a!==b},"in":function(a,b){return Sao.common.DomainInversion.in_(a,b)},"not in":function(a,b){return!Sao.common.DomainInversion.in_(a,b)},like:function(){return!0},ilike:function(){return!0},"not like":function(){return!0},"not ilike":function(){return!0},child_of:function(){return!0},"not child_of":function(){return!0}},locale_part:function(a,b,c){return void 0===c&&(c="id"),a===b?c:a.contains(".")?a.split(".").slice(1).join("."):a},is_leaf:function(a){return a instanceof Array&&a.length>2&&"string"==typeof a[1]},eval_leaf:function(a,b,c){void 0===c&&(c=this.and);var d=a[0],e=a[1],f=a[2];if(d.contains("."))return Boolean(b[d.split(".")[0]]);if("="==e&&(null===b[d]||void 0===b[d])&&c===this.and)return!0;var g=b[d];return g&&g._isAMomentObject&&!f&&(f=g.isDateTime?Sao.DateTime.min:Sao.Date.min),f&&f._isAMomentObject&&!g&&(g=f.isDateTime?Sao.DateTime.min:Sao.Date.min),"string"==typeof g&&f instanceof Array&&2==f.length?f=f.join(","):g instanceof Array&&"string"==typeof f&&2==g.length&&(g=g.join(",")),~["=","!="].indexOf(e)&&g instanceof Array&&"number"==typeof f&&(e={"=":"in","!=":"not in"}[e]),e in this.OPERATORS?this.OPERATORS[e](g,f):!0},inverse_leaf:function(a){return~["AND","OR"].indexOf(a)?a:this.is_leaf(a)?a[1].contains("child_of")?3==a.length?a:[a[3]].concat(a.slice(1)):a:a.map(this.inverse_leaf.bind(this))},filter_leaf:function(a,b,c){return~["AND","OR"].indexOf(a)?a:this.is_leaf(a)?a[0].startsWith(b)&&a.length>3&&a[3]!==c?["id","=",null]:a:a.map(function(a){return this.filter_leaf(a,b,c)}.bind(this))},eval_domain:function(a,b,c){return void 0===c&&(c=this.and),this.is_leaf(a)?this.eval_leaf(a,b,c):jQuery.isEmptyObject(a)&&c==this.and?!0:jQuery.isEmptyObject(a)&&c==this.or?!1:"AND"==a[0]?this.eval_domain(a.slice(1),b):"OR"==a[0]?this.eval_domain(a.slice(1),b,this.or):c(this.eval_domain(a[0],b),this.eval_domain(a.slice(1),b,c))},localize_domain:function(a,b,c){if(~["AND","OR",!0,!1].indexOf(a))return a;if(this.is_leaf(a)){if(a[1].contains("child_of"))return 3==a.length?a:[a[3]].concat(a.slice(1,-1));var d="id";"string"==typeof a[2]&&(d="rec_name");var e=c?3:4;return[this.locale_part(a[0],b,d)].concat(a.slice(1,e)).concat(a.slice(4))}return a.map(function(a){return this.localize_domain(a,b,c)}.bind(this))},simplify:function(a){return this.is_leaf(a)?a:~["OR","AND"].indexOf(a)?a:a instanceof Array&&1==a.length&&~["OR","AND"].indexOf(a[0])?[]:a instanceof Array&&1==a.length&&!this.is_leaf(a[0])?this.simplify(a[0]):a instanceof Array&&2==a.length&&~["AND","OR"].indexOf(a[0])?[this.simplify(a[1])]:a.map(this.simplify.bind(this))},merge:function(a,b){if(jQuery.isEmptyObject(a)||~["AND","OR"].indexOf(a))return[];var c="OR"==a[0]?"OR":"AND";return this.is_leaf(a)?[a]:void 0===b?[c].concat([].concat.apply([],a.map(function(a){return this.merge(a,c)}.bind(this)))):c==b?[].concat.apply([],a.map(function(a){return this.merge(a,c)}.bind(this))):[this.merge(a)]},concat:function(a,b){var c=[];return b&&c.push(b),a.forEach(function(a){jQuery.isEmptyObject(a)||c.push(a)}),this.simplify(this.merge(c))},unique_value:function(a){return a instanceof Array&&1==a.length&&!a[0][0].contains(".")&&"="==a[0][1]?[!0,a[0][1],a[0][2]]:[!1,null,null]},parse:function(a){var b=Sao.common.DomainInversion.And,c=Sao.common.DomainInversion.Or;if(this.is_leaf(a))return a;if(jQuery.isEmptyObject(a))return new b([]);if("OR"===a[0])return new c(a.slice(1));var d=0;return"AND"===a[0]&&(d=1),new b(a.slice(d))},domain_inversion:function(a,b,c){void 0===c&&(c={});var d=this.parse(a);return~d.variables.indexOf(b)?d.inverse(b,c):!0}}),Sao.common.DomainInversion.in_=function(a,b){if(a instanceof Array){if(b instanceof Array){for(var c=0,d=a.length;d>c;c++)if(~b.indexOf(a[c]))return!0;return!1}return Boolean(~a.indexOf(b))}return Boolean(~b.indexOf(a))},Sao.common.DomainInversion.And=Sao.class_(Object,{init:function(a){this.domain_inversion=new Sao.common.DomainInversion,this.branches=a.map(this.domain_inversion.parse.bind(this.domain_inversion)),this.variables=[];for(var b=0,c=this.branches.length;c>b;b++){var d=this.branches[b];this.domain_inversion.is_leaf(d)?this.variables.push(this.base(d[0])):d instanceof Sao.common.DomainInversion.And&&(this.variables=this.variables.concat(d.variables))}},base:function(a){return a.contains(".")?a.split(".")[0]:a},inverse:function(a,b){for(var c=Sao.common.DomainInversion,d=[],e=0,f=this.branches.length;f>e;e++){var g=this.branches[e];if(g instanceof c.And){var h=g.inverse(a,b),i="boolean"==typeof h;if(i){if(h)continue;return!1}d.push(h)}else if(this.domain_inversion.is_leaf(g)&&this.base(g[0])===a)d.push(g);else{var j=g[0];if(j in b&&!(j in b&&this.domain_inversion.eval_leaf(g,b,this.domain_inversion.and)))return!1;d.push(!0)}}return d=d.filter(function(a){return a!==!0}),jQuery.isEmptyObject(d)?!0:this.domain_inversion.simplify(d)}}),Sao.common.DomainInversion.Or=Sao.class_(Sao.common.DomainInversion.And,{inverse:function(a,b){var c=Sao.common.DomainInversion,d=[];if(!~this.variables.indexOf(a)&&!jQuery.isEmptyObject(this.variables.filter(function(a){return!(a in b)})))return!0;for(var e=0,f=this.branches.length;f>e;e++){var g=this.branches[e];if(g instanceof c.And){var h=g.inverse(a,b),i="boolean"==typeof h;if(!~this.variables.indexOf(a)){if(i&&h)return!0;continue}if(i){if(h)return!0;continue}d.push(h)}else if(this.domain_inversion.is_leaf(g)&&this.base(g[0])==a)d.push(g);else{var j=g[0];if(j=this.base(j),j in b&&this.domain_inversion.eval_leaf(g,b,this.domain_inversion.or))return!0;j in b&&!this.domain_inversion.eval_leaf(g,b,this.domain_inversion.or)&&d.push(!1)}}return d=d.filter(function(a){return a!==!1}),jQuery.isEmptyObject(d)?!1:this.domain_inversion.simplify(["OR"].concat(d))}}),Sao.common.guess_mimetype=function(a){return/.*odt$/.test(a)?"application/vnd.oasis.opendocument.text":/.*ods$/.test(a)?"application/vnd.oasis.opendocument.spreadsheet":/.*pdf$/.test(a)?"application/pdf":/.*docx$/.test(a)?"application/vnd.openxmlformats-officedocument.wordprocessingml.document":/.*doc/.test(a)?"application/msword":/.*xlsx$/.test(a)?"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":/.*xls/.test(a)?"application/vnd.ms-excel":"application/octet-binary"},Sao.common.LOCAL_ICONS=["tryton-attachment-hi","tryton-attachment","tryton-bookmark","tryton-cancel","tryton-clear","tryton-close","tryton-connect","tryton-copy","tryton-delete","tryton-dialog-error","tryton-dialog-information","tryton-dialog-warning","tryton-disconnect","tryton-executable","tryton-find-replace","tryton-find","tryton-folder-new","tryton-fullscreen","tryton-go-home","tryton-go-jump","tryton-go-next","tryton-go-previous","tryton-help","tryton-icon","tryton-list-add","tryton-list-remove","tryton-locale","tryton-lock","tryton-log-out","tryton-mail-message-new","tryton-mail-message","tryton-new","tryton-ok","tryton-open","tryton-preferences-system-session","tryton-preferences-system","tryton-preferences","tryton-print-email","tryton-print-open","tryton-print","tryton-refresh","tryton-save-as","tryton-save","tryton-star","tryton-start-here","tryton-system-file-manager","tryton-system","tryton-text-background","tryton-text-foreground","tryton-text-markup","tryton-undo","tryton-unstar","tryton-web-browser"],Sao.common.IconFactory=Sao.class_(Object,{batchnum:10,name2id:{},loaded_icons:{},tryton_icons:[],register_prm:jQuery.when(),load_icons:function(a){if(a=a||!1,!a)for(var b in this.load_icons)this.load_icons.hasOwnProperty(b)&&window.URL.revokeObjectURL(this.load_icons[b]);var c=new Sao.Model("ir.ui.icon");return c.execute("list_icons",[],{}).then(function(b){a||(this.name2id={},this.loaded_icons={}),this.tryton_icons=[];for(var c,d,e=0,f=b.length;f>e;e++)c=b[e][0],d=b[e][1],a&&d in this.loaded_icons||(this.tryton_icons.push([c,d]),this.name2id[d]=c)}.bind(this))},register_icon:function(a){if(!a)return jQuery.Deferred().reject();if(a in this.loaded_icons||~Sao.common.LOCAL_ICONS.indexOf(a))return jQuery.when(this.get_icon_url(a));if("pending"==this.register_prm.state()){var b=jQuery.Deferred();return this.register_prm.then(function(){this.register_icon(a).then(b.resolve,b.reject)}.bind(this)),b}var c;c=a in this.name2id?jQuery.when():this.load_icons(!0);var d=new Sao.Model("ir.ui.icon");return this.register_prm=c.then(function(){var b=function(a){var b,c;for(b=0,c=this.tryton_icons.length;c>b;b++){var d=this.tryton_icons[b];if(Sao.common.compare(d,a))break}return b}.bind(this),c=b([this.name2id[a],a]),e=Math.round(c-this.batchnum/2);e=0>e?0:e;var f=Math.round(c+this.batchnum/2),g=[];this.tryton_icons.slice(e,f).forEach(function(a){g.push(a[0])});var h=d.execute("read",[g,["name","icon"]],{});return h.then(function(c){return c.forEach(function(a){var c;if(navigator.userAgent.match(/firefox/i)){c="data:image/svg+xml;base64,"+window.btoa(unescape(encodeURIComponent(a.icon)));var d=new Image;d.src=c,d.onload=function(){var b=document.createElement("canvas");b.width=d.width,b.height=d.height;var e=b.getContext("2d");e.drawImage(d,0,0),b.toBlob(function(d){var e=c;c=window.URL.createObjectURL(d),this.loaded_icons[a.name]=c,jQuery(document).find("img").each(function(a,b){b.src==e&&(b.src=c)}),b.remove()}.bind(this),"image/png")}.bind(this)}else{var e=new Blob([a.icon],{type:"image/svg+xml"});c=window.URL.createObjectURL(e)}this.loaded_icons[a.name]=c,delete this.name2id[a.name],this.tryton_icons.splice(b([a.id,a.name]),1)}.bind(this)),this.get_icon_url(a)}.bind(this))}.bind(this)),this.register_prm},get_icon_url:function(a){return a in this.loaded_icons?this.loaded_icons[a]:"images/"+a+".svg"}}),Sao.common.ICONFACTORY=new Sao.common.IconFactory,Sao.common.UniqueDialog=Sao.class_(Object,{init:function(){this.running=!1},build_dialog:function(){var a=new Sao.Dialog("",this.class_);return a},run:function(){if(this.running)return jQuery.when();var a=Array.prototype.slice.call(arguments),b=jQuery.Deferred();a.push(b);var c=this.build_dialog.apply(this,a);return c.content.submit(function(a){c.footer.find("button.btn-primary").first().click(),a.preventDefault()}.bind(this)),this.running=!0,c.modal.modal("show"),c.modal.on("shown.bs.modal",function(){c.modal.find("input,select").filter(":visible").first().focus()}),b},close:function(a){a.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),a.modal.modal("hide"),this.running=!1}}),Sao.common.MessageDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"message-dialog",build_dialog:function(a,b,c){var d=Sao.common.MessageDialog._super.build_dialog.call(this);return d.header.remove(),d.body.append(jQuery("<div/>",{"class":"alert alert-info",role:"alert"}).append(jQuery("<span/>",{"class":"glyphicon "+b,"aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Message: "))).append(jQuery("<span/>").append(a).css("white-space","pre-wrap"))),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve("ok")}.bind(this)).appendTo(d.footer),d},run:function(a,b){return Sao.common.MessageDialog._super.run.call(this,a,b||"glyphicon-info-sign")}}),Sao.common.message=new Sao.common.MessageDialog,Sao.common.WarningDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"warning-dialog",build_dialog:function(a,b,c){var d=Sao.common.WarningDialog._super.build_dialog.call(this),e=jQuery("<div/>",{"class":"alert alert-warning",role:"alert"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-alert","aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Warning: "))).append(jQuery("<h4/>").append(b).css("white-space","pre-wrap"));return a&&e.append(jQuery("<span/>").append(a).css("white-space","pre-wrap")),d.body.append(e),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve("ok")}.bind(this)).appendTo(d.footer),d}}),Sao.common.warning=new Sao.common.WarningDialog,Sao.common.UserWarningDialog=Sao.class_(Sao.common.WarningDialog,{class_:"user-warning-dialog",always:!1,_set_always:function(){this.always=jQuery(this).prop("checked")},build_dialog:function(a,b,c){var d=Sao.common.UserWarningDialog._super.build_dialog.call(this,a,b,c);return d.body.append(jQuery("<div/>").append(jQuery("<input/>",{type:"checkbox"}).change(this._set_always.bind(this))).append(jQuery("<span/>").text(Sao.i18n.gettext("Always ignore this warning.")))),d.body.append(jQuery("<p/>").text(Sao.i18n.gettext("Do you want to proceed?"))),d.footer.children().remove(),jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("No")).click(function(){this.close(d),c.reject()}.bind(this)).appendTo(d.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Yes")).click(function(){this.close(d),this.always&&c.resolve("always"),c.resolve("ok")}.bind(this)).appendTo(d.footer),d}}),Sao.common.userwarning=new Sao.common.UserWarningDialog,Sao.common.ConfirmationDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"confirmation-dialog",build_dialog:function(a){var b=Sao.common.ConfirmationDialog._super.build_dialog.call(this);return b.header.remove(),b.body.append(jQuery("<div/>",{"class":"alert alert-info",role:"alert"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-info-sign","aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Confirmation: "))).append(jQuery("<span/>").append(a).css("white-space","pre-wrap"))),b}}),Sao.common.SurDialog=Sao.class_(Sao.common.ConfirmationDialog,{build_dialog:function(a,b){var c=Sao.common.SurDialog._super.build_dialog.call(this,a);return jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c),b.reject()}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(c),b.resolve()}.bind(this)).appendTo(c.footer),c}}),Sao.common.sur=new Sao.common.SurDialog,Sao.common.Sur3BDialog=Sao.class_(Sao.common.ConfirmationDialog,{build_dialog:function(a,b){var c=Sao.common.SurDialog._super.build_dialog.call(this,a);return jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c),b.resolve("cancel")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("No")).click(function(){this.close(c),b.resolve("ko")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Yes")).click(function(){this.close(c),b.resolve("ok")}.bind(this)).appendTo(c.footer),c}}),Sao.common.sur_3b=new Sao.common.Sur3BDialog,Sao.common.AskDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"ask-dialog",run:function(){var a=Array.prototype.slice.call(arguments);return 1==a.length&&a.push(!0),Sao.common.AskDialog._super.run.apply(this,a)},build_dialog:function(a,b,c){var d=Sao.common.AskDialog._super.build_dialog.call(this);d.header.remove();var e=jQuery("<input/>",{"class":"form-control",type:b?"input":"password",id:"ask-dialog-entry"});return d.body.append(jQuery("<div/>",{"class":"form-group"}).append(jQuery("<label/>",{"for":"ask-dialog-entry"}).append(a)).append(e)),jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(d),c.reject()}.bind(this)).appendTo(d.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve(e.val())}.bind(this)).appendTo(d.footer),d}}),Sao.common.ask=new Sao.common.AskDialog,Sao.common.ConcurrencyDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"ask-dialog",build_dialog:function(a,b,c,d){var e=Sao.common.ConcurrencyDialog._super.build_dialog.call(this);return e.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),e.add_title(Sao.i18n.gettext("Concurrency Exception")),e.body.append(jQuery("<div/>",{"class":"alert alert-warning",role:"alert"}).append(jQuery("<p/>").append(jQuery("<span/>",{"class":"glyphicon glyphicon-info-sign","aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Write Concurrency Warning: "))).append(Sao.i18n.gettext("This record has been modified while you were editing it."))).append(jQuery("<p/>").text(Sao.i18n.gettext("Choose:"))).append(jQuery("<ul/>").append(jQuery("<li/>").text(Sao.i18n.gettext('"Cancel" to cancel saving;'))).append(jQuery("<li/>").text(Sao.i18n.gettext('"Compare" to see the modified version;'))).append(jQuery("<li/>").text(Sao.i18n.gettext('"Write Anyway" to save your current version.'))))),jQuery("<button/>",{
-"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(e),d.reject()}.bind(this)).appendTo(e.footer),jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Compare")).click(function(){this.close(e),Sao.Tab.create({model:a,res_id:b,domain:[["id","=",b]],context:c,mode:["form","tree"]}),d.reject()}.bind(this)).appendTo(e.footer),jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Write Anyway")).click(function(){this.close(e),d.resolve()}.bind(this)).appendTo(e.footer),e}}),Sao.common.concurrency=new Sao.common.ConcurrencyDialog,Sao.common.ErrorDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"error-dialog",build_dialog:function(a,b,c){var d=Sao.common.ConcurrencyDialog._super.build_dialog.call(this);return d.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),d.add_title(Sao.i18n.gettext("Application Error")),d.body.append(jQuery("<div/>",{"class":"alert alert-warning",role:"alert"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-alert","aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Warning: "))).append(jQuery("<p/>").append(jQuery("<pre/>").text(b))).append(jQuery("<p/>").append(jQuery("<a/>",{"class":"btn btn-link",href:Sao.config.roundup.url,target:"_blank"}).text(Sao.i18n.gettext("Report Bug"))))),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Close")).click(function(){this.close(d),c.resolve()}.bind(this)).appendTo(d.footer),d}}),Sao.common.error=new Sao.common.ErrorDialog,Sao.common.Processing=Sao.class_(Object,{queries:0,timeout:500,init:function(){this.el=jQuery("<div/>",{id:"processing","class":"text-center"}),this.el.append(jQuery("<span/>",{"class":"label label-info",text:Sao.i18n.gettext("Processing...")})),this.el.hide(),jQuery(function(){this.el.appendTo("body")}.bind(this))},show:function(){return window.setTimeout(function(){this.queries+=1,this.el.show()}.bind(this),this.timeout)},hide:function(a){window.clearTimeout(a),this.queries>0&&(this.queries-=1),this.queries<=0&&(this.queries=0,this.el.hide())}}),Sao.common.processing=new Sao.common.Processing,Sao.common.InputCompletion=Sao.class_(Object,{init:function(a,b,c,d){a.is("input")?(a.wrap('<div class="dropdown"/>'),this.dropdown=a.parent()):(a.addClass("dropdown"),this.dropdown=a),this.input=a.find("input").add(a.filter("input")).first(),this.input.attr("autocomplete","off"),jQuery("<span/>",{"data-toggle":"dropdown"}).appendTo(this.dropdown),this.menu=jQuery("<ul/>",{"class":"dropdown-menu",role:"listbox"}).appendTo(this.dropdown),this.separator=jQuery("<li/>",{role:"separator","class":"divider"}).appendTo(this.menu),this.separator.hide(),this.source=b,this.match_selected=c,this.format=d,this.action_activated=null,this._search_text=null,this.input.on("input",function(){window.setTimeout(this._input.bind(this),300,this.input.val())}.bind(this)),this.input.keydown(function(a){a.which==Sao.common.ESC_KEYCODE?this.dropdown.hasClass("open")&&this.menu.dropdown("toggle"):a.which==Sao.common.RETURN_KEYCODE&&(this.dropdown.hasClass("open")||this.menu.dropdown("toggle"))}.bind(this)),this.dropdown.on("hide.bs.dropdown",function(){this.input.focus(),this.input.closest(".treeview").css("overflow","")}.bind(this)),this.dropdown.on("show.bs.dropdown",function(){this.input.closest(".treeview").css("overflow","visible")}.bind(this))},set_actions:function(a,b){return void 0!==b&&(this.action_activated=b),this.menu.find("li.action").remove(),jQuery.isEmptyObject(a)?void this.separator.hide():(this.separator.show(),void a.forEach(function(a){var b=a[0],c=a[1];jQuery("<li/>",{"class":"action action-"+b}).append(jQuery("<a/>",{href:"#"}).append(this._format_action(c))).click(function(){this.action_activated&&this.action_activated(b),this.input.val("")}.bind(this)).appendTo(this.menu)},this))},_format:function(a){return this.format?this.format(a):a},_format_action:function(a){return this.format_action?this.format_action(a):a},_input:function(a){if(a==this.input.val()){var b;b=this.source instanceof Array?jQuery.when(source.filter(function(b){return b.toLowerCase().startsWith(a.toLowerCase())})):this.source(a),b.then(function(b){a==this.input.val()&&this._set_selection(b)}.bind(this))}},_set_selection:function(a){void 0===a&&(a=[]),this.menu.find("li.completion").remove(),a.reverse().forEach(function(a){jQuery("<li/>",{"class":"completion"}).append(jQuery("<a/>",{href:"#"}).append(this._format(a))).click(function(){this.match_selected&&this.match_selected(a),this.input.focus()}.bind(this)).prependTo(this.menu)},this),this.input.val()?this.dropdown.hasClass("open")||this.menu.dropdown("toggle"):this.dropdown.hasClass("open")&&this.menu.dropdown("toggle")}}),Sao.common.get_completion=function(a,b,c,d){var e=function(a){return a.rec_name},f=new Sao.common.InputCompletion(a,b,c,e);f.set_actions([["search",Sao.i18n.gettext("Search...")],["create",Sao.i18n.gettext("Create...")]],d)},Sao.common.update_completion=function(a,b,c,d,e){var f=a.val();if(!f||!d)return jQuery.when();void 0===e&&(e=c.get_domain(b));var g=c.get_context(b);e=[["rec_name","ilike","%"+f+"%"],e];var h=new Sao.Model(d);return h.execute("search_read",[e,0,Sao.config.limit,null,["rec_name"]],g)},Sao.common.Paned=Sao.class_(Object,{init:function(a){var b;this._orientation=a,this.el=jQuery("<div/>"),"horizontal"==a?(b=jQuery("<div/>",{"class":"row"}).appendTo(this.el),this.child1=jQuery("<div/>",{"class":"col-md-6"}).appendTo(b),this.child2=jQuery("<div/>",{"class":"col-md-6"}).appendTo(b)):"vertical"==a&&(this.child1=jQuery("<div/>",{"class":"row"}).appendTo(this.el),this.child2=jQuery("<div/>",{"class":"row"}).appendTo(this.el))},get_child1:function(){return this.child1},get_child2:function(){return this.child2}}),Sao.common.get_focus_chain=function(a){var b=a.find("input","textarea");return b.sort(function(a,b){if("tabindex"in a.attributes&&"tabindex"in b.attributes){var c=parseInt(a.attributes.tabindex.value),d=parseInt(b.attributes.tabindex.value);return c-d}return"tabindex"in a.attributes?-1:"tabindex"in b.attributes?1:0}),b},Sao.common.find_focusable_child=function(a){var b,c,d,e;if(!a.is(":visible"))return null;if(~["input","select","textarea"].indexOf(a[0].tagName.toLowerCase()))return a;for(d=Sao.common.get_focus_chain(a),b=0,c=d.length;c>b;b++)if(e=Sao.common.find_focusable_child(jQuery(d[b])))return e},Sao.common.find_first_focus_widget=function(a,b){var c,d,e,f,g;if(1==b.length)return jQuery(b[0]);for(e=Sao.common.get_focus_chain(a),c=0;c<e.length;c++){for(f=[],d=0;d<b.length;d++)g=jQuery(b[d]).closest(e[c]).length>0,g&&f.push(b[d]);if(f.length>0)return Sao.common.find_first_focus_widget(jQuery(e[c]),f)}},Sao.common.apply_label_attributes=function(a,b,c){b?a.removeClass("editable required"):(a.addClass("editable"),c?a.addClass("required"):a.removeClass("required"))},Sao.common.download_file=function(a,b){var c=Sao.common.guess_mimetype(b?b.split(".").pop():void 0),d=new Blob([a],{type:c}),e=window.URL.createObjectURL(d),f=new Sao.Dialog(Sao.i18n.gettext("Download")),g=function(){f.modal.modal("hide")},h=jQuery("<a/>",{href:e,download:b,text:b,target:"_blank"}).appendTo(f.body).append(jQuery("<span/>",{"class":"glyphicon glyphicon-download-alt"})).click(g);jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Close")).click(g).appendTo(f.footer);f.modal.on("shown.bs.modal",function(){h[0].click()}),f.modal.modal("show"),f.modal.on("hidden.bs.modal",function(){jQuery(this).remove(),window.URL.revokeObjectURL(this.blob_url)})},Sao.common.ellipsize=function(a,b){if(a.length<=b)return a;var c=Sao.i18n.gettext("...");return a.slice(0,b-c.length)+c}}(),function(){"use strict";Sao.Window={},Sao.Window.InfoBar=Sao.class_(Object,{init:function(){this.text=jQuery("<span/>"),this.text.css("white-space","pre-wrap"),this.el=jQuery("<div/>",{"class":"alert infobar",role:"alert"}).append(jQuery("<button/>",{type:"button","class":"close","aria-label":Sao.i18n.gettext("Close")}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).click(function(){this.el.hide()}.bind(this))).append(this.text),this.el.hide()},message:function(a,b){a?(this.el.removeClass("alert-success alert-info alert-warning alert-danger"),this.el.addClass("alert-"+(b||"info")),this.text.text(a),this.el.show()):this.el.hide()}}),Sao.Window.Form=Sao.class_(Object,{init:function(a,b,c){c=c||{},this.screen=a,this.callback=b,this.many=c.many||0,this.domain=c.domain||null,this.context=c.context||null,this.save_current=c.save_current;var d=jQuery.when(c.title||"");d.then(function(a){this.title=a}.bind(this)),this.prev_view=a.current_view,this.screen.screen_container.alternate_view=!0,this.info_bar=new Sao.Window.InfoBar;for(var e=c.view_type||"form",f=jQuery.when(),g=[],h=0,i=this.screen.views.length;i>h;h++)g.push(this.screen.views[h].view_type);~g.indexOf(e)||~this.screen.view_to_load.indexOf(e)||(f=this.screen.add_view_id(null,e));var j=f.then(function(){return this.screen.switch_view(e).done(function(){c.new_&&this.screen.new_(void 0,c.rec_name)}.bind(this))}.bind(this)),k=new Sao.Dialog("","window-form","lg");this.el=k.modal;var l=this.screen.attributes.readonly||this.screen.group.get_readonly();if("form"==e&&k.footer.append(jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(!c.new_&&this.screen.current_record.id<0?Sao.i18n.gettext("Delete"):Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this))),c.new_&&this.many&&k.footer.append(jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("New")).click(function(){this.response("RESPONSE_ACCEPT")}.bind(this))),this.save_current?k.footer.append(jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Save"))):k.footer.append(jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK"))),k.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),"tree"==e){var m=jQuery("<div/>",{"class":"window-form-toolbar"}).appendTo(k.body),n=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(m);this.wid_text=jQuery("<input/>",{type:"input"}).appendTo(m),this.wid_text.hide();var o=jQuery("<div/>",{"class":"input-group-btn"}).appendTo(n),p=Sao.common.MODELACCESS.get(this.screen.model_name);this.domain&&(this.wid_text.show(),this.but_add=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-plus"})).appendTo(o),this.but_add.click(this.add.bind(this)),this.but_add.prop("disabled",!p.read||l),this.but_remove=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-minus"})).appendTo(o),this.but_remove.click(this.remove.bind(this)),this.but_remove.prop("disabled",!p.read||l)),this.but_new=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("New")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-edit"})).appendTo(o),this.but_new.click(this.new_.bind(this)),this.but_new.prop("disabled",!p.create||l),this.but_del=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Delete")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-trash"})).appendTo(o),this.but_del.click(this.delete_.bind(this)),this.but_del.prop("disabled",!p["delete"]||l),this.but_undel=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Undelete")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-repeat"})).appendTo(o),this.but_undel.click(this.undelete.bind(this)),this.but_undel.prop("disabled",!p["delete"]||l),this.but_previous=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-chevron-left"})).appendTo(o),this.but_previous.click(this.previous.bind(this)),this.label=jQuery("<span/>",{"class":"btn"}).appendTo(o),this.label.text("(0, 0)"),this.but_next=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-chevron-right"})).appendTo(o),this.but_next.click(this.next.bind(this)),this.but_switch=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Switch")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-list-alt"})).appendTo(o),this.but_switch.click(this.switch_.bind(this))}var q=jQuery("<div/>").appendTo(k.body);k.body.append(this.info_bar.el),j.done(function(){d.done(k.add_title.bind(k)),q.append(this.screen.screen_container.alternate_viewport),this.el.modal("show")}.bind(this)),this.el.on("shown.bs.modal",function(a){this.screen.display().done(function(){this.screen.set_cursor()}.bind(this))}.bind(this)),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},add:function(){var a=jQuery.extend([],this.domain),b=this.screen.model_name,c=this.wid_text.val(),d=function(a){var b=jQuery.when();if(!jQuery.isEmptyObject(a)){for(var c=[],d=0,e=a.length;e>d;d++)c.push(a[d][0]);this.screen.group.load(c,!0),b=this.screen.display()}b.done(function(){this.screen.set_cursor()}.bind(this)),this.entry.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(b,d,{sel_multi:!0,context:this.context,domain:a,search_filter:e.quote(c)})},remove:function(){this.screen.remove(!1,!0,!1)},new_:function(){this.screen.new_()},delete_:function(){this.screen.remove(!1,!1,!1)},undelete:function(){this.screen.unremove()},previous:function(){this.screen.display_previous()},next:function(){this.screen.display_next()},switch_:function(){this.screen.switch_view()},response:function(a){var b;this.screen.current_view.set_value();var c=this.screen.group.get_readonly();if(~["RESPONSE_OK","RESPONSE_ACCEPT"].indexOf(a)&&!c&&this.screen.current_record)return void this.screen.current_record.validate().then(function(a){return a&&this.screen.attributes.pre_validate?this.screen.current_record.pre_validate():a}.bind(this)).then(function(c){var d=jQuery.Deferred();if(c&&this.save_current)this.screen.save_current().then(d.resolve,d.reject);else if(c&&"form"==this.screen.current_view.view_type){var e=this.screen.current_view,f=[];for(var g in e.widgets){var h=e.widgets[g];if(h.screen&&h.screen.attributes.pre_validate){var i=h.screen.current_record;i&&f.push(i.pre_validate())}}jQuery.when.apply(jQuery,f).then(d.resolve,d.reject)}else c?(this.info_bar.message(),d.resolve()):(this.info_bar.message(this.screen.invalid_message(),"danger"),d.reject());d.fail(function(){this.screen.display().done(function(){this.screen.set_cursor()}.bind(this))}.bind(this)),d.done(function(){"RESPONSE_ACCEPT"==a?(this.screen.new_(),this.screen.current_view.display().done(function(){this.screen.set_cursor()}.bind(this)),this.many-=1,0===this.many&&this.but_new.prop("disabled",!0)):(b=!0,this.callback(b),this.destroy())}.bind(this))}.bind(this));if("RESPONSE_CANCEL"==a&&!c&&this.screen.current_record){if(b=!1,this.screen.current_record.id<0||this.save_current)this.screen.cancel_current();else if(this.screen.current_record.has_changed())return this.screen.current_record.cancel(),void this.screen.current_record.reload().always(function(){this.callback(b),this.destroy()}.bind(this))}else b="RESPONSE_CANCEL"!=a;this.callback(b),this.destroy()},destroy:function(){this.screen.screen_container.alternate_view=!1,this.screen.screen_container.alternate_viewport.children().detach(),this.prev_view&&this.screen.switch_view(this.prev_view.view_type),this.el.modal("hide")}}),Sao.Window.Attachment=Sao.class_(Sao.Window.Form,{init:function(a,b){this.resource=a.model.name+","+a.id,this.attachment_callback=b;var c=jQuery.extend({},a.get_context()),d=new Sao.Screen("ir.attachment",{domain:[["resource","=",this.resource]],mode:["tree","form"],context:c,exclude_field:"resource"});d.switch_view().done(function(){d.search_filter()});var e=a.rec_name().then(function(a){return Sao.i18n.gettext("Attachments (%1)",a)});Sao.Window.Attachment._super.init.call(this,d,this.callback,{view_type:"tree",title:e})},callback:function(a){var b=jQuery.when();if(a){var c=this.screen.group.model.fields.resource;this.screen.group.forEach(function(a){c.set_client(a,this.resource)}.bind(this)),b=this.screen.save_current()}this.attachment_callback&&b.always(this.attachment_callback.bind(this))}}),Sao.Window.Note=Sao.class_(Sao.Window.Form,{init:function(a,b){this.resource=a.model.name+","+a.id,this.note_callback=b;var c=jQuery.extend({},a.get_context()),d=new Sao.Screen("ir.note",{domain:[["resource","=",this.resource]],mode:["tree","form"],context:c,exclude_field:"resource"});d.switch_view().done(function(){d.search_filter()});var e=a.rec_name().then(function(a){return Sao.i18n.gettext("Notes (%1)",a)});Sao.Window.Note._super.init.call(this,d,this.callback,{view_type:"tree",title:e})},callback:function(a){var b=jQuery.when();if(a){var c=this.screen.group.model.fields.resource,d=this.screen.group.model.fields.unread;this.screen.group.forEach(function(a){(a.get_loaded()||a.id<0)&&(c.set_client(a,this.resource),a._changed.unread||d.set_client(a,!1))}.bind(this)),b=this.screen.save_current()}this.note_callback&&b.always(this.note_callback.bind(this))}}),Sao.Window.Search=Sao.class_(Object,{init:function(a,b,c){c=c||{};var d=c.views_preload||{};this.model_name=a,this.domain=c.domain||[],this.context=c.context||{},this.sel_multi=c.sel_multi,this.callback=b,this.title=c.title||"";var e=new Sao.Dialog(Sao.i18n.gettext("Search %1",this.title),"","lg");this.el=e.modal,jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(e.footer),jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Find")).click(function(){this.response("RESPONSE_APPLY")}.bind(this)).appendTo(e.footer),c.new_&&Sao.common.MODELACCESS.get(a).create&&jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("New")).click(function(){this.response("RESPONSE_ACCEPT")}.bind(this)).appendTo(e.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(e.footer),e.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),this.screen=new Sao.Screen(a,{mode:["tree"],context:this.context,domain:this.domain,view_ids:c.view_ids,views_preload:d,row_activate:this.activate.bind(this)}),this.screen.load_next_view().done(function(){this.screen.switch_view().done(function(){e.body.append(this.screen.screen_container.el),this.el.modal("show"),this.screen.display(),void 0!==c.search_filter&&this.screen.search_filter(c.search_filter)}.bind(this))}.bind(this)),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},activate:function(){this.response("RESPONSE_OK")},response:function(a){var b,c=[];if("RESPONSE_OK"==a)b=this.screen.current_view.selected_records();else{if("RESPONSE_APPLY"==a)return void this.screen.search_filter();if("RESPONSE_ACCEPT"==a){var d=new Sao.Screen(this.model_name,{domain:this.domain,context:this.context,mode:["form"]}),e=function(a){if(a){var b=d.current_record;this.callback([[b.id,b._values.rec_name||""]])}else this.callback(null)};return this.el.modal("hide"),void new Sao.Window.Form(d,e.bind(this),{new_:!0,save_current:!0,title:this.title})}}if(b){var f,g;for(f in b)g=b[f],c.push([g.id,g._values.rec_name||""])}this.callback(c),this.el.modal("hide")}}),Sao.Window.Preferences=Sao.class_(Object,{init:function(a){this.callback=a;var b=new Sao.Dialog("Preferences","","lg");this.el=b.modal,jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(b.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(b.footer),b.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),this.screen=new Sao.Screen("res.user",{mode:[]}),this.screen.attributes.readonly=!1,this.screen.group.set_readonly(!1),this.screen.group.skip_model_access=!0;var c=function(a){this.screen.add_view(a),this.screen.switch_view().done(function(){this.screen.new_(!1),this.screen.model.execute("get_preferences",[!1],{}).then(d.bind(this),this.destroy)}.bind(this))},d=function(a){var c;this.screen.current_record.cancel(),c=this.screen.current_record.set(a),this.screen.current_record.id=this.screen.model.session.user_id,c.then(function(){this.screen.current_record.validate(null,!0).then(function(){this.screen.display(!0)}.bind(this))}.bind(this)),b.body.append(this.screen.screen_container.el),this.el.modal("show")};this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()}),this.screen.model.execute("get_preferences_fields_view",[],{}).then(c.bind(this),this.destroy)},response:function(a){var b=function(){this.destroy(),this.callback()}.bind(this),c=jQuery.when();"RESPONSE_OK"==a&&(c=this.screen.current_record.validate().then(function(a){if(a){var b=jQuery.extend({},this.screen.get()),c=jQuery.extend({},Sao.Session.current_session.context),d=function(a){return{id:0,method:"model.res.user.set_preferences",params:[b,a,c]}};return new Sao.Login(d).run()}}.bind(this))),c.done(b)},destroy:function(){this.el.modal("hide")}}),Sao.Window.Revision=Sao.class_(Object,{init:function(a,b){this.callback=b;var c=new Sao.Dialog(Sao.i18n.gettext("Revision"),"","lg");this.el=c.modal,jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(c.footer),c.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this));var d=jQuery("<div/>",{"class":"form-group"}).appendTo(c.body);jQuery("<label/>",{"for":"revision",text:"Revision"}).appendTo(d),this.select=jQuery("<select/>",{"class":"form-control",id:"revision",placeholder:Sao.i18n.gettext("Revision")}).appendTo(d);var e=Sao.common.date_format(),f="%H:%M:%S.%f";this.select.append(jQuery("<option/>",{value:null,text:""})),a.forEach(function(a){a[2];a=a[0],this.select.append(jQuery("<option/>",{value:a.valueOf(),text:Sao.common.format_datetime(e,f,a)+" "+this.title}))}.bind(this)),this.el.modal("show"),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},response:function(a){var b=null;"RESPONSE_OK"==a&&(b=this.select.val(),b&&(b=Sao.DateTime(parseInt(b,10)))),this.el.modal("hide"),this.callback(b)}}),Sao.Window.CSV=Sao.class_(Object,{init:function(a){this.encodings=["866","ansi_x3.4-1968","arabic","ascii","asmo-708","big5","big5-hkscs","chinese","cn-big5","cp1250","cp1251","cp1252","cp1253","cp1254","cp1255","cp1256","cp1257","cp1258","cp819","cp866","csbig5","cseuckr","cseucpkdfmtjapanese","csgb2312","csibm866","csiso2022jp","csiso2022kr","csiso58gb231280","csiso88596e","csiso88596i","csiso88598e","csiso88598i","csisolatin1","csisolatin2","csisolatin3","csisolatin4","csisolatin5","csisolatin6","csisolatin9","csisolatinarabic","csisolatincyrillic","csisolatingreek","csisolatinhebrew","cskoi8r","csksc56011987","csmacintosh","csshiftjis","cyrillic","dos-874","ecma-114","ecma-118","elot_928","euc-jp","euc-kr","gb18030","gb2312","gb_2312","gb_2312-80","gbk","greek","greek8","hebrew","hz-gb-2312","ibm819","ibm866","iso-2022-cn","iso-2022-cn-ext","iso-2022-jp","iso-2022-kr","iso-8859-1","iso-8859-10","iso-8859-11","iso-8859-13","iso-8859-14","iso-8859-15","iso-8859-16","iso-8859-2","iso-8859-3","iso-8859-4","iso-8859-5","iso-8859-6","iso-8859-6-e","iso-8859-6-i","iso-8859-7","iso-8859-8","iso-8859-8-e","iso-8859-8-i","iso-8859-9","iso-ir-100","iso-ir-101","iso-ir-109","iso-ir-110","iso-ir-126","iso-ir-127","iso-ir-138","iso-ir-144","iso-ir-148","iso-ir-149","iso-ir-157","iso-ir-58","iso8859-1","iso8859-10","iso8859-11","iso8859-13","iso8859-14","iso8859-15","iso8859-2","iso8859-3","iso8859-4","iso8859-5","iso8859-6","iso8859-7","iso8859-8","iso8859-9","iso88591","iso885910","iso885911","iso885913","iso885914","iso885915","iso88592","iso88593","iso88594","iso88595","iso88596","iso88597","iso88598","iso88599","iso_8859-1","iso_8859-15","iso_8859-1:1987","iso_8859-2","iso_8859-2:1987","iso_8859-3","iso_8859-3:1988","iso_8859-4","iso_8859-4:1988","iso_8859-5","iso_8859-5:1988","iso_8859-6","iso_8859-6:1987","iso_8859-7","iso_8859-7:1987","iso_8859-8","iso_8859-8:1988","iso_8859-9","iso_8859-9:1989","koi","koi8","koi8-r","koi8-ru","koi8-u","koi8_r","korean","ks_c_5601-1987","ks_c_5601-1989","ksc5601","ksc_5601","l1","l2","l3","l4","l5","l6","l9","latin1","latin2","latin3","latin4","latin5","latin6","logical","mac","macintosh","ms932","ms_kanji","shift-jis","shift_jis","sjis","sun_eu_greek","tis-620","unicode-1-1-utf-8","us-ascii","utf-16","utf-16be","utf-16le","utf-8","utf8","visual","windows-1250","windows-1251","windows-1252","windows-1253","windows-1254","windows-1255","windows-1256","windows-1257","windows-1258","windows-31j","windows-874","windows-949","x-cp1250","x-cp1251","x-cp1252","x-cp1253","x-cp1254","x-cp1255","x-cp1256","x-cp1257","x-cp1258","x-euc-jp","x-gbk","x-mac-cyrillic","x-mac-roman","x-mac-ukrainian","x-sjis","x-user-defined","x-x-big5"],this.dialog=new Sao.Dialog(a,"csv","lg"),this.el=this.dialog.modal,this.fields={},this.fields_model={},jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(this.dialog.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).click(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)).appendTo(this.dialog.footer);var b=jQuery("<div/>",{"class":"row"}).appendTo(this.dialog.body);jQuery("<hr/>").appendTo(this.dialog.body);var c=jQuery("<div/>",{"class":"col-md-4 column-fields"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("All Fields")})).appendTo(b);this.fields_all=jQuery("<ul/>",{"class":"list-unstyled"}).css("cursor","pointer").appendTo(c);var d=this.get_fields(this.screen.model_name).then(function(a){this.model_populate(a),this.view_populate(this.fields_model,this.fields_all)}.bind(this));this.column_buttons=jQuery("<div/>",{"class":"col-md-4"}).append("<label/>").appendTo(b);jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-plus"})).click(function(){this.fields_all.find(".bg-primary").each(function(a,b){this.sig_sel_add(b)}.bind(this))}.bind(this)).append(" "+Sao.i18n.gettext("Add")).appendTo(this.column_buttons);jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-minus"})).click(function(){this.fields_selected.children("li.bg-primary").remove()}.bind(this)).append(" "+Sao.i18n.gettext("Remove")).appendTo(this.column_buttons),jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-remove"})).click(function(){this.fields_selected.empty()}.bind(this)).append(" "+Sao.i18n.gettext("Clear")).appendTo(this.column_buttons),jQuery("<hr>").appendTo(this.column_buttons);var e=jQuery("<div/>",{"class":"col-md-4 column-fields"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("Fields Selected")})).appendTo(b);this.fields_selected=jQuery("<ul/>",{"class":"list-unstyled"}).css("cursor","pointer").appendTo(e),this.chooser_form=jQuery("<div/>",{"class":"form-inline"}).appendTo(this.dialog.body);var f=jQuery("<div/>",{"class":"row"}).appendTo(this.dialog.body),g=jQuery("<span/>",{"class":"glyphicon glyphicon-plus"}).css("cursor","pointer").html(" "),h=jQuery("<label/>",{text:Sao.i18n.gettext("CSV Parameters")}).css("cursor","pointer");jQuery("<div/>",{"class":"col-md-12"}).append(g).append(h).on("click",function(){g.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),this.expander_csv.collapse("toggle")}.bind(this)).appendTo(f),this.expander_csv=jQuery("<div/>",{id:"expander_csv","class":"collapse"}).appendTo(f);var i=jQuery("<label/>",{text:Sao.i18n.gettext("Delimiter:"),"class":"col-sm-2 control-label","for":"input-delimiter"});this.el_csv_delimiter=jQuery("<input/>",{type:"text","class":"form-control",id:"input-delimiter",size:"1",maxlength:"1",value:","}),jQuery("<div/>",{"class":"form-group"}).append(i).append(jQuery("<div/>",{"class":"col-sm-4"}).append(this.el_csv_delimiter)).appendTo(this.expander_csv);var j=jQuery("<label/>",{text:Sao.i18n.gettext("Quote Char:"),"class":"col-sm-2 control-label","for":"input-quotechar"});this.el_csv_quotechar=jQuery("<input/>",{type:"text","class":"form-control",id:"input-quotechar",size:"1",maxlength:"1",value:'"'}),jQuery("<div/>",{"class":"form-group"}).append(j).append(jQuery("<div/>",{"class":"col-sm-4"}).append(this.el_csv_quotechar)).appendTo(this.expander_csv);var k=jQuery("<label/>",{text:Sao.i18n.gettext("Encoding:"),"class":"col-sm-2 control-label","for":"input-encoding"});this.el_csv_encoding=jQuery("<select/>",{"class":"form-control",id:"input-encoding"});for(var l=0;l<this.encodings.length;l++)jQuery("<option/>",{val:this.encodings[l]}).html(this.encodings[l]).appendTo(this.el_csv_encoding);var m="utf-8";return"Win32"!=navigator.platform&&"Windows"!=navigator.platform||(m="cp1252"),this.el_csv_encoding.children('option[value="'+m+'"]').attr("selected","selected"),jQuery("<div/>",{"class":"form-group"}).append(k).append(jQuery("<div/>",{"class":"col-sm-4"}).append(this.el_csv_encoding)).appendTo(this.expander_csv),this.el.modal("show"),this.el.on("hidden.bs.modal",function(){jQuery(this).remove()}),d},get_fields:function(a){return Sao.rpc({method:"model."+a+".fields_get"},this.session)},on_row_expanded:function(a){var b=jQuery("<ul/>").css("list-style","none").insertAfter(a.view);this.children_expand(a).done(function(){this.view_populate(a.children,b)}.bind(this))},destroy:function(){this.el.modal("hide")}}),Sao.Window.Import=Sao.class_(Sao.Window.CSV,{init:function(a){this.screen=a,this.session=Sao.Session.current_session,this.fields_data={},this.fields_invert={},Sao.Window.Import._super.init.call(this,Sao.i18n.gettext("Import from CSV")),jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-search"})).click(function(){this.autodetect()}.bind(this)).append(" "+Sao.i18n.gettext("Auto-Detect")).appendTo(this.column_buttons);var b=jQuery("<label/>",{text:Sao.i18n.gettext("File to Import"),"class":"col-sm-6 control-label","for":"input-csv-file"});this.file_input=jQuery("<input/>",{type:"file",id:"input-csv-file"}),jQuery("<div/>",{"class":"form-group"}).append(b).append(jQuery("<div/>",{"class":"col-sm-6"}).append(this.file_input)).appendTo(this.chooser_form),jQuery("<hr>").insertAfter(this.chooser_form);var c=jQuery("<label/>",{text:Sao.i18n.gettext("Lines to Skip:"),"class":"col-sm-2 control-label","for":"input-skip"});this.el_csv_skip=jQuery("<input/>",{type:"number","class":"form-control",id:"input-skip",value:"0"}),jQuery("<div/>",{"class":"form-group"}).append(c).append(jQuery("<div/>",{"class":"col-sm-4"}).append(this.el_csv_skip)).appendTo(this.expander_csv)},sig_sel_add:function(a){a=jQuery(a);var b=a.attr("field"),c=jQuery("<li/>",{field:b}).html(a.attr("name")).click(function(a){a.ctrlKey?c.toggleClass("bg-primary"):jQuery(a.target).addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},view_populate:function(a,b){var c=Object.keys(a).sort(function(b,c){return a[c].string<a[b].string?-1:1}).reverse();c.forEach(function(c){
-var d=a[c].string||c,e=jQuery("<li/>",{field:a[c].field,name:a[c].name}).html(d).click(function(a){a.ctrlKey?e.toggleClass("bg-primary"):(this.fields_all.find("li").removeClass("bg-primary"),e.addClass("bg-primary"))}.bind(this)).appendTo(b);if(a[c].view=e,a[c].relation){e.prepend(" ");var f=jQuery("<i/>",{"class":"glyphicon glyphicon-plus"}).click(function(b){b.stopPropagation(),f.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),f.hasClass("glyphicon-minus")?this.on_row_expanded(a[c]):e.next("ul").remove()}.bind(this)).prependTo(e)}}.bind(this))},model_populate:function(a,b,c,d){b=b||this.fields_model,c=c||"",d=d||"",Object.keys(a).forEach(function(e){if(!a[e].readonly){var f=a[e].string||e;f=d+f;var g;g="one2many"==a[e].type?a[e].relation:null;var h={name:f,field:c+e,relation:g,string:a[e].string};b[e]=h,this.fields[c+e]=h,this.fields_invert[f]=c+e,g&&(h.children={})}}.bind(this))},children_expand:function(a){var b=jQuery.Deferred();return jQuery.isEmptyObject(a.children)?this.get_fields(a.relation).done(function(c){this.model_populate(c,a.children,a.field+"/",a.name+"/"),b.resolve(this)}.bind(this)):b.resolve(this),b.promise()},autodetect:function(){var a=this.file_input.val();return a?(this.fields_selected.empty(),this.el_csv_skip.val(1),void Papa.parse(this.file_input[0].files[0],{config:{delimiter:this.el_csv_delimiter.val(),quoteChar:this.el_csv_quotechar.val(),preview:1,encoding:this.el_csv_encoding.val()},error:function(a,b,c,d){Sao.common.warning(Sao.i18n.gettext("Error occured in loading the file"))},complete:function(a){a.data[0].forEach(function(a){if(a in this.fields_invert||a in this.fields)this.auto_select(a);else{var b=this.fields_model,c="",d=a.split("/");this.traverse(b,c,d,0)}}.bind(this))}.bind(this)})):void Sao.common.message.run(Sao.i18n.gettext("You must select an import file first"))},auto_select:function(a){var b,c;if(a in this.fields_invert)b=a,c=this.fields_invert[a];else{if(!(a in this.fields))return void Sao.common.warning.run(Sao.i18n.gettext("Error processing the file at field %1.",a),Sao.i18n.gettext("Error"));b=this.fields[a].name,c=[a]}var d=jQuery("<li/>",{field:c}).html(b).click(function(){d.addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},traverse:function(a,b,c,d){function e(e){a=f.children,b+=c[d]+"/",e.traverse(a,b,c,++d)}if(d>=c.length-1)return void this.auto_select(c.join("/"));var f,g,h=Object.keys(a);for(g=0;g<h.length;g++)if(f=a[h[g]],f.name==b+c[d]||f.field==b+c[d]){this.children_expand(f).done(e);break}return g==h.length?void this.auto_select(c.join("/")):void 0},response:function(a){if("RESPONSE_OK"==a){var b=[];this.fields_selected.children("li").each(function(a,c){b.push(c.getAttribute("field"))});var c=this.file_input.val();c?this.import_csv(c,b).then(function(){this.destroy()}.bind(this)):this.destroy()}else this.destroy()},import_csv:function(a,b){var c=this.el_csv_skip.val(),d=this.el_csv_encoding.val(),e=jQuery.Deferred();return Papa.parse(this.file_input[0].files[0],{config:{delimiter:this.el_csv_delimiter.val(),quoteChar:this.el_csv_quotechar.val(),encoding:d},error:function(a,b,c,d){Sao.common.warning.run(Sao.i18n.gettext("Error occured in loading the file")).always(e.reject)},complete:function(a){function d(a){return unescape(encodeURIComponent(a))}var f=[];a.data.pop(""),a.data.forEach(function(a,b){if(!(c>b)){var e=[];a.forEach(function(a){e.push(d(a))}),f.push(e)}}),Sao.rpc({method:"model."+this.screen.model_name+".import_data",params:[b,f,{}]},this.session).then(function(a){return Sao.common.message.run(Sao.i18n.ngettext("%1 record imported","%1 records imported",a))}).then(e.resolve,e.reject)}.bind(this)}),e.promise()}}),Sao.Window.Export=Sao.class_(Sao.Window.CSV,{init:function(a,b,c,d){this.ids=b,this.screen=a,this.session=Sao.Session.current_session,this.context=d,Sao.Window.Export._super.init.call(this,Sao.i18n.gettext("Export to CSV")).then(function(){c.forEach(function(a){this.sel_field(a)}.bind(this))}.bind(this));var e=jQuery("<div/>",{"class":"row"}).prependTo(this.dialog.body),f=jQuery("<div/>",{"class":"col-md-12"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("Predefined Exports")})).appendTo(e);this.predef_exports_list=jQuery("<ul/>",{"class":"list-unstyled predef-exports"}).css("cursor","pointer").appendTo(f),f.append("<hr/>"),this.predef_exports={},this.fill_predefwin(),jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-floppy-save"})).click(function(){this.addreplace_predef()}.bind(this)).append(" "+Sao.i18n.gettext("Save Export")).appendTo(this.column_buttons),jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-floppy-remove"})).click(function(){this.remove_predef()}.bind(this)).append(" "+Sao.i18n.gettext("Delete Export")).appendTo(this.column_buttons),this.el_add_field_names=jQuery("<input/>",{type:"checkbox",checked:"checked"}),jQuery("<div/>",{"class":"form-group"}).append(jQuery("<div/>",{"class":"col-md-6"}).append(jQuery("<label/>",{text:" "+Sao.i18n.gettext("Add Field Names")}).prepend(this.el_add_field_names))).appendTo(this.expander_csv)},view_populate:function(a,b){var c=Object.keys(a).sort(function(b,c){return a[c].string<a[b].string?-1:1}).reverse();c.forEach(function(c){var d=a[c].path,e=jQuery("<li/>",{path:d}).html(a[c].string).click(function(a){a.ctrlKey?e.toggleClass("bg-primary"):(this.fields_all.find("li").removeClass("bg-primary"),e.addClass("bg-primary"))}.bind(this)).appendTo(b);if(a[c].view=e,a[c].children){e.prepend(" ");var f=jQuery("<i/>",{"class":"glyphicon glyphicon-plus"}).click(function(b){b.stopPropagation(),f.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),f.hasClass("glyphicon-minus")?this.on_row_expanded(a[c]):e.next("ul").remove()}.bind(this)).prependTo(e)}}.bind(this))},model_populate:function(a,b,c,d){b=b||this.fields_model,c=c||"",d=d||"",Object.keys(a).forEach(function(e){var f=a[e],g=f.string||e,h=[{name:e,field:f,string:g}];"selection"==f.type&&h.push({name:e+".translated",field:f,string:Sao.i18n.gettext("%1 (string)",g)}),h.forEach(function(a){var e=c+a.name,f=a.string;c&&(f=d+a.string);var g={path:e,string:a.string,long_string:f,relation:a.field.relation};b[a.name]=g,this.fields[e]=g,-1==a.name.indexOf(".")&&a.field.relation&&(g.children={})}.bind(this))}.bind(this))},children_expand:function(a){var b=jQuery.Deferred();return jQuery.isEmptyObject(a.children)?this.get_fields(a.relation).done(function(c){this.model_populate(c,a.children,a.path+"/",a.string+"/"),b.resolve(this)}.bind(this)):b.resolve(this),b.promise()},sig_sel_add:function(a){a=jQuery(a);var b=a.attr("path");this.sel_field(b)},fill_predefwin:function(){Sao.rpc({method:"model.ir.export.search",params:[["resource","=",this.screen.model_name],{}]},this.session).done(function(a){Sao.rpc({method:"model.ir.export.read",params:[a,{}]},this.session).done(function(a){var b=[];a.forEach(function(a){for(var c=0;c<a.export_fields.length;b.push(a.export_fields[c++]));}),Sao.rpc({method:"model.ir.export.line.read",params:[b,{}]},this.session).done(function(b){var c={};b.forEach(function(a){c[a["export"]]=c[a["export"]]||[],c[a["export"]].push(a)}),a.forEach(function(a){this.predef_exports[a.id]=c[a.id].map(function(b){return b["export"]==a.id?b.name:void 0}),this.add_to_predef(a.id,a.name)}.bind(this)),this.predef_exports_list.children("li").first().focus()}.bind(this))}.bind(this))}.bind(this))},add_to_predef:function(a,b){var c=jQuery("<li/>",{text:b,export_id:a,tabindex:0}).on("keypress",function(a){var b=a.keyCode?a.keyCode:a.which;13!=b&&32!=b||c.click()}).click(function(a){c.addClass("bg-primary").siblings().removeClass("bg-primary"),this.sel_predef(jQuery(a.target).attr("export_id"))}.bind(this));this.predef_exports_list.append(c)},addreplace_predef:function(){for(var a=[],b=this.fields_selected.children("li"),c=0;c<b.length;c++)a.push(b[c].getAttribute("path"));if(0!==a.length){var d,e,f=this.predef_exports_list.children("li.bg-primary");0===f.length?(d=null,Sao.common.ask.run(Sao.i18n.gettext("What is the name of this export?")).then(function(b){b&&this.save_predef(b,a,f)}.bind(this))):(d=f.attr("export_id"),e=f.text(),Sao.common.sur.run(Sao.i18n.gettext("Override %1 definition?",e)).done(function(){this.save_predef(e,a,f),Sao.rpc({method:"model.ir.export.delete",params:[[d],{}]},this.session).then(function(){delete this.predef_exports[d]}.bind(this))}.bind(this)))}},save_predef:function(a,b,c){Sao.rpc({method:"model.ir.export.create",params:[[{name:a,resource:this.screen.model_name,export_fields:[["create",b.map(function(a){return{name:a}})]]}],{}]},this.session).then(function(d){this.predef_exports[d]=b,0===c.length?this.add_to_predef(d,a):(this.predef_exports[d]=b,c.attr("export_id",d))}.bind(this))},remove_predef:function(){var a=this.predef_exports_list.children("li.bg-primary");if(0!==a.length){var b=jQuery(a).attr("export_id");Sao.rpc({method:"model.ir.export.delete",params:[[b],{}]},this.session).then(function(){delete this.predef_exports[b],a.remove()}.bind(this))}},sel_predef:function(a){this.fields_selected.empty(),this.predef_exports[a].forEach(function(a){if(!(a in this.fields)){var b=this.fields_model,c="",d=a.split("/");this.traverse(b,c,d,0)}a in this.fields&&this.sel_field(a)}.bind(this))},traverse:function(a,b,c,d){function e(e){a=f.children,b+=c[d]+"/",e.traverse(a,b,c,++d)}if(d>=c.length-1)return void this.sel_field(c.join("/"));var f,g,h=Object.keys(a);for(g=0;g<h.length;g++)if(f=a[h[g]],f.path==b+c[d]){this.children_expand(f).done(e);break}return g==h.length?void this.sel_field(c.join("/")):void 0},sel_field:function(a){var b=this.fields[a].long_string,c=this.fields[a].relation;if(!c)var d=jQuery("<li/>",{path:a}).html(b).click(function(a){a.ctrlKey?d.toggleClass("bg-primary"):jQuery(a.target).addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},response:function(a){if("RESPONSE_OK"==a){var b=[],c=[];this.fields_selected.children("li").each(function(a,d){b.push(d.getAttribute("path")),c.push(d.innerText)}),Sao.rpc({method:"model."+this.screen.model_name+".export_data",params:[this.ids,b,this.context]},this.session).then(function(a){this.export_csv(c,a).then(function(){this.destroy()}.bind(this))}.bind(this))}else this.destroy()},export_csv:function(a,b){var c=this.el_csv_encoding.val(),d={};d.data=b,this.el_add_field_names.is(":checked")&&(d.fields=a);var e=Papa.unparse(d,{quoteChar:this.el_csv_quotechar.val(),delimiter:this.el_csv_delimiter.val()}),f=new Blob([e],{type:"text/csv;charset="+c}),g=window.URL.createObjectURL(f);return this.blob_url&&window.URL.revokeObjectURL(this.blob_url),this.blob_url=g,window.open(g),Sao.common.message.run(Sao.i18n.ngettext("%1 record saved","%1 records saved",b.length))}})}(),function(){"use strict";Sao.Wizard=Sao.class_(Object,{init:function(a){this.widget=jQuery("<div/>",{"class":"wizard"}),this.name=a||"",this.action_id=null,this.id=null,this.ids=null,this.action=null,this.context=null,this.states={},this.session_id=null,this.start_state=null,this.end_state=null,this.screen=null,this.screen_state=null,this.state=null,this.session=Sao.Session.current_session,this.__processing=!1,this.__waiting_response=!1,this.info_bar=new Sao.Window.InfoBar},run:function(a){this.action=a.action,this.action_id=a.data.action_id,this.id=a.data.id,this.ids=a.data.ids,this.model=a.data.model,this.context=a.context,Sao.rpc({method:"wizard."+this.action+".create",params:[this.session.context]},this.session).then(function(a){this.session_id=a[0],this.start_state=this.state=a[1],this.end_state=a[2],this.process()}.bind(this),function(){this.destroy()}.bind(this))},process:function(){if(!this.__processing&&!this.__waiting_response){var a=function(){if(this.state==this.end_state)return void this.end();var a=jQuery.extend({},this.context);a.active_id=this.id,a.active_ids=this.ids,a.active_model=this.model,a.action_id=this.action_id;var b={};this.screen&&(b[this.screen_state]=this.screen.get_on_change_value()),Sao.rpc({method:"wizard."+this.action+".execute",params:[this.session_id,b,this.state,a]},this.session).then(function(a){if(a.view){this.clean();var b=a.view;this.update(b.fields_view,b.defaults,b.buttons),this.screen_state=b.state,this.__waiting_response=!0}else this.state=this.end_state;var c=function(){a.actions&&a.actions.forEach(function(a){Sao.Action.exec_action(a[0],a[1],jQuery.extend({},this.context))}.bind(this))}.bind(this);this.state==this.end_state?this.end().then(c):c(),this.__processing=!1}.bind(this),function(a){this.__processing=!1}.bind(this))};a.call(this)}},destroy:function(){},end:function(){return Sao.rpc({method:"wizard."+this.action+".delete",params:[this.session_id,this.session.context]},this.session)},clean:function(){this.widget.children().remove(),this.states={}},response:function(a){return this.__waiting_response=!1,this.screen.current_view.set_value(),this.screen.current_record.validate().then(function(b){return b||a==this.end_state?(this.info_bar.message(),this.state=a,void this.process()):(this.screen.display(!0),void this.info_bar.message(this.screen.invalid_message(),"danger"))}.bind(this))},_get_button:function(a){var b=new Sao.common.Button(a);return this.states[a.state]=b,a["default"]?b.el.addClass("btn-primary"):a.state==this.end_state&&b.el.addClass("btn-link"),b},update:function(a,b,c){c.forEach(function(a){this._get_button(a)}.bind(this)),this.screen=new Sao.Screen(a.model,{mode:[],context:this.context}),this.screen.add_view(a),this.screen.switch_view(),this.widget.append(this.screen.screen_container.el),this.screen.new_(!1),this.screen.current_record.set_default(b),this.screen.set_cursor()}}),Sao.Wizard.create=function(a){var b;if(a.window){b=new Sao.Wizard.Form(a.name);var c=new Sao.Tab.Wizard(b);Sao.Tab.add(c)}else b=new Sao.Wizard.Dialog(a.name);b.run(a)},Sao.Wizard.Form=Sao.class_(Sao.Wizard,{init:function(a){Sao.Wizard.Form._super.init.call(this),this.tab=null,this.name=a||"",this.form=jQuery("<div/>",{"class":"wizard-form"}).append(this.widget),this.footer=jQuery("<div/>",{"class":"modal-footer"}).appendTo(this.form)},clean:function(){Sao.Wizard.Form._super.clean.call(this),this.footer.children().remove()},_get_button:function(a){var b=Sao.Wizard.Form._super._get_button.call(this,a);return this.footer.append(b.el),b.el.click(function(){this.response(a.state)}.bind(this)),b},end:function(){return Sao.Wizard.Form._super.end.call(this).always(function(){return this.tab.close()}.bind(this))}}),Sao.Wizard.Dialog=Sao.class_(Sao.Wizard,{init:function(a){a||(a=Sao.i18n.gettext("Wizard")),Sao.Wizard.Dialog._super.init.call(this);var b=new Sao.Dialog(a,"wizard-dialog","lg");this.dialog=b.modal,this.dialog.on("shown.bs.modal",function(){Sao.View.resize(jQuery(this))}),this.content=b.content,this.footer=b.footer,b.body.append(this.widget).append(this.info_bar.el)},clean:function(){Sao.Wizard.Dialog._super.clean.call(this),this.footer.children().remove()},_get_button:function(a){var b=Sao.Wizard.Dialog._super._get_button.call(this,a);return this.footer.append(b.el),a["default"]?(this.content.unbind("submit"),this.content.submit(function(b){this.response(a.state),b.preventDefault()}.bind(this)),b.el.attr("type","submit")):b.el.click(function(){this.response(a.state)}.bind(this)),b},update:function(a,b,c){this.content.unbind("submit"),Sao.Wizard.Dialog._super.update.call(this,a,b,c),this.dialog.modal("show")},destroy:function(a){Sao.Wizard.Dialog._super.destroy.call(this),this.dialog.on("hidden.bs.modal",function(b){this.dialog.remove();var c,d=jQuery(".wizard-dialog").filter(":visible")[0],e=!1;if(d||(d=Sao.Tab.tabs.get_current(),d?d.screen&&d.screen.model_name!=this.model&&(e=!0,c=Sao.main_menu_screen):(e=!0,c=Sao.main_menu_screen)),d&&d.screen&&(c=d.screen),c){if(c.current_record&&!e){var f;f=c.model_name==this.model?this.ids:[c.current_record.id],c.reload(f,!0)}a&&c.client_action(a)}}.bind(this)),this.dialog.modal("hide")},end:function(){return Sao.Wizard.Dialog._super.end.call(this).then(this.destroy.bind(this))},show:function(){this.dialog.modal("show")},hide:function(){this.dialog.modal("hide")},state_changed:function(){this.process()}})}(),function(){"use strict";Sao.View.Board=Sao.class_(Object,{init:function(a,b){var c,d,e,f;this.context=b,this.actions=[],this.el=jQuery("<div/>",{"class":"board"}),c={},e=a.children()[0];for(var g=0,h=e.attributes.length;h>g;g++)d=e.attributes[g],c[d.name]=d.value;for(this.attributes=c,this.el.append(this.parse(e).el),f=[],g=0,h=this.actions.length;h>g;g++)f.push(this.actions[g].action_prm);this.actions_prms=jQuery.when.apply(jQuery,f)},_parse_node:function(a,b,c){switch(a.tagName){case"image":break;case"separator":this._parse_separator(a,b,c);break;case"label":this._parse_label(a,b,c);break;case"newline":b.add_row();break;case"notebook":this._parse_notebook(a,b,c);break;case"page":this._parse_page(a,b,c);break;case"group":this._parse_group(a,b,c);break;case"hpaned":this._parse_pane(a,b,c,"horizontal");break;case"vpaned":this._parse_pane(a,b,c,"vertical");break;case"child":this._parse_child(a,b,c);break;case"action":this._parse_action(a,b,c)}},parse:function(a,b){var c;return b||(b=new Sao.View.Form.Container(Number(a.getAttribute("col")||4))),c=function(a,c){var d,e,f,g;for(d={},f=0,g=c.attributes.length;g>f;f++)e=c.attributes[f],d[e.name]=e.value;["yexpand","yfill","xexpand","xfill","colspan","position"].forEach(function(a){d[a]&&(d[a]=Number(d[a]))}),this._parse_node(c,b,d)},jQuery(a).children().each(c.bind(this)),b},_parse_separator:function(a,b,c){var d,e;d=c.string,e=new Sao.view.Form.Separator(d,c),b.add(c,e)},_parse_label:function(a,b,c){var d,e;return(d=c.string)?(e=new Sao.View.Form.Label(d,c),void b.add(c,e)):void b.add(c)},_parse_notebook:function(a,b,c){var d;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),d=new Sao.View.Form.Notebook(c),b.add(c,d),this.parse(a,b)},_parse_page:function(a,b,c){var d;d=c.string,page=this.parse(a,b),page=new Sao.View.Form.Page(b.add(page.el,d),c)},_parse_group:function(a,b,c){var d;d=new Sao.View.Form.Group(c),b.add(c,d)},_parse_pane:function(a,b,c,d){var e;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),e=new Sao.common.Paned(d),b.add(c,e),this.parse(a,e)},_parse_child:function(a,b,c){var d,e,f;d=this.parse(a),e=b.get_child1(),e.children().length>0?(f=b.get_child2(),f.append(d.el)):e.append(d.el)},_parse_action:function(a,b,c){var d;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),d=new Sao.View.Board.Action(c,this.context),this.actions.push(d),b.add(c,d)},reload:function(){for(var a=0;a<this.actions.length;a++)this.actions[a].display()}}),Sao.View.Board.Action=Sao.class_(Object,{init:function(a,b){void 0===b&&(b={});var c,d;this.name=a.name,this.context=jQuery.extend({},b),c=new Sao.Model("ir.action.act_window"),this.action_prm=c.execute("get",[this.name],this.context),this.action_prm.done(function(b){var c,e,f,g,h,i;if(this.action=b,this.action.mode=[],f=[],(this.action.views||[]).length>0)for(c=0,e=this.action.views.length;e>c;c++)f.push(this.action.views[c][0]),this.action.mode.push(this.action.views[c][1]);else void 0!==this.action.view_id&&(f=[this.action.view_id[0]]);"mode"in a&&(this.action.mode=a.mode),"pyson_domain"in this.action||(this.action.pyson_domain="[]"),jQuery.extend(this.context,Sao.Session.current_session.context),this.context._user=Sao.Session.current_session.user_id,g=new Sao.PYSON.Decoder(this.context),jQuery.extend(this.context,g.decode(this.action.pyson_context||"{}")),g=new Sao.PYSON.Decoder(this.context),jQuery.extend(this.context,g.decode(this.action.pyson_context||"{}")),this.domain=[],this.update_domain([]),h=jQuery.extend({},this.context),h.context=this.context,h._user=Sao.Session.current_session.user_id,g=new Sao.PYSON.Decoder(h),d=g.decode(this.action.pyson_search_value||"{}"),i={mode:this.action.mode,context:this.context,view_ids:f,domain:this.domain,search_value:d,row_activate:this.row_activate.bind(this)},this.screen=new Sao.Screen(this.action.res_model,i),a.string?this.title.html(a.string):this.title.html(this.action.name),this.screen.switch_view().done(function(){this.body.append(this.screen.screen_container.el),this.screen.search_filter()}.bind(this))}.bind(this)),this.el=jQuery("<div/>",{"class":"board-action panel panel-default"}),this.title=jQuery("<div/>",{"class":"panel-heading"}),this.el.append(this.title),this.body=jQuery("<div/>",{"class":"panel-body"}),this.el.append(this.body)},row_activate:function(){var a,b;this.screen.current_record&&("tree"==this.screen.current_view.view_type&&1==this.screen.current_view.attributes.keyword_open?(a=this.screen.current_view.selected_records().map(function(a){return a.id}),Sao.Action.exec_keyword("tree_open",{model:this.screen.model_name,id:this.screen.current_record.id,ids:a},jQuery.extend({},this.context),!1)):b=new Sao.Window.Form(this.screen,function(a){a?this.screen.current_record.save():this.screen.current_record.cancel()}.bind(this)))},set_value:function(){},display:function(){this.screen.search_filter(this.screen.screen_container.get_text())},get_active:function(){return this.screen&&this.screen.current_record?Sao.common.EvalEnvironment(this.screen.current_record):void 0},update_domain:function(a){var b,c,d,e,f,g;for(e=jQuery.extend({},this.context),e.context=e,e._user=Sao.Session.current_session.user_id,b=0,c=a.length;c>b;b++)d=a[b].get_active(),d&&(e[a[b].name]=d);f=new Sao.PYSON.Decoder(e),g=f.decode(this.action.pyson_domain),Sao.common.compare(this.domain,g)||(this.domain.splice(0,this.domain.length),jQuery.extend(this.domain,g),this.screen&&this.display())}})}();
\ No newline at end of file
+function eval_pyson(value){with(Sao.PYSON.eval)return eval(value)}var Sao={};!function(){"use strict";function a(){var a=1040;jQuery(".modal.in").each(function(b){var c=jQuery(this);a++,c.css("zIndex",a),c.next(".modal-backdrop.in").addClass("hidden").css("zIndex",a-1)}),jQuery(".modal.in:visible:last").focus().next(".modal-backdrop.in").removeClass("hidden")}"contains"in String.prototype||(String.prototype.contains=function(a,b){return-1!==String.prototype.indexOf.call(this,a,b)}),String.prototype.startsWith||Object.defineProperty(String.prototype,"startsWith",{enumerable:!1,configurable:!1,writable:!1,value:function(a,b){return b=b||0,this.indexOf(a,b)===b}}),String.prototype.endsWith||Object.defineProperty(String.prototype,"endsWith",{enumerable:!1,configurable:!1,writable:!1,value:function(a,b){b=b||this.length,b-=a.length;var c=this.lastIndexOf(a);return-1!==c&&c===b}}),Array.prototype.some||(Array.prototype.some=function(a){if(null===this)throw new TypeError;var b,c,d=Object(this),e=d.length>>>0;if("function"!=typeof a)throw new TypeError;for(b=arguments[1],c=0;c<e;c++)if(c in d&&a.call(b,d[c],c,d))return!0;return!1});try{document.execCommand("styleWithCSS",!1,!1)}catch(c){}try{document.execCommand("useCSS",!1,!0)}catch(c){}jQuery.fn.extend({uniqueId:function(){var a=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})}}()}),Sao.class_=function(a,b){var c=function(){if(!(this instanceof c))throw new Error("Constructor function requires new operator");this.Class=c,this.init&&this.init.apply(this,arguments)};if(c.prototype=Object.create(a.prototype),c._super=a.prototype,b)for(var d in b)c.prototype[d]=b[d];return c},Sao.Decimal=Number,Sao.Date=function(a,b,c){var d=moment();return d.year(a),d.month(b),d.date(c),d.set({hour:0,minute:0,second:0,millisecond:0}),d.isDate=!0,d},Sao.Date.min=moment(new Date(-864e13)),Sao.Date.min.set({hour:0,minute:0,second:0,millisecond:0}),Sao.Date.min.isDate=!0,Sao.Date.max=moment(new Date(864e13)),Sao.Date.max.set({hour:0,minute:0,second:0,millisecond:0}),Sao.Date.max.isDate=!0,Sao.DateTime=function(a,b,c,d,e,f,g,h){var i;return void 0===b?(i=moment(a),a=void 0):i=moment(),h&&i.utc(),i.year(a),i.month(b),i.date(c),void 0!==b&&(i.hour(d||0),i.minute(e||0),i.second(f||0),i.milliseconds(g||0)),i.isDateTime=!0,i.local(),i},Sao.DateTime.combine=function(a,b){var c=a.clone();return c.set({hour:b.hour(),minute:b.minute(),second:b.second(),millisecond:b.millisecond()}),c.isDateTime=!0,c},Sao.DateTime.min=moment(new Date(-864e13)).local(),Sao.DateTime.min.isDateTime=!0,Sao.DateTime.max=moment(new Date(864e13)).local(),Sao.DateTime.max.isDateTime=!0,Sao.Time=function(a,b,c,d){var e=moment({hour:a,minute:b,second:c,millisecond:d||0});return e.isTime=!0,e},Sao.TimeDelta=function(a,b,c,d,e,f){var g=moment.duration({days:a,seconds:b,milliseconds:c,minutes:d,hours:e,weeks:f});return g.isTimeDelta=!0,g},Sao.config={},Sao.config.limit=1e3,Sao.config.display_size=20,Sao.config.roundup={},Sao.config.roundup.url="http://bugs.tryton.org/roundup/",Sao.config.title="Tryton",Sao.i18n=i18n(),Sao.i18n.setlang=function(a){return a||(a=(navigator.language||navigator.browserLanguage||navigator.userLanguage||"en").replace("-","_")),Sao.i18n.setLocale(a),moment.locale(a.slice(0,2)),jQuery.getJSON("locale/"+a+".json",function(b){b[""].language||(b[""].language=a),b[""]["plural-forms"]||(b[""]["plural-forms"]="nplurals=2; plural=(n!=1);");for(var c in b)""!==c&&(b[c]=2==b[c].length?b[c][1]:b[c].slice(1));Sao.i18n.loadJSON(b)})},Sao.i18n.getlang=function(){return Sao.i18n.getLocale()},Sao.i18n.setlang(),Sao.get_preferences=function(){var a=Sao.Session.current_session;return a.reload_context().then(function(){return Sao.rpc({method:"model.res.user.get_preferences",params:[!1,{}]},a).then(function(a){var b=[];return b.push(Sao.common.MODELACCESS.load_models()),b.push(Sao.common.ICONFACTORY.load_icons()),b.push(Sao.common.MODELHISTORY.load_history()),b.push(Sao.common.VIEW_SEARCH.load_searches()),jQuery.when.apply(jQuery,b).then(function(){(a.actions||[]).forEach(function(a){Sao.Action.execute(a,{},null,{})});var b=Sao.config.title;jQuery.isEmptyObject(a.status_bar)||(b+=" - "+a.status_bar),document.title=b;var c=a.language!=Sao.i18n.getLocale(),d=jQuery.Deferred();return Sao.i18n.setlang(a.language).always(function(){c&&Sao.user_menu(a),d.resolve(a)}),d})})})},Sao.login=function(){Sao.Session.get_credentials().then(function(a){return Sao.Session.current_session=a,a.reload_context()}).then(Sao.get_preferences).then(function(a){Sao.menu(a),Sao.user_menu(a)})},Sao.logout=function(){var a=Sao.Session.current_session;Sao.Tab.tabs.close(!0).done(function(){jQuery("#user-preferences").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#menu").children().remove(),document.title=Sao.config.title,a.do_logout().always(Sao.login)})},Sao.preferences=function(){Sao.Tab.tabs.close(!0).done(function(){jQuery("#user-preferences").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#menu").children().remove(),new Sao.Window.Preferences(function(){Sao.get_preferences().then(function(a){Sao.menu(a),Sao.user_menu(a)})})})},Sao.favorites_menu=function(){var a=function(){e&&e.remove()};if(jQuery(window).click(function(){a()}),0!==jQuery("#user-favorites").children(".dropdown-menu").length)a();else{var b=Sao.main_menu_screen.model_name+".favorite",c=Sao.Session.current_session,d={method:"model."+b+".get"},e=jQuery("<ul/>",{class:"dropdown-menu","aria-expanded":"false"});jQuery("#user-favorites").append(e),Sao.rpc(d,c).then(function(b){b.forEach(function(b){var c=jQuery("<a/>",{href:"#"}),d=b[0],f=jQuery("<li/>",{role:"presentation"}),g=jQuery("<img/>",{class:"favorite-icon"});c.append(g),f.append(c),g.attr("src",Sao.common.ICONFACTORY.get_icon_url(b[2])),c.append(b[1]),c.click(function(){a(),Sao.Action.exec_keyword("tree_open",{model:Sao.main_menu_screen.model_name,id:d,ids:[d]})}),e.append(f)}),e.append(jQuery("<li/>",{class:"divider"})),jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{href:"#"}).click(function(){a(),Sao.Tab.create({model:Sao.main_menu_screen.model_name+".favorite",mode:["tree","form"],name:Sao.i18n.gettext("Manage favorites")})}).text(Sao.i18n.gettext("Manage favorites"))).appendTo(e)})}},Sao.user_menu=function(a){jQuery("#user-preferences").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#user-preferences").append(jQuery("<a/>",{href:"#"}).click(Sao.preferences).append(a.status_bar)),jQuery("#user-logout").append(jQuery("<a/>",{href:"#"}).click(Sao.logout).append(Sao.i18n.gettext("Logout"))),jQuery("#user-favorites").append(jQuery("<a/>",{href:"#","data-toggle":"dropdown"}).click(Sao.favorites_menu).append(Sao.i18n.gettext("Favorites")))},Sao.menu=function(a){var c=new Sao.PYSON.Decoder,d=c.decode(a.pyson_menu),e=!1;jQuery.isEmptyObject(d.views)?d.view_id&&(e=[d.view_id[0]]):e=d.views.map(function(a){return a[0]}),c=new Sao.PYSON.Decoder(Sao.Session.current_session.context);var f=c.decode(d.pyson_context||"{}"),g=c.decode(d.pyson_domain),h=new Sao.Tab.Form(d.res_model,{mode:["tree"],view_ids:e,domain:g,context:f,selection_mode:Sao.common.SELECTION_NONE,limit:null});Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(h),1),h.view_prm.done(function(){Sao.main_menu_screen=h.screen,h.screen.current_view.table.find("thead").hide(),jQuery("#menu").children().remove();var a=new Sao.GlobalSearch;jQuery("#menu").append(a.el),jQuery("#menu").append(h.screen.screen_container.content_box.detach()),h.screen.views[0].columns.push(new b(h.screen.model.fields.favorite))})},Sao.main_menu_screen=null;var b=Sao.class_(Object,{init:function(a){this.field=a,this.header=jQuery("<th/>"),this.attributes=jQuery.extend({},this.field.description),this.attributes.name=this.field.name},get_cell:function(){return jQuery("<span/>",{tabindex:0})},render:function(a,b){return b||(b=this.get_cell()),a.load(this.field.name).done(function(){if(null!==a._values.favorite){var c="glyphicon glyphicon-star";a._values.favorite||(c+="-empty"),b.addClass(c),b.click({record:a,button:b},this.favorite_click)}}.bind(this)),b},favorite_click:function(a){a.stopImmediatePropagation();var b,c=a.data.button;c.hasClass("glyphicon-star-empty")?(c.removeClass("glyphicon-star-empty"),c.addClass("glyphicon-star"),b="set"):(c.removeClass("glyphicon-star"),c.addClass("glyphicon-star-empty"),b="unset");var d=Sao.main_menu_screen.model_name+".favorite",e=Sao.Session.current_session,f={method:"model."+d+"."+b,params:[a.data.record.id,e.context]};Sao.rpc(f,e)}});Sao.Dialog=Sao.class_(Object,{init:function(a,b,c){c=c||"sm",this.modal=jQuery("<div/>",{class:b+" modal fade",role:"dialog","data-backdrop":"static"}),this.content=jQuery("<form/>",{class:"modal-content"}).appendTo(jQuery("<div/>",{class:"modal-dialog modal-"+c}).appendTo(this.modal)),this.header=jQuery("<div/>",{class:"modal-header"}).appendTo(this.content),a&&this.add_title(a),this.body=jQuery("<div/>",{class:"modal-body"}).appendTo(this.content),this.footer=jQuery("<div/>",{class:"modal-footer"}).appendTo(this.content)},add_title:function(a){this.header.append(jQuery("<h4/>",{class:"modal-title"}).append(a))}}),Sao.GlobalSearch=Sao.class_(Object,{init:function(){this.el=jQuery("<div/>",{class:"global-search-container"}),this.search_entry=jQuery("<input>",{class:"form-control",placeholder:Sao.i18n.gettext("Search...")}),this.el.append(this.search_entry);new Sao.common.InputCompletion(this.search_entry,this.update.bind(this),this.match_selected.bind(this),this.format.bind(this))},format:function(a){var b=jQuery("<div/>"),c=jQuery("<img/>",{class:"global-search-icon"}).appendTo(b);return Sao.common.ICONFACTORY.register_icon(a.icon).then(function(a){c.attr("src",a)}),jQuery("<span/>",{class:"global-search-text"}).text(a.record_name).appendTo(b),b},update:function(a){return new Sao.Model("ir.model").execute("global_search",[a,Sao.config.limit,Sao.main_menu_screen.model_name],Sao.main_menu_screen.context).then(function(a){for(var b=[],c=0,d=a.length;c<d;c++)b.push({model:a[c][1],model_name:a[c][2],record_id:a[c][3],record_name:a[c][4],icon:a[c][5]});return b}.bind(this))},match_selected:function(a){if(a.model==Sao.main_menu_screen.model_name)Sao.Action.exec_keyword("tree_open",{model:a.model,id:a.record_id,ids:[a.record_id]},Sao.main_menu_screen.context);else{var b={model:a.model,res_id:a.record_id,mode:["form","tree"],name:a.model_name};Sao.Tab.create(b)}this.search_entry.val("")}}),jQuery(document).on("show.bs.modal",".modal",function(a){jQuery(this).appendTo(jQuery("body"))}).on("shown.bs.modal",".modal.in",function(b){a()}).on("hidden.bs.modal",".modal",function(b){a()})}(),function(){"use strict";Sao.rpc=function(a,b){var c=jQuery.Deferred();b||(b=new Sao.Session);var d=jQuery.extend([],a.params);d.push(jQuery.extend({},b.context,d.pop()));var e=Sao.common.processing.show(),f=jQuery.ajax({headers:{Authorization:"Session "+b.get_auth()},contentType:"application/json",data:JSON.stringify(Sao.rpc.prepareObject({id:Sao.rpc.id++,method:a.method,params:d})),dataType:"json",url:"/"+(b.database||"")+"/",type:"post",complete:[function(){Sao.common.processing.hide(e)}]}),g=function(d){if(null===d)Sao.common.warning.run("",Sao.i18n.gettext("Unable to reach the server")),c.reject();else if(d.error){var e,f,g;if("UserWarning"==d.error[0])return e=d.error[1][0],f=d.error[1][1],g=d.error[1][2],void Sao.common.userwarning.run(f,g).done(function(d){if(!~["always","ok"].indexOf(d))return void c.reject();Sao.rpc({method:"model.res.user.warning.create",params:[[{user:b.user_id,name:e,always:"always"==d}],{}]},b).done(function(){Sao.rpc(a,b).then(c.resolve,c.reject)})});if("UserError"==d.error[0])return f=d.error[1][0],g=d.error[1][1],void Sao.common.warning.run(g,f).always(c.reject);if("ConcurrencyException"==d.error[0]){if(a.method.startsWith("model.")&&(a.method.endsWith(".write")||a.method.endsWith(".delete"))){var h=a.method.split(".").slice(1,-1).join(".");return void Sao.common.concurrency.run(h,a.params[0][0],a.params.slice(-1)[0]).then(function(){delete a.params.slice(-1)[0]._timestamp,Sao.rpc(a,b).then(c.resolve,c.reject)},c.reject)}return void Sao.common.message.run("Concurrency Exception","glyphicon-alert").always(c.reject)}Sao.common.error.run(d.error[0],d.error[1]),c.reject()}else c.resolve(d.result)},h=function(d,e,f){if(403==d.status)return void Sao.Session.renew(b).then(function(){Sao.rpc(a,b).then(c.resolve,c.reject)},c.reject);Sao.common.error.run(e,f),c.reject()};return f.success(g),f.error(h),c.promise()},Sao.rpc.id=0,Sao.rpc.convertJSONObject=function(a,b,c){if(a instanceof Array)for(var d=0,e=a.length;d<e;d++)Sao.rpc.convertJSONObject(a[d],d,a);else if("string"!=typeof a&&"number"!=typeof a&&null!==a)if(a&&a.__class__){switch(a.__class__){case"datetime":a=Sao.DateTime(a.year,a.month-1,a.day,a.hour,a.minute,a.second,a.microsecond/1e3,!0);break;case"date":a=Sao.Date(a.year,a.month-1,a.day);break;case"time":a=Sao.Time(a.hour,a.minute,a.second,a.microsecond/1e3);break;case"timedelta":a=Sao.TimeDelta(null,a.seconds);break;case"bytes":for(var f=atob(a.base64.replace(/\s/g,"")),g=new ArrayBuffer(f.length),h=new Uint8Array(g),i=0;i<f.length;i++)h[i]=f.charCodeAt(i);a=h;break;case"Decimal":a=new Sao.Decimal(a.decimal)}c&&(c[b]=a)}else for(var j in a)Sao.rpc.convertJSONObject(a[j],j,a);return c||a},Sao.rpc.prepareObject=function(a,b,c){if(a instanceof Array){a=jQuery.extend([],a);for(var d=0,e=a.length;d<e;d++)Sao.rpc.prepareObject(a[d],d,a)}else if("string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a&&null!==a&&void 0!==a)if(a.isDate)a={__class__:"date",year:a.year(),month:a.month()+1,day:a.date()};else if(a.isDateTime)a=a.clone(),a={__class__:"datetime",year:a.utc().year(),month:a.utc().month()+1,day:a.utc().date(),hour:a.utc().hour(),minute:a.utc().minute(),second:a.utc().second(),microsecond:1e3*a.utc().millisecond()};else if(a.isTime)a={__class__:"time",hour:a.hour(),minute:a.minute(),second:a.second(),microsecond:1e3*a.millisecond()};else if(a.isTimeDelta)a={__class__:"timedelta",seconds:a.asSeconds()};else if(a instanceof Sao.Decimal)a={__class__:"Decimal",decimal:a.toString()};else if(a instanceof Uint8Array){for(var f=[],g=65535,h=0;h*g<a.length;h++)f.push(String.fromCharCode.apply(null,a.subarray(h*g,(h+1)*g)));a={__class__:"bytes",base64:btoa(f.join(""))}}else{a=jQuery.extend({},a);for(var i in a)Sao.rpc.prepareObject(a[i],i,a)}return c&&(c[b]=a),c||a},jQuery.ajaxSetup({converters:{"text json":function(a){return Sao.rpc.convertJSONObject(jQuery.parseJSON(a))}}})}(),function(){"use strict";Sao.PYSON={},Sao.PYSON.eval={},Sao.PYSON.PYSON=Sao.class_(Object,{init:function(){},pyson:function(){throw"NotImplementedError"},types:function(){throw"NotImplementedError"},toString:function(){return this.pyson().__class__+"("+this.__string_params__().map(function(a){return a instanceof Sao.PYSON.PYSON?a.toString():JSON.stringify(a)}).join(", ")+")"},__string_params__:function(){throw"NotImplementedError"}}),Sao.PYSON.PYSON.eval_=function(a,b){throw"NotImplementedError"},Sao.PYSON.PYSON.init_from_object=function(a){throw"NotImplementedError"},Sao.PYSON.Encoder=Sao.class_(Object,{prepare:function(a,b,c){if(null!==a&&void 0!==a)if(a instanceof Array){a=jQuery.extend([],a);for(var d=0,e=a.length;d<e;d++)this.prepare(a[d],d,a)}else a._isAMomentObject&&(a=a.isDate?new Sao.PYSON.Date(a.year(),a.month()+1,a.date()).pyson():new Sao.PYSON.DateTime(a.year(),a.month()+1,a.date(),a.hours(),a.minutes(),a.seconds(),1e3*a.milliseconds()).pyson());return c&&(c[b]=a),c||a},encode:function(a){return a=this.prepare(a),JSON.stringify(a,function(a,b){return b instanceof Sao.PYSON.PYSON?b.pyson():null===b||void 0===b?null:b})}}),Sao.PYSON.Decoder=Sao.class_(Object,{init:function(a,b){this.__context=a||{},this.noeval=b||!1},decode:function(a){var b=function(a,b){if("object"==typeof b&&null!==b){var c=Sao.PYSON[b.__class__];if(c){if(this.noeval){var d=jQuery.extend({},b);return delete d.__class__,Sao.PYSON[b.__class__].init_from_object(d)}return c.eval_(b,this.__context)}}return b};return JSON.parse(a,b.bind(this))}}),Sao.PYSON.eval.Eval=function(a,b){return new Sao.PYSON.Eval(a,b)},Sao.PYSON.Eval=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){void 0===b&&(b=""),Sao.PYSON.Eval._super.init.call(this),this._value=a,this._default=b},pyson:function(){return{__class__:"Eval",v:this._value,d:this._default}},types:function(){return this._default instanceof Sao.PYSON.PYSON?this._default.types():[typeof this._default]},__string_params__:function(){return[this._value,this._default]}}),Sao.PYSON.Eval.eval_=function(a,b){return a.v in b?b[a.v]:a.d},Sao.PYSON.Eval.init_from_object=function(a){return new Sao.PYSON.Eval(a.v,a.d)},Sao.PYSON.eval.Not=function(a){return new Sao.PYSON.Not(a)},Sao.PYSON.Not=Sao.class_(Sao.PYSON.PYSON,{init:function(a){if(Sao.PYSON.Not._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["boolean","object"]).length||jQuery(["boolean"]).not(a.types()).length)throw"value must be boolean"}else if("boolean"!=typeof a)throw"value must be boolean";this._value=a},pyson:function(){return{__class__:"Not",v:this._value}},types:function(){return["boolean"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Not.eval_=function(a,b){return!a.v},Sao.PYSON.Not.init_from_object=function(a){return new Sao.PYSON.Not(a.v)},Sao.PYSON.eval.Bool=function(a){return new Sao.PYSON.Bool(a)},Sao.PYSON.Bool=Sao.class_(Sao.PYSON.PYSON,{init:function(a){Sao.PYSON.Bool._super.init.call(this),this._value=a},pyson:function(){return{__class__:"Bool",v:this._value}},types:function(){return["boolean"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Bool.eval_=function(a,b){return moment.isMoment(a.v)&&a.v.isTime?Boolean(a.v.hour()||a.v.minute()||a.v.second()||a.v.millisecond()):moment.isDuration(a.v)?Boolean(a.v.valueOf()):a.v instanceof Object?!jQuery.isEmptyObject(a.v):Boolean(a.v)},Sao.PYSON.Bool.init_from_object=function(a){return new Sao.PYSON.Bool(a.v)},Sao.PYSON.eval.And=function(a){return new Sao.PYSON.And(a)},Sao.PYSON.And=Sao.class_(Sao.PYSON.PYSON,{init:function(a){void 0===a&&(a=[]),Sao.PYSON.And._super.init.call(this);for(var b=0,c=a.length;b<c;b++){var d=a[b];if(d instanceof Sao.PYSON.PYSON){if(jQuery(d.types()).not(["boolean"]).length||jQuery(["boolean"]).not(d.types()).length)throw"statement must be boolean"}else if("boolean"!=typeof d)throw"statement must be boolean"}if(a.length<2)throw"must have at least 2 statements";this._statements=a},pyson:function(){return{__class__:"And",s:this._statements}},types:function(){return["boolean"]},__string_params__:function(){return this._statements}}),Sao.PYSON.And.eval_=function(a,b){for(var c=!0,d=0,e=a.s.length;d<e;d++){var f=a.s[d];c=c&&f}return c},Sao.PYSON.And.init_from_object=function(a){return new Sao.PYSON.And(a.s)},Sao.PYSON.eval.Or=function(a){return new Sao.PYSON.Or(a)},Sao.PYSON.Or=Sao.class_(Sao.PYSON.And,{pyson:function(){var a=Sao.PYSON.Or._super.pyson.call(this);return a.__class__="Or",a}}),Sao.PYSON.Or.eval_=function(a,b){for(var c=!1,d=0,e=a.s.length;d<e;d++){var f=a.s[d];c=c||f}return c},Sao.PYSON.Or.init_from_object=function(a){return new Sao.PYSON.Or(a.s)},Sao.PYSON.eval.Equal=function(a,b){return new Sao.PYSON.Equal(a,b)},Sao.PYSON.Equal=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){Sao.PYSON.Equal._super.init.call(this);var c,d;if(c=a instanceof Sao.PYSON.PYSON?a.types():[typeof a],d=b instanceof Sao.PYSON.PYSON?b.types():[typeof b],jQuery(c).not(d).length||jQuery(d).not(c).length)throw"statements must have the same type";this._statement1=a,this._statement2=b},pyson:function(){return{__class__:"Equal",s1:this._statement1,s2:this._statement2}},types:function(){return["boolean"]},__string_params__:function(){return[this._statement1,this._statement2]}}),Sao.PYSON.Equal.eval_=function(a,b){return a.s1 instanceof Array&&a.s2 instanceof Array?Sao.common.compare(a.s1,a.s2):a.s1==a.s2},Sao.PYSON.Equal.init_from_object=function(a){return new Sao.PYSON.Equal(a.s1,a.s2)},Sao.PYSON.eval.Greater=function(a,b,c){return new Sao.PYSON.Greater(a,b,c)},Sao.PYSON.Greater=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){Sao.PYSON.Greater._super.init.call(this);for(var d=[a,b],e=0;e<2;e++){var f=d[e];if(f instanceof Sao.PYSON.PYSON){if(jQuery(f).not(["number"]).length)throw"statement must be an integer or a float"}else if(!~["number","object"].indexOf(typeof f))throw"statement must be an integer or a float"}if(void 0===c&&(c=!1),c instanceof Sao.PYSON.PYSON){if(jQuery(c.types()).not(["boolean"]).length||jQuery(["boolean"]).not(c.types()).length)throw"equal must be boolean"}else if("boolean"!=typeof c)throw"equal must be boolean";this._statement1=a,this._statement2=b,this._equal=c},pyson:function(){return{__class__:"Greater",s1:this._statement1,s2:this._statement2,e:this._equal}},types:function(){return["boolean"]},__string_params__:function(){return[this._statement1,this._statement2,this._equal]}}),Sao.PYSON.Greater._convert=function(a){return a=jQuery.extend({},a),a.s1=Number(a.s1),a.s2=Number(a.s2),a},Sao.PYSON.Greater.eval_=function(a,b){return a=Sao.PYSON.Greater._convert(a),a.e?a.s1>=a.s2:a.s1>a.s2},Sao.PYSON.Greater.init_from_object=function(a){return new Sao.PYSON.Greater(a.s1,a.s2,a.e)},Sao.PYSON.eval.Less=function(a,b,c){return new Sao.PYSON.Less(a,b,c)},Sao.PYSON.Less=Sao.class_(Sao.PYSON.Greater,{pyson:function(){var a=Sao.PYSON.Less._super.pyson.call(this);return a.__class__="Less",a}}),Sao.PYSON.Less._convert=Sao.PYSON.Greater._convert,Sao.PYSON.Less.eval_=function(a,b){return a=Sao.PYSON.Less._convert(a),a.e?a.s1<=a.s2:a.s1<a.s2},Sao.PYSON.Less.init_from_object=function(a){return new Sao.PYSON.Less(a.s1,a.s2,a.e)},Sao.PYSON.eval.If=function(a,b,c){return new Sao.PYSON.If(a,b,c)},Sao.PYSON.If=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){if(Sao.PYSON.If._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["boolean"]).length||jQuery(["boolean"]).not(a.types()).length)throw"condition must be boolean"}else if("boolean"!=typeof a)throw"condition must be boolean";var d,e;if(d=b instanceof Sao.PYSON.PYSON?b.types():[typeof b],void 0===c&&(c=null),e=c instanceof Sao.PYSON.PYSON?c.types():[typeof c],jQuery(d).not(e).length||jQuery(e).not(d).length)throw"then and else statements must be the same type";this._condition=a,this._then_statement=b,this._else_statement=c},pyson:function(){return{__class__:"If",c:this._condition,t:this._then_statement,e:this._else_statement}},types:function(){return this._then_statement instanceof Sao.PYSON.PYSON?this._then_statement.types():[typeof this._then_statement]},__string_params__:function(){return[this._condition,this._then_statement,this._else_statement]}}),Sao.PYSON.If.eval_=function(a,b){return a.c?a.t:a.e},Sao.PYSON.If.init_from_object=function(a){return new Sao.PYSON.If(a.c,a.t,a.e)},Sao.PYSON.eval.Get=function(a,b,c){return new Sao.PYSON.Get(a,b,c)},Sao.PYSON.Get=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){if(Sao.PYSON.Get._super.init.call(this),void 0===c&&(c=null),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["object"]).length||jQuery(["object"]).not(a.types()).length)throw"obj must be a dict"}else if(!(a instanceof Object))throw"obj must be a dict";if(this._obj=a,b instanceof Sao.PYSON.PYSON){if(jQuery(b.types()).not(["string"]).length||jQuery(["string"]).not(b.types()).length)throw"key must be a string"}else if("string"!=typeof b)throw"key must be a string";this._key=b,this._default=c},pyson:function(){return{__class__:"Get",v:this._obj,k:this._key,d:this._default}},types:function(){return this._default instanceof Sao.PYSON.PYSON?this._default.types():[typeof this._default]},__string_params__:function(){return[this._obj,this._key,this._default]}}),Sao.PYSON.Get.eval_=function(a,b){return a.k in a.v?a.v[a.k]:a.d},Sao.PYSON.Get.init_from_object=function(a){return new Sao.PYSON.Get(a.v,a.k,a.d)},Sao.PYSON.eval.In=function(a,b){return new Sao.PYSON.In(a,b)},Sao.PYSON.In=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){if(Sao.PYSON.In._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["string","number"]).length)throw"key must be a string or a number"}else if(!~["string","number"].indexOf(typeof a))throw"key must be a string or a number";if(b instanceof Sao.PYSON.PYSON){if(jQuery(b.types()).not(["object"]).length||jQuery(["object"]).not(b.types()).length)throw"obj must be a dict or a list"}else if(!(b instanceof Object))throw"obj must be a dict or a list";this._key=a,this._obj=b},pyson:function(){return{__class__:"In",k:this._key,v:this._obj}},types:function(){return["boolean"]},__string_params__:function(){return[this._key,this._obj]}}),Sao.PYSON.In.eval_=function(a,b){return a.v.indexOf?Boolean(~a.v.indexOf(a.k)):!!a.v[a.k]},Sao.PYSON.In.init_from_object=function(a){return new Sao.PYSON.In(a.k,a.v)},Sao.PYSON.eval.Date=function(a,b,c,d,e,f){return new Sao.PYSON.Date(a,b,c,d,e,f)},Sao.PYSON.Date=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c,d,e,f){Sao.PYSON.Date._super.init.call(this),void 0===a&&(a=null),void 0===b&&(b=null),void 0===c&&(c=null),void 0===d&&(d=0),void 0===e&&(e=0),void 0===f&&(f=0),this._test(a,"year"),this._test(b,"month"),this._test(c,"day"),this._test(d,"delta_years"),this._test(f,"delta_days"),this._test(e,"delta_months"),this._year=a,this._month=b,this._day=c,this._delta_years=d,this._delta_months=e,this._delta_days=f},pyson:function(){return{__class__:"Date",y:this._year,M:this._month,d:this._day,dy:this._delta_years,dM:this._delta_months,dd:this._delta_days}},types:function(){return["object"]},_test:function(a,b){if(a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["number","object"]).length)throw b+" must be an integer or None"}else if("number"!=typeof a&&null!==a)throw b+" must be an integer or None"},__string_params__:function(){return[this._year,this._month,this._day,this._delta_years,this._delta_months,this._delta_days]}}),Sao.PYSON.Date.eval_=function(a,b){var c=Sao.Date(a.y,a.M&&a.M-1,a.d);return a.dy&&c.add(a.dy,"y"),a.dM&&c.add(a.dM,"M"),a.dd&&c.add(a.dd,"d"),c},Sao.PYSON.Date.init_from_object=function(a){return new Sao.PYSON.Date(a.y,a.M,a.d,a.dy,a.dM,a.dd)},Sao.PYSON.eval.DateTime=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){return new Sao.PYSON.DateTime(a,b,c,d,e,f,g,h,i,j,k,l,m,n)},Sao.PYSON.DateTime=Sao.class_(Sao.PYSON.Date,{init:function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){Sao.PYSON.DateTime._super.init.call(this,a,b,c,h,i,j),void 0===d&&(d=null),void 0===e&&(e=null),void 0===f&&(f=null),void 0===g&&(g=null),void 0===k&&(k=0),void 0===l&&(l=0),void 0===m&&(m=0),void 0===n&&(n=0),this._test(d,"hour"),this._test(e,"minute"),this._test(f,"second"),this._test(g,"microsecond"),this._test(k,"delta_hours"),this._test(l,"delta_minutes"),this._test(m,"delta_seconds"),this._test(n,"delta_microseconds"),this._hour=d,this._minute=e,this._second=f,this._microsecond=g,this._delta_hours=k,this._delta_minutes=l,this._delta_seconds=m,this._delta_microseconds=n},pyson:function(){var a=Sao.PYSON.DateTime._super.pyson.call(this);return a.__class__="DateTime",a.h=this._hour,a.m=this._minute,a.s=this._second,a.ms=this._microsecond,a.dh=this._delta_hours,a.dm=this._delta_minutes,a.ds=this._delta_seconds,a.dms=this._delta_microseconds,a},__string_params__:function(){var a=Sao.PYSON.DateTime._super.__string_params__.call(this);return[a[0],a[1],a[2],this._hour,this._minute,this._second,this._microsecond,a[3],a[4],a[5],this._delta_hours,this._delta_minutes,this._delta_seconds,this._delta_microseconds]}}),Sao.PYSON.DateTime.eval_=function(a,b){var c=Sao.DateTime(a.y,a.M&&a.M-1,a.d,a.h,a.m,a.s,a.ms&&a.ms/1e3);return a.dy&&c.add(a.dy,"y"),a.dM&&c.add(a.dM,"M"),a.dd&&c.add(a.dd,"d"),a.dh&&c.add(a.dh,"h"),a.dm&&c.add(a.dm,"m"),a.ds&&c.add(a.ds,"s"),a.dms&&c.add(a.dms/1e3,"ms"),c},Sao.PYSON.DateTime.init_from_object=function(a){return new Sao.PYSON.DateTime(a.y,a.M,a.d,a.h,a.m,a.s,a.ms,a.dy,a.dM,a.dd,a.dh,a.dm,a.ds,a.dms)},Sao.PYSON.eval.Len=function(a){return new Sao.PYSON.Len(a)},Sao.PYSON.Len=Sao.class_(Sao.PYSON.PYSON,{init:function(a){if(Sao.PYSON.Len._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["object","string"]).length||jQuery(["object","string"]).not(a.types()).length)throw"value must be an object or a string"}else if("object"!=typeof a&&"string"!=typeof a)throw"value must be an object or a string";this._value=a},pyson:function(){return{__class__:"Len",v:this._value}},types:function(){return["integer"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Len.eval_=function(a,b){return"object"==typeof a.v?Object.keys(a.v).length:a.v.length},Sao.PYSON.Len.init_from_object=function(a){return new Sao.PYSON.Len(a.v)}}(),function(){"use strict";Sao.Session=Sao.class_(Object,{init:function(a,b){this.user_id=null,this.session=null,this.prm=jQuery.when(),this.database=a,this.login=b,this.context={},Sao.Session.current_session||(Sao.Session.current_session=this)},get_auth:function(){return btoa(this.login+":"+this.user_id+":"+this.session)},do_login:function(a,b){var c=jQuery.Deferred(),d=function(b){return{method:"common.db.login",params:[a,b,Sao.i18n.getlang()]}};return new Sao.Login(d,this).run().then(function(a){this.user_id=a[0],this.session=a[1],c.resolve()}.bind(this),function(){this.user_id=null,this.session=null,c.reject()}),c.promise()},do_logout:function(){if(!this.user_id||!this.session)return jQuery.when();var a={id:0,method:"common.db.logout",params:[]},b=jQuery.ajax({headers:{Authorization:"Session "+this.get_auth()},contentType:"application/json",data:JSON.stringify(a),dataType:"json",url:"/"+this.database+"/",type:"post"});return this.database=null,this.login=null,this.user_id=null,this.session=null,Sao.Session.current_session===this&&(Sao.Session.current_session=null),b},reload_context:function(){var a={method:"model.res.user.get_preferences",params:[!0,{}]},b=jQuery.extend({},this);return b.context={},Sao.rpc(a,b).then(function(a){this.context=a}.bind(this))}}),Sao.Session.login_dialog=function(){var a=new Sao.Dialog(Sao.i18n.gettext("Login"),"lg");return a.database_select=jQuery("<select/>",{class:"form-control",id:"login-database"}).hide(),a.database_input=jQuery("<input/>",{class:"form-control",id:"login-database"}).hide(),a.login_input=jQuery("<input/>",{class:"form-control",id:"login-login",placeholder:Sao.i18n.gettext("User name")}),a.body.append(jQuery("<div/>",{class:"form-group"}).append(jQuery("<label/>",{class:"control-label",for:"login-database"}).append(Sao.i18n.gettext("Database"))).append(a.database_select).append(a.database_input)).append(jQuery("<div/>",{class:"form-group"}).append(jQuery("<label/>",{class:"control-label",for:"login-login"}).append(Sao.i18n.gettext("User name"))).append(a.login_input)),a.button=jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Login")).appendTo(a.footer),a},Sao.Session.get_credentials=function(){var a=jQuery.Deferred(),b=window.location.hash.replace(/^(#(!|))/,"")||null,c=Sao.Session.login_dialog(),d=function(){return c.modal.find("input,select").filter(":visible").filter(function(){return!jQuery(this).val()})},e=function(){var b=c.login_input.val(),e=e||c.database_select.val()||c.database_input.val();if(c.modal.find(".has-error").removeClass("has-error"),!b||!e)return void d().closest(".form-group").addClass("has-error");c.button.focus(),c.button.prop("disabled",!0),c.modal.modal("hide");var f=new Sao.Session(e,b);f.do_login(b).then(function(){a.resolve(f),c.modal.remove()},function(){c.button.prop("disabled",!1),c.modal.modal("show"),d().closest(".form-group").addClass("has-error"),d().first().focus()})};return c.modal.modal({backdrop:!1,keyboard:!1}),c.modal.find("form").unbind().submit(function(a){e(),a.preventDefault()}),jQuery.when(Sao.DB.list()).then(function(a){var e;a=a||[],a.length<=1?(b=a[0],
+e=c.database_input):(e=c.database_select,a.forEach(function(a){e.append(jQuery("<option/>",{value:a,text:a}))})),e.prop("readonly",1==a.length),e.show(),e.val(b||""),d().first().focus()}),a.promise()},Sao.Session.renew=function(a){if("pending"==a.prm.state())return a.prm;var b=jQuery.Deferred();return a.prm=b.promise(),a.login?(a.do_login(a.login).then(b.resolve,b.reject),a.prm):(b.reject(),a.prm)},Sao.Session.current_session=null,Sao.Login=Sao.class_(Object,{init:function(a,b){this.func=a,this.session=b||Sao.Session.current_session},run:function(a){void 0===a&&(a={});var b=jQuery.Deferred(),c=Sao.common.processing.show(),d=this.func(a);d.id=0;var e={contentType:"application/json",data:JSON.stringify(d),dataType:"json",url:"/"+this.session.database+"/",type:"post",complete:[function(){Sao.common.processing.hide(c)}]};this.session.user_id&&this.session.session&&(e.headers={Authorization:"Session "+this.session.get_auth()});var f=jQuery.ajax(e),g=function(c){if(null===c)Sao.common.warning.run("",Sao.i18n.gettext("Unable to reach the server.")),b.reject();else if(c.error){if(c.error[0].startsWith("403"))return this.run({}).then(b.resolve,b.reject);if(c.error[0].startsWith("404"))b.reject();else if("LoginException"!=c.error[0])Sao.common.error.run(c.error[0],c.error[1]),b.reject();else{var d=c.error[1],e=d[0],f=d[1],g=d[2];this["get_"+g](f).then(function(c){return a[e]=c,this.run(a).then(b.resolve,b.reject)}.bind(this),b.reject)}}else b.resolve(c.result)};return f.success(g.bind(this)),f.error(b.reject),b.promise()},get_char:function(a){return Sao.common.ask.run(a)},get_password:function(a){return Sao.common.ask.run(a,!1)}}),Sao.DB={},Sao.DB.list=function(){var a=Sao.common.processing.show();return jQuery.ajax({contentType:"application/json",data:JSON.stringify({id:0,method:"common.db.list",params:[]}),dataType:"json",url:"/",type:"post",complete:[function(){Sao.common.processing.hide(a)}]}).then(function(a){return a.result})}}(),function(){"use strict";Sao.Model=Sao.class_(Object,{init:function(a,b){b=b||{},this.name=a,this.session=Sao.Session.current_session,this.fields={}},add_fields:function(a){var b=[];for(var c in a)if(a.hasOwnProperty(c)&&!(c in this.fields)){var d=a[c],e=Sao.field.get(d.type);this.fields[c]=new e(d),b.push(c)}return b},execute:function(a,b,c){void 0===c&&(c={});var d={method:"model."+this.name+"."+a,params:b.concat(c)};return Sao.rpc(d,this.session)},find:function(a,b,c,d,e){b||(b=0);var f=this,g=this.execute("search",[a,b,c,d],e),h=function(a){return Sao.Group(f,e,a.map(function(a){return new Sao.Record(f,a)}))};return g.pipe(h)},delete_:function(a){if(jQuery.isEmptyObject(a))return jQuery.when();var b=a[0],c=b.group.root_group();console.assert(a.every(function(a){return a.model.name==b.model.name}),"records not from the same model"),console.assert(a.every(function(a){return a.group.root_group()==b.group.root_group()}),"records not from the same root group"),a=a.filter(function(a){return a.id>=0});var d={};d._timestamp={},a.forEach(function(a){jQuery.extend(d._timestamp,a.get_timestamp())});var e=a.map(function(a){return a.id});return c.on_write_ids(e).then(function(a){return a=a.filter(function(a){return!~e.indexOf(a)}),this.execute("delete",[e],d).then(function(){c.reload(a)})}.bind(this))},copy:function(a,b){if(jQuery.isEmptyObject(a))return jQuery.when();var c=a.map(function(a){return a.id});return this.execute("copy",[c,{}],b)}}),Sao.Group=function(a,b,c){return c.prm=jQuery.when(),c.model=a,c._context=b,c.on_write=[],c.parent=void 0,c.screens=[],c.parent_name="",c.children=[],c.child_name="",c.parent_datetime_field=void 0,c.record_removed=[],c.record_deleted=[],c.__readonly=!1,c.skip_model_access=!1,c.forEach(function(a,b,c){a.group=c}),c.get_readonly=function(){var a=Sao.common.MODELACCESS.get(this.model.name);return!(!this.context._datetime&&(a.write||a.create||this.skip_model_access))||this.__readonly},c.set_readonly=function(a){this.__readonly=a},c.load=function(a,b){var c,d,e=[];for(c=0,d=a.length;c<d;c++){var f=a[c],g=this.get(f);g||(g=new Sao.Record(this.model,f),g.group=this,this.push(g)),e.push(g)}var h,i=[];for(c=0,d=this.record_removed.length;c<d;c++)h=this.record_removed[c],~a.indexOf(h.id)||i.push(h);this.record_removed=i;var j=[];for(c=0,d=this.record_deleted.length;c<d;c++)h=this.record_deleted[c],~a.indexOf(h.id)||j.push(h);this.record_deleted=j,e.length&&b&&this.changed()},c.get=function(a){for(var b=0,c=this.length;b<c;b++){var d=this[b];if(d.id==a)return d}},c.new_=function(a,b,c){var d=new Sao.Record(this.model,b);return d.group=this,a&&d.default_get(c),d},c.add=function(a,b,c){void 0!==b&&-1!=b||(b=this.length),void 0===c&&(c=!0),a.group!=this&&(a.group=this),this.splice(b,0,a);for(var d in this.record_removed)d.id==a.id&&this.record_removed.splice(this.record_removed.indexOf(d),1);for(var e in this.record_deleted)e.id==a.id&&this.record_deleted.splice(this.record_deleted.indexOf(e),1);if(a._changed.id=!0,c&&(this.changed(),this.parent&&this.model.fields[this.parent_name])){var f=this.model.fields[this.parent_name];if(f instanceof Sao.field.Many2One||f instanceof Sao.field.Reference){var g=[this.parent.id,""];f instanceof Sao.field.Reference&&(g=[this.parent.model.name,g]),f.set_client(a,g)}}return a},c.remove=function(a,b,c,d){void 0===c&&(c=!0);this.indexOf(a);a.id>=0&&(b?(~this.record_deleted.indexOf(a)&&this.record_deleted.splice(this.record_deleted.indexOf(a),1),this.record_removed.push(a)):(~this.record_removed.indexOf(a)&&this.record_removed.splice(this.record_removed.indexOf(a),1),this.record_deleted.push(a))),a.group.parent&&(a.group.parent._changed.id=!0),c&&(a._changed.id=!0),(a.id<0||d)&&this._remove(a),a.group.changed(),a.group.root_group().screens.forEach(function(a){a.display()})},c._remove=function(a){var b=this.indexOf(a);this.splice(b,1)},c.unremove=function(a){this.record_removed.splice(this.record_removed.indexOf(a),1),this.record_deleted.splice(this.record_deleted.indexOf(a),1),a.group.changed(),a.group.root_group().screens.forEach(function(a){a.display()})},c.changed=function(){if(!this.parent)return jQuery.when();this.parent._changed[this.child_name]=!0;var a=jQuery.Deferred(),b=this.parent.model.fields[this.child_name].changed(this.parent);return b?b.then(function(){this.parent.validate(null,!0).done(function(){this.parent.group.changed().done(a.resolve)}.bind(this))}.bind(this)):a.resolve(),a},c.root_group=function(){for(var a=this,b=this.parent;b;)a=b.group,b=b.parent;return a},c.save=function(){var a=[];return this.forEach(function(b){a.push(b.save())}),jQuery.isEmptyObject(this.record_deleted)||(this.record_deleted.forEach(function(a){this._remove(a)}.bind(this)),a.push(this.model.delete_(this.record_deleted)),this.record_deleted.splice(0,this.record_deleted.length)),jQuery.when.apply(jQuery,a)},c.written=function(a){return"number"==typeof a&&(a=[a]),this.on_write_ids(a).then(function(b){b=b.filter(function(b){return!~a.indexOf(b)}),this.root_group().reload(b)}.bind(this))},c.reload=function(a){this.children.forEach(function(b){b.reload(a)}),a.forEach(function(a){var b=this.get(a);b&&jQuery.isEmptyObject(b._changed)&&b.cancel()}.bind(this))},c.on_write_ids=function(a){var b=[],c=[];return this.on_write.forEach(function(d){var e=this.model.execute(d,[a],this._context).then(function(a){jQuery.extend(c,a)});b.push(e)}.bind(this)),jQuery.when.apply(jQuery,b).then(function(){return c.filter(function(a,b,c){return b==c.indexOf(a)})})},c.set_parent=function(a){this.parent=a,a&&a.model.name==this.model.name&&this.parent.group.children.push(this)},c.add_fields=function(a){var b=this.model.add_fields(a);if(!jQuery.isEmptyObject(this)){var c=[];this.forEach(function(a){a.id<0&&c.push(a)}),c.length&&b.length&&this.model.execute("default_get",[b,this.context()]).then(function(a){c.forEach(function(b){b.set_default(a)})})}},c.destroy=function(){if(this.parent){var a=this.parent.group.children.indexOf(this);~a&&this.parent.group.children.splice(a,1)}this.parent=null},c.domain=function(){var a=[];if(this.screens.forEach(function(b){b.attributes.domain&&a.push(b.attributes.domain)}),this.parent&&this.child_name){var b=this.parent.model.fields[this.child_name];return[a,b.get_domain(this.parent)]}return a},c.context=function(){var a=jQuery.extend({},this._context);if(this.parent&&(jQuery.extend(a,this.parent.get_context()),this.child_name in this.parent.model.fields)){var b=this.parent.model.fields[this.child_name];jQuery.extend(a,b.get_context(this.parent))}return jQuery.extend(a,this._context),this.parent_datetime_field&&(a._datetime=this.parent.get_eval()[this.parent_datetime_field]),a},c.set_context=function(a){this._context=jQuery.extend({},a)},c.clean4inversion=function(a){if(jQuery.isEmptyObject(a))return[];var b=new Sao.common.DomainInversion,c=a[0],d=a.slice(1);if(~["AND","OR"].indexOf(c));else if(b.is_leaf(c)){var e=c[0];e in this.model.fields&&this.model.fields[e].description.readonly&&(c=[])}else c=this.clean4inversion(c);return[c].concat(this.clean4inversion(d))},c.domain4inversion=function(){var a=this.domain();return this.__domain4inversion&&Sao.common.compare(this.__domain4inversion[0],a)||(this.__domain4inversion=[a,this.clean4inversion(a)]),this.__domain4inversion[1]},c.get_by_path=function(a){a=jQuery.extend([],a);var b=null,c=this,d=function(){if(jQuery.isEmptyObject(a))return b;var e=a[0][0],f=a[0][1];return a.splice(0,1),b=c.get(f),b?e?b.load(e).then(function(){return c=b._values[e],c?d():null}):d():null};return jQuery.when().then(d)},c.sort=function(a){var b={};this.forEach(function(a){b[a.id]=a}),a.forEach(function(a,c){this[c]=b[a.id]}.bind(this))},c},Sao.Record=Sao.class_(Object,{id_counter:-1,init:function(a,b){this.model=a,this.group=Sao.Group(a,{},[]),this.id=b||Sao.Record.prototype.id_counter--,this._values={},this._changed={},this._loaded={},this.fields={},this._timestamp=null,this.attachment_count=-1,this.unread_note=-1,this.button_clicks={},this.state_attrs={},this.autocompletion={},this.exception=!1},has_changed:function(){return!jQuery.isEmptyObject(this._changed)},save:function(a){void 0===a&&(a=!1);var b=this.get_context(),c=jQuery.when(),d=this.get();if(this.id<0||!jQuery.isEmptyObject(d)){if(this.id<0){c=this.model.execute("create",[[d]],b);var e=function(a){this.id=a[0]};c.done(e.bind(this))}else jQuery.isEmptyObject(d)||(b._timestamp=this.get_timestamp(),c=this.model.execute("write",[[this.id],d],b));c=c.done(function(){if(this.cancel(),a)return this.reload()}.bind(this)),this.group&&(c=c.done(function(){return this.group.written(this.id)}.bind(this)))}return this.group.parent&&(delete this.group.parent._changed[this.group.child_name],c=c.done(function(){return this.group.parent.save(a)}.bind(this))),c},reload:function(a){if(this.id<0)return jQuery.when();if(a){var b=a.map(function(a){return this.load(a)}.bind(this));return jQuery.when.apply(jQuery,b)}return this.load("*")},load:function(a){var b,c;if(this.id<0||a in this._loaded)return jQuery.when();if("pending"==this.group.prm.state())return c=jQuery.Deferred(),this.group.prm.then(function(){this.load(a).then(c.resolve,c.reject)}.bind(this)),c;var d={};d[this.id]=this;var e;if("*"==a){e="eager";for(b in this.model.fields)if(this.model.fields.hasOwnProperty(b)){var f=this.model.fields[b].description.loading||"eager";if("eager"!=f){e="lazy";break}}}else e=this.model.fields[a].description.loading||"eager";var g=[];if("eager"==e)for(b in this.model.fields)this.model.fields.hasOwnProperty(b)&&"eager"==(this.model.fields[b].description.loading||"eager")&&g.push(b);else g=Object.keys(this.model.fields);g=g.filter(function(a,b,c){return!(a in this._loaded)}.bind(this));var h=g.slice(),i=["many2one","one2one","reference"];for(var j in g){b=g[j];var k=this.model.fields[b].description;~i.indexOf(k.type)&&h.push(b+".rec_name")}~g.indexOf("rec_name")||h.push("rec_name"),h.push("_timestamp");var l=jQuery.extend({},this.get_context());if("eager"==e){var m,n,o=parseInt(Sao.config.limit/h.length,10),p=function(b){return!(a in b._loaded)&&b.id>=0},q=function(a){return p(a)&&void 0===d[a.id]&&(a.group===this.group||JSON.stringify(a.get_context())===JSON.stringify(l))}.bind(this);this.group.parent&&this.group.parent.model.name==this.model.name?(m=[],m=m.concat.apply(m,this.group.parent.group.children),n=q):(m=this.group,n=p);var r=m.indexOf(this);if(~r)for(var s=m.length,t=1;Object.keys(d).length<o&&(r-t>=0||r+t<s)&&t<2*o;){var u;r-t>=0&&(u=m[r-t],n(u)&&(d[u.id]=u)),r+t<s&&(u=m[r+t],n(u)&&(d[u.id]=u)),t++}}for(b in this.model.fields)this.model.fields.hasOwnProperty(b)&&"binary"==this.model.fields[b].description.type&&~h.indexOf(b,h)&&(l[this.model.name+"."+b]="size");c=this.model.execute("read",[Object.keys(d).map(function(a){return parseInt(a,10)}),h],l);var v=function(a,b){void 0===b&&(b=!1);var c={},e=[];a.forEach(function(a,b,d){c[a.id]=a});for(var f in d)if(d.hasOwnProperty(f)){var g=d[f];g.exception||(g.exception=b);var h=c[f];if(g&&h){for(var i in this._changed)this._changed.hasOwnProperty(i)&&delete h[i];e.push(g.set(h))}}return jQuery.when.apply(jQuery,e)}.bind(this),w=function(){var a,b=[];for(var c in d){a={id:c};for(var e in h)a[h[e]]=null;b.push(a)}return v(b,!0)};return this.group.prm=c.then(v,w),this.group.prm},set:function(a,b){void 0===b&&(b=!0);var c,d,e={},f=[];for(c in a)if(a.hasOwnProperty(c))if(d=a[c],"_timestamp"!=c)if(c in this.model.fields){if(this.model.fields[c]instanceof Sao.field.One2Many&&(e[c]=d),this.model.fields[c]instanceof Sao.field.Many2One||this.model.fields[c]instanceof Sao.field.Reference){var g=c+".rec_name";a.hasOwnProperty(g)?this._values[g]=a[g]:this._values.hasOwnProperty(g)&&delete this._values[g]}this.model.fields[c].set(this,d),this._loaded[c]=!0,f.push(c)}else"rec_name"==c&&(this._values[c]=d);else this._timestamp||(this._timestamp=d);for(c in e)d=e[c],this.model.fields[c].set(this,d),this._loaded[c]=!0;return b?this.validate(f,!0):jQuery.when()},get:function(){var a={};for(var b in this.model.fields)if(this.model.fields.hasOwnProperty(b)){var c=this.model.fields[b];(!c.description.readonly||c instanceof Sao.field.One2Many)&&(void 0===this._changed[b]&&this.id>=0||(a[b]=c.get(this)))}return a},invalid_fields:function(){var a={};for(var b in this.model.fields){var c=this.model.fields[b],d=c.get_state_attrs(this).invalid;d&&(a[b]=d)}return a},get_context:function(){return this.group.context()},field_get:function(a){return this.model.fields[a].get(this)},field_set:function(a,b){this.model.fields[a].set(this,b)},field_get_client:function(a){return this.model.fields[a].get_client(this)},field_set_client:function(a,b,c){this.model.fields[a].set_client(this,b,c)},default_get:function(a){if(!jQuery.isEmptyObject(this.model.fields)){var b=this.get_context();void 0===b.default_rec_name&&(b.default_rec_name=a);return this.model.execute("default_get",[Object.keys(this.model.fields)],b).then(function(a){if(this.group.parent&&this.group.parent_name in this.group.model.fields){var b=this.group.model.fields[this.group.parent_name];b instanceof Sao.field.Reference?a[this.group.parent_name]=[this.group.parent.model.name,this.group.parent.id]:b.description.relation==this.group.parent.model.name&&(a[this.group.parent_name]=this.group.parent.id)}return this.set_default(a)}.bind(this))}return jQuery.when()},set_default:function(a,b){void 0===b&&(b=!0);var c=[],d=[];for(var e in a)if(a.hasOwnProperty(e)){var f=a[e];if(e in this.model.fields){if(this.model.fields[e]instanceof Sao.field.Many2One||this.model.fields[e]instanceof Sao.field.Reference){var g=e+".rec_name";a.hasOwnProperty(g)?this._values[g]=a[g]:this._values.hasOwnProperty(g)&&delete this._values[g]}c.push(this.model.fields[e].set_default(this,f)),this._loaded[e]=!0,d.push(e)}}return jQuery.when.apply(jQuery,c).then(function(){return this.on_change(d).then(function(){return this.on_change_with(d).then(function(){var a=function(){return this.group.root_group().screens.forEach(function(a){return a.display()})}.bind(this);return b?this.validate(null,!0).then(a):a()}.bind(this))}.bind(this))}.bind(this))},get_timestamp:function(){var a={};a[this.model.name+","+this.id]=this._timestamp;for(var b in this.model.fields)this.model.fields.hasOwnProperty(b)&&b in this._loaded&&jQuery.extend(a,this.model.fields[b].get_timestamp(this));return a},get_eval:function(){var a={};for(var b in this.model.fields)!this.model.fields.hasOwnProperty(b)&&this.id>=0||(a[b]=this.model.fields[b].get_eval(this));return a},get_on_change_value:function(a){var b={};for(var c in this.model.fields)a&&~a.indexOf(c)||(!(this.id>=0)||this._loaded[c]&&this._changed[c])&&(b[c]=this.model.fields[c].get_on_change_value(this));return b.id=this.id,b},_get_on_change_args:function(a){var b={},c=Sao.common.EvalEnvironment(this,"on_change");return a.forEach(function(a){var d=c;a.split(".").forEach(function(a){void 0!==d&&(d=d[a])}),b[a]=d}),b.id=this.id,b},on_change:function(a){var b={};return a.forEach(function(a){var c=this.model.fields[a].description.on_change;jQuery.isEmptyObject(c)||(b=jQuery.extend(b,this._get_on_change_args(c)))}.bind(this)),jQuery.isEmptyObject(b)?jQuery.when():this.model.execute("on_change",[b,a],this.get_context()).then(function(a){a.forEach(this.set_on_change.bind(this))}.bind(this))},on_change_with:function(a){var b,c,d={},e={},f={};for(b in this.model.fields)if(this.model.fields.hasOwnProperty(b)&&(c=this.model.fields[b].description.on_change_with,!jQuery.isEmptyObject(c))){for(var g=0;g<a.length&&!~c.indexOf(a[g]);g++);g>=a.length||(jQuery.isEmptyObject(Sao.common.intersect(Object.keys(d).sort(),c.sort()))?(d[b]=!0,e=jQuery.extend(e,this._get_on_change_args(c)),(this.model.fields[b]instanceof Sao.field.Many2One||this.model.fields[b]instanceof Sao.field.Reference)&&delete this._values[b+".rec_name"]):f[b]=!0)}var h,i=[];jQuery.isEmptyObject(d)||(h=this.model.execute("on_change_with",[e,Object.keys(d)],this.get_context()),i.push(h.then(this.set_on_change.bind(this))));var j=function(a){return function(b){this.model.fields[a].set_on_change(this,b)}};for(b in f)f.hasOwnProperty(b)&&(c=this.model.fields[b].description.on_change_with,e=this._get_on_change_args(c),h=this.model.execute("on_change_with_"+b,[e],this.get_context()),i.push(h.then(j(b).bind(this))));return jQuery.when.apply(jQuery,i)},set_on_change:function(a){var b,c;for(b in a)if(a.hasOwnProperty(b)&&(c=a[b],b in this.model.fields)){if(this.model.fields[b]instanceof Sao.field.Many2One||this.model.fields[b]instanceof Sao.field.Reference){var d=b+".rec_name";a.hasOwnProperty(d)?this._values[d]=a[d]:this._values.hasOwnProperty(d)&&delete this._values[d]}this.model.fields[b].set_on_change(this,c)}},autocomplete_with:function(a){var b=[];for(var c in this.model.fields){~(this.model.fields[c].description.autocomplete||[]).indexOf(a)&&b.push(this.do_autocomplete(c))}return jQuery.when.apply(jQuery,b)},do_autocomplete:function(a){this.autocompletion[a]=[];var b=this.model.fields[a],c=b.description.autocomplete,d=this._get_on_change_args(c);return this.model.execute("autocomplete_"+a,[d],this.get_context()).then(function(b){this.autocompletion[a]=b}.bind(this))},expr_eval:function(a){if("string"!=typeof a)return a;var b=jQuery.extend({},this.model.session.context);if(b.context=jQuery.extend({},b),jQuery.extend(b.context,this.get_context()),jQuery.extend(b,this.get_eval()),b.active_model=this.model.name,b.active_id=this.id,b._user=this.model.session.user_id,this.group.parent&&this.group.parent_name){var c=Sao.common.EvalEnvironment(this.group.parent);b["_parent_"+this.group.parent_name]=c}return new Sao.PYSON.Decoder(b).decode(a)},rec_name:function(){return this.model.execute("read",[[this.id],["rec_name"]],this.get_context()).then(function(a){return a[0].rec_name})},validate:function(a,b,c,d){var e=function(){var e=!0,f=[];this.group.screens.forEach(function(a){a.exclude_field&&f.push(a.exclude_field)});for(var g in this.model.fields)if((!(d&&this.id>=0)||g in this._loaded)&&this.model.fields.hasOwnProperty(g)){var h=this.model.fields[g];a&&!~a.indexOf(g)||h.description.readonly||~f.indexOf(g)||h.validate(this,b,c)||(e=!1)}return e}.bind(this);return d?e():this._check_load(a).then(e)},pre_validate:function(){if(jQuery.isEmptyObject(this._changed))return jQuery.Deferred().resolve(!0);var a=this._get_on_change_args(Object.keys(this._changed));return this.model.execute("pre_validate",[a],this.get_context()).then(function(){return!0},function(){return!1})},cancel:function(){this._loaded={},this._changed={},this._timestamp=null,this.button_clicks={}},_check_load:function(a){return this.get_loaded(a)?jQuery.when():this.reload(a)},get_loaded:function(a){if(!jQuery.isEmptyObject(a)){var b=!0;return a.forEach(function(a){a in this._loaded||a in this._changed||(b=!1)}.bind(this)),b}return Sao.common.compare(Object.keys(this.model.fields).sort(),Object.keys(this._loaded).sort())},root_parent:function(){for(var a=this;a.group.parent;)a=a.group.parent;return a},get_path:function(a){for(var b=[],c=this,d="";c&&(b.push([d,c.id]),c.group!==a);)d=c.group.child_name,c=c.group.parent;return b.reverse(),b},deleted:function(){return Boolean(~this.group.record_deleted.indexOf(this))},removed:function(){return Boolean(~this.group.record_removed.indexOf(this))},readonly:function(){return this.deleted()||this.removed()||this.exception},set_field_context:function(){for(var a in this.model.fields)if(this.model.fields.hasOwnProperty(a)){var b=this.model.fields[a],c=this._values[a];if(c&&c.set_context){var d=b.description.context;d&&c.set_context(this.expr_eval(d))}}},get_attachment_count:function(a){var b=jQuery.Deferred();return this.id<0?(b.resolve(0),b):(this.attachment_count<0||a?b=Sao.rpc({method:"model.ir.attachment.search_count",params:[[["resource","=",this.model.name+","+this.id]],this.get_context()]},this.model.session).then(function(a){return this.attachment_count=a,a}.bind(this)):b.resolve(this.attachment_count),b)},get_unread_note:function(a){var b=jQuery.Deferred();return this.id<0?(b.resolve(0),b):(this.unread_note<0||a?b=Sao.rpc({method:"model.ir.note.search_count",params:[[["resource","=",this.model.name+","+this.id],["unread","=",!0]],this.get_context()]},this.model.session).then(function(a){return this.unread_note=a,a}.bind(this)):b.resolve(this.unread_note),b)},get_button_clicks:function(a){if(this.id<0)return jQuery.when();var b=this.button_clicks[a];return void 0!==b?jQuery.when(b):Sao.rpc({method:"model.ir.model.button.click.get_click",params:[this.model.name,a,this.id,{}]},this.model.session).then(function(b){return this.button_clicks[a]=b,b}.bind(this))}}),Sao.field={},Sao.field.get=function(a){switch(a){case"char":return Sao.field.Char;case"selection":return Sao.field.Selection;case"datetime":return Sao.field.DateTime;case"date":return Sao.field.Date;case"time":return Sao.field.Time;case"timedelta":return Sao.field.TimeDelta;case"float":return Sao.field.Float;case"numeric":return Sao.field.Numeric;case"integer":return Sao.field.Integer;case"boolean":return Sao.field.Boolean;case"many2one":return Sao.field.Many2One;case"one2one":return Sao.field.One2One;case"one2many":return Sao.field.One2Many;case"many2many":return Sao.field.Many2Many;case"reference":return Sao.field.Reference;case"binary":return Sao.field.Binary;case"dict":return Sao.field.Dict;default:return Sao.field.Char}},Sao.field.Field=Sao.class_(Object,{_default:null,init:function(a){this.description=a,this.name=a.name},set:function(a,b){a._values[this.name]=b},get:function(a){var b=a._values[this.name];return void 0===b&&(b=this._default),b},set_client:function(a,b,c){var d=this.get(a);this.set(a,b),JSON.stringify(d)!=JSON.stringify(this.get(a))?(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.changed().done(function(){a.group.root_group().screens.forEach(function(a){a.display()})})})})):c&&(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.root_group().screens.forEach(function(a){a.display()})})}))},get_client:function(a){return this.get(a)},set_default:function(a,b){a._values[this.name]=b,a._changed[this.name]=!0},set_on_change:function(a,b){a._values[this.name]=b,a._changed[this.name]=!0},changed:function(a){var b=[];return b.push(a.on_change([this.name])),b.push(a.on_change_with([this.name])),b.push(a.autocomplete_with(this.name)),a.set_field_context(),jQuery.when.apply(jQuery,b)},get_timestamp:function(a){return{}},get_context:function(a){var b=jQuery.extend({},a.get_context());return a.group.parent&&jQuery.extend(b,a.group.parent.get_context()),jQuery.extend(b,a.expr_eval(this.description.context||{})),b},get_domains:function(a,b){var c=new Sao.common.DomainInversion,d=c.domain_inversion([a.group.domain4inversion(),b||[]],this.name,Sao.common.EvalEnvironment(a));return"boolean"!=typeof d||d?"boolean"==typeof d&&d&&(d=[]):d=[["id","=",null]],[d,a.expr_eval(this.description.domain||[])]},get_domain:function(a){var b=this.get_domains(a),c=b[0],d=b[1],e=new Sao.common.DomainInversion;return e.concat([e.localize_domain(c),d])},validation_domains:function(a,b){return(new Sao.common.DomainInversion).concat(this.get_domains(a,b))},get_eval:function(a){return this.get(a)},get_on_change_value:function(a){return this.get_eval(a)},set_state:function(a,b){void 0===b&&(b=["readonly","required","invisible"]);var c=a.expr_eval(this.description.states||{});b.forEach(function(b){"readonly"==b&&this.description.readonly||(void 0!==c[b]?this.get_state_attrs(a)[b]=c[b]:void 0!==this.description[b]&&(this.get_state_attrs(a)[b]=this.description[b]))}.bind(this)),(a.group.get_readonly()||this.get_state_attrs(a).domain_readonly)&&(this.get_state_attrs(a).readonly=!0)},get_state_attrs:function(a){return this.name in a.state_attrs||(a.state_attrs[this.name]=jQuery.extend({},this.description)),(a.group.get_readonly()||a.readonly())&&(a.state_attrs[this.name].readonly=!0),a.state_attrs[this.name]},check_required:function(a){var b=this.get_state_attrs(a);return!(1==b.required&&!this.get(a)&&1!=b.readonly)},validate:function(a,b,c){if(this.description.readonly)return!0;var d=!1;this.get_state_attrs(a).domain_readonly=!1;var e=new Sao.common.DomainInversion,f=e.simplify(this.validation_domains(a,c));if(b||this.check_required(a)||(d="required"),"boolean"==typeof f)f||(d="domain");else if(Sao.common.compare(f,[["id","=",null]]))d="domain";else{var g=e.unique_value(f),h=g[0],i=g[1],j=g[2];if(h){!1===j&&(j=null);var k,l=!0;k=jQuery.isEmptyObject(a.group.domain())?e.merge(f):e.merge(a.group.domain());var m="AND"==k[0];if(i.contains(".")){var n=i.split(".",1)[0],o=i.split(".",1)[1],p=[];m&&e.localize_domain(k.slice(1)).forEach(function(a){p.push(a)}),"id"==o&&~p.indexOf(n)||(l=!1)}l&&!c&&(this.set_client(a,j),this.get_state_attrs(a).domain_readonly=m)}e.eval_domain(f,Sao.common.EvalEnvironment(a))||(d=f)}return this.get_state_attrs(a).invalid=d,!d}}),Sao.field.Char=Sao.class_(Sao.field.Field,{_default:"",get:function(a){return Sao.field.Char._super.get.call(this,a)||this._default}}),Sao.field.Selection=Sao.class_(Sao.field.Field,{_default:null}),Sao.field.DateTime=Sao.class_(Sao.field.Field,{_default:null,time_format:function(a){return a.expr_eval(this.description.format)},set_client:function(a,b,c){var d;b&&(b.isTime?(d=this.get(a),b=d?Sao.DateTime.combine(d,b):null):b.isDate&&(d=this.get(a))&&(b=Sao.DateTime.combine(b,d))),Sao.field.DateTime._super.set_client.call(this,a,b,c)},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)}}),Sao.field.Date=Sao.class_(Sao.field.Field,{_default:null,set_client:function(a,b,c){b&&!b.isDate&&(b.isDate=!0,b.isDateTime=!1),Sao.field.Date._super.set_client.call(this,a,b,c)},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)}}),Sao.field.Time=Sao.class_(Sao.field.Field,{_default:null,time_format:function(a){return a.expr_eval(this.description.format)},set_client:function(a,b,c){b&&(b.isDate||b.isDateTime)&&(b=Sao.Time(b.hour(),b.minute(),b.second(),b.millisecond())),Sao.field.Time._super.set_client.call(this,a,b,c)}}),Sao.field.TimeDelta=Sao.class_(Sao.field.Field,{_default:null,converter:function(a){return a.model.session.context[this.description.converter]},set_client:function(a,b,c){"string"==typeof b&&(b=Sao.common.timedelta.parse(b,this.converter(a))),Sao.field.TimeDelta._super.set_client.call(this,a,b,c)},get_client:function(a){var b=Sao.field.TimeDelta._super.get_client.call(this,a);return Sao.common.timedelta.format(b,this.converter(a))}}),Sao.field.Float=Sao.class_(Sao.field.Field,{_default:null,digits:function(a,b){void 0===b&&(b=1);var c=a.expr_eval(this.description.digits);if(c&&c.every(function(a){return null!==a})){var d=Math.round(Math.log(Math.abs(b))/Math.LN10);return[c[0]+d,c[1]-d]}},check_required:function(a){var b=this.get_state_attrs(a);return 1!=b.required||null!==this.get(a)||1==b.readonly},convert:function(a){return a?(a=Number(a),isNaN(a)&&(a=this._default),a):null},apply_factor:function(a,b){return null!==a&&(a/=b),a},set_client:function(a,b,c,d){void 0===d&&(d=1),b=this.apply_factor(this.convert(b),d),Sao.field.Float._super.set_client.call(this,a,b,c)},get_client:function(a,b){void 0===b&&(b=1);var c=this.get(a);if(null!==c){var d=this.digits(a,b);return d?(c*b).toFixed(d[1]):""+c*b}return""}}),Sao.field.Numeric=Sao.class_(Sao.field.Float,{convert:function(a){return a?(a=new Sao.Decimal(a),isNaN(a.valueOf())&&(a=this._default),a):null},apply_factor:function(a,b){return a=Sao.field.Numeric._super.apply_factor(a,b),null!==a&&(a=new Sao.Decimal(a)),a}}),Sao.field.Integer=Sao.class_(Sao.field.Float,{convert:function(a){return a=parseInt(a,10),isNaN(a)&&(a=this._default),a}}),Sao.field.Boolean=Sao.class_(Sao.field.Field,{_default:!1,set_client:function(a,b,c){b=Boolean(b),Sao.field.Boolean._super.set_client.call(this,a,b,c)},get:function(a){return Boolean(a._values[this.name])},get_client:function(a){return Boolean(a._values[this.name])}}),Sao.field.Many2One=Sao.class_(Sao.field.Field,{_default:null,check_required:function(a){var b=this.get_state_attrs(a);return 1!=b.required||null!==this.get(a)||1==b.readonly},get_client:function(a){var b=a._values[this.name+".rec_name"];return void 0===b&&(this.set(a,this.get(a)),b=a._values[this.name+".rec_name"]||""),b},set:function(a,b){var c=a._values[this.name+".rec_name"]||"",d=function(b){a._values[this.name+".rec_name"]=b[0].rec_name};if(!c&&b>=0&&null!==b){var e=a.model.fields[this.name].description.relation;Sao.rpc({method:"model."+e+".read",params:[[b],["rec_name"],a.get_context()]},a.model.session).done(d.bind(this)).done(function(){a.group.root_group().screens.forEach(function(a){a.display()})})}else d.call(this,[{rec_name:c}]);a._values[this.name]=b},set_client:function(a,b,c){var d;b instanceof Array?(d=b[1],b=b[0]):d=b==this.get(a)?a._values[this.name+".rec_name"]||"":"",a._values[this.name+".rec_name"]=d,Sao.field.Many2One._super.set_client.call(this,a,b,c)},get_context:function(a){var b=Sao.field.Many2One._super.get_context.call(this,a);return this.description.datetime_field&&(b._datetime=a.get_eval()[this.description.datetime_field]),b},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=this.get_domains(a),c=b[0],d=b[1],e=new Sao.common.DomainInversion;return e.concat([e.localize_domain(e.inverse_leaf(c),this.name),d])},get_on_change_value:function(a){return a.group.parent_name==this.name&&a.group.parent?a.group.parent.get_on_change_value([a.group.child_name]):Sao.field.Many2One._super.get_on_change_value.call(this,a)}}),Sao.field.One2One=Sao.class_(Sao.field.Many2One,{}),Sao.field.One2Many=Sao.class_(Sao.field.Field,{init:function(a){Sao.field.One2Many._super.init.call(this,a)},_default:null,_set_value:function(a,b,c){this._set_default_value(a);var d=a._values[this.name],e=jQuery.when();jQuery.isEmptyObject(b)&&(b=[]);var f;if("list values"==(f=jQuery.isEmptyObject(b)||!isNaN(parseInt(b[0],10))?"list ids":"list values")){var g=this.get_context(a),h={}
+;if(b.forEach(function(a){for(var b in a)a.hasOwnProperty(b)&&(b in d.model.fields||~b.indexOf(".")||(h[b]=!0))}),!jQuery.isEmptyObject(h)){var i={method:"model."+this.description.relation+".fields_get",params:[Object.keys(h),g]};e=Sao.rpc(i,a.model.session)}}var j=function(e){var g=[];if(jQuery.isEmptyObject(e)||d.add_fields(e),a._values[this.name]=d,"list ids"==f){for(var h=0,i=d.length;h<i;h++){var j=d[h];~b.indexOf(j.id)||d.remove(j,!0)}d.load(b)}else b.forEach(function(a){var b=d.new_(!1);c?(g.push(b.set_default(a,!1)),d.add(b)):(g.push(b.set(a)),d.push(b))});return jQuery.when.apply(jQuery,g)};return e.then(j)},set:function(a,b,c){void 0===c&&(c=!1);var d,e=a._values[this.name];return void 0!==e?(d=e.model,e.destroy()):d=a.model.name==this.description.relation?a.model:new Sao.Model(this.description.relation),a._values[this.name]=void 0,this._set_default_value(a,d),this._set_value(a,b,c)},get:function(a){var b=a._values[this.name];if(void 0===b)return[];for(var c=b.record_removed,d=b.record_deleted,e=[],f=this.description.relation_field||"",g=[],h=[],i=[],j=0,k=b.length;j<k;j++){var l=b[j];if(!~c.indexOf(l)&&!~d.indexOf(l)){var m;l.id>=0?(m=l.get(),delete m[f],l.has_changed()&&!jQuery.isEmptyObject(m)&&(i.push([l.id]),i.push(m)),g.push(l.id)):(m=l.get(),delete m[f],h.push(m))}}return jQuery.isEmptyObject(g)||e.push(["add",g]),jQuery.isEmptyObject(h)||e.push(["create",h]),jQuery.isEmptyObject(i)||e.push(["write"].concat(i)),jQuery.isEmptyObject(c)||e.push(["remove",c.map(function(a){return a.id})]),jQuery.isEmptyObject(d)||e.push(["delete",d.map(function(a){return a.id})]),e},set_client:function(a,b,c){null===b&&(b=[]),"number"==typeof b&&(b=[b]);var d=this.get_eval(a);this._set_value(a,b),Sao.common.compare(d.sort(),b.sort())?c&&(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.root_group().screens.forEach(function(a){a.display()})})})):(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.changed().done(function(){a.group.root_group().screens.forEach(function(a){a.display()})})})}))},get_client:function(a){return this._set_default_value(a),a._values[this.name]},set_default:function(a,b){return a._changed[this.name]=!0,this.set(a,b,!0)},set_on_change:function(a,b){if(a._changed[this.name]=!0,this._set_default_value(a),b instanceof Array)return void this._set_value(a,b);var c=jQuery.when();if(b.add||b.update){var d=this.get_context(a),e=a._values[this.name].model.fields,f={},g=[];if(b.add)for(var h=0;h<b.add.length;h++)g.push(b.add[h][1]);if([g,b.update].forEach(function(a){jQuery.isEmptyObject(a)||a.forEach(function(a){Object.keys(a).forEach(function(a){a in e||"id"==a||(f[a]=!0)})})}),!jQuery.isEmptyObject(f)){var i={method:"model."+this.description.relation+".fields_get",params:[Object.keys(f),d]};c=Sao.rpc(i,a.model.session)}}var j=[],k=a._values[this.name];k.forEach(function(a){a.id||j.push(a)}),b.remove&&b.remove.forEach(function(a){var b=k.get(a);b&&j.push(b)}.bind(this)),j.forEach(function(a){k.remove(a,!1,!0,!1)}.bind(this)),(b.add||b.update)&&c.then(function(a){k.add_fields(a),b.add&&b.add.forEach(function(a){var b=a[0],c=a[1],d=k.new_(!1);k.add(d,b,!1),d.set_on_change(c)}),b.update&&b.update.forEach(function(a){if(a.id){var b=k.get(a.id);b&&b.set_on_change(a)}})}.bind(this))},_set_default_value:function(a,b){if(void 0===a._values[this.name]){b||(b=new Sao.Model(this.description.relation)),a.model.name==this.description.relation&&(b=a.model);var c=a.expr_eval(this.description.context||{}),d=Sao.Group(b,c,[]);d.set_parent(a),d.parent_name=this.description.relation_field,d.child_name=this.name,a._values[this.name]=d}},get_timestamp:function(a){var b=a._values[this.name];if(void 0===b)return{};for(var c,d={},e=0,f=b.length;e<f;e++)c=b[e],jQuery.extend(d,c.get_timestamp());return d},get_eval:function(a){var b=[],c=a._values[this.name];if(void 0===c)return b;for(var d=c.record_removed,e=c.record_deleted,f=0,g=a._values[this.name].length;f<g;f++){var h=c[f];~d.indexOf(h)||~e.indexOf(h)||b.push(h.id)}return b},get_on_change_value:function(a){var b=[],c=a._values[this.name];if(void 0===c)return b;for(var d=0,e=a._values[this.name].length;d<e;d++){var f=c[d];f.deleted()&&f.removed()||b.push(f.get_on_change_value([this.description.relation_field||""]))}return b},get_removed_ids:function(a){return a._values[this.name].record_removed.map(function(a){return a.id})},get_domain:function(a){return this.get_domains(a)[1]},validation_domains:function(a,b){return this.get_domains(a,b)[0]},validate:function(a,b,c){var d=!1,e=new Sao.common.DomainInversion,f=e.localize_domain(e.domain_inversion(a.group.clean4inversion(c||[]),this.name,Sao.common.EvalEnvironment(a)),this.name);"boolean"==typeof f&&(f=f?[]:[["id","=",null]]);for(var g=0,h=(a._values[this.name]||[]).length;g<h;g++){var i=a._values[this.name][g];!i.get_loaded()&&i.id>=0&&!c||(i.validate(null,b,f,!0)||(d="children"))}var j=Sao.field.One2Many._super.validate.call(this,a,b,c);return j&&d?(this.get_state_attrs(a).invalid=d,!1):j},set_state:function(a,b){this._set_default_value(a),Sao.field.One2Many._super.set_state.call(this,a,b)}}),Sao.field.Many2Many=Sao.class_(Sao.field.One2Many,{get_on_change_value:function(a){return this.get_eval(a)}}),Sao.field.Reference=Sao.class_(Sao.field.Field,{_default:null,get_client:function(a){if(a._values[this.name]){return[a._values[this.name][0],a._values[this.name+".rec_name"]||""]}return null},get:function(a){return a._values[this.name]&&a._values[this.name][0]&&a._values[this.name][1]>=-1?a._values[this.name].join(","):null},set_client:function(a,b,c){if(b){"string"==typeof b&&(b=b.split(","));var d,e=b[0],f=b[1];f instanceof Array?(d=f[1],f=f[0]):(f&&!isNaN(parseInt(f,10))&&(f=parseInt(f,10)),d=[e,f].join(",")==this.get(a)?a._values[this.name+".rec_name"]||"":""),a._values[this.name+".rec_name"]=d,b=[e,f]}Sao.field.Reference._super.set_client.call(this,a,b,c)},set:function(a,b){if(!b)return void(a._values[this.name]=this._default);var c,d;"string"==typeof b?(c=b.split(",")[0],d=b.split(",")[1],d?isNaN(parseInt(d,10))||(d=parseInt(d,10)):d=null):(c=b[0],d=b[1]);var e=a._values[this.name+".rec_name"]||"",f=function(b){a._values[this.name+".rec_name"]=b}.bind(this);c&&null!==d&&d>=0?!e&&d>=0&&Sao.rpc({method:"model."+c+".read",params:[[d],["rec_name"],a.get_context()]},a.model.session).done(function(a){f(a[0].rec_name)}):e=c?"":d,a._values[this.name]=[c,d],f(e)},get_on_change_value:function(a){return a.group.parent_name==this.name&&a.group.parent?[a.group.parent.model.name,a.group.parent.get_on_change_value([a.group.child_name])]:Sao.field.Reference._super.get_on_change_value.call(this,a)},get_context:function(a){var b=Sao.field.Reference._super.get_context.call(this,a);return this.description.datetime_field&&(b._datetime=a.get_eval()[this.description.datetime_field]),b},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=null;a._values[this.name]&&(b=a._values[this.name][0]);var c=this.get_domains(a),d=c[0],e=c[1],f=new Sao.common.DomainInversion;return f.concat([f.localize_domain(f.filter_leaf(d,this.name,b),!0),e])}}),Sao.field.Binary=Sao.class_(Sao.field.Field,{_default:null,get_size:function(a){var b=a._values[this.name]||0;return b instanceof Uint8Array?b.length:b},get_data:function(a){var b=a._values[this.name]||[],c=jQuery.when(b);if(!(b instanceof Uint8Array)){if(a.id<0)return c;var d=a.get_context();c=a.model.execute("read",[[a.id],[this.name]],d).then(function(a){return a[0][this.name]}.bind(this))}return c}}),Sao.field.Dict=Sao.class_(Sao.field.Field,{_default:{},set:function(a,b){if(b){var c=[];for(var d in b)c.push(d);c.sort();var e={};for(var f in c)d=c[f],e[d]=b[d];b=e}Sao.field.Dict._super.set.call(this,a,b)},get:function(a){return Sao.field.Dict._super.get.call(this,a)||this._default},get_client:function(a){return Sao.field.Dict._super.get_client.call(this,a)||this._default},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=new Sao.common.DomainInversion,c=this.get_domains(a),d=c[0],e=c[1];return b.concat([b.localize_domain(b.inverse_leaf(d)),e])},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)},time_format:function(a){return"%X"}})}(),function(){"use strict";Sao.Tab=Sao.class_(Object,{init:function(){Sao.Tab.tabs.push(this),this.buttons={},this.id="tab-"+Sao.Tab.counter++,this.name="",this.name_el=jQuery("<span/>")},create_tabcontent:function(){this.el=jQuery("<div/>",{class:this.class_});var a=this.create_toolbar().appendTo(this.el);this.title=a.find(".title"),this.content=jQuery("<div/>").appendTo(this.el),this.info_bar&&this.el.append(this.info_bar.el)},set_menu:function(a){this.menu_def().forEach(function(b){var c=b[0],d=b[1],e=b[2],f=jQuery("<li/>",{role:"presentation"}).appendTo(a),g=jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(jQuery("<span/>",{class:"glyphicon "+c,"aria-hidden":"true"})).append(" "+d).appendTo(f);e?g.click(function(){this[e]()}.bind(this)):f.addClass("disabled")}.bind(this))},create_toolbar:function(){var a=jQuery("<nav/>",{class:"toolbar navbar navbar-default",role:"toolbar"}).append(jQuery("<div/>",{class:"container-fluid"}).append(jQuery("<div/>",{class:"dropdown navbar-header navbar-left"}).append(jQuery("<a/>",{href:"#",class:"navbar-brand dropdown-toggle","data-toggle":"dropdown",role:"button","aria-expanded":!1,"aria-haspopup":!0}).append(jQuery("<span/>",{class:"title"})).append(jQuery("<span/>",{class:"caret"}))).append(jQuery("<ul/>",{class:"dropdown-menu",role:"menu"})).append(jQuery("<button/>",{type:"button",class:"close visible-xs visible-sm","aria-label":Sao.i18n.gettext("Close")}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).click(function(){this.close()}.bind(this)))).append(jQuery("<div/>",{class:"btn-toolbar navbar-right",role:"toolbar"}))),b=jQuery("<div/>",{class:"toolbar-wrapper"}).append(a);this.set_menu(a.find('ul[role*="menu"]'));var c,d=function(b){if(!b)return void(c=null);c||(c=jQuery("<div/>",{class:"btn-group",role:"group"}).appendTo(a.find(".btn-toolbar"))),this.buttons[b[0]]=jQuery("<button/>",{type:"button",class:"btn btn-default navbar-btn",title:b[2],id:b[0]}).append(jQuery("<span/>",{class:"glyphicon "+b[1],"aria-hidden":"true"})).appendTo(c).data("toggle","tooltip").data("placement","bottom").tooltip(),b[3]?this.buttons[b[0]].click(this[b[3]].bind(this)):item.addClass("disabled")};this.toolbar_def().forEach(d.bind(this)),a.find(".btn-toolbar > .btn-group").last().addClass("hidden-xs");var e=jQuery("#tabs");return a.affix({target:e.parent(),offset:{top:function(){return jQuery("#main_navbar").height()}}}),a.on("affix.bs.affix",function(){b.height(jQuery("#main_navbar").height())}),a.on("affix-top.bs.affix affix-bottom.bs.affix",function(){b.height("")}),a.on("affixed.bs.affix",function(){Sao.Tab.affix_set_with(a)}),a.on("affixed-top.bs.affix affixed-bottom.bs.affix",function(){Sao.Tab.affix_unset_width(a)}),b},close:function(){var a=jQuery("#tabs"),b=jQuery("#tablist"),c=b.find("#nav-"+this.id),d=a.find("#"+this.id);return b.find('a[href="#'+this.id+'"]').tab("show"),this._close_allowed().then(function(){var b=c.nextAll("li").first();b.length||(b=c.prevAll("li").first()),c.tooltip("destroy").remove(),d.remove(),Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(this),1),b&&b.find("a").tab("show"),a.trigger("ready")}.bind(this))},_close_allowed:function(){return jQuery.when()},set_name:function(a){this.name=a,this.name_el.text(Sao.common.ellipsize(a,20)),this.name_el.parents("li").first().attr("title",a).tooltip()}}),Sao.Tab.affix_set_with=function(a){var b=jQuery(a.parent()).width();a.css("width",b)},Sao.Tab.affix_unset_width=function(a){a.css("width","")},jQuery(window).resize(function(){jQuery(".toolbar").each(function(a,b){b=jQuery(b),b.affix("checkPosition"),b.hasClass("affix")?Sao.Tab.affix_set_with(b):Sao.Tab.affix_unset_width(b)})}),Sao.Tab.counter=0,Sao.Tab.tabs=[],Sao.Tab.tabs.close=function(a){if(a&&Sao.Tab.tabs.length)return Sao.common.sur.run(Sao.i18n.gettext("The following action requires to close all tabs.\nDo you want to continue?")).then(function(){return Sao.Tab.tabs.close(!1)});if(Sao.Tab.tabs.length){var b=Sao.Tab.tabs[0];return b.close().then(function(){return~Sao.Tab.tabs.indexOf(b)?jQuery.Deferred().reject():Sao.Tab.tabs.close()})}return Sao.main_menu_screen?Sao.main_menu_screen.save_tree_state().then(function(){Sao.main_menu_screen=null}):jQuery.when()},Sao.Tab.tabs.get_current=function(){var a=jQuery("#tablist"),b=a.find("li").index(a.find("li.active"));return Sao.Tab.tabs[b]},Sao.Tab.tabs.close_current=function(){this.get_current().close()},Sao.Tab.create=function(a){void 0===a.context&&(a.context={});var b;b=a.model?new Sao.Tab.Form(a.model,a):new Sao.Tab.Board(a),Sao.Tab.add(b)},Sao.Tab.add=function(a){var b=jQuery("#tabs"),c=jQuery("#tablist"),d=jQuery("#tabcontent"),e=jQuery("<a/>",{"aria-controls":a.id,role:"tab","data-toggle":"tab",href:"#"+a.id}).append(jQuery("<button/>",{class:"close"}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Close"))).click(function(){a.close()})).append(a.name_el);jQuery("<li/>",{role:"presentation","data-toggle":"tooltip","data-placement":"bottom",id:"nav-"+a.id}).append(e).appendTo(c),jQuery("<div/>",{role:"tabpanel",class:"tab-pane",id:a.id}).html(a.el).appendTo(d),e.on("shown.bs.tab",function(){Sao.View.resize(a.el)}),e.tab("show"),b.trigger("ready")},Sao.Tab.Form=Sao.class_(Sao.Tab,{class_:"tab-form",init:function(a,b){Sao.Tab.Form._super.init.call(this);var c=new Sao.Screen(a,b);c.tab=this,this.screen=c,this.attributes=jQuery.extend({},b),this.info_bar=new Sao.Window.InfoBar,this.create_tabcontent(),this.set_buttons_sensitive(),this.view_prm=this.screen.switch_view().done(function(){this.set_name(b.name||""),this.content.append(c.screen_container.el),b.res_id?(jQuery.isArray(b.res_id)||(b.res_id=[b.res_id]),c.group.load(b.res_id),c.set_current_record(c.group.get(b.res_id)),c.display()):("form"==c.current_view.view_type&&c.new_(),~["tree","graph","calendar"].indexOf(c.current_view.view_type)&&c.search_filter()),this.update_revision()}.bind(this))},toolbar_def:function(){return[["new","glyphicon-edit",Sao.i18n.gettext("Create a new record"),"new_"],["save","glyphicon-save",Sao.i18n.gettext("Save this record"),"save"],["switch","glyphicon-list-alt",Sao.i18n.gettext("Switch view"),"switch_"],["reload","glyphicon-refresh",Sao.i18n.gettext("Reload"),"reload"],null,["previous","glyphicon-chevron-left",Sao.i18n.gettext("Previous Record"),"previous"],["next","glyphicon-chevron-right",Sao.i18n.gettext("Next Record"),"next"],null,["attach","glyphicon-paperclip",Sao.i18n.gettext("Add an attachment to the record"),"attach"],["note","glyphicon-comment",Sao.i18n.gettext("Add a note to the record"),"note"]]},menu_def:function(){return[["glyphicon-edit",Sao.i18n.gettext("New"),"new_"],["glyphicon-save",Sao.i18n.gettext("Save"),"save"],["glyphicon-list-alt",Sao.i18n.gettext("Switch"),"switch_"],["glyphicon-refresh",Sao.i18n.gettext("Reload/Undo"),"reload"],["glyphicon-duplicate",Sao.i18n.gettext("Duplicate"),"copy"],["glyphicon-trash",Sao.i18n.gettext("Delete"),"delete_"],["glyphicon-chevron-left",Sao.i18n.gettext("Previous"),"previous"],["glyphicon-chevron-right",Sao.i18n.gettext("Next"),"next"],["glyphicon-search",Sao.i18n.gettext("Search"),"search"],["glyphicon-time",Sao.i18n.gettext("View Logs..."),"logs"],["glyphicon-time",Sao.i18n.gettext("Show revisions..."),Sao.common.MODELHISTORY.contains(this.screen.model_name)?"revision":null],["glyphicon-remove",Sao.i18n.gettext("Close Tab"),"close"],["glyphicon-paperclip",Sao.i18n.gettext("Attachment"),"attach"],["glyphicon-comment",Sao.i18n.gettext("Note"),"note"],["glyphicon-cog",Sao.i18n.gettext("Action"),"action"],["glyphicon-share-alt",Sao.i18n.gettext("Relate"),"relate"],["glyphicon-print",Sao.i18n.gettext("Print"),"print"],["glyphicon-export",Sao.i18n.gettext("Export"),"export"],["glyphicon-import",Sao.i18n.gettext("Import"),"import"]]},create_toolbar:function(){var a=Sao.Tab.Form._super.create_toolbar.call(this),b=this.screen,c=this.buttons;return b.model.execute("view_toolbar_get",[],b.context).done(function(d){[["action","glyphicon-cog",Sao.i18n.gettext("Launch action")],["relate","glyphicon-share-alt",Sao.i18n.gettext("Open related records")],["print","glyphicon-print",Sao.i18n.gettext("Print report")]].forEach(function(e){var f=jQuery("<div/>",{class:"btn-group",role:"group"}).append(jQuery("<button/>",{type:"button",class:"btn btn-default navbar-btn dropdown-toggle","data-toggle":"dropdown","aria-expanded":!1,"aria-haspopup":!0,title:e[2],id:e[0],disabled:!d[e[0]].length}).append(jQuery("<span/>",{class:"glyphicon "+e[1],"aria-hidden":"true"})).append(jQuery("<span/>",{class:"caret"})).data("toggle","tooltip").data("placement","bottom").tooltip()).append(jQuery("<ul/>",{class:"dropdown-menu",role:"menu","aria-labelledby":e[0]})).appendTo(a.find(".btn-toolbar > .btn-group").last());c[e[0]]=f;var g=(f.on("show.bs.dropdown",function(){jQuery(this).parents(".btn-group").removeClass("hidden-xs")}).on("hide.bs.dropdown",function(){jQuery(this).parents(".btn-group").addClass("hidden-xs")}),f.find('ul[role*="menu"]'));"action"==e[0]&&f.click(function(){g.find(".action_button").remove(),b.get_buttons().forEach(function(a){jQuery("<li/>",{role:"presentation",class:"action_button"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(a.attributes.string||"")).click(function(){b.button(a.attributes)}).appendTo(g)})}),d[e[0]].forEach(function(a){jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(a.name)).click(function(){b.save_current().then(function(){var c=jQuery.extend({},a),d=null;b.current_record&&(d=b.current_record.id);var f=b.current_view.selected_records().map(function(a){return a.id});c=Sao.Action.evaluate(c,e[0],b.current_record);var g={model:b.model_name,id:d,ids:f};Sao.Action.exec_action(c,g,b.context)})}).appendTo(g)})})}),a},_close_allowed:function(){return this.modified_save()},modified_save:function(){return this.screen.save_tree_state(),this.screen.current_view.set_value(),this.screen.modified()?Sao.common.sur_3b.run(Sao.i18n.gettext("This record has been modified\ndo you want to save it?")).then(function(a){switch(a){case"ok":return this.save();case"ko":return this.reload(!1);default:return jQuery.Deferred().reject()}}.bind(this)):jQuery.when()},new_:function(){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.modified_save().done(function(){this.screen.new_().then(function(){this.info_bar.message()}.bind(this))}.bind(this))},save:function(){var a=Sao.common.MODELACCESS.get(this.screen.model_name);return a.write||a.create?this.screen.save_current().then(function(){this.info_bar.message(Sao.i18n.gettext("Record saved."),"info"),this.screen.count_tab_domain()}.bind(this),function(){this.info_bar.message(this.screen.invalid_message(),"danger")}.bind(this)):jQuery.when()},switch_:function(){this.modified_save().done(function(){this.screen.switch_view()}.bind(this))},reload:function(a){void 0===a&&(a=!0);var b=function(){return this.screen.cancel_current().then(function(){return this.screen.save_tree_state(!1),"form"!=this.screen.current_view.view_type&&this.screen.search_filter(this.screen.screen_container.search_entry.val()),this.screen.count_tab_domain(),this.screen.display().then(function(){this.info_bar.message()}.bind(this))}.bind(this))}.bind(this);return a?this.modified_save().then(b):b()},copy:function(){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.modified_save().done(function(){this.screen.copy().then(function(){this.info_bar.message(Sao.i18n.gettext("Working now on the duplicated record(s)."),"info"),this.screen.count_tab_domain()}.bind(this))}.bind(this))},delete_:function(){if(Sao.common.MODELACCESS.get(this.screen.model_name).delete){var a;a="form"==this.screen.current_view.view_type?Sao.i18n.gettext("Are you sure to remove this record?"):Sao.i18n.gettext("Are you sure to remove those records?"),Sao.common.sur.run(a).done(function(){this.screen.remove(!0,!1,!0).then(function(){this.info_bar.message(Sao.i18n.gettext("Records removed."),"info"),this.screen.count_tab_domain()}.bind(this),function(){this.info_bar.message(Sao.i18n.gettext("Records not removed."),"danger")}.bind(this))}.bind(this))}},previous:function(){this.modified_save().done(function(){this.screen.display_previous(),this.info_bar.message()}.bind(this))},next:function(){this.modified_save().done(function(){this.screen.display_next(),this.info_bar.message()}.bind(this))},search:function(){var a=this.screen.screen_container.search_entry;a.is(":visible")&&window.setTimeout(function(){a.focus()},0)},logs:function(){var a=this.screen.current_record;if(!a||a.id<0)return void this.info_bar.message(Sao.i18n.gettext("You have to select one record."),"info");var b=[["id",Sao.i18n.gettext("ID:")],["create_uid.rec_name",Sao.i18n.gettext("Creation User:")],["create_date",Sao.i18n.gettext("Creation Date:")],["write_uid.rec_name",Sao.i18n.gettext("Latest Modification by:")],["write_date",Sao.i18n.gettext("Latest Modification Date:")]];this.screen.model.execute("read",[[a.id],b.map(function(a){return a[0]})],this.screen.context).then(function(a){a=a[0];var c="";b.forEach(function(b){var d=b[0],e=b[1],f=a[d]||"/";a[d]&&~["create_date","write_date"].indexOf(d)&&(f=Sao.common.format_datetime(Sao.common.date_format(),"%H:%M:%S",f)),c+=e+" "+f+"\n"}),c+=Sao.i18n.gettext("Model: ")+this.screen.model.name,Sao.common.message.run(c)}.bind(this))},revision:function(){var a=null;this.screen.current_record&&(a=this.screen.current_record.id);var b=function(b){return function(c){c&&c.add(1,"milliseconds"),"form"==this.screen.current_view.view_type&&c<b[b.length-1][0]&&(c=b[b.length-1][0]),c!=this.screen.context._datetime&&(this.screen.context._datetime=c,"form"!=this.screen.current_view.view_type?this.screen.search_filter(this.screen.screen_container.search_entry.val()):this.screen.new_group([a]),this.screen.display(!0),this.update_revision())}.bind(this)}.bind(this);this.modified_save().done(function(){var a=this.screen.current_view.selected_records().map(function(a){return a.id});this.screen.model.execute("history_revisions",[a],this.screen.context).then(function(a){new Sao.Window.Revision(a,b(a))})}.bind(this))},update_revision:function(){var a,b=this.screen.context._datetime;if(b){var c=Sao.common.date_format();b=Sao.common.format_datetime(c,"%H:%M:%S.%f",b),a=this.name+" @ "+b}else a=this.name;this.title.html(a),this.set_buttons_sensitive(b)},set_buttons_sensitive:function(a){if(a)["new","save"].forEach(function(a){this.buttons[a].parent().addClass("disabled")}.bind(this));else{var b=Sao.common.MODELACCESS.get(this.screen.model_name);[["new",b.create],["save",b.create||b.write]].forEach(function(a){var b=a[0];a[1]?this.buttons[b].parent().removeClass("disabled"):this.buttons[b].parent().addClass("disabled")}.bind(this))}},attach:function(){var a=this.screen.current_record;!a||a.id<0||new Sao.Window.Attachment(a,function(){this.update_attachment_count(!0)}.bind(this))},update_attachment_count:function(a){var b=this.screen.current_record;b?b.get_attachment_count(a).always(this.attachment_count.bind(this)):this.attachment_count(0)},attachment_count:function(a){var b=this.buttons.attach.find(".badge");b.length||(b=jQuery("<span/>",{class:"badge"}).appendTo(this.buttons.attach)),b.text(a);var c=this.screen.get_id();this.buttons.attach.prop("disabled",c<0||null===c)},note:function(){var a=this.screen.current_record;!a||a.id<0||new Sao.Window.Note(a,function(){this.update_unread_note(!0)}.bind(this))},update_unread_note:function(a){var b=this.screen.current_record;b?b.get_unread_note(a).always(this._unread_note.bind(this)):this._unread_note(0)},_unread_note:function(a){var b=this.buttons.note.find(".badge");b.length||(b=jQuery("<span/>",{class:"badge"}).appendTo(this.buttons.note)),b.text(a);var c=this.screen.get_id();this.buttons.note.prop("disabled",c<0||null===c)},record_message:function(){this.info_bar.message()},action:function(){window.setTimeout(function(){this.buttons.action.find("button").click()}.bind(this))},relate:function(){window.setTimeout(function(){this.buttons.relate.find("button").click()}.bind(this))},print:function(){window.setTimeout(function(){this.buttons.print.find("button").click()}.bind(this))},export:function(){new Sao.Window.Export(this.screen,this.screen.current_view.selected_records().map(function(a){return a.id}),this.screen.current_view.get_fields(),this.screen.context)},import:function(){new Sao.Window.Import(this.screen)}}),Sao.Tab.Board=Sao.class_(Sao.Tab,{class_:"tab-board",init:function(a){var b,c;Sao.Tab.Board._super.init.call(this),this.model=a.model,this.view_id=a.view_ids.length>0?a.view_ids[0]:null,this.context=a.context,this.name=a.name||"",this.dialogs=[],this.board=null,b=new Sao.Model("ir.ui.view"),c=b.execute("read",[[this.view_id],["arch"]],this.context),c.done(function(a){var b;b=jQuery(jQuery.parseXML(a[0].arch)),this.board=new Sao.View.Board(b,this.context),this.board.actions_prms.done(function(){var a,b,c;for(a=0,b=this.board.actions.length;a<b;a++)c=this.board.actions[a],c.screen.tab=this}.bind(this)),this.el.append(this.board.el)}.bind(this)),this.create_tabcontent(),this.set_name(this.name),this.title.html(this.name_el.text())},toolbar_def:function(){return[["reload","glyphicon-refresh",Sao.i18n.gettext("Reload"),"reload"]]},menu_def:function(){return[["glyphicon-refresh",Sao.i18n.gettext("Reload/Undo"),"reload"]]},reload:function(){this.board.reload()},record_message:function(){var a,b,c;for(b=this.board.actions.length,a=0,b=b;a<b;a++)c=this.board.actions[a],c.update_domain(this.board.actions)},attachment_count:function(){},note:function(){},update_unread_note:function(){}}),Sao.Tab.Wizard=Sao.class_(Sao.Tab,{class_:"tab-wizard",init:function(a){Sao.Tab.Wizard._super.init.call(this),this.wizard=a,this.set_name(a.name),a.tab=this,this.create_tabcontent(),this.title.html(this.name_el.text()),this.el.append(a.form)},create_toolbar:function(){return jQuery("<span/>")},_close_allowed:function(){var a=this.wizard,b=jQuery.when();a.state!==a.end_state&&a.end_state in a.states&&(b=a.response(a.end_state));var c=jQuery.Deferred();return b.always(function(){a.state===a.end_state?c.resolve():c.reject()}),c.promise()}})}(),function(){"use strict";Sao.ScreenContainer=Sao.class_(Object,{init:function(a){this.alternate_viewport=jQuery("<div/>",{class:"screen-container"}),this.alternate_view=!1,this.search_modal=null,this.search_form=null,this.last_search_text="",this.tab_domain=a||[],this.tab_counter=[],this.el=jQuery("<div/>",{class:"screen-container"}),this.filter_box=jQuery("<form/>",{class:"filter-box"}).submit(function(a){this.do_search(),a.preventDefault()}.bind(this));var b=jQuery("<div/>",{class:"row"}).appendTo(this.filter_box);this.el.append(this.filter_box),this.filter_button=jQuery("<button/>",{type:"button",class:"btn btn-default"}).append(Sao.i18n.gettext("Filters")),this.filter_button.click(this.search_box.bind(this)),this.search_entry=jQuery("<input/>",{class:"form-control",placeholder:Sao.i18n.gettext("Search")}),this.search_list=jQuery("<datalist/>"),this.search_list.uniqueId(),this.search_entry.attr("list",this.search_list.attr("id")),this.search_entry.keypress(this.key_press.bind(this)),this.search_entry.on("input",this.update.bind(this));var c=jQuery("<button/>",{type:"submit",class:"btn btn-default","aria-label":Sao.i18n.gettext("Search")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-search"}));this.but_bookmark=jQuery("<button/>",{type:"button",class:"btn btn-default dropdown-toggle","data-toggle":"dropdown","aria-expanded":!1,"aria-label":Sao.i18n.gettext("Bookmarks"),id:"bookmarks"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-bookmark","aria-hidden":!0}));var d=jQuery("<ul/>",{class:"dropdown-menu",role:"menu","aria-labelledby":"bookmarks"});if(this.but_bookmark.click(function(){d.children().remove();for(var a=this.bookmarks(),b=0;b<a.length;b++){var c=a[b][1],e=a[b][2];jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(c).click(e,this.bookmark_activate.bind(this))).appendTo(d)}}.bind(this)),this.but_star=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon","aria-hidden":!0})).click(this.star_click.bind(this)),this.set_star(),jQuery("<div/>",{class:"input-group"}).append(jQuery("<span/>",{class:"input-group-btn"}).append(this.filter_button)).append(this.search_entry).append(this.search_list).append(jQuery("<span/>",{class:"input-group-btn"}).append(c).append(this.but_star).append(this.but_bookmark).append(d)).appendTo(jQuery("<div/>",{class:"col-sm-10 col-xs-12"}).appendTo(b)),this.but_prev=jQuery("<button/>",{type:"button",class:"btn btn-default","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-menu-left","aria-hidden":!0})),this.but_prev.click(this.search_prev.bind(this)),this.but_next=jQuery("<button/>",{type:"button",class:"btn btn-default","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-menu-right","aria-hidden":!0})),this.but_next.click(this.search_next.bind(this)),jQuery("<div/>",{class:"btn-group",role:"group"}).append(this.but_prev).append(this.but_next).appendTo(jQuery("<div/>",{class:"col-sm-2 pull-right"}).appendTo(b)),this.content_box=jQuery("<div/>",{class:"content-box"}),jQuery.isEmptyObject(this.tab_domain))this.tab=null;else{this.tab=jQuery("<div/>",{class:"tab-domain"}).appendTo(this.el);var e=jQuery("<ul/>",{class:"nav nav-tabs",role:"tablist"}).appendTo(this.tab);jQuery("<div/>",{class:"tab-content"}).appendTo(this.tab);this.tab_domain.forEach(function(a,b){var c=a[0],d=jQuery("<span/>",{class:"badge"});jQuery("<li/>",{role:"presentation",id:"nav-"+b}).append(jQuery("<a/>",{"aria-controls":b,role:"tab","data-toggle":"tab",href:"#"+b}).append(c+" ").append(d)).appendTo(e);this.tab_counter.push(d)}.bind(this)),e.find("a:first").tab("show");var f=this;e.find("a").click(function(a){a.preventDefault(),jQuery(this).tab("show"),f.do_search(),f.screen.count_tab_domain()})}this.el.append(this.content_box)},set_text:function(a){this.search_entry.val(a),this.bookmark_match()},update:function(){var a=this.screen.domain_parser().completion(this.get_text());this.search_list.children().remove(),a.forEach(function(a){jQuery("<option/>",{value:a.trim()}).appendTo(this.search_list)},this)},set_star:function(a){var b=this.but_star.children("span.glyphicon");a?(b.removeClass("glyphicon-star-empty"),b.addClass("glyphicon-star"),this.but_star.attr("aria-label",Sao.i18n.gettext("Remove this bookmark"))):(b.removeClass("glyphicon-star"),b.addClass("glyphicon-star-empty"),this.but_star.attr("aria-label",Sao.i18n.gettext("Bookmark this filter")))},get_star:function(){return this.but_star.children("span.glyphicon").hasClass("glyphicon-star")},star_click:function(){var a=this.get_star(),b=this.screen.model_name,c=function(){this.bookmark_match(),this.but_bookmark.prop("disabled",jQuery.isEmptyObject(this.bookmarks()))}.bind(this);if(a){var d=this.bookmark_match();Sao.common.VIEW_SEARCH.remove(b,d).then(function(){c()})}else{var e=this.get_text();if(!e)return;Sao.common.ask.run(Sao.i18n.gettext("Bookmark Name:")).then(function(a){if(a){var d=this.screen.domain_parser().parse(e);Sao.common.VIEW_SEARCH.add(b,a,d).then(function(){c()}),this.set_text(this.screen.domain_parser().string(d))}}.bind(this))}},bookmarks:function(){return Sao.common.VIEW_SEARCH.get(this.screen.model_name).filter(function(a){return this.screen.domain_parser().stringable(a[2])}.bind(this))},bookmark_activate:function(a){var b=a.data
+;this.set_text(this.screen.domain_parser().string(b)),this.do_search()},bookmark_match:function(){var a=this.get_text();if(a){var b=this.screen.domain_parser().parse(a);this.but_star.prop("disabled",!a);for(var c=(this.get_star(),this.bookmarks()),d=0;d<c.length;d++){var e=c[d][0],f=(c[d][1],c[d][2]);if(this.screen.domain_parser().string(f)===a||Sao.common.compare(f,b))return this.set_star(!0),e}}this.set_star(!1)},search_prev:function(){this.screen.search_prev(this.get_text())},search_next:function(){this.screen.search_next(this.get_text())},get_tab_domain:function(){if(!this.tab)return[];var a=this.tab.find("li").index(this.tab.find("li.active"));return this.tab_domain[a][1]},set_tab_counter:function(a,b){if(!jQuery.isEmptyObject(this.tab_counter)&&this.tab&&(void 0!==b&&null!==b||(b=this.tab.find("li").index(this.tab.find("li.active"))),!(b<0))){var c=this.tab_counter[b];if(c.data("toggle","tooltip"),null===a)c.attr("title",""),c.text("");else{c.attr("title",a);var d=a;a>99&&(d="99+"),c.text(d)}c.tooltip()}},do_search:function(){return this.screen.search_filter(this.get_text())},key_press:function(a){window.setTimeout(function(){this.bookmark_match()}.bind(this))},set_screen:function(a){this.screen=a,this.but_bookmark.prop("disabled",jQuery.isEmptyObject(this.bookmarks())),this.bookmark_match()},show_filter:function(){this.filter_box.show(),this.tab&&this.tab.show()},hide_filter:function(){this.filter_box.hide(),this.tab&&this.tab.hide()},set:function(a){this.alternate_view?(this.alternate_viewport.children().detach(),this.alternate_viewport.append(a)):(this.content_box.children().detach(),this.content_box.append(a))},get_text:function(){return this.search_entry.val()},search_box:function(){var a=this.screen.domain_parser(),b=function(){this.search_modal.modal("hide");for(var b="",c=a.quote.bind(a),d=0;d<this.search_form.fields.length;d++){var e,f=this.search_form.fields[d][0],g=this.search_form.fields[d][1];switch(g.type){case"selection":case"date":case"datetime":case"time":e=g.get_value(c);break;default:e=c(g.val())}e&&(b+=c(f)+": "+e+" ")}this.set_text(b),this.do_search().then(function(){this.last_search_text=this.get_text()}.bind(this))}.bind(this);if(!this.search_modal){var c=new Sao.Dialog(Sao.i18n.gettext("Filters"),"","lg");this.search_modal=c.modal,this.search_form=c.content,this.search_form.addClass("form-horizontal"),this.search_form.submit(function(a){b(),a.preventDefault()});var d,e=[];for(var f in a.fields)d=a.fields[f],(d.searchable||void 0===d.searchable)&&e.push(d);var g=function(a){return function(b){jQuery("<option/>",{value:b,text:b}).appendTo(a)}},h="filter-"+this.screen.model_name+"-";this.search_form.fields=[];for(var i=0;i<e.length;i++){d=e[i];var j,k,l=jQuery("<div/>",{class:"form-group form-group-sm"}).append(jQuery("<label/>",{class:"col-sm-4 control-label",for:h+d.name,text:d.string})).appendTo(c.body);switch(d.type){case"boolean":k=j=jQuery("<select/>",{class:"form-control input-sm",id:h+d.name}),["",Sao.i18n.gettext("True"),Sao.i18n.gettext("False")].forEach(g(j));break;case"selection":k=new Sao.ScreenContainer.Selection(d.selection,h+d.name),j=k.el;break;case"date":case"datetime":case"time":var m,n=Sao.common.date_format();if("date"==d.type)m=n;else{var o=new Sao.PYSON.Decoder({}).decode(d.format);o=Sao.common.moment_format(o),"time"==d.type?m=o:"datetime"==d.type&&(m=n+" "+o)}k=new Sao.ScreenContainer.DateTimes(m,h+d.name),j=k.el;break;default:k=j=jQuery("<input/>",{class:"form-control input-sm",type:"text",placeholder:d.string,id:h+d.name})}jQuery("<div/>",{class:"col-sm-8"}).append(j).appendTo(l),this.search_form.fields.push([d.string,k,j])}jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Find")).click(b).appendTo(c.footer)}if(this.search_modal.modal("show"),this.last_search_text.trim()!==this.get_text().trim()){for(var p=0;p<this.search_form.fields.length;p++){var q=this.search_form.fields[p][1];switch(q.type){case"selection":q.set_value([]);break;case"date":case"datetime":case"time":q.set_value(null,null);break;default:q.val("")}}this.search_form.fields[0][2].focus()}}}),Sao.ScreenContainer.DateTimes=Sao.class_(Object,{type:"date",init:function(a,b){this.el=jQuery("<div/>",{class:"row",id:b});var c=function(c){var d=jQuery("<div/>",{class:"input-group input-group-sm"});return jQuery("<input/>",{class:"form-control input-sm",type:"text",placeholder:c,id:b+"-from"}).appendTo(d),jQuery("<span/>",{class:"input-group-btn"}).append(jQuery("<button/>",{class:"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-calendar"}))).appendTo(d),d.datetimepicker({locale:moment.locale()}),d.data("DateTimePicker").format(a),d};this.from=c("From").appendTo(jQuery("<div/>",{class:"col-md-5"}).appendTo(this.el)),jQuery("<p/>",{class:"text-center"}).append("..").appendTo(jQuery("<div/>",{class:"col-md-1"}).appendTo(this.el)),this.to=c("To").appendTo(jQuery("<div/>",{class:"col-md-5"}).appendTo(this.el))},_get_value:function(a){return a.find("input").val()},get_value:function(a){var b=this._get_value(this.from),c=this._get_value(this.to);return b&&c?b!==c?a(b)+".."+a(c):a(b):b?">="+a(b):c?"<="+a(c):void 0},set_value:function(a,b){this.from.data("DateTimePicker").date(a),this.to.data("DateTimePicker").date(b)}}),Sao.ScreenContainer.Selection=Sao.class_(Object,{type:"selection",init:function(a,b){this.el=jQuery("<select/>",{class:"form-control input-sm",multiple:!0,id:b}),a.forEach(function(a){jQuery("<option/>",{value:a[1],text:a[1]}).appendTo(this.el)}.bind(this))},get_value:function(a){var b=this.el.val();return b&&(b=jQuery.map(b,a).reduce(function(a,b){return a&&(a+=";"),a+b})),b},set_value:function(a){this.el.val(a)}}),Sao.Screen=Sao.class_(Object,{init:function(a,b){this.model_name=a,this.model=new Sao.Model(a,b),this.attributes=jQuery.extend({},b),this.view_ids=jQuery.extend([],b.view_ids),this.view_to_load=jQuery.extend([],b.mode||["tree","form"]),this.views=[],this.views_preload=b.views_preload||{},this.exclude_field=b.exclude_field,this.context=b.context||{},this.new_group(),this.current_view=null,this.current_record=null,this.domain=b.domain||[],this.context_domain=b.context_domain,this.size_limit=null,void 0===this.attributes.limit?this.limit=Sao.config.limit:this.limit=b.limit,this.offset=0,this.order=this.default_order=b.order;var c=Sao.common.MODELACCESS.get(a);c.write||c.create||(this.attributes.readonly=!0),this.search_count=0,this.screen_container=new Sao.ScreenContainer(b.tab_domain),this.context_screen=null,b.context_model&&(this.context_screen=new Sao.Screen(b.context_model,{mode:["form"],context:b.context}),this.context_screen_prm=this.context_screen.switch_view().then(function(){return jQuery("<div/>",{class:"row"}).append(jQuery("<div/>",{class:"col-md-12"}).append(this.context_screen.screen_container.el)).prependTo(this.screen_container.filter_box),this.context_screen.new_(!1).then(function(a){return a.default_get()})}.bind(this))),b.row_activate?this.row_activate=b.row_activate:this.row_activate=this.default_row_activate,this.tree_states={},this.tree_states_done=[],this.fields_view_tree={},this._domain_parser={},this.pre_validate=!1,this.tab=null,this.count_tab_domain()},load_next_view:function(){if(!jQuery.isEmptyObject(this.view_to_load)){var a;jQuery.isEmptyObject(this.view_ids)||(a=this.view_ids.shift());var b=this.view_to_load.shift();return this.add_view_id(a,b)}return jQuery.when()},add_view_id:function(a,b){var c;if(a&&this.views_preload[String(a)])c=this.views_preload[String(a)];else{if(a||!this.views_preload[b]){return this.model.execute("fields_view_get",[a,b],this.context).pipe(this.add_view.bind(this))}c=this.views_preload[b]}return this.add_view(c),jQuery.when()},add_view:function(a){var b=a.arch,c=a.fields,d=a.view_id,e=jQuery(jQuery.parseXML(b));"tree"==e.children().prop("tagName")&&(this.fields_view_tree[d]=a);var f="eager";"form"==e.children().prop("tagName")&&(f="lazy");for(var g in c)g in this.model.fields&&"eager"!=f?c[g].loading=this.model.fields[g].description.loading:c[g].loading=f;this.group.add_fields(c);var h=Sao.View.parse(this,e,a.field_childs);return h.view_id=d,this.views.push(h),h},number_of_views:function(){return this.views.length+this.view_to_load.length},switch_view:function(a){if(this.current_view){this.current_view.set_value(),this.current_record&&!~this.current_record.group.indexOf(this.current_record)&&(this.current_record=null);var b=this.current_view.get_fields();if(this.current_record&&this.current_view.editable&&!this.current_record.validate(b,!1,!1,!0))return this.screen_container.set(this.current_view.el),this.current_view.display().done(function(){this.set_cursor()}.bind(this))}var c=function(){if(!a||!this.current_view||this.current_view.view_type!=a)for(var b=function(){return this.current_view=this.views[this.views.length-1],c()}.bind(this),d=0;d<this.number_of_views();d++){if(this.view_to_load.length)return a||(a=this.view_to_load[0]),this.load_next_view().then(b);if(this.current_view=this.views[(this.views.indexOf(this.current_view)+1)%this.views.length],!a)break;if(this.current_view.view_type==a)break}return this.screen_container.set(this.current_view.el),this.display().done(function(){this.set_cursor()}.bind(this))}.bind(this);return c()},search_filter:function(a,b){if(b=b||!1,this.context_screen){if("pending"==this.context_screen_prm.state())return this.context_screen_prm.then(function(){return this.search_filter(a)}.bind(this));var c=this.context_screen.current_record;if(c&&!c.validate(null,!1,null,!0))return this.new_group([]),this.context_screen.display(!0),jQuery.when();this.context=jQuery.extend({},this.context,this.context_screen.get_on_change_value())}var d=this.search_domain(a,!0);if(this.context_domain){d=["AND",d,new Sao.PYSON.Decoder(this.context).decode(this.context_domain)]}var e=this.screen_container.get_tab_domain();jQuery.isEmptyObject(e)||(d=["AND",d,e]);var f=this.model.find(d,this.offset,this.limit,this.order,this.context),g=jQuery.when(this.search_count);return b||(g=this.model.execute("search_count",[d],this.context)),g.done(function(a){this.search_count=a}.bind(this)),f.done(this.set_group.bind(this)),f.done(this.display.bind(this)),jQuery.when(f,g).done(function(a,b){this.screen_container.but_next.prop("disabled",!(void 0!==this.limit&&a.length==this.limit&&b>this.limit+this.offset))}.bind(this)),this.screen_container.but_prev.prop("disabled",this.offset<=0),this.count_tab_domain(),f},search_domain:function(a,b){b=b||!1;var c=[];if(!this.group.parent&&this.domain_parser()){var d=this.domain_parser();c=a||""===a?d.parse(a):this.attributes.search_value,b&&this.screen_container.set_text(d.string(c))}else c=[["id","in",this.group.map(function(a){return a.id})]];return jQuery.isEmptyObject(c)?c=this.attributes.domain||[]:jQuery.isEmptyObject(this.attributes.domain)||(c=["AND",c,this.attributes.domain]),this.current_view&&"calendar"==this.current_view.view_type&&(c=jQuery.isEmptyObject(c)?this.current_view.current_domain():["AND",c,this.current_view.current_domain()]),c},count_tab_domain:function(){var a=this.search_domain(this.screen_container.get_text());this.screen_container.tab_domain.forEach(function(b,c){if(b[2]){var d=["AND",b[1],a];this.screen_container.set_tab_counter(null,c),this.group.model.execute("search_count",[d],this.context).then(function(a){this.screen_container.set_tab_counter(a,c)}.bind(this))}}.bind(this))},set_group:function(a){var b={};if(this.group){for(var c in this.group.model.fields)this.group.model.fields.hasOwnProperty(c)&&(b[c]=this.group.model.fields[c].description);this.group.screens.splice(this.group.screens.indexOf(this),1),jQuery.extend(a.on_write,this.group.on_write),a.on_write=a.on_write.filter(function(a,b,c){return b==c.indexOf(a)}),this.group.parent&&!a.parent&&(a.parent=this.group.parent)}a.screens.push(this),this.tree_states_done=[],this.group=a,this.model=a.model,a&&a.length?this.set_current_record(a[0]):this.set_current_record(null),this.group.add_fields(b)},new_group:function(a){var b=new Sao.Group(this.model,this.context,[]);b.set_readonly(this.attributes.readonly||!1),a&&b.load(a),this.set_group(b)},set_current_record:function(a){this.current_record=a,this.tab&&(a?(a.get_attachment_count().always(this.tab.attachment_count.bind(this.tab)),a.get_unread_note().always(this.tab.update_unread_note.bind(this.tab))):(this.tab.attachment_count(0),this.tab.update_unread_note(0)),this.tab.record_message())},display:function(a){var b=[];if(this.current_record&&~this.current_record.group.indexOf(this.current_record)||(this.group&&this.group.length&&"calendar"!=this.current_view.view_type?this.current_record=this.group[0]:this.current_record=null),this.views){var c=this.search_active(~["tree","graph","calendar"].indexOf(this.current_view.view_type));b.push(c);for(var d=0;d<this.views.length;d++)this.views[d]&&b.push(this.views[d].display())}return jQuery.when.apply(jQuery,b).then(function(){this.set_tree_state(),this.set_current_record(this.current_record),a&&this.set_cursor(!1,!1)}.bind(this))},display_next:function(){var a=this.current_view;if(a.set_value(),this.set_cursor(!1,!1),~["tree","form"].indexOf(a.view_type)&&this.current_record&&this.current_record.group){for(var b=this.current_record.group,c=this.current_record;b;){var d=b.indexOf(c);if(d<b.length-1){c=b[d+1];break}if(!b.parent||c.group.model_name!=b.parent.group.model_name)break;c=b.parent,b=b.parent.group}this.set_current_record(c)}else this.set_current_record(this.group[0]);this.set_cursor(!1,!1),a.display()},display_previous:function(){var a=this.current_view;if(a.set_value(),this.set_cursor(!1,!1),~["tree","form"].indexOf(a.view_type)&&this.current_record&&this.current_record.group){for(var b=this.current_record.group,c=this.current_record;b;){var d=b.indexOf(c);if(d>0){c=b[d-1];break}if(!b.parent||c.group.model_name!=b.parent.group.model_name)break;c=b.parent,b=b.parent.group}this.set_current_record(c)}else this.set_current_record(this.group[0]);this.set_cursor(!1,!1),a.display()},default_row_activate:function(){"tree"==this.current_view.view_type&&1==this.current_view.attributes.keyword_open?Sao.Action.exec_keyword("tree_open",{model:this.model_name,id:this.get_id(),ids:[this.get_id()]},jQuery.extend({},this.context),!1):this.modified()||this.switch_view("form")},get_id:function(){if(this.current_record)return this.current_record.id},new_:function(a,b){var c=this.current_view;void 0===a&&(a=!0);var d=jQuery.when();if("calendar"==this.current_view.view_type){var e=this.current_view.get_selected_date();d=this.switch_view("form")}return this.current_view&&("tree"==this.current_view.view_type&&!this.current_view.editable||"graph"==this.current_view.view_type)&&(d=this.switch_view("form")),d.then(function(){var d;d=this.current_record?this.current_record.group:this.group;var f,g=d.new_(!1,void 0,b);return f=a?g.default_get(b):jQuery.when(),f.then(function(){return d.add(g,this.new_model_position()),this.set_current_record(g),"calendar"==c.view_type&&c.set_default_date(g,e),this.display().done(function(){this.set_cursor(!0,!0)}.bind(this)),g}.bind(this))}.bind(this))},new_model_position:function(){var a=-1;return this.current_view&&"tree"==this.current_view.view_type&&"top"==this.current_view.attributes.editable&&(a=0),a},set_on_write:function(a){a&&(~this.group.on_write.indexOf(a)||this.group.on_write.push(a))},cancel_current:function(){var a=[];return this.current_record&&(this.current_record.cancel(),this.current_record.id<0&&a.push(this.remove(!1,!1,!1,[this.current_record]))),jQuery.when.apply(jQuery,a)},save_current:function(){var a=this.current_record;if(!a){if("tree"!=this.current_view.view_type||!this.group||!this.group.length)return jQuery.when();this.set_current_record(this.group[0])}this.current_view.set_value();var b=this.current_view.get_fields(),c=a.get_path(this.group),d=jQuery.Deferred();"tree"==this.current_view.view_type?d=this.group.save().then(function(){return this.current_record}.bind(this)):a.validate(b).then(function(b){b?a.save().then(function(){d.resolve(a)},d.reject):(this.current_view.display().done(this.set_cursor.bind(this)),d.reject())}.bind(this));var e=jQuery.Deferred();return d.then(function(a){return c&&a&&a.id&&c.splice(-1,1,[c[c.length-1][0],a.id]),this.group.get_by_path(c).then(function(a){this.set_current_record(a)}.bind(this))}.bind(this)).then(function(){this.display().always(e.resolve)}.bind(this),function(){this.display().always(e.reject)}.bind(this)),e.promise()},set_cursor:function(a,b){this.current_view&&~["tree","form"].indexOf(this.current_view.view_type)&&this.current_view.set_cursor(a,b)},modified:function(){var a=function(a){return a.has_changed()||a.id<0};if("tree"!=this.current_view.view_type){if(this.current_record&&a(this.current_record))return!0}else if(this.group.some(a))return!0;return!1},unremove:function(){this.current_view.selected_records().forEach(function(a){a.group.unremove(a)})},remove:function(a,b,c,d){var e=jQuery.when();if(d=d||this.current_view.selected_records(),jQuery.isEmptyObject(d))return e;a&&(e=this.model.delete_(d));var f=d[0],g=f.group,h=g.indexOf(f),i=f.get_path(this.group);return e.then(function(){d.forEach(function(a){a.group.remove(a,b,!0,c)});var e=[];if(a&&d.forEach(function(a){a.group.parent&&e.push(a.group.parent.save(!1)),~a.group.record_deleted.indexOf(a)&&a.group.record_deleted.splice(a.group.record_deleted.indexOf(a),1),~a.group.record_removed.indexOf(a)&&a.group.record_removed.splice(a.group.record_removed.indexOf(a),1)}),h>0){var f=g[h-1];i.splice(-1,1,[i[i.length-1][0],f.id])}else i.splice(-1,1);return jQuery.isEmptyObject(i)?this.group.length&&this.set_current_record(this.group[0]):e.push(this.group.get_by_path(i).then(function(a){this.set_current_record(a)}.bind(this))),jQuery.when.apply(jQuery,e).then(function(){this.display().done(function(){this.set_cursor()}.bind(this))}.bind(this))}.bind(this))},copy:function(){var a=jQuery.Deferred(),b=this.current_view.selected_records();return this.model.copy(b,this.context).then(function(b){this.group.load(b),jQuery.isEmptyObject(b)||this.set_current_record(this.group.get(b[0])),this.display().always(a.resolve)}.bind(this),a.reject),a.promise()},search_active:function(a){return a&&!this.group.parent?(this.screen_container.set_screen(this),this.screen_container.show_filter()):this.screen_container.hide_filter(),jQuery.when()},domain_parser:function(){var a,b,c;if((a=this.current_view?this.current_view.view_id:null)in this._domain_parser)return this._domain_parser[a];a in this.fields_view_tree?b=this.fields_view_tree[a]:(this.model.execute("fields_view_get",[!1,"tree"],this.context).then(function(b){this.fields_view_tree[a]=b,c.update_fields(b.fields)}.bind(this)),b={},b.fields={});var d=jQuery.extend({},b.fields),e=function(a){return function(b){a.selection=b}};for(var f in d){var g=d[f];"selection"!=g.type&&"reference"!=g.type||(g.selection instanceof Array||this.get_selection(g).then(e(g)))}if("arch"in b){var h=jQuery(jQuery.parseXML(b.arch)),i=h.find("tree").children().filter(function(a,b){return"field"==b.tagName}).map(function(a,b){return b.getAttribute("name")}),j={};i.each(function(a,b){j[b]=d[b]}),d=j}[["id",Sao.i18n.gettext("ID"),"integer"],["create_uid",Sao.i18n.gettext("Creation User"),"many2one"],["create_date",Sao.i18n.gettext("Creation Date"),"datetime"],["write_uid",Sao.i18n.gettext("Modification User"),"many2one"],["write_date",Sao.i18n.gettext("Modification Date"),"datetime"]].forEach(function(a){var b=a[0],c=a[1],e=a[2];b in d||(d[b]={string:c,name:b,type:e},"datetime"==e&&(d[b].format='"%H:%M:%S"'))});var k=jQuery.extend({},this.model.session.context,this.context);return c=new Sao.common.DomainParser(d,k),this._domain_parser[a]=c,c},get_selection:function(a){var b,c=a.selection_change_with;if(jQuery.isEmptyObject(c))b=this.model.execute(a.selection,[]);else{var d={};c.forEach(function(a){d[a]=null}),b=this.model.execute(a.selection,[d])}return b.then(function(a){return a.sort(function(a,b){return a[1].localeCompare(b[1])})})},search_prev:function(a){this.limit&&(this.offset-=this.limit),this.search_filter(a)},search_next:function(a){this.limit&&(this.offset+=this.limit),this.search_filter(a)},invalid_message:function(a){a||(a=this.current_record);var b={};for(var c in a.model.fields){var d=a.model.fields[c];b[c]=d.description}var e=new Sao.common.DomainParser(b),f=[],g=a.invalid_fields();return Object.keys(g).sort().forEach(function(b){var c=g[b],d=a.model.fields[b].description.string;"required"==c||Sao.common.compare(c,[[b,"!=",null]])?f.push(Sao.i18n.gettext('"%1" is required',d)):"domain"==c?f.push(Sao.i18n.gettext('"%1" is not valid according to its domain',d)):"children"==c?f.push(Sao.i18n.gettext('The values of "%1" are not valid',d)):e.stringable(c)?f.push(e.string(c)):f.push(Sao.i18n.gettext('"%1" is not valid according to its domain'),d)}),f.length>5&&(f.splice(5,f.length),f.push("...")),f.join("\n")},get:function(){return this.current_record?(this.current_view.set_value(),this.current_record.get()):null},get_on_change_value:function(){return this.current_record?(this.current_view.set_value(),this.current_record.get_on_change_value()):null},reload:function(a,b){this.group.reload(a),b&&this.group.written(a),this.group.parent&&this.group.parent.root_parent().reload(),this.display()},get_buttons:function(){var a=this.current_view.selected_records();if(jQuery.isEmptyObject(a))return[];var b=this.current_view.get_buttons();return a.forEach(function(a){b=b.filter(function(b){if(a.group.get_readonly()||a.readonly())return!1;if("instance"===b.attributes.type)return!1;var c=a.expr_eval(b.attributes.states||{});return!(c.invisible||c.readonly)})}),b},button:function(a){var b,c=function(a){this.reload(b,!0),"string"==typeof a?this.client_action(a):a&&Sao.Action.execute(a,{model:this.model_name,id:this.current_record.id,ids:b},null,this.context,!0)},d=this.current_view.selected_records();this.current_view.set_value();for(var e=this.current_view.get_fields(),f=[],g=function(a){return function(){this.display(!0),a.validate(e)}.bind(this)}.bind(this),h=0;h<d.length;h++){var i=d[h],j=i.expr_eval(a.states||{}).pre_validate||[];f.push(i.validate(e,!1,j))}jQuery.when.apply(jQuery,f).then(function(){for(var e,f=0;f<d.length;f++){e=d[f];if(!arguments[f])return void Sao.common.warning.run(this.invalid_message(e),Sao.i18n.gettext("Pre-validation")).then(g(e))}var h=jQuery.when();void 0!==a.confirm&&(h=Sao.common.sur.run(a.confirm)),h.then(function(){var e=this.current_record;if("instance"===a.type){var g=e.expr_eval(a.change||[]),h=e._get_on_change_args(g);e.model.execute(a.name,[h],this.context).then(function(a){e.set_on_change(a),e.group.root_group().screens.forEach(function(a){a.display()})})}else e.save(!1).done(function(){var g=jQuery.extend({},this.context);for(g._timestamp={},b=[],f=0;f<d.length;f++)e=d[f],jQuery.extend(g._timestamp,e.get_timestamp()),b.push(e.id);e.model.execute(a.name,[b],g).then(c.bind(this))}.bind(this))}.bind(this))}.bind(this))},client_action:function(a){var b=Sao.common.MODELACCESS.get(this.model_name);if("new"==a)b.create&&this.new_();else if("delete"==a)b.delete&&this.remove(!this.group.parent,!1,!this.group.parent);else if("remove"==a)b.write&&b.read&&this.group.parent&&this.remove(!1,!0,!1);else if("copy"==a)b.create&&this.copy();else if("next"==a)this.display_next();else if("previous"==a)this.display_previous();else if("close"==a)Sao.Tab.close_current();else if(a.startsWith("switch")){var c=a.split(" ")[1];this.switch_view(c)}else"reload"==a?~["tree","graph","calendar"].indexOf(this.current_view.view_type)&&!this.group.parent&&this.search_filter():"reload menu"==a?Sao.get_preferences().then(function(a){Sao.menu(a)}):"reload context"==a&&Sao.get_preferences()},save_tree_state:function(a){var b,c=[];a=void 0===a||a;var d,e,f,g,h,i,j=this.group.parent?this.group.parent.id:null,k=this.group.parent?this.group.parent._timestamp:null;for(d=0,e=this.views.length;d<e;d++)if(f=this.views[d],"form"==f.view_type){for(var l in f.widgets)if(f.widgets.hasOwnProperty(l))for(g=f.widgets[l],h=0,i=g.length;h<i;h++)g[h].screen&&(b=g[h].screen.save_tree_state(a),c.push(b));1==this.views.length&&this.current_record&&(j in this.tree_states||(this.tree_states[j]={}),this.tree_states[j][f.children_field||null]=[k,[],[[this.current_record.id]]])}else if("tree"==f.view_type){var m=f.get_expanded_paths(),n=f.get_selected_paths();if(j in this.tree_states||(this.tree_states[j]={}),this.tree_states[j][f.children_field||null]=[k,m,n],a&&f.attributes.tree_state){var o=new Sao.Model("ir.ui.view_tree_state");b=o.execute("set",[this.model_name,this.get_tree_domain(j),f.children_field,JSON.stringify(m),JSON.stringify(n)],{}),c.push(b)}}return jQuery.when.apply(jQuery,c)},get_tree_domain:function(a){var b;return b=a?(this.domain||[]).concat([[this.exclude_field,"=",a]]):this.domain,JSON.stringify(Sao.rpc.prepareObject(b))},set_tree_state:function(){var a,b,c,d,e,f=this.current_view;~["tree","form"].indexOf(f.view_type)&&(~this.tree_states_done.indexOf(f)||("form"!=f.view_type||jQuery.isEmptyObject(this.tree_states_done))&&("tree"!=f.view_type||f.attributes.tree_state)&&((a=this.group.parent?this.group.parent.id:null)<0||(b=parent?parent._timestamp:null,a in this.tree_states||(this.tree_states[a]={}),c=this.tree_states[a][f.children_field||null],c&&b!=c[0]&&(c=void 0),void 0===c?(e=new Sao.Model("ir.ui.view_tree_state"),d=e.execute("get",[this.model_name,this.get_tree_domain(a),f.children_field],{}).then(function(a){return[b,JSON.parse(a[0]),JSON.parse(a[1])]})):d=jQuery.when(c),d.done(function(b){var c,d,e;if(this.tree_states[a][f.children_field||null]=b,c=b[1],d=b[2],"tree"==f.view_type)f.display(d,c);else if(!jQuery.isEmptyObject(d)){for(var g=0;g<d[0].length;g++){var h=this.group.get(d[0][g]);if(!h)break;e=h}e&&e!=this.current_record&&(this.set_current_record(e),f.display())}}.bind(this)),this.tree_states_done.push(f))))}})}(),function(){"use strict";Sao.View=Sao.class_(Object,{init:function(a,b){this.screen=a,this.view_type=null,this.el=null,this.view_id=null,this.fields={};var c=b.children()[0].attributes;this.attributes={};for(var d=0,e=c.length;d<e;d++){var f=c[d];this.attributes[f.name]=f.value}a.set_on_write(this.attributes.on_write)},set_value:function(){},get_fields:function(){return Object.keys(this.fields)},selected_records:function(){return[]},get_buttons:function(){return[]}}),Sao.View.idpath2path=function(a,b){var c,d=[];if(!b)return[];for(var e=0,f=a.rows.length;e<f;e++)if(a.rows[e].record.id==b[0]){d.push(e),c=Sao.View.idpath2path(a.rows[e],b.slice(1,b.length)),d=d.concat(c);break}return d},Sao.View.parse=function(a,b,c){switch(b.children().prop("tagName")){case"tree":return new Sao.View.Tree(a,b,c);case"form":return new Sao.View.Form(a,b);case"graph":return new Sao.View.Graph(a,b);case"calendar":return new Sao.View.Calendar(a,b)}},Sao.View.resize=function(a){a||(a=jQuery(document)),a.find(".treeview").each(function(){var a=jQuery(this);a.css("width","100%"),a.children(".tree").css("table-layout","fixed")}),a.find(".treeview").each(function(){var a=jQuery(this);a.width()&&(a.css("width",a.width()),a.children(".tree").css("table-layout","auto"))})},jQuery(window).resize(function(){Sao.View.resize()})}(),function(){"use strict";Sao.View.Form=Sao.class_(Sao.View,{editable:!0,init:function(a,b){Sao.View.Form._super.init.call(this,a,b),this.view_type="form",this.el=jQuery("<div/>",{class:"form"}),this.widgets={},this.widget_id=0,this.state_widgets=[],this.containers=[],this.notebooks=[];var c=b.children()[0],d=this.parse(a.model,c);this.el.append(d.el)},_parse_node:function(a,b,c,d,e){var f;switch(b.tagName){case"image":this._parse_image(a,b,c,d);break;case"separator":this._parse_separator(a,b,c,d);break;case"label":f=this._parse_label(a,b,c,d),d.name&&f&&(e[d.name]=f);break;case"newline":c.add_row();break;case"button":this._parse_button(b,c,d);break;case"notebook":this._parse_notebook(a,b,c,d);break;case"page":this._parse_page(a,b,c,d);break;case"field":if(f=this._parse_field(a,b,c,d),d.name in e&&f&&f.labelled){var g=e[d.name];g.el.uniqueId(),f.labelled.uniqueId(),f.labelled.attr("aria-labelledby",g.el.attr("id")),g.el.attr("for",f.labelled.attr("id"))}break;case"group":this._parse_group(a,b,c,d);break;case"hpaned":this._parse_paned(a,b,c,d,"horizontal");break;case"vpaned":this._parse_paned(a,b,c,d,"vertical");break;case"child":this._parse_child(a,b,c,d)}},parse:function(a,b,c){void 0===c&&(c=new Sao.View.Form.Container(Number(b.getAttribute("col")||4)),this.containers.push(c));var d={},e=function(b,e){for(var f={},g=0,h=e.attributes.length;g<h;g++){var i=e.attributes[g];f[i.name]=i.value}["readonly","invisible"].forEach(function(a){f[a]&&(f[a]=1==f[a])}),["yexpand","yfill","xexpand","xfill","colspan"].forEach(function(a){f[a]&&(f[a]=Number(f[a]))}),this._parse_node(a,e,c,f,d)};return jQuery(b).children().each(e.bind(this)),c},_parse_image:function(a,b,c,d){var e=new Sao.View.Form.Image_(d);this.state_widgets.push(e),c.add(d,e)},_parse_separator:function(a,b,c,d){var e=d.name,f=d.string;e in a.fields&&(!d.states&&e in a.fields&&(d.states=a.fields[e].description.states),f||(f=a.fields[e].description.string));var g=new Sao.View.Form.Separator(f,d);this.state_widgets.push(g),c.add(d,g)},_parse_label:function(a,b,c,d){var e=d.name,f=d.string;if(void 0===d.xexpand&&(d.xexpand=0),e in a.fields){if(e==this.screen.exclude_field)return void c.add(d);!d.states&&e in a.fields&&(d.states=a.fields[e].description.states),f||(f=a.fields[e].description.string+": "),void 0===d.xalign&&(d.xalign=1)}var g;return f&&(g=new Sao.View.Form.Label(f,d),this.state_widgets.push(g)),c.add(d,g),g},_parse_button:function(a,b,c){var d=new Sao.common.Button(c);this.state_widgets.push(d),b.add(c,d),d.el.click(d,this.button_clicked.bind(this))},_parse_notebook:function(a,b,c,d){void 0===d.colspan&&(d.colspan=4);var e=new Sao.View.Form.Notebook(d);this.notebooks.push(e),this.state_widgets.push(e),c.add(d,e),this.parse(a,b,e)},_parse_page:function(a,b,c,d){d.string;if(d.name in a.fields){var e=a.fields[d.name];if(d.name==this.screen.exclude_field)return;["states","string"].forEach(function(a){void 0===d[a]&&void 0!==e.description[a]&&(d[a]=e.description[a])})}var f=this.parse(a,b);f=new Sao.View.Form.Page(c.add(f.el,d.string),d),this.state_widgets.push(f)},_parse_field:function(a,b,c,d){var e=d.name;if(!(e in a.fields)||e==this.screen.exclude_field)return void c.add(d);d.widget||(d.widget=a.fields[e].description.type);var f=["relation","domain","selection","help","relation_field","string","views","add_remove","sort","context","size","filename","autocomplete","translate","create","delete","selection_change_with","schema_model"];for(var g in f){var h=f[g];h in a.fields[e].description&&null===b.getAttribute(h)&&(d[h]=a.fields[e].description[h])}var i=Sao.View.form_widget_get(d.widget);if(!i)return void c.add(d);var j=new i(e,a,d);return j.position=this.widget_id+=1,j.view=this,c.add(d,j),void 0===this.widgets[e]&&(this.widgets[e]=[]),this.widgets[e].push(j),this.fields[e]=!0,j},_parse_group:function(a,b,c,d){var e=new Sao.View.Form.Group(d);e.add(this.parse(a,b)),this.state_widgets.push(e),c.add(d,e)},_parse_paned:function(a,b,c,d,e){void 0===d.yexpand&&(d.yexpand=!0),void 0===d.yfill&&(d.yfill=!0);var f=new Sao.common.Paned(e);c.add(d,f),this.parse(a,b,f)},_parse_child:function(a,b,c,d){var e,f=this.parse(a,b);e=c.get_child1().children().length?c.get_child2():c.get_child1(),e.append(f.el)},get_buttons:function(){var a=[];for(var b in this.state_widgets){var c=this.state_widgets[b];c instanceof Sao.common.Button&&a.push(c)}return a},display:function(){var a,b,c=this.screen.current_record,d={};if(c){var e=[];for(b in c.model.fields)a=c.model.fields[b],e.push([b,a.description.loading||"eager"]);e.sort(function(a,b){return a[1].localeCompare(b[1])}),e.forEach(function(a){var b=a[0];d[b]=c.load(b)})}var f=function(a,b,c){var e=jQuery.when();c in d&&(e=d[c]),e.done(function(){
+b.set_state(a)})},g=function(a,b,c){return function(e){var f=jQuery.when();c in d&&(f=d[c]),f.done(function(){e.display(a,b)})}};for(b in this.widgets){var h=this.widgets[b];a=null,c&&(a=c.model.fields[b]),a&&f(c,a,b),h.forEach(g(c,a,b))}return jQuery.when.apply(jQuery,jQuery.map(d,function(a){return a})).done(function(){var a;for(a in this.state_widgets){this.state_widgets[a].set_state(c)}for(a in this.containers){this.containers[a].resize()}Sao.View.resize(this.el)}.bind(this))},set_value:function(){var a=this.screen.current_record;if(a){var b=function(b){b.set_value(a,this)};for(var c in this.widgets)if(c in a.model.fields){var d=this.widgets[c],e=a.model.fields[c];d.forEach(b,e)}}},button_clicked:function(a){var b=a.data;b.el.prop("disabled",!0);try{this.screen.button(b.attributes)}finally{b.el.prop("disabled",!1)}},selected_records:function(){return this.screen.current_record?[this.screen.current_record]:[]},set_cursor:function(a,b){var c,d,e,f,g,h,i,j,k,l=jQuery(document.activeElement),m=l.closest(this.el)>0;if(b||m){if(b)for(c=0;c<this.notebooks.length;c++)g=this.notebooks[c],g.set_current_page(0);this.attributes.cursor in this.widgets?f=Sao.common.find_focusable_child(this.widgets[this.attributes.cursor][0].el):(h=Sao.common.find_focusable_child(this.el))&&h.focus()}var n=this.screen.current_record;if(n){var o=[],p=this.el.find(".has-error"),q=n.invalid_fields();for(d in q)for(i=this.widgets[d],c=0;c<p.length;c++)for(j=jQuery(p[c]),e=0;e<i.length;e++)if(j.closest(i[e].el).length>0){o.push(j);break}o.length>0&&(f=Sao.common.find_first_focus_widget(this.el,o))}if(f){for(c=0;c<this.notebooks.length;c++)for(g=this.notebooks[c],k=g.get_n_pages(),e=0;e<k;e++)if(h=g.get_nth_page(e),jQuery(f).closest(h).length>0){g.set_current_page(e);break}jQuery(f).find("input,select,textarea").focus()}}}),Sao.View.Form.Container=Sao.class_(Object,{init:function(a){void 0===a&&(a=4),a<0&&(a=0),this.col=a,this.el=jQuery("<table/>",{class:"form-container responsive responsive-noheader"}),this.add_row()},add_row:function(){this.el.append(jQuery("<tr/>"))},rows:function(){return this.el.children().children("tr")},row:function(){return this.rows().last()},add:function(a,b){var c=a.colspan;void 0===c&&(c=1);var d=a.xfill;void 0===d&&(d=1);var e=a.xexpand;void 0===e&&(e=1);var f=this.row();if(this.col>0){var g=0;f.children().map(function(a,b){g+=Number(jQuery(b).attr("colspan")||1)}),g+c>this.col&&(this.add_row(),f=this.row())}var h;b&&(h=b.el);var i=jQuery("<td/>",{colspan:c,class:b?b.class_||"":""}).append(h);f.append(i),b&&(a.yfill&&i.css("vertical-align","top"),void 0!==a.xalign&&i.css("text-align",a.xalign>=.5?"right":"left"),e&&(i.addClass("xexpand"),i.css("width","100%")),d&&(i.addClass("xfill"),e&&h.css("width","100%")),a.help&&(b.el.data("toggle","tooltip"),b.el.attr("title",a.help),b.el.tooltip()))},resize:function(){var a,b,c=this.rows().toArray(),d=[],e=this.col,f=!1,g=function(b){b=jQuery(b);var c=[];return a=0,b.children().map(function(){var b=jQuery(this),d=Math.min(Number(b.attr("colspan")),e);b.hasClass("xexpand")&&!jQuery.isEmptyObject(b.children())&&"none"!=b.children(":not(.tooltip)").css("display")&&c.push([b,a]),a+=d}),c};c.sort(function(a,b){if(a=g(a),b=g(b),a.length==b.length){var c=function(a,b){var c=b[0];return a+Math.min(Number(c.attr("colspan")),e)};return a.reduce(c,0)-b.reduce(c,0)}return b.length-a.length}),c.forEach(function(c){c=jQuery(c);var h=g(c),i=100/h.length;h.forEach(function(c){var f=c[0];a=c[1];var g=Math.min(Number(f.attr("colspan")),e),h=0;for(b=0;b<g;b++)h+=d[a+b]||0;for(b=0;b<g;b++)if(h){if(h>i){var j=h-i;d[a+b]&&(d[a+b]-=j/(h/d[a+b]))}}else d[a+b]=i/g}),jQuery.isEmptyObject(h)||(f=!0)}),c.forEach(function(c){c=jQuery(c),a=0,c.children().map(function(){var c=jQuery(this),f=Math.min(Number(c.attr("colspan")),e);if(c.hasClass("xexpand")&&"none"!=c.children(":not(.tooltip)").css("display")){var g=0;for(b=0;b<f;b++)g+=d[a+b]||0;c.css("width",g+"%")}else c.css("width","");"none"==c.children().css("display")?c.css("visibility","collapse"):c.css("visibility","visible"),a+=f})}),f?this.el.css("width","100%"):this.el.css("width","")}}),Sao.View.Form.StateWidget=Sao.class_(Object,{init:function(a){this.attributes=a},set_state:function(a){var b;b=a?a.expr_eval(this.attributes.states||{}):{};var c=b.invisible;void 0===c&&(c=this.attributes.invisible),c?this.hide():this.show()},show:function(){this.el.show()},hide:function(){this.el.hide()}}),Sao.View.Form.LabelMixin=Sao.class_(Sao.View.Form.StateWidget,{set_state:function(a){Sao.View.Form.LabelMixin._super.set_state.call(this,a);var b;if(this.attributes.name&&a&&(b=a.model.fields[this.attributes.name]),void 0===this.attributes.string&&b){var c="";a&&(c=b.get_client(a)||""),this.label_el.val(c)}var d;d=a?a.expr_eval(this.attributes.states||{}):{},b&&b.description.readonly||d.readonly,Sao.common.apply_label_attributes(this.label_el,b&&b.description.readonly||d.readonly,b&&b.description.required||d.required)}}),Sao.View.Form.Separator=Sao.class_(Sao.View.Form.LabelMixin,{init:function(a,b){Sao.View.Form.Separator._super.init.call(this,b),this.el=jQuery("<div/>",{class:"form-separator"}),this.label_el=jQuery("<label/>"),a&&this.label_el.text(a),this.el.append(this.label_el),this.el.append(jQuery("<hr/>"))}}),Sao.View.Form.Label=Sao.class_(Sao.View.Form.LabelMixin,{class_:"form-label",init:function(a,b){Sao.View.Form.Label._super.init.call(this,b),this.el=this.label_el=jQuery("<label/>",{text:a,class:this.class_})}}),Sao.View.Form.Notebook=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-notebook",init:function(a){Sao.View.Form.Notebook._super.init.call(this,a),this.el=jQuery("<div/>",{class:this.class_}),this.nav=jQuery("<ul/>",{class:"nav nav-tabs",role:"tablist"}).appendTo(this.el),this.panes=jQuery("<div/>",{class:"tab-content"}).appendTo(this.el),this.selected=!1},add:function(a,b){var c=jQuery("<div/>",{role:"tabpanel",class:"tab-pane"}).uniqueId(),d=c.attr("id"),e=jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{"aria-controls":d,role:"tab","data-toggle":"tab",href:"#"+d}).append(b).on("shown.bs.tab",function(){Sao.View.resize(a)})).appendTo(this.nav);return c.html(a).appendTo(this.panes),this.selected||(e.addClass("active"),c.addClass("active"),this.selected=!0),e},set_current_page:function(a){this.nav.find('li[role="presentation"]:eq('+a+") a").tab("show")},get_n_pages:function(){return this.nav.find("li[role='presentation']").length},get_nth_page:function(a){return jQuery(this.panes.find("div[role='tabpanel']")[a])}}),Sao.View.Form.Page=Sao.class_(Sao.View.Form.StateWidget,{init:function(a,b){Sao.View.Form.Page._super.init.call(this,b),this.el=a}}),Sao.View.Form.Group=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-group_",init:function(a){Sao.View.Form.Group._super.init.call(this,a),this.el=jQuery("<div/>",{class:this.class_})},add:function(a){this.el.append(a.el)}}),Sao.View.Form.Image_=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-image_",init:function(a){Sao.View.Form.Image_._super.init.call(this,a),this.el=jQuery("<div/>",{class_:this.class_}),this.img=jQuery("<img/>",{class:"center-block"}).appendTo(this.el),Sao.common.ICONFACTORY.register_icon(a.name).done(function(a){this.img.attr("src",a)}.bind(this))}}),Sao.View.form_widget_get=function(a){switch(a){case"char":return Sao.View.Form.Char;case"password":return Sao.View.Form.Password;case"date":return Sao.View.Form.Date;case"datetime":return Sao.View.Form.DateTime;case"time":return Sao.View.Form.Time;case"timedelta":return Sao.View.Form.TimeDelta;case"integer":case"biginteger":return Sao.View.Form.Integer;case"float":case"numeric":return Sao.View.Form.Float;case"selection":return Sao.View.Form.Selection;case"boolean":return Sao.View.Form.Boolean;case"text":return Sao.View.Form.Text;case"richtext":return Sao.View.Form.RichText;case"many2one":return Sao.View.Form.Many2One;case"one2one":return Sao.View.Form.One2One;case"reference":return Sao.View.Form.Reference;case"one2many":return Sao.View.Form.One2Many;case"many2many":return Sao.View.Form.Many2Many;case"binary":return Sao.View.Form.Binary;case"multiselection":return Sao.View.Form.MultiSelection;case"image":return Sao.View.Form.Image;case"url":return Sao.View.Form.URL;case"email":return Sao.View.Form.Email;case"callto":return Sao.View.Form.CallTo;case"sip":return Sao.View.Form.SIP;case"progressbar":return Sao.View.Form.ProgressBar;case"dict":return Sao.View.Form.Dict;case"pyson":return Sao.View.Form.PYSON}},Sao.View.Form.Widget=Sao.class_(Object,{init:function(a,b,c){this.field_name=a,this.model=b,this.view=null,this.attributes=c,this.el=null,this.position=0,this.visible=!0,this.labelled=null},display:function(a,b){var c=this.attributes.readonly,d=this.attributes.invisible,e=this.attributes.required;if(!b)return void 0===c&&(c=!0),void 0===d&&(d=!1),void 0===e&&(e=!1),this.set_readonly(c),this.set_invisible(d),void this.set_required(e);var f=b.get_state_attrs(a);void 0===c&&void 0===(c=f.readonly)&&(c=!1),void 0===e&&void 0===(e=f.required)&&(e=!1),this.view.screen.attributes.readonly&&(c=!0),this.set_readonly(c),this.set_required(e);var g=f.invalid;!c&&g?this.el.addClass("has-error"):this.el.removeClass("has-error"),void 0===d&&void 0===(d=b.get_state_attrs(a).invisible)&&(d=!1),this.set_invisible(d)},record:function(){if(this.view&&this.view.screen)return this.view.screen.current_record},field:function(){var a=this.record();if(a)return a.model.fields[this.field_name]},focus_out:function(){this.field()&&this.visible&&this.set_value(this.record(),this.field())},set_value:function(a,b){},set_readonly:function(a){this._readonly=a,this.el.prop("disabled",a)},set_required:function(a){},set_invisible:function(a){this.visible=!a,a?this.el.hide():this.el.show()}}),Sao.View.Form.TranslateDialog=Sao.class_(Object,{init:function(a,b){var c=new Sao.Dialog(Sao.i18n.gettext("Translate"),this.class_,this,a);c.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),this.languages=a,this.read(b,c),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c)}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(this.write.bind(this,b,c)).appendTo(c.footer),c.content.submit(function(a){a.preventDefault(),c.footer.find("button.btn-primary").first().click()}),c.modal.modal("show"),c.modal.on("shown.bs.modal",function(){c.modal.find("input,select").filter(":visible").first().focus()})},close:function(a){a.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),a.modal.modal("hide")},read:function(a,b){this.languages.forEach(function(c){var d={};d.language=c.code;var e,f=[[a.record().id],[a.field_name],d],g={method:"model."+a.model.name+".read",params:f},h=jQuery("<div/>",{class:"row form-group"}),i=a.translate_widget();i.attr("data-lang-id",c.id);var j=jQuery("<input/>",{type:"checkbox",title:Sao.i18n.gettext("Edit")});a._readonly&&j.attr("disabled",!0);var k=jQuery("<input/>",{type:"checkbox",disabled:!0,title:Sao.i18n.gettext("Fuzzy")}),l=Sao.rpc(g,a.model.session).then(function(b){e=b[0][a.field_name]}.bind(this));f=[[a.record().id],[a.field_name],d],d.fuzzy_translation=!0,g={method:"model."+a.model.name+".read",params:f},l.then(function(){Sao.rpc(g,a.model.session).then(function(b){e=b[0][a.field_name],a.translate_widget_set(i,e),k.attr("checked",b[0].name!=e)}.bind(this))}.bind(this)),j.click(function(){a.translate_widget_set_readonly(i)}),b.body.append(h),h.append(jQuery("<div/>",{class:"col-sm-3"}).append(c.name)),h.append(jQuery("<div/>",{class:"col-sm-6"}).append(i)),h.append(jQuery("<div/>",{class:"col-sm-1"}).append(j)),h.append(jQuery("<div/>",{class:"col-sm-1"}).append(k))}.bind(this))},write:function(a,b){var c=[];this.languages.forEach(function(b){var d=jQuery("[data-lang-id="+b.id+"]");if(!d.attr("readonly")){var e=a.model.session.context.language,f={};f.language=b.code,f.fuzzy_translation=!1;var g={};g[a.field_name]=d.val();var h=[[a.record().id],g,f],i={method:"model."+a.model.name+".write",params:h},j=Sao.rpc(i,a.model.session).then(function(){b.code==e&&a.view.display()});c.push(j)}}.bind(this)),this.close(b),jQuery.when.apply(jQuery,c).then(function(){a.record().cancel()})}}),Sao.View.Form.TranslateMixin={},Sao.View.Form.TranslateMixin.init=function(){this.translate=Sao.View.Form.TranslateMixin.translate.bind(this),this.translate_widget_set_readonly=Sao.View.Form.TranslateMixin.translate_widget_set_readonly.bind(this),this.translate_widget_set=Sao.View.Form.TranslateMixin.translate_widget_set.bind(this)},Sao.View.Form.TranslateMixin.translate=function(){if(this.record().id<0||this.record().has_changed()){var a=Sao.i18n.gettext("You need to save the record before adding translations.");return void Sao.common.message.run(a)}var b=this.model.session,c=[[["translatable","=","true"]]],d={method:"model.ir.lang.search",params:c.concat({})};Sao.rpc(d,b).then(function(a){if(jQuery.isEmptyObject(a))return void Sao.common.message.run(Sao.i18n.gettext("No other language available."));var c=[a,["code","name"]],d={method:"model.ir.lang.read",params:c.concat({})};Sao.rpc(d,b).then(function(a){new Sao.View.Form.TranslateDialog(a,this)}.bind(this))}.bind(this))},Sao.View.Form.TranslateMixin.translate_widget_set_readonly=function(a,b){a.attr("readonly")?a.removeAttr("readonly"):a.attr("readonly",!0)},Sao.View.Form.TranslateMixin.translate_widget_set=function(a,b){a.val(b||"")},Sao.View.Form.Char=Sao.class_(Sao.View.Form.Widget,{class_:"form-char",init:function(a,b,c){if(Sao.View.Form.Char._super.init.call(this,a,b,c),Sao.View.Form.TranslateMixin.init.call(this),this.el=jQuery("<div/>",{class:this.class_}),this.group=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el),this.input=this.labelled=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(this.group),jQuery.isEmptyObject(c.autocomplete)||(this.datalist=jQuery("<datalist/>").appendTo(this.el),this.datalist.uniqueId(),this.input.attr("list",this.datalist.attr("id"))),this.el.change(this.focus_out.bind(this)),c.size||this.group.css("width","100%"),this.attributes.translate){jQuery("<button/>",{class:"btn btn-default btn-sm form-control",type:"button","aria-label":Sao.i18n.gettext("Translate")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-flag"})).appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(this.group)).click(this.translate.bind(this))}},get_client_value:function(a,b){var c="";return b&&(c=b.get_client(a)),c},display:function(a,b){if(Sao.View.Form.Char._super.display.call(this,a,b),this.datalist){this.datalist.children().remove();var c=function(){var b=[];a&&(b=a.autocompletion[this.field_name]||[]),b.forEach(function(a){jQuery("<option/>",{value:a}).appendTo(this.datalist)}.bind(this))}.bind(this);!a||this.field_name in a.autocompletion?c():a.do_autocomplete(this.field_name).done(c)}var d="",e="100%";a&&(d=a.expr_eval(this.attributes.size))>0&&(e=null),this.input.val(this.get_client_value(a,b)),this.input.attr("maxlength",d),this.input.attr("size",d),this.group.css("width",e)},set_value:function(a,b){b.set_client(a,this.input.val())},set_readonly:function(a){this.input.prop("readonly",a)},focus:function(){this.input.focus()},translate_widget:function(){return jQuery("<input/>",{class:"form-control",readonly:"readonly"})}}),Sao.View.Form.Password=Sao.class_(Sao.View.Form.Char,{class_:"form-password",init:function(a,b,c){Sao.View.Form.Password._super.init.call(this,a,b,c),this.input.prop("type","password"),this.button=jQuery("<button/>",{class:"btn btn-default btn-sm form-control",type:"button"}).appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(this.group)),this._set_password_label(),this.button.click(this.toggle_visibility.bind(this))},toggle_visibility:function(){"password"==this.input.prop("type")?(this.input.prop("type","text"),this.input.attr("autocomplete","off")):(this.input.prop("type","password"),this.input.removeAttr("autocomplete")),this._set_password_label()},_set_password_label:function(){"password"==this.input.prop("type")?this.button.text(Sao.i18n.gettext("Show")):this.button.text(Sao.i18n.gettext("Hide"))}}),Sao.View.Form.Date=Sao.class_(Sao.View.Form.Widget,{class_:"form-date",_width:"12em",init:function(a,b,c){Sao.View.Form.Date._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.date=this.labelled=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el),this.input=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(this.date),jQuery("<span/>",{class:"input-group-btn"}).append(jQuery("<button/>",{class:"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-calendar"}))).appendTo(this.date),this.date.datetimepicker({locale:moment.locale()}),this.date.css("width",this._width),this.date.on("dp.change",this.focus_out.bind(this))},get_format:function(a,b){return b.date_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isDate=!0),c},display:function(a,b){a&&b&&this.date.data("DateTimePicker").format(Sao.common.moment_format(this.get_format(a,b))),Sao.View.Form.Date._super.display.call(this,a,b);var c;c=a?b.get_client(a):null,this.date.data("DateTimePicker").date(c)},focus:function(){this.input.focus()},set_value:function(a,b){b.set_client(a,this.get_value(a,b))},set_readonly:function(a){this.date.find("button").prop("disabled",a),this.date.find("input").prop("readonly",a)}}),Sao.View.Form.DateTime=Sao.class_(Sao.View.Form.Date,{class_:"form-datetime",_width:"25em",get_format:function(a,b){return b.date_format(a)+" "+b.time_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isDateTime=!0),c}}),Sao.View.Form.Time=Sao.class_(Sao.View.Form.Date,{class_:"form-time",_width:"10em",get_format:function(a,b){return b.time_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isTime=!0),c}}),Sao.View.Form.TimeDelta=Sao.class_(Sao.View.Form.Widget,{class_:"form-timedelta",init:function(a,b,c){Sao.View.Form.TimeDelta._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.input=this.labelled=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(this.el),this.el.change(this.focus_out.bind(this))},display:function(a,b){if(Sao.View.Form.TimeDelta._super.display.call(this,a,b),a){var c=a.field_get_client(this.field_name);this.input.val(c||"")}else this.input.val("")},focus:function(){this.input.focus()},set_value:function(a,b){b.set_client(a,this.input.val())},set_readonly:function(a){this.input.prop("readonly",a)}}),Sao.View.Form.Integer=Sao.class_(Sao.View.Form.Char,{class_:"form-integer",init:function(a,b,c){Sao.View.Form.Integer._super.init.call(this,a,b,c),this.input.attr("type","text"),this.input.attr("width",8),this.group.css("width",""),this.factor=Number(c.factor||1)},set_value:function(a,b){b.set_client(a,this.input.val(),void 0,this.factor)},get_client_value:function(a,b){var c="";return b&&(c=b.get_client(a,this.factor)),c}}),Sao.View.Form.Float=Sao.class_(Sao.View.Form.Integer,{class_:"form-float"}),Sao.View.Form.Selection=Sao.class_(Sao.View.Form.Widget,{class_:"form-selection",init:function(a,b,c){Sao.View.Form.Selection._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.select=this.labelled=jQuery("<select/>",{class:"form-control input-sm"}),this.el.append(this.select),this.select.change(this.focus_out.bind(this)),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a,this.set_selection.bind(this))},update_selection:function(a,b,c){Sao.common.selection_mixin.update_selection.call(this,a,b,function(a){this.set_selection(a),c&&c()}.bind(this))},set_selection:function(a){var b=this.select;b.empty(),a.forEach(function(a){b.append(jQuery("<option/>",{value:JSON.stringify(a[0]),text:a[1]}))})},display_update_selection:function(a,b){this.update_selection(a,b,function(){if(!b)return void this.select.val("");for(var c,d=b.get(a),e=!1,f=0,g=this.selection.length;f<g;f++)if(this.selection[f][0]===d){e=!0;break}e?c=jQuery.when():(c=Sao.common.selection_mixin.get_inactive_selection.call(this,d),c.done(function(a){this.select.append(jQuery("<option/>",{value:JSON.stringify(a[0]),text:a[1],disabled:!0}))}.bind(this))),c.done(function(){this.select.val(JSON.stringify(d))}.bind(this))}.bind(this))},display:function(a,b){Sao.View.Form.Selection._super.display.call(this,a,b),this.display_update_selection(a,b)},focus:function(){this.select.focus()},value_get:function(){return JSON.parse(this.select.val())},set_value:function(a,b){var c=this.value_get();b.set_client(a,c)},set_readonly:function(a){this.select.prop("disabled",a)}}),Sao.View.Form.Boolean=Sao.class_(Sao.View.Form.Widget,{class_:"form-boolean",init:function(a,b,c){Sao.View.Form.Boolean._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.input=this.labelled=jQuery("<input/>",{type:"checkbox",class:"form-control input-sm"}).appendTo(this.el),this.input.change(this.focus_out.bind(this)),this.input.click(function(){return!jQuery(this).prop("readonly")})},display:function(a,b){Sao.View.Form.Boolean._super.display.call(this,a,b),a?this.input.prop("checked",a.field_get(this.field_name)):this.input.prop("checked",!1)},focus:function(){this.input.focus()},set_value:function(a,b){var c=this.input.prop("checked");b.set_client(a,c)},set_readonly:function(a){this.input.prop("readonly",a)}}),Sao.View.Form.Text=Sao.class_(Sao.View.Form.Widget,{class_:"form-text",init:function(a,b,c){if(Sao.View.Form.Text._super.init.call(this,a,b,c),Sao.View.Form.TranslateMixin.init.call(this),this.el=jQuery("<div/>",{class:this.class_}),this.input=this.labelled=jQuery("<textarea/>",{class:"form-control input-sm"}).appendTo(this.el),this.input.change(this.focus_out.bind(this)),this.attributes.translate){var d=jQuery("<button/>",{class:"btn btn-default btn-sm form-control",type:"button","aria-label":Sao.i18n.gettext("Translate")}).appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(this.el));d.append(jQuery("<span/>",{class:"glyphicon glyphicon-flag"})),d.click(this.translate.bind(this))}},display:function(a,b){if(Sao.View.Form.Text._super.display.call(this,a,b),a){var c=a.field_get_client(this.field_name);this.input.val(c)}else this.input.val("")},focus:function(){this.input.focus()},set_value:function(a,b){var c=this.input.val()||"";b.set_client(a,c)},set_readonly:function(a){this.input.prop("readonly",a)},translate_widget:function(){return jQuery("<textarea/>",{class:"form-control",readonly:"readonly"})}}),Sao.View.Form.RichText=Sao.class_(Sao.View.Form.Widget,{class_:"form-richtext",init:function(a,b,c){Sao.View.Form.RichText._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_+" panel panel-default"}),parseInt(c.toolbar||"1",10)&&this.get_toolbar().appendTo(this.el),this.input=this.labelled=jQuery("<div/>",{class:"richtext",contenteditable:!0}).appendTo(jQuery("<div/>",{class:"panel-body"}).appendTo(this.el)),this.el.focusout(this.focus_out.bind(this))},get_toolbar:function(){var a,b,c,d=jQuery("<div/>",{class:"btn-toolbar",role:"toolbar"}).appendTo(jQuery("<div/>",{class:"panel-heading"})),e=function(a){document.execCommand(a.data)},f=function(f){var g=jQuery("<div/>",{class:"btn-group",role:"group"}).appendTo(d);for(a in f)b=f[a],c=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-"+b.icon})).appendTo(g),c.click(b.command,e)};f([{icon:"bold",command:"bold"},{icon:"italic",command:"italic"},{icon:"text-color",command:"underline"}]);var g=[{heading:Sao.i18n.gettext("Font"),options:["Normal","Serif","Sans","Monospace"],command:"fontname"},{heading:Sao.i18n.gettext("Size"),options:[1,2,3,4,5,6,7],command:"fontsize"}],h=function(a,b){return function(c){a.append(jQuery("<li/>").append(jQuery("<a/>",{href:"#"}).append(c).click(function(){document.execCommand(b.command,!1,c)})))}};for(a in g){b=g[a];var i=jQuery("<div/>",{class:"btn-group",role:"group"}).appendTo(d);c=jQuery("<button/>",{class:"btn btn-default dropdown-toggle",type:"button","data-toggle":"dropdown","aria-expanded":!1,"aria-haspopup":!0}).append(b.heading).append(jQuery("<span/>",{class:"caret"})).appendTo(i);var j=jQuery("<ul/>",{class:"dropdown-menu"}).appendTo(i);b.options.forEach(h(j,b))}return f([{icon:"align-left",command:"justifyLeft"},{icon:"align-center",command:"justifyCenter"},{icon:"align-right",command:"justifyRight"},{icon:"align-justify",command:"justifyFull"}]),[["foreColor","#000000"]].forEach(function(a){var b=a[0],c=a[1];jQuery("<input/>",{class:"btn btn-default",type:"color"}).appendTo(d).change(function(){document.execCommand(b,!1,jQuery(this).val())}).focusin(function(){document.execCommand(b,!1,jQuery(this).val())}).val(c)}),d},focus_out:function(){window.setTimeout(function(){0===this.el.find(":focus").length&&Sao.View.Form.RichText._super.focus_out.call(this)}.bind(this),0)},display:function(a,b){Sao.View.Form.RichText._super.display.call(this,a,b);var c="";a&&(c=a.field_get_client(this.field_name)),this.input.html(c)},focus:function(){this.input.focus()},set_value:function(a,b){this.input.find("div").each(function(a,b){if(b=jQuery(b),b.css("text-align")){var c=b.css("text-align").split("-").pop();b.attr("align",c),b.css("text-align","")}"start"==b.attr("align")&&b.attr("align","left")});var c=this.input.html()||"";b.set_client(a,c)},set_readonly:function(a){this.input.prop("contenteditable",!a),this.toolbar&&this.toolbar.find("button,select").prop("disabled",a)}}),Sao.View.Form.Many2One=Sao.class_(Sao.View.Form.Widget,{class_:"form-many2one",init:function(a,b,c){Sao.View.Form.Many2One._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_});var d=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el);this.entry=this.labelled=jQuery("<input/>",{type:"input",class:"form-control input-sm"}).appendTo(d),this.entry.on("keydown",this.key_press.bind(this)),c.completion&&"1"!=c.completion||(Sao.common.get_completion(d,this._update_completion.bind(this),this._completion_match_selected.bind(this),this._completion_action_activated.bind(this)),this.wid_completion=!0),this.but_primary=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon"})).appendTo(jQuery("<span/>",{class:"input-group-btn"}).prependTo(d)),this.but_secondary=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon"})).appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(d)),this.but_primary.click("primary",this.edit.bind(this)),this.but_secondary.click("secondary",this.edit.bind(this)),this.el.change(this.focus_out.bind(this)),this._readonly=!1},get_screen:function(){var a=this.field().get_domain(this.record()),b=this.field().get_context(this.record());return new Sao.Screen(this.get_model(),{context:b,domain:a,mode:["form"],view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views,readonly:this._readonly})},set_text:function(a){jQuery.isEmptyObject(a)&&(a=""),this.entry.val(a)},get_text:function(){var a=this.record();return a?a.field_get_client(this.field_name):""},focus_out:function(){(this.attributes.completion&&"1"!=this.attributes.completion||!this.el.find(".dropdown").hasClass("open"))&&Sao.View.Form.Many2One._super.focus_out.call(this)},set_value:function(a,b){b.get_client(a)!=this.entry.val()&&(b.set_client(a,this.value_from_id(null,"")),this.entry.val(""))},display:function(a,b){var c=this.record();if(!c||!a||c.id==a.id){var d;if(Sao.View.Form.Many2One._super.display.call(this,a,b),this._set_button_sensitive(),this._set_completion(),!a)return void this.entry.val("");this.set_text(b.get_client(a));var e,f;d=b.get(a),this.has_target(d)?(e="glyphicon-folder-open",f="glyphicon-erase"):(e=null,f="glyphicon-search"),this.entry.prop("readonly")&&(f=null),[[e,this.but_primary],[f,this.but_secondary]].forEach(function(a){var b=a[0],c=a[1],d=c.find(".glyphicon");d.removeClass().addClass("glyphicon"),b?(c.parent().css("display","table-cell"),d.addClass(b)):c.parent().css("display","none")})}},focus:function(){this.entry.focus()},set_readonly:function(a){this._readonly=a,this._set_button_sensitive()},_set_button_sensitive:function(){this.entry.prop("readonly",this._readonly),this.but_primary.prop("disabled",!this.read_access()),this.but_secondary.prop("disabled",this._readonly)},get_access:function(a){var b=this.get_model();return!b||Sao.common.MODELACCESS.get(b)[a]},read_access:function(){return this.get_access("read")},create_access:function(){return this.attributes.create&&this.get_access("create")},id_from_value:function(a){return a},value_from_id:function(a,b){return void 0===b&&(b=""),[a,b]},get_model:function(){return this.attributes.relation},has_target:function(a){return void 0!==a&&null!==a},edit:function(a){var b=this.get_model();if(b&&Sao.common.MODELACCESS.get(b).read){var c,d=this.record(),e=d.field_get(this.field_name);if(a&&"secondary"==a.data&&!this._readonly&&this.has_target(e))return this.record().field_set_client(this.field_name,this.value_from_id(null,"")),void this.entry.val("");if(this.has_target(e)){var f=this.get_screen(),g=this.id_from_value(d.field_get(this.field_name));return f.new_group([g]),c=function(a){if(a){f.current_record.rec_name().done(function(a){var b=this.value_from_id(f.current_record.id,a);this.record().field_set_client(this.field_name,b,!0)}.bind(this))}},void new Sao.Window.Form(f,c.bind(this),{save_current:!0,title:this.attributes.string})}if(b){var h=this.field().get_domain(d),i=this.field().get_context(d),j=this.entry.val();c=function(a){if(!jQuery.isEmptyObject(a)){var b=this.value_from_id(a[0][0],a[0][1]);this.record().field_set_client(this.field_name,b,!0)}};var k=new Sao.common.DomainParser;return void new Sao.Window.Search(b,c.bind(this),{sel_multi:!1,context:i,domain:h,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.create_access(),search_filter:k.quote(j),title:this.attributes.string})}}},new_:function(a){var b=this.get_model();if(b&&Sao.common.MODELACCESS.get(b).create){var c=this.get_screen(),d=function(a){if(a){c.current_record.rec_name().done(function(a){var b=this.value_from_id(c.current_record.id,a);this.record().field_set_client(this.field_name,b)}.bind(this))}};new Sao.Window.Form(c,d.bind(this),{new_:!0,save_current:!0,title:this.attributes.string,rec_name:this.entry.val()})}},key_press:function(a){var b=!this.entry.prop("readonly"),c=[Sao.common.TAB_KEYCODE],d=[Sao.common.BACKSPACE_KEYCODE,Sao.common.DELETE_KEYCODE];if(this.wid_completion||c.push(Sao.common.RETURN_KEYCODE),a.which==Sao.common.F3_KEYCODE&&b&&this.create_access())this.new_(),a.preventDefault();else if(a.which==Sao.common.F2_KEYCODE&&this.read_access())this.edit(),a.preventDefault();else if(~c.indexOf(a.which)&&b){if((!this.attributes.completion||"1"==this.attributes.completion)&&this.el.find(".dropdown").hasClass("open"))return;this.activate()}else if(this.has_target(this.record().field_get(this.field_name))&&b){var e=this.get_text();(e!=this.entry.val()||~d.indexOf(a.which))&&(this.entry.val(""),this.record().field_set_client(this.field_name,this.value_from_id(null,"")))}},activate:function(){var a=this.get_model();if(a&&Sao.common.MODELACCESS.get(a).read){var b=this.record(),c=b.field_get(this.field_name);new Sao.Model(a);if(a&&!this.has_target(c)){var d=this.entry.val();if(!this._readonly&&(d||this.field().get_state_attrs(this.record()).required)){var e=this.field().get_domain(b),f=this.field().get_context(b),g=function(a){if(jQuery.isEmptyObject(a))this.entry.val("");else{var b=this.value_from_id(a[0][0],a[0][1]);this.record().field_set_client(this.field_name,b,!0)}},h=new Sao.common.DomainParser
+;new Sao.Window.Search(a,g.bind(this),{sel_multi:!1,context:f,domain:e,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.create_access(),search_filter:h.quote(d),title:this.attributes.string})}}}},_set_completion:function(){var a=this.el.find(".action-search");this.read_access()?a.removeClass("disabled"):a.addClass("disabled");var b=this.el.find(".action-create");this.create_access()?b.removeClass("disabled"):b.addClass("disabled")},_update_completion:function(a){var b=this.record();if(b){var c=this.field(),d=c.get(b);if(this.has_target(d)){var e=this.id_from_value(d);if(void 0!==e&&e>0)return jQuery.when()}var f=this.get_model();return Sao.common.update_completion(this.entry,b,c,f)}},_completion_match_selected:function(a){this.record().field_set_client(this.field_name,this.value_from_id(a.id,a.rec_name),!0)},_completion_action_activated:function(a){"search"==a?this.edit():"create"==a&&this.new_()}}),Sao.View.Form.One2One=Sao.class_(Sao.View.Form.Many2One,{class_:"form-one2one"}),Sao.View.Form.Reference=Sao.class_(Sao.View.Form.Many2One,{class_:"form-reference",init:function(a,b,c){Sao.View.Form.Reference._super.init.call(this,a,b,c),this.el.addClass("form-inline"),this.select=jQuery("<select/>",{class:"form-control input-sm","aria-label":c.string}),this.el.prepend(jQuery("<span/>").text("-")),this.el.prepend(this.select),this.select.change(this.select_changed.bind(this)),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a,this.set_selection.bind(this))},update_selection:function(a,b,c){Sao.common.selection_mixin.update_selection.call(this,a,b,function(a){this.set_selection(a),c&&c()}.bind(this))},set_selection:function(a){var b=this.select;b.empty(),a.forEach(function(a){b.append(jQuery("<option/>",{value:a[0],text:a[1]}))})},id_from_value:function(a){return parseInt(a.split(",")[1],10)},value_from_id:function(a,b){return b||(b=""),[this.get_model(),[a,b]]},get_text:function(){var a=this.record();return a?a.field_get_client(this.field_name)[1]:""},get_model:function(){return this.select.val()},has_target:function(a){if(null===a)return!1;var b=a.split(",")[0];return a=a.split(",")[1],jQuery.isEmptyObject(a)?a=null:(a=parseInt(a,10),isNaN(a)&&(a=null)),b==this.get_model()&&a>=0},_set_button_sensitive:function(){Sao.View.Form.Reference._super._set_button_sensitive.call(this),this.select.prop("disabled",this.entry.prop("readonly"))},select_changed:function(){this.entry.val("");var a,b=this.get_model();a=b?[b,[-1,""]]:["",""],this.record().field_set_client(this.field_name,a)},set_value:function(a,b){var c;if(this.get_model()){c=b.get_client(a,this.field_name);var d,e;c instanceof Array?(d=c[0],e=c[1]):(d="",e=""),d==this.get_model()&&e==this.entry.val()||(b.set_client(a,null),this.entry.val(""))}else c=this.entry.val(),jQuery.isEmptyObject(c)?b.set_client(a,null):b.set_client(a,["",c])},set_text:function(a){var b;a?(b=a[0],a=a[1]):(b=null,a=null),Sao.View.Form.Reference._super.set_text.call(this,a),b?this.select.val(b):this.select.val("")},display:function(a,b){this.update_selection(a,b,function(){Sao.View.Form.Reference._super.display.call(this,a,b)}.bind(this))},set_readonly:function(a){Sao.View.Form.Reference._super.set_readonly.call(this,a),this.select.prop("disabled",a)}}),Sao.View.Form.One2Many=Sao.class_(Sao.View.Form.Widget,{class_:"form-one2many",init:function(a,b,c){Sao.View.Form.One2Many._super.init.call(this,a,b,c),this._readonly=!0,this._required=!1,this.el=jQuery("<div/>",{class:this.class_+" panel panel-default"}),this.menu=jQuery("<div/>",{class:this.class_+"-menu panel-heading"}),this.el.append(this.menu),this.title=jQuery("<label/>",{class:this.class_+"-string",text:c.string}),this.menu.append(this.title),this.title.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",this.title.attr("id")),this.title.attr("for",this.el.attr("id"));var d=jQuery("<div/>",{class:this.class_+"-toolbar"});this.menu.append(d);var e=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(d);this.wid_text=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(e),this.wid_text.hide();var f=jQuery("<div/>",{class:"input-group-btn"}).appendTo(e);c.add_remove&&(this.wid_text.show(),this.but_add=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-plus"})).appendTo(f),this.but_add.click(this.add.bind(this)),this.but_remove=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-minus"})).appendTo(f),this.but_remove.click(this.remove.bind(this))),this.but_new=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("New")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-edit"})).appendTo(f),this.but_new.click(this.new_.bind(this)),this.but_open=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Open")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-folder-open"})).appendTo(f),this.but_open.click(this.open.bind(this)),this.but_del=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Delete")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-trash"})).appendTo(f),this.but_del.click(this.delete_.bind(this)),this.but_undel=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Undelete")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-repeat"})).appendTo(f),this.but_undel.click(this.undelete.bind(this)),this.but_previous=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-chevron-left"})).appendTo(f),this.but_previous.click(this.previous.bind(this)),this.label=jQuery("<span/>",{class:"btn"}).appendTo(f),this.label.text("(0, 0)"),this.but_next=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-chevron-right"})).appendTo(f),this.but_next.click(this.next.bind(this)),this.but_switch=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Switch")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-list-alt"})).appendTo(f),this.but_switch.click(this.switch_.bind(this)),this.content=jQuery("<div/>",{class:this.class_+"-content panel-body"}),this.el.append(this.content);var g=(c.mode||"tree,form").split(",");this.screen=new Sao.Screen(c.relation,{mode:g,view_ids:(c.view_ids||"").split(","),views_preload:c.views||{},row_activate:this.activate.bind(this),exclude_field:c.relation_field||null,limit:null,pre_validate:c.pre_validate}),this.screen.pre_validate=1==c.pre_validate,this.prm=this.screen.switch_view(g[0]).done(function(){this.content.append(this.screen.screen_container.el)}.bind(this)),this.but_switch.prop("disabled",this.screen.number_of_views()<=0)},set_readonly:function(a){this._readonly=a,this._set_button_sensitive(),this._set_label_state()},set_required:function(a){this._required=a,this._set_label_state()},_set_label_state:function(){Sao.common.apply_label_attributes(this.title,this._readonly,this._required)},_set_button_sensitive:function(){var a,b,c=Sao.common.MODELACCESS.get(this.screen.model_name),d=this.record(),e=this.field();if(d&&e){var f=d.expr_eval(this.attributes.size);b=e.get_eval(d).length,a=void 0!==f&&null!==f&&b>=f>=0}else b=null,a=!1;var g=this.attributes.create;void 0===g&&(g=!0),this.but_new.prop("disabled",this._readonly||!g||a||!c.create);var h=this.attributes.delete;void 0===h&&(h=!0),this.but_del.prop("disabled",this._readonly||!h||!c.delete),this.but_undel.prop("disabled",this._readonly||a),this.but_open.prop("disabled",!c.read),this.attributes.add_remove&&(this.wid_text.prop("disabled",this._readonly),this.but_add.prop("disabled",this._readonly||a||!c.write||!c.read),this.but_remove.prop("disabled",this._readonly||!c.write||!c.read))},display:function(a,b){Sao.View.Form.One2Many._super.display.call(this,a,b),this._set_button_sensitive(),this.prm.done(function(){if(a){if(void 0===b)return this.screen.new_group(),this.screen.set_current_record(null),this.screen.group.parent=null,void this.screen.display();var c=a.field_get_client(this.field_name);c!=this.screen.group&&(this.screen.set_group(c),"tree"==this.screen.current_view.view_type&&this.screen.current_view.editable&&this.screen.set_current_record(null));var d=[],e=null;a&&(d=b.get_domain(a),e=a.expr_eval(this.attributes.size)),this._readonly&&(e=null===e?this.screen.group.length:Math.min(e,this.screen.group.length)),Sao.common.compare(this.screen.domain,d)||(this.screen.domain=d),this.screen.size_limit=e,this.screen.display()}}.bind(this))},focus:function(){this.wid_text.is(":visible")&&this.wid_text.focus()},activate:function(a){this.edit()},add:function(a){var b=Sao.common.MODELACCESS.get(this.screen.model_name);if(b.write&&b.read){this.view.set_value();var c=this.field().get_domain(this.record()),d=this.field().get_context(this.record());c=[c,this.record().expr_eval(this.attributes.add_remove)];c=["OR",c,["id","in",this.field().get_removed_ids(this.record())]];var e=this.wid_text.val(),f=function(a){var b=jQuery.when();if(!jQuery.isEmptyObject(a)){var c,d,e=[];for(c=0,d=a.length;c<d;c++)e.push(a[c][0]);this.screen.group.load(e,!0),b=this.screen.display()}b.done(function(){this.screen.set_cursor()}.bind(this)),this.wid_text.val("")}.bind(this),g=new Sao.common.DomainParser;new Sao.Window.Search(this.attributes.relation,f,{sel_multi:!0,context:d,domain:c,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:!this.but_new.prop("disabled"),search_filter:g.quote(e),title:this.attributes.string})}},remove:function(a){var b=Sao.common.MODELACCESS.get(this.screen.model_name);b.write&&b.read&&this.screen.remove(!1,!0,!1)},new_:function(a){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.validate().done(function(){this.attributes.product?this.new_product():this.new_single()}.bind(this))},new_single:function(){var a=jQuery.extend({},this.field().get_context(this.record()));if("form"==this.screen.current_view.type||this.screen.current_view.editable)this.screen.new_(),this.screen.current_view.el.prop("disabled",!1);else{var b=this.record(),c=b.expr_eval(this.attributes.size)||-1;c-=this.field().get_eval(b);new Sao.Window.Form(this.screen,function(){},{new_:!0,many:c,context:a,title:this.attributes.string})}},new_product:function(){var a=this.attributes.product.split(","),b={},c=this.screen;c.new_(!1).then(function(d){d.default_get().then(function(e){d.set_default(e);var f=function(){if(jQuery.isEmptyObject(a))return g();var e=c.model.fields[a.pop()],h=e.description.relation;h||f();var i=e.get_domain(d),j=e.get_context(d),k=function(a){jQuery.isEmptyObject(a)||(b[e.name]=a),f()};new Sao.Window.Search(h,k,{sel_multi:!0,context:j,domain:i,search_filter:"",title:this.attributes.string})}.bind(this),g=function(){if(jQuery.isEmptyObject(b))return void c.group.remove(d,!0);var a=Object.keys(b),f=a.map(function(a){return b[a]});Sao.common.product(f).forEach(function(b){var f=function(c){var d=jQuery.extend({},e);a.forEach(function(a,c){d[a]=b[c][0],d[a+".rec_name"]=b[c][1]}),c.set_default(d)};d?(f(d),d=null):c.new_(!1).then(f)})};f()}.bind(this))}.bind(this))},open:function(a){this.edit()},delete_:function(a){Sao.common.MODELACCESS.get(this.screen.model_name).delete&&this.screen.remove(!1,!1,!1)},undelete:function(a){this.screen.unremove()},previous:function(a){this.validate().done(function(){this.screen.display_previous()}.bind(this))},next:function(a){this.validate().done(function(){this.screen.display_next()}.bind(this))},switch_:function(a){this.screen.switch_view()},edit:function(){Sao.common.MODELACCESS.get(this.screen.model_name).read&&this.validate().done(function(){this.screen.current_record&&new Sao.Window.Form(this.screen,function(){},{title:this.attributes.string})}.bind(this))},validate:function(){var a=jQuery.Deferred();this.view.set_value();var b=this.screen.current_record;if(b){var c=this.screen.current_view.get_fields();b.validate(c).then(function(c){return c?this.screen.pre_validate?b.pre_validate().then(function(b){if(!b)return void a.reject();a.resolve()}):void a.resolve():(this.screen.display(!0),void a.reject())}.bind(this))}else a.resolve();return a},set_value:function(a,b){this.screen.save_tree_state()}}),Sao.View.Form.Many2Many=Sao.class_(Sao.View.Form.Widget,{class_:"form-many2many",init:function(a,b,c){Sao.View.Form.Many2Many._super.init.call(this,a,b,c),this._readonly=!0,this._required=!1,this.el=jQuery("<div/>",{class:this.class_+" panel panel-default"}),this.menu=jQuery("<div/>",{class:this.class_+"-menu panel-heading"}),this.el.append(this.menu),this.title=jQuery("<label/>",{class:this.class_+"-string",text:c.string}),this.menu.append(this.title),this.title.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",this.title.attr("id")),this.title.attr("for",this.el.attr("id"));var d=jQuery("<div/>",{class:this.class_+"-toolbar"});this.menu.append(d);var e=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(d);this.entry=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(e),this.entry.on("keydown",this.key_press.bind(this));var f=jQuery("<div/>",{class:"input-group-btn"}).appendTo(e);this.but_add=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-plus"})).appendTo(f),this.but_add.click(this.add.bind(this)),this.but_remove=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-minus"})).appendTo(f),this.but_remove.click(this.remove.bind(this)),this.content=jQuery("<div/>",{class:this.class_+"-content panel-body"}),this.el.append(this.content),this.screen=new Sao.Screen(c.relation,{mode:["tree"],view_ids:(c.view_ids||"").split(","),views_preload:c.views||{},row_activate:this.activate.bind(this),limit:null}),this.prm=this.screen.switch_view("tree").done(function(){this.content.append(this.screen.screen_container.el)}.bind(this))},set_readonly:function(a){this._readonly=a,this._set_button_sensitive(),this._set_label_state()},set_required:function(a){this._required=a,this._set_label_state()},_set_label_state:function(){Sao.common.apply_label_attributes(this.title,this._readonly,this._required)},_set_button_sensitive:function(){var a=!1,b=this.record(),c=this.field();if(b&&c){var d=b.expr_eval(this.attributes.size),e=c.get_eval(b).length;a=void 0!==d&&null!==d&&e>=d>=0}this.entry.prop("disabled",this._readonly),this.but_add.prop("disabled",this._readonly||a),this.but_remove.prop("disabled",this._readonly)},display:function(a,b){Sao.View.Form.Many2Many._super.display.call(this,a,b),this.prm.done(function(){if(a){if(void 0===b)return this.screen.new_group(),this.screen.set_current_record(null),this.screen.group.parent=null,void this.screen.display();var c=a.field_get_client(this.field_name);c!=this.screen.group&&this.screen.set_group(c),this.screen.display()}}.bind(this))},focus:function(){this.entry.focus()},activate:function(){this.edit()},add:function(){var a=this.field().get_domain(this.record()),b=this.field().get_context(this.record()),c=this.entry.val(),d=function(a){if(!jQuery.isEmptyObject(a)){var b,c,d=[];for(b=0,c=a.length;b<c;b++)d.push(a[b][0]);this.screen.group.load(d,!0),this.screen.display()}this.entry.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(this.attributes.relation,d,{sel_multi:!0,context:b,domain:a,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.attributes.create,search_filter:e.quote(c),title:this.attributes.string})},remove:function(){this.screen.remove(!1,!0,!1)},key_press:function(a){var b=[Sao.common.TAB_KEYCODE];this.wid_completion||b.push(Sao.common.RETURN_KEYCODE),a.which==Sao.common.F3_KEYCODE?(this.new_(),a.preventDefault()):a.which==Sao.common.F2_KEYCODE?(this.add(),a.preventDefault()):~b.indexOf(a.which)&&this.entry.val()&&this.add()},_get_screen_form:function(){var a=this.field().get_domain(this.record()),b=this.record().expr_eval(this.attributes.add_remove);jQuery.isEmptyObject(b)||(a=[a,b]);var c=this.field().get_context(this.record()),d=(this.attributes.view_ids||"").split(",");return jQuery.isEmptyObject(d)||d.shift(),new Sao.Screen(this.attributes.relation,{domain:a,view_ids:d,mode:["form"],views_preload:this.attributes.views,context:c})},edit:function(){if(!jQuery.isEmptyObject(this.screen.current_record)){var a=this._get_screen_form();a.new_group([this.screen.current_record.id]);var b=function(b){b&&a.current_record.save().done(function(){this.screen.current_record.cancel()}.bind(this))}.bind(this);a.switch_view().done(function(){new Sao.Window.Form(a,b,{title:this.attributes.string})}.bind(this))}},new_:function(){var a=this._get_screen_form(),b=function(b){if(b){var c=a.current_record;this.screen.group.load([c.id],!0)}this.entry.val("")}.bind(this);a.switch_view().done(function(){new Sao.Window.Form(a,b,{new_:!0,save_current:!0,title:this.attributes.string,rec_name:this.entry.val()})}.bind(this))}}),Sao.View.Form.BinaryMixin=Sao.class_(Sao.View.Form.Widget,{init:function(a,b,c){Sao.View.Form.BinaryMixin._super.init.call(this,a,b,c),this.filename=c.filename||null},toolbar:function(a){var b=jQuery("<div/>",{class:a,role:"group"});return this.but_select=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-search"})).appendTo(b),this.but_select.click(this.select.bind(this)),this.filename&&(this.but_open=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-folder-open"})).appendTo(b),this.but_open.click(this.open.bind(this))),this.but_save_as=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-save"})).appendTo(b),this.but_save_as.click(this.save_as.bind(this)),this.but_clear=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-erase"})).appendTo(b),this.but_clear.click(this.clear.bind(this)),b},filename_field:function(){var a=this.record();if(a)return a.model.fields[this.filename]},select:function(){var a=this.record(),b=function(){d.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),d.modal.modal("hide")},c=function(){var c=new FileReader;c.onload=function(b){var d,e=this.field(),f=new Uint8Array(c.result);d=e.get_size?f:String.fromCharCode.apply(null,f),e.set_client(a,d)}.bind(this),c.onloadend=function(a){b()};var d=e[0].files[0];c.readAsArrayBuffer(d),this.filename&&this.filename_field().set_client(a,d.name)}.bind(this),d=new Sao.Dialog(Sao.i18n.gettext("Select"),"file-dialog");d.footer.append(jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(b)).append(jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).click(c)),d.content.submit(function(a){c(),a.preventDefault()});var e=jQuery("<input/>",{type:"file"}).appendTo(d.body);d.modal.modal("show")},open:function(){var a={},b=this.filename_field();if(b){var c=b.get_client(this.record());a.mimetype=Sao.common.guess_mimetype(c)}this.save_as(a)},save_as:function(a){var b,c=(a.mimetype,this.field()),d=this.record();b=c.get_data?c.get_data(d):jQuery.when(c.get(d)),b.done(function(a){var b,c=this.filename_field();c&&(b=c.get(this.record())),Sao.common.download_file(a,b)}.bind(this))},clear:function(){var a=this.filename_field();a&&a.set_client(this.record(),null),this.field().set_client(this.record(),null)}}),Sao.View.Form.Binary=Sao.class_(Sao.View.Form.BinaryMixin,{class_:"form-binary",blob_url:"",init:function(a,b,c){Sao.View.Form.Binary._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.filename&&c.filename_visible&&(this.text=jQuery("<input/>",{type:"input",class:"form-control input-sm"}).appendTo(this.el),this.text.change(this.focus_out.bind(this)),this.text.on("keydown",this.key_press.bind(this)));var d=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el);this.size=jQuery("<input/>",{type:"input",class:"form-control input-sm",readonly:!0}).appendTo(d),this.toolbar("input-group-btn").appendTo(d)},display:function(a,b){if(Sao.View.Form.Binary._super.display.call(this,a,b),!b)return this.size.val(""),this.filename&&this.but_open.button("disable"),this.text&&this.text.val(""),void this.but_save_as.button("disable");var c;c=b.get_size?b.get_size(a):b.get(a).length;var d;d=c?"enable":"disable",this.filename&&(this.text&&this.text.val(this.filename_field().get(a)||""),this.but_open.button(d)),this.size.val(Sao.common.humanize(c)),this.but_save_as.button(d)},key_press:function(a){var b=!this.wid_text.prop("readonly");a.which==Sao.common.F3_KEYCODE&&b?(this.new_(),a.preventDefault()):a.which==Sao.common.F2_KEYCODE&&(this.open(),a.preventDefault())},set_value:function(a,b){this.text&&this.filename_field().set_client(a,this.text.val()||"")},set_readonly:function(a){a?(this.but_select.hide(),this.but_clear.hide()):(this.but_select.show(),this.but_clear.show()),this.wid_text&&this.wid_text.prop("readonly",a)}}),Sao.View.Form.MultiSelection=Sao.class_(Sao.View.Form.Selection,{class_:"form-multiselection",expand:!0,init:function(a,b,c){this.nullable_widget=!1,Sao.View.Form.MultiSelection._super.init.call(this,a,b,c),this.select.prop("multiple",!0)},display_update_selection:function(a,b){var c,d,e;this.update_selection(a,b,function(){var f=this.attributes.yexpand;if(void 0===f&&(f=this.expand),f||this.select.prop("size",this.select.children().length),b){var g=[],h=a.field_get_client(this.field_name);for(c=0,d=h.length;c<d;c++)e=h[c],~h.record_removed.indexOf(e)||~h.record_deleted.indexOf(e)||g.push(e.id);this.select.val(g)}}.bind(this))},set_value:function(a,b){var c=this.select.val();c=c?c.map(function(a){return parseInt(a,10)}):[],b.set_client(a,c)}}),Sao.View.Form.Image=Sao.class_(Sao.View.Form.BinaryMixin,{class_:"form-image",init:function(a,b,c){Sao.View.Form.Image._super.init.call(this,a,b,c),this.height=parseInt(c.height||100,10),this.width=parseInt(c.width||300,10),this.el=jQuery("<div/>"),this.image=jQuery("<img/>",{class:"center-block"}).appendTo(this.el),this.image.css("max-height",this.height),this.image.css("max-width",this.width),this.image.css("height","auto"),this.image.css("width","auto");var d=this.toolbar("btn-group");c.readonly||jQuery("<div/>",{class:"text-center"}).append(d).appendTo(this.el),this.update_img()},set_readonly:function(a){[this.but_select,this.but_open,this.but_save_as,this.but_clear].forEach(function(b){b&&b.prop("disable",a)})},clear:function(){Sao.View.Form.Image._super.clear.call(this),this.update_img()},update_img:function(){var a,b=this.record();b&&(a=b.field_get_client(this.field_name)),a=a?a>Sao.common.BIG_IMAGE_SIZE?jQuery.when(null):b.model.fields[this.field_name].get_data(b):jQuery.when(null),a.done(function(a){var b,c;a?(c=new Blob([a]),b=window.URL.createObjectURL(c)):b=null,this.image.attr("src",b)}.bind(this))},display:function(a,b){Sao.View.Form.Image._super.display.call(this,a,b),this.update_img()}}),Sao.View.Form.URL=Sao.class_(Sao.View.Form.Char,{class_:"form-url",init:function(a,b,c){Sao.View.Form.URL._super.init.call(this,a,b,c),this.button=jQuery("<a/>",{class:"btn btn-default",target:"_new"}).appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(this.group)),this.icon=jQuery("<img/>").appendTo(this.button),this.set_icon()},display:function(a,b){Sao.View.Form.URL._super.display.call(this,a,b);var c="";if(a&&(c=a.field_get_client(this.field_name)),this.set_url(c),a&this.attributes.icon){var d,e=this.attributes.icon;d=e in a.model.fields?a.field_get_client(e):e,this.set_icon(d)}},set_icon:function(a){a=a||"tryton-web-browser",Sao.common.ICONFACTORY.register_icon(a).done(function(a){this.icon.attr("src",a)}.bind(this))},set_url:function(a){this.button.attr("href",a)},set_readonly:function(a){Sao.View.Form.URL._super.set_readonly.call(this,a),a?(this.input.hide(),this.button.removeClass("btn-default"),this.button.addClass("btn-link")):(this.input.show(),this.button.removeClass("btn-link"),this.button.addClass("btn-default"))}}),Sao.View.Form.Email=Sao.class_(Sao.View.Form.URL,{class_:"form-email",set_url:function(a){Sao.View.Form.Email._super.set_url.call(this,"mailto:"+a)}}),Sao.View.Form.CallTo=Sao.class_(Sao.View.Form.URL,{class_:"form-callto",set_url:function(a){Sao.View.Form.CallTo._super.set_url.call(this,"callto:"+a)}}),Sao.View.Form.SIP=Sao.class_(Sao.View.Form.URL,{class_:"form-sip",set_url:function(a){Sao.View.Form.SIP._super.set_url.call(this,"sip:"+a)}}),Sao.View.Form.ProgressBar=Sao.class_(Sao.View.Form.Widget,{class_:"form-char",init:function(a,b,c){Sao.View.Form.ProgressBar._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_+" progress"}),this.progressbar=jQuery("<div/>",{class:"progress-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100}).appendTo(this.el),this.progressbar.css("min-width: 2em")},display:function(a,b){Sao.View.Form.ProgressBar._super.display.call(this,a,b);var c,d;b?(c=b.get(a),(d=b.get_client(a,100))&&(d=Sao.i18n.gettext("%1%",d))):(c=0,d=""),this.progressbar.attr("aria-valuenow",100*c),this.progressbar.css("width",100*c+"%"),this.progressbar.text(d)}}),Sao.View.Form.Dict=Sao.class_(Sao.View.Form.Widget,{class_:"form-dict",init:function(a,b,c){Sao.View.Form.Dict._super.init.call(this,a,b,c),this.schema_model=new Sao.Model(c.schema_model),this.keys={},this.fields={},this.rows={},this.el=jQuery("<div/>",{class:this.class_+" panel panel-default"});var d=jQuery("<div/>",{class:this.class_+"-heading panel-heading"}).appendTo(this.el),e=jQuery("<label/>",{class:this.class_+"-string",text:c.string}).appendTo(d);e.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",e.attr("id")),e.attr("for",this.el.attr("id"));var f=jQuery("<div/>",{class:this.class_+"-body panel-body"}).appendTo(this.el);this.container=jQuery("<div/>",{class:this.class_+"-container"}).appendTo(f);var g=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(jQuery("<div>",{class:"col-md-12"}).appendTo(jQuery("<div/>",{class:"row"}).appendTo(jQuery("<div/>",{class:"container-fluid"}).appendTo(f))));this.wid_text=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(g),this.but_add=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-plus"})).appendTo(jQuery("<div/>",{class:"input-group-btn"}).appendTo(g)),this.but_add.click(this.add.bind(this)),this._readonly=!1,this._record_id=null},add:function(){var a=this.field().get_context(this.record()),b=this.wid_text.val(),c=this.field().get_domain(this.record()),d=function(a){if(!jQuery.isEmptyObject(a)){var b=a.map(function(a){return a[0]});this.add_new_keys(b)}this.wid_text.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(this.schema_model.name,d,{sel_multi:!0,context:a,domain:c,new_:!1,search_filter:e.quote(b),title:this.attributes.string})},add_new_keys:function(a){var b=this.field().get_context(this.record());this.schema_model.execute("get_keys",[a],b).then(function(a){var b=!1;a.forEach(function(a){this.fields[a.name]||(this.keys[a.name]=a,this.add_line(a.name),b||(this.fields[a.name].input.focus(),b=!0))}.bind(this))}.bind(this))},remove:function(a,b){void 0===b&&(b=!0),delete this.fields[a],this.rows[a].remove(),delete this.rows[a],b&&this.set_value(this.record(),this.field())},set_value:function(a,b){b.set_client(a,this.get_value())},get_value:function(){var a={};for(var b in this.fields){var c=this.fields[b];a[b]=c.get_value()}return a},set_readonly:function(a){this._readonly=a,this._set_button_sensitive();for(var b in this.fields){this.fields[b].set_readonly(a)}this.wid_text.prop("disabled",a)},_set_button_sensitive:function(){var a=this.attributes.create;void 0===a&&(a=!0);var b=this.attributes.delete;void 0===b&&(b=!0),this.but_add.prop("disabled",this._readonly||!a);for(var c in this.fields){this.fields[c].button.prop("disabled",this._readonly||!b)}},add_line:function(a){var b,c;this.fields[a]=b=new(this.get_entries(this.keys[a].type_))(a,this),this.rows[a]=c=jQuery("<div/>",{class:"row"});var d=this.keys[a].string+Sao.i18n.gettext(":"),e=jQuery("<label/>",{text:d}).appendTo(jQuery("<div/>",{class:"dict-label col-md-4"}).appendTo(c));b.el.addClass("col-md-8").appendTo(c),e.uniqueId(),b.labelled.uniqueId(),b.labelled.attr("aria-labelledby",e.attr("id")),e.attr("for",b.labelled.attr("id")),b.button.click(function(){this.remove(a,!0)}.bind(this)),c.appendTo(this.container)},add_keys:function(a){var b=this.field().get_context(this.record()),c=this.field().get_domain(this.record()),d=Math.min(10,Sao.config.limit);a=jQuery.extend([],a);for(var e=function(a){return this.schema_model.execute("get_keys",[a],b).then(f)}.bind(this),f=function(a){for(var b=0,c=a.length;b<c;b++){var d=a[b];this.keys[d.name]=d}}.bind(this),g=[];a.length>0;){var h=a.splice(0,d);g.push(this.schema_model.execute("search",[[["name","in",h],c],0,Sao.config.limit,null],b).then(e))}return jQuery.when.apply(jQuery,g)},display:function(a,b){if(Sao.View.Form.Dict._super.display.call(this,a,b),b){var c,d=a?a.id:null;if(d!=this._record_id){for(c in this.fields)this.remove(c,!1);this._record_id=d}var e,f=b.get_client(a),g=Object.keys(f).filter(function(a){return!this.keys[a]}.bind(this));e=jQuery.isEmptyObject(g)?jQuery.when():this.add_keys(g),e.then(function(){var a,b,c,d=Object.keys(f).sort();for(a=0,b=d.length;a<b;a++){c=d[a];var e=f[c];if(this.keys[c]){this.fields[c]||this.add_line(c);var g=this.fields[c];g.set_value(e),g.set_readonly(this._readonly)}}var h=Object.keys(this.fields).filter(function(a){return!f[a]});for(a=0,b=h.length;a<b;a++)c=h[a],this.remove(c,!1)}.bind(this)),this._set_button_sensitive()}},get_entries:function(a){switch(a){case"char":return Sao.View.Form.Dict.Entry;case"boolean":return Sao.View.Form.Dict.Boolean;case"selection":return Sao.View.Form.Dict.Selection;case"integer":return Sao.View.Form.Dict.Integer;case"float":return Sao.View.Form.Dict.Float;case"numeric":return Sao.View.Form.Dict.Numeric;case"date":return Sao.View.Form.Dict.Date;case"datetime":return Sao.View.Form.Dict.DateTime}}}),Sao.View.Form.Dict.Entry=Sao.class_(Object,{class_:"dict-char",init:function(a,b){this.name=a,this.definition=b.keys[a],this.parent_widget=b,this.create_widget()},create_widget:function(){this.el=jQuery("<div/>",{class:this.class_});var a=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el);this.input=this.labelled=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(a),this.button=jQuery("<button/>",{class:"btn btn-default",type:"button","arial-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-minus"})).appendTo(jQuery("<div/>",{class:"input-group-btn"}).appendTo(a)),this.el.change(this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){return this.input.val()},set_value:function(a){this.input.val(a||"")},set_readonly:function(a){this._readonly=a,this.input.prop("readonly",a)}}),Sao.View.Form.Dict.Boolean=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-boolean",create_widget:function(){Sao.View.Form.Dict.Boolean._super.create_widget.call(this),this.input.attr("type","checkbox"),this.input.change(this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){return this.input.prop("checked")},
+set_value:function(a){this.input.prop("checked",a)}}),Sao.View.Form.Dict.Selection=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-selection",create_widget:function(){Sao.View.Form.Dict.Selection._super.create_widget.call(this);var a=jQuery("<select/>",{class:"form-control input-sm"});a.change(this.parent_widget.focus_out.bind(this.parent_widget)),this.input.replaceWith(a),this.input=this.labelled=a;var b=jQuery.extend([],this.definition.selection);b.splice(0,0,[null,""]),b.forEach(function(b){a.append(jQuery("<option/>",{value:JSON.stringify(b[0]),text:b[1]}))})},get_value:function(){return JSON.parse(this.input.val())},set_value:function(a){this.input.val(JSON.stringify(a))}}),Sao.View.Form.Dict.Integer=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-integer",get_value:function(){var a=parseInt(this.input.val(),10);return isNaN(a)?null:a}}),Sao.View.Form.Dict.Float=Sao.class_(Sao.View.Form.Dict.Integer,{class_:"dict-float",get_value:function(){var a=Number(this.input.val());return isNaN(a)?null:a}}),Sao.View.Form.Dict.Numeric=Sao.class_(Sao.View.Form.Dict.Float,{class_:"dict-numeric",get_value:function(){var a=new Sao.Decimal(this.input.val());return isNaN(a.valueOf())?null:a}}),Sao.View.Form.Dict.Date=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-date",format:"%x",create_widget:function(){Sao.View.Form.Dict.Date._super.create_widget.call(this);var a=this.button.parent();jQuery("<button/>",{class:"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-calendar"})).prependTo(a),this.input.datetimepicker({format:Sao.common.moment_format(this.format),locale:moment.locale()}),this.input.on("dp.change",this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){var a=this.input.data("DateTimePicker").date();return a&&(a.isDate=!0),a},set_value:function(a){this.input.data("DateTimePicker").date(a)}}),Sao.View.Form.Dict.DateTime=Sao.class_(Sao.View.Form.Dict.Date,{class_:"dict-datetime",format:"%x %X",get_value:function(){var a=this.input.data("DateTimePicker").date();return a&&(a.isDateTime=!0),a}}),Sao.View.Form.PYSON=Sao.class_(Sao.View.Form.Char,{class_:"form-pyson",init:function(a,b,c){Sao.View.Form.PYSON._super.init.call(this,a,b,c),this.encoder=new Sao.PYSON.Encoder({}),this.decoder=new Sao.PYSON.Decoder({},!0),this.el.keyup(this.validate_pyson.bind(this));var d=jQuery("<button/>",{class:"btn btn-default",type:"button"});this.icon=jQuery("<span/>",{class:"glyphicon"}),d.append(this.icon),d.appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(this.group))},get_encoded_value:function(){var a=this.input.val();if(!a)return a;try{return this.encoder.encode(eval_pyson(a))}catch(b){return null}},set_value:function(a,b){b.set_client(a,this.get_encoded_value())},get_client_value:function(a,b){var c=Sao.View.Form.PYSON._super.get_client_value.call(this,a,b);return c&&(c=this.decoder.decode(c).toString()),c},validate_pyson:function(){var a="ok";null===this.get_encoded_value()&&(a="remove"),this.icon.removeClass().addClass("glyphicon").addClass(" glyphicon-"+a+"-sign")},focus_out:function(){this.validate_pyson(),Sao.View.Form.PYSON._super.focus_out.call(this)}})}(),function(){"use strict";function a(a,b,c){var d=Sao.config.display_size,e=jQuery.Deferred(),f=function(g){a.slice(g,g+d).forEach(function(a){a.redraw(b,c)}),g+=d,g<a.length?setTimeout(f,0,g):e.resolve()};return setTimeout(f,0,0),e}Sao.View.tree_column_get=function(a){switch(a){case"char":return Sao.View.Tree.CharColumn;case"text":return Sao.View.Tree.TextColum;case"many2one":return Sao.View.Tree.Many2OneColumn;case"one2one":return Sao.View.Tree.One2OneColumn;case"date":return Sao.View.Tree.DateColumn;case"time":return Sao.View.Tree.TimeColumn;case"timedelta":return Sao.View.Tree.TimeDeltaColumn;case"one2many":return Sao.View.Tree.One2ManyColumn;case"many2many":return Sao.View.Tree.Many2ManyColumn;case"selection":return Sao.View.Tree.SelectionColumn;case"reference":return Sao.View.Tree.ReferenceColumn;case"float":case"numeric":return Sao.View.Tree.FloatColumn;case"integer":case"biginteger":return Sao.View.Tree.IntegerColumn;case"boolean":return Sao.View.Tree.BooleanColumn;case"binary":return Sao.View.Tree.BinaryColumn;case"image":return Sao.View.Tree.ImageColumn;case"url":case"email":case"callto":case"sip":return Sao.View.Tree.URLColumn;case"progressbar":return Sao.View.Tree.ProgressBar}},Sao.View.Tree=Sao.class_(Sao.View,{init:function(a,b,c){Sao.View.Tree._super.init.call(this,a,b),this.view_type="tree",this.selection_mode=a.attributes.selection_mode||Sao.common.SELECTION_SINGLE,this.el=jQuery("<div/>",{class:"treeview responsive"}),this.expanded={},this.children_field=c,this.editable=Boolean(this.attributes.editable),this.columns=[],this.create_columns(a.model,b),this.rows=[],this.table=jQuery("<table/>",{class:"tree table table-hover table-striped"}),this.el.append(this.table),this.thead=jQuery("<thead/>").appendTo(this.table);var d=jQuery("<tr/>");if(this.selection_mode!=Sao.common.SELECTION_NONE){var e=jQuery("<th/>",{class:"selection"});this.selection=jQuery("<input/>",{type:"checkbox",class:"selection"}),this.selection.change(this.selection_changed.bind(this)),e.append(this.selection),d.append(e)}this.thead.append(d),this.columns.forEach(function(a){e=jQuery("<th/>");var b=jQuery("<label/>").text(a.attributes.string);if(this.editable&&(a.attributes.required&&b.addClass("required"),a.attributes.readonly||b.addClass("editable")),a.attributes.help&&(b.data("toggle","tooltip"),b.attr("title",a.attributes.help),b.tooltip()),a.sortable){var c=jQuery("<span/>");b.append(c),a.arrow=c,e.click(a,this.sort_model.bind(this)),b.addClass("sortable")}d.append(e.append(b)),a.header=e},this),this.tbody=jQuery("<tbody/>"),this.table.append(this.tbody);var f=jQuery("<div/>",{class:"treefooter"});this.more=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("More")).click(function(){this.display_size+=Sao.config.display_size,this.display()}.bind(this)),f.append(this.more),this.more.hide(),this.display_size=Sao.config.display_size,this.el.append(f)},create_columns:function(a,b){b.find("tree").children().each(function(b,c){for(var d,e,f={},g=0,h=c.attributes.length;g<h;g++)e=c.attributes[g],f[e.name]=e.value;if(["readonly","expand","completion"].forEach(function(a){f[a]&&(f[a]=1==f[a])}),"field"==c.tagName){var i=f.name;f.widget||(f.widget=a.fields[i].description.type);var j=["relation","domain","selection","relation_field","string","views","invisible","add_remove","sort","context","filename","autocomplete","translate","create","delete","selection_change_with","schema_model","required","readonly","help"];for(g in j){var k=j[g];k in a.fields[i].description&&null===c.getAttribute(k)&&(f[k]=a.fields[i].description[k])}d=new(Sao.View.tree_column_get(f.widget))(a,f);~["url","email","callto","sip"].indexOf(f.widget)&&d.prefixes.push(new Sao.View.Tree.Affix(f,f.widget)),"icon"in f&&d.prefixes.push(new Sao.View.Tree.Affix(f));var l,m,n=c.childNodes;for(g=0;g<n.length;g++){for(l=n[g],m={},g=0,h=l.attributes.length;g<h;g++)e=l.attributes[g],m[e.name]=e.value;m.name||(m.name=i),"prefix"==l.tagName?d.prefixes.push(new Sao.View.Tree.Affix(m)):d.suffixes.push(new Sao.View.Tree.Affix(m))}this.attributes.sequence||this.children_field||!1===a.fields[i].description.sortable||(d.sortable=!0),this.fields[i]=!0}else"button"==c.tagName&&(d=new Sao.View.Tree.ButtonColumn(this.screen,f));this.columns.push(d)}.bind(this))},sort_model:function(a){var b=a.data,c=b.arrow,d="glyphicon glyphicon-triangle-top",e="glyphicon glyphicon-triangle-bottom";this.columns.forEach(function(a){a.arrow&&a!=b&&a.arrow.hasClass("glyphicon")&&a.arrow.removeClass(d+" "+e)}),this.screen.order=this.screen.default_order,c.hasClass(e)?(c.removeClass(e),c.addClass(d),this.screen.order=[[b.attributes.name,"DESC"]]):c.hasClass(d)?c.removeClass(d):(c.addClass(e),this.screen.order=[[b.attributes.name,"ASC"]]);var f=[];this.screen.group.forEach(function(a){a.id<0&&(f=a.group)});var g=this.screen.screen_container.get_text();!jQuery.isEmptyObject(f)||this.screen.search_count==this.screen.group.length||this.screen.parent?this.screen.search_filter(g,!0).then(function(a){this.screen.group.sort(a)}.bind(this)):this.screen.search_filter(g)},get_buttons:function(){var a=[];return this.columns.forEach(function(b){b instanceof Sao.View.Tree.ButtonColumn&&a.push(b)}),a},display:function(a,b){var c=this.screen.current_record;if(!a)if(a=this.get_selected_paths(),c){var d=c.get_path(this.screen.group);d=d.map(function(a){return a[1]}),Sao.common.contains(a,d)||(a=[d])}else c||(a=[]);b=b||[];var e=function(){return this.rows.map(function(a){return a.record})}.bind(this),f=Math.min(this.screen.group.length,this.display_size);this.children_field?this.construct(a,b):f>this.rows.length&&Sao.common.compare(this.screen.group.slice(0,this.rows.length),e())?this.construct(a,b,!0):f==this.rows.length&&Sao.common.compare(this.screen.group,e())||this.construct(a,b);var g=[];jQuery.isEmptyObject(this.screen.domain)||g.push(this.screen.domain);var h=this.screen.screen_container.get_tab_domain();jQuery.isEmptyObject(h)||g.push(h);var i=new Sao.common.DomainInversion;g=i.simplify(g);var j=new Sao.PYSON.Decoder(this.screen.context);return this.columns.forEach(function(a){var b=a.attributes.name;if(b)if(j.decode(a.attributes.tree_invisible||"0")||b===this.screen.exclude_field)a.header.hide(),a.header.addClass("invisible");else{var c=i.domain_inversion(g,b);"boolean"!=typeof c&&(c=i.simplify(c));var d=i.unique_value(c)[0];d&&jQuery.isEmptyObject(this.children_field)?(a.header.hide(),a.header.addClass("invisible")):(a.header.show(),a.header.removeClass("invisible"))}}.bind(this)),this.columns.filter(function(a){return a.header.is(":visible")}).length>1?(this.table.addClass("responsive"),this.table.addClass("responsive-header")):(this.table.removeClass("responsive"),this.table.removeClass("responsive-header")),this.redraw(a,b)},construct:function(a,b,c){var d=this.tbody;c||(this.rows=[],this.tbody=jQuery("<tbody/>"));var e=this.rows.length,f=function(c,d,e){var f;f=this.editable?Sao.View.Tree.RowEditable:Sao.View.Tree.Row;var g=new f(this,c,this.rows.length);this.rows.push(g),g.construct(a,b)};this.screen.group.slice(e,this.display_size).forEach(f.bind(this)),this.display_size>=this.screen.group.length?this.more.hide():this.more.show(),c||d.replaceWith(this.tbody)},redraw:function(b,c){return a(this.rows,b,c)},switch_:function(a){this.screen.row_activate()},select_changed:function(a){var b=this.screen.current_record;if(this.screen.set_current_record(a),this.editable&&b){var c=function(){this.screen.set_current_record(b),this.set_cursor()}.bind(this);this.screen.group.parent||b===a?b!==a&&this.screen.attributes.pre_validate&&b.pre_validate().then(function(a){a||c()}):b.validate(this.get_fields()).then(function(a){a?b.save().fail(c):c()})}},selected_records:function(){if(this.selection_mode==Sao.common.SELECTION_NONE)return[];var a=[],b=function(c){c.is_selected()&&a.push(c.record),c.rows.forEach(b)};return this.rows.forEach(b),this.selection.prop("checked")&&!this.selection.prop("indeterminate")&&this.screen.group.slice(this.rows.length).forEach(function(b){a.push(b)}),a},selection_changed:function(){var a=this.selection.prop("checked"),b=function(c){c.set_selection(a),c.rows.forEach(b)};this.rows.forEach(b),a&&this.rows[0]?this.select_changed(this.rows[0].record):this.select_changed(null)},update_selection:function(){if(!this.selection.prop("checked")){var a=this.selected_records();this.selection.prop("indeterminate",!1),jQuery.isEmptyObject(a)?this.selection.prop("checked",!1):a.length==this.tbody.children().length&&this.display_size>=this.screen.group.length?this.selection.prop("checked",!0):(this.selection.prop("indeterminate",!0),this.selection.prop("checked",!0))}},get_selected_paths:function(){function a(c,d){var e,f,g,h;for(e=0,g=c.rows.length;e<g;e++)f=c.rows[e],h=d.concat([f.record.id]),f.is_selected()&&b.push(h),a(f,h)}var b=[];return a(this,[]),b},get_expanded_paths:function(a,b){var c,d,e,f,g;void 0===a&&(a=[]),void 0===b&&(b=[]),d=[],e=this.find_row(a),f=e?e.rows:this.rows;for(var h=0,i=this.n_children(e);h<i;h++)g=a.concat([h]),(e=f[h])&&e.is_expanded()&&(c=b.concat(e.record.id),d.push(c),d=d.concat(this.get_expanded_paths(g,c)));return d},find_row:function(a){for(var b,c=null,d=this.rows,e=0,f=a.length;e<f;e++){if(b=a[e],!d||b>=d.length)return null;if(c=d[b],d=c.rows,!this.children_field)break}return c},n_children:function(a){return a&&this.children_field?a.record._values[this.children_field].length:this.rows.length},set_cursor:function(a,b){var c,d,e,f,g,h,i,j;if(this.screen.current_record){for(d=null,c=0;c<this.rows.length;c++)if(e=this.rows[c].record_to_path(this.screen.current_record)){e.unshift(c),d=e;break}f=null,d?(h=d[0],i=d.slice(1),i.length>0&&this.rows[h].expand_to_path(i),f=this.find_row(d)):this.rows.length>0&&(f=this.rows[0]),f&&null!==(g=f.next_column(null,a))&&(j=f._get_column_td(g),this.editable?(j.triggerHandler("click"),a?j.triggerHandler("click"):j.find(":input,[tabindex=0]").focus()):j.find(":input,[tabindex=0]").focus())}}}),Sao.View.Tree.Row=Sao.class_(Object,{init:function(a,b,c,d){this.tree=a,this.rows=[],this.record=b,this.parent_=d,this.children_field=a.children_field,this.expander=null;var e=[];d&&(e=jQuery.extend([],d.path.split("."))),e.push(c),this.path=e.join("."),this.el=jQuery("<tr/>")},is_expanded:function(){return this.path in this.tree.expanded},get_last_child:function(){return this.children_field&&this.is_expanded()&&!jQuery.isEmptyObject(this.rows)?this.rows[this.rows.length-1].get_last_child():this},get_id_path:function(){return this.parent_?this.parent_.get_id_path().concat([this.record.id]):[this.record.id]},build_widgets:function(){var a=jQuery("<table/>");a.css("width","100%");var b=jQuery("<tr/>");return a.append(b),[a,b]},construct:function(a,b){a=a||[],b=b||[];for(var c=this.el[0];c.firstChild;)c.removeChild(c.firstChild);var d;this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(d=jQuery("<td/>"),this.el.append(d),this.selection=jQuery("<input/>",{type:"checkbox",class:"selection"}),this.selection.change(this.selection_changed.bind(this)),d.append(this.selection));for(var e=this.path.split(".").length,f=0;f<this.tree.columns.length;f++){var g=this.tree.columns[f];d=jQuery("<td/>",{"data-title":g.attributes.string+Sao.i18n.gettext(": ")}).append(jQuery("<div/>",{"aria-hidden":!0})),d.css("overflow","hidden"),d.on("click keypress",{column:f,td:d},Sao.common.click_press(this.select_row.bind(this),!0)),this.tree.editable?(g.attributes.required&&d.addClass("required"),g.attributes.readonly||d.addClass("editable")):d.dblclick(this.switch_row.bind(this));var h=this.build_widgets(),i=h[0],j=h[1];if(d.append(i),0===f&&this.children_field){var k="glyphicon-plus";(this.is_expanded()||~b.indexOf(this.record.id))&&(k="glyphicon-minus"),this.expander=jQuery("<span/>",{class:"glyphicon "+k,tabindex:0}),this.expander.html(" "),this.expander.css("margin-left",e-1+"em"),this.expander.css("float","left"),this.expander.on("click keypress",Sao.common.click_press(this.toggle_row.bind(this))),j.append(jQuery("<td/>",{class:"expander"}).append(this.expander).css("width",1))}var l;if(g.prefixes)for(l=0;l<g.prefixes.length;l++){g.prefixes[l];j.append(jQuery("<td/>",{class:"prefix"}).css("width",1))}if(j.append(jQuery("<td/>",{class:"widget"})),g.suffixes)for(l=0;l<g.suffixes.length;l++){g.suffixes[l];j.append(jQuery("<td/>",{class:"suffix"}).css("width",1))}this.el.append(d)}if(this.parent_){this.parent_.get_last_child().el.after(this.el)}else this.tree.tbody.append(this.el);var m=this.get_id_path();(this.is_expanded()||Sao.common.contains(b,m))&&(this.tree.expanded[this.path]=this,this.expand_children(a,b))},_get_column_td:function(a,b){b=b||this.el;var c=0;return this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(c+=1),jQuery(b.children()[a+c])},redraw:function(b,c){b=b||[],c=c||[];for(var d=function(){jQuery.isEmptyObject(this.record.field_get(this.children_field))&&this.expander.css("visibility","hidden")},e=this.tree.thead.is(":visible"),f=0;f<this.tree.columns.length;f++){0===f&&this.children_field&&this.record.load(this.children_field).done(d.bind(this));var g,h=this.tree.columns[f],i=this._get_column_td(f),j=i.find("tr");if(h.prefixes)for(var k=0;k<h.prefixes.length;k++){var l=h.prefixes[k],m=jQuery(j.children(".prefix")[k]);g=m.children(),g.length?l.render(this.record,g):m.html(l.render(this.record))}var n=j.children(".widget");if(g=n.children(),g.length?h.render(this.record,g):n.html(h.render(this.record)),h.suffixes)for(var o=0;o<h.suffixes.length;o++){var p=h.suffixes[o],q=jQuery(j.children(".suffix")[o]);g=q.children(),g.length?p.render(this.record,g):q.html(p.render(this.record))}h.header.is(":hidden")&&e||"none"==h.header.css("display")?(i.hide(),i.addClass("invisible")):(i.show(),i.removeClass("invisible"))}var r=this.get_id_path();this.set_selection(Sao.common.contains(b,r)),this.is_expanded()||Sao.common.contains(c,r)?(this.tree.expanded[this.path]=this,!this.record._values[this.children_field]||this.record._values[this.children_field].length>0&&0===this.rows.length?this.expand_children(b,c):a(this.rows,b,c),this.expander&&this.update_expander(!0)):this.expander&&this.update_expander(!1),this.record.deleted()||this.record.removed()?this.el.css("text-decoration","line-through"):this.el.css("text-decoration","inherit")},toggle_row:function(){return this.is_expanded()?(this.update_expander(!1),delete this.tree.expanded[this.path],this.collapse_children()):(this.update_expander(!0),this.tree.expanded[this.path]=this,this.expand_children()),!1},update_expander:function(a){a?(this.expander.removeClass("glyphicon-plus"),this.expander.addClass("glyphicon-minus")):(this.expander.removeClass("glyphicon-minus"),this.expander.addClass("glyphicon-plus"))},collapse_children:function(){this.rows.forEach(function(a,b,c){a.collapse_children();var d=a.el[0];d.parentNode.removeChild(d)}),this.rows=[]},expand_children:function(b,c){var d=function(){if(jQuery.isEmptyObject(this.rows)){var d=[],e=function(a,e,f){var g=new this.Class(this.tree,a,e,this);g.construct(b,c),this.rows.push(g),d.push(g)};this.record.field_get_client(this.children_field).forEach(e.bind(this)),a(d,b,c)}};return this.record.load(this.children_field).done(d.bind(this))},switch_row:function(){window.getSelection?window.getSelection().empty?window.getSelection().empty():window.getSelection().removeAllRanges&&window.getSelection().removeAllRanges():document.selection&&document.selection.empty(),(this.tree.selection_mode==Sao.common.SELECTION_NONE||(this.set_selection(!0),this.selection_changed(),this.is_selected()))&&this.tree.switch_(this.path)},select_row:function(a){this.tree.selection_mode==Sao.common.SELECTION_NONE?(this.tree.select_changed(this.record),this.switch_row()):(a.ctrlKey||this.tree.selection_mode!=Sao.common.SELECTION_SINGLE||this.tree.rows.forEach(function(a){a.set_selection(!1)}.bind(this)),this.set_selection(!this.is_selected()),this.selection_changed());var b=a.data.td,c=a.data.column;b.on("click keypress",{column:c,td:b},Sao.common.click_press(this.select_row.bind(this),!0))},is_selected:function(){return this.tree.selection_mode!=Sao.common.SELECTION_NONE&&this.selection.prop("checked")},set_selection:function(a){this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(this.selection.prop("checked",a),a||this.tree.selection.prop("checked",!1))},selection_changed:function(){var a=this.is_selected();this.set_selection(a),a?this.tree.select_changed(this.record):this.tree.select_changed(this.tree.selected_records()[0]||null),this.tree.update_selection()},record_to_path:function(a){var b,c;if(a==this.record)return[];for(b=0;b<this.rows.length;b++)if(c=this.rows[b].record_to_path(a))return c.unshift(b),c},expand_to_path:function(a){var b,c;b=a[0],c=a.slice(1),c.length>0&&this.rows[b].expand_children().done(function(){this.rows[b].expand_to_path(c)}.bind(this))},next_column:function(a,b,c){var d,e,f,g,h,i;for(c=c||1,null===a&&c>0?a=-1:null===a&&(a=0),h=0,d=0;d<this.tree.columns.length;d++)if(h=(a+c*(d+1))%this.tree.columns.length,h<0&&(h+=this.tree.columns.length),g=this.tree.columns[h],i=g.field.get_state_attrs(this.record),f=i.invisible,g.header.is(":hidden")&&(f=!0),e=!!b&&(g.attributes.readonly||i.readonly),!f&&!e)return h}}),Sao.View.Tree.RowEditable=Sao.class_(Sao.View.Tree.Row,{init:function(a,b,c,d){Sao.View.Tree.RowEditable._super.init.call(this,a,b,c,d),this.edited_column=null},redraw:function(a,b){var c,d,e,f,g;for(Sao.View.Tree.RowEditable._super.redraw.call(this,a,b),c=0;c<this.tree.columns.length;c++)e=this._get_column_td(c),d=e.find("tr"),(f=jQuery(d.children(".widget-editable")).data("widget"))&&(g=this.record.model.fields[f.field_name],f.display(this.record,g))},select_row:function(a){function b(a,d){var e,f;for(e=0;e<a.length;e++)f=a[e],f.is_selected()&&(c=f),f!=d&&f.set_selection(!1),b(f.rows,d)}var c,d,e,f,g;b(this.tree.rows,this),this.selection_changed();var h;h=c&&c!=this&&!this.tree.screen.group.parent?c.record.save():jQuery.when(),h.done(function(){if(c&&null!==c.edited_column){d=c.get_active_td(),d.on("click keypress",{td:d,column:c.edited_column},Sao.common.click_press(c.select_row.bind(c),!0));var b=this.tree.columns[c.edited_column];c.get_static_el().html(b.render(c.record)).show(),c.empty_editable_el()}var h=this.is_selected(),i=a.data.column,j=this.tree.columns[i],k=j.field.get_state_attrs(this.record),l=j.attributes.readonly||k.readonly;if(h&&!l){this.edited_column=i,e=this.get_active_td();var m=j.attributes,n=Sao.View.editabletree_widget_get(m.widget);g=new n(m.name,this.tree.screen.model,m),g.view=this.tree,g.el.on("focusin",function(){jQuery(this).parents(".treeview td").css("overflow","visible")}),g.el.on("focusout",function(){jQuery(this).parents(".treeview td").css("overflow","hidden")});var o=this.get_editable_el();o.append(g.el),o.data("widget",g),g.el.on("keydown",this.key_press.bind(this)),f=this.record.model.fields[g.field_name],g.display(this.record,f),this.get_static_el().hide(),this.get_editable_el().show(),g.el.focus()}else if(!h){this.set_selection(!0),this.selection_changed();var p=a.data.td;p.on("click keypress",{column:i,td:p},Sao.common.click_press(this.select_row.bind(this),!0))}}.bind(this))},get_static_el:function(){return this.get_active_td().find(".widget")},get_editable_el:function(){var a=this.get_active_td(),b=a.find(".widget-editable");return b.length||(b=jQuery("<td/>",{class:"widget-editable"}).insertAfter(a.find(".widget"))),b},empty_editable_el:function(){var a;a=this.get_editable_el(),a.empty(),a.data("widget",null),this.edited_column=null},get_active_td:function(){return this._get_column_td(this.edited_column)},key_press:function(a){var b,c,d,e,f;if(a.which==Sao.common.TAB_KEYCODE||a.which==Sao.common.UP_KEYCODE||a.which==Sao.common.DOWN_KEYCODE||a.which==Sao.common.ESC_KEYCODE||a.which==Sao.common.RETURN_KEYCODE){if(this.tree.columns[this.edited_column].field.validate(this.record))if(a.which==Sao.common.TAB_KEYCODE){var g=1;a.shiftKey&&(g=-1),a.preventDefault(),d=this.next_column(this.edited_column,!0,g),null!==d&&window.setTimeout(function(){var a=this._get_column_td(d);a.triggerHandler("click",{column:d,td:a})}.bind(this),0)}else if(a.which==Sao.common.UP_KEYCODE||a.which==Sao.common.DOWN_KEYCODE)f=a.which==Sao.common.UP_KEYCODE?this.el.prev("tr"):this.el.next("tr"),c=this.edited_column,this.record.validate(this.tree.get_fields()).then(function(a){if(a){if(this.tree.screen.attributes.pre_validate)return this.record.pre_validate().fail(function(){f=null});if(!this.tree.screen.model.parent)return this.record.save().fail(function(){f=null})}else{f=null;var b=this.record.invalid_fields();for(e=0;e<this.tree.columns.length;e++){this.tree.columns[e].attributes.name in b&&(c=e)}}}.bind(this)).then(function(){window.setTimeout(function(){this._get_column_td(c,f).trigger("click").trigger("click")}.bind(this),0)}.bind(this));else if(a.which==Sao.common.ESC_KEYCODE)this.get_static_el().show(),b=this.get_active_td(),b.on("click keypress",{column:this.edited_column,td:b},Sao.common.click_press(this.select_row.bind(this),!0)),this.empty_editable_el();else if(a.which==Sao.common.RETURN_KEYCODE){var h=function(a){var b=this._get_column_td(this.edited_column,a);b.triggerHandler("click"),b.triggerHandler("click")}.bind(this);if(f="bottom"==this.tree.attributes.editable?this.el.next("tr"):this.el.prev("tr"),f.length)h(f);else{var i,j=this.tree.screen.group,k=Sao.common.MODELACCESS.get(this.tree.screen.model_name),l=null!==this.tree.screen.size_limit&&j.length>=this.tree.screen.size_limit;i=!k.create||l?jQuery.when():this.tree.screen.new_(),i.done(function(){var a,b=this.tree.tbody.children("tr");a="bottom"==this.tree.attributes.editable?b.last():b.first(),h(a)}.bind(this))}}}}}),Sao.View.Tree.Affix=Sao.class_(Object,{init:function(a,b){this.attributes=a,this.protocol=b||null,this.icon=a.icon,this.protocol&&!this.icon&&(this.icon="tryton-web-browser")},get_cell:function(){var a;return this.protocol?(a=jQuery("<a/>",{target:"_new"}),a.append(jQuery("<img/>")),a.click({cell:a},this.clicked.bind(this))):this.icon?a=jQuery("<img/>"):(a=jQuery("<span/>"),a.attr("tabindex",0)),a.addClass("column-affix"),a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){var c,d,e=a.model.fields[this.attributes.name];if(e.get_state_attrs(a).invisible?b.hide():b.show(),this.protocol){if(c=e.get(a),!jQuery.isEmptyObject(c))switch(this.protocol){case"email":c="mailto:"+c;break;case"callto":c="callto:"+c;break;case"sip":c="sip:"+c}b.attr("src",c)}if(this.icon){if(this.icon in a.model.fields){c=a.model.fields[this.icon].get_client(a)}else c=this.icon;d=Sao.common.ICONFACTORY.register_icon(c),d.done(function(a){var c;c=b.children("img").length?b.children("img"):b,c.attr("src",a)}.bind(this))}else c=this.attributes.string||"",c||(c=e.get_client(a)||""),b.text(c)}.bind(this)),b},clicked:function(a){a.preventDefault(),window.open(a.data.cell.attr("src"),"_blank")}}),Sao.View.Tree.CharColumn=Sao.class_(Object,{class_:"column-char",init:function(a,b){this.type="field",this.model=a,this.field=a.fields[b.name],this.attributes=b,this.prefixes=[],this.suffixes=[],this.header=null},get_cell:function(){return jQuery("<div/>",{class:this.class_,tabindex:0})},update_text:function(a,b){a.text(this.field.get_client(b))},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){this.update_text(b,a),this.field.set_state(a),this.field.get_state_attrs(a).invisible?b.hide():b.show()}.bind(this)),b}}),Sao.View.Tree.TextColum=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-text"}),Sao.View.Tree.IntegerColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-integer",init:function(a,b){Sao.View.Tree.IntegerColumn._super.init.call(this,a,b),this.factor=Number(b.factor||1)},get_cell:function(){return Sao.View.Tree.IntegerColumn._super.get_cell.call(this)},update_text:function(a,b){a.text(this.field.get_client(b,this.factor))}}),Sao.View.Tree.FloatColumn=Sao.class_(Sao.View.Tree.IntegerColumn,{class_:"column-float"}),Sao.View.Tree.BooleanColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-boolean",get_cell:function(){return jQuery("<input/>",{type:"checkbox",disabled:!0,class:this.class_,tabindex:0})},update_text:function(a,b){a.prop("checked",this.field.get(b))}}),Sao.View.Tree.Many2OneColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-many2one"}),Sao.View.Tree.One2OneColumn=Sao.class_(Sao.View.Tree.Many2OneColumn,{class_:"column-one2one"}),Sao.View.Tree.SelectionColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-selection",init:function(a,b){Sao.View.Tree.SelectionColumn._super.init.call(this,a,b),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a)},update_selection:function(a,b){Sao.common.selection_mixin.update_selection.call(this,a,this.field,b)},update_text:function(a,b){this.update_selection(b,function(){for(var c,d,e=this.field.get(b),f=!1,g=0,h=this.selection.length;g<h;g++)if(this.selection[g][0]===e){f=!0,d=this.selection[g][1];break}c=f?jQuery.when(d):Sao.common.selection_mixin.get_inactive_selection.call(this,e).then(function(a){return a[1]}),c.done(function(b){a.text(b)}.bind(this))}.bind(this))}}),Sao.View.Tree.ReferenceColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-reference",init:function(a,b){Sao.View.Tree.ReferenceColumn._super.init.call(this,a,b),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a)},update_selection:function(a,b){Sao.common.selection_mixin.update_selection.call(this,a,this.field,b)},update_text:function(a,b){this.update_selection(b,function(){var c,d,e=this.field.get_client(b);if(e?(c=e[0],d=e[1]):(c="",d=""),c){for(var f=0,g=this.selection.length;f<g;f++)if(this.selection[f][0]===c){c=this.selection[f][1];break}a.text(c+","+d)}else a.text(d)}.bind(this))}}),Sao.View.Tree.DateColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-date",update_text:function(a,b){var c=this.field.get_client(b),d=this.field.date_format(b);a.text(Sao.common.format_date(d,c))}}),Sao.View.Tree.TimeColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-time",update_text:function(a,b){var c=this.field.get_client(b);a.text(Sao.common.format_time(this.field.time_format(b),c))}}),Sao.View.Tree.TimeDeltaColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-timedelta"}),Sao.View.Tree.One2ManyColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-one2many",update_text:function(a,b){a.text("( "+this.field.get_client(b).length+" )")}}),Sao.View.Tree.Many2ManyColumn=Sao.class_(Sao.View.Tree.One2ManyColumn,{class_:"column-many2many"}),Sao.View.Tree.BinaryColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-binary",update_text:function(a,b){var c;c=this.field.get_size?this.field.get_size(b):this.field.get(b).length,a.text(Sao.common.humanize(c))}}),Sao.View.Tree.ImageColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-image",get_cell:function(){var a=jQuery("<img/>",{class:this.class_,tabindex:0});return a.css("width","100%"),a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){var c=this.field.get_client(a);c=c?c>Sao.common.BIG_IMAGE_SIZE?jQuery.when(null):this.field.get_data(a):jQuery.when(null),c.done(function(a){var c,d;a?(d=new Blob([a]),c=window.URL.createObjectURL(d)):c=null,b.attr("src",c)}.bind(this))}.bind(this)),b}}),Sao.View.Tree.URLColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-url",render:function(a,b){return b=Sao.View.Tree.URLColumn._super.render.call(this,a,b),this.field.set_state(a),this.field.get_state_attrs(a).readonly?b.hide():b.show(),b}}),Sao.View.Tree.ProgressBar=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-progressbar",get_cell:function(){var a=jQuery("<div/>",{class:this.class_+" progress",tabindex:0});return jQuery("<div/>",{class:"progress-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100}).appendTo(a).css("min-width: 2em"),a},update_text:function(a,b){var c=this.field.get_client(b,100);c&&(c=Sao.i18n.gettext("%1%",c));var d=this.field.get(b)||0,e=a.find(".progress-bar");e.attr("aria-valuenow",100*d),e.css("width",100*d+"%"),e.text(c)}}),Sao.View.Tree.ButtonColumn=Sao.class_(Object,{init:function(a,b){this.screen=a,this.type="button",this.attributes=b},render:function(a,b){var c=new Sao.common.Button(this.attributes,b);b||c.el.click([a,c],this.button_clicked.bind(this));var d=jQuery.map(this.screen.model.fields,function(a,b){return"eager"==(a.description.loading||"eager")?b:void 0});return a.load(d[0]).done(function(){c.set_state(a)}),c.el},button_clicked:function(a){var b=a.data[0],c=a.data[1];if(b==this.screen.current_record){
+var d=b.expr_eval(this.attributes.states||{});if(!d.invisible&&!d.readonly){c.el.prop("disabled",!0);try{this.screen.button(this.attributes)}finally{c.el.prop("disabled",!1)}}}}}),Sao.View.editabletree_widget_get=function(a){switch(a){case"char":case"text":case"url":case"email":case"callto":case"sip":return Sao.View.EditableTree.Char;case"date":return Sao.View.EditableTree.Date;case"time":return Sao.View.EditableTree.Time;case"timedelta":return Sao.View.EditableTree.TimeDelta;case"integer":case"biginteger":return Sao.View.EditableTree.Integer;case"float":case"numeric":return Sao.View.EditableTree.Float;case"selection":return Sao.View.EditableTree.Selection;case"boolean":return Sao.View.EditableTree.Boolean;case"many2one":return Sao.View.EditableTree.Many2One;case"reference":return Sao.View.EditableTree.Reference;case"one2one":return Sao.View.EditableTree.One2One;case"one2many":case"many2many":return Sao.View.EditableTree.One2Many;case"binary":return Sao.View.EditableTree.Binary}},Sao.View.EditableTree={},Sao.View.EditableTree.editable_mixin=function(a){var b=function(a){a.which!=Sao.common.TAB_KEYCODE&&a.which!=Sao.common.UP_KEYCODE&&a.which!=Sao.common.DOWN_KEYCODE&&a.which!=Sao.common.ESC_KEYCODE&&a.which!=Sao.common.RETURN_KEYCODE||this.focus_out()};a.el.on("keydown",b.bind(a))},Sao.View.EditableTree.Char=Sao.class_(Sao.View.Form.Char,{class_:"editabletree-char",init:function(a,b,c){Sao.View.EditableTree.Char._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Date=Sao.class_(Sao.View.Form.Date,{class_:"editabletree-date",init:function(a,b,c){Sao.View.EditableTree.Date._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Time=Sao.class_(Sao.View.Form.Time,{class_:"editabletree-time",init:function(a,b,c){Sao.View.EditableTree.Time._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.TimeDelta=Sao.class_(Sao.View.Form.TimeDelta,{class_:"editabletree-timedelta",init:function(a,b,c){Sao.View.EditableTree.TimeDelta._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Integer=Sao.class_(Sao.View.Form.Integer,{class_:"editabletree-integer",init:function(a,b,c){Sao.View.EditableTree.Integer._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Float=Sao.class_(Sao.View.Form.Float,{class_:"editabletree-float",init:function(a,b,c){Sao.View.EditableTree.Float._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Selection=Sao.class_(Sao.View.Form.Selection,{class_:"editabletree-selection",init:function(a,b,c){Sao.View.EditableTree.Selection._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Boolean=Sao.class_(Sao.View.Form.Boolean,{class_:"editabletree-boolean",init:function(a,b,c){Sao.View.EditableTree.Boolean._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Many2One=Sao.class_(Sao.View.Form.Many2One,{class_:"editabletree-many2one",init:function(a,b,c){Sao.View.EditableTree.Many2One._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.Many2One._super.key_press.call(this,a)}}),Sao.View.EditableTree.Reference=Sao.class_(Sao.View.Form.Reference,{class_:"editabletree-reference",init:function(a,b,c){Sao.View.EditableTree.Reference._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.Reference._super.key_press.call(this,a)}}),Sao.View.EditableTree.One2One=Sao.class_(Sao.View.Form.One2One,{class_:"editabletree-one2one",init:function(a,b,c){Sao.View.EditableTree.One2One._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.One2One._super.key_press.call(this,a)}}),Sao.View.EditableTree.One2Many=Sao.class_(Sao.View.EditableTree.Char,{class_:"editabletree-one2many",init:function(a,b,c){Sao.View.EditableTree.One2Many._super.init.call(this,a,b,c)},display:function(a,b){a?this.el.val("("+b.get_client(a).length+")"):this.el.val("")},key_press:function(a){a.which==Sao.common.TAB_KEYCODE&&this.focus_out()},set_value:function(a,b){}}),Sao.View.EditableTree.Binary=Sao.class_(Sao.View.Form.Binary,{class_:"editabletree-binary",init:function(a,b,c){Sao.View.EditableTree.Binary._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}})}(),function(){"use strict";Sao.View.Graph=Sao.class_(Sao.View,{init:function(a,b){Sao.View.Graph._super.init.call(this,a,b),this.view_type="graph",this.el=jQuery("<div/>",{class:"graph"}),this.widgets={},this.widget=this.parse(b.children()[0]),this.widgets.root=this.widget,this.el.append(this.widget.el)},parse:function(a){var b,c,d,e,f,g,h,i=null,j=[],k=function(a){for(var b,c={},d=0,e=a.attributes.length;d<e;d++)b=a.attributes[d],c[b.name]=b.value;return c};for(e=0,f=a.children.length;e<f;e++)switch(d=a.children[e],d.tagName){case"x":for(g=0,h=d.children.length;g<h;g++)i=k(d.children[g]),b=this.screen.model.fields[i.name],i.type=b.description.type,i.string||(i.string=b.description.string);break;case"y":for(g=0,h=d.children.length;g<h;g++)c=k(d.children[g]),c.string||"#"==c.name||(b=this.screen.model.fields[c.name],c.string=b.description.string),j.push(c)}var l;switch(this.attributes.type){case"hbar":l=Sao.View.Graph.HorizontalBar;break;case"line":l=Sao.View.Graph.Line;break;case"pie":l=Sao.View.Graph.Pie;break;default:l=Sao.View.Graph.VerticalBar}return new l(this,i,j)},display:function(){return this.widget.display(this.screen.group)}}),Sao.View.Graph.Chart=Sao.class_(Object,{_chart_type:void 0,init:function(a,b,c){this.view=a,this.xfield=b,this.yfields=c,this.el=jQuery("<div/>"),this.el.uniqueId()},update_data:function(a){var b,c,d,e,f,g,h,i={};this.ids={},i.columns=[["labels"]],i.names={};var j={},k=[this.xfield.name];for(e=0,f=this.yfields.length;e<f;e++)c=this.yfields[e],i.columns.push([c.name]),i.names[c.name]=c.string,j[c.key||c.name]=e+1,k.push(c.name);var l=[],m=function(e){return function(){b=a[e];var f=b.field_get_client(this.xfield.name);f&&(f.isDate||f.isDateTime)&&(f=f.toDate()),i.columns[0][e+1]=f,this._add_id(f,b.id);var k;for(g=0,h=this.yfields.length;g<h;g++){if(c=this.yfields[g],d=c.key||c.name,k=i.columns[j[d]],c.domain){var l=jQuery.extend({},Sao.session.current_session.context);l.context=l,l._user=Sao.session.current_session.user_id;for(var m in a.model.fields)l[m]=b.field_get(m);if(!new Sao.PYSON.Decoder(l).decode(c.domain)){k[e+1]=0;continue}}if("#"==c.name)k[e+1]=1;else{var n=b.field_get(c.name);n&&n.isTimeDelta&&(n=n.asSeconds()),k[e+1]=n||0}}}.bind(this)}.bind(this),n=function(a){return function(b){l.push(a.load(b))}},o=[];for(e=0,f=a.length;e<f;e++){for(b=a[e],k.forEach(n(a[e])),g=0,h=i.columns.length;g<h;g++)i.columns[g].push(void 0);o.push(jQuery.when.apply(jQuery,l).then(m(e)))}return jQuery.when.apply(jQuery,o).then(function(){return i})},_add_id:function(a,b){a in this.ids||(this.ids[a]=[]),this.ids[a].push(b)},display:function(a){var b=this.update_data(a);return b.done(function(a){c3.generate(this._c3_config(a))}.bind(this)),b},_c3_config:function(a){var b={};b.bindto="#"+this.el.attr("id"),b.data=a,b.data.type=this._chart_type,b.data.x="labels",b.data.onclick=this.action.bind(this);var c=this.xfield.type;if("date"==c||"datetime"==c){var d,e,f;e=this.view.screen.context.date_format||"%x",f="%X",d="datetime"==c?function(a){return Sao.common.format_datetime(e,f,moment(a))}:function(a){return Sao.common.format_date(e,moment(a))},b.axis={x:{type:"timeseries",tick:{format:d}}}}else b.axis={x:{type:"category"}};for(var g={},h=0;h<this.yfields.length;h++){var i=this.yfields[h];i.color&&(g[i.name]=i.color)}return b.data.color=function(a,b){var c=b.id||b;return g[c]||a},b},action:function(a,b){var c=this.ids[this._action_key(a)],d=jQuery.extend({},this.view.screen.context);delete d.active_ids,delete d.active_id,Sao.Action.exec_keyword("graph_open",{model:this.view.screen.model_name,id:c[0],ids:c},d,!1)},_action_key:function(a){return a.x}}),Sao.View.Graph.VerticalBar=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"bar"}),Sao.View.Graph.HorizontalBar=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"bar",_c3_config:function(a){Sao.View.Graph.HorizontalBar._super._c3_config.call(this,a).axis.rotated=!0}}),Sao.View.Graph.Line=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"line"}),Sao.View.Graph.Pie=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"pie",_c3_config:function(a){var b,c,d,e,f=Sao.View.Graph.Pie._super._c3_config.call(this,a),g=[],h={};for(b=0,c=a.columns.length;b<c;b++)"labels"==a.columns[b][0]?d=a.columns[b].slice(1):e=a.columns[b].slice(1);delete f.axis,delete f.data.x;var i,j=this.xfield.type;if("date"==j||"datetime"==j){var k=this.view.screen.context.date_format||"%x",l=k+" %X";i="datetime"==j?function(a){return Sao.common.format_datetime(l,a)}:function(a){return Sao.common.format_date(k,a)}}var m;for(b=0,c=d.length;b<c;b++)m=d[b],i&&(m=i(m)),g.push([b,e[b]]),h[b]=m;return f.data.columns=g,f.data.names=h,f},_add_id:function(a,b){var c=this.xfield.type;if("date"==c||"datetime"==c){var d=this.view.screen.context.date_format||"%x",e=d+" %X";a="datetime"==c?Sao.common.format_datetime(e,a):Sao.common.format_date(d,a)}Sao.View.Graph.Pie._super._add_id.call(this,a,b)},_action_key:function(a){return a.id}})}(),function(){"use strict";Sao.View.Calendar=Sao.class_(Sao.View,{init:function(a,b){Sao.View.Calendar._super.init.call(this,a,b),this.processing=!0,this.view_type="calendar",this.el=jQuery("<div/>",{class:"calendar"});var c=Sao.i18n.getlang();c=c.slice(0,2);var d="month";"week"==this.attributes.mode&&(d=this.get_week_view()),this.el.fullCalendar({defaultView:d,header:{left:"prev,next",center:"title",right:" month,"+this.get_week_view()},timeFormat:"H:mm",events:this.get_events.bind(this),locale:c,buttonIcons:!1,eventRender:this.event_render.bind(this),eventResize:this.event_resize.bind(this),eventDrop:this.event_drop.bind(this),eventClick:this.event_click.bind(this),dayClick:this.day_click.bind(this)}),this.fields=[],b.find("calendar").children().each(function(a,b){"field"==b.tagName&&this.fields.push(b.attributes.name.value)}.bind(this)),this.el.fullCalendar("changeView",d)},get_colors:function(a){var b={};return b.text_color="black",this.attributes.color&&(b.text_color=a.field_get(this.attributes.color)),b.background_color="lightblue",this.attributes.background_color&&(b.background_color=a.field_get(this.attributes.background_color)),b},display:function(){this.el.fullCalendar("render"),this.processing||this.el.fullCalendar("refetchEvents")},insert_event:function(a){var b=this.screen.model.fields[this.fields[0]].get_client(a),c=a.field_get_client(this.attributes.dtstart),d=null;this.attributes.dtend&&(d=a.field_get_client(this.attributes.dtend));for(var e=!0,f=[],g=1;g<this.fields.length;g++)f.push(this.screen.model.fields[this.fields[g]].get_client(a));if(f=f.join("\n"),c){if(d&&d.isDateTime?e=!1:d&&!d.isSame(c)&&"calendar"==this.screen.current_view.view_type&&d.add(1,"day"),d&&c>d)return;var h=this.get_colors(a),i={title:b,start:c,end:d,allDay:e,editable:!0,color:h.background_color,textColor:h.text_color,record:a,description:f};this.events.push(i)}},get_events:function(a,b,c,d){this.processing=!0,this.start=Sao.DateTime(a.utc()),this.end=Sao.DateTime(b.utc());var e=jQuery.when();if("form"!=this.screen.current_view.view_type){var f=this.screen.screen_container.get_text();e=this.screen.search_filter(f)}this.events=[];var g=[];e.then(function(){return this.screen.group.forEach(function(a){var b=[];this.fields.forEach(function(c){b.push(a.load(c))});var c=jQuery.when.apply(jQuery,b).then(function(){this.insert_event(a)}.bind(this));g.push(c)}.bind(this)),jQuery.when.apply(jQuery,g).then(function(){d(this.events)}.bind(this)).always(function(){this.processing=!1}.bind(this))}.bind(this))},get_week_view:function(){return"datetime"==this.screen.model.fields[this.attributes.dtstart].description.type?"agendaWeek":"basicWeek"},event_click:function(a,b,c){this.clicked_event||(this.clicked_event=!0,this.screen.set_current_record(a.record),this.screen.switch_view().always(function(){this.clicked_event=!1}.bind(this)))},event_drop:function(a,b,c,d,e,f){var g=this.attributes.dtstart,h=this.attributes.dtend,i=a.record,j=(i.group,i.field_get(g)),k=j;h&&(k=i.field_get(h));var l=a.start,m=a.end;m!=j&&m||(m=l),j.isDateTime?(m=Sao.DateTime(m.format()).utc(),l=Sao.DateTime(l.format()).utc()):j.isSame(k)||(m.subtract(1,"day"),this.el.fullCalendar("refetchEvents")),j<=l?(h&&i.field_set_client(h,m),i.field_set_client(g,l)):(i.field_set_client(g,l),h&&i.field_set_client(h,m)),i.save()},event_resize:function(a,b,c,d,e,f){var g=this.attributes.dtend,h=a.record,i=(h.group,h.field_get(g)),j=a.end;!0===i.isDateTime?j=Sao.DateTime(j.format()).utc():(j.subtract(1,"day"),this.el.fullCalendar("refetchEvents")),j!=i&&j||(j=i),h.field_set_client(g,j),h.save()},event_render:function(a,b,c){this.screen.model.fields.date&&"calendar"==this.screen.view_name&&b.find(".fc-time").remove(),b.append(a.description),b.css("white-space","pre"),Sao.common.MODELACCESS.get(this.screen.model_name).write||(a.editable=!1)},day_click:function(a,b,c){Sao.common.MODELACCESS.get(this.screen.model_name).create&&(this.el.fullCalendar("gotoDate",a),this.screen.set_current_record(null),this.screen.new_())},current_domain:function(){if(!this.start&&!this.end)return[["id","=",-1]];var a=Sao.DateTime(this.start),b=Sao.DateTime(this.end),c=this.attributes.dtstart,d=this.attributes.dtend||c;return["OR",["AND",[c,">=",a],[c,"<",b]],["AND",[d,">=",a],[d,"<",b]],["AND",[c,"<",a],[d,">",b]]]},get_displayed_period:function(){var a=[];return this.start&&this.end&&a.push(this.start,this.end),a},set_default_date:function(a,b){var c=this.attributes.dtstart;a.field_set(c,b)},get_selected_date:function(){return this.el.fullCalendar("getDate")}})}(),function(){"use strict";Sao.Action={report_blob_url:void 0},Sao.Action.exec_action=function(a,b,c){function d(a){if(!b.model||!b.ids)return jQuery.when(a);var d=5,e=b.ids.slice(0,d);return Sao.rpc({method:"model."+b.model+".read",params:[e,["rec_name"],c]},Sao.Session.current_session).then(function(c){var e=c.map(function(a){return a.rec_name}).join(Sao.i18n.gettext(", "));return b.ids.length>d&&(e+=Sao.i18n.gettext(",…")),Sao.i18n.gettext("%1 (%2)",a,e)})}c=void 0===c?{}:jQuery.extend({},c);var e=Sao.Session.current_session;"date_format"in c||e.context.locale&&e.context.locale.date&&(c.date_format=e.context.locale.date),b=void 0===b?{}:jQuery.extend({},b),b.action_id=a.id;var f,g={};switch(a.type){case"ir.action.act_window":g.view_ids=[],g.mode=null,jQuery.isEmptyObject(a.views)?jQuery.isEmptyObject(a.view_id)||(g.view_ids=[a.view_id[0]]):(g.view_ids=[],g.mode=[],a.views.forEach(function(a){g.view_ids.push(a[0]),g.mode.push(a[1])})),void 0===a.pyson_domain&&(a.pyson_domain="[]");var h={active_model:b.model||null,active_id:b.id||null,active_ids:b.ids};h=jQuery.extend(h,e.context),h._user=e.user_id;var i=new Sao.PYSON.Decoder(h);return g.context=jQuery.extend({},c,i.decode(a.pyson_context||"{}")),h=jQuery.extend(h,g.context),h=jQuery.extend(h,c),h.context=h,i=new Sao.PYSON.Decoder(h),g.domain=i.decode(a.pyson_domain),g.order=i.decode(a.pyson_order),g.search_value=i.decode(a.pyson_search_value||"[]"),g.tab_domain=[],a.domains.forEach(function(a,b){g.tab_domain.push([a[0],i.decode(a[1]),a[2]])}),f=jQuery.when(a.name),g.model=a.res_model||b.res_model,g.res_id=a.res_id||b.res_id,g.context_model=a.context_model,g.context_domain=a.context_domain,g.limit=a.limit,g.icon=a["icon.rec_name"]||"","form_relate"===(a.keyword||"")&&(f=d(a.name)),void f.then(function(a){g.name=a,Sao.Tab.create(g)});case"ir.action.wizard":return g.action=a.wiz_name,g.data=b,g.context=c,g.window=a.window,f=jQuery.when(a.name),"form_action"===(a.keyword||"form_action")&&(f=d(a.name)),void f.done(function(a){g.name=a,Sao.Wizard.create(g)});case"ir.action.report":return g.name=a.report_name,g.data=b,g.direct_print=a.direct_print,g.email_print=a.email_print,g.email=a.email,g.context=c,void Sao.Action.exec_report(g);case"ir.action.url":return void window.open(a.url,"_blank")}},Sao.Action.exec_keyword=function(a,b,c,d,e){void 0===d&&(d=!0),void 0===e&&(e=!1);var f=b.id,g={method:"model.ir.action.keyword.get_keyword",params:[a,[b.model,f],{}]},h=Sao.rpc(g,Sao.Session.current_session),i=function(a){var f={};for(var g in a){var h=a[g];f[h.name.replace(/_/g,"")]=h}return Sao.common.selection(Sao.i18n.gettext("Select your action"),f,e).then(function(a){Sao.Action.exec_action(a,b,c)},function(){jQuery.isEmptyObject(f)&&d&&alert(Sao.i18n.gettext("No action defined."))})};return h.pipe(i)},Sao.Action.exec_report=function(a){a.context||(a.context={}),a.email||(a.email={});var b=jQuery.extend({},a.data),c=jQuery.extend({},Sao.Session.current_session.context);jQuery.extend(c,a.context),c.direct_print=a.direct_print,c.email_print=a.email_print,c.email=a.email,Sao.rpc({method:"report."+a.name+".execute",params:[b.ids||[],b,c]},Sao.Session.current_session).done(function(a){var b=a[0],c=a[1],d=(a[2],a[3]),e=d+"."+b;Sao.common.download_file(c,e)})},Sao.Action.execute=function(a,b,c,d,e){c?Sao.rpc({method:"model."+c+".search_read",params:[[["action","=",a]],0,1,null,null,d]},Sao.Session.current_session).done(function(a){var f=a[0];if(e){var g={"ir.action.report":"form_report","ir.action.wizard":"form_action","ir.action.act_window":"form_relate"};f.keyword||(f.keyword=g[c])}Sao.Action.exec_action(f,b,d)}):Sao.rpc({method:"model.ir.action.read",params:[[a],["type"],d]},Sao.Session.current_session).done(function(c){Sao.Action.execute(a,b,c[0].type,d,e)})},Sao.Action.evaluate=function(a,b,c){a=jQuery.extend({},a);var d={};return"pyson_email"in a&&(d=c.expr_eval(a.pyson_email),jQuery.isEmptyObject(d)&&(d={})),"subject"in d||(d.subject=a.name.replace(/_/g,"")),a.email=d,a}}(),function(){"use strict";Sao.common={},Sao.common.BACKSPACE_KEYCODE=8,Sao.common.TAB_KEYCODE=9,Sao.common.RETURN_KEYCODE=13,Sao.common.ESC_KEYCODE=27,Sao.common.UP_KEYCODE=38,Sao.common.DOWN_KEYCODE=40,Sao.common.DELETE_KEYCODE=46,Sao.common.F2_KEYCODE=113,Sao.common.F3_KEYCODE=114,Sao.common.SELECTION_NONE=1,Sao.common.SELECTION_SINGLE=2,Sao.common.SELECTION_MULTIPLE=3,Sao.common.BIG_IMAGE_SIZE=Math.pow(10,6),Sao.common.compare=function(a,b){if(a.length!=b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]instanceof Array&&b[c]instanceof Array){if(!Sao.common.compare(a[c],b[c]))return!1}else if(a[c]!=b[c])return!1;return!0},Sao.common.contains=function(a,b){for(var c=0;c<a.length;c++)if(Sao.common.compare(a[c],b))return!0;return!1},Sao.common.intersect=function(a,b){for(var c=0,d=0,e=[];c<a.length&&d<b.length;)a[c]<b[d]?c++:a[c]>b[d]?d++:(e.push(a[c]),c++,d++);return e},Sao.common.click_press=function(a,b){return function c(d){if("keypress"!=d.type||d.which==Sao.common.RETURN_KEYCODE)return b&&jQuery(this).off("click keypress",null,c),a(d)}},Sao.common.product=function(a,b){b=b||1;for(var c=[],d=0;d<b;)c=c.concat(a),d++;var e=[[]];return c.forEach(function(a){var b=[];e.forEach(function(c){a.forEach(function(a){b.push(c.concat([a]))})}),e=b}),e},Sao.common.selection=function(a,b,c){void 0===c&&(c=!1);var d=jQuery.Deferred();if(jQuery.isEmptyObject(b))return d.fail(),d;var e=Object.keys(b).sort();if(1==e.length&&!c){var f=e[0];return d.resolve(b[f]),d}var g=new Sao.Dialog(a||Sao.i18n.gettext("Your selection:"),"selection-dialog");return e.forEach(function(a,b){jQuery("<div/>",{class:"checkbox"}).append(jQuery("<label/>").append(jQuery("<input/>",{type:"radio",name:"selection",value:b})).append(" "+a)).appendTo(g.body)}),g.body.find("input").first().prop("checked",!0),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){g.modal.modal("hide"),d.fail()}).appendTo(g.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){var a=g.body.find("input:checked").attr("value");g.modal.modal("hide"),d.resolve(b[e[a]])}).appendTo(g.footer),g.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),g.modal.modal("show"),d},Sao.common.moment_format=function(a){return a.replace("%a","ddd").replace("%A","dddd").replace("%w","d").replace("%d","DD").replace("%b","MMM").replace("%B","MMMM").replace("%m","MM").replace("%y","YY").replace("%Y","YYYY").replace("%H","HH").replace("%I","hh").replace("%p","A").replace("%M","mm").replace("%S","ss").replace("%f","SSS").replace("%z","ZZ").replace("%Z","zz").replace("%j","DDDD").replace("%U","ww").replace("%W","WW").replace("%c","llll").replace("%x","L").replace("%X","LTS").replace("%","%%")},Sao.common.date_format=function(a){if(jQuery.isEmptyObject(a)&&(a="%Y-%m-%d",Sao.Session.current_session)){var b=Sao.Session.current_session.context;b.locale&&b.locale.date&&(a=b.locale.date)}return Sao.common.moment_format(a)},Sao.common.format_time=function(a,b){return b?b.format(Sao.common.moment_format(a)):""},Sao.common.parse_time=function(a,b){if(jQuery.isEmptyObject(b))return null;var c=function(c){var d=a.indexOf(c);if(~d){var e=parseInt(b.slice(d,d+c.length),10);if(!isNaN(e))return e}return 0};return Sao.Time(c("%H"),c("%M"),c("%S"),c("%f"))},Sao.common.format_date=function(a,b){return b?b.format(Sao.common.moment_format(a)):""},Sao.common.parse_date=function(a,b){var c=moment(b,Sao.common.moment_format(a));return c=c.isValid()?Sao.Date(c.year(),c.month(),c.date()):null},Sao.common.format_datetime=function(a,b,c){return c?c.format(Sao.common.moment_format(a+" "+b)):""},Sao.common.parse_datetime=function(a,b,c){var d=moment(c,Sao.common.moment_format(a+" "+b));return d=d.isValid()?Sao.DateTime(d.year(),d.month(),d.date(),d.hour(),d.minute(),d.second(),d.millisecond()):null},Sao.common.timedelta={},Sao.common.timedelta.DEFAULT_CONVERTER={s:1},Sao.common.timedelta.DEFAULT_CONVERTER.m=60*Sao.common.timedelta.DEFAULT_CONVERTER.s,Sao.common.timedelta.DEFAULT_CONVERTER.h=60*Sao.common.timedelta.DEFAULT_CONVERTER.m,Sao.common.timedelta.DEFAULT_CONVERTER.d=24*Sao.common.timedelta.DEFAULT_CONVERTER.h,Sao.common.timedelta.DEFAULT_CONVERTER.w=7*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta.DEFAULT_CONVERTER.M=30*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta.DEFAULT_CONVERTER.Y=365*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta._get_separator=function(){return{Y:Sao.i18n.gettext("Y"),M:Sao.i18n.gettext("M"),w:Sao.i18n.gettext("w"),d:Sao.i18n.gettext("d"),h:Sao.i18n.gettext("h"),m:Sao.i18n.gettext("m"),s:Sao.i18n.gettext("s")}},Sao.common.timedelta.format=function(a,b){if(!a)return"";b||(b=Sao.common.timedelta.DEFAULT_CONVERTER);var c=[];a=a.asSeconds();var d="";a<0&&(d="-"),a=Math.abs(a),b=Object.keys(b).map(function(a){return[a,b[a]]}),b.sort(function(a,b){return b[1]-a[1]});for(var e,f,g=[],h=0;h<b.length;h++){e=b[h][0],f=b[h][1];var i=Math.floor(a/f);a-=i*f,g.push(i)}for(h=0;h<b.length-3;h++)e=b[h][0],(f=g[h])&&c.push(f+Sao.common.timedelta._get_separator()[e]);if(jQuery(g.slice(-3)).is(function(a,b){return b})||jQuery.isEmptyObject(c)){var j=g.slice(-3,-1);j=("00"+j[0]).slice(-2)+":"+("00"+j[1]).slice(-2),(g.slice(-1)[0]||a)&&(j+=":"+("00"+g.slice(-1)[0]).slice(-2)),c.push(j)}return c=d+c.reduce(function(a,b){return a?a+" "+b:b}),a&&(jQuery(g.slice(-3)).is(function(a,b){return b})||(c+=" "),c+=(""+a.toFixed(6)).slice(1)),c},Sao.common.timedelta.parse=function(a,b){if(!a)return null;b||(b=Sao.common.timedelta.DEFAULT_CONVERTER);var c,d=Sao.common.timedelta._get_separator();for(var e in d)c=d[e],a=a.replace(c,c+" ");for(var f,g=0,h=a.split(" "),i=0;i<h.length;i++){var j=h[i];if(j.contains(":"))for(var k=j.split(":"),l=[b.h,b.m,b.s],m=0;m<Math.min(k.length,l.length);m++){var n=k[m],o=l[m];f=Math.abs(Number(n))*o,isNaN(f)||(g+=f)}else{var p=!1;for(var q in d)if(c=d[q],j.endsWith(c)){j=j.slice(0,-c.length),f=Math.abs(parseInt(j,10))*b[q],isNaN(f)||(g+=f),p=!0;break}p||(f=Math.abs(Number(j)),isNaN(f)||(g+=f))}}return a.contains("-")&&(g*=-1),Sao.TimeDelta(null,g)},Sao.common.ModelAccess=Sao.class_(Object,{init:function(){this.batchnum=100,this._access={}},load_models:function(a){var b=jQuery.Deferred();return a||(this._access={}),Sao.rpc({method:"model.ir.model.list_models",params:[{}]},Sao.Session.current_session).then(function(a){for(var c=[],d=function(a){this._access=jQuery.extend(this._access,a)},e=0;e<a.length;e+=this.batchnum){var f=a.slice(e,e+this.batchnum);c.push(Sao.rpc({method:"model.ir.model.access.get_access",params:[f,{}]},Sao.Session.current_session).then(d.bind(this)))}jQuery.when.apply(jQuery,c).then(b.resolve,b.reject)}.bind(this)),b},get:function(a){return this._access[a]||{}}}),Sao.common.MODELACCESS=new Sao.common.ModelAccess,Sao.common.ModelHistory=Sao.class_(Object,{init:function(){this._models=[]},load_history:function(){return this._models=[],Sao.rpc({method:"model.ir.model.list_history",params:[{}]},Sao.Session.current_session).then(function(a){this._models=a}.bind(this))},contains:function(a){return~this._models.indexOf(a)}}),Sao.common.MODELHISTORY=new Sao.common.ModelHistory,Sao.common.ViewSearch=Sao.class_(Object,{load_searches:function(){return this.searches={},Sao.rpc({method:"model.ir.ui.view_search.get_search",params:[{}]},Sao.Session.current_session).then(function(a){this.searches=a}.bind(this))},get:function(a){return this.searches[a]||[]},add:function(a,b,c){return Sao.rpc({method:"model.ir.ui.view_search.create",params:[[{model:a,name:b,domain:(new Sao.PYSON.Encoder).encode(c)}],{}]},Sao.Session.current_session).then(function(d){var e=d[0];void 0===this.searches[a]&&(this.searches[a]=[]),this.searches[a].push([e,b,c])}.bind(this))},remove:function(a,b){return Sao.rpc({method:"model.ir.ui.view_search.delete",params:[[b],{}]},Sao.Session.current_session).then(function(){for(var c=0;c<this.searches[a].length;c++){if(this.searches[a][c][0]===b){this.searches[a].splice(c,1);break}}}.bind(this))}}),Sao.common.VIEW_SEARCH=new Sao.common.ViewSearch,Sao.common.humanize=function(a){for(var b=["bytes","KB","MB","GB","TB","PB"],c=0,d=b.length;c<d;c++){if(a<1e3)return a.toPrecision(4)+" "+b[c];a/=1e3}},Sao.common.EvalEnvironment=function(a,b){void 0===b&&(b="eval");var c;if("eval"==b)c=a.get_eval();else{c={};for(var d in a.model.fields){var e=a.model.fields[d];c[d]=e.get_on_change_value(a)}}return c.id=a.id,a.group.parent&&Object.defineProperty(c,"_parent_"+a.group.parent_name,{enumerable:!0,get:function(){return Sao.common.EvalEnvironment(a.group.parent,b)}}),c.get=function(a,b){return this.hasOwnProperty(a)?this[a]:b},c},Sao.common.selection_mixin={},Sao.common.selection_mixin.init=function(){this.selection=null,this.inactive_selection=[],this._last_domain=null,this._values2selection={},this._domain_cache={},void 0===this.nullable_widget&&(this.nullable_widget=!0)},Sao.common.selection_mixin.init_selection=function(a,b){a||(a={},(this.attributes.selection_change_with||[]).forEach(function(b){a[b]=null}));var c,d=JSON.stringify(a),e=this.attributes.selection||[],f=function(a){a=jQuery.extend([],a),(void 0===this.attributes.sort||this.attributes.sort)&&a.sort(function(a,b){return a[1].localeCompare(b[1])}),this.selection=jQuery.extend([],a),b&&b(this.selection)};e instanceof Array||d in this._values2selection?(d in this._values2selection&&(e=this._values2selection[d]),f.call(this,e),c=jQuery.when()):(c=jQuery.isEmptyObject(this.attributes.selection_change_with)?this.model.execute(e,[]):this.model.execute(e,[a]),c=c.then(function(a){return this._values2selection[d]=a,a}.bind(this)),c=c.then(f.bind(this))),this.inactive_selection=[],this._selection_prm=c},Sao.common.selection_mixin.update_selection=function(a,b,c){var d=function(){if(!b)return void(c&&c(this.selection));var d=b.get_domain(a);if("reference"==b.description.type&&(d=[]),"relation"in this.attributes){var e=b.get_context(a),f=JSON.stringify([d,e]);if(f in this._domain_cache&&(this.selection=this._domain_cache[f],this._last_domain=[d,e]),null!==this._last_domain&&Sao.common.compare(d,this._last_domain[0])&&JSON.stringify(e)==JSON.stringify(this._last_domain[1]))return void(c&&c(this.selection));var g=Sao.rpc({method:"model."+this.attributes.relation+".search_read",params:[d,0,null,null,["rec_name"],e]},a.model.session);g.done(function(a){var b=[];a.forEach(function(a){b.push([a.id,a.rec_name])}),this.nullable_widget&&b.push([null,""]),this._last_domain=d,this._domain_cache[f]=b,this.selection=jQuery.extend([],b),c&&c(this.selection)}.bind(this)),g.fail(function(){this._last_domain=null,this.selection=[],c&&c(this.selection)}.bind(this))}else{var h=this.attributes.selection_change_with||[],i=a._get_on_change_args(h);delete i.id,Sao.common.selection_mixin.init_selection.call(this,i,function(){Sao.common.selection_mixin.filter_selection.call(this,d,a,b),c&&c(this.selection)}.bind(this))}};this._selection_prm.done(d.bind(this))},Sao.common.selection_mixin.filter_selection=function(a,b,c){if(!jQuery.isEmptyObject(a)){var d=new Sao.common.DomainInversion;this.selection=this.selection.filter(function(b){var c={};return c[this.field_name]=b[0],d.eval_domain(a,c)}.bind(this))}},Sao.common.selection_mixin.get_inactive_selection=function(a){if(!this.attributes.relation)return jQuery.when([]);for(var b=0,c=this.inactive_selection.length;b<c;b++)if(a==this.inactive_selection[b][0])return jQuery.when(this.inactive_selection[b]);return Sao.rpc({method:"model."+this.attributes.relation+".read",params:[[a],["rec_name"],{}]},Sao.Session.current_session).then(function(a){return this.inactive_selection.push([a[0].id,a[0].rec_name]),[a[0].id,a[0].rec_name]}.bind(this))},Sao.common.Button=Sao.class_(Object,{init:function(a,b){this.attributes=a,b?this.el=b:(this.el=jQuery("<button/>"),this.el.append(a.string||""),this.attributes.rule&&this.el.append(" ").append(jQuery("<span/>",{class:"badge"}))),this.icon=this.el.children("img"),this.icon.length||(this.icon=jQuery("<img/>").prependTo(this.el),this.icon.hide()),this.el.addClass("btn btn-default"),this.el.attr("type","button"),this.icon.addClass("icon"),this.icon.attr("aria-hidden",!0),this.set_icon(a.icon)},set_icon:function(a){if(!a)return this.icon.attr("src",""),void this.icon.hide();Sao.common.ICONFACTORY.register_icon(a).done(function(a){this.icon.attr("src",a),this.icon.show()}.bind(this))},set_state:function(a){var b;if(b=a?a.expr_eval(this.attributes.states||{}):{},b.invisible?this.el.hide():this.el.show(),this.el.prop("disabled",b.readonly),this.set_icon(b.icon||this.attributes.icon),this.attributes.rule){var c;c=a?a.get_button_clicks(this.attributes.name):jQuery.when(),c.then(function(a){var b=this.el.children(".badge"),c=[],d="";if(!jQuery.isEmptyObject(a)){for(var e in a)c.push(a[e]);d=Sao.i18n.gettext("By: ")+c.join(Sao.i18n.gettext(", "))}b.data("toggle","tooltip"),b.text(c.length||""),b.attr("title",d),b.tooltip()}.bind(this))}if((void 0===this.attributes.type||"class"===this.attributes.type)&&a)for(var d=a.group.parent;d;){if(d.has_changed()){this.el.prop("disabled",!1);break}d=d.group.parent}}}),Sao.common.udlex=Sao.class_(Object,{init:function(a){var b=Sao.class_(Object,{init:function(a){this.stream=a.split(""),this.i=0},read:function(a){if(void 0===a&&(a=1),this.i>=this.stream.length)return null;var b=this.stream.slice(this.i,this.i+a).join();return this.i+=a,b}});this.instream=new b(a),this.eof=null,this.commenters="",this.nowordchars=[":",">","<","=","!",'"',";","(",")"],this.whitespace=" \t\r\n",this.whitespace_split=!1,this.quotes='"',this.escape="\\",this.escapedquotes='"',this.state=" ",this.pushback=[],this.token=""},get_token:function(){return this.pushback.length>0?this.pushback.shift():this.read_token()},read_token:function(){for(var a=!1,b=" ";;){
+var c=this.instream.read(1);if(null===this.state){this.token="";break}if(" "==this.state){if(!c){this.state=null;break}if(this.whitespace.contains(c)){if(this.token||a)break;continue}if(this.commenters.contains(c));else if(this.escape.contains(c))b="a",this.state=c;else if(~this.nowordchars.indexOf(c))if(this.quotes.contains(c))this.state=c;else{if(!this.whitespace_split){if(this.token=c,this.token||a)break;continue}this.token=c,this.state="a"}else this.token=c,this.state="a"}else if(this.quotes.contains(this.state)){if(a=!0,!c)throw"no closing quotation";c==this.state?this.state="a":this.escape.contains(c)&&this.escapedquotes.contains(this.state)?(b=this.state,this.state=c):this.token=this.token+c}else if(this.escape.contains(this.state)){if(!c)throw"no escaped character";this.quotes.contains(b)&&c!=this.state&&c!=b&&(this.token=this.token+this.state),this.token=this.token+c,this.state=b}else if("a"==this.state){if(!c){this.state=null;break}if(this.whitespace.contains(c)){if(this.state=" ",this.token||a)break;continue}if(this.commenters.contains(c));else if(this.quotes.contains(c))this.state=c;else if(this.escape.contains(c))b="a",this.state=c;else{if(~this.nowordchars.indexOf(c)&&!this.quotes.contains(c)&&!this.whitespace_split){if(this.pushback.unshift(c),this.state=" ",this.token)break;continue}this.token=this.token+c}}}var d=this.token;return this.token="",a||""!==d||(d=null),d},next:function(){var a=this.get_token();return a==this.eof?null:a}}),Sao.common.DomainParser=Sao.class_(Object,{OPERATORS:["!=","<=",">=","=","!","<",">"],init:function(a,b){this.fields={},this.strings={},this.update_fields(a),this.context=b},update_fields:function(a){for(var b in a){var c=a[b];(c.searchable||void 0===c.searchable)&&(this.fields[b]=c,this.strings[c.string.toLowerCase()]=c)}},parse:function(a){try{for(var b=new Sao.common.udlex(a),c=[];;){var d=b.next();if(null===d)break;c.push(d)}return c=this.group_operator(c),c=this.parenthesize(c),c=this.group(c),c=this.operatorize(c,"or"),c=this.operatorize(c,"and"),c=this.parse_clause(c),this.simplify(c)}catch(e){if("no closing quotation"==e)return this.parse(a+'"');throw e}},stringable:function(a){var b=function(a){if(!a)return!0;var b=function(a){return a instanceof Array};return(~["AND","OR"].indexOf(a[0])||b(a[0]))&&a.slice(1).every(b)?this.stringable(a):a[0]in this.fields||"rec_name"==a[0]}.bind(this);return!a||(~["AND","OR"].indexOf(a[0])&&(a=a.slice(1)),a.every(b))},string:function(a){var b=function(a){if(jQuery.isEmptyObject(a))return"";if("string"!=typeof a[0]||~["AND","OR"].indexOf(a[0]))return"("+this.string(a)+")";var b,c=a[0],d=a[1],e=a[2];if(c.endsWith(".rec_name")&&(c=c.slice(0,-9)),!(c in this.fields))return b=e.replace("%%","__"),b.startsWith("%")&&b.endsWith("%")&&(e=e.slice(1,-1)),this.quote(e);var f=this.fields[c],g=null;a.length>3&&(g=a[3]),d.contains("ilike")&&(b=e.replace("%%","__"),b.startsWith("%")&&b.endsWith("%")?e=e.slice(1,-1):b.contains("%")||(d="ilike"==d?"=":"!",e=e.replace("%%","%")));var h=this.default_operator(f);h==d.trim()?(d="",~this.OPERATORS.indexOf(e)&&(d='"" ')):d.contains(h)&&(d.contains("not")||d.contains("!"))&&(d=d.replace(h,"").replace("not","!").trim()),d.endsWith("in")&&(d="not in"==d?"!":"");var i=this.format_value(f,e,g);return~this.OPERATORS.indexOf(d)&&~["char","text","selection"].indexOf(f.type)&&""===e&&(i='""'),this.quote(f.string)+": "+d+i};if(b=b.bind(this),jQuery.isEmptyObject(a))return"";var c=" ";return"AND"!=a[0]&&"OR"!=a[0]||("OR"==a[0]&&(c=" or "),a=a.slice(1)),a.map(b).join(c)},completion:function(a){var b,c,d=[],e=this.parse(a),f=0;for(b=a.length;b>0&&(")"!=a[b]&&" "!=a[b]);b--)")"==a[b]&&(f+=1);var g=this.ending_clause(e),h=g[0],i=g[1],j=i-f,k=this.string(e);j>0&&(k=k.substring(0,k.length-j)),k!=a&&d.push(k);var l,m,n=function(a,b){return b>0?a.substring(0,b):a};if(null!==h&&0===f){var o=this.complete(h);for(b=0,c=o.length;b<c;b++)l=o[b],m=this.string(this.replace_ending_clause(e,l)),d.push(n(m,j))}if(a.length>0){if(" "!=a.substr(a.length-1,1))return d;if(a.length>=2||":"==a.substr(a.length-2,1))return d}var p,q,r;for(var s in this.strings){p=this.strings[s],q=this.default_operator(p),r="","ilike"!=q&&"not ilike"!=q||(r=this.likify(r));var t=this.append_ending_clause(e,[p.name,q,r],j),u=this.string(t);d.push(n(u,j))}return d},complete:function(a){var b,c,d,e=[];1==a.length?b=a[0]:3==a.length?(b=a[0],c=a[1],d=a[2]):(b=a[0],c=a[1],d=a[2],a[3],b.endsWith(".rec_name")&&(b=b.substring(0,b.length-9)));var f;"rec_name"==b&&("ilike"==c&&(f=d.replace(/%%/g,"__"),f.startsWith("%")||f.endsWith("%")?d=f.substring(1,f.length-1):~f.indexOf("%")&&(d=d.replace(/%%/g,"%")),c=null),b=d,d=""),void 0!==b&&null!==b||(b="");var g;if(!(b.toLowerCase()in this.strings||b in this.fields)){for(var h in this.strings)g=this.strings[h],g.string.toLowerCase().startsWith(b.toLowerCase())&&(c=this.default_operator(g),d="","ilike"==c&&(d=this.likify(d)),e.push([g.name,c,d]));return e}if(g=b in this.fields?this.fields[b]:this.strings[b.toLowerCase()],c)for(var i=this.complete_value(g,d),j=0,k=i.length;j<k;j++)e.push([g.name,c,i[j]]);else c=this.default_operator(g),d="","ilike"!=c&&"not ilike"!=c||(d=this.likify(d)),e.push([g.name,c,d]);return e},is_leaf:function(a){return a instanceof Array&&a.clause},ending_clause:function(a,b){if(void 0===b&&(b=0),0===a.length)return[null,b];var c=a[a.length-1];return this.is_leaf(c)?[c,b]:this.ending_clause(c,b+1)},replace_ending_clause:function(a,b){var c,d,e=[];for(c=0,d=a.length-1;c<d;c++)e.push(a[c]);return this.is_leaf(a[c])?e.push(b):e=e.concat(this.replace_ending_clause(a[c],b)),e},append_ending_clause:function(a,b,c){if(0===a.length)return[b];var d=a.slice(0,-1),e=a[a.length-1];return this.is_leaf(e)?(d.push(e),0===c&&d.push(b)):d.push(this.append_ending_clause(e,b,c-1)),d},complete_value:function(a,b){var c=function(){return b?[!0]:[!1]},d=function(){var c=[],d=null!==b?b:"";b instanceof Array&&(d=b[b.length-1]),d=d.replace(/^%*|%*$/g,"");var e,f,g,h;for(e=0,f=a.selection.length;e<f;e++)g=a.selection[e][0],h=a.selection[e][1].toLowerCase(),h.startsWith(d.toLowerCase())&&(b instanceof Array?c.push(b.slice(0,-1).concat([g])):c.push(g));return c},e=function(){var c=[],d=null!==b?b:"";b instanceof Array&&(d=b[b.length-1]),d=d.replace(/^%*|%*$/g,"");var e,f,g,h;for(e=0,f=a.selection.length;e<f;e++)g=a.selection[e][0],h=a.selection[e][1].toLowerCase(),h.startsWith(d.toLowerCase())&&(b instanceof Array?c.push(b.slice(0,-1).concat([g])):c.push(this.likify(g)));return c}.bind(this),f=function(){return[Sao.Date(),Sao.DateTime().utc()]},g=function(){return[Sao.Date()]},h=function(){return[Sao.Time()]},i={boolean:c,selection:d,reference:e,datetime:f,date:g,time:h};return a.type in i?i[a.type]():[]},group_operator:function(a){var b=a[0],c=[];return a.slice(1).forEach(function(a){"="==a&&b&&~this.OPERATORS.indexOf(b+a)?(c.push(b+a),b=null):(null!==b&&c.push(b),b=a)}.bind(this)),null!==b&&c.push(b),c},parenthesize:function(a){var b=[],c=b,d=[];return a.forEach(function(a,b){void 0!==c&&("("==a?(d.push(c),c=c[c.push([])-1]):")"==a?c=d.pop():c.push(a))}),b},group:function(a){var b=[],c=function(a){var b=[],d=function(a){b.push([a])},e=a.indexOf(":");if(!~e)return a.forEach(d),b.forEach(function(a){a.clause=!0}),b;for(var f=function(a,c){return function(d){if(jQuery.isEmptyObject(a))b.push(d);else{var e;jQuery.isEmptyObject(c)?(e=a.concat(d),e.clause=!0,b.push(e)):(null!==d[0]&&c.push(d[0]),e=a.concat([c]),e.clause=!0,b.push(e)),a.splice(0,a.length)}}},g=0;g<e;g++){var h=a.slice(g,e).join(" ");if(h.toLowerCase()in this.strings){jQuery.isEmptyObject(a.slice(0,g))?d(null):a.slice(0,g).forEach(d),h=[h];var i=[""].concat(this.OPERATORS);e+1<a.length&&~i.indexOf(a[e+1])?(h=h.concat([a[e+1]]),e+=1):h=h.concat([null]);for(var j=[];e+2<a.length&&";"==a[e+2];)j.push(a[e+1]),e+=2;if(c(a.slice(e+1)).forEach(f(h,j)),!jQuery.isEmptyObject(h)){var k;jQuery.isEmptyObject(j)?(k=h.concat([null]),k.clause=!0,b.push(k)):(k=h.concat([j]),k.clause=!0,b.push(k))}break}}return b};c=c.bind(this);var d=[];return a.forEach(function(a){this.is_generator(a)?(c(d).forEach(function(a){Sao.common.compare(a,[null])||b.push(a)}),d=[],b.push(this.group(a))):d.push(a)}.bind(this)),c(d).forEach(function(a){Sao.common.compare(a,[null])||b.push(a)}),b},is_generator:function(a){return a instanceof Array&&void 0===a.clause},operatorize:function(a,b){var c=[];b=b||"or",a=jQuery.extend([],a);for(var d=function(a){return a instanceof Array?Sao.common.compare(a,[b]):a==b},e=a.shift();d(e);)e=a.shift();if(void 0===e)return c;this.is_generator(e)&&(e=this.operatorize(e,b));for(var f=null;!jQuery.isEmptyObject(a);)if(f=a.shift(),this.is_generator(f)&&!d(f)&&(f=this.operatorize(f,b)),d(f)){for(f=a.shift();d(f);)f=a.shift();this.is_generator(f)&&(f=this.operatorize(f,b)),void 0!==f?e=[b.toUpperCase(),e,f]:d(e)||(c.push([b.toUpperCase(),e]),e=null),f=null}else d(e)||c.push(e),e=f;return jQuery.isEmptyObject(a)&&(null===f||d(f)?null===e||d(e)||c.push(e):c.push(f)),c},_clausify:function(a){return a.clause=!0,a},parse_clause:function(a){var b=[];return a.forEach(function(a){if(this.is_generator(a))jQuery.merge(b,this.parse_clause(a));else if("OR"==a||"AND"==a)b.push(a);else if(1!=a.length||a[0]instanceof Array){if(3==a.length&&a[0].toLowerCase()in this.strings){var c=(a[0],a[1]),d=a[2],e=this.strings[a[0].toLowerCase()],f=null;if("reference"==e.type){var g=this.split_target_value(e,d);f=g[0],d=g[1]}if(c||(c=this.default_operator(e)),d instanceof Array&&(c="!"==c?"not in":"in"),"!"==c&&(c=this.negate_operator(this.default_operator(e))),~["integer","float","numeric","datetime","date","time"].indexOf(e.type)&&d&&d.contains("..")){var h=d.split("..",2),i=this.convert_value(e,h[0]),j=this.convert_value(e,h[1]);return void b.push([this._clausify([e.name,">=",i]),this._clausify([e.name,"<=",j])])}d=d instanceof Array?d.map(function(a){return this.convert_value(e,a)}.bind(this)):this.convert_value(e,d),c.contains("like")&&(d=this.likify(d)),f?b.push(this._clausify([e.name+".rec_name",c,d,f])):b.push(this._clausify([e.name,c,d]))}}else b.push(this._clausify(["rec_name","ilike",this.likify(a[0])]))}.bind(this)),b},likify:function(a){return a?a.replace("%%","__").contains("%")?a:"%"+a+"%":"%"},quote:function(a){if("string"!=typeof a)return a;a.contains("\\")&&(a=a.replace(new RegExp("\\\\","g"),"\\\\")),a.contains('"')&&(a=a.replace(new RegExp('"',"g"),'\\"'));for(var b=[":"," ","(",")"].concat(this.OPERATORS),c=0;c<b.length;c++){var d=b[c];if(a.contains(d))return'"'+a+'"'}return a},default_operator:function(a){return~["char","text","many2one","many2many","one2many","reference"].indexOf(a.type)?"ilike":"="},negate_operator:function(a){switch(a){case"ilike":return"not ilike";case"=":return"!=";case"in":return"not in"}},time_format:function(a){return new Sao.PYSON.Decoder({}).decode(a.format)},split_target_value:function(a,b){var c=null;if("string"==typeof b)for(var d=0;d<a.selection.length;d++){var e=a.selection[d],f=e[0],g=e[1];if(b.toLowerCase().startsWith(g.toLowerCase()+",")){c=f,b=b.slice(g.length+1);break}}return[c,b]},convert_value:function(a,b){var c=function(){if("string"==typeof b)for(var c=0;c<a.selection.length;c++){var d=a.selection[c],e=d[0],f=d[1];if(b.toLowerCase()==f.toLowerCase())return e}return b},d={boolean:function(){return"string"==typeof b?[Sao.i18n.gettext("y"),Sao.i18n.gettext("Yes"),Sao.i18n.gettext("True"),Sao.i18n.gettext("t"),"1"].some(function(a){return a.toLowerCase().startsWith(b.toLowerCase())}):Boolean(b)},float:function(){var a=Number(b);return isNaN(a)||""===b||null===b?null:a},integer:function(){var a=parseInt(b,10);return isNaN(a)?null:a},numeric:function(){var a=new Sao.Decimal(b);return isNaN(a.valueOf())||""===b||null===b?null:a},selection:c,reference:c,datetime:function(){var c=Sao.common.parse_datetime(Sao.common.date_format(),this.time_format(a),b);return c||(c=Sao.common.parse_date(Sao.common.date_format(),b)),c}.bind(this),date:function(){return Sao.common.parse_date(Sao.common.date_format(),b)},time:function(){try{return Sao.common.parse_time(this.time_format(a),b)}catch(c){return null}}.bind(this),timedelta:function(){var c=null;return a.converter&&(c=this.context[a.converter]),Sao.common.timedelta.parse(b,c)}.bind(this),many2one:function(){return""===b?null:b}},e=d[a.type];return e?e():b},format_value:function(a,b,c){void 0===c&&(c=null);var d=function(){if(!b&&0!==b&&b!==new Sao.Decimal(0))return"";var a=String(b).split(".")[1];return a=a?a.length:0,b.toFixed(a)},e=function(){for(var c=0;c<a.selection.length;c++)if(a.selection[c][0]==b)return a.selection[c][1];return b||""},f=function(){if(!c)return e();for(var d=0;d<a.selection.length;d++)if(a.selection[d][0]==c){c=a.selection[d][1];break}return c+","+b},g={boolean:function(){return b?Sao.i18n.gettext("True"):Sao.i18n.gettext("False")},integer:function(){return b||0===b?""+parseInt(b,10):""},float:d,numeric:d,selection:e,reference:f,datetime:function(){return b?b.isDate||!(b.hour()||b.minute()||b.second())?Sao.common.format_date(Sao.common.date_format(),b):Sao.common.format_datetime(Sao.common.date_format(),this.time_format(a),b):""}.bind(this),date:function(){return Sao.common.format_date(Sao.common.date_format(),b)},time:function(){return b?Sao.common.format_time(this.time_format(a),b):""}.bind(this),timedelta:function(){if(!b||!b.valueOf())return"";var c=null;return a.converter&&(c=this.context[a.converter]),Sao.common.timedelta.format(b,c)}.bind(this),many2one:function(){return null===b?"":b}};if(b instanceof Array)return b.map(function(b){return this.format_value(a,b)}.bind(this)).join(";");var h=g[a.type];return h?this.quote(h(b)):null===b?"":this.quote(b)},simplify:function(a){return a instanceof Array&&!this.is_leaf(a)?1==a.length&&a[0]instanceof Array&&("AND"==a[0][0]||"OR"==a[0][0]||a[0][0]instanceof Array)?this.simplify(a[0]):2==a.length&&("AND"==a[0]||"OR"==a[0])&&a[1]instanceof Array?this.simplify(a[1]):(3==a.length&&("AND"==a[0]||"OR"==a[0])&&a[1]instanceof Array&&a[0]==a[1][0]&&(a=this.simplify(a[1]).concat([a[2]])),a.map(this.simplify.bind(this))):a}}),Sao.common.DomainInversion=Sao.class_(Object,{and:function(a,b){return a&&b},or:function(a,b){return a||b},OPERATORS:{"=":function(a,b){return a instanceof Array&&b instanceof Array?Sao.common.compare(a,b):a===b},">":function(a,b){return a>b},"<":function(a,b){return a<b},"<=":function(a,b){return a<=b},">=":function(a,b){return a>=b},"!=":function(a,b){return a instanceof Array&&b instanceof Array?!Sao.common.compare(a,b):a!==b},in:function(a,b){return Sao.common.DomainInversion.in_(a,b)},"not in":function(a,b){return!Sao.common.DomainInversion.in_(a,b)},like:function(){return!0},ilike:function(){return!0},"not like":function(){return!0},"not ilike":function(){return!0},child_of:function(){return!0},"not child_of":function(){return!0}},locale_part:function(a,b,c){return void 0===c&&(c="id"),a===b?c:a.contains(".")?a.split(".").slice(1).join("."):a},is_leaf:function(a){return a instanceof Array&&a.length>2&&"string"==typeof a[1]},eval_leaf:function(a,b,c){void 0===c&&(c=this.and);var d=a[0],e=a[1],f=a[2];if(d.contains("."))return Boolean(b[d.split(".")[0]]);if("="==e&&(null===b[d]||void 0===b[d])&&c===this.and)return!0;var g=b[d];return g&&g._isAMomentObject&&!f&&(f=g.isDateTime?Sao.DateTime.min:Sao.Date.min),f&&f._isAMomentObject&&!g&&(g=f.isDateTime?Sao.DateTime.min:Sao.Date.min),"string"==typeof g&&f instanceof Array&&2==f.length?f=f.join(","):g instanceof Array&&"string"==typeof f&&2==g.length&&(g=g.join(",")),~["=","!="].indexOf(e)&&g instanceof Array&&"number"==typeof f&&(e={"=":"in","!=":"not in"}[e]),!(e in this.OPERATORS)||this.OPERATORS[e](g,f)},inverse_leaf:function(a){return~["AND","OR"].indexOf(a)?a:this.is_leaf(a)?a[1].contains("child_of")?3==a.length?a:[a[3]].concat(a.slice(1)):a:a.map(this.inverse_leaf.bind(this))},filter_leaf:function(a,b,c){return~["AND","OR"].indexOf(a)?a:this.is_leaf(a)?a[0].startsWith(b)&&a.length>3&&a[3]!==c?["id","=",null]:a:a.map(function(a){return this.filter_leaf(a,b,c)}.bind(this))},eval_domain:function(a,b,c){return void 0===c&&(c=this.and),this.is_leaf(a)?this.eval_leaf(a,b,c):!(!jQuery.isEmptyObject(a)||c!=this.and)||(!jQuery.isEmptyObject(a)||c!=this.or)&&("AND"==a[0]?this.eval_domain(a.slice(1),b):"OR"==a[0]?this.eval_domain(a.slice(1),b,this.or):c(this.eval_domain(a[0],b),this.eval_domain(a.slice(1),b,c)))},localize_domain:function(a,b,c){if(~["AND","OR",!0,!1].indexOf(a))return a;if(this.is_leaf(a)){if(a[1].contains("child_of"))return 3==a.length?a:[a[3]].concat(a.slice(1,-1));var d="id";"string"==typeof a[2]&&(d="rec_name");var e=c?3:4;return[this.locale_part(a[0],b,d)].concat(a.slice(1,e)).concat(a.slice(4))}return a.map(function(a){return this.localize_domain(a,b,c)}.bind(this))},simplify:function(a){return this.is_leaf(a)?a:~["OR","AND"].indexOf(a)?a:a instanceof Array&&1==a.length&&~["OR","AND"].indexOf(a[0])?[]:a instanceof Array&&1==a.length&&!this.is_leaf(a[0])?this.simplify(a[0]):a instanceof Array&&2==a.length&&~["AND","OR"].indexOf(a[0])?[this.simplify(a[1])]:a.map(this.simplify.bind(this))},merge:function(a,b){if(jQuery.isEmptyObject(a)||~["AND","OR"].indexOf(a))return[];var c="OR"==a[0]?"OR":"AND";return this.is_leaf(a)?[a]:void 0===b?[c].concat([].concat.apply([],a.map(function(a){return this.merge(a,c)}.bind(this)))):c==b?[].concat.apply([],a.map(function(a){return this.merge(a,c)}.bind(this))):[this.merge(a)]},concat:function(a,b){var c=[];return b&&c.push(b),a.forEach(function(a){jQuery.isEmptyObject(a)||c.push(a)}),this.simplify(this.merge(c))},unique_value:function(a){return a instanceof Array&&1==a.length&&!a[0][0].contains(".")&&"="==a[0][1]?[!0,a[0][1],a[0][2]]:[!1,null,null]},parse:function(a){var b=Sao.common.DomainInversion.And,c=Sao.common.DomainInversion.Or;if(this.is_leaf(a))return a;if(jQuery.isEmptyObject(a))return new b([]);if("OR"===a[0])return new c(a.slice(1));var d=0;return"AND"===a[0]&&(d=1),new b(a.slice(d))},domain_inversion:function(a,b,c){void 0===c&&(c={});var d=this.parse(a);return!~d.variables.indexOf(b)||d.inverse(b,c)}}),Sao.common.DomainInversion.in_=function(a,b){if(a instanceof Array){if(b instanceof Array){for(var c=0,d=a.length;c<d;c++)if(~b.indexOf(a[c]))return!0;return!1}return Boolean(~a.indexOf(b))}return Boolean(~b.indexOf(a))},Sao.common.DomainInversion.And=Sao.class_(Object,{init:function(a){this.domain_inversion=new Sao.common.DomainInversion,this.branches=a.map(this.domain_inversion.parse.bind(this.domain_inversion)),this.variables=[];for(var b=0,c=this.branches.length;b<c;b++){var d=this.branches[b];this.domain_inversion.is_leaf(d)?this.variables.push(this.base(d[0])):d instanceof Sao.common.DomainInversion.And&&(this.variables=this.variables.concat(d.variables))}},base:function(a){return a.contains(".")?a.split(".")[0]:a},inverse:function(a,b){for(var c=Sao.common.DomainInversion,d=[],e=0,f=this.branches.length;e<f;e++){var g=this.branches[e];if(g instanceof c.And){var h=g.inverse(a,b);if("boolean"==typeof h){if(h)continue;return!1}d.push(h)}else if(this.domain_inversion.is_leaf(g)&&this.base(g[0])===a)d.push(g);else{var i=g[0];if(i in b&&!(i in b&&this.domain_inversion.eval_leaf(g,b,this.domain_inversion.and)))return!1;d.push(!0)}}return d=d.filter(function(a){return!0!==a}),!!jQuery.isEmptyObject(d)||this.domain_inversion.simplify(d)}}),Sao.common.DomainInversion.Or=Sao.class_(Sao.common.DomainInversion.And,{inverse:function(a,b){var c=Sao.common.DomainInversion,d=[];if(!~this.variables.indexOf(a)&&!jQuery.isEmptyObject(this.variables.filter(function(a){return!(a in b)})))return!0;for(var e=0,f=this.branches.length;e<f;e++){var g=this.branches[e];if(g instanceof c.And){var h=g.inverse(a,b),i="boolean"==typeof h;if(!~this.variables.indexOf(a)){if(i&&h)return!0;continue}if(i){if(h)return!0;continue}d.push(h)}else if(this.domain_inversion.is_leaf(g)&&this.base(g[0])==a)d.push(g);else{var j=g[0];if((j=this.base(j))in b&&this.domain_inversion.eval_leaf(g,b,this.domain_inversion.or))return!0;j in b&&!this.domain_inversion.eval_leaf(g,b,this.domain_inversion.or)&&d.push(!1)}}return d=d.filter(function(a){return!1!==a}),!jQuery.isEmptyObject(d)&&this.domain_inversion.simplify(["OR"].concat(d))}}),Sao.common.guess_mimetype=function(a){return/.*odt$/.test(a)?"application/vnd.oasis.opendocument.text":/.*ods$/.test(a)?"application/vnd.oasis.opendocument.spreadsheet":/.*pdf$/.test(a)?"application/pdf":/.*docx$/.test(a)?"application/vnd.openxmlformats-officedocument.wordprocessingml.document":/.*doc/.test(a)?"application/msword":/.*xlsx$/.test(a)?"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":/.*xls/.test(a)?"application/vnd.ms-excel":"application/octet-binary"},Sao.common.LOCAL_ICONS=["tryton-attachment-hi","tryton-attachment","tryton-bookmark","tryton-cancel","tryton-clear","tryton-close","tryton-connect","tryton-copy","tryton-delete","tryton-dialog-error","tryton-dialog-information","tryton-dialog-warning","tryton-disconnect","tryton-executable","tryton-find-replace","tryton-find","tryton-folder-new","tryton-fullscreen","tryton-go-home","tryton-go-jump","tryton-go-next","tryton-go-previous","tryton-help","tryton-icon","tryton-list-add","tryton-list-remove","tryton-locale","tryton-lock","tryton-log-out","tryton-mail-message-new","tryton-mail-message","tryton-new","tryton-ok","tryton-open","tryton-preferences-system-session","tryton-preferences-system","tryton-preferences","tryton-print-email","tryton-print-open","tryton-print","tryton-refresh","tryton-save-as","tryton-save","tryton-star","tryton-start-here","tryton-system-file-manager","tryton-system","tryton-text-background","tryton-text-foreground","tryton-text-markup","tryton-undo","tryton-unstar","tryton-web-browser"],Sao.common.IconFactory=Sao.class_(Object,{batchnum:10,name2id:{},loaded_icons:{},tryton_icons:[],register_prm:jQuery.when(),load_icons:function(a){if(!(a=a||!1))for(var b in this.load_icons)this.load_icons.hasOwnProperty(b)&&window.URL.revokeObjectURL(this.load_icons[b]);return new Sao.Model("ir.ui.icon").execute("list_icons",[],{}).then(function(b){a||(this.name2id={},this.loaded_icons={}),this.tryton_icons=[];for(var c,d,e=0,f=b.length;e<f;e++)c=b[e][0],d=b[e][1],a&&d in this.loaded_icons||(this.tryton_icons.push([c,d]),this.name2id[d]=c)}.bind(this))},register_icon:function(a){if(!a)return jQuery.Deferred().reject();if(a in this.loaded_icons||~Sao.common.LOCAL_ICONS.indexOf(a))return jQuery.when(this.get_icon_url(a));if("pending"==this.register_prm.state()){var b=jQuery.Deferred();return this.register_prm.then(function(){this.register_icon(a).then(b.resolve,b.reject)}.bind(this)),b}var c;c=a in this.name2id?jQuery.when():this.load_icons(!0);var d=new Sao.Model("ir.ui.icon");return this.register_prm=c.then(function(){var b=function(a){var b,c;for(b=0,c=this.tryton_icons.length;b<c;b++){var d=this.tryton_icons[b];if(Sao.common.compare(d,a))break}return b}.bind(this),c=b([this.name2id[a],a]),e=Math.round(c-this.batchnum/2);e=e<0?0:e;var f=Math.round(c+this.batchnum/2),g=[];return this.tryton_icons.slice(e,f).forEach(function(a){g.push(a[0])}),d.execute("read",[g,["name","icon"]],{}).then(function(c){return c.forEach(function(a){var c;if(navigator.userAgent.match(/firefox/i)){c="data:image/svg+xml;base64,"+window.btoa(unescape(encodeURIComponent(a.icon)));var d=new Image;d.src=c,d.onload=function(){var b=document.createElement("canvas");b.width=d.width,b.height=d.height,b.getContext("2d").drawImage(d,0,0),b.toBlob(function(d){var e=c;c=window.URL.createObjectURL(d),this.loaded_icons[a.name]=c,jQuery(document).find("img").each(function(a,b){b.src==e&&(b.src=c)}),b.remove()}.bind(this),"image/png")}.bind(this)}else{var e=new Blob([a.icon],{type:"image/svg+xml"});c=window.URL.createObjectURL(e)}this.loaded_icons[a.name]=c,delete this.name2id[a.name],this.tryton_icons.splice(b([a.id,a.name]),1)}.bind(this)),this.get_icon_url(a)}.bind(this))}.bind(this)),this.register_prm},get_icon_url:function(a){return a in this.loaded_icons?this.loaded_icons[a]:"images/"+a+".svg"}}),Sao.common.ICONFACTORY=new Sao.common.IconFactory,Sao.common.UniqueDialog=Sao.class_(Object,{init:function(){this.running=!1},build_dialog:function(){return new Sao.Dialog("",this.class_)},run:function(){if(this.running)return jQuery.when();var a=Array.prototype.slice.call(arguments),b=jQuery.Deferred();a.push(b);var c=this.build_dialog.apply(this,a);return c.content.submit(function(a){c.footer.find("button.btn-primary").first().click(),a.preventDefault()}.bind(this)),this.running=!0,c.modal.modal("show"),c.modal.on("shown.bs.modal",function(){c.modal.find("input,select").filter(":visible").first().focus()}),b},close:function(a){a.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),a.modal.modal("hide"),this.running=!1}}),Sao.common.MessageDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"message-dialog",build_dialog:function(a,b,c){var d=Sao.common.MessageDialog._super.build_dialog.call(this);return d.header.remove(),d.body.append(jQuery("<div/>",{class:"alert alert-info",role:"alert"}).append(jQuery("<span/>",{class:"glyphicon "+b,"aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Message: "))).append(jQuery("<span/>").append(a).css("white-space","pre-wrap"))),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve("ok")}.bind(this)).appendTo(d.footer),d},run:function(a,b){return Sao.common.MessageDialog._super.run.call(this,a,b||"glyphicon-info-sign")}}),Sao.common.message=new Sao.common.MessageDialog,Sao.common.WarningDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"warning-dialog",build_dialog:function(a,b,c){var d=Sao.common.WarningDialog._super.build_dialog.call(this),e=jQuery("<div/>",{class:"alert alert-warning",role:"alert"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-alert","aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Warning: "))).append(jQuery("<h4/>").append(b).css("white-space","pre-wrap"));return a&&e.append(jQuery("<span/>").append(a).css("white-space","pre-wrap")),d.body.append(e),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve("ok")}.bind(this)).appendTo(d.footer),d}}),Sao.common.warning=new Sao.common.WarningDialog,Sao.common.UserWarningDialog=Sao.class_(Sao.common.WarningDialog,{class_:"user-warning-dialog",always:!1,_set_always:function(){this.always=jQuery(this).prop("checked")},build_dialog:function(a,b,c){var d=Sao.common.UserWarningDialog._super.build_dialog.call(this,a,b,c);return d.body.append(jQuery("<div/>").append(jQuery("<input/>",{type:"checkbox"}).change(this._set_always.bind(this))).append(jQuery("<span/>").text(Sao.i18n.gettext("Always ignore this warning.")))),d.body.append(jQuery("<p/>").text(Sao.i18n.gettext("Do you want to proceed?"))),d.footer.children().remove(),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("No")).click(function(){this.close(d),c.reject()}.bind(this)).appendTo(d.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Yes")).click(function(){this.close(d),this.always&&c.resolve("always"),c.resolve("ok")}.bind(this)).appendTo(d.footer),d}}),Sao.common.userwarning=new Sao.common.UserWarningDialog,Sao.common.ConfirmationDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"confirmation-dialog",build_dialog:function(a){var b=Sao.common.ConfirmationDialog._super.build_dialog.call(this);return b.header.remove(),b.body.append(jQuery("<div/>",{class:"alert alert-info",role:"alert"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-info-sign","aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Confirmation: "))).append(jQuery("<span/>").append(a).css("white-space","pre-wrap"))),b}}),Sao.common.SurDialog=Sao.class_(Sao.common.ConfirmationDialog,{build_dialog:function(a,b){var c=Sao.common.SurDialog._super.build_dialog.call(this,a);return jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c),b.reject()}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(c),b.resolve()}.bind(this)).appendTo(c.footer),c}}),Sao.common.sur=new Sao.common.SurDialog,Sao.common.Sur3BDialog=Sao.class_(Sao.common.ConfirmationDialog,{build_dialog:function(a,b){var c=Sao.common.SurDialog._super.build_dialog.call(this,a);return jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c),b.resolve("cancel")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("No")).click(function(){this.close(c),b.resolve("ko")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Yes")).click(function(){this.close(c),b.resolve("ok")}.bind(this)).appendTo(c.footer),c}}),Sao.common.sur_3b=new Sao.common.Sur3BDialog,Sao.common.AskDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"ask-dialog",run:function(){var a=Array.prototype.slice.call(arguments);return 1==a.length&&a.push(!0),Sao.common.AskDialog._super.run.apply(this,a)},build_dialog:function(a,b,c){var d=Sao.common.AskDialog._super.build_dialog.call(this);d.header.remove();var e=jQuery("<input/>",{class:"form-control",type:b?"input":"password",id:"ask-dialog-entry"});return d.body.append(jQuery("<div/>",{class:"form-group"}).append(jQuery("<label/>",{for:"ask-dialog-entry"}).append(a)).append(e)),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(d),c.reject()}.bind(this)).appendTo(d.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve(e.val())}.bind(this)).appendTo(d.footer),d}}),Sao.common.ask=new Sao.common.AskDialog,Sao.common.ConcurrencyDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"ask-dialog",build_dialog:function(a,b,c,d){var e=Sao.common.ConcurrencyDialog._super.build_dialog.call(this);return e.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),e.add_title(Sao.i18n.gettext("Concurrency Exception")),e.body.append(jQuery("<div/>",{class:"alert alert-warning",role:"alert"}).append(jQuery("<p/>").append(jQuery("<span/>",{class:"glyphicon glyphicon-info-sign","aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Write Concurrency Warning: "))).append(Sao.i18n.gettext("This record has been modified while you were editing it."))).append(jQuery("<p/>").text(Sao.i18n.gettext("Choose:"))).append(jQuery("<ul/>").append(jQuery("<li/>").text(Sao.i18n.gettext('"Cancel" to cancel saving;'))).append(jQuery("<li/>").text(Sao.i18n.gettext('"Compare" to see the modified version;'))).append(jQuery("<li/>").text(Sao.i18n.gettext('"Write Anyway" to save your current version.'))))),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(e),d.reject()}.bind(this)).appendTo(e.footer),jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Compare")).click(function(){this.close(e),Sao.Tab.create({model:a,res_id:b,domain:[["id","=",b]],context:c,mode:["form","tree"]}),d.reject()}.bind(this)).appendTo(e.footer),jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Write Anyway")).click(function(){this.close(e),d.resolve()}.bind(this)).appendTo(e.footer),e}}),Sao.common.concurrency=new Sao.common.ConcurrencyDialog,Sao.common.ErrorDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"error-dialog",build_dialog:function(a,b,c){var d=Sao.common.ConcurrencyDialog._super.build_dialog.call(this)
+;return d.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),d.add_title(Sao.i18n.gettext("Application Error")),d.body.append(jQuery("<div/>",{class:"alert alert-warning",role:"alert"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-alert","aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Warning: "))).append(jQuery("<p/>").append(jQuery("<pre/>").text(b))).append(jQuery("<p/>").append(jQuery("<a/>",{class:"btn btn-link",href:Sao.config.roundup.url,target:"_blank"}).text(Sao.i18n.gettext("Report Bug"))))),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Close")).click(function(){this.close(d),c.resolve()}.bind(this)).appendTo(d.footer),d}}),Sao.common.error=new Sao.common.ErrorDialog,Sao.common.Processing=Sao.class_(Object,{queries:0,timeout:500,init:function(){this.el=jQuery("<div/>",{id:"processing",class:"text-center"}),this.el.append(jQuery("<span/>",{class:"label label-info",text:Sao.i18n.gettext("Processing...")})),this.el.hide(),jQuery(function(){this.el.appendTo("body")}.bind(this))},show:function(){return window.setTimeout(function(){this.queries+=1,this.el.show()}.bind(this),this.timeout)},hide:function(a){window.clearTimeout(a),this.queries>0&&(this.queries-=1),this.queries<=0&&(this.queries=0,this.el.hide())}}),Sao.common.processing=new Sao.common.Processing,Sao.common.InputCompletion=Sao.class_(Object,{init:function(a,b,c,d){a.is("input")?(a.wrap('<div class="dropdown"/>'),this.dropdown=a.parent()):(a.addClass("dropdown"),this.dropdown=a),this.input=a.find("input").add(a.filter("input")).first(),this.input.attr("autocomplete","off"),jQuery("<span/>",{"data-toggle":"dropdown"}).appendTo(this.dropdown),this.menu=jQuery("<ul/>",{class:"dropdown-menu",role:"listbox"}).appendTo(this.dropdown),this.separator=jQuery("<li/>",{role:"separator",class:"divider"}).appendTo(this.menu),this.separator.hide(),this.source=b,this.match_selected=c,this.format=d,this.action_activated=null,this._search_text=null,this.input.on("input",function(){window.setTimeout(this._input.bind(this),300,this.input.val())}.bind(this)),this.input.keydown(function(a){a.which==Sao.common.ESC_KEYCODE?this.dropdown.hasClass("open")&&this.menu.dropdown("toggle"):a.which==Sao.common.RETURN_KEYCODE&&(this.dropdown.hasClass("open")||this.menu.dropdown("toggle"))}.bind(this)),this.dropdown.on("hide.bs.dropdown",function(){this.input.focus(),this.input.closest(".treeview").css("overflow","")}.bind(this)),this.dropdown.on("show.bs.dropdown",function(){this.input.closest(".treeview").css("overflow","visible")}.bind(this))},set_actions:function(a,b){if(void 0!==b&&(this.action_activated=b),this.menu.find("li.action").remove(),jQuery.isEmptyObject(a))return void this.separator.hide();this.separator.show(),a.forEach(function(a){var b=a[0],c=a[1];jQuery("<li/>",{class:"action action-"+b}).append(jQuery("<a/>",{href:"#"}).append(this._format_action(c))).click(function(){this.action_activated&&this.action_activated(b),this.input.val("")}.bind(this)).appendTo(this.menu)},this)},_format:function(a){return this.format?this.format(a):a},_format_action:function(a){return this.format_action?this.format_action(a):a},_input:function(a){if(a==this.input.val()){var b;b=this.source instanceof Array?jQuery.when(source.filter(function(b){return b.toLowerCase().startsWith(a.toLowerCase())})):this.source(a),b.then(function(b){a==this.input.val()&&this._set_selection(b)}.bind(this))}},_set_selection:function(a){void 0===a&&(a=[]),this.menu.find("li.completion").remove(),a.reverse().forEach(function(a){jQuery("<li/>",{class:"completion"}).append(jQuery("<a/>",{href:"#"}).append(this._format(a))).click(function(){this.match_selected&&this.match_selected(a),this.input.focus()}.bind(this)).prependTo(this.menu)},this),this.input.val()?this.dropdown.hasClass("open")||this.menu.dropdown("toggle"):this.dropdown.hasClass("open")&&this.menu.dropdown("toggle")}}),Sao.common.get_completion=function(a,b,c,d){var e=function(a){return a.rec_name};new Sao.common.InputCompletion(a,b,c,e).set_actions([["search",Sao.i18n.gettext("Search...")],["create",Sao.i18n.gettext("Create...")]],d)},Sao.common.update_completion=function(a,b,c,d,e){var f=a.val();if(!f||!d)return jQuery.when();void 0===e&&(e=c.get_domain(b));var g=c.get_context(b);return e=[["rec_name","ilike","%"+f+"%"],e],new Sao.Model(d).execute("search_read",[e,0,Sao.config.limit,null,["rec_name"]],g)},Sao.common.Paned=Sao.class_(Object,{init:function(a){var b;this._orientation=a,this.el=jQuery("<div/>"),"horizontal"==a?(b=jQuery("<div/>",{class:"row"}).appendTo(this.el),this.child1=jQuery("<div/>",{class:"col-md-6"}).appendTo(b),this.child2=jQuery("<div/>",{class:"col-md-6"}).appendTo(b)):"vertical"==a&&(this.child1=jQuery("<div/>",{class:"row"}).appendTo(this.el),this.child2=jQuery("<div/>",{class:"row"}).appendTo(this.el))},get_child1:function(){return this.child1},get_child2:function(){return this.child2}}),Sao.common.get_focus_chain=function(a){var b=a.find("input","textarea");return b.sort(function(a,b){if("tabindex"in a.attributes&&"tabindex"in b.attributes){return parseInt(a.attributes.tabindex.value)-parseInt(b.attributes.tabindex.value)}return"tabindex"in a.attributes?-1:"tabindex"in b.attributes?1:0}),b},Sao.common.find_focusable_child=function(a){var b,c,d,e;if(!a.is(":visible"))return null;if(~["input","select","textarea"].indexOf(a[0].tagName.toLowerCase()))return a;for(d=Sao.common.get_focus_chain(a),b=0,c=d.length;b<c;b++)if(e=Sao.common.find_focusable_child(jQuery(d[b])))return e},Sao.common.find_first_focus_widget=function(a,b){var c,d,e,f;if(1==b.length)return jQuery(b[0]);for(e=Sao.common.get_focus_chain(a),c=0;c<e.length;c++){for(f=[],d=0;d<b.length;d++)jQuery(b[d]).closest(e[c]).length>0&&f.push(b[d]);if(f.length>0)return Sao.common.find_first_focus_widget(jQuery(e[c]),f)}},Sao.common.apply_label_attributes=function(a,b,c){b?a.removeClass("editable required"):(a.addClass("editable"),c?a.addClass("required"):a.removeClass("required"))},Sao.common.download_file=function(a,b){var c=Sao.common.guess_mimetype(b?b.split(".").pop():void 0),d=new Blob([a],{type:c}),e=window.URL.createObjectURL(d),f=new Sao.Dialog(Sao.i18n.gettext("Download")),g=function(){f.modal.modal("hide")},h=jQuery("<a/>",{href:e,download:b,text:b,target:"_blank"}).appendTo(f.body).append(jQuery("<span/>",{class:"glyphicon glyphicon-download-alt"})).click(g);jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Close")).click(g).appendTo(f.footer);f.modal.on("shown.bs.modal",function(){h[0].click()}),f.modal.modal("show"),f.modal.on("hidden.bs.modal",function(){jQuery(this).remove(),window.URL.revokeObjectURL(this.blob_url)})},Sao.common.ellipsize=function(a,b){if(a.length<=b)return a;var c=Sao.i18n.gettext("...");return a.slice(0,b-c.length)+c}}(),function(){"use strict";Sao.Window={},Sao.Window.InfoBar=Sao.class_(Object,{init:function(){this.text=jQuery("<span/>"),this.text.css("white-space","pre-wrap"),this.el=jQuery("<div/>",{class:"alert infobar",role:"alert"}).append(jQuery("<button/>",{type:"button",class:"close","aria-label":Sao.i18n.gettext("Close")}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).click(function(){this.el.hide()}.bind(this))).append(this.text),this.el.hide()},message:function(a,b){a?(this.el.removeClass("alert-success alert-info alert-warning alert-danger"),this.el.addClass("alert-"+(b||"info")),this.text.text(a),this.el.show()):this.el.hide()}}),Sao.Window.Form=Sao.class_(Object,{init:function(a,b,c){c=c||{},this.screen=a,this.callback=b,this.many=c.many||0,this.domain=c.domain||null,this.context=c.context||null,this.save_current=c.save_current;var d=jQuery.when(c.title||"");d.then(function(a){this.title=a}.bind(this)),this.prev_view=a.current_view,this.screen.screen_container.alternate_view=!0,this.info_bar=new Sao.Window.InfoBar;for(var e=c.view_type||"form",f=jQuery.when(),g=[],h=0,i=this.screen.views.length;h<i;h++)g.push(this.screen.views[h].view_type);~g.indexOf(e)||~this.screen.view_to_load.indexOf(e)||(f=this.screen.add_view_id(null,e));var j=f.then(function(){return this.screen.switch_view(e).done(function(){c.new_&&this.screen.new_(void 0,c.rec_name)}.bind(this))}.bind(this)),k=new Sao.Dialog("","window-form","lg");this.el=k.modal;var l=this.screen.attributes.readonly||this.screen.group.get_readonly();if("form"==e&&k.footer.append(jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(!c.new_&&this.screen.current_record.id<0?Sao.i18n.gettext("Delete"):Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this))),c.new_&&this.many&&k.footer.append(jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("New")).click(function(){this.response("RESPONSE_ACCEPT")}.bind(this))),this.save_current?k.footer.append(jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Save"))):k.footer.append(jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK"))),k.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),"tree"==e){var m=jQuery("<div/>",{class:"window-form-toolbar"}).appendTo(k.body),n=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(m);this.wid_text=jQuery("<input/>",{type:"input"}).appendTo(m),this.wid_text.hide();var o=jQuery("<div/>",{class:"input-group-btn"}).appendTo(n),p=Sao.common.MODELACCESS.get(this.screen.model_name);this.domain&&(this.wid_text.show(),this.but_add=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-plus"})).appendTo(o),this.but_add.click(this.add.bind(this)),this.but_add.prop("disabled",!p.read||l),this.but_remove=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-minus"})).appendTo(o),this.but_remove.click(this.remove.bind(this)),this.but_remove.prop("disabled",!p.read||l)),this.but_new=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("New")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-edit"})).appendTo(o),this.but_new.click(this.new_.bind(this)),this.but_new.prop("disabled",!p.create||l),this.but_del=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Delete")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-trash"})).appendTo(o),this.but_del.click(this.delete_.bind(this)),this.but_del.prop("disabled",!p.delete||l),this.but_undel=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Undelete")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-repeat"})).appendTo(o),this.but_undel.click(this.undelete.bind(this)),this.but_undel.prop("disabled",!p.delete||l),this.but_previous=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-chevron-left"})).appendTo(o),this.but_previous.click(this.previous.bind(this)),this.label=jQuery("<span/>",{class:"btn"}).appendTo(o),this.label.text("(0, 0)"),this.but_next=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-chevron-right"})).appendTo(o),this.but_next.click(this.next.bind(this)),this.but_switch=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Switch")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-list-alt"})).appendTo(o),this.but_switch.click(this.switch_.bind(this))}var q=jQuery("<div/>").appendTo(k.body);k.body.append(this.info_bar.el),j.done(function(){d.done(k.add_title.bind(k)),q.append(this.screen.screen_container.alternate_viewport),this.el.modal("show")}.bind(this)),this.el.on("shown.bs.modal",function(a){this.screen.display().done(function(){this.screen.set_cursor()}.bind(this))}.bind(this)),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},add:function(){var a=jQuery.extend([],this.domain),b=this.screen.model_name,c=this.wid_text.val(),d=function(a){var b=jQuery.when();if(!jQuery.isEmptyObject(a)){for(var c=[],d=0,e=a.length;d<e;d++)c.push(a[d][0]);this.screen.group.load(c,!0),b=this.screen.display()}b.done(function(){this.screen.set_cursor()}.bind(this)),this.entry.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(b,d,{sel_multi:!0,context:this.context,domain:a,search_filter:e.quote(c)})},remove:function(){this.screen.remove(!1,!0,!1)},new_:function(){this.screen.new_()},delete_:function(){this.screen.remove(!1,!1,!1)},undelete:function(){this.screen.unremove()},previous:function(){this.screen.display_previous()},next:function(){this.screen.display_next()},switch_:function(){this.screen.switch_view()},response:function(a){var b;this.screen.current_view.set_value();var c=this.screen.group.get_readonly();if(~["RESPONSE_OK","RESPONSE_ACCEPT"].indexOf(a)&&!c&&this.screen.current_record)return void this.screen.current_record.validate().then(function(a){return a&&this.screen.attributes.pre_validate?this.screen.current_record.pre_validate():a}.bind(this)).then(function(c){var d=jQuery.Deferred();if(c&&this.save_current)this.screen.save_current().then(d.resolve,d.reject);else if(c&&"form"==this.screen.current_view.view_type){var e=this.screen.current_view,f=[];for(var g in e.widgets){var h=e.widgets[g];if(h.screen&&h.screen.attributes.pre_validate){var i=h.screen.current_record;i&&f.push(i.pre_validate())}}jQuery.when.apply(jQuery,f).then(d.resolve,d.reject)}else c?(this.info_bar.message(),d.resolve()):(this.info_bar.message(this.screen.invalid_message(),"danger"),d.reject());d.fail(function(){this.screen.display().done(function(){this.screen.set_cursor()}.bind(this))}.bind(this)),d.done(function(){"RESPONSE_ACCEPT"==a?(this.screen.new_(),this.screen.current_view.display().done(function(){this.screen.set_cursor()}.bind(this)),this.many-=1,0===this.many&&this.but_new.prop("disabled",!0)):(b=!0,this.callback(b),this.destroy())}.bind(this))}.bind(this));if("RESPONSE_CANCEL"==a&&!c&&this.screen.current_record){if(b=!1,this.screen.current_record.id<0||this.save_current)this.screen.cancel_current();else if(this.screen.current_record.has_changed())return this.screen.current_record.cancel(),void this.screen.current_record.reload().always(function(){this.callback(b),this.destroy()}.bind(this))}else b="RESPONSE_CANCEL"!=a;this.callback(b),this.destroy()},destroy:function(){this.screen.screen_container.alternate_view=!1,this.screen.screen_container.alternate_viewport.children().detach(),this.prev_view&&this.screen.switch_view(this.prev_view.view_type),this.el.modal("hide")}}),Sao.Window.Attachment=Sao.class_(Sao.Window.Form,{init:function(a,b){this.resource=a.model.name+","+a.id,this.attachment_callback=b;var c=jQuery.extend({},a.get_context()),d=new Sao.Screen("ir.attachment",{domain:[["resource","=",this.resource]],mode:["tree","form"],context:c,exclude_field:"resource"});d.switch_view().done(function(){d.search_filter()});var e=a.rec_name().then(function(a){return Sao.i18n.gettext("Attachments (%1)",a)});Sao.Window.Attachment._super.init.call(this,d,this.callback,{view_type:"tree",title:e})},callback:function(a){var b=jQuery.when();if(a){var c=this.screen.group.model.fields.resource;this.screen.group.forEach(function(a){c.set_client(a,this.resource)}.bind(this)),b=this.screen.save_current()}this.attachment_callback&&b.always(this.attachment_callback.bind(this))}}),Sao.Window.Note=Sao.class_(Sao.Window.Form,{init:function(a,b){this.resource=a.model.name+","+a.id,this.note_callback=b;var c=jQuery.extend({},a.get_context()),d=new Sao.Screen("ir.note",{domain:[["resource","=",this.resource]],mode:["tree","form"],context:c,exclude_field:"resource"});d.switch_view().done(function(){d.search_filter()});var e=a.rec_name().then(function(a){return Sao.i18n.gettext("Notes (%1)",a)});Sao.Window.Note._super.init.call(this,d,this.callback,{view_type:"tree",title:e})},callback:function(a){var b=jQuery.when();if(a){var c=this.screen.group.model.fields.resource,d=this.screen.group.model.fields.unread;this.screen.group.forEach(function(a){(a.get_loaded()||a.id<0)&&(c.set_client(a,this.resource),a._changed.unread||d.set_client(a,!1))}.bind(this)),b=this.screen.save_current()}this.note_callback&&b.always(this.note_callback.bind(this))}}),Sao.Window.Search=Sao.class_(Object,{init:function(a,b,c){c=c||{};var d=c.views_preload||{};this.model_name=a,this.domain=c.domain||[],this.context=c.context||{},this.sel_multi=c.sel_multi,this.callback=b,this.title=c.title||"";var e=new Sao.Dialog(Sao.i18n.gettext("Search %1",this.title),"","lg");this.el=e.modal,jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(e.footer),jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Find")).click(function(){this.response("RESPONSE_APPLY")}.bind(this)).appendTo(e.footer),c.new_&&Sao.common.MODELACCESS.get(a).create&&jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("New")).click(function(){this.response("RESPONSE_ACCEPT")}.bind(this)).appendTo(e.footer),jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(e.footer),e.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),this.screen=new Sao.Screen(a,{mode:["tree"],context:this.context,domain:this.domain,view_ids:c.view_ids,views_preload:d,row_activate:this.activate.bind(this)}),this.screen.load_next_view().done(function(){this.screen.switch_view().done(function(){e.body.append(this.screen.screen_container.el),this.el.modal("show"),this.screen.display(),void 0!==c.search_filter&&this.screen.search_filter(c.search_filter)}.bind(this))}.bind(this)),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},activate:function(){this.response("RESPONSE_OK")},response:function(a){var b,c=[];if("RESPONSE_OK"==a)b=this.screen.current_view.selected_records();else{if("RESPONSE_APPLY"==a)return void this.screen.search_filter();if("RESPONSE_ACCEPT"==a){var d=new Sao.Screen(this.model_name,{domain:this.domain,context:this.context,mode:["form"]}),e=function(a){if(a){var b=d.current_record;this.callback([[b.id,b._values.rec_name||""]])}else this.callback(null)};return this.el.modal("hide"),void new Sao.Window.Form(d,e.bind(this),{new_:!0,save_current:!0,title:this.title})}}if(b){var f,g;for(f in b)g=b[f],c.push([g.id,g._values.rec_name||""])}this.callback(c),this.el.modal("hide")}}),Sao.Window.Preferences=Sao.class_(Object,{init:function(a){this.callback=a;var b=new Sao.Dialog("Preferences","","lg");this.el=b.modal,jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(b.footer),jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(b.footer),b.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),this.screen=new Sao.Screen("res.user",{mode:[]}),this.screen.attributes.readonly=!1,this.screen.group.set_readonly(!1),this.screen.group.skip_model_access=!0;var c=function(a){this.screen.add_view(a),this.screen.switch_view().done(function(){this.screen.new_(!1),this.screen.model.execute("get_preferences",[!1],{}).then(d.bind(this),this.destroy)}.bind(this))},d=function(a){var c;this.screen.current_record.cancel(),c=this.screen.current_record.set(a),this.screen.current_record.id=this.screen.model.session.user_id,c.then(function(){this.screen.current_record.validate(null,!0).then(function(){this.screen.display(!0)}.bind(this))}.bind(this)),b.body.append(this.screen.screen_container.el),this.el.modal("show")};this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()}),this.screen.model.execute("get_preferences_fields_view",[],{}).then(c.bind(this),this.destroy)},response:function(a){var b=function(){this.destroy(),this.callback()}.bind(this),c=jQuery.when();"RESPONSE_OK"==a&&(c=this.screen.current_record.validate().then(function(a){if(a){var b=jQuery.extend({},this.screen.get()),c=jQuery.extend({},Sao.Session.current_session.context),d=function(a){return{id:0,method:"model.res.user.set_preferences",params:[b,a,c]}};return new Sao.Login(d).run()}}.bind(this))),c.done(b)},destroy:function(){this.el.modal("hide")}}),Sao.Window.Revision=Sao.class_(Object,{init:function(a,b){this.callback=b;var c=new Sao.Dialog(Sao.i18n.gettext("Revision"),"","lg");this.el=c.modal,jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(c.footer),c.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this));var d=jQuery("<div/>",{class:"form-group"}).appendTo(c.body);jQuery("<label/>",{for:"revision",text:"Revision"}).appendTo(d),this.select=jQuery("<select/>",{class:"form-control",id:"revision",placeholder:Sao.i18n.gettext("Revision")}).appendTo(d);var e=Sao.common.date_format();this.select.append(jQuery("<option/>",{value:null,text:""})),a.forEach(function(a){a[2],a=a[0],this.select.append(jQuery("<option/>",{value:a.valueOf(),text:Sao.common.format_datetime(e,"%H:%M:%S.%f",a)+" "+this.title}))}.bind(this)),this.el.modal("show"),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},response:function(a){var b=null;"RESPONSE_OK"==a&&(b=this.select.val())&&(b=Sao.DateTime(parseInt(b,10))),this.el.modal("hide"),this.callback(b)}}),Sao.Window.CSV=Sao.class_(Object,{init:function(a){this.encodings=["866","ansi_x3.4-1968","arabic","ascii","asmo-708","big5","big5-hkscs","chinese","cn-big5","cp1250","cp1251","cp1252","cp1253","cp1254","cp1255","cp1256","cp1257","cp1258","cp819","cp866","csbig5","cseuckr","cseucpkdfmtjapanese","csgb2312","csibm866","csiso2022jp","csiso2022kr","csiso58gb231280","csiso88596e","csiso88596i","csiso88598e","csiso88598i","csisolatin1","csisolatin2","csisolatin3","csisolatin4","csisolatin5","csisolatin6","csisolatin9","csisolatinarabic","csisolatincyrillic","csisolatingreek","csisolatinhebrew","cskoi8r","csksc56011987","csmacintosh","csshiftjis","cyrillic","dos-874","ecma-114","ecma-118","elot_928","euc-jp","euc-kr","gb18030","gb2312","gb_2312","gb_2312-80","gbk","greek","greek8","hebrew","hz-gb-2312","ibm819","ibm866","iso-2022-cn","iso-2022-cn-ext","iso-2022-jp","iso-2022-kr","iso-8859-1","iso-8859-10","iso-8859-11","iso-8859-13","iso-8859-14","iso-8859-15","iso-8859-16","iso-8859-2","iso-8859-3","iso-8859-4","iso-8859-5","iso-8859-6","iso-8859-6-e","iso-8859-6-i","iso-8859-7","iso-8859-8","iso-8859-8-e","iso-8859-8-i","iso-8859-9","iso-ir-100","iso-ir-101","iso-ir-109","iso-ir-110","iso-ir-126","iso-ir-127","iso-ir-138","iso-ir-144","iso-ir-148","iso-ir-149","iso-ir-157","iso-ir-58","iso8859-1","iso8859-10","iso8859-11","iso8859-13","iso8859-14","iso8859-15","iso8859-2","iso8859-3","iso8859-4","iso8859-5","iso8859-6","iso8859-7","iso8859-8","iso8859-9","iso88591","iso885910","iso885911","iso885913","iso885914","iso885915","iso88592","iso88593","iso88594","iso88595","iso88596","iso88597","iso88598","iso88599","iso_8859-1","iso_8859-15","iso_8859-1:1987","iso_8859-2","iso_8859-2:1987","iso_8859-3","iso_8859-3:1988","iso_8859-4","iso_8859-4:1988","iso_8859-5","iso_8859-5:1988","iso_8859-6","iso_8859-6:1987","iso_8859-7","iso_8859-7:1987","iso_8859-8","iso_8859-8:1988","iso_8859-9","iso_8859-9:1989","koi","koi8","koi8-r","koi8-ru","koi8-u","koi8_r","korean","ks_c_5601-1987","ks_c_5601-1989","ksc5601","ksc_5601","l1","l2","l3","l4","l5","l6","l9","latin1","latin2","latin3","latin4","latin5","latin6","logical","mac","macintosh","ms932","ms_kanji","shift-jis","shift_jis","sjis","sun_eu_greek","tis-620","unicode-1-1-utf-8","us-ascii","utf-16","utf-16be","utf-16le","utf-8","utf8","visual","windows-1250","windows-1251","windows-1252","windows-1253","windows-1254","windows-1255","windows-1256","windows-1257","windows-1258","windows-31j","windows-874","windows-949","x-cp1250","x-cp1251","x-cp1252","x-cp1253","x-cp1254","x-cp1255","x-cp1256","x-cp1257","x-cp1258","x-euc-jp","x-gbk","x-mac-cyrillic","x-mac-roman","x-mac-ukrainian","x-sjis","x-user-defined","x-x-big5"],this.dialog=new Sao.Dialog(a,"csv","lg"),this.el=this.dialog.modal,this.fields={},this.fields_model={},jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(this.dialog.footer),jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).click(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)).appendTo(this.dialog.footer);var b=jQuery("<div/>",{class:"row"}).appendTo(this.dialog.body);jQuery("<hr/>").appendTo(this.dialog.body);var c=jQuery("<div/>",{class:"col-md-4 column-fields"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("All Fields")})).appendTo(b);this.fields_all=jQuery("<ul/>",{class:"list-unstyled"}).css("cursor","pointer").appendTo(c);var d=this.get_fields(this.screen.model_name).then(function(a){this.model_populate(a),this.view_populate(this.fields_model,this.fields_all)}.bind(this));this.column_buttons=jQuery("<div/>",{class:"col-md-4"}).append("<label/>").appendTo(b);jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-plus"})).click(function(){this.fields_all.find(".bg-primary").each(function(a,b){this.sig_sel_add(b)}.bind(this))}.bind(this)).append(" "+Sao.i18n.gettext("Add")).appendTo(this.column_buttons);jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-minus"})).click(function(){this.fields_selected.children("li.bg-primary").remove()}.bind(this)).append(" "+Sao.i18n.gettext("Remove")).appendTo(this.column_buttons),jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-remove"})).click(function(){this.fields_selected.empty()}.bind(this)).append(" "+Sao.i18n.gettext("Clear")).appendTo(this.column_buttons),jQuery("<hr>").appendTo(this.column_buttons);var e=jQuery("<div/>",{class:"col-md-4 column-fields"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("Fields Selected")})).appendTo(b);this.fields_selected=jQuery("<ul/>",{class:"list-unstyled"}).css("cursor","pointer").appendTo(e),this.chooser_form=jQuery("<div/>",{class:"form-inline"}).appendTo(this.dialog.body);var f=jQuery("<div/>",{class:"row"}).appendTo(this.dialog.body),g=jQuery("<span/>",{class:"glyphicon glyphicon-plus"}).css("cursor","pointer").html(" "),h=jQuery("<label/>",{text:Sao.i18n.gettext("CSV Parameters")}).css("cursor","pointer");jQuery("<div/>",{class:"col-md-12"}).append(g).append(h).on("click",function(){g.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),this.expander_csv.collapse("toggle")}.bind(this)).appendTo(f),this.expander_csv=jQuery("<div/>",{id:"expander_csv",class:"collapse"}).appendTo(f);var i=jQuery("<label/>",{text:Sao.i18n.gettext("Delimiter:"),class:"col-sm-2 control-label",for:"input-delimiter"});this.el_csv_delimiter=jQuery("<input/>",{type:"text",class:"form-control",id:"input-delimiter",size:"1",maxlength:"1",value:","}),jQuery("<div/>",{class:"form-group"}).append(i).append(jQuery("<div/>",{class:"col-sm-4"}).append(this.el_csv_delimiter)).appendTo(this.expander_csv);var j=jQuery("<label/>",{text:Sao.i18n.gettext("Quote Char:"),class:"col-sm-2 control-label",for:"input-quotechar"});this.el_csv_quotechar=jQuery("<input/>",{type:"text",class:"form-control",id:"input-quotechar",size:"1",maxlength:"1",value:'"'}),jQuery("<div/>",{class:"form-group"}).append(j).append(jQuery("<div/>",{class:"col-sm-4"}).append(this.el_csv_quotechar)).appendTo(this.expander_csv);var k=jQuery("<label/>",{text:Sao.i18n.gettext("Encoding:"),class:"col-sm-2 control-label",for:"input-encoding"});this.el_csv_encoding=jQuery("<select/>",{class:"form-control",id:"input-encoding"});for(var l=0;l<this.encodings.length;l++)jQuery("<option/>",{val:this.encodings[l]}).html(this.encodings[l]).appendTo(this.el_csv_encoding);var m="utf-8";return"Win32"!=navigator.platform&&"Windows"!=navigator.platform||(m="cp1252"),this.el_csv_encoding.children('option[value="'+m+'"]').attr("selected","selected"),jQuery("<div/>",{class:"form-group"}).append(k).append(jQuery("<div/>",{class:"col-sm-4"}).append(this.el_csv_encoding)).appendTo(this.expander_csv),this.el.modal("show"),this.el.on("hidden.bs.modal",function(){jQuery(this).remove()}),d},get_fields:function(a){return Sao.rpc({method:"model."+a+".fields_get"},this.session)},on_row_expanded:function(a){var b=jQuery("<ul/>").css("list-style","none").insertAfter(a.view);this.children_expand(a).done(function(){this.view_populate(a.children,b)}.bind(this))},destroy:function(){this.el.modal("hide")}}),Sao.Window.Import=Sao.class_(Sao.Window.CSV,{init:function(a){this.screen=a,this.session=Sao.Session.current_session,this.fields_data={},this.fields_invert={},Sao.Window.Import._super.init.call(this,Sao.i18n.gettext("Import from CSV")),jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-search"})).click(function(){this.autodetect()}.bind(this)).append(" "+Sao.i18n.gettext("Auto-Detect")).appendTo(this.column_buttons);var b=jQuery("<label/>",{text:Sao.i18n.gettext("File to Import"),class:"col-sm-6 control-label",for:"input-csv-file"});this.file_input=jQuery("<input/>",{type:"file",id:"input-csv-file"}),jQuery("<div/>",{class:"form-group"}).append(b).append(jQuery("<div/>",{class:"col-sm-6"}).append(this.file_input)).appendTo(this.chooser_form),jQuery("<hr>").insertAfter(this.chooser_form);var c=jQuery("<label/>",{text:Sao.i18n.gettext("Lines to Skip:"),class:"col-sm-2 control-label",for:"input-skip"});this.el_csv_skip=jQuery("<input/>",{type:"number",class:"form-control",id:"input-skip",value:"0"}),jQuery("<div/>",{class:"form-group"}).append(c).append(jQuery("<div/>",{class:"col-sm-4"}).append(this.el_csv_skip)).appendTo(this.expander_csv)},sig_sel_add:function(a){a=jQuery(a);var b=a.attr("field"),c=jQuery("<li/>",{field:b}).html(a.attr("name")).click(function(a){a.ctrlKey?c.toggleClass("bg-primary"):jQuery(a.target).addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},view_populate:function(a,b){Object.keys(a).sort(function(b,c){return a[c].string<a[b].string?-1:1}).reverse().forEach(function(c){var d=a[c].string||c,e=jQuery("<li/>",{field:a[c].field,name:a[c].name}).html(d).click(function(a){a.ctrlKey?e.toggleClass("bg-primary"):(this.fields_all.find("li").removeClass("bg-primary"),e.addClass("bg-primary"))}.bind(this)).appendTo(b);if(a[c].view=e,a[c].relation){e.prepend(" ");var f=jQuery("<i/>",{class:"glyphicon glyphicon-plus"}).click(function(b){b.stopPropagation(),f.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),f.hasClass("glyphicon-minus")?this.on_row_expanded(a[c]):e.next("ul").remove()}.bind(this)).prependTo(e)}}.bind(this))},model_populate:function(a,b,c,d){b=b||this.fields_model,c=c||"",d=d||"",Object.keys(a).forEach(function(e){if(!a[e].readonly){var f=a[e].string||e;f=d+f;var g;g="one2many"==a[e].type?a[e].relation:null;var h={name:f,field:c+e,relation:g,string:a[e].string};b[e]=h,this.fields[c+e]=h,this.fields_invert[f]=c+e,g&&(h.children={})}}.bind(this))},children_expand:function(a){var b=jQuery.Deferred();return jQuery.isEmptyObject(a.children)?this.get_fields(a.relation).done(function(c){
+this.model_populate(c,a.children,a.field+"/",a.name+"/"),b.resolve(this)}.bind(this)):b.resolve(this),b.promise()},autodetect:function(){if(!this.file_input.val())return void Sao.common.message.run(Sao.i18n.gettext("You must select an import file first"));this.fields_selected.empty(),this.el_csv_skip.val(1),Papa.parse(this.file_input[0].files[0],{config:{delimiter:this.el_csv_delimiter.val(),quoteChar:this.el_csv_quotechar.val(),preview:1,encoding:this.el_csv_encoding.val()},error:function(a,b,c,d){Sao.common.warning(Sao.i18n.gettext("Error occured in loading the file"))},complete:function(a){a.data[0].forEach(function(a){if(a in this.fields_invert||a in this.fields)this.auto_select(a);else{var b=this.fields_model,c=a.split("/");this.traverse(b,"",c,0)}}.bind(this))}.bind(this)})},auto_select:function(a){var b,c;if(a in this.fields_invert)b=a,c=this.fields_invert[a];else{if(!(a in this.fields))return void Sao.common.warning.run(Sao.i18n.gettext("Error processing the file at field %1.",a),Sao.i18n.gettext("Error"));b=this.fields[a].name,c=[a]}var d=jQuery("<li/>",{field:c}).html(b).click(function(){d.addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},traverse:function(a,b,c,d){function e(e){a=f.children,b+=c[d]+"/",e.traverse(a,b,c,++d)}if(d>=c.length-1)return void this.auto_select(c.join("/"));var f,g,h=Object.keys(a);for(g=0;g<h.length;g++)if(f=a[h[g]],f.name==b+c[d]||f.field==b+c[d]){this.children_expand(f).done(e);break}return g==h.length?void this.auto_select(c.join("/")):void 0},response:function(a){if("RESPONSE_OK"==a){var b=[];this.fields_selected.children("li").each(function(a,c){b.push(c.getAttribute("field"))});var c=this.file_input.val();c?this.import_csv(c,b).then(function(){this.destroy()}.bind(this)):this.destroy()}else this.destroy()},import_csv:function(a,b){var c=this.el_csv_skip.val(),d=this.el_csv_encoding.val(),e=jQuery.Deferred();return Papa.parse(this.file_input[0].files[0],{config:{delimiter:this.el_csv_delimiter.val(),quoteChar:this.el_csv_quotechar.val(),encoding:d},error:function(a,b,c,d){Sao.common.warning.run(Sao.i18n.gettext("Error occured in loading the file")).always(e.reject)},complete:function(a){function d(a){return unescape(encodeURIComponent(a))}var f=[];a.data.pop(""),a.data.forEach(function(a,b){if(!(b<c)){var e=[];a.forEach(function(a){e.push(d(a))}),f.push(e)}}),Sao.rpc({method:"model."+this.screen.model_name+".import_data",params:[b,f,{}]},this.session).then(function(a){return Sao.common.message.run(Sao.i18n.ngettext("%1 record imported","%1 records imported",a))}).then(e.resolve,e.reject)}.bind(this)}),e.promise()}}),Sao.Window.Export=Sao.class_(Sao.Window.CSV,{init:function(a,b,c,d){this.ids=b,this.screen=a,this.session=Sao.Session.current_session,this.context=d,Sao.Window.Export._super.init.call(this,Sao.i18n.gettext("Export to CSV")).then(function(){c.forEach(function(a){this.sel_field(a)}.bind(this))}.bind(this));var e=jQuery("<div/>",{class:"row"}).prependTo(this.dialog.body),f=jQuery("<div/>",{class:"col-md-12"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("Predefined Exports")})).appendTo(e);this.predef_exports_list=jQuery("<ul/>",{class:"list-unstyled predef-exports"}).css("cursor","pointer").appendTo(f),f.append("<hr/>"),this.predef_exports={},this.fill_predefwin(),jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-floppy-save"})).click(function(){this.addreplace_predef()}.bind(this)).append(" "+Sao.i18n.gettext("Save Export")).appendTo(this.column_buttons),jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-floppy-remove"})).click(function(){this.remove_predef()}.bind(this)).append(" "+Sao.i18n.gettext("Delete Export")).appendTo(this.column_buttons),this.el_add_field_names=jQuery("<input/>",{type:"checkbox",checked:"checked"}),jQuery("<div/>",{class:"form-group"}).append(jQuery("<div/>",{class:"col-md-6"}).append(jQuery("<label/>",{text:" "+Sao.i18n.gettext("Add Field Names")}).prepend(this.el_add_field_names))).appendTo(this.expander_csv)},view_populate:function(a,b){Object.keys(a).sort(function(b,c){return a[c].string<a[b].string?-1:1}).reverse().forEach(function(c){var d=a[c].path,e=jQuery("<li/>",{path:d}).html(a[c].string).click(function(a){a.ctrlKey?e.toggleClass("bg-primary"):(this.fields_all.find("li").removeClass("bg-primary"),e.addClass("bg-primary"))}.bind(this)).appendTo(b);if(a[c].view=e,a[c].children){e.prepend(" ");var f=jQuery("<i/>",{class:"glyphicon glyphicon-plus"}).click(function(b){b.stopPropagation(),f.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),f.hasClass("glyphicon-minus")?this.on_row_expanded(a[c]):e.next("ul").remove()}.bind(this)).prependTo(e)}}.bind(this))},model_populate:function(a,b,c,d){b=b||this.fields_model,c=c||"",d=d||"",Object.keys(a).forEach(function(e){var f=a[e],g=f.string||e,h=[{name:e,field:f,string:g}];"selection"==f.type&&h.push({name:e+".translated",field:f,string:Sao.i18n.gettext("%1 (string)",g)}),h.forEach(function(a){var e=c+a.name,f=a.string;c&&(f=d+a.string);var g={path:e,string:a.string,long_string:f,relation:a.field.relation};b[a.name]=g,this.fields[e]=g,-1==a.name.indexOf(".")&&a.field.relation&&(g.children={})}.bind(this))}.bind(this))},children_expand:function(a){var b=jQuery.Deferred();return jQuery.isEmptyObject(a.children)?this.get_fields(a.relation).done(function(c){this.model_populate(c,a.children,a.path+"/",a.string+"/"),b.resolve(this)}.bind(this)):b.resolve(this),b.promise()},sig_sel_add:function(a){a=jQuery(a);var b=a.attr("path");this.sel_field(b)},fill_predefwin:function(){Sao.rpc({method:"model.ir.export.search",params:[["resource","=",this.screen.model_name],{}]},this.session).done(function(a){Sao.rpc({method:"model.ir.export.read",params:[a,{}]},this.session).done(function(a){var b=[];a.forEach(function(a){for(var c=0;c<a.export_fields.length;b.push(a.export_fields[c++]));}),Sao.rpc({method:"model.ir.export.line.read",params:[b,{}]},this.session).done(function(b){var c={};b.forEach(function(a){c[a.export]=c[a.export]||[],c[a.export].push(a)}),a.forEach(function(a){this.predef_exports[a.id]=c[a.id].map(function(b){if(b.export==a.id)return b.name}),this.add_to_predef(a.id,a.name)}.bind(this)),this.predef_exports_list.children("li").first().focus()}.bind(this))}.bind(this))}.bind(this))},add_to_predef:function(a,b){var c=jQuery("<li/>",{text:b,export_id:a,tabindex:0}).on("keypress",function(a){var b=a.keyCode?a.keyCode:a.which;13!=b&&32!=b||c.click()}).click(function(a){c.addClass("bg-primary").siblings().removeClass("bg-primary"),this.sel_predef(jQuery(a.target).attr("export_id"))}.bind(this));this.predef_exports_list.append(c)},addreplace_predef:function(){for(var a=[],b=this.fields_selected.children("li"),c=0;c<b.length;c++)a.push(b[c].getAttribute("path"));if(0!==a.length){var d,e,f=this.predef_exports_list.children("li.bg-primary");0===f.length?(d=null,Sao.common.ask.run(Sao.i18n.gettext("What is the name of this export?")).then(function(b){b&&this.save_predef(b,a,f)}.bind(this))):(d=f.attr("export_id"),e=f.text(),Sao.common.sur.run(Sao.i18n.gettext("Override %1 definition?",e)).done(function(){this.save_predef(e,a,f),Sao.rpc({method:"model.ir.export.delete",params:[[d],{}]},this.session).then(function(){delete this.predef_exports[d]}.bind(this))}.bind(this)))}},save_predef:function(a,b,c){Sao.rpc({method:"model.ir.export.create",params:[[{name:a,resource:this.screen.model_name,export_fields:[["create",b.map(function(a){return{name:a}})]]}],{}]},this.session).then(function(d){this.predef_exports[d]=b,0===c.length?this.add_to_predef(d,a):(this.predef_exports[d]=b,c.attr("export_id",d))}.bind(this))},remove_predef:function(){var a=this.predef_exports_list.children("li.bg-primary");if(0!==a.length){var b=jQuery(a).attr("export_id");Sao.rpc({method:"model.ir.export.delete",params:[[b],{}]},this.session).then(function(){delete this.predef_exports[b],a.remove()}.bind(this))}},sel_predef:function(a){this.fields_selected.empty(),this.predef_exports[a].forEach(function(a){if(!(a in this.fields)){var b=this.fields_model,c=a.split("/");this.traverse(b,"",c,0)}a in this.fields&&this.sel_field(a)}.bind(this))},traverse:function(a,b,c,d){function e(e){a=f.children,b+=c[d]+"/",e.traverse(a,b,c,++d)}if(d>=c.length-1)return void this.sel_field(c.join("/"));var f,g,h=Object.keys(a);for(g=0;g<h.length;g++)if(f=a[h[g]],f.path==b+c[d]){this.children_expand(f).done(e);break}return g==h.length?void this.sel_field(c.join("/")):void 0},sel_field:function(a){var b=this.fields[a].long_string;if(!this.fields[a].relation)var c=jQuery("<li/>",{path:a}).html(b).click(function(a){a.ctrlKey?c.toggleClass("bg-primary"):jQuery(a.target).addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},response:function(a){if("RESPONSE_OK"==a){var b=[],c=[];this.fields_selected.children("li").each(function(a,d){b.push(d.getAttribute("path")),c.push(d.innerText)}),Sao.rpc({method:"model."+this.screen.model_name+".export_data",params:[this.ids,b,this.context]},this.session).then(function(a){this.export_csv(c,a).then(function(){this.destroy()}.bind(this))}.bind(this))}else this.destroy()},export_csv:function(a,b){var c=this.el_csv_encoding.val(),d={};d.data=b,this.el_add_field_names.is(":checked")&&(d.fields=a);var e=Papa.unparse(d,{quoteChar:this.el_csv_quotechar.val(),delimiter:this.el_csv_delimiter.val()}),f=new Blob([e],{type:"text/csv;charset="+c}),g=window.URL.createObjectURL(f);return this.blob_url&&window.URL.revokeObjectURL(this.blob_url),this.blob_url=g,window.open(g),Sao.common.message.run(Sao.i18n.ngettext("%1 record saved","%1 records saved",b.length))}})}(),function(){"use strict";Sao.Wizard=Sao.class_(Object,{init:function(a){this.widget=jQuery("<div/>",{class:"wizard"}),this.name=a||"",this.action_id=null,this.id=null,this.ids=null,this.action=null,this.context=null,this.states={},this.session_id=null,this.start_state=null,this.end_state=null,this.screen=null,this.screen_state=null,this.state=null,this.session=Sao.Session.current_session,this.__processing=!1,this.__waiting_response=!1,this.info_bar=new Sao.Window.InfoBar},run:function(a){this.action=a.action,this.action_id=a.data.action_id,this.id=a.data.id,this.ids=a.data.ids,this.model=a.data.model,this.context=a.context,Sao.rpc({method:"wizard."+this.action+".create",params:[this.session.context]},this.session).then(function(a){this.session_id=a[0],this.start_state=this.state=a[1],this.end_state=a[2],this.process()}.bind(this),function(){this.destroy()}.bind(this))},process:function(){if(!this.__processing&&!this.__waiting_response){(function(){if(this.state==this.end_state)return void this.end();var a=jQuery.extend({},this.context);a.active_id=this.id,a.active_ids=this.ids,a.active_model=this.model,a.action_id=this.action_id;var b={};this.screen&&(b[this.screen_state]=this.screen.get_on_change_value()),Sao.rpc({method:"wizard."+this.action+".execute",params:[this.session_id,b,this.state,a]},this.session).then(function(a){if(a.view){this.clean();var b=a.view;this.update(b.fields_view,b.defaults,b.buttons),this.screen_state=b.state,this.__waiting_response=!0}else this.state=this.end_state;var c=function(){a.actions&&a.actions.forEach(function(a){Sao.Action.exec_action(a[0],a[1],jQuery.extend({},this.context))}.bind(this))}.bind(this);this.state==this.end_state?this.end().then(c):c(),this.__processing=!1}.bind(this),function(a){this.__processing=!1}.bind(this))}).call(this)}},destroy:function(){},end:function(){return Sao.rpc({method:"wizard."+this.action+".delete",params:[this.session_id,this.session.context]},this.session)},clean:function(){this.widget.children().remove(),this.states={}},response:function(a){return this.__waiting_response=!1,this.screen.current_view.set_value(),this.screen.current_record.validate().then(function(b){if(!b&&a!=this.end_state)return this.screen.display(!0),void this.info_bar.message(this.screen.invalid_message(),"danger");this.info_bar.message(),this.state=a,this.process()}.bind(this))},_get_button:function(a){var b=new Sao.common.Button(a);return this.states[a.state]=b,a.default?b.el.addClass("btn-primary"):a.state==this.end_state&&b.el.addClass("btn-link"),b},update:function(a,b,c){c.forEach(function(a){this._get_button(a)}.bind(this)),this.screen=new Sao.Screen(a.model,{mode:[],context:this.context}),this.screen.add_view(a),this.screen.switch_view(),this.widget.append(this.screen.screen_container.el),this.screen.new_(!1),this.screen.current_record.set_default(b),this.screen.set_cursor()}}),Sao.Wizard.create=function(a){var b;if(a.window){b=new Sao.Wizard.Form(a.name);var c=new Sao.Tab.Wizard(b);Sao.Tab.add(c)}else b=new Sao.Wizard.Dialog(a.name);b.run(a)},Sao.Wizard.Form=Sao.class_(Sao.Wizard,{init:function(a){Sao.Wizard.Form._super.init.call(this),this.tab=null,this.name=a||"",this.form=jQuery("<div/>",{class:"wizard-form"}).append(this.widget),this.footer=jQuery("<div/>",{class:"modal-footer"}).appendTo(this.form)},clean:function(){Sao.Wizard.Form._super.clean.call(this),this.footer.children().remove()},_get_button:function(a){var b=Sao.Wizard.Form._super._get_button.call(this,a);return this.footer.append(b.el),b.el.click(function(){this.response(a.state)}.bind(this)),b},end:function(){return Sao.Wizard.Form._super.end.call(this).always(function(){return this.tab.close()}.bind(this))}}),Sao.Wizard.Dialog=Sao.class_(Sao.Wizard,{init:function(a){a||(a=Sao.i18n.gettext("Wizard")),Sao.Wizard.Dialog._super.init.call(this);var b=new Sao.Dialog(a,"wizard-dialog","lg");this.dialog=b.modal,this.dialog.on("shown.bs.modal",function(){Sao.View.resize(jQuery(this))}),this.content=b.content,this.footer=b.footer,b.body.append(this.widget).append(this.info_bar.el)},clean:function(){Sao.Wizard.Dialog._super.clean.call(this),this.footer.children().remove()},_get_button:function(a){var b=Sao.Wizard.Dialog._super._get_button.call(this,a);return this.footer.append(b.el),a.default?(this.content.unbind("submit"),this.content.submit(function(b){this.response(a.state),b.preventDefault()}.bind(this)),b.el.attr("type","submit")):b.el.click(function(){this.response(a.state)}.bind(this)),b},update:function(a,b,c){this.content.unbind("submit"),Sao.Wizard.Dialog._super.update.call(this,a,b,c),this.dialog.modal("show")},destroy:function(a){Sao.Wizard.Dialog._super.destroy.call(this),this.dialog.on("hidden.bs.modal",function(b){this.dialog.remove();var c,d=jQuery(".wizard-dialog").filter(":visible")[0],e=!1;if(d||(d=Sao.Tab.tabs.get_current(),d?d.screen&&d.screen.model_name!=this.model&&(e=!0,c=Sao.main_menu_screen):(e=!0,c=Sao.main_menu_screen)),d&&d.screen&&(c=d.screen),c){if(c.current_record&&!e){var f;f=c.model_name==this.model?this.ids:[c.current_record.id],c.reload(f,!0)}a&&c.client_action(a)}}.bind(this)),this.dialog.modal("hide")},end:function(){return Sao.Wizard.Dialog._super.end.call(this).then(this.destroy.bind(this))},show:function(){this.dialog.modal("show")},hide:function(){this.dialog.modal("hide")},state_changed:function(){this.process()}})}(),function(){"use strict";Sao.View.Board=Sao.class_(Object,{init:function(a,b){var c,d,e,f;this.context=b,this.actions=[],this.el=jQuery("<div/>",{class:"board"}),c={},e=a.children()[0];for(var g=0,h=e.attributes.length;g<h;g++)d=e.attributes[g],c[d.name]=d.value;for(this.attributes=c,this.el.append(this.parse(e).el),f=[],g=0,h=this.actions.length;g<h;g++)f.push(this.actions[g].action_prm);this.actions_prms=jQuery.when.apply(jQuery,f)},_parse_node:function(a,b,c){switch(a.tagName){case"image":break;case"separator":this._parse_separator(a,b,c);break;case"label":this._parse_label(a,b,c);break;case"newline":b.add_row();break;case"notebook":this._parse_notebook(a,b,c);break;case"page":this._parse_page(a,b,c);break;case"group":this._parse_group(a,b,c);break;case"hpaned":this._parse_pane(a,b,c,"horizontal");break;case"vpaned":this._parse_pane(a,b,c,"vertical");break;case"child":this._parse_child(a,b,c);break;case"action":this._parse_action(a,b,c)}},parse:function(a,b){var c;return b||(b=new Sao.View.Form.Container(Number(a.getAttribute("col")||4))),c=function(a,c){var d,e,f,g;for(d={},f=0,g=c.attributes.length;f<g;f++)e=c.attributes[f],d[e.name]=e.value;["yexpand","yfill","xexpand","xfill","colspan","position"].forEach(function(a){d[a]&&(d[a]=Number(d[a]))}),this._parse_node(c,b,d)},jQuery(a).children().each(c.bind(this)),b},_parse_separator:function(a,b,c){var d,e;d=c.string,e=new Sao.view.Form.Separator(d,c),b.add(c,e)},_parse_label:function(a,b,c){var d,e;if(!(d=c.string))return void b.add(c);e=new Sao.View.Form.Label(d,c),b.add(c,e)},_parse_notebook:function(a,b,c){var d;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),d=new Sao.View.Form.Notebook(c),b.add(c,d),this.parse(a,b)},_parse_page:function(a,b,c){var d;d=c.string,page=this.parse(a,b),page=new Sao.View.Form.Page(b.add(page.el,d),c)},_parse_group:function(a,b,c){var d;d=new Sao.View.Form.Group(c),b.add(c,d)},_parse_pane:function(a,b,c,d){var e;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),e=new Sao.common.Paned(d),b.add(c,e),this.parse(a,e)},_parse_child:function(a,b,c){var d,e,f;d=this.parse(a),e=b.get_child1(),e.children().length>0?(f=b.get_child2(),f.append(d.el)):e.append(d.el)},_parse_action:function(a,b,c){var d;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),d=new Sao.View.Board.Action(c,this.context),this.actions.push(d),b.add(c,d)},reload:function(){for(var a=0;a<this.actions.length;a++)this.actions[a].display()}}),Sao.View.Board.Action=Sao.class_(Object,{init:function(a,b){void 0===b&&(b={});var c,d;this.name=a.name,this.context=jQuery.extend({},b),c=new Sao.Model("ir.action.act_window"),this.action_prm=c.execute("get",[this.name],this.context),this.action_prm.done(function(b){var c,e,f,g,h,i;if(this.action=b,this.action.mode=[],f=[],(this.action.views||[]).length>0)for(c=0,e=this.action.views.length;c<e;c++)f.push(this.action.views[c][0]),this.action.mode.push(this.action.views[c][1]);else void 0!==this.action.view_id&&(f=[this.action.view_id[0]]);"mode"in a&&(this.action.mode=a.mode),"pyson_domain"in this.action||(this.action.pyson_domain="[]"),jQuery.extend(this.context,Sao.Session.current_session.context),this.context._user=Sao.Session.current_session.user_id,g=new Sao.PYSON.Decoder(this.context),jQuery.extend(this.context,g.decode(this.action.pyson_context||"{}")),g=new Sao.PYSON.Decoder(this.context),jQuery.extend(this.context,g.decode(this.action.pyson_context||"{}")),this.domain=[],this.update_domain([]),h=jQuery.extend({},this.context),h.context=this.context,h._user=Sao.Session.current_session.user_id,g=new Sao.PYSON.Decoder(h),d=g.decode(this.action.pyson_search_value||"{}"),i={mode:this.action.mode,context:this.context,view_ids:f,domain:this.domain,search_value:d,row_activate:this.row_activate.bind(this)},this.screen=new Sao.Screen(this.action.res_model,i),a.string?this.title.html(a.string):this.title.html(this.action.name),this.screen.switch_view().done(function(){this.body.append(this.screen.screen_container.el),this.screen.search_filter()}.bind(this))}.bind(this)),this.el=jQuery("<div/>",{class:"board-action panel panel-default"}),this.title=jQuery("<div/>",{class:"panel-heading"}),this.el.append(this.title),this.body=jQuery("<div/>",{class:"panel-body"}),this.el.append(this.body)},row_activate:function(){var a;this.screen.current_record&&("tree"==this.screen.current_view.view_type&&1==this.screen.current_view.attributes.keyword_open?(a=this.screen.current_view.selected_records().map(function(a){return a.id}),Sao.Action.exec_keyword("tree_open",{model:this.screen.model_name,id:this.screen.current_record.id,ids:a},jQuery.extend({},this.context),!1)):new Sao.Window.Form(this.screen,function(a){a?this.screen.current_record.save():this.screen.current_record.cancel()}.bind(this)))},set_value:function(){},display:function(){this.screen.search_filter(this.screen.screen_container.get_text())},get_active:function(){if(this.screen&&this.screen.current_record)return Sao.common.EvalEnvironment(this.screen.current_record)},update_domain:function(a){var b,c,d,e,f,g;for(e=jQuery.extend({},this.context),e.context=e,e._user=Sao.Session.current_session.user_id,b=0,c=a.length;b<c;b++)(d=a[b].get_active())&&(e[a[b].name]=d);f=new Sao.PYSON.Decoder(e),g=f.decode(this.action.pyson_domain),Sao.common.compare(this.domain,g)||(this.domain.splice(0,this.domain.length),jQuery.extend(this.domain,g),this.screen&&this.display())}})}();
\ No newline at end of file
diff --git a/locale/bg_BG.json b/locale/bg_BG.json
deleted file mode 100644
index 9fb066f..0000000
--- a/locale/bg_BG.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/ca_ES.json b/locale/ca_ES.json
deleted file mode 100644
index 2e73d63..0000000
--- a/locale/ca_ES.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,"Sortir"],"Search...":[null,"Cerca..."],"Unable to reach the server":[null,"No ha estat possible connectar-se al servidor."],"Unable to reach the server.":[null,"No ha estat possible connectar-se al servidor."],"Login":[null,"Identificació"],"Password":[null,"Contrasenya"],"Database":[null,"Base de dades"],"OK":[null,"OK"],"Toggle navigation":[null,"Commuta navegació"],"Menu":[null,"Menú"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"L'acció seleccionada requereix tancar totes les pestanyes.\nVoleu continuar?"],"Close":[null,"Tanca"],"New":[null,"Nou"],"Create a new record":[null,"Crea un nou registre"],"Save":[null,"Desa"],"Save this record":[null,"Desa aquest registre"],"Switch":[null,"Canvia"],"Switch view":[null,"Canvia la vista"],"Reload":[null,"Recarrega"],"Previous":[null,"Registre anterior"],"Previous Record":[null,"Registre següent"],"Next":[null,"Següent"],"Next Record":[null,"Següent registre"],"Attachment":[null,"Adjunt"],"Add an attachment to the record":[null,"Afegeix un adjunt en el registre"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"Refresca/Desfés"],"Duplicate":[null,"Duplica"],"Delete":[null,"Elimina"],"Search":[null,"Cerca"],"View Logs...":[null,"Veure registre..."],"Show revisions...":[null,"Mostra revisions..."],"Close Tab":[null,"Tanca pestanya"],"Action":[null,"Acció"],"Relate":[null,"Relacionat"],"Print":[null,"Imprimeix"],"Launch action":[null,"Executa acció"],"Open related records":[null,"Obra registres relacionats"],"Print report":[null,"Imprimeix informe"],"This record has been modified\ndo you want to save it?":[null,"Aquest registre ha estat modificat mentre l'editàveu\nel voleu desar?"],"Record saved.":[null,"Registre desat"],"Working now on the duplicated record(s).":[null,"Està treballant amb un registre(s) duplicat."],"Are you sure to remove this record?":[null,"Esteu segurs d'eliminar aquest registre?"],"Are you sure to remove those records?":[null,"Esteu segurs d'eliminar aquests registres?"],"Records removed.":[null,"Registres eliminats"],"Records not removed.":[null,"Registres no eliminats"],"You have to select one record.":[null,"Ha de seleccionar un registre"],"ID:":[null,"ID:"],"Creation User:":[null,"Creat per:"],"Creation Date:":[null,"Data de creació:"],"Latest Modification by:":[null,"Última modificació per:"],"Latest Modification Date:":[null,"Última data de modificació:"],"Model: ":[null,"Model:"],"Attachment(%1)":[null,"Adjunt(%1)"],"Note(%1)":[null,""],"Filters":[null,"Filtres"],"Bookmarks":[null,"Cerques preferides"],"Remove this bookmark":[null,"Elimina de les cerques preferides"],"Bookmark this filter":[null,"Desa com a cerca preferida"],"Bookmark Name:":[null,"Nom de la cerca preferida"],"True":[null,"Verdader"],"False":[null,"Fals"],"Find":[null,"Cerca"],"ID":[null,"ID"],"Creation User":[null,"Creat per:"],"Creation Date":[null,"Data de creació:"],"Modification User":[null,"Modificat per"],"Modification Date":[null,"Última data de modificació:"],"\"%1\" is required":[null,"\"%1\" és obligatori."],"\"%1\" is not valid according to its domain":[null,"\"%1\" no és vàlid segons el seu domini."],"The values of \"%1\" are not valid":[null,"Els valors de \"%1\" no són vàlids."],"Pre-validation":[null,"Prevalidació"],"Font":[null,"Tipus de lletra"],"Size":[null,"Mida"],"Add":[null,"Afegeix"],"Remove":[null,"Elimina"],"Open":[null,"Obre"],"Undelete":[null,"Recupera"],"Select":[null,"Selecciona"],"Cancel":[null,"Cancel·la"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Més"],"Calendar view not yet implemented":[null,"La vista de calendari encara no està implementada."],"Warning":[null,"Avís"],"Select your action":[null,"Seleccioneu la vostra acció"],"No action defined!":[null,"No s'ha definit cap acció."],"Your selection:":[null,"La vostra selecció:"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"y":[null,"a"],"yes":[null,"sí"],"true":[null,"cert"],"t":[null,"c"],"Message: ":[null,"Missatge: "],"Warning: ":[null,"Avís: "],"Always ignore this warning.":[null,"Ignora sempre aquest advertiment."],"Do you want to proceed?":[null,"Voleu continuar?"],"No":[null,"No"],"Yes":[null,"Sí"],"Confirmation: ":[null,"Confirmació: "],"Concurrency Exception":[null,"Excepció de concurrència"],"Write Concurrency Warning: ":[null,"Avís de concurrència d'escriptura: "],"This record has been modified while you were editing it.":[null,"Aquest registre ha estat modificat mentre l'editàveu."],"Choose:":[null,"Trieu:"],"\"Cancel\" to cancel saving;":[null,"\"Cancel·la\" per no desar;"],"\"Compare\" to see the modified version;":[null,"\"Compara\" per veure la versió modificada;"],"\"Write Anyway\" to save your current version.":[null,"\"Desa de totes formes\" per desar els vostres canvis."],"Compare":[null,"Compara"],"Write Anyway":[null,"Desa de totes formes"],"Application Error":[null,"Error d'aplicació."],"Report Bug":[null,"Informa de l'error"],"Revision":[null,"Revisió"],"Wizard":[null,"Assistent"]}
\ No newline at end of file
diff --git a/locale/cs_CZ.json b/locale/cs_CZ.json
deleted file mode 100644
index 9fb066f..0000000
--- a/locale/cs_CZ.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/de_DE.json b/locale/de_DE.json
deleted file mode 100644
index a4ec096..0000000
--- a/locale/de_DE.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,"Abmelden"],"Search...":[null,"Suche..."],"Unable to reach the server":[null,"Kann nicht zum Server verbinden"],"Unable to reach the server.":[null,"Kann nicht zum Server verbinden."],"Login":[null,"Anmelden"],"Password":[null,"Passwort"],"Database":[null,"Datenbank"],"OK":[null,"OK"],"Toggle navigation":[null,"Navigation umschalten"],"Menu":[null,"Menü"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"Die folgende Aktion erfordert die Schließung aller Registerkarten.\nFortfahren?"],"Close":[null,"Schließen"],"New":[null,"Neu"],"Create a new record":[null,"Einen neuen Datensatz erstellen"],"Save":[null,"Speichern"],"Save this record":[null,"Diesen Datensatz speichern"],"Switch":[null,"Ansicht wechseln"],"Switch view":[null,"Ansicht wechseln"],"Reload":[null,"Neu laden"],"Previous":[null,"Vorheriger"],"Previous Record":[null,"Vorheriger Datensatz"],"Next":[null,"Nächster"],"Next Record":[null,"Nächster Datensatz"],"Attachment":[null,"Anhang"],"Add an attachment to the record":[null,"Einen Anhang zum Datensatz hinzufügen"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"Neu laden/Rückgängig"],"Duplicate":[null,"Duplizieren"],"Delete":[null,"Löschen"],"Search":[null,"Suchen"],"View Logs...":[null,"Protokoll ansehen..."],"Show revisions...":[null,"Bearbeitungen anzeigen..."],"Close Tab":[null,"Registerkarte schließen"],"Action":[null,"Aktion"],"Relate":[null,"Beziehung"],"Print":[null,"Drucken"],"Launch action":[null,"Aktion ausführen"],"Open related records":[null,"Datensätze einer Beziehung öffnen"],"Print report":[null,"Bericht drucken"],"This record has been modified\ndo you want to save it?":[null,"Datensatz geändert.\nSoll der Datensatz gespeichert werden?"],"Record saved.":[null,"Der Datensatz wurde gespeichert."],"Working now on the duplicated record(s).":[null,"Sie arbeiten nun an dem/den duplizierten Datensatz/Datensätzen."],"Are you sure to remove this record?":[null,"Möchten Sie diesen Datensatz wirklich löschen?"],"Are you sure to remove those records?":[null,"Möchten Sie diese Datensätze wirklich löschen?"],"Records removed.":[null,"Die Datensätze wurden gelöscht."],"Records not removed.":[null,"Die Datensätze wurden nicht gelöscht."],"You have to select one record.":[null,"Ein Datensatz muss ausgewählt werden."],"ID:":[null,"ID:"],"Creation User:":[null,"Erstellt von:"],"Creation Date:":[null,"Erstellt am:"],"Latest Modification by:":[null,"Zuletzt verändert von"],"Latest Modification Date:":[null,"Zuletzt verändert am"],"Model: ":[null,"Modell:"],"Attachment(%1)":[null,"Anhang(%1)"],"Note(%1)":[null,""],"Filters":[null,"Filter"],"Bookmarks":[null,"Lesezeichen"],"Remove this bookmark":[null,"Dieses Lesezeichen entfernen"],"Bookmark this filter":[null,"Diesen Filter als Lesezeichen hinzufügen"],"Bookmark Name:":[null,"Lesezeichenname:"],"True":[null,"Wahr"],"False":[null,"Falsch"],"Find":[null,"Suchen"],"ID":[null,"ID"],"Creation User":[null,"Erstellt von"],"Creation Date":[null,"Erstellt am:"],"Modification User":[null,"Zuletzt verändert von"],"Modification Date":[null,"Zuletzt verändert am"],"\"%1\" is required":[null,"In Feld \"%1\" ist ein Eintrag erforderlich."],"\"%1\" is not valid according to its domain":[null,"\"%1\" liegt nicht im gültigen Wertebereich (Domain)."],"The values of \"%1\" are not valid":[null,"Die Werte von \"%1\" sind ungültig."],"Pre-validation":[null,"Vorvalidierung"],"Font":[null,"Schriftart"],"Size":[null,"Größe"],"Add":[null,"Hinzufügen"],"Remove":[null,"Entfernen"],"Open":[null,"Öffnen"],"Undelete":[null,"Löschung rückgängig machen"],"Select":[null,"Auswählen"],"Cancel":[null,"Abbrechen"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Mehr"],"Calendar view not yet implemented":[null,"Kalenderansicht noch nicht verfügbar"],"Warning":[null,"Warnung"],"Select your action":[null,"Wählen Sie eine Aktion"],"No action defined!":[null,"Keine Aktion angegeben."],"Your selection:":[null,"Ihre Auswahl:"],"Y":[null,"J"],"M":[null,"M"],"w":[null,"W"],"d":[null,"t"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"y":[null,"j"],"yes":[null,"Ja"],"true":[null,"Wahr"],"t":[null,"W"],"Message: ":[null,"Nachricht: "],"Warning: ":[null,"Warnung: "],"Always ignore this warning.":[null,"Diese Warnung immer ignorieren."],"Do you want to proceed?":[null,"Fortfahren?"],"No":[null,"Nein"],"Yes":[null,"Ja"],"Confirmation: ":[null,"Bestätigung: "],"Concurrency Exception":[null,"Aktualisierungskonflikt"],"Write Concurrency Warning: ":[null,"Aktualisierungskonflikt beim Schreiben des aktuellen Datensatzes: "],"This record has been modified while you were editing it.":[null,"Dieser Datensatz wurde anderweitig geändert, während Sie ihn bearbeitet haben."],"Choose:":[null,"Lösungsmöglichkeiten:"],"\"Cancel\" to cancel saving;":[null,"- \"Abbrechen\" um den Speichervorgang abzubrechen,"],"\"Compare\" to see the modified version;":[null,"- \"Vergleichen\" um die geänderte Version des Datensatzes zu betrachten,"],"\"Write Anyway\" to save your current version.":[null,"- \"Überschreiben\" um die gespeicherte Version mit Ihrer Version zu überschreiben."],"Compare":[null,"Vergleichen"],"Write Anyway":[null,"Überschreiben"],"Application Error":[null,"Anwendungsfehler"],"Report Bug":[null,"Fehler berichten"],"Revision":[null,"Bearbeitung"],"Wizard":[null,"Assistent"]}
\ No newline at end of file
diff --git a/locale/fr_FR.json b/locale/fr_FR.json
deleted file mode 100644
index 1ff54f9..0000000
--- a/locale/fr_FR.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,"Déconnexion"],"Search...":[null,"Recherche..."],"Unable to reach the server":[null,"Impossible de joindre le serveur"],"Unable to reach the server.":[null,"Impossible de joindre le serveur."],"Login":[null,"Connexion"],"Password":[null,"Mot de passe"],"Database":[null,"Base de données"],"OK":[null,"Valider"],"Toggle navigation":[null,"Basculer la navigation"],"Menu":[null,"Menu"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"L'action suivante nécessite de fermer tous les onglets.\nVoulez-vous continuer ?"],"Close":[null,"Fermer"],"New":[null,"Nouveau"],"Create a new record":[null,"Crée un nouvel enregistrement"],"Save":[null,"Sauver"],"Save this record":[null,"Sauver cet enregistrement"],"Switch":[null,"Basculer"],"Switch view":[null,"Basculer la vue"],"Reload":[null,"Recharger"],"Previous":[null,"Précédent"],"Previous Record":[null,"Enregistrement précédent"],"Next":[null,"Suivant"],"Next Record":[null,"Enregistrement suivant"],"Attachment":[null,"Attachement"],"Add an attachment to the record":[null,"Ajouter un attachement à l'enregistrement"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"Recharger/Annuler"],"Duplicate":[null,"Dupliquer"],"Delete":[null,"Supprimer"],"Search":[null,"Rechercher"],"View Logs...":[null,"Voir les Logs..."],"Show revisions...":[null,"Afficher les révisions..."],"Close Tab":[null,"Fermer l'onglet"],"Action":[null,"Actions"],"Relate":[null,"Relation"],"Print":[null,"Imprimer"],"Launch action":[null,"Lancer une action"],"Open related records":[null,"Ouvrir les enregistrements liés"],"Print report":[null,"Imprimer un rapport"],"This record has been modified\ndo you want to save it?":[null,"Cet enregistrement a été modifié\nvoulez-vous le sauvegarder ?"],"Record saved.":[null,"Enregistrement sauvé."],"Working now on the duplicated record(s).":[null,"Sur les enregistrement(s) dupliqué(s) maintenant."],"Are you sure to remove this record?":[null,"Êtes-vous sûr de vouloir supprimer cet enregistrement ?"],"Are you sure to remove those records?":[null,"Êtes-vous sûr de vouloir supprimer ces enregistrements ?"],"Records removed.":[null,"Enregistrements supprimés."],"Records not removed.":[null,"Enregistrements non supprimés."],"You have to select one record.":[null,"Vous devez sélectionner un enregistrement."],"ID:":[null,"ID :"],"Creation User:":[null,"Créé par l'utilisateur :"],"Creation Date:":[null,"Date de création :"],"Latest Modification by:":[null,"Dernière modification par :"],"Latest Modification Date:":[null,"Date de dernière modification :"],"Model: ":[null,"Modèle : "],"Attachment(%1)":[null,"Attachement(%1)"],"Note(%1)":[null,""],"Filters":[null,"Filtres"],"Bookmarks":[null,"Marques-pages"],"Remove this bookmark":[null,"Supprimer ce marque-page"],"Bookmark this filter":[null,"Sauver ce filtre"],"Bookmark Name:":[null,"Nom du marque-page :"],"True":[null,"Vrai"],"False":[null,"Faux"],"Find":[null,"Chercher"],"ID":[null,"ID"],"Creation User":[null,"Créé par l'utilisateur"],"Creation Date":[null,"Date de création"],"Modification User":[null,"Modifié par l'utilisateur"],"Modification Date":[null,"Date de modification"],"\"%1\" is required":[null,"« %1 » est requis"],"\"%1\" is not valid according to its domain":[null,"« %1 » n'est pas valide selon son domaine"],"The values of \"%1\" are not valid":[null,"Les valeurs de « %1 » ne sont pas valides"],"Pre-validation":[null,"Pré-validation"],"Font":[null,"Police"],"Size":[null,"Taille"],"Add":[null,"Ajouter"],"Remove":[null,"Enlever"],"Open":[null,"Ouvrir"],"Undelete":[null,"Restaurer"],"Select":[null,"Sélectionner"],"Cancel":[null,"Annuler"],"%1%":[null,"%1%"],":":[null," :"],"More":[null,"Plus"],"Calendar view not yet implemented":[null,"La vue calendrier n'est pas encore implémentée"],"Warning":[null,"Avertissement"],"Select your action":[null,"Sélectionnez votre action"],"No action defined!":[null,"Pas d'action définie !"],"Your selection:":[null,"Votre sélection :"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"j"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"y":[null,"y"],"yes":[null,"oui"],"true":[null,"vrai"],"t":[null,"v"],"Message: ":[null,"Message : "],"Warning: ":[null,"Avertissement : "],"Always ignore this warning.":[null,"Toujours ignorer cet avertissement."],"Do you want to proceed?":[null,"Souhaitez-vous continuer ?"],"No":[null,"Non"],"Yes":[null,"Oui"],"Confirmation: ":[null,"Confirmation : "],"Concurrency Exception":[null,"Erreur d'accès concurrent"],"Write Concurrency Warning: ":[null,"Attention, accès en écriture concurrents : "],"This record has been modified while you were editing it.":[null,"Cet enregistrement a été édité pendant que vous étiez en train de le modifier."],"Choose:":[null,"Choisissez :"],"\"Cancel\" to cancel saving;":[null,"« Annuler » pour annuler vos modifications ;"],"\"Compare\" to see the modified version;":[null,"« Comparer » pour voir la nouvelle version ;"],"\"Write Anyway\" to save your current version.":[null,"« Écraser » pour sauver vos modifications."],"Compare":[null,"Comparer"],"Write Anyway":[null,"Écraser"],"Application Error":[null,"Erreur applicative"],"Report Bug":[null,"Rapporter un bogue"],"Revision":[null,"Révision"],"Wizard":[null,"Assistant"]}
\ No newline at end of file
diff --git a/locale/lo_LA.json b/locale/lo_LA.json
deleted file mode 100644
index 9fb066f..0000000
--- a/locale/lo_LA.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/lt_LT.json b/locale/lt_LT.json
deleted file mode 100644
index 9fb066f..0000000
--- a/locale/lt_LT.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/nl_NL.json b/locale/nl_NL.json
deleted file mode 100644
index 9fb066f..0000000
--- a/locale/nl_NL.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/ru_RU.json b/locale/ru_RU.json
deleted file mode 100644
index 9fb066f..0000000
--- a/locale/ru_RU.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/sl_SI.json b/locale/sl_SI.json
deleted file mode 100644
index c4868dd..0000000
--- a/locale/sl_SI.json
+++ /dev/null
@@ -1 +0,0 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,"Odjava"],"Search...":[null,"Išči ..."],"Unable to reach the server":[null,"Ni se mogoče povezati s strežnikom"],"Unable to reach the server.":[null,"Ni se mogoče povezati s strežnikom."],"Login":[null,"Prijava"],"Password":[null,"Geslo"],"Database":[null,"Podatkovna baza"],"OK":[null,"V redu"],"Toggle navigation":[null,"Vklop/izklop krmarjenja"],"Menu":[null,"Meni"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"Za slednji ukrep se bodo zaprli vsi zavihki.\nAli želiš nadaljevati?"],"Close":[null,"Zapri"],"New":[null,"Novo"],"Create a new record":[null,"Ustvari nov zapis"],"Save":[null,"Shrani"],"Save this record":[null,"Shrani ta zapis"],"Switch":[null,"Preklopi"],"Switch view":[null,"Preklopi pogled"],"Reload":[null,"Ponovno naloži"],"Previous":[null,"Prejšnji"],"Previous Record":[null,"Prejšnji zapis"],"Next":[null,"Naslednji"],"Next Record":[null,"Naslednji zapis"],"Attachment":[null,"Priponka"],"Add an attachment to the record":[null,"Dodaj priponko zapisu"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"Ponovno naloži"],"Duplicate":[null,"Podvoji"],"Delete":[null,"Zbriši"],"Search":[null,"Išči"],"View Logs...":[null,"Prikaži dnevnik ..."],"Show revisions...":[null,"Prikaži revizije ..."],"Close Tab":[null,"Zapri zavihek"],"Action":[null,"Ukrep"],"Relate":[null,"Veza"],"Print":[null,"Tisk"],"Launch action":[null,"Zaženi ukrep"],"Open related records":[null,"Odpri povezane zapise"],"Print report":[null,"Izpis poročila"],"This record has been modified\ndo you want to save it?":[null,"Ta zapis je bil spremenjen,\nga želiš shraniti?"],"Record saved.":[null,"Zapis shranjen."],"Working now on the duplicated record(s).":[null,"Trenutno se dela na podvojenem zapisu."],"Are you sure to remove this record?":[null,"Ali res želiš zbrisati ta zapis?"],"Are you sure to remove those records?":[null,"Ali res želiš zbrisati te zapise?"],"Records removed.":[null,"Zapisi zbrisani."],"Records not removed.":[null,"Zapisi niso bili zbrisani."],"You have to select one record.":[null,"En zapis mora biti izbran."],"ID:":[null,"ID:"],"Creation User:":[null,"Ustvaril:"],"Creation Date:":[null,"Ustvarjeno:"],"Latest Modification by:":[null,"Nazadnje popravil:"],"Latest Modification Date:":[null,"Nazadnje popravljeno:"],"Model: ":[null,"Model: "],"Attachment(%1)":[null,"Priponka(%1)"],"Note(%1)":[null,""],"Filters":[null,"Filtri"],"Bookmarks":[null,"Zaznamki"],"Remove this bookmark":[null,"Zbriši ta zaznamek"],"Bookmark this filter":[null,"Shrani ta filter"],"Bookmark Name:":[null,"Ime zaznamka:"],"True":[null,"Da"],"False":[null,"Ne"],"Find":[null,"Najdi"],"ID":[null,"ID"],"Creation User":[null,"Ustvaril"],"Creation Date":[null,"Ustvarjeno"],"Modification User":[null,"Popravil"],"Modification Date":[null,"Popravljeno"],"\"%1\" is required":[null,"Polje \"%1\" je obvezno"],"\"%1\" is not valid according to its domain":[null,"Polje \"%1\" ni veljavno glede na svojo domeno"],"The values of \"%1\" are not valid":[null,"Vrednosti polja \"%1\" niso veljavne"],"Pre-validation":[null,"Predpreverjanje"],"Font":[null,"Pisava"],"Size":[null,"Velikost"],"Add":[null,"Dodaj"],"Remove":[null,"Odstrani"],"Open":[null,"Odpri"],"Undelete":[null,"Povrni"],"Select":[null,"Izberi"],"Cancel":[null,"Prekliči"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Več"],"Calendar view not yet implemented":[null,"Koledarski pogled še ni implementiran"],"Warning":[null,"Opozorilo"],"Select your action":[null,"Izberi ukrep"],"No action defined!":[null,"Nobenega ukrepa še ni določenega"],"Your selection:":[null,"Vaša izbira:"],"Y":[null,"l"],"M":[null,"M"],"w":[null,"t"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"y":[null,"d"],"yes":[null,"da"],"true":[null,"da"],"t":[null,"d"],"Message: ":[null,"Sporočilo:"],"Warning: ":[null,"Opozorilo: "],"Always ignore this warning.":[null,"Vedno prezri to opozorilo."],"Do you want to proceed?":[null,"Ali želiš nadaljevati?"],"No":[null,"Ne"],"Yes":[null,"Da"],"Confirmation: ":[null,"Potrditev: "],"Concurrency Exception":[null,"Napaka sočasnega izvajanja"],"Write Concurrency Warning: ":[null,"Opozorilo sočasnega zapisovanja: "],"This record has been modified while you were editing it.":[null,"Ta zapis je bil spremenjen v času vašega popravljanja."],"Choose:":[null,"Izberi:"],"\"Cancel\" to cancel saving;":[null,"\"Prekliči\" - prekliči spremembe;"],"\"Compare\" to see the modified version;":[null,"\"Primerjaj\" - primerjaj z drugo različico;"],"\"Write Anyway\" to save your current version.":[null,"\"Vseeno shrani\" - shrani trenutno različico."],"Compare":[null,"Primerjaj"],"Write Anyway":[null,"Vseeno shrani"],"Application Error":[null,"Programska napaka"],"Report Bug":[null,"Prijavi programsko napako"],"Revision":[null,"Različica"],"Wizard":[null,"Čarovnik"]}
\ No newline at end of file
diff --git a/package.json b/package.json
index c0af292..3b207a0 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "tryton-sao",
   "title": "sao",
   "description": "Tryton webclient",
-  "version": "4.4.0",
+  "version": "4.4.1",
   "homepage": "http://www.tryton.org/",
   "author": {
     "name": "Tryton"
diff --git a/src/action.js b/src/action.js
index 6eb1433..3175724 100644
--- a/src/action.js
+++ b/src/action.js
@@ -49,7 +49,7 @@
         var name_prm;
         switch (action.type) {
             case 'ir.action.act_window':
-                params.view_ids = false;
+                params.view_ids = [];
                 params.mode = null;
                 if (!jQuery.isEmptyObject(action.views)) {
                     params.view_ids = [];
@@ -71,18 +71,16 @@
                     active_ids: data.ids
                 };
                 ctx = jQuery.extend(ctx, session.context);
-                var eval_ctx = jQuery.extend({}, ctx);
-                eval_ctx._user = session.user_id;
+                ctx._user = session.user_id;
+                var decoder = new Sao.PYSON.Decoder(ctx);
                 params.context = jQuery.extend(
-                        {}, context, new Sao.PYSON.Decoder(eval_ctx).decode(
-                            action.pyson_context || '{}'));
+                    {}, context,
+                    decoder.decode( action.pyson_context || '{}'));
                 ctx = jQuery.extend(ctx, params.context);
                 ctx = jQuery.extend(ctx, context);
 
-                var domain_context = jQuery.extend({}, ctx);
-                domain_context.context = ctx;
-                domain_context._user = session.user_id;
-                var decoder = new Sao.PYSON.Decoder(domain_context);
+                ctx.context = ctx;
+                decoder = new Sao.PYSON.Decoder(ctx);
                 params.domain = decoder.decode(action.pyson_domain);
                 params.order = decoder.decode(action.pyson_order);
                 params.search_value = decoder.decode(
diff --git a/src/screen.js b/src/screen.js
index 9e4642d..a1a2db1 100644
--- a/src/screen.js
+++ b/src/screen.js
@@ -1067,7 +1067,7 @@
             }
             var prm = jQuery.when();
             if (this.current_view.view_type == 'calendar') {
-                var selected_date = this.current_view.date;
+                var selected_date = this.current_view.get_selected_date();
                 prm = this.switch_view('form');
             }
             if (this.current_view &&
diff --git a/src/view/calendar.js b/src/view/calendar.js
index 25aeb3a..fab3f80 100644
--- a/src/view/calendar.js
+++ b/src/view/calendar.js
@@ -233,7 +233,8 @@
             var model_access = Sao.common.MODELACCESS.get(
                 this.screen.model_name);
             if (model_access.create) {
-                this.date = date;
+                // Set the calendar date to the clicked date
+                this.el.fullCalendar('gotoDate', date);
                 this.screen.set_current_record(null);
                 this.screen.new_();
             }
@@ -263,11 +264,11 @@
         },
         set_default_date: function(record, selected_date){
             var dtstart = this.attributes.dtstart;
-            if (record.model.fields[dtstart].description.type == 'datetime') {
-                selected_date = Sao.DateTime(selected_date.format()).utc();
-            }
-            record.field_set_client(dtstart, selected_date);
+            record.field_set(dtstart, selected_date);
         },
+        get_selected_date: function(){
+            return this.el.fullCalendar('getDate');
+        }
     });
 
 }());
commit 339d3111b3bf84edce90f5c5d05d68a0697e189f
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Wed Jun 7 15:27:10 2017 +0200

    Merging upstream version 4.4.0.

diff --git a/CHANGELOG b/CHANGELOG
index 0253dd5..d03a883 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,11 +1,9 @@
-Version 4.2.3 - 2017-03-10
-* Bug fixes (see mercurial logs for details)
-
-Version 4.2.2 - 2017-02-06
-* Bug fixes (see mercurial logs for details)
-
-Version 4.2.1 - 2017-01-03
+Version 4.4.0 - 2017-05-01
 * Bug fixes (see mercurial logs for details)
+* Manage help attribute on tree views
+* Manage color attribute on graph view
+* Add support for size on Many2Many
+* Allow to show plain text in password field
 
 Version 4.2.0 - 2016-11-28
 * Bug fixes (see mercurial logs for details)
diff --git a/Gruntfile.js b/Gruntfile.js
index 0945139..407b8ad 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -127,23 +127,38 @@ module.exports = function(grunt) {
     }
   });
 
-  // Load the plugin that provides the "uglify" task.
-  grunt.loadNpmTasks('grunt-contrib-concat');
-  grunt.loadNpmTasks('grunt-xgettext');
-  grunt.loadNpmTasks('grunt-shell');
-  grunt.loadNpmTasks('grunt-contrib-jshint');
-  grunt.loadNpmTasks('grunt-contrib-uglify');
-  grunt.loadNpmTasks('grunt-contrib-less');
-  grunt.loadNpmTasks('grunt-contrib-watch');
-  grunt.loadNpmTasks('grunt-po2json');
-  grunt.loadNpmTasks('grunt-contrib-qunit');
-
-  // Default task(s).
-  grunt.registerTask('default', [
-      'concat', 'jshint', 'uglify', 'less', 'po2json'
-  ]);
-  grunt.registerTask('dev', ['concat', 'jshint', 'less:dev']);
-  grunt.registerTask('msgmerge', ['shell:msgmerge']);
-  grunt.registerTask('test', ['concat', 'jshint', 'less:dev', 'qunit']);
+  grunt.registerTask('default', 'Build for production.', function() {
+    grunt.loadNpmTasks('grunt-contrib-concat');
+    grunt.loadNpmTasks('grunt-contrib-jshint');
+    grunt.loadNpmTasks('grunt-contrib-uglify');
+    grunt.loadNpmTasks('grunt-contrib-less');
+    grunt.loadNpmTasks('grunt-po2json');
+    grunt.task.run(['concat', 'jshint', 'uglify', 'less', 'po2json']);
+    });
+  grunt.registerTask('dev', 'Build for development.', function() {
+    grunt.loadNpmTasks('grunt-contrib-concat');
+    grunt.loadNpmTasks('grunt-contrib-jshint');
+    grunt.loadNpmTasks('grunt-contrib-less');
+    grunt.task.run(['concat', 'jshint', 'less:dev']);
+    });
+  grunt.registerTask('devwatch', 'Watch development', function() {
+    grunt.loadNpmTasks('grunt-contrib-watch');
+    grunt.task.run(['watch']);
+    });
+  grunt.registerTask('msgmerge', 'Update locale messages.', function() {
+    grunt.loadNpmTasks('grunt-shell');
+    grunt.task.run(['shell:msgmerge']);
+    });
+  grunt.registerTask('xgettext', ' Extracts translatable messages', function() {
+    grunt.loadNpmTasks('grunt-xgettext');
+    grunt.task.run(['xgettext']);
+  });
+  grunt.registerTask('test', 'Run tests', function() {
+    grunt.loadNpmTasks('grunt-contrib-concat');
+    grunt.loadNpmTasks('grunt-contrib-jshint');
+    grunt.loadNpmTasks('grunt-contrib-less');
+    grunt.loadNpmTasks('grunt-contrib-qunit');
+    grunt.task.run(['concat', 'jshint', 'less:dev', 'qunit']);
+    });
 
 };
diff --git a/README b/README
index a779c66..24837ce 100644
--- a/README
+++ b/README
@@ -12,7 +12,7 @@ Installation
 Once you've downloaded and unpacked the sao source release, enter the directory
 where the archive was unpacked, and run:
 
-    # npm install
+    # npm install --production
     # grunt
 
 Note that the entry `root` in the section `[web]` of `trytond.conf` must be set
diff --git a/dist/tryton-sao.css b/dist/tryton-sao.css
index 38cf648..8da531d 100644
--- a/dist/tryton-sao.css
+++ b/dist/tryton-sao.css
@@ -1,26 +1,22 @@
-.navbar {
-  z-index: 1000;
+#tablist > li > a > span {
+  display: inline-block;
+  max-width: 9em;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 .tab-form nav.toolbar,
 .tab-board nav.toolbar {
   margin-bottom: 1px;
 }
-.tab-form nav.toolbar ul.nav > li > a,
-.tab-board nav.toolbar ul.nav > li > a {
-  padding-right: 0px;
-}
 .tab-form nav.toolbar.affix,
 .tab-board nav.toolbar.affix {
   top: 51px;
   z-index: 999;
 }
-.nav-tabs > li .close {
-  margin: -2px 0 0 10px;
-  font-size: 18px;
-}
 @media screen and (max-width: 767px) {
-  .tab-form .navbar-nav > li,
-  .tab-board .navbar-nav > li {
+  .tab-form .navbar-header > ul > li,
+  .tab-board .navbar-header > ul > li {
     float: left;
     width: 50%;
   }
@@ -53,6 +49,7 @@ button img.icon {
   overflow: hidden;
   text-overflow: ellipsis;
   min-width: 30px;
+  text-align: center;
 }
 .treeview > table.tree > thead > tr > th > label.sortable {
   cursor: pointer;
@@ -109,10 +106,10 @@ button img.icon {
 .form {
   width: 100%;
 }
-.form > .form-container {
+.form > table.form-container {
   width: 100%;
 }
-.form > .form-container td {
+.form > table.form-container > tbody > tr > td {
   padding: 1px;
 }
 .form td.form-label {
@@ -203,6 +200,12 @@ button img.icon {
 .column-timedelta {
   text-align: right;
 }
+input.column-boolean,
+input.selection {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
 .form-boolean input[type=checkbox],
 .editabletree-boolean input[type=checkbox] {
   width: initial;
@@ -217,6 +220,9 @@ button img.icon {
 .progress {
   margin-bottom: 0px;
 }
+.window-form .window-form-toolbar {
+  text-align: right;
+}
 .csv .modal-dialog .column-fields {
   height: 35vh;
   overflow-y: scroll;
@@ -234,10 +240,10 @@ button img.icon {
   table.responsive,
   table.responsive > thead,
   table.responsive > thead > tr,
-  table.responsive > thead > tr > th,
+  table.responsive > thead > tr > th:not(.invisible),
   table.responsive > tbody,
   table.responsive > tbody > tr,
-  table.responsive > tbody > tr > td {
+  table.responsive > tbody > tr > td:not(.invisible) {
     display: block !important;
   }
   table.responsive {
@@ -267,7 +273,6 @@ button img.icon {
     border: none;
     border-bottom: 1px solid #eee;
     position: relative;
-    padding-left: 30%;
   }
   table.responsive-header > tbody > tr > td:before {
     /* Now like a table header */
@@ -275,15 +280,19 @@ button img.icon {
     /* Top/left values mimic padding */
     top: 6px;
     left: 6px;
-    width: 30%;
     padding-right: 10px;
     text-align: left;
-    font-weight: bold;
     overflow: hidden;
     text-overflow: ellipsis;
     /* Label */
     content: attr(data-title);
   }
+  table.responsive-header > tbody > tr > td.required:before {
+    font-weight: bold;
+  }
+  table.responsive-header > tbody > tr > td.editable:before {
+    font-style: italic;
+  }
 }
 #processing {
   position: fixed;
diff --git a/dist/tryton-sao.js b/dist/tryton-sao.js
index c604665..764bfe1 100644
--- a/dist/tryton-sao.js
+++ b/dist/tryton-sao.js
@@ -398,7 +398,8 @@ var Sao = {};
             'view_ids': view_ids,
             'domain': domain,
             'context': action_ctx,
-            'selection_mode': Sao.common.SELECTION_NONE
+            'selection_mode': Sao.common.SELECTION_NONE,
+            'limit': null
         });
         Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(form), 1);
         form.view_prm.done(function() {
@@ -664,7 +665,7 @@ var Sao = {};
                 } else if (data.error[0] == 'UserError') {
                     msg = data.error[1][0];
                     description = data.error[1][1];
-                    Sao.common.warning.run(msg, description)
+                    Sao.common.warning.run(description, msg)
                         .always(dfd.reject);
                     return;
                 } else if (data.error[0] == 'ConcurrencyException') {
@@ -1787,7 +1788,7 @@ var Sao = {};
         dialog.login_input = jQuery('<input/>', {
             'class': 'form-control',
             'id': 'login-login',
-            'placeholder': Sao.i18n.gettext('Login')
+            'placeholder': Sao.i18n.gettext('User name')
         });
         dialog.body.append(jQuery('<div/>', {
             'class': 'form-group'
@@ -1802,7 +1803,7 @@ var Sao = {};
         }).append(jQuery('<label/>', {
             'class': 'control-label',
             'for': 'login-login'
-        }).append(Sao.i18n.gettext('Login')))
+        }).append(Sao.i18n.gettext('User name')))
         .append(dialog.login_input)
         );
         dialog.button = jQuery('<button/>', {
@@ -2232,7 +2233,7 @@ var Sao = {};
             if (modified) {
                 record._changed.id = true;
             }
-            if (!(record.group.parent) || (record.id < 0) || force_remove) {
+            if ((record.id < 0) || force_remove) {
                 this._remove(record);
             }
             record.group.changed();
@@ -2287,7 +2288,11 @@ var Sao = {};
                 deferreds.push(record.save());
             });
             if (!jQuery.isEmptyObject(this.record_deleted)) {
+                this.record_deleted.forEach(function(record) {
+                    this._remove(record);
+                }.bind(this));
                 deferreds.push(this.model.delete_(this.record_deleted));
+                this.record_deleted.splice(0, this.record_deleted.length);
             }
             return jQuery.when.apply(jQuery, deferreds);
         };
@@ -2720,7 +2725,6 @@ var Sao = {};
             var name, value;
             var rec_named_fields = ['many2one', 'one2one', 'reference'];
             var later = {};
-            var promises = [];
             var fieldnames = [];
             for (name in values) {
                 if (!values.hasOwnProperty(name)) {
@@ -2762,17 +2766,10 @@ var Sao = {};
                 this.model.fields[name].set(this, value);
                 this._loaded[name] = true;
             }
-            for (var fname in this.model.fields) {
-                var field = this.model.fields[fname];
-                if (field.description.autocomplete &&
-                        field.description.autocomplete.length > 0) {
-                    promises.push(this.do_autocomplete(fname));
-                }
-            }
             if (validate) {
-                promises.push(this.validate(fieldnames, true));
+                return this.validate(fieldnames, true);
             }
-            return jQuery.when.apply(jQuery, promises);
+            return jQuery.when();
         },
         get: function() {
             var value = {};
@@ -2781,7 +2778,8 @@ var Sao = {};
                     continue;
                 }
                 var field = this.model.fields[name];
-                if (field.description.readonly) {
+                if (field.description.readonly &&
+                        !(field instanceof Sao.field.One2Many)) {
                     continue;
                 }
                 if ((this._changed[name] === undefined) && this.id >= 0) {
@@ -2818,16 +2816,6 @@ var Sao = {};
             this.model.fields[name].set_client(this, value, force_change);
         },
         default_get: function(rec_name) {
-            var dfd = jQuery.Deferred();
-            var promises = [];
-            // Ensure promisses is filled before default_get is resolved
-            for (var fname in this.model.fields) {
-                var field = this.model.fields[fname];
-                if (field.description.autocomplete &&
-                        field.description.autocomplete.length > 0) {
-                    promises.push(this.do_autocomplete(fname));
-                }
-            }
             if (!jQuery.isEmptyObject(this.model.fields)) {
                 var context = this.get_context();
                 if (context.default_rec_name === undefined) {
@@ -2835,7 +2823,7 @@ var Sao = {};
                 }
                 var prm = this.model.execute('default_get',
                         [Object.keys(this.model.fields)], context);
-                prm.then(function(values) {
+                return prm.then(function(values) {
                     if (this.group.parent &&
                             this.group.parent_name in this.group.model.fields) {
                         var parent_field =
@@ -2850,15 +2838,10 @@ var Sao = {};
                                 this.group.parent.id;
                         }
                     }
-                    promises.push(this.set_default(values));
-                    jQuery.when.apply(jQuery, promises).then(function() {
-                        dfd.resolve(values);
-                    });
+                    return this.set_default(values);
                 }.bind(this));
-            } else {
-                dfd.resolve();
             }
-            return dfd;
+            return jQuery.when();
         },
         set_default: function(values, validate) {
             if (validate === undefined) {
@@ -3133,7 +3116,7 @@ var Sao = {};
                     if (fields && !~fields.indexOf(fname)) {
                         continue;
                     }
-                    if (field.get_state_attrs(this).readonly) {
+                    if (field.description.readonly) {
                         continue;
                     }
                     if (~exclude_fields.indexOf(fname)) {
@@ -4465,6 +4448,7 @@ var Sao = {};
             Sao.Tab.tabs.push(this);
             this.buttons = {};
             this.id = 'tab-' + Sao.Tab.counter++;
+            this.name = '';
             this.name_el = jQuery('<span/>');
         },
         create_tabcontent: function() {
@@ -4473,7 +4457,7 @@ var Sao = {};
             });
 
             var toolbar = this.create_toolbar().appendTo(this.el);
-            this.title = toolbar.find('a.navbar-brand');
+            this.title = toolbar.find('.title');
 
             this.content = jQuery('<div/>').appendTo(this.el);
 
@@ -4507,84 +4491,90 @@ var Sao = {};
             }.bind(this));
         },
         create_toolbar: function() {
-            var toolbar = jQuery(
-                    '<nav class="navbar-default toolbar" role="navigation">' +
-                    '<div class="container-fluid">' +
-                    '<div class="navbar-header">' +
-                    '<a class="navbar-brand" href="#"></a>' +
-                    '<button type="button" class="navbar-toggle collapsed" ' +
-                    'data-toggle="collapse" ' +
-                    'data-target="#navbar-' + this.id + '">' +
-                    '<span class="sr-only">' +
-                    Sao.i18n.gettext('Toggle navigation') +
-                    '</span>' +
-                    '<span class="icon-bar"></span>' +
-                    '<span class="icon-bar"></span>' +
-                    '<span class="icon-bar"></span>' +
-                    '</div>' +
-                    '<div class="collapse navbar-collapse" ' +
-                    'id="navbar-' + this.id + '">' +
-                    '<ul class="nav navbar-nav">' +
-                    '<li class="dropdown">' +
-                    '<a href="#" class="dropdown-toggle" ' +
-                    'data-toggle="dropdown" role="button" ' +
-                    'aria-expanded="false">' +
-                    '<span class="glyphicon glyphicon-wrench" ' +
-                    'aria-hidden="true"></span>' +
-                    '<span class="visible-xs">' +
-                    Sao.i18n.gettext('Menu') +
-                    '</span>' +
-                    '<span class="caret"></span>' +
-                    '</a>' +
-                    '<ul class="dropdown-menu" role="menu">' +
-                    '</ul>' +
-                    '</li>' +
-                    '</ul>' +
-                    '</div>' +
-                    '</div>' +
-                    '</nav>'
-                    );
+            var toolbar = jQuery('<nav/>', {
+                'class': 'toolbar navbar navbar-default',
+                'role': 'toolbar'
+            }).append(jQuery('<div/>', {
+                'class': 'container-fluid'
+            }).append(jQuery('<div/>', {
+                'class': 'dropdown navbar-header navbar-left'
+            }).append(jQuery('<a/>', {
+                'href': "#",
+                'class': "navbar-brand dropdown-toggle",
+                'data-toggle': 'dropdown',
+                'role': 'button',
+                'aria-expanded': false,
+                'aria-haspopup': true
+            }).append(jQuery('<span/>', {
+                'class': 'title'
+            })).append(jQuery('<span/>', {
+                'class': 'caret'
+            }))).append(jQuery('<ul/>', {
+                'class': 'dropdown-menu',
+                'role': 'menu'
+            })).append(jQuery('<button/>', {
+                'type': 'button',
+                'class': 'close visible-xs visible-sm',
+                'aria-label': Sao.i18n.gettext('Close')
+            }).append(jQuery('<span/>', {
+                'aria-hidden': true
+            }).append('×')).click(function() {
+                this.close();
+            }.bind(this)))).append(jQuery('<div/>', {
+                'class': 'btn-toolbar navbar-right',
+                'role': 'toolbar'
+            })));
             var wrapper = jQuery('<div/>', {
-                'class': 'nav-wrapper'
+                'class': 'toolbar-wrapper'
             }).append(toolbar);
             this.set_menu(toolbar.find('ul[role*="menu"]'));
 
+            var group;
             var add_button = function(tool) {
-                var item = jQuery('<li/>', {
-                    'role': 'presentation'
-                }).appendTo(toolbar.find('.navbar-collapse > ul'));
-                this.buttons[tool[0]] = jQuery('<a/>', {
-                    'role': 'menuitem',
-                    'href': '#',
+                if (!tool) {
+                    group = null;
+                    return;
+                }
+                if (!group) {
+                    group = jQuery('<div/>', {
+                        'class': 'btn-group',
+                        'role': 'group'
+                    }).appendTo(toolbar.find('.btn-toolbar'));
+                }
+                this.buttons[tool[0]] = jQuery('<button/>', {
+                    'type': 'button',
+                    'class': 'btn btn-default navbar-btn',
+                    'title': tool[2],
                     'id': tool[0]
                 })
                 .append(jQuery('<span/>', {
                     'class': 'glyphicon ' + tool[1],
                     'aria-hidden': 'true'
                 }))
-                .append(jQuery('<span/>', {
-                    'class': 'hidden-sm'
-                }).append(' ' + tool[2]))
-                .appendTo(item);
-                if (tool[4]) {
-                    this.buttons[tool[0]].click(this[tool[4]].bind(this));
+                .appendTo(group)
+                .data('toggle', 'tooltip')
+                .data('placement', 'bottom')
+                .tooltip();
+                if (tool[3]) {
+                    this.buttons[tool[0]].click(this[tool[3]].bind(this));
                 } else {
                     item.addClass('disabled');
                 }
-                // TODO tooltip
             };
             this.toolbar_def().forEach(add_button.bind(this));
+            toolbar.find('.btn-toolbar > .btn-group').last().addClass(
+                    'hidden-xs');
             var tabs = jQuery('#tabs');
             toolbar.affix({
                 'target': tabs.parent(),
                 'offset': {
                     'top': function() {
-                        return tabs.find('.nav-tabs').height();
+                        return jQuery('#main_navbar').height();
                     }
                 }
             });
             toolbar.on('affix.bs.affix', function() {
-                wrapper.height(toolbar.height());
+                wrapper.height(jQuery('#main_navbar').height());
             });
             toolbar.on('affix-top.bs.affix affix-bottom.bs.affix',
                     function() {
@@ -4601,15 +4591,16 @@ var Sao = {};
         },
         close: function() {
             var tabs = jQuery('#tabs');
-            var tab = tabs.find('#nav-' + this.id);
+            var tablist = jQuery('#tablist');
+            var tab = tablist.find('#nav-' + this.id);
             var content = tabs.find('#' + this.id);
-            tabs.find('a[href="#' + this.id + '"]').tab('show');
+            tablist.find('a[href="#' + this.id + '"]').tab('show');
             return this._close_allowed().then(function() {
-                var next = tab.next();
+                var next = tab.nextAll('li').first();
                 if (!next.length) {
-                    next = tab.prev();
+                    next = tab.prevAll('li').first();
                 }
-                tab.remove();
+                tab.tooltip('destroy').remove();
                 content.remove();
                 Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(this), 1);
                 if (next) {
@@ -4622,7 +4613,9 @@ var Sao = {};
             return jQuery.when();
         },
         set_name: function(name) {
-            this.name_el.text(name);
+            this.name = name;
+            this.name_el.text(Sao.common.ellipsize(name, 20));
+            this.name_el.parents('li').first().attr('title', name).tooltip();
         }
     });
 
@@ -4674,7 +4667,7 @@ var Sao = {};
         return jQuery.when();
     };
     Sao.Tab.tabs.get_current = function() {
-        var tabs = jQuery('#tabs > ul');
+        var tabs = jQuery('#tablist');
         var i = tabs.find('li').index(tabs.find('li.active'));
         return Sao.Tab.tabs[i];
     };
@@ -4698,6 +4691,8 @@ var Sao = {};
 
     Sao.Tab.add = function(tab) {
         var tabs = jQuery('#tabs');
+        var tablist = jQuery('#tablist');
+        var tabcontent = jQuery('#tabcontent');
         var tab_link = jQuery('<a/>', {
             'aria-controls': tab.id,
             'role': 'tab',
@@ -4716,15 +4711,17 @@ var Sao = {};
         .append(tab.name_el);
         jQuery('<li/>', {
             'role': 'presentation',
+            'data-toggle': 'tooltip',
+            'data-placement': 'bottom',
             id: 'nav-' + tab.id
         }).append(tab_link)
-        .appendTo(tabs.find('> .nav-tabs'));
+        .appendTo(tablist);
         jQuery('<div/>', {
             role: 'tabpanel',
             'class': 'tab-pane',
             id: tab.id
         }).html(tab.el)
-        .appendTo(tabs.find('> .tab-content'));
+        .appendTo(tabcontent);
         tab_link.on('shown.bs.tab', function() {
             Sao.View.resize(tab.el);
         });
@@ -4772,28 +4769,22 @@ var Sao = {};
         toolbar_def: function() {
             return [
                 ['new', 'glyphicon-edit',
-                Sao.i18n.gettext('New'),
                 Sao.i18n.gettext('Create a new record'), 'new_'],
                 ['save', 'glyphicon-save',
-                Sao.i18n.gettext('Save'),
                 Sao.i18n.gettext('Save this record'), 'save'],
                 ['switch', 'glyphicon-list-alt',
-                Sao.i18n.gettext('Switch'),
                 Sao.i18n.gettext('Switch view'), 'switch_'],
                 ['reload', 'glyphicon-refresh',
-                Sao.i18n.gettext('Reload'),
                 Sao.i18n.gettext('Reload'), 'reload'],
+                null,
                 ['previous', 'glyphicon-chevron-left',
-                Sao.i18n.gettext('Previous'),
                 Sao.i18n.gettext('Previous Record'), 'previous'],
                 ['next', 'glyphicon-chevron-right',
-                Sao.i18n.gettext('Next'),
                 Sao.i18n.gettext('Next Record'), 'next'],
+                null,
                 ['attach', 'glyphicon-paperclip',
-                Sao.i18n.gettext('Attachment'),
                 Sao.i18n.gettext('Add an attachment to the record'), 'attach'],
                 ['note', 'glyphicon-comment',
-                Sao.i18n.gettext('Note'),
                 Sao.i18n.gettext('Add a note to the record'), 'note']
             ];
         },
@@ -4834,46 +4825,54 @@ var Sao = {};
             prm.done(function(toolbars) {
                 [
                 ['action', 'glyphicon-cog',
-                    Sao.i18n.gettext('Action'),
                     Sao.i18n.gettext('Launch action')],
                 ['relate', 'glyphicon-share-alt',
-                     Sao.i18n.gettext('Relate'),
                      Sao.i18n.gettext('Open related records')],
                 ['print', 'glyphicon-print',
-                     Sao.i18n.gettext('Print'),
                      Sao.i18n.gettext('Print report')]
                 ].forEach(function(menu_action) {
-                    var button = jQuery('<li/>', {
-                        'class': 'dropdown'
+                    var button = jQuery('<div/>', {
+                        'class': 'btn-group',
+                        'role': 'group'
                     })
-                    .append(jQuery('<a/>', {
-                        href: '#',
-                        id: menu_action[0],
-                        'class': 'dropdown-toggle',
+                    .append(jQuery('<button/>', {
+                        'type': 'button',
+                        'class': 'btn btn-default navbar-btn dropdown-toggle',
                         'data-toggle': 'dropdown',
-                        role: 'button',
-                        'aria-expanded': 'false'
+                        'aria-expanded': false,
+                        'aria-haspopup': true,
+                        'title': menu_action[2],
+                        'id': menu_action[0],
+                        'disabled': !toolbars[menu_action[0]].length
                     })
                         .append(jQuery('<span/>', {
                             'class': 'glyphicon ' + menu_action[1],
                             'aria-hidden': 'true'
                         }))
                         .append(jQuery('<span/>', {
-                            'class': 'hidden-sm'
-                        }).append(' ' + menu_action[2] + ' '))
-                        .append(jQuery('<span/>', {
                             'class': 'caret'
-                        })))
+                        }))
+                        .data('toggle', 'tooltip')
+                        .data('placement', 'bottom')
+                        .tooltip())
                     .append(jQuery('<ul/>', {
                         'class': 'dropdown-menu',
-                        role: 'menu',
+                        'role': 'menu',
                         'aria-labelledby': menu_action[0]
                     }))
-                    .appendTo(toolbar.find('.navbar-collapse > ul'));
+                    .appendTo(toolbar.find('.btn-toolbar > .btn-group').last());
                     buttons[menu_action[0]] = button;
+                    var dropdown = button
+                        .on('show.bs.dropdown', function() {
+                            jQuery(this).parents('.btn-group').removeClass(
+                                    'hidden-xs');
+                        }).on('hide.bs.dropdown', function() {
+                            jQuery(this).parents('.btn-group').addClass(
+                                    'hidden-xs');
+                        });
                     var menu = button.find('ul[role*="menu"]');
                     if (menu_action[0] == 'action') {
-                        button.find('a').click(function() {
+                        button.click(function() {
                             menu.find('.action_button').remove();
                             var buttons = screen.get_buttons();
                             buttons.forEach(function(button) {
@@ -5167,9 +5166,9 @@ var Sao = {};
                 var time_format = '%H:%M:%S.%f';
                 revision = Sao.common.format_datetime(date_format, time_format,
                         revision);
-                label = this.name_el.text() + ' @ '+ revision;
+                label = this.name + ' @ '+ revision;
             } else {
-                label = this.name_el.text();
+                label = this.name;
             }
             this.title.html(label);
             this.set_buttons_sensitive(revision);
@@ -5213,8 +5212,13 @@ var Sao = {};
             }
         },
         attachment_count: function(count) {
-            var label = Sao.i18n.gettext('Attachment(%1)', count);
-            this.buttons.attach.text(label);
+            var badge = this.buttons.attach.find('.badge');
+            if (!badge.length) {
+                badge = jQuery('<span/>', {
+                    'class': 'badge'
+                }).appendTo(this.buttons.attach);
+            }
+            badge.text(count);
             var record_id = this.screen.get_id();
             this.buttons.attach.prop('disabled',
                 record_id < 0 || record_id === null);
@@ -5238,8 +5242,13 @@ var Sao = {};
             }
         },
         _unread_note: function(unread) {
-            var label = Sao.i18n.gettext('Note(%1)', unread);
-            this.buttons.note.text(label);
+            var badge = this.buttons.note.find('.badge');
+            if (!badge.length) {
+                badge = jQuery('<span/>', {
+                    'class': 'badge'
+                }).appendTo(this.buttons.note);
+            }
+            badge.text(unread);
             var record_id = this.screen.get_id();
             this.buttons.note.prop('disabled',
                     record_id < 0 || record_id === null);
@@ -5249,20 +5258,17 @@ var Sao = {};
         },
         action: function() {
             window.setTimeout(function() {
-                this.buttons.action.find('ul.dropdown-menu')
-                    .dropdown('toggle');
+                this.buttons.action.find('button').click();
             }.bind(this));
         },
         relate: function() {
             window.setTimeout(function() {
-                this.buttons.relate.find('ul.dropdown-menu')
-                    .dropdown('toggle');
+                this.buttons.relate.find('button').click();
             }.bind(this));
         },
         print: function() {
             window.setTimeout(function() {
-                this.buttons.print.find('ul.dropdown-menu')
-                    .dropdown('toggle');
+                this.buttons.print.find('button').click();
             }.bind(this));
         },
         export: function(){
@@ -5270,7 +5276,8 @@ var Sao = {};
                 this.screen.current_view.selected_records().map(function(r) {
                     return r.id;
                 }),
-                this.screen.current_view.get_fields());
+                this.screen.current_view.get_fields(),
+                this.screen.context);
         },
         import: function(){
             new Sao.Window.Import(this.screen);
@@ -5312,7 +5319,6 @@ var Sao = {};
         toolbar_def: function() {
             return [
                 ['reload', 'glyphicon-refresh',
-                Sao.i18n.gettext('Reload'),
                 Sao.i18n.gettext('Reload'), 'reload']
             ];
         },
@@ -5867,7 +5873,7 @@ var Sao = {};
                     jQuery('<div/>', {
                         'class': 'col-sm-8'
                     }).append(input).appendTo(form_group);
-                    this.search_form.fields.push([field.string, entry]);
+                    this.search_form.fields.push([field.string, entry, input]);
                 }
 
                 jQuery('<button/>', {
@@ -5893,7 +5899,7 @@ var Sao = {};
                             fentry.val('');
                     }
                 }
-                this.search_form.fields[0][1].focus();
+                this.search_form.fields[0][2].focus();
             }
         }
     });
@@ -6000,7 +6006,6 @@ var Sao = {};
             this.model_name = model_name;
             this.model = new Sao.Model(model_name, attributes);
             this.attributes = jQuery.extend({}, attributes);
-            this.attributes.limit = this.attributes.limit || Sao.config.limit;
             this.view_ids = jQuery.extend([], attributes.view_ids);
             this.view_to_load = jQuery.extend([],
                 attributes.mode || ['tree', 'form']);
@@ -6012,8 +6017,13 @@ var Sao = {};
             this.current_view = null;
             this.current_record = null;
             this.domain = attributes.domain || [];
+            this.context_domain = attributes.context_domain;
             this.size_limit = null;
-            this.limit = attributes.limit || Sao.config.limit;
+            if (this.attributes.limit === undefined) {
+                this.limit = Sao.config.limit;
+            } else {
+                this.limit = attributes.limit;
+            }
             this.offset = 0;
             this.order = this.default_order = attributes.order;
             var access = Sao.common.MODELACCESS.get(model_name);
@@ -6187,6 +6197,10 @@ var Sao = {};
             }
 
             var domain = this.search_domain(search_string, true);
+            if (this.context_domain) {
+                var decoder = new Sao.PYSON.Decoder(this.context);
+                domain = ['AND', domain, decoder.decode(this.context_domain)];
+            }
             var tab_domain = this.screen_container.get_tab_domain();
             if (!jQuery.isEmptyObject(tab_domain)) {
                 domain = ['AND', domain, tab_domain];
@@ -6206,7 +6220,8 @@ var Sao = {};
             grp_prm.done(this.display.bind(this));
             jQuery.when(grp_prm, count_prm).done(function(group, count) {
                 this.screen_container.but_next.prop('disabled',
-                        !(group.length == this.limit &&
+                        !(this.limit !== undefined &&
+                            group.length == this.limit &&
                             count > this.limit + this.offset));
             }.bind(this));
             this.screen_container.but_prev.prop('disabled', this.offset <= 0);
@@ -6290,10 +6305,10 @@ var Sao = {};
             this.tree_states_done = [];
             this.group = group;
             this.model = group.model;
-            if (jQuery.isEmptyObject(group)) {
-                this.set_current_record(null);
-            } else {
+            if (group && group.length) {
                 this.set_current_record(group[0]);
+            } else {
+                this.set_current_record(null);
             }
             this.group.add_fields(fields);
         },
@@ -6325,7 +6340,7 @@ var Sao = {};
             var deferreds = [];
             if (this.current_record &&
                     ~this.current_record.group.indexOf(this.current_record)) {
-            } else if (!jQuery.isEmptyObject(this.group) &&
+            } else if (this.group && this.group.length &&
                     (this.current_view.view_type != 'calendar')) {
                 this.current_record = this.group[0];
             } else {
@@ -6502,7 +6517,7 @@ var Sao = {};
             var current_record = this.current_record;
             if (!current_record) {
                 if ((this.current_view.view_type == 'tree') &&
-                        (!jQuery.isEmptyObject(this.group))) {
+                        this.group && this.group.length) {
                     this.set_current_record(this.group[0]);
                 } else {
                     return jQuery.when();
@@ -6513,12 +6528,15 @@ var Sao = {};
             var path = current_record.get_path(this.group);
             var prm = jQuery.Deferred();
             if (this.current_view.view_type == 'tree') {
-                prm = this.group.save();
+                prm = this.group.save().then(function() {
+                    return this.current_record;
+                }.bind(this));
             } else {
                 current_record.validate(fields).then(function(validate) {
                     if (validate) {
-                        current_record.save().then(
-                            prm.resolve, prm.reject);
+                        current_record.save().then(function() {
+                            prm.resolve(current_record);
+                        }, prm.reject);
                     } else {
                         this.current_view.display().done(
                                 this.set_cursor.bind(this));
@@ -6527,16 +6545,15 @@ var Sao = {};
                 }.bind(this));
             }
             var dfd = jQuery.Deferred();
-            prm = prm.then(function() {
-                if (path && current_record.id) {
+            prm.then(function(current_record) {
+                if (path && current_record && current_record.id) {
                     path.splice(-1, 1,
                             [path[path.length - 1][0], current_record.id]);
                 }
                 return this.group.get_by_path(path).then(function(record) {
                     this.set_current_record(record);
                 }.bind(this));
-            }.bind(this));
-            prm.then(function() {
+            }.bind(this)).then(function() {
                 this.display().always(dfd.resolve);
             }.bind(this), function() {
                 this.display().always(dfd.reject);
@@ -6764,11 +6781,15 @@ var Sao = {};
             });
         },
         search_prev: function(search_string) {
-            this.offset -= this.limit;
+            if (this.limit) {
+                this.offset -= this.limit;
+            }
             this.search_filter(search_string);
         },
         search_next: function(search_string) {
-            this.offset += this.limit;
+            if (this.limit) {
+                this.offset += this.limit;
+            }
             this.search_filter(search_string);
         },
         invalid_message: function(record) {
@@ -6871,7 +6892,7 @@ var Sao = {};
                         model: this.model_name,
                         id: this.current_record.id,
                         ids: ids
-                    }, null, this.context);
+                    }, null, this.context, true);
                 }
             };
 
@@ -7672,6 +7693,7 @@ function eval_pyson(value){
     Sao.View.Form.Container = Sao.class_(Object, {
         init: function(col) {
             if (col === undefined) col = 4;
+            if (col < 0) col = 0;
             this.col = col;
             this.el = jQuery('<table/>', {
                 'class': 'form-container responsive responsive-noheader'
@@ -7694,14 +7716,16 @@ function eval_pyson(value){
             if (xfill === undefined) xfill = 1;
             var xexpand = attributes.xexpand;
             if (xexpand === undefined) xexpand = 1;
-            var len = 0;
             var row = this.row();
-            row.children().map(function(i, e) {
-                len += Number(jQuery(e).attr('colspan') || 1);
-            });
-            if (len + colspan > this.col) {
-                this.add_row();
-                row = this.row();
+            if (this.col > 0) {
+                var len = 0;
+                row.children().map(function(i, e) {
+                    len += Number(jQuery(e).attr('colspan') || 1);
+                });
+                if (len + colspan > this.col) {
+                    this.add_row();
+                    row = this.row();
+                }
             }
             var el;
             if (widget) {
@@ -8405,7 +8429,7 @@ function eval_pyson(value){
                 'type': 'text',
                 'class': 'form-control input-sm'
             }).appendTo(this.group);
-            if (attributes.autocomplete) {
+            if (!jQuery.isEmptyObject(attributes.autocomplete)) {
                 this.datalist = jQuery('<datalist/>').appendTo(this.el);
                 this.datalist.uniqueId();
                 this.input.attr('list', this.datalist.attr('id'));
@@ -8439,15 +8463,22 @@ function eval_pyson(value){
             Sao.View.Form.Char._super.display.call(this, record, field);
             if (this.datalist) {
                 this.datalist.children().remove();
-                var selection = [];
-                if (record) {
-                    selection = record.autocompletion[this.field_name] || [];
+                var set_autocompletion = function() {
+                    var selection = [];
+                    if (record) {
+                        selection = record.autocompletion[this.field_name] || [];
+                    }
+                    selection.forEach(function(e) {
+                        jQuery('<option/>', {
+                            'value': e
+                        }).appendTo(this.datalist);
+                    }.bind(this));
+                }.bind(this);
+                if (record && !(this.field_name in record.autocompletion)) {
+                    record.do_autocomplete(this.field_name).done(set_autocompletion);
+                } else {
+                    set_autocompletion();
                 }
-                selection.forEach(function(e) {
-                    jQuery('<option/>', {
-                        'value': e
-                    }).appendTo(this.datalist);
-                }.bind(this));
             }
 
             // Set size
@@ -8487,6 +8518,32 @@ function eval_pyson(value){
             Sao.View.Form.Password._super.init.call(this, field_name, model,
                 attributes);
             this.input.prop('type', 'password');
+            this.button = jQuery('<button/>', {
+                'class': 'btn btn-default btn-sm form-control',
+                'type': 'button'
+            }).appendTo(jQuery('<span/>', {
+                'class': 'input-group-btn'
+            }).appendTo(this.group));
+            this._set_password_label();
+            this.button.click(this.toggle_visibility.bind(this));
+
+        },
+        toggle_visibility: function() {
+            if (this.input.prop('type') == 'password') {
+                this.input.prop('type', 'text');
+                this.input.attr('autocomplete', 'off');
+            } else {
+                this.input.prop('type', 'password');
+                this.input.removeAttr('autocomplete');
+            }
+            this._set_password_label();
+        },
+        _set_password_label: function() {
+            if (this.input.prop('type') == 'password') {
+                this.button.text(Sao.i18n.gettext('Show'));
+            } else {
+                this.button.text(Sao.i18n.gettext('Hide'));
+            }
         }
     });
 
@@ -9701,6 +9758,7 @@ function eval_pyson(value){
                 views_preload: attributes.views || {},
                 row_activate: this.activate.bind(this),
                 exclude_field: attributes.relation_field || null,
+                limit: null,
                 pre_validate: attributes.pre_validate
             });
             this.screen.pre_validate = attributes.pre_validate == 1;
@@ -9808,7 +9866,6 @@ function eval_pyson(value){
                     this.screen.domain = domain;
                 }
                 this.screen.size_limit = size_limit;
-                this.screen.attributes.readonly = this._readonly;
                 this.screen.display();
             }.bind(this));
         },
@@ -10124,7 +10181,8 @@ function eval_pyson(value){
                 mode: ['tree'],
                 view_ids: (attributes.view_ids || '').split(','),
                 views_preload: attributes.views || {},
-                row_activate: this.activate.bind(this)
+                row_activate: this.activate.bind(this),
+                limit: null
             });
             this.prm = this.screen.switch_view('tree').done(function() {
                 this.content.append(this.screen.screen_container.el);
@@ -10144,9 +10202,15 @@ function eval_pyson(value){
                     this._required);
         },
         _set_button_sensitive: function() {
-            var size_limit = false;
-            if (this.record() && this.field()) {
-                // TODO
+            var size_limit = false,
+                record = this.record(),
+                field = this.field();
+            if (record && field) {
+                var field_size = record.expr_eval(this.attributes.size);
+                var m2m_size = field.get_eval(record).length;
+                size_limit = (((field_size !== undefined) &&
+                            (field_size !== null)) &&
+                        (m2m_size >= field_size >= 0));
             }
 
             this.entry.prop('disabled', this._readonly);
@@ -10423,13 +10487,12 @@ function eval_pyson(value){
                 prm = jQuery.when(field.get(record));
             }
             prm.done(function(data) {
-                var blob = new Blob([data], {type: mimetype});
-                var blob_url = window.URL.createObjectURL(blob);
-                if (this.blob_url) {
-                    window.URL.revokeObjectURL(this.blob_url);
+                var name;
+                var field = this.filename_field();
+                if (field) {
+                    name = field.get(this.record());
                 }
-                this.blob_url = blob_url;
-                window.open(blob_url);
+                Sao.common.download_file(data, name);
             }.bind(this));
         },
         clear: function() {
@@ -11200,7 +11263,7 @@ function eval_pyson(value){
             return value;
         },
         set_value: function(value) {
-            this.date.data('DateTimePicker').date(value);
+            this.input.data('DateTimePicker').date(value);
         }
     });
 
@@ -11376,6 +11439,11 @@ function eval_pyson(value){
                         label.addClass('editable');
                     }
                 }
+                if (column.attributes.help) {
+                    label.data('toggle', 'tooltip');
+                    label.attr('title', column.attributes.help);
+                    label.tooltip();
+                }
                 if (column.sortable) {
                     var arrow = jQuery('<span/>');
                     label.append(arrow);
@@ -11430,7 +11498,7 @@ function eval_pyson(value){
                         'add_remove', 'sort', 'context', 'filename',
                         'autocomplete', 'translate', 'create', 'delete',
                         'selection_change_with', 'schema_model', 'required',
-                        'readonly'];
+                        'readonly', 'help'];
                     for (i in attribute_names) {
                         var attr = attribute_names[i];
                         if ((attr in model.fields[name].description) &&
@@ -11593,10 +11661,10 @@ function eval_pyson(value){
                 if (!name) {
                     return;
                 }
-                if (decoder.decode(column.attributes.tree_invisible || '0')) {
-                    column.header.hide();
-                } else if (name === this.screen.exclude_field) {
+                if ((decoder.decode(column.attributes.tree_invisible || '0')) ||
+                        (name === this.screen.exclude_field)) {
                     column.header.hide();
+                    column.header.addClass('invisible');
                 } else {
                     var inv_domain = inversion.domain_inversion(domain, name);
                     if (typeof inv_domain != 'boolean') {
@@ -11605,8 +11673,10 @@ function eval_pyson(value){
                     var unique = inversion.unique_value(inv_domain)[0];
                     if (unique && jQuery.isEmptyObject(this.children_field)) {
                         column.header.hide();
+                        column.header.addClass('invisible');
                     } else {
                         column.header.show();
+                        column.header.removeClass('invisible');
                     }
                 }
             }.bind(this));
@@ -11933,7 +12003,8 @@ function eval_pyson(value){
             for (var i = 0; i < this.tree.columns.length; i++) {
                 var column = this.tree.columns[i];
                 td = jQuery('<td/>', {
-                    'data-title': column.attributes.string
+                    // TODO RTL
+                    'data-title': column.attributes.string + Sao.i18n.gettext(': ')
                 }).append(jQuery('<div/>', { // For responsive min-height
                     'aria-hidden': true
                 }));
@@ -11943,6 +12014,13 @@ function eval_pyson(value){
                             true));
                 if (!this.tree.editable) {
                     td.dblclick(this.switch_row.bind(this));
+                } else {
+                    if (column.attributes.required) {
+                        td.addClass('required');
+                    }
+                    if (!column.attributes.readonly) {
+                        td.addClass('editable');
+                    }
                 }
                 var widgets = this.build_widgets();
                 var table = widgets[0];
@@ -12066,8 +12144,10 @@ function eval_pyson(value){
                 if ((column.header.is(':hidden') && thead_visible) ||
                         column.header.css('display') == 'none') {
                     td.hide();
+                    td.addClass('invisible');
                 } else {
                     td.show();
+                    td.removeClass('invisible');
                 }
             }
             var row_id_path = this.get_id_path();
@@ -13212,6 +13292,7 @@ function eval_pyson(value){
                         for (j=0, c_len=child.children.length; j < c_len; j++) {
                             xfield = get_attributes(child.children[j]);
                             field = this.screen.model.fields[xfield.name];
+                            xfield.type = field.description.type;
                             if (!(xfield.string || '')) {
                                 xfield.string = field.description.string;
                             }
@@ -13285,6 +13366,10 @@ function eval_pyson(value){
                 return function () {
                     record = group[index];
                     var x = record.field_get_client(this.xfield.name);
+                    // c3 does not support moment
+                    if (x && (x.isDate || x.isDateTime)) {
+                        x = x.toDate();
+                    }
                     data.columns[0][index + 1] = x;
                     this._add_id(x, record.id);
 
@@ -13341,13 +13426,10 @@ function eval_pyson(value){
             });
         },
         _add_id: function(key, id) {
-            // c3 do not use the moment instance but its date repr when calling
-            // onclick
-            var id_x = (key.isDate || key.isDateTime) ? key._d : key;
-            if (!(id_x in this.ids)) {
-                this.ids[id_x] = [];
+            if (!(key in this.ids)) {
+                this.ids[key] = [];
             }
-            this.ids[id_x].push(id);
+            this.ids[key].push(id);
         },
         display: function(group) {
             var update_prm = this.update_data(group);
@@ -13365,22 +13447,12 @@ function eval_pyson(value){
             c3_config.data.x = 'labels';
             c3_config.data.onclick = this.action.bind(this);
 
-            var i, len;
-            var found, labels;
-            for (i = 0, len = data.columns.length; i < len; i++) {
-                labels = data.columns[i];
-                if (labels[0] == 'labels') {
-                    found = true;
-                    break;
-                }
-            }
-            if (found && (labels.length > 1) &&
-                    (labels[1] && (labels[1].isDateTime || labels[1].isDate)))
-            {
+            var type = this.xfield.type;
+            if ((type == 'date') || (type == 'datetime')) {
                 var format_func, date_format, time_format;
                 date_format = this.view.screen.context.date_format || '%x';
                 time_format = '%X';
-                if (labels[1].isDateTime) {
+                if (type == 'datetime') {
                     format_func = function(dt) {
                         return Sao.common.format_datetime(date_format,
                                 time_format, moment(dt));
@@ -13398,14 +13470,25 @@ function eval_pyson(value){
                         }
                     }
                 };
-            }
-            else {
+            } else {
                 c3_config.axis = {
                     x: {
                         type: 'category',
                     }
                 };
             }
+            var colors = {};
+            for (var i = 0; i < this.yfields.length; i++) {
+                var field = this.yfields[i];
+                if (field.color) {
+                    colors[field.name] = field.color;
+                }
+            }
+            c3_config.data.color = function(color, column) {
+                // column is an object when called for legend
+                var name = column.id || column;
+                return colors[name] || color;
+            };
             return c3_config;
         },
         action: function(data, element) {
@@ -13460,12 +13543,12 @@ function eval_pyson(value){
             // Pie chart do not support axis definition.
             delete config.axis;
             delete config.data.x;
-            var format_func, date_format, datetime_format;
-            if ((labels.length > 0) &&
-                    (labels[0].isDateTime || labels[0].isDate)) {
-                date_format = this.view.screen.context.date_format || '%x';
-                datetime_format = date_format + ' %X';
-                if (labels[1].isDateTime) {
+            var format_func;
+            var type = this.xfield.type;
+            if ((type == 'date') || (type == 'datetime')) {
+                var date_format = this.view.screen.context.date_format || '%x';
+                var datetime_format = date_format + ' %X';
+                if (type == 'datetime') {
                     format_func = function(dt) {
                         return Sao.common.format_datetime(datetime_format, dt);
                     };
@@ -13490,20 +13573,17 @@ function eval_pyson(value){
             return config;
         },
         _add_id: function(key, id) {
-            var id_x = key;
-            if (key.isDateTime || key.isDate) {
+            var type = this.xfield.type;
+            if ((type == 'date') || (type == 'datetime')) {
                 var date_format = this.view.screen.context.date_format || '%x';
                 var datetime_format = date_format + ' %X';
-                if (key.isDateTime) {
-                    id_x = Sao.common.format_datetime(datetime_format, key);
+                if (type == 'datetime') {
+                    key = Sao.common.format_datetime(datetime_format, key);
                 } else {
-                    id_x = Sao.common.format_date(date_format, key);
+                    key = Sao.common.format_date(date_format, key);
                 }
             }
-            if (!(id_x in this.ids)) {
-                this.ids[id_x] = [];
-            }
-            this.ids[id_x].push(id);
+            Sao.View.Graph.Pie._super._add_id.call(this, key, id);
         },
         _action_key: function(data) {
             return data.id;
@@ -13884,6 +13964,7 @@ function eval_pyson(value){
                 params.model = action.res_model || data.res_model;
                 params.res_id = action.res_id || data.res_id;
                 params.context_model = action.context_model;
+                params.context_domain = action.context_domain;
                 params.limit = action.limit;
                 params.icon = action['icon.rec_name'] || '';
 
@@ -13985,31 +14066,36 @@ function eval_pyson(value){
             var name = result[3];
 
             // TODO direct print
-            var blob = new Blob([data],
-                {type: Sao.common.guess_mimetype(report_type)});
-            var blob_url = window.URL.createObjectURL(blob);
-            if (Sao.Action.report_blob_url) {
-                window.URL.revokeObjectURL(Sao.Action.report_blob_url);
-            }
-            Sao.Action.report_blob_url = blob_url;
-            window.open(blob_url);
+            var file_name = name + '.' + report_type;
+            Sao.common.download_file(data, file_name);
         });
     };
 
-    Sao.Action.execute = function(id, data, type, context) {
+    Sao.Action.execute = function(id, data, type, context, keyword) {
         if (!type) {
             Sao.rpc({
                 'method': 'model.ir.action.read',
                 'params': [[id], ['type'], context]
             }, Sao.Session.current_session).done(function(result) {
-                Sao.Action.execute(id, data, result[0].type, context);
+                Sao.Action.execute(id, data, result[0].type, context, keyword);
             });
         } else {
             Sao.rpc({
                 'method': 'model.' + type + '.search_read',
                 'params': [[['action', '=', id]], 0, 1, null, null, context]
             }, Sao.Session.current_session).done(function(result) {
-                Sao.Action.exec_action(result[0], data, context);
+                var action = result[0];
+                if (keyword) {
+                    var keywords = {
+                        'ir.action.report': 'form_report',
+                        'ir.action.wizard': 'form_action',
+                        'ir.action.act_window': 'form_relate'
+                    };
+                    if (!action.keyword) {
+                        action.keyword = keywords[type];
+                    }
+                }
+                Sao.Action.exec_action(action, data, context);
             });
         }
     };
@@ -16711,8 +16797,7 @@ function eval_pyson(value){
         build_dialog: function(message, title, prm) {
             var dialog = Sao.common.WarningDialog._super.build_dialog.call(
                 this);
-            dialog.add_title(title);
-            dialog.body.append(jQuery('<div/>', {
+            var content = jQuery('<div/>', {
                 'class': 'alert alert-warning',
                 role: 'alert'
             }).append(jQuery('<span/>', {
@@ -16721,9 +16806,15 @@ function eval_pyson(value){
             })).append(jQuery('<span/>', {
                 'class': 'sr-only'
             }).append(Sao.i18n.gettext('Warning: '))
-            ).append(jQuery('<span/>')
-                .append(message)
-                .css('white-space', 'pre-wrap')));
+            ).append(jQuery('<h4/>')
+                .append(title)
+                .css('white-space', 'pre-wrap'));
+            if (message) {
+                content.append(jQuery('<span/>')
+                    .append(message)
+                    .css('white-space', 'pre-wrap'));
+            }
+            dialog.body.append(content);
             jQuery('<button/>', {
                 'class': 'btn btn-primary',
                 'type': 'button'
@@ -17005,7 +17096,7 @@ function eval_pyson(value){
             });
             this.el.append(jQuery('<span/>', {
                 'class': 'label label-info',
-                'text': 'Processing...'
+                'text': Sao.i18n.gettext('Processing...')
             }));
             this.el.hide();
             jQuery(function() {
@@ -17313,6 +17404,51 @@ function eval_pyson(value){
             label.removeClass('editable required');
         }
     };
+
+    Sao.common.download_file = function(data, name) {
+        var type = Sao.common.guess_mimetype(
+            name ? name.split('.').pop() : undefined);
+        var blob = new Blob([data], {type: type});
+        var blob_url = window.URL.createObjectURL(blob);
+
+        var dialog = new Sao.Dialog(Sao.i18n.gettext('Download'));
+        var close = function() {
+            dialog.modal.modal('hide');
+        };
+        var a = jQuery('<a/>', {
+                'href': blob_url,
+                'download': name,
+                'text': name,
+                'target': '_blank'
+                }).appendTo(dialog.body)
+                .append(jQuery('<span/>', {
+                    'class': 'glyphicon glyphicon-download-alt'}))
+                .click(close);
+        var button = jQuery('<button/>', {
+            'class': 'btn btn-default',
+            'type': 'button'
+        }).append(Sao.i18n.gettext('Close')).click(close)
+            .appendTo(dialog.footer);
+        dialog.modal.on('shown.bs.modal', function() {
+            // Force the click trigger
+            a[0].click();
+        });
+        dialog.modal.modal('show');
+
+        dialog.modal.on('hidden.bs.modal', function() {
+            jQuery(this).remove();
+            window.URL.revokeObjectURL(this.blob_url);
+        });
+
+    };
+
+    Sao.common.ellipsize = function(string, length) {
+        if (string.length <= length) {
+            return string;
+        }
+        var ellipsis = Sao.i18n.gettext('...');
+        return string.slice(0, length - ellipsis.length) + ellipsis;
+    };
 }());
 
 /* This file is part of Tryton.  The COPYRIGHT file at the top level of
@@ -17389,7 +17525,7 @@ function eval_pyson(value){
                     }
                 }.bind(this));
             }.bind(this));
-            var dialog = new Sao.Dialog('', '', 'lg');
+            var dialog = new Sao.Dialog('', 'window-form', 'lg');
             this.el = dialog.modal;
 
             var readonly = (this.screen.attributes.readonly ||
@@ -17432,7 +17568,9 @@ function eval_pyson(value){
             }.bind(this));
 
             if (view_type == 'tree') {
-                var menu = jQuery('<div/>').appendTo(dialog.body);
+                var menu = jQuery('<div/>', {
+                    'class': 'window-form-toolbar'
+                }).appendTo(dialog.body);
                 var group = jQuery('<div/>', {
                     'class': 'input-group input-group-sm'
                 }).appendTo(menu);
@@ -17729,7 +17867,7 @@ function eval_pyson(value){
                 this.screen.group.forEach(function(record) {
                     resource.set_client(record, this.resource);
                 }.bind(this));
-                prm = this.screen.group.save();
+                prm = this.screen.save_current();
             }
             if (this.attachment_callback) {
                 prm.always(this.attachment_callback.bind(this));
@@ -17770,7 +17908,7 @@ function eval_pyson(value){
                         }
                     }
                 }.bind(this));
-                prm = this.screen.group.save();
+                prm = this.screen.save_current();
             }
             if (this.note_callback) {
                 prm.always(this.note_callback.bind(this));
@@ -17863,13 +18001,9 @@ function eval_pyson(value){
 
                 var callback = function(result) {
                     if (result) {
-                        screen.save_current().then(function() {
-                            var record = screen.current_record;
-                            this.callback([[record.id,
-                                record._values.rec_name || '']]);
-                        }.bind(this), function() {
-                            this.callback(null);
-                        }.bind(this));
+                        var record = screen.current_record;
+                        this.callback([[record.id,
+                            record._values.rec_name || '']]);
                     } else {
                         this.callback(null);
                     }
@@ -17877,6 +18011,7 @@ function eval_pyson(value){
                 this.el.modal('hide');
                 new Sao.Window.Form(screen, callback.bind(this), {
                     new_: true,
+                    save_current: true,
                     title: this.title
                 });
                 return;
@@ -18255,7 +18390,6 @@ function eval_pyson(value){
                 'size': '1',
                 'maxlength': '1',
                 'value': '\"',
-                'readonly': '' // Until PapaParse releases custom quote feature
             });
 
             jQuery('<div/>', {
@@ -18493,7 +18627,7 @@ function eval_pyson(value){
             Papa.parse(this.file_input[0].files[0], {
                 config: {
                     delimiter: this.el_csv_delimiter.val(),
-                    // TODO quoteChar: this.el_csv_quotechar.val(),
+                    quoteChar: this.el_csv_quotechar.val(),
                     preview: 1,
                     encoding: this.el_csv_encoding.val()
                 },
@@ -18592,7 +18726,7 @@ function eval_pyson(value){
             Papa.parse(this.file_input[0].files[0], {
                 config: {
                     delimiter: this.el_csv_delimiter.val(),
-                    // TODO quoteChar: this.el_csv_quotechar.val(),
+                    quoteChar: this.el_csv_quotechar.val(),
                     encoding: encoding
                 },
                 error: function(err, file, inputElem, reason) {
@@ -18632,10 +18766,11 @@ function eval_pyson(value){
     });
 
     Sao.Window.Export = Sao.class_(Sao.Window.CSV, {
-        init: function(screen, ids, names) {
+        init: function(screen, ids, names, context) {
             this.ids = ids;
             this.screen = screen;
             this.session = Sao.Session.current_session;
+            this.context = context;
             Sao.Window.Export._super.init.call(this,
                 Sao.i18n.gettext('Export to CSV')).then(function() {
                     names.forEach(function(name) {
@@ -18995,7 +19130,7 @@ function eval_pyson(value){
                 Sao.rpc({
                     'method': 'model.' + this.screen.model_name +
                         '.export_data',
-                    'params': [this.ids, fields, {}]
+                    'params': [this.ids, fields, this.context]
                 }, this.session).then(function(data) {
                     this.export_csv(fields2, data).then(function() {
                         this.destroy();
@@ -19013,7 +19148,7 @@ function eval_pyson(value){
                 unparse_obj.fields = fields;
             }
             var csv = Papa.unparse(unparse_obj, {
-                // TODO quoteChar: this.el_csv_quotechar.val(),
+                quoteChar: this.el_csv_quotechar.val(),
                 delimiter: this.el_csv_delimiter.val()
             });
             var blob = new Blob([csv], {type: 'text/csv;charset=' + encoding});
@@ -19515,11 +19650,14 @@ function eval_pyson(value){
 
     Sao.View.Board.Action = Sao.class_(Object, {
         init: function(attributes, context) {
+            if (context === undefined) {
+                context = {};
+            }
             var model, action_prm, act_window;
             var decoder, search_context, search_value;
 
             this.name = attributes.name;
-            this.context = context || {};
+            this.context = jQuery.extend({}, context);
 
             act_window = new Sao.Model('ir.action.act_window');
             this.action_prm = act_window.execute('get', [this.name],
diff --git a/dist/tryton-sao.min.css b/dist/tryton-sao.min.css
index 38cf648..8da531d 100644
--- a/dist/tryton-sao.min.css
+++ b/dist/tryton-sao.min.css
@@ -1,26 +1,22 @@
-.navbar {
-  z-index: 1000;
+#tablist > li > a > span {
+  display: inline-block;
+  max-width: 9em;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 .tab-form nav.toolbar,
 .tab-board nav.toolbar {
   margin-bottom: 1px;
 }
-.tab-form nav.toolbar ul.nav > li > a,
-.tab-board nav.toolbar ul.nav > li > a {
-  padding-right: 0px;
-}
 .tab-form nav.toolbar.affix,
 .tab-board nav.toolbar.affix {
   top: 51px;
   z-index: 999;
 }
-.nav-tabs > li .close {
-  margin: -2px 0 0 10px;
-  font-size: 18px;
-}
 @media screen and (max-width: 767px) {
-  .tab-form .navbar-nav > li,
-  .tab-board .navbar-nav > li {
+  .tab-form .navbar-header > ul > li,
+  .tab-board .navbar-header > ul > li {
     float: left;
     width: 50%;
   }
@@ -53,6 +49,7 @@ button img.icon {
   overflow: hidden;
   text-overflow: ellipsis;
   min-width: 30px;
+  text-align: center;
 }
 .treeview > table.tree > thead > tr > th > label.sortable {
   cursor: pointer;
@@ -109,10 +106,10 @@ button img.icon {
 .form {
   width: 100%;
 }
-.form > .form-container {
+.form > table.form-container {
   width: 100%;
 }
-.form > .form-container td {
+.form > table.form-container > tbody > tr > td {
   padding: 1px;
 }
 .form td.form-label {
@@ -203,6 +200,12 @@ button img.icon {
 .column-timedelta {
   text-align: right;
 }
+input.column-boolean,
+input.selection {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
 .form-boolean input[type=checkbox],
 .editabletree-boolean input[type=checkbox] {
   width: initial;
@@ -217,6 +220,9 @@ button img.icon {
 .progress {
   margin-bottom: 0px;
 }
+.window-form .window-form-toolbar {
+  text-align: right;
+}
 .csv .modal-dialog .column-fields {
   height: 35vh;
   overflow-y: scroll;
@@ -234,10 +240,10 @@ button img.icon {
   table.responsive,
   table.responsive > thead,
   table.responsive > thead > tr,
-  table.responsive > thead > tr > th,
+  table.responsive > thead > tr > th:not(.invisible),
   table.responsive > tbody,
   table.responsive > tbody > tr,
-  table.responsive > tbody > tr > td {
+  table.responsive > tbody > tr > td:not(.invisible) {
     display: block !important;
   }
   table.responsive {
@@ -267,7 +273,6 @@ button img.icon {
     border: none;
     border-bottom: 1px solid #eee;
     position: relative;
-    padding-left: 30%;
   }
   table.responsive-header > tbody > tr > td:before {
     /* Now like a table header */
@@ -275,15 +280,19 @@ button img.icon {
     /* Top/left values mimic padding */
     top: 6px;
     left: 6px;
-    width: 30%;
     padding-right: 10px;
     text-align: left;
-    font-weight: bold;
     overflow: hidden;
     text-overflow: ellipsis;
     /* Label */
     content: attr(data-title);
   }
+  table.responsive-header > tbody > tr > td.required:before {
+    font-weight: bold;
+  }
+  table.responsive-header > tbody > tr > td.editable:before {
+    font-style: italic;
+  }
 }
 #processing {
   position: fixed;
diff --git a/dist/tryton-sao.min.js b/dist/tryton-sao.min.js
index a8bc3ef..ce489cd 100644
--- a/dist/tryton-sao.min.js
+++ b/dist/tryton-sao.min.js
@@ -1,14 +1,14 @@
-/*! tryton-sao-4.2.3 | GPL-3
+/*! tryton-sao-4.4.0 | GPL-3
 This file is part of Tryton.  The COPYRIGHT file at the top level of
 this repository contains the full copyright notices and license terms. */
-function eval_pyson(value){with(Sao.PYSON.eval)return eval(value)}var Sao={};!function(){"use strict";function a(){var a=1040;jQuery(".modal.in").each(function(b){var c=jQuery(this);a++,c.css("zIndex",a),c.next(".modal-backdrop.in").addClass("hidden").css("zIndex",a-1)}),jQuery(".modal.in:visible:last").focus().next(".modal-backdrop.in").removeClass("hidden")}"contains"in String.prototype||(String.prototype.contains=function(a,b){return-1!==String.prototype.indexOf.call(this,a,b)}),String.prototype.startsWith||Object.defineProperty(String.prototype,"startsWith",{enumerable:!1,configurable:!1,writable:!1,value:function(a,b){return b=b||0,this.indexOf(a,b)===b}}),String.prototype.endsWith||Object.defineProperty(String.prototype,"endsWith",{enumerable:!1,configurable:!1,writable:!1,value:function(a,b){b=b||this.length,b-=a.length;var c=this.lastIndexOf(a);return c!==-1&&c===b}}),Array.prototype.some||(Array.prototype.some=function(a){if(null===this)throw new TypeError;var b,c,d=Object(this),e=d.length>>>0;if("function"!=typeof a)throw new TypeError;for(b=arguments[1],c=0;c<e;c++)if(c in d&&a.call(b,d[c],c,d))return!0;return!1});try{document.execCommand("styleWithCSS",!1,!1)}catch(b){}try{document.execCommand("useCSS",!1,!0)}catch(b){}jQuery.fn.extend({uniqueId:function(){var a=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})}}()}),Sao.class_=function(a,b){var c=function(){if(!(this instanceof c))throw new Error("Constructor function requires new operator");this.Class=c,this.init&&this.init.apply(this,arguments)};if(c.prototype=Object.create(a.prototype),c._super=a.prototype,b)for(var d in b)c.prototype[d]=b[d];return c},Sao.Decimal=Number,Sao.Date=function(a,b,c){var d=moment();return d.year(a),d.month(b),d.date(c),d.set({hour:0,minute:0,second:0,millisecond:0}),d.isDate=!0,d},Sao.Date.min=moment(new Date(-864e13)),Sao.Date.min.set({hour:0,minute:0,second:0,millisecond:0}),Sao.Date.min.isDate=!0,Sao.Date.max=moment(new Date(864e13)),Sao.Date.max.set({hour:0,minute:0,second:0,millisecond:0}),Sao.Date.max.isDate=!0,Sao.DateTime=function(a,b,c,d,e,f,g,h){var i;return void 0===b?(i=moment(a),a=void 0):i=moment(),h&&i.utc(),i.year(a),i.month(b),i.date(c),void 0!==b&&(i.hour(d||0),i.minute(e||0),i.second(f||0),i.milliseconds(g||0)),i.isDateTime=!0,i.local(),i},Sao.DateTime.combine=function(a,b){var c=a.clone();return c.set({hour:b.hour(),minute:b.minute(),second:b.second(),millisecond:b.millisecond()}),c.isDateTime=!0,c},Sao.DateTime.min=moment(new Date(-864e13)).local(),Sao.DateTime.min.isDateTime=!0,Sao.DateTime.max=moment(new Date(864e13)).local(),Sao.DateTime.max.isDateTime=!0,Sao.Time=function(a,b,c,d){var e=moment({hour:a,minute:b,second:c,millisecond:d||0});return e.isTime=!0,e},Sao.TimeDelta=function(a,b,c,d,e,f){var g=moment.duration({days:a,seconds:b,milliseconds:c,minutes:d,hours:e,weeks:f});return g.isTimeDelta=!0,g},Sao.config={},Sao.config.limit=1e3,Sao.config.display_size=20,Sao.config.roundup={},Sao.config.roundup.url="http://bugs.tryton.org/roundup/",Sao.config.title="Tryton",Sao.i18n=i18n(),Sao.i18n.setlang=function(a){return a||(a=(navigator.language||navigator.browserLanguage||navigator.userLanguage||"en").replace("-","_")),Sao.i18n.setLocale(a),moment.locale(a.slice(0,2)),jQuery.getJSON("locale/"+a+".json",function(b){b[""].language||(b[""].language=a),b[""]["plural-forms"]||(b[""]["plural-forms"]="nplurals=2; plural=(n!=1);");for(var c in b)""!==c&&(b[c]=2==b[c].length?b[c][1]:b[c].slice(1));Sao.i18n.loadJSON(b)})},Sao.i18n.getlang=function(){return Sao.i18n.getLocale()},Sao.i18n.setlang(),Sao.get_preferences=function(){var a=Sao.Session.current_session;return a.reload_context().then(function(){return Sao.rpc({method:"model.res.user.get_preferences",params:[!1,{}]},a).then(function(a){var b=[];return b.push(Sao.common.MODELACCESS.load_models()),b.push(Sao.common.ICONFACTORY.load_icons()),b.push(Sao.common.MODELHISTORY.load_history()),b.push(Sao.common.VIEW_SEARCH.load_searches()),jQuery.when.apply(jQuery,b).then(function(){(a.actions||[]).forEach(function(a){Sao.Action.execute(a,{},null,{})});var b=Sao.config.title;jQuery.isEmptyObject(a.status_bar)||(b+=" - "+a.status_bar),document.title=b;var c=a.language!=Sao.i18n.getLocale(),d=jQuery.Deferred();return Sao.i18n.setlang(a.language).always(function(){c&&Sao.user_menu(a),d.resolve(a)}),d})})})},Sao.login=function(){Sao.Session.get_credentials().then(function(a){return Sao.Session.current_session=a,a.reload_context()}).then(Sao.get_preferences).then(function(a){Sao.menu(a),Sao.user_menu(a)})},Sao.logout=function(){var a=Sao.Session.current_session;Sao.Tab.tabs.close(!0).done(function(){jQuery("#user-preferences").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#menu").children().remove(),document.title=Sao.config.title,a.do_logout().always(Sao.login)})},Sao.preferences=function(){Sao.Tab.tabs.close(!0).done(function(){jQuery("#user-preferences").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#menu").children().remove(),new Sao.Window.Preferences(function(){Sao.get_preferences().then(function(a){Sao.menu(a),Sao.user_menu(a)})})})},Sao.favorites_menu=function(){var a=function(){e&&e.remove()};if(jQuery(window).click(function(){a()}),0!==jQuery("#user-favorites").children(".dropdown-menu").length)a();else{var b=Sao.main_menu_screen.model_name+".favorite",c=Sao.Session.current_session,d={method:"model."+b+".get"},e=jQuery("<ul/>",{class:"dropdown-menu","aria-expanded":"false"});jQuery("#user-favorites").append(e),Sao.rpc(d,c).then(function(b){b.forEach(function(b){var c=jQuery("<a/>",{href:"#"}),d=b[0],f=jQuery("<li/>",{role:"presentation"}),g=jQuery("<img/>",{class:"favorite-icon"});c.append(g),f.append(c),g.attr("src",Sao.common.ICONFACTORY.get_icon_url(b[2])),c.append(b[1]),c.click(function(){a(),Sao.Action.exec_keyword("tree_open",{model:Sao.main_menu_screen.model_name,id:d,ids:[d]})}),e.append(f)}),e.append(jQuery("<li/>",{class:"divider"})),jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{href:"#"}).click(function(){a(),Sao.Tab.create({model:Sao.main_menu_screen.model_name+".favorite",mode:["tree","form"],name:Sao.i18n.gettext("Manage favorites")})}).text(Sao.i18n.gettext("Manage favorites"))).appendTo(e)})}},Sao.user_menu=function(a){jQuery("#user-preferences").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#user-preferences").append(jQuery("<a/>",{href:"#"}).click(Sao.preferences).append(a.status_bar)),jQuery("#user-logout").append(jQuery("<a/>",{href:"#"}).click(Sao.logout).append(Sao.i18n.gettext("Logout"))),jQuery("#user-favorites").append(jQuery("<a/>",{href:"#","data-toggle":"dropdown"}).click(Sao.favorites_menu).append(Sao.i18n.gettext("Favorites")))},Sao.menu=function(a){var b=new Sao.PYSON.Decoder,d=b.decode(a.pyson_menu),e=!1;jQuery.isEmptyObject(d.views)?d.view_id&&(e=[d.view_id[0]]):e=d.views.map(function(a){return a[0]}),b=new Sao.PYSON.Decoder(Sao.Session.current_session.context);var f=b.decode(d.pyson_context||"{}"),g=b.decode(d.pyson_domain),h=new Sao.Tab.Form(d.res_model,{mode:["tree"],view_ids:e,domain:g,context:f,selection_mode:Sao.common.SELECTION_NONE});Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(h),1),h.view_prm.done(function(){Sao.main_menu_screen=h.screen;var a=h.screen.current_view;a.table.find("thead").hide(),jQuery("#menu").children().remove();var b=new Sao.GlobalSearch;jQuery("#menu").append(b.el),jQuery("#menu").append(h.screen.screen_container.content_box.detach()),h.screen.views[0].columns.push(new c(h.screen.model.fields.favorite))})},Sao.main_menu_screen=null;var c=Sao.class_(Object,{init:function(a){this.field=a,this.header=jQuery("<th/>"),this.attributes=jQuery.extend({},this.field.description),this.attributes.name=this.field.name},get_cell:function(){var a=jQuery("<span/>",{tabindex:0});return a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.field.name).done(function(){if(null!==a._values.favorite){var c="glyphicon glyphicon-star";a._values.favorite||(c+="-empty"),b.addClass(c),b.click({record:a,button:b},this.favorite_click)}}.bind(this)),b},favorite_click:function(a){a.stopImmediatePropagation();var b,c=a.data.button;c.hasClass("glyphicon-star-empty")?(c.removeClass("glyphicon-star-empty"),c.addClass("glyphicon-star"),b="set"):(c.removeClass("glyphicon-star"),c.addClass("glyphicon-star-empty"),b="unset");var d=Sao.main_menu_screen.model_name+".favorite",e=Sao.Session.current_session,f={method:"model."+d+"."+b,params:[a.data.record.id,e.context]};Sao.rpc(f,e)}});Sao.Dialog=Sao.class_(Object,{init:function(a,b,c){c=c||"sm",this.modal=jQuery("<div/>",{class:b+" modal fade",role:"dialog","data-backdrop":"static"}),this.content=jQuery("<form/>",{class:"modal-content"}).appendTo(jQuery("<div/>",{class:"modal-dialog modal-"+c}).appendTo(this.modal)),this.header=jQuery("<div/>",{class:"modal-header"}).appendTo(this.content),a&&this.add_title(a),this.body=jQuery("<div/>",{class:"modal-body"}).appendTo(this.content),this.footer=jQuery("<div/>",{class:"modal-footer"}).appendTo(this.content)},add_title:function(a){this.header.append(jQuery("<h4/>",{class:"modal-title"}).append(a))}}),Sao.GlobalSearch=Sao.class_(Object,{init:function(){this.el=jQuery("<div/>",{class:"global-search-container"}),this.search_entry=jQuery("<input>",{class:"form-control",placeholder:Sao.i18n.gettext("Search...")}),this.el.append(this.search_entry);new Sao.common.InputCompletion(this.search_entry,this.update.bind(this),this.match_selected.bind(this),this.format.bind(this))},format:function(a){var b=jQuery("<div/>"),c=jQuery("<img/>",{class:"global-search-icon"}).appendTo(b);return Sao.common.ICONFACTORY.register_icon(a.icon).then(function(a){c.attr("src",a)}),jQuery("<span/>",{class:"global-search-text"}).text(a.record_name).appendTo(b),b},update:function(a){var b=new Sao.Model("ir.model");return b.execute("global_search",[a,Sao.config.limit,Sao.main_menu_screen.model_name],Sao.main_menu_screen.context).then(function(a){for(var b=[],c=0,d=a.length;c<d;c++)b.push({model:a[c][1],model_name:a[c][2],record_id:a[c][3],record_name:a[c][4],icon:a[c][5]});return b}.bind(this))},match_selected:function(a){if(a.model==Sao.main_menu_screen.model_name)Sao.Action.exec_keyword("tree_open",{model:a.model,id:a.record_id,ids:[a.record_id]},Sao.main_menu_screen.context);else{var b={model:a.model,res_id:a.record_id,mode:["form","tree"],name:a.model_name};Sao.Tab.create(b)}this.search_entry.val("")}}),jQuery(document).on("show.bs.modal",".modal",function(a){jQuery(this).appendTo(jQuery("body"))}).on("shown.bs.modal",".modal.in",function(b){a()}).on("hidden.bs.modal",".modal",function(b){a()})}(),function(){"use strict";Sao.rpc=function(a,b){var c=jQuery.Deferred();b||(b=new Sao.Session);var d=jQuery.extend([],a.params);d.push(jQuery.extend({},b.context,d.pop()));var e=Sao.common.processing.show(),f=jQuery.ajax({headers:{Authorization:"Session "+b.get_auth()},contentType:"application/json",data:JSON.stringify(Sao.rpc.prepareObject({id:Sao.rpc.id++,method:a.method,params:d})),dataType:"json",url:"/"+(b.database||"")+"/",type:"post",complete:[function(){Sao.common.processing.hide(e)}]}),g=function(d){if(null===d)Sao.common.warning.run("",Sao.i18n.gettext("Unable to reach the server")),c.reject();else if(d.error){var e,f,g;if("UserWarning"==d.error[0])return e=d.error[1][0],f=d.error[1][1],g=d.error[1][2],void Sao.common.userwarning.run(f,g).done(function(d){return~["always","ok"].indexOf(d)?void Sao.rpc({method:"model.res.user.warning.create",params:[[{user:b.user_id,name:e,always:"always"==d}],{}]},b).done(function(){Sao.rpc(a,b).then(c.resolve,c.reject)}):void c.reject()});if("UserError"==d.error[0])return f=d.error[1][0],g=d.error[1][1],void Sao.common.warning.run(f,g).always(c.reject);if("ConcurrencyException"==d.error[0]){if(a.method.startsWith("model.")&&(a.method.endsWith(".write")||a.method.endsWith(".delete"))){var h=a.method.split(".").slice(1,-1).join(".");return void Sao.common.concurrency.run(h,a.params[0][0],a.params.slice(-1)[0]).then(function(){delete a.params.slice(-1)[0]._timestamp,Sao.rpc(a,b).then(c.resolve,c.reject)},c.reject)}return void Sao.common.message.run("Concurrency Exception","glyphicon-alert").always(c.reject)}Sao.common.error.run(d.error[0],d.error[1]),c.reject()}else c.resolve(d.result)},h=function(d,e,f){return 403==d.status?void Sao.Session.renew(b).then(function(){Sao.rpc(a,b).then(c.resolve,c.reject)},c.reject):(Sao.common.error.run(e,f),void c.reject())};return f.success(g),f.error(h),c.promise()},Sao.rpc.id=0,Sao.rpc.convertJSONObject=function(a,b,c){if(a instanceof Array)for(var d=0,e=a.length;d<e;d++)Sao.rpc.convertJSONObject(a[d],d,a);else if("string"!=typeof a&&"number"!=typeof a&&null!==a)if(a&&a.__class__){switch(a.__class__){case"datetime":a=Sao.DateTime(a.year,a.month-1,a.day,a.hour,a.minute,a.second,a.microsecond/1e3,!0);break;case"date":a=Sao.Date(a.year,a.month-1,a.day);break;case"time":a=Sao.Time(a.hour,a.minute,a.second,a.microsecond/1e3);break;case"timedelta":a=Sao.TimeDelta(null,a.seconds);break;case"bytes":for(var f=atob(a.base64.replace(/\s/g,"")),g=new ArrayBuffer(f.length),h=new Uint8Array(g),i=0;i<f.length;i++)h[i]=f.charCodeAt(i);a=h;break;case"Decimal":a=new Sao.Decimal(a.decimal)}c&&(c[b]=a)}else for(var j in a)Sao.rpc.convertJSONObject(a[j],j,a);return c||a},Sao.rpc.prepareObject=function(a,b,c){if(a instanceof Array){a=jQuery.extend([],a);for(var d=0,e=a.length;d<e;d++)Sao.rpc.prepareObject(a[d],d,a)}else if("string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a&&null!==a&&void 0!==a)if(a.isDate)a={__class__:"date",year:a.year(),month:a.month()+1,day:a.date()};else if(a.isDateTime)a=a.clone(),a={__class__:"datetime",year:a.utc().year(),month:a.utc().month()+1,day:a.utc().date(),hour:a.utc().hour(),minute:a.utc().minute(),second:a.utc().second(),microsecond:1e3*a.utc().millisecond()};else if(a.isTime)a={__class__:"time",hour:a.hour(),minute:a.minute(),second:a.second(),microsecond:1e3*a.millisecond()};else if(a.isTimeDelta)a={__class__:"timedelta",seconds:a.asSeconds()};else if(a instanceof Sao.Decimal)a={__class__:"Decimal",decimal:a.toString()};else if(a instanceof Uint8Array){for(var f=[],g=65535,h=0;h*g<a.length;h++)f.push(String.fromCharCode.apply(null,a.subarray(h*g,(h+1)*g)));a={__class__:"bytes",base64:btoa(f.join(""))}}else{a=jQuery.extend({},a);for(var i in a)Sao.rpc.prepareObject(a[i],i,a)}return c&&(c[b]=a),c||a},jQuery.ajaxSetup({converters:{"text json":function(a){return Sao.rpc.convertJSONObject(jQuery.parseJSON(a))}}})}(),function(){"use strict";Sao.PYSON={},Sao.PYSON.eval={},Sao.PYSON.PYSON=Sao.class_(Object,{init:function(){},pyson:function(){throw"NotImplementedError"},types:function(){throw"NotImplementedError"},toString:function(){var a=this.pyson().__class__,b=this.__string_params__().map(function(a){return a instanceof Sao.PYSON.PYSON?a.toString():JSON.stringify(a)});return a+"("+b.join(", ")+")"},__string_params__:function(){throw"NotImplementedError"}}),Sao.PYSON.PYSON.eval_=function(a,b){throw"NotImplementedError"},Sao.PYSON.PYSON.init_from_object=function(a){throw"NotImplementedError"},Sao.PYSON.Encoder=Sao.class_(Object,{prepare:function(a,b,c){if(null!==a&&void 0!==a)if(a instanceof Array){a=jQuery.extend([],a);for(var d=0,e=a.length;d<e;d++)this.prepare(a[d],d,a)}else a._isAMomentObject&&(a=a.isDate?new Sao.PYSON.Date(a.year(),a.month()+1,a.date()).pyson():new Sao.PYSON.DateTime(a.year(),a.month()+1,a.date(),a.hours(),a.minutes(),a.seconds(),1e3*a.milliseconds()).pyson());return c&&(c[b]=a),c||a},encode:function(a){return a=this.prepare(a),JSON.stringify(a,function(a,b){return b instanceof Sao.PYSON.PYSON?b.pyson():null===b||void 0===b?null:b})}}),Sao.PYSON.Decoder=Sao.class_(Object,{init:function(a,b){this.__context=a||{},this.noeval=b||!1},decode:function(a){var b=function(a,b){if("object"==typeof b&&null!==b){var c=Sao.PYSON[b.__class__];if(c){if(this.noeval){var d=jQuery.extend({},b);return delete d.__class__,Sao.PYSON[b.__class__].init_from_object(d)}return c.eval_(b,this.__context)}}return b};return JSON.parse(a,b.bind(this))}}),Sao.PYSON.eval.Eval=function(a,b){return new Sao.PYSON.Eval(a,b)},Sao.PYSON.Eval=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){void 0===b&&(b=""),Sao.PYSON.Eval._super.init.call(this),this._value=a,this._default=b},pyson:function(){return{__class__:"Eval",v:this._value,d:this._default}},types:function(){return this._default instanceof Sao.PYSON.PYSON?this._default.types():[typeof this._default]},__string_params__:function(){return[this._value,this._default]}}),Sao.PYSON.Eval.eval_=function(a,b){return a.v in b?b[a.v]:a.d},Sao.PYSON.Eval.init_from_object=function(a){return new Sao.PYSON.Eval(a.v,a.d)},Sao.PYSON.eval.Not=function(a){return new Sao.PYSON.Not(a)},Sao.PYSON.Not=Sao.class_(Sao.PYSON.PYSON,{init:function(a){if(Sao.PYSON.Not._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["boolean","object"]).length||jQuery(["boolean"]).not(a.types()).length)throw"value must be boolean"}else if("boolean"!=typeof a)throw"value must be boolean";this._value=a},pyson:function(){return{__class__:"Not",v:this._value}},types:function(){return["boolean"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Not.eval_=function(a,b){return!a.v},Sao.PYSON.Not.init_from_object=function(a){return new Sao.PYSON.Not(a.v)},Sao.PYSON.eval.Bool=function(a){return new Sao.PYSON.Bool(a)},Sao.PYSON.Bool=Sao.class_(Sao.PYSON.PYSON,{init:function(a){Sao.PYSON.Bool._super.init.call(this),this._value=a},pyson:function(){return{__class__:"Bool",v:this._value}},types:function(){return["boolean"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Bool.eval_=function(a,b){return moment.isMoment(a.v)&&a.v.isTime?Boolean(a.v.hour()||a.v.minute()||a.v.second()||a.v.millisecond()):moment.isDuration(a.v)?Boolean(a.v.valueOf()):a.v instanceof Object?!jQuery.isEmptyObject(a.v):Boolean(a.v)},Sao.PYSON.Bool.init_from_object=function(a){return new Sao.PYSON.Bool(a.v)},Sao.PYSON.eval.And=function(a){return new Sao.PYSON.And(a)},Sao.PYSON.And=Sao.class_(Sao.PYSON.PYSON,{init:function(a){void 0===a&&(a=[]),Sao.PYSON.And._super.init.call(this);for(var b=0,c=a.length;b<c;b++){var d=a[b];if(d instanceof Sao.PYSON.PYSON){if(jQuery(d.types()).not(["boolean"]).length||jQuery(["boolean"]).not(d.types()).length)throw"statement must be boolean"}else if("boolean"!=typeof d)throw"statement must be boolean"}if(a.length<2)throw"must have at least 2 statements";this._statements=a},pyson:function(){return{__class__:"And",s:this._statements}},types:function(){return["boolean"]},__string_params__:function(){return this._statements}}),Sao.PYSON.And.eval_=function(a,b){for(var c=!0,d=0,e=a.s.length;d<e;d++){var f=a.s[d];c=c&&f}return c},Sao.PYSON.And.init_from_object=function(a){return new Sao.PYSON.And(a.s)},Sao.PYSON.eval.Or=function(a){return new Sao.PYSON.Or(a)},Sao.PYSON.Or=Sao.class_(Sao.PYSON.And,{pyson:function(){var a=Sao.PYSON.Or._super.pyson.call(this);return a.__class__="Or",a}}),Sao.PYSON.Or.eval_=function(a,b){for(var c=!1,d=0,e=a.s.length;d<e;d++){var f=a.s[d];c=c||f}return c},Sao.PYSON.Or.init_from_object=function(a){return new Sao.PYSON.Or(a.s)},Sao.PYSON.eval.Equal=function(a,b){return new Sao.PYSON.Equal(a,b)},Sao.PYSON.Equal=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){Sao.PYSON.Equal._super.init.call(this);var c,d;if(c=a instanceof Sao.PYSON.PYSON?a.types():[typeof a],d=b instanceof Sao.PYSON.PYSON?b.types():[typeof b],jQuery(c).not(d).length||jQuery(d).not(c).length)throw"statements must have the same type";this._statement1=a,this._statement2=b},pyson:function(){return{__class__:"Equal",s1:this._statement1,s2:this._statement2}},types:function(){return["boolean"]},__string_params__:function(){return[this._statement1,this._statement2]}}),Sao.PYSON.Equal.eval_=function(a,b){return a.s1 instanceof Array&&a.s2 instanceof Array?Sao.common.compare(a.s1,a.s2):a.s1==a.s2},Sao.PYSON.Equal.init_from_object=function(a){return new Sao.PYSON.Equal(a.s1,a.s2)},Sao.PYSON.eval.Greater=function(a,b,c){return new Sao.PYSON.Greater(a,b,c)},Sao.PYSON.Greater=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){Sao.PYSON.Greater._super.init.call(this);for(var d=[a,b],e=0;e<2;e++){var f=d[e];if(f instanceof Sao.PYSON.PYSON){if(jQuery(f).not(["number"]).length)throw"statement must be an integer or a float"}else if(!~["number","object"].indexOf(typeof f))throw"statement must be an integer or a float"}if(void 0===c&&(c=!1),c instanceof Sao.PYSON.PYSON){if(jQuery(c.types()).not(["boolean"]).length||jQuery(["boolean"]).not(c.types()).length)throw"equal must be boolean"}else if("boolean"!=typeof c)throw"equal must be boolean";this._statement1=a,this._statement2=b,this._equal=c},pyson:function(){return{__class__:"Greater",s1:this._statement1,s2:this._statement2,e:this._equal}},types:function(){return["boolean"]},__string_params__:function(){return[this._statement1,this._statement2,this._equal]}}),Sao.PYSON.Greater._convert=function(a){return a=jQuery.extend({},a),a.s1=Number(a.s1),a.s2=Number(a.s2),a},Sao.PYSON.Greater.eval_=function(a,b){return a=Sao.PYSON.Greater._convert(a),a.e?a.s1>=a.s2:a.s1>a.s2},Sao.PYSON.Greater.init_from_object=function(a){return new Sao.PYSON.Greater(a.s1,a.s2,a.e)},Sao.PYSON.eval.Less=function(a,b,c){return new Sao.PYSON.Less(a,b,c)},Sao.PYSON.Less=Sao.class_(Sao.PYSON.Greater,{pyson:function(){var a=Sao.PYSON.Less._super.pyson.call(this);return a.__class__="Less",a}}),Sao.PYSON.Less._convert=Sao.PYSON.Greater._convert,Sao.PYSON.Less.eval_=function(a,b){return a=Sao.PYSON.Less._convert(a),a.e?a.s1<=a.s2:a.s1<a.s2},Sao.PYSON.Less.init_from_object=function(a){return new Sao.PYSON.Less(a.s1,a.s2,a.e)},Sao.PYSON.eval.If=function(a,b,c){return new Sao.PYSON.If(a,b,c)},Sao.PYSON.If=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){if(Sao.PYSON.If._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["boolean"]).length||jQuery(["boolean"]).not(a.types()).length)throw"condition must be boolean"}else if("boolean"!=typeof a)throw"condition must be boolean";var d,e;if(d=b instanceof Sao.PYSON.PYSON?b.types():[typeof b],void 0===c&&(c=null),e=c instanceof Sao.PYSON.PYSON?c.types():[typeof c],jQuery(d).not(e).length||jQuery(e).not(d).length)throw"then and else statements must be the same type";this._condition=a,this._then_statement=b,this._else_statement=c},pyson:function(){return{__class__:"If",c:this._condition,t:this._then_statement,e:this._else_statement}},types:function(){return this._then_statement instanceof Sao.PYSON.PYSON?this._then_statement.types():[typeof this._then_statement]},__string_params__:function(){return[this._condition,this._then_statement,this._else_statement]}}),Sao.PYSON.If.eval_=function(a,b){return a.c?a.t:a.e},Sao.PYSON.If.init_from_object=function(a){return new Sao.PYSON.If(a.c,a.t,a.e)},Sao.PYSON.eval.Get=function(a,b,c){return new Sao.PYSON.Get(a,b,c)},Sao.PYSON.Get=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){if(Sao.PYSON.Get._super.init.call(this),void 0===c&&(c=null),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["object"]).length||jQuery(["object"]).not(a.types()).length)throw"obj must be a dict"}else if(!(a instanceof Object))throw"obj must be a dict";if(this._obj=a,b instanceof Sao.PYSON.PYSON){if(jQuery(b.types()).not(["string"]).length||jQuery(["string"]).not(b.types()).length)throw"key must be a string"}else if("string"!=typeof b)throw"key must be a string";this._key=b,this._default=c},pyson:function(){return{__class__:"Get",v:this._obj,k:this._key,d:this._default}},types:function(){return this._default instanceof Sao.PYSON.PYSON?this._default.types():[typeof this._default]},__string_params__:function(){return[this._obj,this._key,this._default]}}),Sao.PYSON.Get.eval_=function(a,b){return a.k in a.v?a.v[a.k]:a.d},Sao.PYSON.Get.init_from_object=function(a){return new Sao.PYSON.Get(a.v,a.k,a.d)},Sao.PYSON.eval.In=function(a,b){return new Sao.PYSON.In(a,b)},Sao.PYSON.In=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){if(Sao.PYSON.In._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["string","number"]).length)throw"key must be a string or a number"}else if(!~["string","number"].indexOf(typeof a))throw"key must be a string or a number";if(b instanceof Sao.PYSON.PYSON){if(jQuery(b.types()).not(["object"]).length||jQuery(["object"]).not(b.types()).length)throw"obj must be a dict or a list"}else if(!(b instanceof Object))throw"obj must be a dict or a list";this._key=a,this._obj=b},pyson:function(){return{__class__:"In",k:this._key,v:this._obj}},types:function(){return["boolean"]},__string_params__:function(){return[this._key,this._obj]}}),Sao.PYSON.In.eval_=function(a,b){return a.v.indexOf?Boolean(~a.v.indexOf(a.k)):!!a.v[a.k]},Sao.PYSON.In.init_from_object=function(a){return new Sao.PYSON.In(a.k,a.v)},Sao.PYSON.eval.Date=function(a,b,c,d,e,f){return new Sao.PYSON.Date(a,b,c,d,e,f)},Sao.PYSON.Date=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c,d,e,f){Sao.PYSON.Date._super.init.call(this),void 0===a&&(a=null),void 0===b&&(b=null),void 0===c&&(c=null),void 0===d&&(d=0),void 0===e&&(e=0),void 0===f&&(f=0),this._test(a,"year"),this._test(b,"month"),this._test(c,"day"),this._test(d,"delta_years"),this._test(f,"delta_days"),this._test(e,"delta_months"),this._year=a,this._month=b,this._day=c,this._delta_years=d,this._delta_months=e,this._delta_days=f},pyson:function(){return{__class__:"Date",y:this._year,M:this._month,d:this._day,dy:this._delta_years,dM:this._delta_months,dd:this._delta_days}},types:function(){return["object"]},_test:function(a,b){if(a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["number","object"]).length)throw b+" must be an integer or None"}else if("number"!=typeof a&&null!==a)throw b+" must be an integer or None"},__string_params__:function(){return[this._year,this._month,this._day,this._delta_years,this._delta_months,this._delta_days]}}),Sao.PYSON.Date.eval_=function(a,b){var c=Sao.Date(a.y,a.M&&a.M-1,a.d);return a.dy&&c.add(a.dy,"y"),a.dM&&c.add(a.dM,"M"),a.dd&&c.add(a.dd,"d"),c},Sao.PYSON.Date.init_from_object=function(a){return new Sao.PYSON.Date(a.y,a.M,a.d,a.dy,a.dM,a.dd)},Sao.PYSON.eval.DateTime=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){return new Sao.PYSON.DateTime(a,b,c,d,e,f,g,h,i,j,k,l,m,n)},Sao.PYSON.DateTime=Sao.class_(Sao.PYSON.Date,{init:function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){Sao.PYSON.DateTime._super.init.call(this,a,b,c,h,i,j),void 0===d&&(d=null),void 0===e&&(e=null),void 0===f&&(f=null),void 0===g&&(g=null),void 0===k&&(k=0),void 0===l&&(l=0),void 0===m&&(m=0),void 0===n&&(n=0),this._test(d,"hour"),this._test(e,"minute"),this._test(f,"second"),this._test(g,"microsecond"),this._test(k,"delta_hours"),this._test(l,"delta_minutes"),this._test(m,"delta_seconds"),this._test(n,"delta_microseconds"),this._hour=d,this._minute=e,this._second=f,this._microsecond=g,this._delta_hours=k,this._delta_minutes=l,this._delta_seconds=m,this._delta_microseconds=n},pyson:function(){var a=Sao.PYSON.DateTime._super.pyson.call(this);return a.__class__="DateTime",a.h=this._hour,a.m=this._minute,a.s=this._second,a.ms=this._microsecond,a.dh=this._delta_hours,a.dm=this._delta_minutes,a.ds=this._delta_seconds,a.dms=this._delta_microseconds,a},__string_params__:function(){var a=Sao.PYSON.DateTime._super.__string_params__.call(this);return[a[0],a[1],a[2],this._hour,this._minute,this._second,this._microsecond,a[3],a[4],a[5],this._delta_hours,this._delta_minutes,this._delta_seconds,this._delta_microseconds]}}),Sao.PYSON.DateTime.eval_=function(a,b){var c=Sao.DateTime(a.y,a.M&&a.M-1,a.d,a.h,a.m,a.s,a.ms&&a.ms/1e3);return a.dy&&c.add(a.dy,"y"),a.dM&&c.add(a.dM,"M"),a.dd&&c.add(a.dd,"d"),a.dh&&c.add(a.dh,"h"),a.dm&&c.add(a.dm,"m"),a.ds&&c.add(a.ds,"s"),a.dms&&c.add(a.dms/1e3,"ms"),c},Sao.PYSON.DateTime.init_from_object=function(a){return new Sao.PYSON.DateTime(a.y,a.M,a.d,a.h,a.m,a.s,a.ms,a.dy,a.dM,a.dd,a.dh,a.dm,a.ds,a.dms)},Sao.PYSON.eval.Len=function(a){return new Sao.PYSON.Len(a)},Sao.PYSON.Len=Sao.class_(Sao.PYSON.PYSON,{init:function(a){if(Sao.PYSON.Len._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["object","string"]).length||jQuery(["object","string"]).not(a.types()).length)throw"value must be an object or a string"}else if("object"!=typeof a&&"string"!=typeof a)throw"value must be an object or a string";this._value=a},pyson:function(){return{__class__:"Len",v:this._value}},types:function(){return["integer"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Len.eval_=function(a,b){return"object"==typeof a.v?Object.keys(a.v).length:a.v.length},Sao.PYSON.Len.init_from_object=function(a){return new Sao.PYSON.Len(a.v)}}(),function(){"use strict";Sao.Session=Sao.class_(Object,{init:function(a,b){this.user_id=null,this.session=null,this.prm=jQuery.when(),this.database=a,this.login=b,this.context={},Sao.Session.current_session||(Sao.Session.current_session=this)},get_auth:function(){return btoa(this.login+":"+this.user_id+":"+this.session)},do_login:function(a,b){var c=jQuery.Deferred(),d=function(b){return{method:"common.db.login",params:[a,b,Sao.i18n.getlang()]}};return new Sao.Login(d,this).run().then(function(a){this.user_id=a[0],this.session=a[1],c.resolve()}.bind(this),function(){this.user_id=null,this.session=null,c.reject()}),c.promise()},do_logout:function(){if(!this.user_id||!this.session)return jQuery.when();var a={id:0,method:"common.db.logout",params:[]},b=jQuery.ajax({headers:{Authorization:"Session "+this.get_auth()},contentType:"application/json",data:JSON.stringify(a),dataType:"json",url:"/"+this.database+"/",type:"post"});return this.database=null,this.login=null,this.user_id=null,this.session=null,Sao.Session.current_session===this&&(Sao.Session.current_session=null),b},reload_context:function(){var a={method:"model.res.user.get_preferences",params:[!0,{}]},b=jQuery.extend({},this);b.context={};var c=Sao.rpc(a,b);return c.then(function(a){this.context=a}.bind(this))}}),Sao.Session.login_dialog=function(){var a=new Sao.Dialog(Sao.i18n.gettext("Login"),"lg");return a.database_select=jQuery("<select/>",{class:"form-control",id:"login-database"}).hide(),a.database_input=jQuery("<input/>",{class:"form-control",id:"login-database"}).hide(),a.login_input=jQuery("<input/>",{class:"form-control",id:"login-login",placeholder:Sao.i18n.gettext("Login")}),a.body.append(jQuery("<div/>",{class:"form-group"}).append(jQuery("<label/>",{class:"control-label",for:"login-database"}).append(Sao.i18n.gettext("Database"))).append(a.database_select).append(a.database_input)).append(jQuery("<div/>",{class:"form-group"}).append(jQuery("<label/>",{class:"control-label",for:"login-login"}).append(Sao.i18n.gettext("Login"))).append(a.login_input)),a.button=jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Login")).appendTo(a.footer),a},Sao.Session.get_credentials=function(){var a=jQuery.Deferred(),b=window.location.hash.replace(/^(#(!|))/,"")||null,c=Sao.Session.login_dialog(),d=function(){return c.modal.find("input,select").filter(":visible").filter(function(){return!jQuery(this).val()})},e=function(){var b=c.login_input.val(),e=e||c.database_select.val()||c.database_input.val();if(c.modal.find(".has-error").removeClass("has-error"),!b||!e)return void d().closest(".form-group").addClass("has-error");c.button.focus(),c.button.prop("disabled",!0),c.modal.modal("hide");var f=new Sao.Session(e,b);f.do_login(b).then(function(){a.resolve(f),c.modal.remove()},function(){c.button.prop("disabled",!1),c.modal.modal("show"),d().closest(".form-group").addClass("has-error"),d().first().focus()})};return c.modal.modal({backdrop:!1,keyboard:!1}),c.modal.find("form").unbind().submit(function(a){e(),a.preventDefault()}),jQuery.when(Sao.DB.list()).then(function(a){var e;a=a||[],a.length<=1?(b=a[0],e=c.database_input):(e=c.database_select,
-a.forEach(function(a){e.append(jQuery("<option/>",{value:a,text:a}))})),e.prop("readonly",1==a.length),e.show(),e.val(b||""),d().first().focus()}),a.promise()},Sao.Session.renew=function(a){if("pending"==a.prm.state())return a.prm;var b=jQuery.Deferred();return a.prm=b.promise(),a.login?(a.do_login(a.login).then(b.resolve,b.reject),a.prm):(b.reject(),a.prm)},Sao.Session.current_session=null,Sao.Login=Sao.class_(Object,{init:function(a,b){this.func=a,this.session=b||Sao.Session.current_session},run:function(a){void 0===a&&(a={});var b=jQuery.Deferred(),c=Sao.common.processing.show(),d=this.func(a);d.id=0;var e={contentType:"application/json",data:JSON.stringify(d),dataType:"json",url:"/"+this.session.database+"/",type:"post",complete:[function(){Sao.common.processing.hide(c)}]};this.session.user_id&&this.session.session&&(e.headers={Authorization:"Session "+this.session.get_auth()});var f=jQuery.ajax(e),g=function(c){if(null===c)Sao.common.warning.run("",Sao.i18n.gettext("Unable to reach the server.")),b.reject();else if(c.error){if(c.error[0].startsWith("403"))return this.run({}).then(b.resolve,b.reject);if(c.error[0].startsWith("404"))b.reject();else if("LoginException"!=c.error[0])Sao.common.error.run(c.error[0],c.error[1]),b.reject();else{var d=c.error[1],e=d[0],f=d[1],g=d[2];this["get_"+g](f).then(function(c){return a[e]=c,this.run(a).then(b.resolve,b.reject)}.bind(this),b.reject)}}else b.resolve(c.result)};return f.success(g.bind(this)),f.error(b.reject),b.promise()},get_char:function(a){return Sao.common.ask.run(a)},get_password:function(a){return Sao.common.ask.run(a,!1)}}),Sao.DB={},Sao.DB.list=function(){var a=Sao.common.processing.show();return jQuery.ajax({contentType:"application/json",data:JSON.stringify({id:0,method:"common.db.list",params:[]}),dataType:"json",url:"/",type:"post",complete:[function(){Sao.common.processing.hide(a)}]}).then(function(a){return a.result})}}(),function(){"use strict";Sao.Model=Sao.class_(Object,{init:function(a,b){b=b||{},this.name=a,this.session=Sao.Session.current_session,this.fields={}},add_fields:function(a){var b=[];for(var c in a)if(a.hasOwnProperty(c)&&!(c in this.fields)){var d=a[c],e=Sao.field.get(d.type);this.fields[c]=new e(d),b.push(c)}return b},execute:function(a,b,c){void 0===c&&(c={});var d={method:"model."+this.name+"."+a,params:b.concat(c)};return Sao.rpc(d,this.session)},find:function(a,b,c,d,e){b||(b=0);var f=this,g=this.execute("search",[a,b,c,d],e),h=function(a){return Sao.Group(f,e,a.map(function(a){return new Sao.Record(f,a)}))};return g.pipe(h)},delete_:function(a){if(jQuery.isEmptyObject(a))return jQuery.when();var b=a[0],c=b.group.root_group();console.assert(a.every(function(a){return a.model.name==b.model.name}),"records not from the same model"),console.assert(a.every(function(a){return a.group.root_group()==b.group.root_group()}),"records not from the same root group"),a=a.filter(function(a){return a.id>=0});var d={};d._timestamp={},a.forEach(function(a){jQuery.extend(d._timestamp,a.get_timestamp())});var e=a.map(function(a){return a.id});return c.on_write_ids(e).then(function(a){return a=a.filter(function(a){return!~e.indexOf(a)}),this.execute("delete",[e],d).then(function(){c.reload(a)})}.bind(this))},copy:function(a,b){if(jQuery.isEmptyObject(a))return jQuery.when();var c=a.map(function(a){return a.id});return this.execute("copy",[c,{}],b)}}),Sao.Group=function(a,b,c){return c.prm=jQuery.when(),c.model=a,c._context=b,c.on_write=[],c.parent=void 0,c.screens=[],c.parent_name="",c.children=[],c.child_name="",c.parent_datetime_field=void 0,c.record_removed=[],c.record_deleted=[],c.__readonly=!1,c.skip_model_access=!1,c.forEach(function(a,b,c){a.group=c}),c.get_readonly=function(){var a=Sao.common.MODELACCESS.get(this.model.name);return!(!this.context._datetime&&(a.write||a.create||this.skip_model_access))||this.__readonly},c.set_readonly=function(a){this.__readonly=a},c.load=function(a,b){var c,d,e=[];for(c=0,d=a.length;c<d;c++){var f=a[c],g=this.get(f);g||(g=new Sao.Record(this.model,f),g.group=this,this.push(g)),e.push(g)}var h,i=[];for(c=0,d=this.record_removed.length;c<d;c++)h=this.record_removed[c],~a.indexOf(h.id)||i.push(h);this.record_removed=i;var j=[];for(c=0,d=this.record_deleted.length;c<d;c++)h=this.record_deleted[c],~a.indexOf(h.id)||j.push(h);this.record_deleted=j,e.length&&b&&this.changed()},c.get=function(a){for(var b=0,c=this.length;b<c;b++){var d=this[b];if(d.id==a)return d}},c.new_=function(a,b,c){var d=new Sao.Record(this.model,b);return d.group=this,a&&d.default_get(c),d},c.add=function(a,b,c){void 0!==b&&b!=-1||(b=this.length),void 0===c&&(c=!0),a.group!=this&&(a.group=this),this.splice(b,0,a);for(var d in this.record_removed)d.id==a.id&&this.record_removed.splice(this.record_removed.indexOf(d),1);for(var e in this.record_deleted)e.id==a.id&&this.record_deleted.splice(this.record_deleted.indexOf(e),1);if(a._changed.id=!0,c&&(this.changed(),this.parent&&this.model.fields[this.parent_name])){var f=this.model.fields[this.parent_name];if(f instanceof Sao.field.Many2One||f instanceof Sao.field.Reference){var g=[this.parent.id,""];f instanceof Sao.field.Reference&&(g=[this.parent.model.name,g]),f.set_client(a,g)}}return a},c.remove=function(a,b,c,d){void 0===c&&(c=!0);this.indexOf(a);a.id>=0&&(b?(~this.record_deleted.indexOf(a)&&this.record_deleted.splice(this.record_deleted.indexOf(a),1),this.record_removed.push(a)):(~this.record_removed.indexOf(a)&&this.record_removed.splice(this.record_removed.indexOf(a),1),this.record_deleted.push(a))),a.group.parent&&(a.group.parent._changed.id=!0),c&&(a._changed.id=!0),(!a.group.parent||a.id<0||d)&&this._remove(a),a.group.changed(),a.group.root_group().screens.forEach(function(a){a.display()})},c._remove=function(a){var b=this.indexOf(a);this.splice(b,1)},c.unremove=function(a){this.record_removed.splice(this.record_removed.indexOf(a),1),this.record_deleted.splice(this.record_deleted.indexOf(a),1),a.group.changed(),a.group.root_group().screens.forEach(function(a){a.display()})},c.changed=function(){if(!this.parent)return jQuery.when();this.parent._changed[this.child_name]=!0;var a=jQuery.Deferred(),b=this.parent.model.fields[this.child_name].changed(this.parent);return b?b.then(function(){this.parent.validate(null,!0).done(function(){this.parent.group.changed().done(a.resolve)}.bind(this))}.bind(this)):a.resolve(),a},c.root_group=function(){for(var a=this,b=this.parent;b;)a=b.group,b=b.parent;return a},c.save=function(){var a=[];return this.forEach(function(b){a.push(b.save())}),jQuery.isEmptyObject(this.record_deleted)||a.push(this.model.delete_(this.record_deleted)),jQuery.when.apply(jQuery,a)},c.written=function(a){return"number"==typeof a&&(a=[a]),this.on_write_ids(a).then(function(b){b=b.filter(function(b){return!~a.indexOf(b)}),this.root_group().reload(b)}.bind(this))},c.reload=function(a){this.children.forEach(function(b){b.reload(a)}),a.forEach(function(a){var b=this.get(a);b&&jQuery.isEmptyObject(b._changed)&&b.cancel()}.bind(this))},c.on_write_ids=function(a){var b=[],c=[];return this.on_write.forEach(function(d){var e=this.model.execute(d,[a],this._context).then(function(a){jQuery.extend(c,a)});b.push(e)}.bind(this)),jQuery.when.apply(jQuery,b).then(function(){return c.filter(function(a,b,c){return b==c.indexOf(a)})})},c.set_parent=function(a){this.parent=a,a&&a.model.name==this.model.name&&this.parent.group.children.push(this)},c.add_fields=function(a){var b=this.model.add_fields(a);if(!jQuery.isEmptyObject(this)){var c=[];this.forEach(function(a){a.id<0&&c.push(a)}),c.length&&b.length&&this.model.execute("default_get",[b,this.context()]).then(function(a){c.forEach(function(b){b.set_default(a)})})}},c.destroy=function(){if(this.parent){var a=this.parent.group.children.indexOf(this);~a&&this.parent.group.children.splice(a,1)}this.parent=null},c.domain=function(){var a=[];if(this.screens.forEach(function(b){b.attributes.domain&&a.push(b.attributes.domain)}),this.parent&&this.child_name){var b=this.parent.model.fields[this.child_name];return[a,b.get_domain(this.parent)]}return a},c.context=function(){var a=jQuery.extend({},this._context);if(this.parent&&(jQuery.extend(a,this.parent.get_context()),this.child_name in this.parent.model.fields)){var b=this.parent.model.fields[this.child_name];jQuery.extend(a,b.get_context(this.parent))}return jQuery.extend(a,this._context),this.parent_datetime_field&&(a._datetime=this.parent.get_eval()[this.parent_datetime_field]),a},c.set_context=function(a){this._context=jQuery.extend({},a)},c.clean4inversion=function(a){if(jQuery.isEmptyObject(a))return[];var b=new Sao.common.DomainInversion,c=a[0],d=a.slice(1);if(~["AND","OR"].indexOf(c));else if(b.is_leaf(c)){var e=c[0];e in this.model.fields&&this.model.fields[e].description.readonly&&(c=[])}else c=this.clean4inversion(c);return[c].concat(this.clean4inversion(d))},c.domain4inversion=function(){var a=this.domain();return this.__domain4inversion&&Sao.common.compare(this.__domain4inversion[0],a)||(this.__domain4inversion=[a,this.clean4inversion(a)]),this.__domain4inversion[1]},c.get_by_path=function(a){a=jQuery.extend([],a);var b=null,c=this,d=function(){if(jQuery.isEmptyObject(a))return b;var e=a[0][0],f=a[0][1];return a.splice(0,1),b=c.get(f),b?e?b.load(e).then(function(){return c=b._values[e],c?d():null}):d():null};return jQuery.when().then(d)},c.sort=function(a){var b={};this.forEach(function(a){b[a.id]=a}),a.forEach(function(a,c){this[c]=b[a.id]}.bind(this))},c},Sao.Record=Sao.class_(Object,{id_counter:-1,init:function(a,b){this.model=a,this.group=Sao.Group(a,{},[]),this.id=b||Sao.Record.prototype.id_counter--,this._values={},this._changed={},this._loaded={},this.fields={},this._timestamp=null,this.attachment_count=-1,this.unread_note=-1,this.button_clicks={},this.state_attrs={},this.autocompletion={},this.exception=!1},has_changed:function(){return!jQuery.isEmptyObject(this._changed)},save:function(a){void 0===a&&(a=!1);var b=this.get_context(),c=jQuery.when(),d=this.get();if(this.id<0||!jQuery.isEmptyObject(d)){if(this.id<0){c=this.model.execute("create",[[d]],b);var e=function(a){this.id=a[0]};c.done(e.bind(this))}else jQuery.isEmptyObject(d)||(b._timestamp=this.get_timestamp(),c=this.model.execute("write",[[this.id],d],b));c=c.done(function(){if(this.cancel(),a)return this.reload()}.bind(this)),this.group&&(c=c.done(function(){return this.group.written(this.id)}.bind(this)))}return this.group.parent&&(delete this.group.parent._changed[this.group.child_name],c=c.done(function(){return this.group.parent.save(a)}.bind(this))),c},reload:function(a){if(this.id<0)return jQuery.when();if(a){var b=a.map(function(a){return this.load(a)}.bind(this));return jQuery.when.apply(jQuery,b)}return this.load("*")},load:function(a){var b,c;if(this.id<0||a in this._loaded)return jQuery.when();if("pending"==this.group.prm.state())return c=jQuery.Deferred(),this.group.prm.then(function(){this.load(a).then(c.resolve,c.reject)}.bind(this)),c;var d={};d[this.id]=this;var e;if("*"==a){e="eager";for(b in this.model.fields)if(this.model.fields.hasOwnProperty(b)){var f=this.model.fields[b].description.loading||"eager";if("eager"!=f){e="lazy";break}}}else e=this.model.fields[a].description.loading||"eager";var g=[];if("eager"==e)for(b in this.model.fields)this.model.fields.hasOwnProperty(b)&&"eager"==(this.model.fields[b].description.loading||"eager")&&g.push(b);else g=Object.keys(this.model.fields);g=g.filter(function(a,b,c){return!(a in this._loaded)}.bind(this));var h=g.slice(),i=["many2one","one2one","reference"];for(var j in g){b=g[j];var k=this.model.fields[b].description;~i.indexOf(k.type)&&h.push(b+".rec_name")}~g.indexOf("rec_name")||h.push("rec_name"),h.push("_timestamp");var l=jQuery.extend({},this.get_context());if("eager"==e){var m,n,o=parseInt(Sao.config.limit/h.length,10),p=function(b){return!(a in b._loaded)&&b.id>=0},q=function(a){return p(a)&&void 0===d[a.id]&&(a.group===this.group||JSON.stringify(a.get_context())===JSON.stringify(l))}.bind(this);this.group.parent&&this.group.parent.model.name==this.model.name?(m=[],m=m.concat.apply(m,this.group.parent.group.children),n=q):(m=this.group,n=p);var r=m.indexOf(this);if(~r)for(var s=m.length,t=1;Object.keys(d).length<o&&(r-t>=0||r+t<s)&&t<2*o;){var u;r-t>=0&&(u=m[r-t],n(u)&&(d[u.id]=u)),r+t<s&&(u=m[r+t],n(u)&&(d[u.id]=u)),t++}}for(b in this.model.fields)this.model.fields.hasOwnProperty(b)&&"binary"==this.model.fields[b].description.type&&~h.indexOf(b,h)&&(l[this.model.name+"."+b]="size");c=this.model.execute("read",[Object.keys(d).map(function(a){return parseInt(a,10)}),h],l);var v=function(a,b){void 0===b&&(b=!1);var c={},e=[];a.forEach(function(a,b,d){c[a.id]=a});for(var f in d)if(d.hasOwnProperty(f)){var g=d[f];g.exception||(g.exception=b);var h=c[f];if(g&&h){for(var i in this._changed)this._changed.hasOwnProperty(i)&&delete h[i];e.push(g.set(h))}}return jQuery.when.apply(jQuery,e)}.bind(this),w=function(){var a,b=[];for(var c in d){a={id:c};for(var e in h)a[h[e]]=null;b.push(a)}return v(b,!0)};return this.group.prm=c.then(v,w),this.group.prm},set:function(a,b){void 0===b&&(b=!0);var c,d,e={},f=[],g=[];for(c in a)if(a.hasOwnProperty(c))if(d=a[c],"_timestamp"!=c)if(c in this.model.fields){if(this.model.fields[c]instanceof Sao.field.One2Many&&(e[c]=d),this.model.fields[c]instanceof Sao.field.Many2One||this.model.fields[c]instanceof Sao.field.Reference){var h=c+".rec_name";a.hasOwnProperty(h)?this._values[h]=a[h]:this._values.hasOwnProperty(h)&&delete this._values[h]}this.model.fields[c].set(this,d),this._loaded[c]=!0,g.push(c)}else"rec_name"==c&&(this._values[c]=d);else this._timestamp||(this._timestamp=d);for(c in e)d=e[c],this.model.fields[c].set(this,d),this._loaded[c]=!0;for(var i in this.model.fields){var j=this.model.fields[i];j.description.autocomplete&&j.description.autocomplete.length>0&&f.push(this.do_autocomplete(i))}return b&&f.push(this.validate(g,!0)),jQuery.when.apply(jQuery,f)},get:function(){var a={};for(var b in this.model.fields)if(this.model.fields.hasOwnProperty(b)){var c=this.model.fields[b];c.description.readonly||void 0===this._changed[b]&&this.id>=0||(a[b]=c.get(this))}return a},invalid_fields:function(){var a={};for(var b in this.model.fields){var c=this.model.fields[b],d=c.get_state_attrs(this).invalid;d&&(a[b]=d)}return a},get_context:function(){return this.group.context()},field_get:function(a){return this.model.fields[a].get(this)},field_set:function(a,b){this.model.fields[a].set(this,b)},field_get_client:function(a){return this.model.fields[a].get_client(this)},field_set_client:function(a,b,c){this.model.fields[a].set_client(this,b,c)},default_get:function(a){var b=jQuery.Deferred(),c=[];for(var d in this.model.fields){var e=this.model.fields[d];e.description.autocomplete&&e.description.autocomplete.length>0&&c.push(this.do_autocomplete(d))}if(jQuery.isEmptyObject(this.model.fields))b.resolve();else{var f=this.get_context();void 0===f.default_rec_name&&(f.default_rec_name=a);var g=this.model.execute("default_get",[Object.keys(this.model.fields)],f);g.then(function(a){if(this.group.parent&&this.group.parent_name in this.group.model.fields){var d=this.group.model.fields[this.group.parent_name];d instanceof Sao.field.Reference?a[this.group.parent_name]=[this.group.parent.model.name,this.group.parent.id]:d.description.relation==this.group.parent.model.name&&(a[this.group.parent_name]=this.group.parent.id)}c.push(this.set_default(a)),jQuery.when.apply(jQuery,c).then(function(){b.resolve(a)})}.bind(this))}return b},set_default:function(a,b){void 0===b&&(b=!0);var c=[],d=[];for(var e in a)if(a.hasOwnProperty(e)){var f=a[e];if(e in this.model.fields){if(this.model.fields[e]instanceof Sao.field.Many2One||this.model.fields[e]instanceof Sao.field.Reference){var g=e+".rec_name";a.hasOwnProperty(g)?this._values[g]=a[g]:this._values.hasOwnProperty(g)&&delete this._values[g]}c.push(this.model.fields[e].set_default(this,f)),this._loaded[e]=!0,d.push(e)}}return jQuery.when.apply(jQuery,c).then(function(){return this.on_change(d).then(function(){return this.on_change_with(d).then(function(){var a=function(){return this.group.root_group().screens.forEach(function(a){return a.display()})}.bind(this);return b?this.validate(null,!0).then(a):a()}.bind(this))}.bind(this))}.bind(this))},get_timestamp:function(){var a={};a[this.model.name+","+this.id]=this._timestamp;for(var b in this.model.fields)this.model.fields.hasOwnProperty(b)&&b in this._loaded&&jQuery.extend(a,this.model.fields[b].get_timestamp(this));return a},get_eval:function(){var a={};for(var b in this.model.fields)!this.model.fields.hasOwnProperty(b)&&this.id>=0||(a[b]=this.model.fields[b].get_eval(this));return a},get_on_change_value:function(a){var b={};for(var c in this.model.fields)a&&~a.indexOf(c)||(!(this.id>=0)||this._loaded[c]&&this._changed[c])&&(b[c]=this.model.fields[c].get_on_change_value(this));return b.id=this.id,b},_get_on_change_args:function(a){var b={},c=Sao.common.EvalEnvironment(this,"on_change");return a.forEach(function(a){var d=c;a.split(".").forEach(function(a){void 0!==d&&(d=d[a])}),b[a]=d}),b.id=this.id,b},on_change:function(a){var b={};if(a.forEach(function(a){var c=this.model.fields[a].description.on_change;jQuery.isEmptyObject(c)||(b=jQuery.extend(b,this._get_on_change_args(c)))}.bind(this)),jQuery.isEmptyObject(b))return jQuery.when();var c=this.model.execute("on_change",[b,a],this.get_context());return c.then(function(a){a.forEach(this.set_on_change.bind(this))}.bind(this))},on_change_with:function(a){var b,c,d={},e={},f={};for(b in this.model.fields)if(this.model.fields.hasOwnProperty(b)&&(c=this.model.fields[b].description.on_change_with,!jQuery.isEmptyObject(c))){for(var g=0;g<a.length&&!~c.indexOf(a[g]);g++);g>=a.length||(jQuery.isEmptyObject(Sao.common.intersect(Object.keys(d).sort(),c.sort()))?(d[b]=!0,e=jQuery.extend(e,this._get_on_change_args(c)),(this.model.fields[b]instanceof Sao.field.Many2One||this.model.fields[b]instanceof Sao.field.Reference)&&delete this._values[b+".rec_name"]):f[b]=!0)}var h,i=[];jQuery.isEmptyObject(d)||(h=this.model.execute("on_change_with",[e,Object.keys(d)],this.get_context()),i.push(h.then(this.set_on_change.bind(this))));var j=function(a){return function(b){this.model.fields[a].set_on_change(this,b)}};for(b in f)f.hasOwnProperty(b)&&(c=this.model.fields[b].description.on_change_with,e=this._get_on_change_args(c),h=this.model.execute("on_change_with_"+b,[e],this.get_context()),i.push(h.then(j(b).bind(this))));return jQuery.when.apply(jQuery,i)},set_on_change:function(a){var b,c;for(b in a)if(a.hasOwnProperty(b)&&(c=a[b],b in this.model.fields)){if(this.model.fields[b]instanceof Sao.field.Many2One||this.model.fields[b]instanceof Sao.field.Reference){var d=b+".rec_name";a.hasOwnProperty(d)?this._values[d]=a[d]:this._values.hasOwnProperty(d)&&delete this._values[d]}this.model.fields[b].set_on_change(this,c)}},autocomplete_with:function(a){var b=[];for(var c in this.model.fields){var d=this.model.fields[c],e=d.description.autocomplete||[];~e.indexOf(a)&&b.push(this.do_autocomplete(c))}return jQuery.when.apply(jQuery,b)},do_autocomplete:function(a){this.autocompletion[a]=[];var b=this.model.fields[a],c=b.description.autocomplete,d=this._get_on_change_args(c),e=this.model.execute("autocomplete_"+a,[d],this.get_context());return e.then(function(b){this.autocompletion[a]=b}.bind(this))},expr_eval:function(a){if("string"!=typeof a)return a;var b=jQuery.extend({},this.model.session.context);if(b.context=jQuery.extend({},b),jQuery.extend(b.context,this.get_context()),jQuery.extend(b,this.get_eval()),b.active_model=this.model.name,b.active_id=this.id,b._user=this.model.session.user_id,this.group.parent&&this.group.parent_name){var c=Sao.common.EvalEnvironment(this.group.parent);b["_parent_"+this.group.parent_name]=c}return new Sao.PYSON.Decoder(b).decode(a)},rec_name:function(){var a=this.model.execute("read",[[this.id],["rec_name"]],this.get_context());return a.then(function(a){return a[0].rec_name})},validate:function(a,b,c,d){var e=function(){var e=!0,f=[];this.group.screens.forEach(function(a){a.exclude_field&&f.push(a.exclude_field)});for(var g in this.model.fields)if((!(d&&this.id>=0)||g in this._loaded)&&this.model.fields.hasOwnProperty(g)){var h=this.model.fields[g];a&&!~a.indexOf(g)||h.get_state_attrs(this).readonly||~f.indexOf(g)||h.validate(this,b,c)||(e=!1)}return e}.bind(this);return d?e():this._check_load(a).then(e)},pre_validate:function(){if(jQuery.isEmptyObject(this._changed))return jQuery.Deferred().resolve(!0);var a=this._get_on_change_args(Object.keys(this._changed));return this.model.execute("pre_validate",[a],this.get_context()).then(function(){return!0},function(){return!1})},cancel:function(){this._loaded={},this._changed={},this._timestamp=null,this.button_clicks={}},_check_load:function(a){return this.get_loaded(a)?jQuery.when():this.reload(a)},get_loaded:function(a){if(!jQuery.isEmptyObject(a)){var b=!0;return a.forEach(function(a){a in this._loaded||a in this._changed||(b=!1)}.bind(this)),b}return Sao.common.compare(Object.keys(this.model.fields).sort(),Object.keys(this._loaded).sort())},root_parent:function(){for(var a=this;a.group.parent;)a=a.group.parent;return a},get_path:function(a){for(var b=[],c=this,d="";c&&(b.push([d,c.id]),c.group!==a);)d=c.group.child_name,c=c.group.parent;return b.reverse(),b},deleted:function(){return Boolean(~this.group.record_deleted.indexOf(this))},removed:function(){return Boolean(~this.group.record_removed.indexOf(this))},readonly:function(){return this.deleted()||this.removed()||this.exception},set_field_context:function(){for(var a in this.model.fields)if(this.model.fields.hasOwnProperty(a)){var b=this.model.fields[a],c=this._values[a];if(c&&c.set_context){var d=b.description.context;d&&c.set_context(this.expr_eval(d))}}},get_attachment_count:function(a){var b=jQuery.Deferred();return this.id<0?(b.resolve(0),b):(this.attachment_count<0||a?b=Sao.rpc({method:"model.ir.attachment.search_count",params:[[["resource","=",this.model.name+","+this.id]],this.get_context()]},this.model.session).then(function(a){return this.attachment_count=a,a}.bind(this)):b.resolve(this.attachment_count),b)},get_unread_note:function(a){var b=jQuery.Deferred();return this.id<0?(b.resolve(0),b):(this.unread_note<0||a?b=Sao.rpc({method:"model.ir.note.search_count",params:[[["resource","=",this.model.name+","+this.id],["unread","=",!0]],this.get_context()]},this.model.session).then(function(a){return this.unread_note=a,a}.bind(this)):b.resolve(this.unread_note),b)},get_button_clicks:function(a){if(this.id<0)return jQuery.when();var b=this.button_clicks[a];return void 0!==b?jQuery.when(b):Sao.rpc({method:"model.ir.model.button.click.get_click",params:[this.model.name,a,this.id,{}]},this.model.session).then(function(b){return this.button_clicks[a]=b,b}.bind(this))}}),Sao.field={},Sao.field.get=function(a){switch(a){case"char":return Sao.field.Char;case"selection":return Sao.field.Selection;case"datetime":return Sao.field.DateTime;case"date":return Sao.field.Date;case"time":return Sao.field.Time;case"timedelta":return Sao.field.TimeDelta;case"float":return Sao.field.Float;case"numeric":return Sao.field.Numeric;case"integer":return Sao.field.Integer;case"boolean":return Sao.field.Boolean;case"many2one":return Sao.field.Many2One;case"one2one":return Sao.field.One2One;case"one2many":return Sao.field.One2Many;case"many2many":return Sao.field.Many2Many;case"reference":return Sao.field.Reference;case"binary":return Sao.field.Binary;case"dict":return Sao.field.Dict;default:return Sao.field.Char}},Sao.field.Field=Sao.class_(Object,{_default:null,init:function(a){this.description=a,this.name=a.name},set:function(a,b){a._values[this.name]=b},get:function(a){var b=a._values[this.name];return void 0===b&&(b=this._default),b},set_client:function(a,b,c){var d=this.get(a);this.set(a,b),JSON.stringify(d)!=JSON.stringify(this.get(a))?(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.changed().done(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})})})):c&&(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})}))},get_client:function(a){return this.get(a)},set_default:function(a,b){a._values[this.name]=b,a._changed[this.name]=!0},set_on_change:function(a,b){a._values[this.name]=b,a._changed[this.name]=!0},changed:function(a){var b=[];return b.push(a.on_change([this.name])),b.push(a.on_change_with([this.name])),b.push(a.autocomplete_with(this.name)),a.set_field_context(),jQuery.when.apply(jQuery,b)},get_timestamp:function(a){return{}},get_context:function(a){var b=jQuery.extend({},a.get_context());return a.group.parent&&jQuery.extend(b,a.group.parent.get_context()),jQuery.extend(b,a.expr_eval(this.description.context||{})),b},get_domains:function(a,b){var c=new Sao.common.DomainInversion,d=c.domain_inversion([a.group.domain4inversion(),b||[]],this.name,Sao.common.EvalEnvironment(a));"boolean"!=typeof d||d?"boolean"==typeof d&&d&&(d=[]):d=[["id","=",null]];var e=a.expr_eval(this.description.domain||[]);return[d,e]},get_domain:function(a){var b=this.get_domains(a),c=b[0],d=b[1],e=new Sao.common.DomainInversion;return e.concat([e.localize_domain(c),d])},validation_domains:function(a,b){var c=new Sao.common.DomainInversion;return c.concat(this.get_domains(a,b))},get_eval:function(a){return this.get(a)},get_on_change_value:function(a){return this.get_eval(a)},set_state:function(a,b){void 0===b&&(b=["readonly","required","invisible"]);var c=a.expr_eval(this.description.states||{});b.forEach(function(b){"readonly"==b&&this.description.readonly||(void 0!==c[b]?this.get_state_attrs(a)[b]=c[b]:void 0!==this.description[b]&&(this.get_state_attrs(a)[b]=this.description[b]))}.bind(this)),(a.group.get_readonly()||this.get_state_attrs(a).domain_readonly)&&(this.get_state_attrs(a).readonly=!0)},get_state_attrs:function(a){return this.name in a.state_attrs||(a.state_attrs[this.name]=jQuery.extend({},this.description)),(a.group.get_readonly()||a.readonly())&&(a.state_attrs[this.name].readonly=!0),a.state_attrs[this.name]},check_required:function(a){var b=this.get_state_attrs(a);return!(1==b.required&&!this.get(a)&&1!=b.readonly)},validate:function(a,b,c){if(this.description.readonly)return!0;var d=!1;this.get_state_attrs(a).domain_readonly=!1;var e=new Sao.common.DomainInversion,f=e.simplify(this.validation_domains(a,c));if(b||this.check_required(a)||(d="required"),"boolean"==typeof f)f||(d="domain");else if(Sao.common.compare(f,[["id","=",null]]))d="domain";else{var g=e.unique_value(f),h=g[0],i=g[1],j=g[2];if(h){j===!1&&(j=null);var k,l=!0;k=jQuery.isEmptyObject(a.group.domain())?e.merge(f):e.merge(a.group.domain());var m="AND"==k[0];if(i.contains(".")){var n=i.split(".",1)[0],o=i.split(".",1)[1],p=[];m&&e.localize_domain(k.slice(1)).forEach(function(a){p.push(a)}),"id"==o&&~p.indexOf(n)||(l=!1)}l&&!c&&(this.set_client(a,j),this.get_state_attrs(a).domain_readonly=m)}e.eval_domain(f,Sao.common.EvalEnvironment(a))||(d=f)}return this.get_state_attrs(a).invalid=d,!d}}),Sao.field.Char=Sao.class_(Sao.field.Field,{_default:"",get:function(a){return Sao.field.Char._super.get.call(this,a)||this._default}}),Sao.field.Selection=Sao.class_(Sao.field.Field,{_default:null}),Sao.field.DateTime=Sao.class_(Sao.field.Field,{_default:null,time_format:function(a){return a.expr_eval(this.description.format)},set_client:function(a,b,c){var d;b&&(b.isTime?(d=this.get(a),b=d?Sao.DateTime.combine(d,b):null):b.isDate&&(d=this.get(a),d&&(b=Sao.DateTime.combine(b,d)))),Sao.field.DateTime._super.set_client.call(this,a,b,c)},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)}}),Sao.field.Date=Sao.class_(Sao.field.Field,{_default:null,set_client:function(a,b,c){b&&!b.isDate&&(b.isDate=!0,b.isDateTime=!1),Sao.field.Date._super.set_client.call(this,a,b,c)},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)}}),Sao.field.Time=Sao.class_(Sao.field.Field,{_default:null,time_format:function(a){return a.expr_eval(this.description.format)},set_client:function(a,b,c){b&&(b.isDate||b.isDateTime)&&(b=Sao.Time(b.hour(),b.minute(),b.second(),b.millisecond())),Sao.field.Time._super.set_client.call(this,a,b,c)}}),Sao.field.TimeDelta=Sao.class_(Sao.field.Field,{_default:null,converter:function(a){return a.model.session.context[this.description.converter]},set_client:function(a,b,c){"string"==typeof b&&(b=Sao.common.timedelta.parse(b,this.converter(a))),Sao.field.TimeDelta._super.set_client.call(this,a,b,c)},get_client:function(a){var b=Sao.field.TimeDelta._super.get_client.call(this,a);return Sao.common.timedelta.format(b,this.converter(a))}}),Sao.field.Float=Sao.class_(Sao.field.Field,{_default:null,digits:function(a,b){void 0===b&&(b=1);var c=a.expr_eval(this.description.digits);if(c&&c.every(function(a){return null!==a})){var d=Math.round(Math.log(Math.abs(b))/Math.LN10);return[c[0]+d,c[1]-d]}},check_required:function(a){var b=this.get_state_attrs(a);return 1!=b.required||null!==this.get(a)||1==b.readonly},convert:function(a){return a?(a=Number(a),isNaN(a)&&(a=this._default),a):null},apply_factor:function(a,b){return null!==a&&(a/=b),a},set_client:function(a,b,c,d){void 0===d&&(d=1),b=this.apply_factor(this.convert(b),d),Sao.field.Float._super.set_client.call(this,a,b,c)},get_client:function(a,b){void 0===b&&(b=1);var c=this.get(a);if(null!==c){var d=this.digits(a,b);return d?(c*b).toFixed(d[1]):""+c*b}return""}}),Sao.field.Numeric=Sao.class_(Sao.field.Float,{convert:function(a){return a?(a=new Sao.Decimal(a),isNaN(a.valueOf())&&(a=this._default),a):null},apply_factor:function(a,b){return a=Sao.field.Numeric._super.apply_factor(a,b),null!==a&&(a=new Sao.Decimal(a)),a}}),Sao.field.Integer=Sao.class_(Sao.field.Float,{convert:function(a){return a=parseInt(a,10),isNaN(a)&&(a=this._default),a}}),Sao.field.Boolean=Sao.class_(Sao.field.Field,{_default:!1,set_client:function(a,b,c){b=Boolean(b),Sao.field.Boolean._super.set_client.call(this,a,b,c)},get:function(a){return Boolean(a._values[this.name])},get_client:function(a){return Boolean(a._values[this.name])}}),Sao.field.Many2One=Sao.class_(Sao.field.Field,{_default:null,check_required:function(a){var b=this.get_state_attrs(a);return 1!=b.required||null!==this.get(a)||1==b.readonly},get_client:function(a){var b=a._values[this.name+".rec_name"];return void 0===b&&(this.set(a,this.get(a)),b=a._values[this.name+".rec_name"]||""),b},set:function(a,b){var c=a._values[this.name+".rec_name"]||"",d=function(b){a._values[this.name+".rec_name"]=b[0].rec_name};if(!c&&b>=0&&null!==b){var e=a.model.fields[this.name].description.relation;Sao.rpc({method:"model."+e+".read",params:[[b],["rec_name"],a.get_context()]},a.model.session).done(d.bind(this)).done(function(){a.group.root_group().screens.forEach(function(a){a.display()})})}else d.call(this,[{rec_name:c}]);a._values[this.name]=b},set_client:function(a,b,c){var d;b instanceof Array?(d=b[1],b=b[0]):d=b==this.get(a)?a._values[this.name+".rec_name"]||"":"",a._values[this.name+".rec_name"]=d,Sao.field.Many2One._super.set_client.call(this,a,b,c)},get_context:function(a){var b=Sao.field.Many2One._super.get_context.call(this,a);return this.description.datetime_field&&(b._datetime=a.get_eval()[this.description.datetime_field]),b},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=this.get_domains(a),c=b[0],d=b[1],e=new Sao.common.DomainInversion;return e.concat([e.localize_domain(e.inverse_leaf(c),this.name),d])},get_on_change_value:function(a){return a.group.parent_name==this.name&&a.group.parent?a.group.parent.get_on_change_value([a.group.child_name]):Sao.field.Many2One._super.get_on_change_value.call(this,a)}}),Sao.field.One2One=Sao.class_(Sao.field.Many2One,{}),Sao.field.One2Many=Sao.class_(Sao.field.Field,{init:function(a){Sao.field.One2Many._super.init.call(this,a);
-},_default:null,_set_value:function(a,b,c){this._set_default_value(a);var d=a._values[this.name],e=jQuery.when();jQuery.isEmptyObject(b)&&(b=[]);var f;if(f=jQuery.isEmptyObject(b)||!isNaN(parseInt(b[0],10))?"list ids":"list values","list values"==f){var g=this.get_context(a),h={};if(b.forEach(function(a){for(var b in a)a.hasOwnProperty(b)&&(b in d.model.fields||~b.indexOf(".")||(h[b]=!0))}),!jQuery.isEmptyObject(h)){var i={method:"model."+this.description.relation+".fields_get",params:[Object.keys(h),g]};e=Sao.rpc(i,a.model.session)}}var j=function(e){var g=[];if(jQuery.isEmptyObject(e)||d.add_fields(e),a._values[this.name]=d,"list ids"==f){for(var h=0,i=d.length;h<i;h++){var j=d[h];~b.indexOf(j.id)||d.remove(j,!0)}d.load(b)}else b.forEach(function(a){var b=d.new_(!1);c?(g.push(b.set_default(a,!1)),d.add(b)):(g.push(b.set(a)),d.push(b))});return jQuery.when.apply(jQuery,g)};return e.then(j)},set:function(a,b,c){void 0===c&&(c=!1);var d,e=a._values[this.name];return void 0!==e?(d=e.model,e.destroy()):d=a.model.name==this.description.relation?a.model:new Sao.Model(this.description.relation),a._values[this.name]=void 0,this._set_default_value(a,d),this._set_value(a,b,c)},get:function(a){var b=a._values[this.name];if(void 0===b)return[];for(var c=b.record_removed,d=b.record_deleted,e=[],f=this.description.relation_field||"",g=[],h=[],i=[],j=0,k=b.length;j<k;j++){var l=b[j];if(!~c.indexOf(l)&&!~d.indexOf(l)){var m;l.id>=0?(m=l.get(),delete m[f],l.has_changed()&&!jQuery.isEmptyObject(m)&&(i.push([l.id]),i.push(m)),g.push(l.id)):(m=l.get(),delete m[f],h.push(m))}}return jQuery.isEmptyObject(g)||e.push(["add",g]),jQuery.isEmptyObject(h)||e.push(["create",h]),jQuery.isEmptyObject(i)||e.push(["write"].concat(i)),jQuery.isEmptyObject(c)||e.push(["remove",c.map(function(a){return a.id})]),jQuery.isEmptyObject(d)||e.push(["delete",d.map(function(a){return a.id})]),e},set_client:function(a,b,c){null===b&&(b=[]),"number"==typeof b&&(b=[b]);var d=this.get_eval(a);this._set_value(a,b),Sao.common.compare(d.sort(),b.sort())?c&&(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})})):(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.changed().done(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})})}))},get_client:function(a){return this._set_default_value(a),a._values[this.name]},set_default:function(a,b){return a._changed[this.name]=!0,this.set(a,b,!0)},set_on_change:function(a,b){if(a._changed[this.name]=!0,this._set_default_value(a),b instanceof Array)return void this._set_value(a,b);var c=jQuery.when();if(b.add||b.update){var d=this.get_context(a),e=a._values[this.name].model.fields,f={},g=[];if(b.add)for(var h=0;h<b.add.length;h++)g.push(b.add[h][1]);if([g,b.update].forEach(function(a){jQuery.isEmptyObject(a)||a.forEach(function(a){Object.keys(a).forEach(function(a){a in e||"id"==a||(f[a]=!0)})})}),!jQuery.isEmptyObject(f)){var i={method:"model."+this.description.relation+".fields_get",params:[Object.keys(f),d]};c=Sao.rpc(i,a.model.session)}}var j=[],k=a._values[this.name];k.forEach(function(a){a.id||j.push(a)}),b.remove&&b.remove.forEach(function(a){var b=k.get(a);b&&j.push(b)}.bind(this)),j.forEach(function(a){k.remove(a,!1,!0,!1)}.bind(this)),(b.add||b.update)&&c.then(function(a){k.add_fields(a),b.add&&b.add.forEach(function(a){var b=a[0],c=a[1],d=k.new_(!1);k.add(d,b,!1),d.set_on_change(c)}),b.update&&b.update.forEach(function(a){if(a.id){var b=k.get(a.id);b&&b.set_on_change(a)}})}.bind(this))},_set_default_value:function(a,b){if(void 0===a._values[this.name]){b||(b=new Sao.Model(this.description.relation)),a.model.name==this.description.relation&&(b=a.model);var c=a.expr_eval(this.description.context||{}),d=Sao.Group(b,c,[]);d.set_parent(a),d.parent_name=this.description.relation_field,d.child_name=this.name,a._values[this.name]=d}},get_timestamp:function(a){var b=a._values[this.name];if(void 0===b)return{};for(var c,d={},e=0,f=b.length;e<f;e++)c=b[e],jQuery.extend(d,c.get_timestamp());return d},get_eval:function(a){var b=[],c=a._values[this.name];if(void 0===c)return b;for(var d=c.record_removed,e=c.record_deleted,f=0,g=a._values[this.name].length;f<g;f++){var h=c[f];~d.indexOf(h)||~e.indexOf(h)||b.push(h.id)}return b},get_on_change_value:function(a){var b=[],c=a._values[this.name];if(void 0===c)return b;for(var d=0,e=a._values[this.name].length;d<e;d++){var f=c[d];f.deleted()&&f.removed()||b.push(f.get_on_change_value([this.description.relation_field||""]))}return b},get_removed_ids:function(a){return a._values[this.name].record_removed.map(function(a){return a.id})},get_domain:function(a){var b=this.get_domains(a),c=b[1];return c},validation_domains:function(a,b){return this.get_domains(a,b)[0]},validate:function(a,b,c){var d=!1,e=new Sao.common.DomainInversion,f=e.localize_domain(e.domain_inversion(a.group.clean4inversion(c||[]),this.name,Sao.common.EvalEnvironment(a)),this.name);"boolean"==typeof f&&(f=f?[]:[["id","=",null]]);for(var g=0,h=(a._values[this.name]||[]).length;g<h;g++){var i=a._values[this.name][g];!i.get_loaded()&&i.id>=0&&!c||i.validate(null,b,f,!0)||(d="children")}var j=Sao.field.One2Many._super.validate.call(this,a,b,c);return j&&d?(this.get_state_attrs(a).invalid=d,!1):j},set_state:function(a,b){this._set_default_value(a),Sao.field.One2Many._super.set_state.call(this,a,b)}}),Sao.field.Many2Many=Sao.class_(Sao.field.One2Many,{get_on_change_value:function(a){return this.get_eval(a)}}),Sao.field.Reference=Sao.class_(Sao.field.Field,{_default:null,get_client:function(a){if(a._values[this.name]){var b=a._values[this.name][0],c=a._values[this.name+".rec_name"]||"";return[b,c]}return null},get:function(a){return a._values[this.name]&&a._values[this.name][0]&&a._values[this.name][1]>=-1?a._values[this.name].join(","):null},set_client:function(a,b,c){if(b){"string"==typeof b&&(b=b.split(","));var d,e=b[0],f=b[1];f instanceof Array?(d=f[1],f=f[0]):(f&&!isNaN(parseInt(f,10))&&(f=parseInt(f,10)),d=[e,f].join(",")==this.get(a)?a._values[this.name+".rec_name"]||"":""),a._values[this.name+".rec_name"]=d,b=[e,f]}Sao.field.Reference._super.set_client.call(this,a,b,c)},set:function(a,b){if(!b)return void(a._values[this.name]=this._default);var c,d;"string"==typeof b?(c=b.split(",")[0],d=b.split(",")[1],d?isNaN(parseInt(d,10))||(d=parseInt(d,10)):d=null):(c=b[0],d=b[1]);var e=a._values[this.name+".rec_name"]||"",f=function(b){a._values[this.name+".rec_name"]=b}.bind(this);c&&null!==d&&d>=0?!e&&d>=0&&Sao.rpc({method:"model."+c+".read",params:[[d],["rec_name"],a.get_context()]},a.model.session).done(function(a){f(a[0].rec_name)}):e=c?"":d,a._values[this.name]=[c,d],f(e)},get_on_change_value:function(a){return a.group.parent_name==this.name&&a.group.parent?[a.group.parent.model.name,a.group.parent.get_on_change_value([a.group.child_name])]:Sao.field.Reference._super.get_on_change_value.call(this,a)},get_context:function(a){var b=Sao.field.Reference._super.get_context.call(this,a);return this.description.datetime_field&&(b._datetime=a.get_eval()[this.description.datetime_field]),b},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=null;a._values[this.name]&&(b=a._values[this.name][0]);var c=this.get_domains(a),d=c[0],e=c[1],f=new Sao.common.DomainInversion;return f.concat([f.localize_domain(f.filter_leaf(d,this.name,b),!0),e])}}),Sao.field.Binary=Sao.class_(Sao.field.Field,{_default:null,get_size:function(a){var b=a._values[this.name]||0;return b instanceof Uint8Array?b.length:b},get_data:function(a){var b=a._values[this.name]||[],c=jQuery.when(b);if(!(b instanceof Uint8Array)){if(a.id<0)return c;var d=a.get_context();c=a.model.execute("read",[[a.id],[this.name]],d).then(function(a){return a[0][this.name]}.bind(this))}return c}}),Sao.field.Dict=Sao.class_(Sao.field.Field,{_default:{},set:function(a,b){if(b){var c=[];for(var d in b)c.push(d);c.sort();var e={};for(var f in c)d=c[f],e[d]=b[d];b=e}Sao.field.Dict._super.set.call(this,a,b)},get:function(a){return Sao.field.Dict._super.get.call(this,a)||this._default},get_client:function(a){return Sao.field.Dict._super.get_client.call(this,a)||this._default},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=new Sao.common.DomainInversion,c=this.get_domains(a),d=c[0],e=c[1];return b.concat([b.localize_domain(b.inverse_leaf(d)),e])},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)},time_format:function(a){return"%X"}})}(),function(){"use strict";Sao.Tab=Sao.class_(Object,{init:function(){Sao.Tab.tabs.push(this),this.buttons={},this.id="tab-"+Sao.Tab.counter++,this.name_el=jQuery("<span/>")},create_tabcontent:function(){this.el=jQuery("<div/>",{class:this.class_});var a=this.create_toolbar().appendTo(this.el);this.title=a.find("a.navbar-brand"),this.content=jQuery("<div/>").appendTo(this.el),this.info_bar&&this.el.append(this.info_bar.el)},set_menu:function(a){this.menu_def().forEach(function(b){var c=b[0],d=b[1],e=b[2],f=jQuery("<li/>",{role:"presentation"}).appendTo(a),g=jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(jQuery("<span/>",{class:"glyphicon "+c,"aria-hidden":"true"})).append(" "+d).appendTo(f);e?g.click(function(){this[e]()}.bind(this)):f.addClass("disabled")}.bind(this))},create_toolbar:function(){var a=jQuery('<nav class="navbar-default toolbar" role="navigation"><div class="container-fluid"><div class="navbar-header"><a class="navbar-brand" href="#"></a><button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-'+this.id+'"><span class="sr-only">'+Sao.i18n.gettext("Toggle navigation")+'</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></div><div class="collapse navbar-collapse" id="navbar-'+this.id+'"><ul class="nav navbar-nav"><li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><span class="glyphicon glyphicon-wrench" aria-hidden="true"></span><span class="visible-xs">'+Sao.i18n.gettext("Menu")+'</span><span class="caret"></span></a><ul class="dropdown-menu" role="menu"></ul></li></ul></div></div></nav>'),b=jQuery("<div/>",{class:"nav-wrapper"}).append(a);this.set_menu(a.find('ul[role*="menu"]'));var c=function(b){var c=jQuery("<li/>",{role:"presentation"}).appendTo(a.find(".navbar-collapse > ul"));this.buttons[b[0]]=jQuery("<a/>",{role:"menuitem",href:"#",id:b[0]}).append(jQuery("<span/>",{class:"glyphicon "+b[1],"aria-hidden":"true"})).append(jQuery("<span/>",{class:"hidden-sm"}).append(" "+b[2])).appendTo(c),b[4]?this.buttons[b[0]].click(this[b[4]].bind(this)):c.addClass("disabled")};this.toolbar_def().forEach(c.bind(this));var d=jQuery("#tabs");return a.affix({target:d.parent(),offset:{top:function(){return d.find(".nav-tabs").height()}}}),a.on("affix.bs.affix",function(){b.height(a.height())}),a.on("affix-top.bs.affix affix-bottom.bs.affix",function(){b.height("")}),a.on("affixed.bs.affix",function(){Sao.Tab.affix_set_with(a)}),a.on("affixed-top.bs.affix affixed-bottom.bs.affix",function(){Sao.Tab.affix_unset_width(a)}),b},close:function(){var a=jQuery("#tabs"),b=a.find("#nav-"+this.id),c=a.find("#"+this.id);return a.find('a[href="#'+this.id+'"]').tab("show"),this._close_allowed().then(function(){var d=b.next();d.length||(d=b.prev()),b.remove(),c.remove(),Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(this),1),d&&d.find("a").tab("show"),a.trigger("ready")}.bind(this))},_close_allowed:function(){return jQuery.when()},set_name:function(a){this.name_el.text(a)}}),Sao.Tab.affix_set_with=function(a){var b=jQuery(a.parent()).width();a.css("width",b)},Sao.Tab.affix_unset_width=function(a){a.css("width","")},jQuery(window).resize(function(){jQuery(".toolbar").each(function(a,b){b=jQuery(b),b.affix("checkPosition"),b.hasClass("affix")?Sao.Tab.affix_set_with(b):Sao.Tab.affix_unset_width(b)})}),Sao.Tab.counter=0,Sao.Tab.tabs=[],Sao.Tab.tabs.close=function(a){if(a&&Sao.Tab.tabs.length)return Sao.common.sur.run(Sao.i18n.gettext("The following action requires to close all tabs.\nDo you want to continue?")).then(function(){return Sao.Tab.tabs.close(!1)});if(Sao.Tab.tabs.length){var b=Sao.Tab.tabs[0];return b.close().then(function(){return~Sao.Tab.tabs.indexOf(b)?jQuery.Deferred().reject():Sao.Tab.tabs.close()})}return Sao.main_menu_screen?Sao.main_menu_screen.save_tree_state().then(function(){Sao.main_menu_screen=null}):jQuery.when()},Sao.Tab.tabs.get_current=function(){var a=jQuery("#tabs > ul"),b=a.find("li").index(a.find("li.active"));return Sao.Tab.tabs[b]},Sao.Tab.tabs.close_current=function(){var a=this.get_current();a.close()},Sao.Tab.create=function(a){void 0===a.context&&(a.context={});var b;b=a.model?new Sao.Tab.Form(a.model,a):new Sao.Tab.Board(a),Sao.Tab.add(b)},Sao.Tab.add=function(a){var b=jQuery("#tabs"),c=jQuery("<a/>",{"aria-controls":a.id,role:"tab","data-toggle":"tab",href:"#"+a.id}).append(jQuery("<button/>",{class:"close"}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Close"))).click(function(){a.close()})).append(a.name_el);jQuery("<li/>",{role:"presentation",id:"nav-"+a.id}).append(c).appendTo(b.find("> .nav-tabs")),jQuery("<div/>",{role:"tabpanel",class:"tab-pane",id:a.id}).html(a.el).appendTo(b.find("> .tab-content")),c.on("shown.bs.tab",function(){Sao.View.resize(a.el)}),c.tab("show"),b.trigger("ready")},Sao.Tab.Form=Sao.class_(Sao.Tab,{class_:"tab-form",init:function(a,b){Sao.Tab.Form._super.init.call(this);var c=new Sao.Screen(a,b);c.tab=this,this.screen=c,this.attributes=jQuery.extend({},b),this.info_bar=new Sao.Window.InfoBar,this.create_tabcontent(),this.set_buttons_sensitive(),this.view_prm=this.screen.switch_view().done(function(){this.set_name(b.name||""),this.content.append(c.screen_container.el),b.res_id?(jQuery.isArray(b.res_id)||(b.res_id=[b.res_id]),c.group.load(b.res_id),c.set_current_record(c.group.get(b.res_id)),c.display()):("form"==c.current_view.view_type&&c.new_(),~["tree","graph","calendar"].indexOf(c.current_view.view_type)&&c.search_filter()),this.update_revision()}.bind(this))},toolbar_def:function(){return[["new","glyphicon-edit",Sao.i18n.gettext("New"),Sao.i18n.gettext("Create a new record"),"new_"],["save","glyphicon-save",Sao.i18n.gettext("Save"),Sao.i18n.gettext("Save this record"),"save"],["switch","glyphicon-list-alt",Sao.i18n.gettext("Switch"),Sao.i18n.gettext("Switch view"),"switch_"],["reload","glyphicon-refresh",Sao.i18n.gettext("Reload"),Sao.i18n.gettext("Reload"),"reload"],["previous","glyphicon-chevron-left",Sao.i18n.gettext("Previous"),Sao.i18n.gettext("Previous Record"),"previous"],["next","glyphicon-chevron-right",Sao.i18n.gettext("Next"),Sao.i18n.gettext("Next Record"),"next"],["attach","glyphicon-paperclip",Sao.i18n.gettext("Attachment"),Sao.i18n.gettext("Add an attachment to the record"),"attach"],["note","glyphicon-comment",Sao.i18n.gettext("Note"),Sao.i18n.gettext("Add a note to the record"),"note"]]},menu_def:function(){return[["glyphicon-edit",Sao.i18n.gettext("New"),"new_"],["glyphicon-save",Sao.i18n.gettext("Save"),"save"],["glyphicon-list-alt",Sao.i18n.gettext("Switch"),"switch_"],["glyphicon-refresh",Sao.i18n.gettext("Reload/Undo"),"reload"],["glyphicon-duplicate",Sao.i18n.gettext("Duplicate"),"copy"],["glyphicon-trash",Sao.i18n.gettext("Delete"),"delete_"],["glyphicon-chevron-left",Sao.i18n.gettext("Previous"),"previous"],["glyphicon-chevron-right",Sao.i18n.gettext("Next"),"next"],["glyphicon-search",Sao.i18n.gettext("Search"),"search"],["glyphicon-time",Sao.i18n.gettext("View Logs..."),"logs"],["glyphicon-time",Sao.i18n.gettext("Show revisions..."),Sao.common.MODELHISTORY.contains(this.screen.model_name)?"revision":null],["glyphicon-remove",Sao.i18n.gettext("Close Tab"),"close"],["glyphicon-paperclip",Sao.i18n.gettext("Attachment"),"attach"],["glyphicon-comment",Sao.i18n.gettext("Note"),"note"],["glyphicon-cog",Sao.i18n.gettext("Action"),"action"],["glyphicon-share-alt",Sao.i18n.gettext("Relate"),"relate"],["glyphicon-print",Sao.i18n.gettext("Print"),"print"],["glyphicon-export",Sao.i18n.gettext("Export"),"export"],["glyphicon-import",Sao.i18n.gettext("Import"),"import"]]},create_toolbar:function(){var a=Sao.Tab.Form._super.create_toolbar.call(this),b=this.screen,c=this.buttons,d=b.model.execute("view_toolbar_get",[],b.context);return d.done(function(d){[["action","glyphicon-cog",Sao.i18n.gettext("Action"),Sao.i18n.gettext("Launch action")],["relate","glyphicon-share-alt",Sao.i18n.gettext("Relate"),Sao.i18n.gettext("Open related records")],["print","glyphicon-print",Sao.i18n.gettext("Print"),Sao.i18n.gettext("Print report")]].forEach(function(e){var f=jQuery("<li/>",{class:"dropdown"}).append(jQuery("<a/>",{href:"#",id:e[0],class:"dropdown-toggle","data-toggle":"dropdown",role:"button","aria-expanded":"false"}).append(jQuery("<span/>",{class:"glyphicon "+e[1],"aria-hidden":"true"})).append(jQuery("<span/>",{class:"hidden-sm"}).append(" "+e[2]+" ")).append(jQuery("<span/>",{class:"caret"}))).append(jQuery("<ul/>",{class:"dropdown-menu",role:"menu","aria-labelledby":e[0]})).appendTo(a.find(".navbar-collapse > ul"));c[e[0]]=f;var g=f.find('ul[role*="menu"]');"action"==e[0]&&f.find("a").click(function(){g.find(".action_button").remove();var a=b.get_buttons();a.forEach(function(a){jQuery("<li/>",{role:"presentation",class:"action_button"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(a.attributes.string||"")).click(function(){b.button(a.attributes)}).appendTo(g)})}),d[e[0]].forEach(function(a){jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(a.name)).click(function(){b.save_current().then(function(){var c=jQuery.extend({},a),d=null;b.current_record&&(d=b.current_record.id);var f=b.current_view.selected_records().map(function(a){return a.id});c=Sao.Action.evaluate(c,e[0],b.current_record);var g={model:b.model_name,id:d,ids:f};Sao.Action.exec_action(c,g,b.context)})}).appendTo(g)})})}),a},_close_allowed:function(){return this.modified_save()},modified_save:function(){return this.screen.save_tree_state(),this.screen.current_view.set_value(),this.screen.modified()?Sao.common.sur_3b.run(Sao.i18n.gettext("This record has been modified\ndo you want to save it?")).then(function(a){switch(a){case"ok":return this.save();case"ko":return this.reload(!1);default:return jQuery.Deferred().reject()}}.bind(this)):jQuery.when()},new_:function(){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.modified_save().done(function(){this.screen.new_().then(function(){this.info_bar.message()}.bind(this))}.bind(this))},save:function(){var a=Sao.common.MODELACCESS.get(this.screen.model_name);return a.write||a.create?this.screen.save_current().then(function(){this.info_bar.message(Sao.i18n.gettext("Record saved."),"info"),this.screen.count_tab_domain()}.bind(this),function(){this.info_bar.message(this.screen.invalid_message(),"danger")}.bind(this)):jQuery.when()},switch_:function(){this.modified_save().done(function(){this.screen.switch_view()}.bind(this))},reload:function(a){void 0===a&&(a=!0);var b=function(){return this.screen.cancel_current().then(function(){return this.screen.save_tree_state(!1),"form"!=this.screen.current_view.view_type&&this.screen.search_filter(this.screen.screen_container.search_entry.val()),this.screen.count_tab_domain(),this.screen.display().then(function(){this.info_bar.message()}.bind(this))}.bind(this))}.bind(this);return a?this.modified_save().then(b):b()},copy:function(){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.modified_save().done(function(){this.screen.copy().then(function(){this.info_bar.message(Sao.i18n.gettext("Working now on the duplicated record(s)."),"info"),this.screen.count_tab_domain()}.bind(this))}.bind(this))},delete_:function(){if(Sao.common.MODELACCESS.get(this.screen.model_name).delete){var a;a="form"==this.screen.current_view.view_type?Sao.i18n.gettext("Are you sure to remove this record?"):Sao.i18n.gettext("Are you sure to remove those records?"),Sao.common.sur.run(a).done(function(){this.screen.remove(!0,!1,!0).then(function(){this.info_bar.message(Sao.i18n.gettext("Records removed."),"info"),this.screen.count_tab_domain()}.bind(this),function(){this.info_bar.message(Sao.i18n.gettext("Records not removed."),"danger")}.bind(this))}.bind(this))}},previous:function(){this.modified_save().done(function(){this.screen.display_previous(),this.info_bar.message()}.bind(this))},next:function(){this.modified_save().done(function(){this.screen.display_next(),this.info_bar.message()}.bind(this))},search:function(){var a=this.screen.screen_container.search_entry;a.is(":visible")&&window.setTimeout(function(){a.focus()},0)},logs:function(){var a=this.screen.current_record;if(!a||a.id<0)return void this.info_bar.message(Sao.i18n.gettext("You have to select one record."),"info");var b=[["id",Sao.i18n.gettext("ID:")],["create_uid.rec_name",Sao.i18n.gettext("Creation User:")],["create_date",Sao.i18n.gettext("Creation Date:")],["write_uid.rec_name",Sao.i18n.gettext("Latest Modification by:")],["write_date",Sao.i18n.gettext("Latest Modification Date:")]];this.screen.model.execute("read",[[a.id],b.map(function(a){return a[0]})],this.screen.context).then(function(a){a=a[0];var c="";b.forEach(function(b){var d=b[0],e=b[1],f=a[d]||"/";a[d]&&~["create_date","write_date"].indexOf(d)&&(f=Sao.common.format_datetime(Sao.common.date_format(),"%H:%M:%S",f)),c+=e+" "+f+"\n"}),c+=Sao.i18n.gettext("Model: ")+this.screen.model.name,Sao.common.message.run(c)}.bind(this))},revision:function(){var a=null;this.screen.current_record&&(a=this.screen.current_record.id);var b=function(b){return function(c){c&&c.add(1,"milliseconds"),"form"==this.screen.current_view.view_type&&c<b[b.length-1][0]&&(c=b[b.length-1][0]),c!=this.screen.context._datetime&&(this.screen.context._datetime=c,"form"!=this.screen.current_view.view_type?this.screen.search_filter(this.screen.screen_container.search_entry.val()):this.screen.new_group([a]),this.screen.display(!0),this.update_revision())}.bind(this)}.bind(this);this.modified_save().done(function(){var a=this.screen.current_view.selected_records().map(function(a){return a.id});this.screen.model.execute("history_revisions",[a],this.screen.context).then(function(a){new Sao.Window.Revision(a,b(a))})}.bind(this))},update_revision:function(){var a,b=this.screen.context._datetime;if(b){var c=Sao.common.date_format(),d="%H:%M:%S.%f";b=Sao.common.format_datetime(c,d,b),a=this.name_el.text()+" @ "+b}else a=this.name_el.text();this.title.html(a),this.set_buttons_sensitive(b)},set_buttons_sensitive:function(a){if(a)["new","save"].forEach(function(a){this.buttons[a].parent().addClass("disabled")}.bind(this));else{var b=Sao.common.MODELACCESS.get(this.screen.model_name);[["new",b.create],["save",b.create||b.write]].forEach(function(a){var b=a[0],c=a[1];c?this.buttons[b].parent().removeClass("disabled"):this.buttons[b].parent().addClass("disabled")}.bind(this))}},attach:function(){var a=this.screen.current_record;!a||a.id<0||new Sao.Window.Attachment(a,function(){this.update_attachment_count(!0)}.bind(this))},update_attachment_count:function(a){var b=this.screen.current_record;b?b.get_attachment_count(a).always(this.attachment_count.bind(this)):this.attachment_count(0)},attachment_count:function(a){var b=Sao.i18n.gettext("Attachment(%1)",a);this.buttons.attach.text(b);var c=this.screen.get_id();this.buttons.attach.prop("disabled",c<0||null===c)},note:function(){var a=this.screen.current_record;!a||a.id<0||new Sao.Window.Note(a,function(){this.update_unread_note(!0)}.bind(this))},update_unread_note:function(a){var b=this.screen.current_record;b?b.get_unread_note(a).always(this._unread_note.bind(this)):this._unread_note(0)},_unread_note:function(a){var b=Sao.i18n.gettext("Note(%1)",a);this.buttons.note.text(b);var c=this.screen.get_id();this.buttons.note.prop("disabled",c<0||null===c)},record_message:function(){this.info_bar.message()},action:function(){window.setTimeout(function(){this.buttons.action.find("ul.dropdown-menu").dropdown("toggle")}.bind(this))},relate:function(){window.setTimeout(function(){this.buttons.relate.find("ul.dropdown-menu").dropdown("toggle")}.bind(this))},print:function(){window.setTimeout(function(){this.buttons.print.find("ul.dropdown-menu").dropdown("toggle")}.bind(this))},export:function(){new Sao.Window.Export(this.screen,this.screen.current_view.selected_records().map(function(a){return a.id}),this.screen.current_view.get_fields())},import:function(){new Sao.Window.Import(this.screen)}}),Sao.Tab.Board=Sao.class_(Sao.Tab,{class_:"tab-board",init:function(a){var b,c;Sao.Tab.Board._super.init.call(this),this.model=a.model,this.view_id=a.view_ids.length>0?a.view_ids[0]:null,this.context=a.context,this.name=a.name||"",this.dialogs=[],this.board=null,b=new Sao.Model("ir.ui.view"),c=b.execute("read",[[this.view_id],["arch"]],this.context),c.done(function(a){var b;b=jQuery(jQuery.parseXML(a[0].arch)),this.board=new Sao.View.Board(b,this.context),this.board.actions_prms.done(function(){var a,b,c;for(a=0,b=this.board.actions.length;a<b;a++)c=this.board.actions[a],c.screen.tab=this}.bind(this)),this.el.append(this.board.el)}.bind(this)),this.create_tabcontent(),this.set_name(this.name),this.title.html(this.name_el.text())},toolbar_def:function(){return[["reload","glyphicon-refresh",Sao.i18n.gettext("Reload"),Sao.i18n.gettext("Reload"),"reload"]]},menu_def:function(){return[["glyphicon-refresh",Sao.i18n.gettext("Reload/Undo"),"reload"]]},reload:function(){this.board.reload()},record_message:function(){var a,b,c;for(b=this.board.actions.length,a=0,b=b;a<b;a++)c=this.board.actions[a],c.update_domain(this.board.actions)},attachment_count:function(){},note:function(){},update_unread_note:function(){}}),Sao.Tab.Wizard=Sao.class_(Sao.Tab,{class_:"tab-wizard",init:function(a){Sao.Tab.Wizard._super.init.call(this),this.wizard=a,this.set_name(a.name),a.tab=this,this.create_tabcontent(),this.title.html(this.name_el.text()),this.el.append(a.form)},create_toolbar:function(){return jQuery("<span/>")},_close_allowed:function(){var a=this.wizard,b=jQuery.when();a.state!==a.end_state&&a.end_state in a.states&&(b=a.response(a.end_state));var c=jQuery.Deferred();return b.always(function(){a.state===a.end_state?c.resolve():c.reject()}),c.promise()}})}(),function(){"use strict";Sao.ScreenContainer=Sao.class_(Object,{init:function(a){this.alternate_viewport=jQuery("<div/>",{class:"screen-container"}),this.alternate_view=!1,this.search_modal=null,this.search_form=null,this.last_search_text="",this.tab_domain=a||[],this.tab_counter=[],this.el=jQuery("<div/>",{class:"screen-container"}),this.filter_box=jQuery("<form/>",{class:"filter-box"}).submit(function(a){this.do_search(),a.preventDefault()}.bind(this));var b=jQuery("<div/>",{class:"row"}).appendTo(this.filter_box);this.el.append(this.filter_box),this.filter_button=jQuery("<button/>",{type:"button",class:"btn btn-default"}).append(Sao.i18n.gettext("Filters")),this.filter_button.click(this.search_box.bind(this)),this.search_entry=jQuery("<input/>",{class:"form-control",placeholder:Sao.i18n.gettext("Search")}),this.search_list=jQuery("<datalist/>"),this.search_list.uniqueId(),this.search_entry.attr("list",this.search_list.attr("id")),this.search_entry.keypress(this.key_press.bind(this)),this.search_entry.on("input",this.update.bind(this));var c=jQuery("<button/>",{type:"submit",class:"btn btn-default","aria-label":Sao.i18n.gettext("Search")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-search"}));this.but_bookmark=jQuery("<button/>",{type:"button",class:"btn btn-default dropdown-toggle","data-toggle":"dropdown","aria-expanded":!1,"aria-label":Sao.i18n.gettext("Bookmarks"),id:"bookmarks"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-bookmark","aria-hidden":!0}));var d=jQuery("<ul/>",{class:"dropdown-menu",role:"menu","aria-labelledby":"bookmarks"});if(this.but_bookmark.click(function(){d.children().remove();for(var a=this.bookmarks(),b=0;b<a.length;b++){var c=a[b][1],e=a[b][2];jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(c).click(e,this.bookmark_activate.bind(this))).appendTo(d)}}.bind(this)),this.but_star=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon","aria-hidden":!0})).click(this.star_click.bind(this)),this.set_star(),jQuery("<div/>",{class:"input-group"}).append(jQuery("<span/>",{class:"input-group-btn"}).append(this.filter_button)).append(this.search_entry).append(this.search_list).append(jQuery("<span/>",{class:"input-group-btn"}).append(c).append(this.but_star).append(this.but_bookmark).append(d)).appendTo(jQuery("<div/>",{class:"col-sm-10 col-xs-12"}).appendTo(b)),this.but_prev=jQuery("<button/>",{type:"button",class:"btn btn-default","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-menu-left","aria-hidden":!0})),this.but_prev.click(this.search_prev.bind(this)),this.but_next=jQuery("<button/>",{type:"button",class:"btn btn-default","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-menu-right","aria-hidden":!0})),this.but_next.click(this.search_next.bind(this)),jQuery("<div/>",{class:"btn-group",role:"group"}).append(this.but_prev).append(this.but_next).appendTo(jQuery("<div/>",{class:"col-sm-2 pull-right"}).appendTo(b)),this.content_box=jQuery("<div/>",{class:"content-box"}),jQuery.isEmptyObject(this.tab_domain))this.tab=null;else{this.tab=jQuery("<div/>",{class:"tab-domain"}).appendTo(this.el);var e=jQuery("<ul/>",{class:"nav nav-tabs",role:"tablist"}).appendTo(this.tab);jQuery("<div/>",{class:"tab-content"}).appendTo(this.tab);this.tab_domain.forEach(function(a,b){var c=a[0],d=jQuery("<span/>",{class:"badge"});jQuery("<li/>",{role:"presentation",id:"nav-"+b}).append(jQuery("<a/>",{"aria-controls":b,role:"tab","data-toggle":"tab",href:"#"+b}).append(c+" ").append(d)).appendTo(e);this.tab_counter.push(d)}.bind(this)),e.find("a:first").tab("show");var f=this;e.find("a").click(function(a){a.preventDefault(),jQuery(this).tab("show"),f.do_search(),f.screen.count_tab_domain()})}this.el.append(this.content_box)},set_text:function(a){this.search_entry.val(a),this.bookmark_match()},update:function(){var a=this.screen.domain_parser().completion(this.get_text());this.search_list.children().remove(),a.forEach(function(a){jQuery("<option/>",{value:a.trim()}).appendTo(this.search_list)},this)},set_star:function(a){var b=this.but_star.children("span.glyphicon");a?(b.removeClass("glyphicon-star-empty"),b.addClass("glyphicon-star"),this.but_star.attr("aria-label",Sao.i18n.gettext("Remove this bookmark"))):(b.removeClass("glyphicon-star"),b.addClass("glyphicon-star-empty"),this.but_star.attr("aria-label",Sao.i18n.gettext("Bookmark this filter")))},get_star:function(){var a=this.but_star.children("span.glyphicon");return a.hasClass("glyphicon-star")},star_click:function(){var a=this.get_star(),b=this.screen.model_name,c=function(){this.bookmark_match(),this.but_bookmark.prop("disabled",jQuery.isEmptyObject(this.bookmarks()))}.bind(this);if(a){var d=this.bookmark_match();Sao.common.VIEW_SEARCH.remove(b,d).then(function(){c()})}else{var e=this.get_text();if(!e)return;Sao.common.ask.run(Sao.i18n.gettext("Bookmark Name:")).then(function(a){if(a){var d=this.screen.domain_parser().parse(e);Sao.common.VIEW_SEARCH.add(b,a,d).then(function(){c()}),this.set_text(this.screen.domain_parser().string(d))}}.bind(this))}},bookmarks:function(){var a=Sao.common.VIEW_SEARCH.get(this.screen.model_name);return a.filter(function(a){return this.screen.domain_parser().stringable(a[2])}.bind(this))},bookmark_activate:function(a){var b=a.data;this.set_text(this.screen.domain_parser().string(b)),
-this.do_search()},bookmark_match:function(){var a=this.get_text();if(a){var b=this.screen.domain_parser().parse(a);this.but_star.prop("disabled",!a);for(var c=(this.get_star(),this.bookmarks()),d=0;d<c.length;d++){var e=c[d][0],f=(c[d][1],c[d][2]),g=this.screen.domain_parser().string(f);if(g===a||Sao.common.compare(f,b))return this.set_star(!0),e}}this.set_star(!1)},search_prev:function(){this.screen.search_prev(this.get_text())},search_next:function(){this.screen.search_next(this.get_text())},get_tab_domain:function(){if(!this.tab)return[];var a=this.tab.find("li").index(this.tab.find("li.active"));return this.tab_domain[a][1]},set_tab_counter:function(a,b){if(!jQuery.isEmptyObject(this.tab_counter)&&this.tab&&(void 0!==b&&null!==b||(b=this.tab.find("li").index(this.tab.find("li.active"))),!(b<0))){var c=this.tab_counter[b];if(c.data("toggle","tooltip"),null===a)c.attr("title",""),c.text("");else{c.attr("title",a);var d=a;a>99&&(d="99+"),c.text(d)}c.tooltip()}},do_search:function(){return this.screen.search_filter(this.get_text())},key_press:function(a){window.setTimeout(function(){this.bookmark_match()}.bind(this))},set_screen:function(a){this.screen=a,this.but_bookmark.prop("disabled",jQuery.isEmptyObject(this.bookmarks())),this.bookmark_match()},show_filter:function(){this.filter_box.show(),this.tab&&this.tab.show()},hide_filter:function(){this.filter_box.hide(),this.tab&&this.tab.hide()},set:function(a){this.alternate_view?(this.alternate_viewport.children().detach(),this.alternate_viewport.append(a)):(this.content_box.children().detach(),this.content_box.append(a))},get_text:function(){return this.search_entry.val()},search_box:function(){var a=this.screen.domain_parser(),b=function(){this.search_modal.modal("hide");for(var b="",c=a.quote.bind(a),d=0;d<this.search_form.fields.length;d++){var e,f=this.search_form.fields[d][0],g=this.search_form.fields[d][1];switch(g.type){case"selection":case"date":case"datetime":case"time":e=g.get_value(c);break;default:e=c(g.val())}e&&(b+=c(f)+": "+e+" ")}this.set_text(b),this.do_search().then(function(){this.last_search_text=this.get_text()}.bind(this))}.bind(this);if(!this.search_modal){var c=new Sao.Dialog(Sao.i18n.gettext("Filters"),"","lg");this.search_modal=c.modal,this.search_form=c.content,this.search_form.addClass("form-horizontal"),this.search_form.submit(function(a){b(),a.preventDefault()});var d,e=[];for(var f in a.fields)d=a.fields[f],(d.searchable||void 0===d.searchable)&&e.push(d);var g=function(a){return function(b){jQuery("<option/>",{value:b,text:b}).appendTo(a)}},h="filter-"+this.screen.model_name+"-";this.search_form.fields=[];for(var i=0;i<e.length;i++){d=e[i];var j,k,l=jQuery("<div/>",{class:"form-group form-group-sm"}).append(jQuery("<label/>",{class:"col-sm-4 control-label",for:h+d.name,text:d.string})).appendTo(c.body);switch(d.type){case"boolean":k=j=jQuery("<select/>",{class:"form-control input-sm",id:h+d.name}),["",Sao.i18n.gettext("True"),Sao.i18n.gettext("False")].forEach(g(j));break;case"selection":k=new Sao.ScreenContainer.Selection(d.selection,h+d.name),j=k.el;break;case"date":case"datetime":case"time":var m,n=Sao.common.date_format();if("date"==d.type)m=n;else{var o=new Sao.PYSON.Decoder({}).decode(d.format);o=Sao.common.moment_format(o),"time"==d.type?m=o:"datetime"==d.type&&(m=n+" "+o)}k=new Sao.ScreenContainer.DateTimes(m,h+d.name),j=k.el;break;default:k=j=jQuery("<input/>",{class:"form-control input-sm",type:"text",placeholder:d.string,id:h+d.name})}jQuery("<div/>",{class:"col-sm-8"}).append(j).appendTo(l),this.search_form.fields.push([d.string,k])}jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Find")).click(b).appendTo(c.footer)}if(this.search_modal.modal("show"),this.last_search_text.trim()!==this.get_text().trim()){for(var p=0;p<this.search_form.fields.length;p++){var q=this.search_form.fields[p][1];switch(q.type){case"selection":q.set_value([]);break;case"date":case"datetime":case"time":q.set_value(null,null);break;default:q.val("")}}this.search_form.fields[0][1].focus()}}}),Sao.ScreenContainer.DateTimes=Sao.class_(Object,{type:"date",init:function(a,b){this.el=jQuery("<div/>",{class:"row",id:b});var c=function(c){var d=jQuery("<div/>",{class:"input-group input-group-sm"});return jQuery("<input/>",{class:"form-control input-sm",type:"text",placeholder:c,id:b+"-from"}).appendTo(d),jQuery("<span/>",{class:"input-group-btn"}).append(jQuery("<button/>",{class:"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-calendar"}))).appendTo(d),d.datetimepicker({locale:moment.locale()}),d.data("DateTimePicker").format(a),d};this.from=c("From").appendTo(jQuery("<div/>",{class:"col-md-5"}).appendTo(this.el)),jQuery("<p/>",{class:"text-center"}).append("..").appendTo(jQuery("<div/>",{class:"col-md-1"}).appendTo(this.el)),this.to=c("To").appendTo(jQuery("<div/>",{class:"col-md-5"}).appendTo(this.el))},_get_value:function(a){return a.find("input").val()},get_value:function(a){var b=this._get_value(this.from),c=this._get_value(this.to);return b&&c?b!==c?a(b)+".."+a(c):a(b):b?">="+a(b):c?"<="+a(c):void 0},set_value:function(a,b){this.from.data("DateTimePicker").date(a),this.to.data("DateTimePicker").date(b)}}),Sao.ScreenContainer.Selection=Sao.class_(Object,{type:"selection",init:function(a,b){this.el=jQuery("<select/>",{class:"form-control input-sm",multiple:!0,id:b}),a.forEach(function(a){jQuery("<option/>",{value:a[1],text:a[1]}).appendTo(this.el)}.bind(this))},get_value:function(a){var b=this.el.val();return b&&(b=jQuery.map(b,a).reduce(function(a,b){return a&&(a+=";"),a+b})),b},set_value:function(a){this.el.val(a)}}),Sao.Screen=Sao.class_(Object,{init:function(a,b){this.model_name=a,this.model=new Sao.Model(a,b),this.attributes=jQuery.extend({},b),this.attributes.limit=this.attributes.limit||Sao.config.limit,this.view_ids=jQuery.extend([],b.view_ids),this.view_to_load=jQuery.extend([],b.mode||["tree","form"]),this.views=[],this.views_preload=b.views_preload||{},this.exclude_field=b.exclude_field,this.context=b.context||{},this.new_group(),this.current_view=null,this.current_record=null,this.domain=b.domain||[],this.size_limit=null,this.limit=b.limit||Sao.config.limit,this.offset=0,this.order=this.default_order=b.order;var c=Sao.common.MODELACCESS.get(a);c.write||c.create||(this.attributes.readonly=!0),this.search_count=0,this.screen_container=new Sao.ScreenContainer(b.tab_domain),this.context_screen=null,b.context_model&&(this.context_screen=new Sao.Screen(b.context_model,{mode:["form"],context:b.context}),this.context_screen_prm=this.context_screen.switch_view().then(function(){return jQuery("<div/>",{class:"row"}).append(jQuery("<div/>",{class:"col-md-12"}).append(this.context_screen.screen_container.el)).prependTo(this.screen_container.filter_box),this.context_screen.new_(!1).then(function(a){return a.default_get()})}.bind(this))),b.row_activate?this.row_activate=b.row_activate:this.row_activate=this.default_row_activate,this.tree_states={},this.tree_states_done=[],this.fields_view_tree={},this._domain_parser={},this.pre_validate=!1,this.tab=null,this.count_tab_domain()},load_next_view:function(){if(!jQuery.isEmptyObject(this.view_to_load)){var a;jQuery.isEmptyObject(this.view_ids)||(a=this.view_ids.shift());var b=this.view_to_load.shift();return this.add_view_id(a,b)}return jQuery.when()},add_view_id:function(a,b){var c;if(a&&this.views_preload[String(a)])c=this.views_preload[String(a)];else{if(a||!this.views_preload[b]){var d=this.model.execute("fields_view_get",[a,b],this.context);return d.pipe(this.add_view.bind(this))}c=this.views_preload[b]}return this.add_view(c),jQuery.when()},add_view:function(a){var b=a.arch,c=a.fields,d=a.view_id,e=jQuery(jQuery.parseXML(b));"tree"==e.children().prop("tagName")&&(this.fields_view_tree[d]=a);var f="eager";"form"==e.children().prop("tagName")&&(f="lazy");for(var g in c)g in this.model.fields&&"eager"!=f?c[g].loading=this.model.fields[g].description.loading:c[g].loading=f;this.group.add_fields(c);var h=Sao.View.parse(this,e,a.field_childs);return h.view_id=d,this.views.push(h),h},number_of_views:function(){return this.views.length+this.view_to_load.length},switch_view:function(a){if(this.current_view){this.current_view.set_value(),this.current_record&&!~this.current_record.group.indexOf(this.current_record)&&(this.current_record=null);var b=this.current_view.get_fields();if(this.current_record&&this.current_view.editable&&!this.current_record.validate(b,!1,!1,!0))return this.screen_container.set(this.current_view.el),this.current_view.display().done(function(){this.set_cursor()}.bind(this))}var c=function(){if(!a||!this.current_view||this.current_view.view_type!=a)for(var b=function(){return this.current_view=this.views[this.views.length-1],c()}.bind(this),d=0;d<this.number_of_views();d++){if(this.view_to_load.length)return a||(a=this.view_to_load[0]),this.load_next_view().then(b);if(this.current_view=this.views[(this.views.indexOf(this.current_view)+1)%this.views.length],!a)break;if(this.current_view.view_type==a)break}return this.screen_container.set(this.current_view.el),this.display().done(function(){this.set_cursor()}.bind(this))}.bind(this);return c()},search_filter:function(a,b){if(b=b||!1,this.context_screen){if("pending"==this.context_screen_prm.state())return this.context_screen_prm.then(function(){return this.search_filter(a)}.bind(this));var c=this.context_screen.current_record;if(c&&!c.validate(null,!1,null,!0))return this.new_group([]),this.context_screen.display(!0),jQuery.when();this.context=jQuery.extend({},this.context,this.context_screen.get_on_change_value())}var d=this.search_domain(a,!0),e=this.screen_container.get_tab_domain();jQuery.isEmptyObject(e)||(d=["AND",d,e]);var f=this.model.find(d,this.offset,this.limit,this.order,this.context),g=jQuery.when(this.search_count);return b||(g=this.model.execute("search_count",[d],this.context)),g.done(function(a){this.search_count=a}.bind(this)),f.done(this.set_group.bind(this)),f.done(this.display.bind(this)),jQuery.when(f,g).done(function(a,b){this.screen_container.but_next.prop("disabled",!(a.length==this.limit&&b>this.limit+this.offset))}.bind(this)),this.screen_container.but_prev.prop("disabled",this.offset<=0),this.count_tab_domain(),f},search_domain:function(a,b){b=b||!1;var c=[];if(!this.group.parent&&this.domain_parser()){var d=this.domain_parser();c=a||""===a?d.parse(a):this.attributes.search_value,b&&this.screen_container.set_text(d.string(c))}else c=[["id","in",this.group.map(function(a){return a.id})]];return jQuery.isEmptyObject(c)?c=this.attributes.domain||[]:jQuery.isEmptyObject(this.attributes.domain)||(c=["AND",c,this.attributes.domain]),this.current_view&&"calendar"==this.current_view.view_type&&(c=jQuery.isEmptyObject(c)?this.current_view.current_domain():["AND",c,this.current_view.current_domain()]),c},count_tab_domain:function(){var a=this.search_domain(this.screen_container.get_text());this.screen_container.tab_domain.forEach(function(b,c){if(b[2]){var d=["AND",b[1],a];this.screen_container.set_tab_counter(null,c),this.group.model.execute("search_count",[d],this.context).then(function(a){this.screen_container.set_tab_counter(a,c)}.bind(this))}}.bind(this))},set_group:function(a){var b={};if(this.group){for(var c in this.group.model.fields)this.group.model.fields.hasOwnProperty(c)&&(b[c]=this.group.model.fields[c].description);this.group.screens.splice(this.group.screens.indexOf(this),1),jQuery.extend(a.on_write,this.group.on_write),a.on_write=a.on_write.filter(function(a,b,c){return b==c.indexOf(a)}),this.group.parent&&!a.parent&&(a.parent=this.group.parent)}a.screens.push(this),this.tree_states_done=[],this.group=a,this.model=a.model,jQuery.isEmptyObject(a)?this.set_current_record(null):this.set_current_record(a[0]),this.group.add_fields(b)},new_group:function(a){var b=new Sao.Group(this.model,this.context,[]);b.set_readonly(this.attributes.readonly||!1),a&&b.load(a),this.set_group(b)},set_current_record:function(a){this.current_record=a,this.tab&&(a?(a.get_attachment_count().always(this.tab.attachment_count.bind(this.tab)),a.get_unread_note().always(this.tab.update_unread_note.bind(this.tab))):(this.tab.attachment_count(0),this.tab.update_unread_note(0)),this.tab.record_message())},display:function(a){var b=[];if(this.current_record&&~this.current_record.group.indexOf(this.current_record)||(jQuery.isEmptyObject(this.group)||"calendar"==this.current_view.view_type?this.current_record=null:this.current_record=this.group[0]),this.views){var c=this.search_active(~["tree","graph","calendar"].indexOf(this.current_view.view_type));b.push(c);for(var d=0;d<this.views.length;d++)this.views[d]&&b.push(this.views[d].display())}return jQuery.when.apply(jQuery,b).then(function(){this.set_tree_state(),this.set_current_record(this.current_record),a&&this.set_cursor(!1,!1)}.bind(this))},display_next:function(){var a=this.current_view;if(a.set_value(),this.set_cursor(!1,!1),~["tree","form"].indexOf(a.view_type)&&this.current_record&&this.current_record.group){for(var b=this.current_record.group,c=this.current_record;b;){var d=b.indexOf(c);if(d<b.length-1){c=b[d+1];break}if(!b.parent||c.group.model_name!=b.parent.group.model_name)break;c=b.parent,b=b.parent.group}this.set_current_record(c)}else this.set_current_record(this.group[0]);this.set_cursor(!1,!1),a.display()},display_previous:function(){var a=this.current_view;if(a.set_value(),this.set_cursor(!1,!1),~["tree","form"].indexOf(a.view_type)&&this.current_record&&this.current_record.group){for(var b=this.current_record.group,c=this.current_record;b;){var d=b.indexOf(c);if(d>0){c=b[d-1];break}if(!b.parent||c.group.model_name!=b.parent.group.model_name)break;c=b.parent,b=b.parent.group}this.set_current_record(c)}else this.set_current_record(this.group[0]);this.set_cursor(!1,!1),a.display()},default_row_activate:function(){"tree"==this.current_view.view_type&&1==this.current_view.attributes.keyword_open?Sao.Action.exec_keyword("tree_open",{model:this.model_name,id:this.get_id(),ids:[this.get_id()]},jQuery.extend({},this.context),!1):this.modified()||this.switch_view("form")},get_id:function(){if(this.current_record)return this.current_record.id},new_:function(a,b){var c=this.current_view;void 0===a&&(a=!0);var d=jQuery.when();if("calendar"==this.current_view.view_type){var e=this.current_view.date;d=this.switch_view("form")}return this.current_view&&("tree"==this.current_view.view_type&&!this.current_view.editable||"graph"==this.current_view.view_type)&&(d=this.switch_view("form")),d.then(function(){var d;d=this.current_record?this.current_record.group:this.group;var f,g=d.new_(!1,void 0,b);return f=a?g.default_get(b):jQuery.when(),f.then(function(){return d.add(g,this.new_model_position()),this.set_current_record(g),"calendar"==c.view_type&&c.set_default_date(g,e),this.display().done(function(){this.set_cursor(!0,!0)}.bind(this)),g}.bind(this))}.bind(this))},new_model_position:function(){var a=-1;return this.current_view&&"tree"==this.current_view.view_type&&"top"==this.current_view.attributes.editable&&(a=0),a},set_on_write:function(a){a&&(~this.group.on_write.indexOf(a)||this.group.on_write.push(a))},cancel_current:function(){var a=[];return this.current_record&&(this.current_record.cancel(),this.current_record.id<0&&a.push(this.remove(!1,!1,!1,[this.current_record]))),jQuery.when.apply(jQuery,a)},save_current:function(){var a=this.current_record;if(!a){if("tree"!=this.current_view.view_type||jQuery.isEmptyObject(this.group))return jQuery.when();this.set_current_record(this.group[0])}this.current_view.set_value();var b=this.current_view.get_fields(),c=a.get_path(this.group),d=jQuery.Deferred();"tree"==this.current_view.view_type?d=this.group.save():a.validate(b).then(function(b){b?a.save().then(d.resolve,d.reject):(this.current_view.display().done(this.set_cursor.bind(this)),d.reject())}.bind(this));var e=jQuery.Deferred();return d=d.then(function(){return c&&a.id&&c.splice(-1,1,[c[c.length-1][0],a.id]),this.group.get_by_path(c).then(function(a){this.set_current_record(a)}.bind(this))}.bind(this)),d.then(function(){this.display().always(e.resolve)}.bind(this),function(){this.display().always(e.reject)}.bind(this)),e.promise()},set_cursor:function(a,b){this.current_view&&~["tree","form"].indexOf(this.current_view.view_type)&&this.current_view.set_cursor(a,b)},modified:function(){var a=function(a){return a.has_changed()||a.id<0};if("tree"!=this.current_view.view_type){if(this.current_record&&a(this.current_record))return!0}else if(this.group.some(a))return!0;return!1},unremove:function(){var a=this.current_view.selected_records();a.forEach(function(a){a.group.unremove(a)})},remove:function(a,b,c,d){var e=jQuery.when();if(d=d||this.current_view.selected_records(),jQuery.isEmptyObject(d))return e;a&&(e=this.model.delete_(d));var f=d[0],g=f.group,h=g.indexOf(f),i=f.get_path(this.group);return e.then(function(){d.forEach(function(a){a.group.remove(a,b,!0,c)});var e=[];if(a&&d.forEach(function(a){a.group.parent&&e.push(a.group.parent.save(!1)),~a.group.record_deleted.indexOf(a)&&a.group.record_deleted.splice(a.group.record_deleted.indexOf(a),1),~a.group.record_removed.indexOf(a)&&a.group.record_removed.splice(a.group.record_removed.indexOf(a),1)}),h>0){var f=g[h-1];i.splice(-1,1,[i[i.length-1][0],f.id])}else i.splice(-1,1);return jQuery.isEmptyObject(i)?this.group.length&&this.set_current_record(this.group[0]):e.push(this.group.get_by_path(i).then(function(a){this.set_current_record(a)}.bind(this))),jQuery.when.apply(jQuery,e).then(function(){this.display().done(function(){this.set_cursor()}.bind(this))}.bind(this))}.bind(this))},copy:function(){var a=jQuery.Deferred(),b=this.current_view.selected_records();return this.model.copy(b,this.context).then(function(b){this.group.load(b),jQuery.isEmptyObject(b)||this.set_current_record(this.group.get(b[0])),this.display().always(a.resolve)}.bind(this),a.reject),a.promise()},search_active:function(a){return a&&!this.group.parent?(this.screen_container.set_screen(this),this.screen_container.show_filter()):this.screen_container.hide_filter(),jQuery.when()},domain_parser:function(){var a,b,c;if(a=this.current_view?this.current_view.view_id:null,a in this._domain_parser)return this._domain_parser[a];a in this.fields_view_tree?b=this.fields_view_tree[a]:(this.model.execute("fields_view_get",[!1,"tree"],this.context).then(function(b){this.fields_view_tree[a]=b,c.update_fields(b.fields)}.bind(this)),b={},b.fields={});var d=jQuery.extend({},b.fields),e=function(a){return function(b){a.selection=b}};for(var f in d){var g=d[f];"selection"!=g.type&&"reference"!=g.type||g.selection instanceof Array||this.get_selection(g).then(e(g))}if("arch"in b){var h=jQuery(jQuery.parseXML(b.arch)),i=h.find("tree").children().filter(function(a,b){return"field"==b.tagName}).map(function(a,b){return b.getAttribute("name")}),j={};i.each(function(a,b){j[b]=d[b]}),d=j}[["id",Sao.i18n.gettext("ID"),"integer"],["create_uid",Sao.i18n.gettext("Creation User"),"many2one"],["create_date",Sao.i18n.gettext("Creation Date"),"datetime"],["write_uid",Sao.i18n.gettext("Modification User"),"many2one"],["write_date",Sao.i18n.gettext("Modification Date"),"datetime"]].forEach(function(a){var b=a[0],c=a[1],e=a[2];b in d||(d[b]={string:c,name:b,type:e},"datetime"==e&&(d[b].format='"%H:%M:%S"'))});var k=jQuery.extend({},this.model.session.context,this.context);return c=new Sao.common.DomainParser(d,k),this._domain_parser[a]=c,c},get_selection:function(a){var b,c=a.selection_change_with;if(jQuery.isEmptyObject(c))b=this.model.execute(a.selection,[]);else{var d={};c.forEach(function(a){d[a]=null}),b=this.model.execute(a.selection,[d])}return b.then(function(a){return a.sort(function(a,b){return a[1].localeCompare(b[1])})})},search_prev:function(a){this.offset-=this.limit,this.search_filter(a)},search_next:function(a){this.offset+=this.limit,this.search_filter(a)},invalid_message:function(a){a||(a=this.current_record);var b={};for(var c in a.model.fields){var d=a.model.fields[c];b[c]=d.description}var e=new Sao.common.DomainParser(b),f=[],g=a.invalid_fields();return Object.keys(g).sort().forEach(function(b){var c=g[b],d=a.model.fields[b].description.string;"required"==c||Sao.common.compare(c,[[b,"!=",null]])?f.push(Sao.i18n.gettext('"%1" is required',d)):"domain"==c?f.push(Sao.i18n.gettext('"%1" is not valid according to its domain',d)):"children"==c?f.push(Sao.i18n.gettext('The values of "%1" are not valid',d)):e.stringable(c)?f.push(e.string(c)):f.push(Sao.i18n.gettext('"%1" is not valid according to its domain'),d)}),f.length>5&&(f.splice(5,f.length),f.push("...")),f.join("\n")},get:function(){return this.current_record?(this.current_view.set_value(),this.current_record.get()):null},get_on_change_value:function(){return this.current_record?(this.current_view.set_value(),this.current_record.get_on_change_value()):null},reload:function(a,b){this.group.reload(a),b&&this.group.written(a),this.group.parent&&this.group.parent.root_parent().reload(),this.display()},get_buttons:function(){var a=this.current_view.selected_records();if(jQuery.isEmptyObject(a))return[];var b=this.current_view.get_buttons();return a.forEach(function(a){b=b.filter(function(b){if(a.group.get_readonly()||a.readonly())return!1;if("instance"===b.attributes.type)return!1;var c=a.expr_eval(b.attributes.states||{});return!(c.invisible||c.readonly)})}),b},button:function(a){var b,c=function(a){this.reload(b,!0),"string"==typeof a?this.client_action(a):a&&Sao.Action.execute(a,{model:this.model_name,id:this.current_record.id,ids:b},null,this.context)},d=this.current_view.selected_records();this.current_view.set_value();for(var e=this.current_view.get_fields(),f=[],g=function(a){return function(){this.display(!0),a.validate(e)}.bind(this)}.bind(this),h=0;h<d.length;h++){var i=d[h],j=i.expr_eval(a.states||{}).pre_validate||[];f.push(i.validate(e,!1,j))}jQuery.when.apply(jQuery,f).then(function(){for(var e,f=0;f<d.length;f++){e=d[f];var h=arguments[f];if(!h)return void Sao.common.warning.run(this.invalid_message(e),Sao.i18n.gettext("Pre-validation")).then(g(e))}var i=jQuery.when();void 0!==a.confirm&&(i=Sao.common.sur.run(a.confirm)),i.then(function(){var e=this.current_record;if("instance"===a.type){var g=e.expr_eval(a.change||[]),h=e._get_on_change_args(g);e.model.execute(a.name,[h],this.context).then(function(a){e.set_on_change(a),e.group.root_group().screens.forEach(function(a){a.display()})})}else e.save(!1).done(function(){var g=jQuery.extend({},this.context);for(g._timestamp={},b=[],f=0;f<d.length;f++)e=d[f],jQuery.extend(g._timestamp,e.get_timestamp()),b.push(e.id);e.model.execute(a.name,[b],g).then(c.bind(this))}.bind(this))}.bind(this))}.bind(this))},client_action:function(a){var b=Sao.common.MODELACCESS.get(this.model_name);if("new"==a)b.create&&this.new_();else if("delete"==a)b.delete&&this.remove(!this.group.parent,!1,!this.group.parent);else if("remove"==a)b.write&&b.read&&this.group.parent&&this.remove(!1,!0,!1);else if("copy"==a)b.create&&this.copy();else if("next"==a)this.display_next();else if("previous"==a)this.display_previous();else if("close"==a)Sao.Tab.close_current();else if(a.startsWith("switch")){var c=a.split(" ")[1];this.switch_view(c)}else"reload"==a?~["tree","graph","calendar"].indexOf(this.current_view.view_type)&&!this.group.parent&&this.search_filter():"reload menu"==a?Sao.get_preferences().then(function(a){Sao.menu(a)}):"reload context"==a&&Sao.get_preferences()},save_tree_state:function(a){var b,c=[];a=void 0===a||a;var d,e,f,g,h,i,j=this.group.parent?this.group.parent.id:null,k=this.group.parent?this.group.parent._timestamp:null;for(d=0,e=this.views.length;d<e;d++)if(f=this.views[d],"form"==f.view_type){for(var l in f.widgets)if(f.widgets.hasOwnProperty(l))for(g=f.widgets[l],h=0,i=g.length;h<i;h++)g[h].screen&&(b=g[h].screen.save_tree_state(a),c.push(b));1==this.views.length&&this.current_record&&(j in this.tree_states||(this.tree_states[j]={}),this.tree_states[j][f.children_field||null]=[k,[],[[this.current_record.id]]])}else if("tree"==f.view_type){var m=f.get_expanded_paths(),n=f.get_selected_paths();if(j in this.tree_states||(this.tree_states[j]={}),this.tree_states[j][f.children_field||null]=[k,m,n],a&&f.attributes.tree_state){var o=new Sao.Model("ir.ui.view_tree_state");b=o.execute("set",[this.model_name,this.get_tree_domain(j),f.children_field,JSON.stringify(m),JSON.stringify(n)],{}),c.push(b)}}return jQuery.when.apply(jQuery,c)},get_tree_domain:function(a){var b;return b=a?(this.domain||[]).concat([[this.exclude_field,"=",a]]):this.domain,JSON.stringify(Sao.rpc.prepareObject(b))},set_tree_state:function(){var a,b,c,d,e,f=this.current_view;~["tree","form"].indexOf(f.view_type)&&(~this.tree_states_done.indexOf(f)||("form"!=f.view_type||jQuery.isEmptyObject(this.tree_states_done))&&("tree"!=f.view_type||f.attributes.tree_state)&&(a=this.group.parent?this.group.parent.id:null,a<0||(b=parent?parent._timestamp:null,a in this.tree_states||(this.tree_states[a]={}),c=this.tree_states[a][f.children_field||null],c&&b!=c[0]&&(c=void 0),void 0===c?(e=new Sao.Model("ir.ui.view_tree_state"),d=e.execute("get",[this.model_name,this.get_tree_domain(a),f.children_field],{}).then(function(a){return[b,JSON.parse(a[0]),JSON.parse(a[1])]})):d=jQuery.when(c),d.done(function(b){var c,d,e;if(this.tree_states[a][f.children_field||null]=b,c=b[1],d=b[2],"tree"==f.view_type)f.display(d,c);else if(!jQuery.isEmptyObject(d)){for(var g=0;g<d[0].length;g++){var h=this.group.get(d[0][g]);if(!h)break;e=h}e&&e!=this.current_record&&(this.set_current_record(e),f.display())}}.bind(this)),this.tree_states_done.push(f))))}})}(),function(){"use strict";Sao.View=Sao.class_(Object,{init:function(a,b){this.screen=a,this.view_type=null,this.el=null,this.view_id=null,this.fields={};var c=b.children()[0].attributes;this.attributes={};for(var d=0,e=c.length;d<e;d++){var f=c[d];this.attributes[f.name]=f.value}a.set_on_write(this.attributes.on_write)},set_value:function(){},get_fields:function(){return Object.keys(this.fields)},selected_records:function(){return[]},get_buttons:function(){return[]}}),Sao.View.idpath2path=function(a,b){var c,d=[];if(!b)return[];for(var e=0,f=a.rows.length;e<f;e++)if(a.rows[e].record.id==b[0]){d.push(e),c=Sao.View.idpath2path(a.rows[e],b.slice(1,b.length)),d=d.concat(c);break}return d},Sao.View.parse=function(a,b,c){switch(b.children().prop("tagName")){case"tree":return new Sao.View.Tree(a,b,c);case"form":return new Sao.View.Form(a,b);case"graph":return new Sao.View.Graph(a,b);case"calendar":return new Sao.View.Calendar(a,b)}},Sao.View.resize=function(a){a||(a=jQuery(document)),a.find(".treeview").each(function(){var a=jQuery(this);a.css("width","100%"),a.children(".tree").css("table-layout","fixed")}),a.find(".treeview").each(function(){var a=jQuery(this);a.width()&&(a.css("width",a.width()),a.children(".tree").css("table-layout","auto"))})},jQuery(window).resize(function(){Sao.View.resize()})}(),function(){"use strict";Sao.View.Form=Sao.class_(Sao.View,{editable:!0,init:function(a,b){Sao.View.Form._super.init.call(this,a,b),this.view_type="form",this.el=jQuery("<div/>",{class:"form"}),this.widgets={},this.widget_id=0,this.state_widgets=[],this.containers=[],this.notebooks=[];var c=b.children()[0],d=this.parse(a.model,c);this.el.append(d.el)},_parse_node:function(a,b,c,d,e){var f;switch(b.tagName){case"image":this._parse_image(a,b,c,d);break;case"separator":this._parse_separator(a,b,c,d);break;case"label":f=this._parse_label(a,b,c,d),d.name&&f&&(e[d.name]=f);break;case"newline":c.add_row();break;case"button":this._parse_button(b,c,d);break;case"notebook":this._parse_notebook(a,b,c,d);break;case"page":this._parse_page(a,b,c,d);break;case"field":if(f=this._parse_field(a,b,c,d),d.name in e&&f&&f.labelled){var g=e[d.name];g.el.uniqueId(),f.labelled.uniqueId(),f.labelled.attr("aria-labelledby",g.el.attr("id")),g.el.attr("for",f.labelled.attr("id"))}break;case"group":this._parse_group(a,b,c,d);break;case"hpaned":this._parse_paned(a,b,c,d,"horizontal");break;case"vpaned":this._parse_paned(a,b,c,d,"vertical");break;case"child":this._parse_child(a,b,c,d)}},parse:function(a,b,c){void 0===c&&(c=new Sao.View.Form.Container(Number(b.getAttribute("col")||4)),this.containers.push(c));var d={},e=function(b,e){for(var f={},g=0,h=e.attributes.length;g<h;g++){var i=e.attributes[g];f[i.name]=i.value}["readonly","invisible"].forEach(function(a){f[a]&&(f[a]=1==f[a])}),["yexpand","yfill","xexpand","xfill","colspan"].forEach(function(a){f[a]&&(f[a]=Number(f[a]))}),this._parse_node(a,e,c,f,d)};return jQuery(b).children().each(e.bind(this)),c},_parse_image:function(a,b,c,d){var e=new Sao.View.Form.Image_(d);this.state_widgets.push(e),c.add(d,e)},_parse_separator:function(a,b,c,d){var e=d.name,f=d.string;e in a.fields&&(!d.states&&e in a.fields&&(d.states=a.fields[e].description.states),f||(f=a.fields[e].description.string));var g=new Sao.View.Form.Separator(f,d);this.state_widgets.push(g),c.add(d,g)},_parse_label:function(a,b,c,d){var e=d.name,f=d.string;if(void 0===d.xexpand&&(d.xexpand=0),e in a.fields){if(e==this.screen.exclude_field)return void c.add(d);!d.states&&e in a.fields&&(d.states=a.fields[e].description.states),f||(f=a.fields[e].description.string+": "),void 0===d.xalign&&(d.xalign=1)}var g;return f&&(g=new Sao.View.Form.Label(f,d),this.state_widgets.push(g)),c.add(d,g),g},_parse_button:function(a,b,c){var d=new Sao.common.Button(c);this.state_widgets.push(d),b.add(c,d),d.el.click(d,this.button_clicked.bind(this))},_parse_notebook:function(a,b,c,d){void 0===d.colspan&&(d.colspan=4);var e=new Sao.View.Form.Notebook(d);this.notebooks.push(e),this.state_widgets.push(e),c.add(d,e),this.parse(a,b,e)},_parse_page:function(a,b,c,d){d.string;if(d.name in a.fields){var e=a.fields[d.name];if(d.name==this.screen.exclude_field)return;["states","string"].forEach(function(a){void 0===d[a]&&void 0!==e.description[a]&&(d[a]=e.description[a])})}var f=this.parse(a,b);f=new Sao.View.Form.Page(c.add(f.el,d.string),d),this.state_widgets.push(f)},_parse_field:function(a,b,c,d){var e=d.name;if(!(e in a.fields)||e==this.screen.exclude_field)return void c.add(d);d.widget||(d.widget=a.fields[e].description.type);var f=["relation","domain","selection","help","relation_field","string","views","add_remove","sort","context","size","filename","autocomplete","translate","create","delete","selection_change_with","schema_model"];for(var g in f){var h=f[g];h in a.fields[e].description&&null===b.getAttribute(h)&&(d[h]=a.fields[e].description[h])}var i=Sao.View.form_widget_get(d.widget);if(!i)return void c.add(d);var j=new i(e,a,d);return j.position=this.widget_id+=1,j.view=this,c.add(d,j),void 0===this.widgets[e]&&(this.widgets[e]=[]),this.widgets[e].push(j),this.fields[e]=!0,j},_parse_group:function(a,b,c,d){var e=new Sao.View.Form.Group(d);e.add(this.parse(a,b)),this.state_widgets.push(e),c.add(d,e)},_parse_paned:function(a,b,c,d,e){void 0===d.yexpand&&(d.yexpand=!0),void 0===d.yfill&&(d.yfill=!0);var f=new Sao.common.Paned(e);c.add(d,f),this.parse(a,b,f)},_parse_child:function(a,b,c,d){var e,f=this.parse(a,b);e=c.get_child1().children().length?c.get_child2():c.get_child1(),e.append(f.el)},get_buttons:function(){var a=[];for(var b in this.state_widgets){var c=this.state_widgets[b];c instanceof Sao.common.Button&&a.push(c)}return a},display:function(){var a,b,c=this.screen.current_record,d={};if(c){var e=[];for(b in c.model.fields)a=c.model.fields[b],e.push([b,a.description.loading||"eager"]);e.sort(function(a,b){return a[1].localeCompare(b[1])}),e.forEach(function(a){var b=a[0];d[b]=c.load(b)})}var f=function(a,b,c){var e=jQuery.when();c in d&&(e=d[c]),e.done(function(){b.set_state(a)})},g=function(a,b,c){return function(e){var f=jQuery.when();c in d&&(f=d[c]),f.done(function(){e.display(a,b)})}};for(b in this.widgets){var h=this.widgets[b];a=null,c&&(a=c.model.fields[b]),a&&f(c,a,b),h.forEach(g(c,a,b))}return jQuery.when.apply(jQuery,jQuery.map(d,function(a){
-return a})).done(function(){var a;for(a in this.state_widgets){var b=this.state_widgets[a];b.set_state(c)}for(a in this.containers){var d=this.containers[a];d.resize()}Sao.View.resize(this.el)}.bind(this))},set_value:function(){var a=this.screen.current_record;if(a){var b=function(b){b.set_value(a,this)};for(var c in this.widgets)if(c in a.model.fields){var d=this.widgets[c],e=a.model.fields[c];d.forEach(b,e)}}},button_clicked:function(a){var b=a.data;b.el.prop("disabled",!0);try{this.screen.button(b.attributes)}finally{b.el.prop("disabled",!1)}},selected_records:function(){return this.screen.current_record?[this.screen.current_record]:[]},set_cursor:function(a,b){var c,d,e,f,g,h,i,j,k,l,m=jQuery(document.activeElement),n=m.closest(this.el)>0;if(b||n){if(b)for(c=0;c<this.notebooks.length;c++)g=this.notebooks[c],g.set_current_page(0);this.attributes.cursor in this.widgets?f=Sao.common.find_focusable_child(this.widgets[this.attributes.cursor][0].el):(h=Sao.common.find_focusable_child(this.el),h&&h.focus())}var o=this.screen.current_record;if(o){var p=[],q=this.el.find(".has-error"),r=o.invalid_fields();for(d in r)for(i=this.widgets[d],c=0;c<q.length;c++)for(j=jQuery(q[c]),e=0;e<i.length;e++)if(j.closest(i[e].el).length>0){p.push(j);break}p.length>0&&(f=Sao.common.find_first_focus_widget(this.el,p))}if(f){for(c=0;c<this.notebooks.length;c++)for(g=this.notebooks[c],k=g.get_n_pages(),e=0;e<k;e++)if(h=g.get_nth_page(e),l=jQuery(f).closest(h).length>0){g.set_current_page(e);break}jQuery(f).find("input,select,textarea").focus()}}}),Sao.View.Form.Container=Sao.class_(Object,{init:function(a){void 0===a&&(a=4),this.col=a,this.el=jQuery("<table/>",{class:"form-container responsive responsive-noheader"}),this.add_row()},add_row:function(){this.el.append(jQuery("<tr/>"))},rows:function(){return this.el.children().children("tr")},row:function(){return this.rows().last()},add:function(a,b){var c=a.colspan;void 0===c&&(c=1);var d=a.xfill;void 0===d&&(d=1);var e=a.xexpand;void 0===e&&(e=1);var f=0,g=this.row();g.children().map(function(a,b){f+=Number(jQuery(b).attr("colspan")||1)}),f+c>this.col&&(this.add_row(),g=this.row());var h;b&&(h=b.el);var i=jQuery("<td/>",{colspan:c,class:b?b.class_||"":""}).append(h);g.append(i),b&&(a.yfill&&i.css("vertical-align","top"),void 0!==a.xalign&&i.css("text-align",a.xalign>=.5?"right":"left"),e&&(i.addClass("xexpand"),i.css("width","100%")),d&&(i.addClass("xfill"),e&&h.css("width","100%")),a.help&&(b.el.data("toggle","tooltip"),b.el.attr("title",a.help),b.el.tooltip()))},resize:function(){var a,b,c=this.rows().toArray(),d=[],e=this.col,f=!1,g=function(b){b=jQuery(b);var c=[];return a=0,b.children().map(function(){var b=jQuery(this),d=Math.min(Number(b.attr("colspan")),e);b.hasClass("xexpand")&&!jQuery.isEmptyObject(b.children())&&"none"!=b.children(":not(.tooltip)").css("display")&&c.push([b,a]),a+=d}),c};c.sort(function(a,b){if(a=g(a),b=g(b),a.length==b.length){var c=function(a,b){var c=b[0],d=Math.min(Number(c.attr("colspan")),e);return a+d};return a.reduce(c,0)-b.reduce(c,0)}return b.length-a.length}),c.forEach(function(c){c=jQuery(c);var h=g(c),i=100/h.length;h.forEach(function(c){var f=c[0];a=c[1];var g=Math.min(Number(f.attr("colspan")),e),h=0;for(b=0;b<g;b++)h+=d[a+b]||0;for(b=0;b<g;b++)if(h){if(h>i){var j=h-i;d[a+b]&&(d[a+b]-=j/(h/d[a+b]))}}else d[a+b]=i/g}),jQuery.isEmptyObject(h)||(f=!0)}),c.forEach(function(c){c=jQuery(c),a=0,c.children().map(function(){var c=jQuery(this),f=Math.min(Number(c.attr("colspan")),e);if(c.hasClass("xexpand")&&"none"!=c.children(":not(.tooltip)").css("display")){var g=0;for(b=0;b<f;b++)g+=d[a+b]||0;c.css("width",g+"%")}else c.css("width","");"none"==c.children().css("display")?c.css("visibility","collapse"):c.css("visibility","visible"),a+=f})}),f?this.el.css("width","100%"):this.el.css("width","")}}),Sao.View.Form.StateWidget=Sao.class_(Object,{init:function(a){this.attributes=a},set_state:function(a){var b;b=a?a.expr_eval(this.attributes.states||{}):{};var c=b.invisible;void 0===c&&(c=this.attributes.invisible),c?this.hide():this.show()},show:function(){this.el.show()},hide:function(){this.el.hide()}}),Sao.View.Form.LabelMixin=Sao.class_(Sao.View.Form.StateWidget,{set_state:function(a){Sao.View.Form.LabelMixin._super.set_state.call(this,a);var b;if(this.attributes.name&&a&&(b=a.model.fields[this.attributes.name]),void 0===this.attributes.string&&b){var c="";a&&(c=b.get_client(a)||""),this.label_el.val(c)}var d;d=a?a.expr_eval(this.attributes.states||{}):{},b&&b.description.readonly||d.readonly,Sao.common.apply_label_attributes(this.label_el,b&&b.description.readonly||d.readonly,b&&b.description.required||d.required)}}),Sao.View.Form.Separator=Sao.class_(Sao.View.Form.LabelMixin,{init:function(a,b){Sao.View.Form.Separator._super.init.call(this,b),this.el=jQuery("<div/>",{class:"form-separator"}),this.label_el=jQuery("<label/>"),a&&this.label_el.text(a),this.el.append(this.label_el),this.el.append(jQuery("<hr/>"))}}),Sao.View.Form.Label=Sao.class_(Sao.View.Form.LabelMixin,{class_:"form-label",init:function(a,b){Sao.View.Form.Label._super.init.call(this,b),this.el=this.label_el=jQuery("<label/>",{text:a,class:this.class_})}}),Sao.View.Form.Notebook=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-notebook",init:function(a){Sao.View.Form.Notebook._super.init.call(this,a),this.el=jQuery("<div/>",{class:this.class_}),this.nav=jQuery("<ul/>",{class:"nav nav-tabs",role:"tablist"}).appendTo(this.el),this.panes=jQuery("<div/>",{class:"tab-content"}).appendTo(this.el),this.selected=!1},add:function(a,b){var c=jQuery("<div/>",{role:"tabpanel",class:"tab-pane"}).uniqueId(),d=c.attr("id"),e=jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{"aria-controls":d,role:"tab","data-toggle":"tab",href:"#"+d}).append(b).on("shown.bs.tab",function(){Sao.View.resize(a)})).appendTo(this.nav);return c.html(a).appendTo(this.panes),this.selected||(e.addClass("active"),c.addClass("active"),this.selected=!0),e},set_current_page:function(a){var b=this.nav.find('li[role="presentation"]:eq('+a+") a");b.tab("show")},get_n_pages:function(){return this.nav.find("li[role='presentation']").length},get_nth_page:function(a){return jQuery(this.panes.find("div[role='tabpanel']")[a])}}),Sao.View.Form.Page=Sao.class_(Sao.View.Form.StateWidget,{init:function(a,b){Sao.View.Form.Page._super.init.call(this,b),this.el=a}}),Sao.View.Form.Group=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-group_",init:function(a){Sao.View.Form.Group._super.init.call(this,a),this.el=jQuery("<div/>",{class:this.class_})},add:function(a){this.el.append(a.el)}}),Sao.View.Form.Image_=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-image_",init:function(a){Sao.View.Form.Image_._super.init.call(this,a),this.el=jQuery("<div/>",{class_:this.class_}),this.img=jQuery("<img/>",{class:"center-block"}).appendTo(this.el),Sao.common.ICONFACTORY.register_icon(a.name).done(function(a){this.img.attr("src",a)}.bind(this))}}),Sao.View.form_widget_get=function(a){switch(a){case"char":return Sao.View.Form.Char;case"password":return Sao.View.Form.Password;case"date":return Sao.View.Form.Date;case"datetime":return Sao.View.Form.DateTime;case"time":return Sao.View.Form.Time;case"timedelta":return Sao.View.Form.TimeDelta;case"integer":case"biginteger":return Sao.View.Form.Integer;case"float":case"numeric":return Sao.View.Form.Float;case"selection":return Sao.View.Form.Selection;case"boolean":return Sao.View.Form.Boolean;case"text":return Sao.View.Form.Text;case"richtext":return Sao.View.Form.RichText;case"many2one":return Sao.View.Form.Many2One;case"one2one":return Sao.View.Form.One2One;case"reference":return Sao.View.Form.Reference;case"one2many":return Sao.View.Form.One2Many;case"many2many":return Sao.View.Form.Many2Many;case"binary":return Sao.View.Form.Binary;case"multiselection":return Sao.View.Form.MultiSelection;case"image":return Sao.View.Form.Image;case"url":return Sao.View.Form.URL;case"email":return Sao.View.Form.Email;case"callto":return Sao.View.Form.CallTo;case"sip":return Sao.View.Form.SIP;case"progressbar":return Sao.View.Form.ProgressBar;case"dict":return Sao.View.Form.Dict;case"pyson":return Sao.View.Form.PYSON}},Sao.View.Form.Widget=Sao.class_(Object,{init:function(a,b,c){this.field_name=a,this.model=b,this.view=null,this.attributes=c,this.el=null,this.position=0,this.visible=!0,this.labelled=null},display:function(a,b){var c=this.attributes.readonly,d=this.attributes.invisible,e=this.attributes.required;if(!b)return void 0===c&&(c=!0),void 0===d&&(d=!1),void 0===e&&(e=!1),this.set_readonly(c),this.set_invisible(d),void this.set_required(e);var f=b.get_state_attrs(a);void 0===c&&(c=f.readonly,void 0===c&&(c=!1)),void 0===e&&(e=f.required,void 0===e&&(e=!1)),this.view.screen.attributes.readonly&&(c=!0),this.set_readonly(c),this.set_required(e);var g=f.invalid;!c&&g?this.el.addClass("has-error"):this.el.removeClass("has-error"),void 0===d&&(d=b.get_state_attrs(a).invisible,void 0===d&&(d=!1)),this.set_invisible(d)},record:function(){if(this.view&&this.view.screen)return this.view.screen.current_record},field:function(){var a=this.record();if(a)return a.model.fields[this.field_name]},focus_out:function(){this.field()&&this.visible&&this.set_value(this.record(),this.field())},set_value:function(a,b){},set_readonly:function(a){this._readonly=a,this.el.prop("disabled",a)},set_required:function(a){},set_invisible:function(a){this.visible=!a,a?this.el.hide():this.el.show()}}),Sao.View.Form.TranslateDialog=Sao.class_(Object,{init:function(a,b){var c=new Sao.Dialog(Sao.i18n.gettext("Translate"),this.class_,this,a);c.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),this.languages=a,this.read(b,c),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c)}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(this.write.bind(this,b,c)).appendTo(c.footer),c.content.submit(function(a){a.preventDefault(),c.footer.find("button.btn-primary").first().click()}),c.modal.modal("show"),c.modal.on("shown.bs.modal",function(){c.modal.find("input,select").filter(":visible").first().focus()})},close:function(a){a.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),a.modal.modal("hide")},read:function(a,b){this.languages.forEach(function(c){var d={};d.language=c.code;var e,f=[[a.record().id],[a.field_name],d],g={method:"model."+a.model.name+".read",params:f},h=jQuery("<div/>",{class:"row form-group"}),i=a.translate_widget();i.attr("data-lang-id",c.id);var j=jQuery("<input/>",{type:"checkbox",title:Sao.i18n.gettext("Edit")});a._readonly&&j.attr("disabled",!0);var k=jQuery("<input/>",{type:"checkbox",disabled:!0,title:Sao.i18n.gettext("Fuzzy")}),l=Sao.rpc(g,a.model.session).then(function(b){e=b[0][a.field_name]}.bind(this));f=[[a.record().id],[a.field_name],d],d.fuzzy_translation=!0,g={method:"model."+a.model.name+".read",params:f},l.then(function(){Sao.rpc(g,a.model.session).then(function(b){e=b[0][a.field_name],a.translate_widget_set(i,e),k.attr("checked",b[0].name!=e)}.bind(this))}.bind(this)),j.click(function(){a.translate_widget_set_readonly(i)}),b.body.append(h),h.append(jQuery("<div/>",{class:"col-sm-3"}).append(c.name)),h.append(jQuery("<div/>",{class:"col-sm-6"}).append(i)),h.append(jQuery("<div/>",{class:"col-sm-1"}).append(j)),h.append(jQuery("<div/>",{class:"col-sm-1"}).append(k))}.bind(this))},write:function(a,b){var c=[];this.languages.forEach(function(b){var d=jQuery("[data-lang-id="+b.id+"]");if(!d.attr("readonly")){var e=a.model.session.context.language,f={};f.language=b.code,f.fuzzy_translation=!1;var g={};g[a.field_name]=d.val();var h=[[a.record().id],g,f],i={method:"model."+a.model.name+".write",params:h},j=Sao.rpc(i,a.model.session).then(function(){b.code==e&&a.view.display()});c.push(j)}}.bind(this)),this.close(b),jQuery.when.apply(jQuery,c).then(function(){a.record().cancel()})}}),Sao.View.Form.TranslateMixin={},Sao.View.Form.TranslateMixin.init=function(){this.translate=Sao.View.Form.TranslateMixin.translate.bind(this),this.translate_widget_set_readonly=Sao.View.Form.TranslateMixin.translate_widget_set_readonly.bind(this),this.translate_widget_set=Sao.View.Form.TranslateMixin.translate_widget_set.bind(this)},Sao.View.Form.TranslateMixin.translate=function(){if(this.record().id<0||this.record().has_changed()){var a=Sao.i18n.gettext("You need to save the record before adding translations.");return void Sao.common.message.run(a)}var b=this.model.session,c=[[["translatable","=","true"]]],d={method:"model.ir.lang.search",params:c.concat({})};Sao.rpc(d,b).then(function(a){if(jQuery.isEmptyObject(a))return void Sao.common.message.run(Sao.i18n.gettext("No other language available."));var c=[a,["code","name"]],d={method:"model.ir.lang.read",params:c.concat({})};Sao.rpc(d,b).then(function(a){new Sao.View.Form.TranslateDialog(a,this)}.bind(this))}.bind(this))},Sao.View.Form.TranslateMixin.translate_widget_set_readonly=function(a,b){a.attr("readonly")?a.removeAttr("readonly"):a.attr("readonly",!0)},Sao.View.Form.TranslateMixin.translate_widget_set=function(a,b){a.val(b||"")},Sao.View.Form.Char=Sao.class_(Sao.View.Form.Widget,{class_:"form-char",init:function(a,b,c){if(Sao.View.Form.Char._super.init.call(this,a,b,c),Sao.View.Form.TranslateMixin.init.call(this),this.el=jQuery("<div/>",{class:this.class_}),this.group=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el),this.input=this.labelled=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(this.group),c.autocomplete&&(this.datalist=jQuery("<datalist/>").appendTo(this.el),this.datalist.uniqueId(),this.input.attr("list",this.datalist.attr("id"))),this.el.change(this.focus_out.bind(this)),c.size||this.group.css("width","100%"),this.attributes.translate){var d=jQuery("<button/>",{class:"btn btn-default btn-sm form-control",type:"button","aria-label":Sao.i18n.gettext("Translate")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-flag"})).appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(this.group));d.click(this.translate.bind(this))}},get_client_value:function(a,b){var c="";return b&&(c=b.get_client(a)),c},display:function(a,b){if(Sao.View.Form.Char._super.display.call(this,a,b),this.datalist){this.datalist.children().remove();var c=[];a&&(c=a.autocompletion[this.field_name]||[]),c.forEach(function(a){jQuery("<option/>",{value:a}).appendTo(this.datalist)}.bind(this))}var d="",e="100%";a&&(d=a.expr_eval(this.attributes.size),d>0&&(e=null)),this.input.val(this.get_client_value(a,b)),this.input.attr("maxlength",d),this.input.attr("size",d),this.group.css("width",e)},set_value:function(a,b){b.set_client(a,this.input.val())},set_readonly:function(a){this.input.prop("readonly",a)},focus:function(){this.input.focus()},translate_widget:function(){return jQuery("<input/>",{class:"form-control",readonly:"readonly"})}}),Sao.View.Form.Password=Sao.class_(Sao.View.Form.Char,{class_:"form-password",init:function(a,b,c){Sao.View.Form.Password._super.init.call(this,a,b,c),this.input.prop("type","password")}}),Sao.View.Form.Date=Sao.class_(Sao.View.Form.Widget,{class_:"form-date",_width:"12em",init:function(a,b,c){Sao.View.Form.Date._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.date=this.labelled=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el),this.input=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(this.date),jQuery("<span/>",{class:"input-group-btn"}).append(jQuery("<button/>",{class:"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-calendar"}))).appendTo(this.date),this.date.datetimepicker({locale:moment.locale()}),this.date.css("width",this._width),this.date.on("dp.change",this.focus_out.bind(this))},get_format:function(a,b){return b.date_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isDate=!0),c},display:function(a,b){a&&b&&this.date.data("DateTimePicker").format(Sao.common.moment_format(this.get_format(a,b))),Sao.View.Form.Date._super.display.call(this,a,b);var c;c=a?b.get_client(a):null,this.date.data("DateTimePicker").date(c)},focus:function(){this.input.focus()},set_value:function(a,b){b.set_client(a,this.get_value(a,b))},set_readonly:function(a){this.date.find("button").prop("disabled",a),this.date.find("input").prop("readonly",a)}}),Sao.View.Form.DateTime=Sao.class_(Sao.View.Form.Date,{class_:"form-datetime",_width:"25em",get_format:function(a,b){return b.date_format(a)+" "+b.time_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isDateTime=!0),c}}),Sao.View.Form.Time=Sao.class_(Sao.View.Form.Date,{class_:"form-time",_width:"10em",get_format:function(a,b){return b.time_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isTime=!0),c}}),Sao.View.Form.TimeDelta=Sao.class_(Sao.View.Form.Widget,{class_:"form-timedelta",init:function(a,b,c){Sao.View.Form.TimeDelta._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.input=this.labelled=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(this.el),this.el.change(this.focus_out.bind(this))},display:function(a,b){if(Sao.View.Form.TimeDelta._super.display.call(this,a,b),a){var c=a.field_get_client(this.field_name);this.input.val(c||"")}else this.input.val("")},focus:function(){this.input.focus()},set_value:function(a,b){b.set_client(a,this.input.val())},set_readonly:function(a){this.input.prop("readonly",a)}}),Sao.View.Form.Integer=Sao.class_(Sao.View.Form.Char,{class_:"form-integer",init:function(a,b,c){Sao.View.Form.Integer._super.init.call(this,a,b,c),this.input.attr("type","text"),this.input.attr("width",8),this.group.css("width",""),this.factor=Number(c.factor||1)},set_value:function(a,b){b.set_client(a,this.input.val(),void 0,this.factor)},get_client_value:function(a,b){var c="";return b&&(c=b.get_client(a,this.factor)),c}}),Sao.View.Form.Float=Sao.class_(Sao.View.Form.Integer,{class_:"form-float"}),Sao.View.Form.Selection=Sao.class_(Sao.View.Form.Widget,{class_:"form-selection",init:function(a,b,c){Sao.View.Form.Selection._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.select=this.labelled=jQuery("<select/>",{class:"form-control input-sm"}),this.el.append(this.select),this.select.change(this.focus_out.bind(this)),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a,this.set_selection.bind(this))},update_selection:function(a,b,c){Sao.common.selection_mixin.update_selection.call(this,a,b,function(a){this.set_selection(a),c&&c()}.bind(this))},set_selection:function(a){var b=this.select;b.empty(),a.forEach(function(a){b.append(jQuery("<option/>",{value:JSON.stringify(a[0]),text:a[1]}))})},display_update_selection:function(a,b){this.update_selection(a,b,function(){if(!b)return void this.select.val("");for(var c,d=b.get(a),e=!1,f=0,g=this.selection.length;f<g;f++)if(this.selection[f][0]===d){e=!0;break}e?c=jQuery.when():(c=Sao.common.selection_mixin.get_inactive_selection.call(this,d),c.done(function(a){this.select.append(jQuery("<option/>",{value:JSON.stringify(a[0]),text:a[1],disabled:!0}))}.bind(this))),c.done(function(){this.select.val(JSON.stringify(d))}.bind(this))}.bind(this))},display:function(a,b){Sao.View.Form.Selection._super.display.call(this,a,b),this.display_update_selection(a,b)},focus:function(){this.select.focus()},value_get:function(){return JSON.parse(this.select.val())},set_value:function(a,b){var c=this.value_get();b.set_client(a,c)},set_readonly:function(a){this.select.prop("disabled",a)}}),Sao.View.Form.Boolean=Sao.class_(Sao.View.Form.Widget,{class_:"form-boolean",init:function(a,b,c){Sao.View.Form.Boolean._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.input=this.labelled=jQuery("<input/>",{type:"checkbox",class:"form-control input-sm"}).appendTo(this.el),this.input.change(this.focus_out.bind(this)),this.input.click(function(){return!jQuery(this).prop("readonly")})},display:function(a,b){Sao.View.Form.Boolean._super.display.call(this,a,b),a?this.input.prop("checked",a.field_get(this.field_name)):this.input.prop("checked",!1)},focus:function(){this.input.focus()},set_value:function(a,b){var c=this.input.prop("checked");b.set_client(a,c)},set_readonly:function(a){this.input.prop("readonly",a)}}),Sao.View.Form.Text=Sao.class_(Sao.View.Form.Widget,{class_:"form-text",init:function(a,b,c){if(Sao.View.Form.Text._super.init.call(this,a,b,c),Sao.View.Form.TranslateMixin.init.call(this),this.el=jQuery("<div/>",{class:this.class_}),this.input=this.labelled=jQuery("<textarea/>",{class:"form-control input-sm"}).appendTo(this.el),this.input.change(this.focus_out.bind(this)),this.attributes.translate){var d=jQuery("<button/>",{class:"btn btn-default btn-sm form-control",type:"button","aria-label":Sao.i18n.gettext("Translate")}).appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(this.el));d.append(jQuery("<span/>",{class:"glyphicon glyphicon-flag"})),d.click(this.translate.bind(this))}},display:function(a,b){if(Sao.View.Form.Text._super.display.call(this,a,b),a){var c=a.field_get_client(this.field_name);this.input.val(c)}else this.input.val("")},focus:function(){this.input.focus()},set_value:function(a,b){var c=this.input.val()||"";b.set_client(a,c)},set_readonly:function(a){this.input.prop("readonly",a)},translate_widget:function(){return jQuery("<textarea/>",{class:"form-control",readonly:"readonly"})}}),Sao.View.Form.RichText=Sao.class_(Sao.View.Form.Widget,{class_:"form-richtext",init:function(a,b,c){Sao.View.Form.RichText._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_+" panel panel-default"}),parseInt(c.toolbar||"1",10)&&this.get_toolbar().appendTo(this.el),this.input=this.labelled=jQuery("<div/>",{class:"richtext",contenteditable:!0}).appendTo(jQuery("<div/>",{class:"panel-body"}).appendTo(this.el)),this.el.focusout(this.focus_out.bind(this))},get_toolbar:function(){var a,b,c,d=jQuery("<div/>",{class:"btn-toolbar",role:"toolbar"}).appendTo(jQuery("<div/>",{class:"panel-heading"})),e=function(a){document.execCommand(a.data)},f=function(f){var g=jQuery("<div/>",{class:"btn-group",role:"group"}).appendTo(d);for(a in f)b=f[a],c=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-"+b.icon})).appendTo(g),c.click(b.command,e)};f([{icon:"bold",command:"bold"},{icon:"italic",command:"italic"},{icon:"text-color",command:"underline"}]);var g=[{heading:Sao.i18n.gettext("Font"),options:["Normal","Serif","Sans","Monospace"],command:"fontname"},{heading:Sao.i18n.gettext("Size"),options:[1,2,3,4,5,6,7],command:"fontsize"}],h=function(a,b){return function(c){a.append(jQuery("<li/>").append(jQuery("<a/>",{href:"#"}).append(c).click(function(){document.execCommand(b.command,!1,c)})))}};for(a in g){b=g[a];var i=jQuery("<div/>",{class:"btn-group",role:"group"}).appendTo(d);c=jQuery("<button/>",{class:"btn btn-default dropdown-toggle",type:"button","data-toggle":"dropdown","aria-expanded":!1,"aria-haspopup":!0}).append(b.heading).append(jQuery("<span/>",{class:"caret"})).appendTo(i);var j=jQuery("<ul/>",{class:"dropdown-menu"}).appendTo(i);b.options.forEach(h(j,b))}return f([{icon:"align-left",command:"justifyLeft"},{icon:"align-center",command:"justifyCenter"},{icon:"align-right",command:"justifyRight"},{icon:"align-justify",command:"justifyFull"}]),[["foreColor","#000000"]].forEach(function(a){var b=a[0],c=a[1];jQuery("<input/>",{class:"btn btn-default",type:"color"}).appendTo(d).change(function(){document.execCommand(b,!1,jQuery(this).val())}).focusin(function(){document.execCommand(b,!1,jQuery(this).val())}).val(c)}),d},focus_out:function(){window.setTimeout(function(){0===this.el.find(":focus").length&&Sao.View.Form.RichText._super.focus_out.call(this)}.bind(this),0)},display:function(a,b){Sao.View.Form.RichText._super.display.call(this,a,b);var c="";a&&(c=a.field_get_client(this.field_name)),this.input.html(c)},focus:function(){this.input.focus()},set_value:function(a,b){this.input.find("div").each(function(a,b){if(b=jQuery(b),b.css("text-align")){var c=b.css("text-align").split("-").pop();b.attr("align",c),b.css("text-align","")}"start"==b.attr("align")&&b.attr("align","left")});var c=this.input.html()||"";b.set_client(a,c)},set_readonly:function(a){this.input.prop("contenteditable",!a),this.toolbar&&this.toolbar.find("button,select").prop("disabled",a)}}),Sao.View.Form.Many2One=Sao.class_(Sao.View.Form.Widget,{class_:"form-many2one",init:function(a,b,c){Sao.View.Form.Many2One._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_});var d=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el);this.entry=this.labelled=jQuery("<input/>",{type:"input",class:"form-control input-sm"}).appendTo(d),this.entry.on("keydown",this.key_press.bind(this)),c.completion&&"1"!=c.completion||(Sao.common.get_completion(d,this._update_completion.bind(this),this._completion_match_selected.bind(this),this._completion_action_activated.bind(this)),this.wid_completion=!0),this.but_primary=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon"})).appendTo(jQuery("<span/>",{class:"input-group-btn"}).prependTo(d)),this.but_secondary=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon"})).appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(d)),this.but_primary.click("primary",this.edit.bind(this)),this.but_secondary.click("secondary",this.edit.bind(this)),this.el.change(this.focus_out.bind(this)),this._readonly=!1},get_screen:function(){var a=this.field().get_domain(this.record()),b=this.field().get_context(this.record());return new Sao.Screen(this.get_model(),{context:b,domain:a,mode:["form"],view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views,readonly:this._readonly})},set_text:function(a){jQuery.isEmptyObject(a)&&(a=""),this.entry.val(a)},get_text:function(){var a=this.record();return a?a.field_get_client(this.field_name):""},focus_out:function(){(this.attributes.completion&&"1"!=this.attributes.completion||!this.el.find(".dropdown").hasClass("open"))&&Sao.View.Form.Many2One._super.focus_out.call(this)},set_value:function(a,b){b.get_client(a)!=this.entry.val()&&(b.set_client(a,this.value_from_id(null,"")),this.entry.val(""))},display:function(a,b){var c=this.record();if(!c||!a||c.id==a.id){var d;if(Sao.View.Form.Many2One._super.display.call(this,a,b),this._set_button_sensitive(),this._set_completion(),!a)return void this.entry.val("");this.set_text(b.get_client(a));var e,f;d=b.get(a),this.has_target(d)?(e="glyphicon-folder-open",f="glyphicon-erase"):(e=null,f="glyphicon-search"),this.entry.prop("readonly")&&(f=null),[[e,this.but_primary],[f,this.but_secondary]].forEach(function(a){var b=a[0],c=a[1],d=c.find(".glyphicon");d.removeClass().addClass("glyphicon"),b?(c.parent().css("display","table-cell"),d.addClass(b)):c.parent().css("display","none")})}},focus:function(){this.entry.focus()},set_readonly:function(a){this._readonly=a,this._set_button_sensitive()},_set_button_sensitive:function(){this.entry.prop("readonly",this._readonly),this.but_primary.prop("disabled",!this.read_access()),this.but_secondary.prop("disabled",this._readonly)},get_access:function(a){var b=this.get_model();return!b||Sao.common.MODELACCESS.get(b)[a]},read_access:function(){return this.get_access("read")},create_access:function(){return this.attributes.create&&this.get_access("create")},id_from_value:function(a){return a},value_from_id:function(a,b){return void 0===b&&(b=""),[a,b]},get_model:function(){return this.attributes.relation},has_target:function(a){return void 0!==a&&null!==a},edit:function(a){var b=this.get_model();if(b&&Sao.common.MODELACCESS.get(b).read){var c,d,e=this.record(),f=e.field_get(this.field_name);if(a&&"secondary"==a.data&&!this._readonly&&this.has_target(f))return this.record().field_set_client(this.field_name,this.value_from_id(null,"")),void this.entry.val("");if(this.has_target(f)){var g=this.get_screen(),h=this.id_from_value(e.field_get(this.field_name));return g.new_group([h]),d=function(a){if(a){var b=g.current_record.rec_name();b.done(function(a){var b=this.value_from_id(g.current_record.id,a);this.record().field_set_client(this.field_name,b,!0)}.bind(this))}},void(c=new Sao.Window.Form(g,d.bind(this),{save_current:!0,title:this.attributes.string}))}if(b){var i=this.field().get_domain(e),j=this.field().get_context(e),k=this.entry.val();d=function(a){if(!jQuery.isEmptyObject(a)){var b=this.value_from_id(a[0][0],a[0][1]);this.record().field_set_client(this.field_name,b,!0)}};var l=new Sao.common.DomainParser;return void(c=new Sao.Window.Search(b,d.bind(this),{sel_multi:!1,context:j,domain:i,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.create_access(),search_filter:l.quote(k),title:this.attributes.string}))}}},new_:function(a){var b=this.get_model();if(b&&Sao.common.MODELACCESS.get(b).create){var c=this.get_screen(),d=function(a){if(a){var b=c.current_record.rec_name();b.done(function(a){var b=this.value_from_id(c.current_record.id,a);this.record().field_set_client(this.field_name,b)}.bind(this))}};new Sao.Window.Form(c,d.bind(this),{new_:!0,save_current:!0,title:this.attributes.string,rec_name:this.entry.val()})}},key_press:function(a){var b=!this.entry.prop("readonly"),c=[Sao.common.TAB_KEYCODE],d=[Sao.common.BACKSPACE_KEYCODE,Sao.common.DELETE_KEYCODE];if(this.wid_completion||c.push(Sao.common.RETURN_KEYCODE),a.which==Sao.common.F3_KEYCODE&&b&&this.create_access())this.new_(),a.preventDefault();else if(a.which==Sao.common.F2_KEYCODE&&this.read_access())this.edit(),a.preventDefault();else if(~c.indexOf(a.which)&&b){if((!this.attributes.completion||"1"==this.attributes.completion)&&this.el.find(".dropdown").hasClass("open"))return;this.activate()}else if(this.has_target(this.record().field_get(this.field_name))&&b){var e=this.get_text();(e!=this.entry.val()||~d.indexOf(a.which))&&(this.entry.val(""),this.record().field_set_client(this.field_name,this.value_from_id(null,"")))}},activate:function(){var a=this.get_model();if(a&&Sao.common.MODELACCESS.get(a).read){var b=this.record(),c=b.field_get(this.field_name);new Sao.Model(a);if(a&&!this.has_target(c)){var d=this.entry.val();if(!this._readonly&&(d||this.field().get_state_attrs(this.record()).required)){var e=this.field().get_domain(b),f=this.field().get_context(b),g=function(a){if(jQuery.isEmptyObject(a))this.entry.val("");else{var b=this.value_from_id(a[0][0],a[0][1]);this.record().field_set_client(this.field_name,b,!0)}},h=new Sao.common.DomainParser;new Sao.Window.Search(a,g.bind(this),{sel_multi:!1,context:f,domain:e,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.create_access(),search_filter:h.quote(d),title:this.attributes.string})}}}},_set_completion:function(){var a=this.el.find(".action-search");this.read_access()?a.removeClass("disabled"):a.addClass("disabled");var b=this.el.find(".action-create");this.create_access()?b.removeClass("disabled"):b.addClass("disabled")},_update_completion:function(a){var b=this.record();if(b){var c=this.field(),d=c.get(b);if(this.has_target(d)){var e=this.id_from_value(d);if(void 0!==e&&e>0)return jQuery.when()}var f=this.get_model();return Sao.common.update_completion(this.entry,b,c,f)}},_completion_match_selected:function(a){this.record().field_set_client(this.field_name,this.value_from_id(a.id,a.rec_name),!0)},_completion_action_activated:function(a){"search"==a?this.edit():"create"==a&&this.new_()}}),Sao.View.Form.One2One=Sao.class_(Sao.View.Form.Many2One,{class_:"form-one2one"
-}),Sao.View.Form.Reference=Sao.class_(Sao.View.Form.Many2One,{class_:"form-reference",init:function(a,b,c){Sao.View.Form.Reference._super.init.call(this,a,b,c),this.el.addClass("form-inline"),this.select=jQuery("<select/>",{class:"form-control input-sm","aria-label":c.string}),this.el.prepend(jQuery("<span/>").text("-")),this.el.prepend(this.select),this.select.change(this.select_changed.bind(this)),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a,this.set_selection.bind(this))},update_selection:function(a,b,c){Sao.common.selection_mixin.update_selection.call(this,a,b,function(a){this.set_selection(a),c&&c()}.bind(this))},set_selection:function(a){var b=this.select;b.empty(),a.forEach(function(a){b.append(jQuery("<option/>",{value:a[0],text:a[1]}))})},id_from_value:function(a){return parseInt(a.split(",")[1],10)},value_from_id:function(a,b){return b||(b=""),[this.get_model(),[a,b]]},get_text:function(){var a=this.record();return a?a.field_get_client(this.field_name)[1]:""},get_model:function(){return this.select.val()},has_target:function(a){if(null===a)return!1;var b=a.split(",")[0];return a=a.split(",")[1],jQuery.isEmptyObject(a)?a=null:(a=parseInt(a,10),isNaN(a)&&(a=null)),b==this.get_model()&&a>=0},_set_button_sensitive:function(){Sao.View.Form.Reference._super._set_button_sensitive.call(this),this.select.prop("disabled",this.entry.prop("readonly"))},select_changed:function(){this.entry.val("");var a,b=this.get_model();a=b?[b,[-1,""]]:["",""],this.record().field_set_client(this.field_name,a)},set_value:function(a,b){var c;if(this.get_model()){c=b.get_client(a,this.field_name);var d,e;c instanceof Array?(d=c[0],e=c[1]):(d="",e=""),d==this.get_model()&&e==this.entry.val()||(b.set_client(a,null),this.entry.val(""))}else c=this.entry.val(),jQuery.isEmptyObject(c)?b.set_client(a,null):b.set_client(a,["",c])},set_text:function(a){var b;a?(b=a[0],a=a[1]):(b=null,a=null),Sao.View.Form.Reference._super.set_text.call(this,a),b?this.select.val(b):this.select.val("")},display:function(a,b){this.update_selection(a,b,function(){Sao.View.Form.Reference._super.display.call(this,a,b)}.bind(this))},set_readonly:function(a){Sao.View.Form.Reference._super.set_readonly.call(this,a),this.select.prop("disabled",a)}}),Sao.View.Form.One2Many=Sao.class_(Sao.View.Form.Widget,{class_:"form-one2many",init:function(a,b,c){Sao.View.Form.One2Many._super.init.call(this,a,b,c),this._readonly=!0,this._required=!1,this.el=jQuery("<div/>",{class:this.class_+" panel panel-default"}),this.menu=jQuery("<div/>",{class:this.class_+"-menu panel-heading"}),this.el.append(this.menu),this.title=jQuery("<label/>",{class:this.class_+"-string",text:c.string}),this.menu.append(this.title),this.title.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",this.title.attr("id")),this.title.attr("for",this.el.attr("id"));var d=jQuery("<div/>",{class:this.class_+"-toolbar"});this.menu.append(d);var e=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(d);this.wid_text=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(e),this.wid_text.hide();var f=jQuery("<div/>",{class:"input-group-btn"}).appendTo(e);c.add_remove&&(this.wid_text.show(),this.but_add=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-plus"})).appendTo(f),this.but_add.click(this.add.bind(this)),this.but_remove=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-minus"})).appendTo(f),this.but_remove.click(this.remove.bind(this))),this.but_new=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("New")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-edit"})).appendTo(f),this.but_new.click(this.new_.bind(this)),this.but_open=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Open")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-folder-open"})).appendTo(f),this.but_open.click(this.open.bind(this)),this.but_del=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Delete")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-trash"})).appendTo(f),this.but_del.click(this.delete_.bind(this)),this.but_undel=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Undelete")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-repeat"})).appendTo(f),this.but_undel.click(this.undelete.bind(this)),this.but_previous=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-chevron-left"})).appendTo(f),this.but_previous.click(this.previous.bind(this)),this.label=jQuery("<span/>",{class:"btn"}).appendTo(f),this.label.text("(0, 0)"),this.but_next=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-chevron-right"})).appendTo(f),this.but_next.click(this.next.bind(this)),this.but_switch=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Switch")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-list-alt"})).appendTo(f),this.but_switch.click(this.switch_.bind(this)),this.content=jQuery("<div/>",{class:this.class_+"-content panel-body"}),this.el.append(this.content);var g=(c.mode||"tree,form").split(",");this.screen=new Sao.Screen(c.relation,{mode:g,view_ids:(c.view_ids||"").split(","),views_preload:c.views||{},row_activate:this.activate.bind(this),exclude_field:c.relation_field||null,pre_validate:c.pre_validate}),this.screen.pre_validate=1==c.pre_validate,this.prm=this.screen.switch_view(g[0]).done(function(){this.content.append(this.screen.screen_container.el)}.bind(this)),this.but_switch.prop("disabled",this.screen.number_of_views()<=0)},set_readonly:function(a){this._readonly=a,this._set_button_sensitive(),this._set_label_state()},set_required:function(a){this._required=a,this._set_label_state()},_set_label_state:function(){Sao.common.apply_label_attributes(this.title,this._readonly,this._required)},_set_button_sensitive:function(){var a,b,c=Sao.common.MODELACCESS.get(this.screen.model_name),d=this.record(),e=this.field();if(d&&e){var f=d.expr_eval(this.attributes.size);b=e.get_eval(d).length,a=void 0!==f&&null!==f&&b>=f>=0}else b=null,a=!1;var g=this.attributes.create;void 0===g&&(g=!0),this.but_new.prop("disabled",this._readonly||!g||a||!c.create);var h=this.attributes.delete;void 0===h&&(h=!0),this.but_del.prop("disabled",this._readonly||!h||!c.delete),this.but_undel.prop("disabled",this._readonly||a),this.but_open.prop("disabled",!c.read),this.attributes.add_remove&&(this.wid_text.prop("disabled",this._readonly),this.but_add.prop("disabled",this._readonly||a||!c.write||!c.read),this.but_remove.prop("disabled",this._readonly||!c.write||!c.read))},display:function(a,b){Sao.View.Form.One2Many._super.display.call(this,a,b),this._set_button_sensitive(),this.prm.done(function(){if(a){if(void 0===b)return this.screen.new_group(),this.screen.set_current_record(null),this.screen.group.parent=null,void this.screen.display();var c=a.field_get_client(this.field_name);c!=this.screen.group&&(this.screen.set_group(c),"tree"==this.screen.current_view.view_type&&this.screen.current_view.editable&&this.screen.set_current_record(null));var d=[],e=null;a&&(d=b.get_domain(a),e=a.expr_eval(this.attributes.size)),this._readonly&&(e=null===e?this.screen.group.length:Math.min(e,this.screen.group.length)),Sao.common.compare(this.screen.domain,d)||(this.screen.domain=d),this.screen.size_limit=e,this.screen.attributes.readonly=this._readonly,this.screen.display()}}.bind(this))},focus:function(){this.wid_text.is(":visible")&&this.wid_text.focus()},activate:function(a){this.edit()},add:function(a){var b=Sao.common.MODELACCESS.get(this.screen.model_name);if(b.write&&b.read){this.view.set_value();var c=this.field().get_domain(this.record()),d=this.field().get_context(this.record());c=[c,this.record().expr_eval(this.attributes.add_remove)];var e=this.field().get_removed_ids(this.record());c=["OR",c,["id","in",e]];var f=this.wid_text.val(),g=function(a){var b=jQuery.when();if(!jQuery.isEmptyObject(a)){var c,d,e=[];for(c=0,d=a.length;c<d;c++)e.push(a[c][0]);this.screen.group.load(e,!0),b=this.screen.display()}b.done(function(){this.screen.set_cursor()}.bind(this)),this.wid_text.val("")}.bind(this),h=new Sao.common.DomainParser;new Sao.Window.Search(this.attributes.relation,g,{sel_multi:!0,context:d,domain:c,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:!this.but_new.prop("disabled"),search_filter:h.quote(f),title:this.attributes.string})}},remove:function(a){var b=Sao.common.MODELACCESS.get(this.screen.model_name);b.write&&b.read&&this.screen.remove(!1,!0,!1)},new_:function(a){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.validate().done(function(){this.attributes.product?this.new_product():this.new_single()}.bind(this))},new_single:function(){var a=jQuery.extend({},this.field().get_context(this.record()));if("form"==this.screen.current_view.type||this.screen.current_view.editable)this.screen.new_(),this.screen.current_view.el.prop("disabled",!1);else{var b=this.record(),c=b.expr_eval(this.attributes.size)||-1;c-=this.field().get_eval(b);new Sao.Window.Form(this.screen,function(){},{new_:!0,many:c,context:a,title:this.attributes.string})}},new_product:function(){var a=this.attributes.product.split(","),b={},c=this.screen;c.new_(!1).then(function(d){d.default_get().then(function(e){d.set_default(e);var f=function(){if(jQuery.isEmptyObject(a))return g();var e=c.model.fields[a.pop()],h=e.description.relation;h||f();var i=e.get_domain(d),j=e.get_context(d),k=function(a){jQuery.isEmptyObject(a)||(b[e.name]=a),f()};new Sao.Window.Search(h,k,{sel_multi:!0,context:j,domain:i,search_filter:"",title:this.attributes.string})}.bind(this),g=function(){if(jQuery.isEmptyObject(b))return void c.group.remove(d,!0);var a=Object.keys(b),f=a.map(function(a){return b[a]});Sao.common.product(f).forEach(function(b){var f=function(c){var d=jQuery.extend({},e);a.forEach(function(a,c){d[a]=b[c][0],d[a+".rec_name"]=b[c][1]}),c.set_default(d)};d?(f(d),d=null):c.new_(!1).then(f)})};f()}.bind(this))}.bind(this))},open:function(a){this.edit()},delete_:function(a){Sao.common.MODELACCESS.get(this.screen.model_name).delete&&this.screen.remove(!1,!1,!1)},undelete:function(a){this.screen.unremove()},previous:function(a){this.validate().done(function(){this.screen.display_previous()}.bind(this))},next:function(a){this.validate().done(function(){this.screen.display_next()}.bind(this))},switch_:function(a){this.screen.switch_view()},edit:function(){Sao.common.MODELACCESS.get(this.screen.model_name).read&&this.validate().done(function(){var a=this.screen.current_record;if(a){new Sao.Window.Form(this.screen,function(){},{title:this.attributes.string})}}.bind(this))},validate:function(){var a=jQuery.Deferred();this.view.set_value();var b=this.screen.current_record;if(b){var c=this.screen.current_view.get_fields();b.validate(c).then(function(c){return c?this.screen.pre_validate?b.pre_validate().then(function(b){return b?void a.resolve():void a.reject()}):void a.resolve():(this.screen.display(!0),void a.reject())}.bind(this))}else a.resolve();return a},set_value:function(a,b){this.screen.save_tree_state()}}),Sao.View.Form.Many2Many=Sao.class_(Sao.View.Form.Widget,{class_:"form-many2many",init:function(a,b,c){Sao.View.Form.Many2Many._super.init.call(this,a,b,c),this._readonly=!0,this._required=!1,this.el=jQuery("<div/>",{class:this.class_+" panel panel-default"}),this.menu=jQuery("<div/>",{class:this.class_+"-menu panel-heading"}),this.el.append(this.menu),this.title=jQuery("<label/>",{class:this.class_+"-string",text:c.string}),this.menu.append(this.title),this.title.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",this.title.attr("id")),this.title.attr("for",this.el.attr("id"));var d=jQuery("<div/>",{class:this.class_+"-toolbar"});this.menu.append(d);var e=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(d);this.entry=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(e),this.entry.on("keydown",this.key_press.bind(this));var f=jQuery("<div/>",{class:"input-group-btn"}).appendTo(e);this.but_add=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-plus"})).appendTo(f),this.but_add.click(this.add.bind(this)),this.but_remove=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-minus"})).appendTo(f),this.but_remove.click(this.remove.bind(this)),this.content=jQuery("<div/>",{class:this.class_+"-content panel-body"}),this.el.append(this.content),this.screen=new Sao.Screen(c.relation,{mode:["tree"],view_ids:(c.view_ids||"").split(","),views_preload:c.views||{},row_activate:this.activate.bind(this)}),this.prm=this.screen.switch_view("tree").done(function(){this.content.append(this.screen.screen_container.el)}.bind(this))},set_readonly:function(a){this._readonly=a,this._set_button_sensitive(),this._set_label_state()},set_required:function(a){this._required=a,this._set_label_state()},_set_label_state:function(){Sao.common.apply_label_attributes(this.title,this._readonly,this._required)},_set_button_sensitive:function(){var a=!1;this.record()&&this.field(),this.entry.prop("disabled",this._readonly),this.but_add.prop("disabled",this._readonly||a),this.but_remove.prop("disabled",this._readonly)},display:function(a,b){Sao.View.Form.Many2Many._super.display.call(this,a,b),this.prm.done(function(){if(a){if(void 0===b)return this.screen.new_group(),this.screen.set_current_record(null),this.screen.group.parent=null,void this.screen.display();var c=a.field_get_client(this.field_name);c!=this.screen.group&&this.screen.set_group(c),this.screen.display()}}.bind(this))},focus:function(){this.entry.focus()},activate:function(){this.edit()},add:function(){var a=this.field().get_domain(this.record()),b=this.field().get_context(this.record()),c=this.entry.val(),d=function(a){if(!jQuery.isEmptyObject(a)){var b,c,d=[];for(b=0,c=a.length;b<c;b++)d.push(a[b][0]);this.screen.group.load(d,!0),this.screen.display()}this.entry.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(this.attributes.relation,d,{sel_multi:!0,context:b,domain:a,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.attributes.create,search_filter:e.quote(c),title:this.attributes.string})},remove:function(){this.screen.remove(!1,!0,!1)},key_press:function(a){var b=[Sao.common.TAB_KEYCODE];this.wid_completion||b.push(Sao.common.RETURN_KEYCODE),a.which==Sao.common.F3_KEYCODE?(this.new_(),a.preventDefault()):a.which==Sao.common.F2_KEYCODE?(this.add(),a.preventDefault()):~b.indexOf(a.which)&&this.entry.val()&&this.add()},_get_screen_form:function(){var a=this.field().get_domain(this.record()),b=this.record().expr_eval(this.attributes.add_remove);jQuery.isEmptyObject(b)||(a=[a,b]);var c=this.field().get_context(this.record()),d=(this.attributes.view_ids||"").split(",");return jQuery.isEmptyObject(d)||d.shift(),new Sao.Screen(this.attributes.relation,{domain:a,view_ids:d,mode:["form"],views_preload:this.attributes.views,context:c})},edit:function(){if(!jQuery.isEmptyObject(this.screen.current_record)){var a=this._get_screen_form();a.new_group([this.screen.current_record.id]);var b=function(b){b&&a.current_record.save().done(function(){this.screen.current_record.cancel()}.bind(this))}.bind(this);a.switch_view().done(function(){new Sao.Window.Form(a,b,{title:this.attributes.string})}.bind(this))}},new_:function(){var a=this._get_screen_form(),b=function(b){if(b){var c=a.current_record;this.screen.group.load([c.id],!0)}this.entry.val("")}.bind(this);a.switch_view().done(function(){new Sao.Window.Form(a,b,{new_:!0,save_current:!0,title:this.attributes.string,rec_name:this.entry.val()})}.bind(this))}}),Sao.View.Form.BinaryMixin=Sao.class_(Sao.View.Form.Widget,{init:function(a,b,c){Sao.View.Form.BinaryMixin._super.init.call(this,a,b,c),this.filename=c.filename||null},toolbar:function(a){var b=jQuery("<div/>",{class:a,role:"group"});return this.but_select=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-search"})).appendTo(b),this.but_select.click(this.select.bind(this)),this.filename&&(this.but_open=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-folder-open"})).appendTo(b),this.but_open.click(this.open.bind(this))),this.but_save_as=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-save"})).appendTo(b),this.but_save_as.click(this.save_as.bind(this)),this.but_clear=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-erase"})).appendTo(b),this.but_clear.click(this.clear.bind(this)),b},filename_field:function(){var a=this.record();if(a)return a.model.fields[this.filename]},select:function(){var a=this.record(),b=function(){d.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),d.modal.modal("hide")},c=function(){var c=new FileReader;c.onload=function(b){var d,e=this.field(),f=new Uint8Array(c.result);d=e.get_size?f:String.fromCharCode.apply(null,f),e.set_client(a,d)}.bind(this),c.onloadend=function(a){b()};var d=e[0].files[0];c.readAsArrayBuffer(d),this.filename&&this.filename_field().set_client(a,d.name)}.bind(this),d=new Sao.Dialog(Sao.i18n.gettext("Select"),"file-dialog");d.footer.append(jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(b)).append(jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).click(c)),d.content.submit(function(a){c(),a.preventDefault()});var e=jQuery("<input/>",{type:"file"}).appendTo(d.body);d.modal.modal("show")},open:function(){var a={},b=this.filename_field();if(b){var c=b.get_client(this.record());a.mimetype=Sao.common.guess_mimetype(c)}this.save_as(a)},save_as:function(a){var b,c=a.mimetype||"application/octet-binary",d=this.field(),e=this.record();b=d.get_data?d.get_data(e):jQuery.when(d.get(e)),b.done(function(a){var b=new Blob([a],{type:c}),d=window.URL.createObjectURL(b);this.blob_url&&window.URL.revokeObjectURL(this.blob_url),this.blob_url=d,window.open(d)}.bind(this))},clear:function(){var a=this.filename_field();a&&a.set_client(this.record(),null),this.field().set_client(this.record(),null)}}),Sao.View.Form.Binary=Sao.class_(Sao.View.Form.BinaryMixin,{class_:"form-binary",blob_url:"",init:function(a,b,c){Sao.View.Form.Binary._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_}),this.filename&&c.filename_visible&&(this.text=jQuery("<input/>",{type:"input",class:"form-control input-sm"}).appendTo(this.el),this.text.change(this.focus_out.bind(this)),this.text.on("keydown",this.key_press.bind(this)));var d=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el);this.size=jQuery("<input/>",{type:"input",class:"form-control input-sm",readonly:!0}).appendTo(d),this.toolbar("input-group-btn").appendTo(d)},display:function(a,b){if(Sao.View.Form.Binary._super.display.call(this,a,b),!b)return this.size.val(""),this.filename&&this.but_open.button("disable"),this.text&&this.text.val(""),void this.but_save_as.button("disable");var c;c=b.get_size?b.get_size(a):b.get(a).length;var d;d=c?"enable":"disable",this.filename&&(this.text&&this.text.val(this.filename_field().get(a)||""),this.but_open.button(d)),this.size.val(Sao.common.humanize(c)),this.but_save_as.button(d)},key_press:function(a){var b=!this.wid_text.prop("readonly");a.which==Sao.common.F3_KEYCODE&&b?(this.new_(),a.preventDefault()):a.which==Sao.common.F2_KEYCODE&&(this.open(),a.preventDefault())},set_value:function(a,b){this.text&&this.filename_field().set_client(a,this.text.val()||"")},set_readonly:function(a){a?(this.but_select.hide(),this.but_clear.hide()):(this.but_select.show(),this.but_clear.show()),this.wid_text&&this.wid_text.prop("readonly",a)}}),Sao.View.Form.MultiSelection=Sao.class_(Sao.View.Form.Selection,{class_:"form-multiselection",expand:!0,init:function(a,b,c){this.nullable_widget=!1,Sao.View.Form.MultiSelection._super.init.call(this,a,b,c),this.select.prop("multiple",!0)},display_update_selection:function(a,b){var c,d,e;this.update_selection(a,b,function(){var f=this.attributes.yexpand;if(void 0===f&&(f=this.expand),f||this.select.prop("size",this.select.children().length),b){var g=[],h=a.field_get_client(this.field_name);for(c=0,d=h.length;c<d;c++)e=h[c],~h.record_removed.indexOf(e)||~h.record_deleted.indexOf(e)||g.push(e.id);this.select.val(g)}}.bind(this))},set_value:function(a,b){var c=this.select.val();c=c?c.map(function(a){return parseInt(a,10)}):[],b.set_client(a,c)}}),Sao.View.Form.Image=Sao.class_(Sao.View.Form.BinaryMixin,{class_:"form-image",init:function(a,b,c){Sao.View.Form.Image._super.init.call(this,a,b,c),this.height=parseInt(c.height||100,10),this.width=parseInt(c.width||300,10),this.el=jQuery("<div/>"),this.image=jQuery("<img/>",{class:"center-block"}).appendTo(this.el),this.image.css("max-height",this.height),this.image.css("max-width",this.width),this.image.css("height","auto"),this.image.css("width","auto");var d=this.toolbar("btn-group");c.readonly||jQuery("<div/>",{class:"text-center"}).append(d).appendTo(this.el),this.update_img()},set_readonly:function(a){[this.but_select,this.but_open,this.but_save_as,this.but_clear].forEach(function(b){b&&b.prop("disable",a)})},clear:function(){Sao.View.Form.Image._super.clear.call(this),this.update_img()},update_img:function(){var a,b=this.record();b&&(a=b.field_get_client(this.field_name)),a=a?a>Sao.common.BIG_IMAGE_SIZE?jQuery.when(null):b.model.fields[this.field_name].get_data(b):jQuery.when(null),a.done(function(a){var b,c;a?(c=new Blob([a]),b=window.URL.createObjectURL(c)):b=null,this.image.attr("src",b)}.bind(this))},display:function(a,b){Sao.View.Form.Image._super.display.call(this,a,b),this.update_img()}}),Sao.View.Form.URL=Sao.class_(Sao.View.Form.Char,{class_:"form-url",init:function(a,b,c){Sao.View.Form.URL._super.init.call(this,a,b,c),this.button=jQuery("<a/>",{class:"btn btn-default",target:"_new"}).appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(this.group)),this.icon=jQuery("<img/>").appendTo(this.button),this.set_icon()},display:function(a,b){Sao.View.Form.URL._super.display.call(this,a,b);var c="";if(a&&(c=a.field_get_client(this.field_name)),this.set_url(c),a&this.attributes.icon){var d,e=this.attributes.icon;d=e in a.model.fields?a.field_get_client(e):e,this.set_icon(d)}},set_icon:function(a){a=a||"tryton-web-browser",Sao.common.ICONFACTORY.register_icon(a).done(function(a){this.icon.attr("src",a)}.bind(this))},set_url:function(a){this.button.attr("href",a)},set_readonly:function(a){Sao.View.Form.URL._super.set_readonly.call(this,a),a?(this.input.hide(),this.button.removeClass("btn-default"),this.button.addClass("btn-link")):(this.input.show(),this.button.removeClass("btn-link"),this.button.addClass("btn-default"))}}),Sao.View.Form.Email=Sao.class_(Sao.View.Form.URL,{class_:"form-email",set_url:function(a){Sao.View.Form.Email._super.set_url.call(this,"mailto:"+a)}}),Sao.View.Form.CallTo=Sao.class_(Sao.View.Form.URL,{class_:"form-callto",set_url:function(a){Sao.View.Form.CallTo._super.set_url.call(this,"callto:"+a)}}),Sao.View.Form.SIP=Sao.class_(Sao.View.Form.URL,{class_:"form-sip",set_url:function(a){Sao.View.Form.SIP._super.set_url.call(this,"sip:"+a)}}),Sao.View.Form.ProgressBar=Sao.class_(Sao.View.Form.Widget,{class_:"form-char",init:function(a,b,c){Sao.View.Form.ProgressBar._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{class:this.class_+" progress"}),this.progressbar=jQuery("<div/>",{class:"progress-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100}).appendTo(this.el),this.progressbar.css("min-width: 2em")},display:function(a,b){Sao.View.Form.ProgressBar._super.display.call(this,a,b);var c,d;b?(c=b.get(a),d=b.get_client(a,100),d&&(d=Sao.i18n.gettext("%1%",d))):(c=0,d=""),this.progressbar.attr("aria-valuenow",100*c),this.progressbar.css("width",100*c+"%"),this.progressbar.text(d)}}),Sao.View.Form.Dict=Sao.class_(Sao.View.Form.Widget,{class_:"form-dict",init:function(a,b,c){Sao.View.Form.Dict._super.init.call(this,a,b,c),this.schema_model=new Sao.Model(c.schema_model),this.keys={},this.fields={},this.rows={},this.el=jQuery("<div/>",{class:this.class_+" panel panel-default"});var d=jQuery("<div/>",{class:this.class_+"-heading panel-heading"}).appendTo(this.el),e=jQuery("<label/>",{class:this.class_+"-string",text:c.string}).appendTo(d);e.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",e.attr("id")),e.attr("for",this.el.attr("id"));var f=jQuery("<div/>",{class:this.class_+"-body panel-body"}).appendTo(this.el);this.container=jQuery("<div/>",{class:this.class_+"-container"}).appendTo(f);var g=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(jQuery("<div>",{class:"col-md-12"}).appendTo(jQuery("<div/>",{class:"row"}).appendTo(jQuery("<div/>",{class:"container-fluid"}).appendTo(f))));this.wid_text=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(g),this.but_add=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-plus"})).appendTo(jQuery("<div/>",{class:"input-group-btn"}).appendTo(g)),this.but_add.click(this.add.bind(this)),this._readonly=!1,this._record_id=null},add:function(){var a=this.field().get_context(this.record()),b=this.wid_text.val(),c=this.field().get_domain(this.record()),d=function(a){if(!jQuery.isEmptyObject(a)){var b=a.map(function(a){return a[0]});this.add_new_keys(b)}this.wid_text.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(this.schema_model.name,d,{sel_multi:!0,context:a,domain:c,new_:!1,search_filter:e.quote(b),title:this.attributes.string})},add_new_keys:function(a){var b=this.field().get_context(this.record());this.schema_model.execute("get_keys",[a],b).then(function(a){var b=!1;a.forEach(function(a){this.fields[a.name]||(this.keys[a.name]=a,this.add_line(a.name),b||(this.fields[a.name].input.focus(),b=!0))}.bind(this))}.bind(this))},remove:function(a,b){void 0===b&&(b=!0),delete this.fields[a],this.rows[a].remove(),delete this.rows[a],b&&this.set_value(this.record(),this.field())},set_value:function(a,b){b.set_client(a,this.get_value())},get_value:function(){var a={};for(var b in this.fields){var c=this.fields[b];a[b]=c.get_value()}return a},set_readonly:function(a){this._readonly=a,this._set_button_sensitive();for(var b in this.fields){var c=this.fields[b];c.set_readonly(a)}this.wid_text.prop("disabled",a)},_set_button_sensitive:function(){var a=this.attributes.create;void 0===a&&(a=!0);var b=this.attributes.delete;void 0===b&&(b=!0),this.but_add.prop("disabled",this._readonly||!a);for(var c in this.fields){var d=this.fields[c].button;d.prop("disabled",this._readonly||!b)}},add_line:function(a){var b,c;this.fields[a]=b=new(this.get_entries(this.keys[a].type_))(a,this),this.rows[a]=c=jQuery("<div/>",{class:"row"});var d=this.keys[a].string+Sao.i18n.gettext(":"),e=jQuery("<label/>",{text:d}).appendTo(jQuery("<div/>",{class:"dict-label col-md-4"}).appendTo(c));b.el.addClass("col-md-8").appendTo(c),e.uniqueId(),b.labelled.uniqueId(),b.labelled.attr("aria-labelledby",e.attr("id")),e.attr("for",b.labelled.attr("id")),b.button.click(function(){this.remove(a,!0)}.bind(this)),c.appendTo(this.container)},add_keys:function(a){var b=this.field().get_context(this.record()),c=this.field().get_domain(this.record()),d=Math.min(10,Sao.config.limit);a=jQuery.extend([],a);for(var e=function(a){return this.schema_model.execute("get_keys",[a],b).then(f)}.bind(this),f=function(a){for(var b=0,c=a.length;b<c;b++){var d=a[b];this.keys[d.name]=d}}.bind(this),g=[];a.length>0;){var h=a.splice(0,d);g.push(this.schema_model.execute("search",[[["name","in",h],c],0,Sao.config.limit,null],b).then(e))}return jQuery.when.apply(jQuery,g)},display:function(a,b){if(Sao.View.Form.Dict._super.display.call(this,a,b),b){var c,d=a?a.id:null;if(d!=this._record_id){for(c in this.fields)this.remove(c,!1);this._record_id=d}var e,f=b.get_client(a),g=Object.keys(f).filter(function(a){return!this.keys[a]}.bind(this));e=jQuery.isEmptyObject(g)?jQuery.when():this.add_keys(g),e.then(function(){var a,b,c,d=Object.keys(f).sort();for(a=0,b=d.length;a<b;a++){c=d[a];var e=f[c];if(this.keys[c]){this.fields[c]||this.add_line(c);var g=this.fields[c];g.set_value(e),g.set_readonly(this._readonly)}}var h=Object.keys(this.fields).filter(function(a){return!f[a]});for(a=0,b=h.length;a<b;a++)c=h[a],this.remove(c,!1)}.bind(this)),this._set_button_sensitive()}},get_entries:function(a){switch(a){case"char":return Sao.View.Form.Dict.Entry;case"boolean":return Sao.View.Form.Dict.Boolean;case"selection":return Sao.View.Form.Dict.Selection;case"integer":return Sao.View.Form.Dict.Integer;case"float":return Sao.View.Form.Dict.Float;case"numeric":return Sao.View.Form.Dict.Numeric;case"date":return Sao.View.Form.Dict.Date;case"datetime":return Sao.View.Form.Dict.DateTime}}}),Sao.View.Form.Dict.Entry=Sao.class_(Object,{class_:"dict-char",init:function(a,b){this.name=a,this.definition=b.keys[a],this.parent_widget=b,this.create_widget()},create_widget:function(){this.el=jQuery("<div/>",{class:this.class_});var a=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(this.el);this.input=this.labelled=jQuery("<input/>",{type:"text",class:"form-control input-sm"}).appendTo(a),this.button=jQuery("<button/>",{class:"btn btn-default",type:"button","arial-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-minus"})).appendTo(jQuery("<div/>",{class:"input-group-btn"}).appendTo(a)),this.el.change(this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){return this.input.val()},set_value:function(a){this.input.val(a||"")},set_readonly:function(a){this._readonly=a,this.input.prop("readonly",a)}}),Sao.View.Form.Dict.Boolean=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-boolean",create_widget:function(){Sao.View.Form.Dict.Boolean._super.create_widget.call(this),this.input.attr("type","checkbox"),this.input.change(this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){return this.input.prop("checked")},set_value:function(a){this.input.prop("checked",a)}}),Sao.View.Form.Dict.Selection=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-selection",create_widget:function(){Sao.View.Form.Dict.Selection._super.create_widget.call(this);var a=jQuery("<select/>",{class:"form-control input-sm"});a.change(this.parent_widget.focus_out.bind(this.parent_widget)),this.input.replaceWith(a),this.input=this.labelled=a;var b=jQuery.extend([],this.definition.selection);b.splice(0,0,[null,""]),b.forEach(function(b){a.append(jQuery("<option/>",{value:JSON.stringify(b[0]),text:b[1]}))})},get_value:function(){return JSON.parse(this.input.val())},set_value:function(a){this.input.val(JSON.stringify(a))}}),Sao.View.Form.Dict.Integer=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-integer",get_value:function(){var a=parseInt(this.input.val(),10);return isNaN(a)?null:a}}),Sao.View.Form.Dict.Float=Sao.class_(Sao.View.Form.Dict.Integer,{class_:"dict-float",get_value:function(){var a=Number(this.input.val());return isNaN(a)?null:a;
-}}),Sao.View.Form.Dict.Numeric=Sao.class_(Sao.View.Form.Dict.Float,{class_:"dict-numeric",get_value:function(){var a=new Sao.Decimal(this.input.val());return isNaN(a.valueOf())?null:a}}),Sao.View.Form.Dict.Date=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-date",format:"%x",create_widget:function(){Sao.View.Form.Dict.Date._super.create_widget.call(this);var a=this.button.parent();jQuery("<button/>",{class:"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-calendar"})).prependTo(a),this.input.datetimepicker({format:Sao.common.moment_format(this.format),locale:moment.locale()}),this.input.on("dp.change",this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){var a=this.input.data("DateTimePicker").date();return a&&(a.isDate=!0),a},set_value:function(a){this.date.data("DateTimePicker").date(a)}}),Sao.View.Form.Dict.DateTime=Sao.class_(Sao.View.Form.Dict.Date,{class_:"dict-datetime",format:"%x %X",get_value:function(){var a=this.input.data("DateTimePicker").date();return a&&(a.isDateTime=!0),a}}),Sao.View.Form.PYSON=Sao.class_(Sao.View.Form.Char,{class_:"form-pyson",init:function(a,b,c){Sao.View.Form.PYSON._super.init.call(this,a,b,c),this.encoder=new Sao.PYSON.Encoder({}),this.decoder=new Sao.PYSON.Decoder({},!0),this.el.keyup(this.validate_pyson.bind(this));var d=jQuery("<button/>",{class:"btn btn-default",type:"button"});this.icon=jQuery("<span/>",{class:"glyphicon"}),d.append(this.icon),d.appendTo(jQuery("<span/>",{class:"input-group-btn"}).appendTo(this.group))},get_encoded_value:function(){var a=this.input.val();if(!a)return a;try{return this.encoder.encode(eval_pyson(a))}catch(b){return null}},set_value:function(a,b){b.set_client(a,this.get_encoded_value())},get_client_value:function(a,b){var c=Sao.View.Form.PYSON._super.get_client_value.call(this,a,b);return c&&(c=this.decoder.decode(c).toString()),c},validate_pyson:function(){var a="ok";null===this.get_encoded_value()&&(a="remove"),this.icon.removeClass().addClass("glyphicon").addClass(" glyphicon-"+a+"-sign")},focus_out:function(){this.validate_pyson(),Sao.View.Form.PYSON._super.focus_out.call(this)}})}(),function(){"use strict";function a(a,b,c){var d=Sao.config.display_size,e=jQuery.Deferred(),f=function(g){a.slice(g,g+d).forEach(function(a){a.redraw(b,c)}),g+=d,g<a.length?setTimeout(f,0,g):e.resolve()};return setTimeout(f,0,0),e}Sao.View.tree_column_get=function(a){switch(a){case"char":return Sao.View.Tree.CharColumn;case"text":return Sao.View.Tree.TextColum;case"many2one":return Sao.View.Tree.Many2OneColumn;case"one2one":return Sao.View.Tree.One2OneColumn;case"date":return Sao.View.Tree.DateColumn;case"time":return Sao.View.Tree.TimeColumn;case"timedelta":return Sao.View.Tree.TimeDeltaColumn;case"one2many":return Sao.View.Tree.One2ManyColumn;case"many2many":return Sao.View.Tree.Many2ManyColumn;case"selection":return Sao.View.Tree.SelectionColumn;case"reference":return Sao.View.Tree.ReferenceColumn;case"float":case"numeric":return Sao.View.Tree.FloatColumn;case"integer":case"biginteger":return Sao.View.Tree.IntegerColumn;case"boolean":return Sao.View.Tree.BooleanColumn;case"binary":return Sao.View.Tree.BinaryColumn;case"image":return Sao.View.Tree.ImageColumn;case"url":case"email":case"callto":case"sip":return Sao.View.Tree.URLColumn;case"progressbar":return Sao.View.Tree.ProgressBar}},Sao.View.Tree=Sao.class_(Sao.View,{init:function(a,b,c){Sao.View.Tree._super.init.call(this,a,b),this.view_type="tree",this.selection_mode=a.attributes.selection_mode||Sao.common.SELECTION_SINGLE,this.el=jQuery("<div/>",{class:"treeview responsive"}),this.expanded={},this.children_field=c,this.editable=Boolean(this.attributes.editable),this.columns=[],this.create_columns(a.model,b),this.rows=[],this.table=jQuery("<table/>",{class:"tree table table-hover table-striped"}),this.el.append(this.table),this.thead=jQuery("<thead/>").appendTo(this.table);var d=jQuery("<tr/>");if(this.selection_mode!=Sao.common.SELECTION_NONE){var e=jQuery("<th/>",{class:"selection"});this.selection=jQuery("<input/>",{type:"checkbox",class:"selection"}),this.selection.change(this.selection_changed.bind(this)),e.append(this.selection),d.append(e)}this.thead.append(d),this.columns.forEach(function(a){e=jQuery("<th/>");var b=jQuery("<label/>").text(a.attributes.string);if(this.editable&&(a.attributes.required&&b.addClass("required"),a.attributes.readonly||b.addClass("editable")),a.sortable){var c=jQuery("<span/>");b.append(c),a.arrow=c,e.click(a,this.sort_model.bind(this)),b.addClass("sortable")}d.append(e.append(b)),a.header=e},this),this.tbody=jQuery("<tbody/>"),this.table.append(this.tbody);var f=jQuery("<div/>",{class:"treefooter"});this.more=jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("More")).click(function(){this.display_size+=Sao.config.display_size,this.display()}.bind(this)),f.append(this.more),this.more.hide(),this.display_size=Sao.config.display_size,this.el.append(f)},create_columns:function(a,b){b.find("tree").children().each(function(b,c){for(var d,e,f={},g=0,h=c.attributes.length;g<h;g++)e=c.attributes[g],f[e.name]=e.value;if(["readonly","expand","completion"].forEach(function(a){f[a]&&(f[a]=1==f[a])}),"field"==c.tagName){var i=f.name;f.widget||(f.widget=a.fields[i].description.type);var j=["relation","domain","selection","relation_field","string","views","invisible","add_remove","sort","context","filename","autocomplete","translate","create","delete","selection_change_with","schema_model","required","readonly"];for(g in j){var k=j[g];k in a.fields[i].description&&null===c.getAttribute(k)&&(f[k]=a.fields[i].description[k])}var l=Sao.View.tree_column_get(f.widget);d=new l(a,f);~["url","email","callto","sip"].indexOf(f.widget)&&d.prefixes.push(new Sao.View.Tree.Affix(f,f.widget)),"icon"in f&&d.prefixes.push(new Sao.View.Tree.Affix(f));var m,n,o=c.childNodes;for(g=0;g<o.length;g++){for(m=o[g],n={},g=0,h=m.attributes.length;g<h;g++)e=m.attributes[g],n[e.name]=e.value;n.name||(n.name=i),"prefix"==m.tagName?d.prefixes.push(new Sao.View.Tree.Affix(n)):d.suffixes.push(new Sao.View.Tree.Affix(n))}this.attributes.sequence||this.children_field||a.fields[i].description.sortable===!1||(d.sortable=!0),this.fields[i]=!0}else"button"==c.tagName&&(d=new Sao.View.Tree.ButtonColumn(this.screen,f));this.columns.push(d)}.bind(this))},sort_model:function(a){var b=a.data,c=b.arrow,d="glyphicon glyphicon-triangle-top",e="glyphicon glyphicon-triangle-bottom";this.columns.forEach(function(a){a.arrow&&a!=b&&a.arrow.hasClass("glyphicon")&&a.arrow.removeClass(d+" "+e)}),this.screen.order=this.screen.default_order,c.hasClass(e)?(c.removeClass(e),c.addClass(d),this.screen.order=[[b.attributes.name,"DESC"]]):c.hasClass(d)?c.removeClass(d):(c.addClass(e),this.screen.order=[[b.attributes.name,"ASC"]]);var f=[];this.screen.group.forEach(function(a){a.id<0&&(f=a.group)});var g=this.screen.screen_container.get_text();!jQuery.isEmptyObject(f)||this.screen.search_count==this.screen.group.length||this.screen.parent?this.screen.search_filter(g,!0).then(function(a){this.screen.group.sort(a)}.bind(this)):this.screen.search_filter(g)},get_buttons:function(){var a=[];return this.columns.forEach(function(b){b instanceof Sao.View.Tree.ButtonColumn&&a.push(b)}),a},display:function(a,b){var c=this.screen.current_record;if(!a)if(a=this.get_selected_paths(),c){var d=c.get_path(this.screen.group);d=d.map(function(a){return a[1]}),Sao.common.contains(a,d)||(a=[d])}else c||(a=[]);b=b||[];var e=function(){return this.rows.map(function(a){return a.record})}.bind(this),f=Math.min(this.screen.group.length,this.display_size);this.children_field?this.construct(a,b):f>this.rows.length&&Sao.common.compare(this.screen.group.slice(0,this.rows.length),e())?this.construct(a,b,!0):f==this.rows.length&&Sao.common.compare(this.screen.group,e())||this.construct(a,b);var g=[];jQuery.isEmptyObject(this.screen.domain)||g.push(this.screen.domain);var h=this.screen.screen_container.get_tab_domain();jQuery.isEmptyObject(h)||g.push(h);var i=new Sao.common.DomainInversion;g=i.simplify(g);var j=new Sao.PYSON.Decoder(this.screen.context);return this.columns.forEach(function(a){var b=a.attributes.name;if(b)if(j.decode(a.attributes.tree_invisible||"0"))a.header.hide();else if(b===this.screen.exclude_field)a.header.hide();else{var c=i.domain_inversion(g,b);"boolean"!=typeof c&&(c=i.simplify(c));var d=i.unique_value(c)[0];d&&jQuery.isEmptyObject(this.children_field)?a.header.hide():a.header.show()}}.bind(this)),this.columns.filter(function(a){return a.header.is(":visible")}).length>1?(this.table.addClass("responsive"),this.table.addClass("responsive-header")):(this.table.removeClass("responsive"),this.table.removeClass("responsive-header")),this.redraw(a,b)},construct:function(a,b,c){var d=this.tbody;c||(this.rows=[],this.tbody=jQuery("<tbody/>"));var e=this.rows.length,f=function(c,d,e){var f;f=this.editable?Sao.View.Tree.RowEditable:Sao.View.Tree.Row;var g=new f(this,c,this.rows.length);this.rows.push(g),g.construct(a,b)};this.screen.group.slice(e,this.display_size).forEach(f.bind(this)),this.display_size>=this.screen.group.length?this.more.hide():this.more.show(),c||d.replaceWith(this.tbody)},redraw:function(b,c){return a(this.rows,b,c)},switch_:function(a){this.screen.row_activate()},select_changed:function(a){var b=this.screen.current_record;if(this.screen.set_current_record(a),this.editable&&b){var c=function(){this.screen.set_current_record(b),this.set_cursor()}.bind(this);this.screen.group.parent||b===a?b!==a&&this.screen.attributes.pre_validate&&b.pre_validate().then(function(a){a||c()}):b.validate(this.get_fields()).then(function(a){a?b.save().fail(c):c()})}},selected_records:function(){if(this.selection_mode==Sao.common.SELECTION_NONE)return[];var a=[],b=function(c){c.is_selected()&&a.push(c.record),c.rows.forEach(b)};return this.rows.forEach(b),this.selection.prop("checked")&&!this.selection.prop("indeterminate")&&this.screen.group.slice(this.rows.length).forEach(function(b){a.push(b)}),a},selection_changed:function(){var a=this.selection.prop("checked"),b=function(c){c.set_selection(a),c.rows.forEach(b)};this.rows.forEach(b),a&&this.rows[0]?this.select_changed(this.rows[0].record):this.select_changed(null)},update_selection:function(){if(!this.selection.prop("checked")){var a=this.selected_records();this.selection.prop("indeterminate",!1),jQuery.isEmptyObject(a)?this.selection.prop("checked",!1):a.length==this.tbody.children().length&&this.display_size>=this.screen.group.length?this.selection.prop("checked",!0):(this.selection.prop("indeterminate",!0),this.selection.prop("checked",!0))}},get_selected_paths:function(){function a(c,d){var e,f,g,h;for(e=0,g=c.rows.length;e<g;e++)f=c.rows[e],h=d.concat([f.record.id]),f.is_selected()&&b.push(h),a(f,h)}var b=[];return a(this,[]),b},get_expanded_paths:function(a,b){var c,d,e,f,g;void 0===a&&(a=[]),void 0===b&&(b=[]),d=[],e=this.find_row(a),f=e?e.rows:this.rows;for(var h=0,i=this.n_children(e);h<i;h++)g=a.concat([h]),e=f[h],e&&e.is_expanded()&&(c=b.concat(e.record.id),d.push(c),d=d.concat(this.get_expanded_paths(g,c)));return d},find_row:function(a){for(var b,c=null,d=this.rows,e=0,f=a.length;e<f;e++){if(b=a[e],!d||b>=d.length)return null;if(c=d[b],d=c.rows,!this.children_field)break}return c},n_children:function(a){return a&&this.children_field?a.record._values[this.children_field].length:this.rows.length},set_cursor:function(a,b){var c,d,e,f,g,h,i,j;if(this.screen.current_record){for(d=null,c=0;c<this.rows.length;c++)if(e=this.rows[c].record_to_path(this.screen.current_record)){e.unshift(c),d=e;break}f=null,d?(h=d[0],i=d.slice(1),i.length>0&&this.rows[h].expand_to_path(i),f=this.find_row(d)):this.rows.length>0&&(f=this.rows[0]),f&&(g=f.next_column(null,a),null!==g&&(j=f._get_column_td(g),this.editable?(j.triggerHandler("click"),a?j.triggerHandler("click"):j.find(":input,[tabindex=0]").focus()):j.find(":input,[tabindex=0]").focus()))}}}),Sao.View.Tree.Row=Sao.class_(Object,{init:function(a,b,c,d){this.tree=a,this.rows=[],this.record=b,this.parent_=d,this.children_field=a.children_field,this.expander=null;var e=[];d&&(e=jQuery.extend([],d.path.split("."))),e.push(c),this.path=e.join("."),this.el=jQuery("<tr/>")},is_expanded:function(){return this.path in this.tree.expanded},get_last_child:function(){return this.children_field&&this.is_expanded()&&!jQuery.isEmptyObject(this.rows)?this.rows[this.rows.length-1].get_last_child():this},get_id_path:function(){return this.parent_?this.parent_.get_id_path().concat([this.record.id]):[this.record.id]},build_widgets:function(){var a=jQuery("<table/>");a.css("width","100%");var b=jQuery("<tr/>");return a.append(b),[a,b]},construct:function(a,b){a=a||[],b=b||[];for(var c=this.el[0];c.firstChild;)c.removeChild(c.firstChild);var d;this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(d=jQuery("<td/>"),this.el.append(d),this.selection=jQuery("<input/>",{type:"checkbox",class:"selection"}),this.selection.change(this.selection_changed.bind(this)),d.append(this.selection));for(var e=this.path.split(".").length,f=0;f<this.tree.columns.length;f++){var g=this.tree.columns[f];d=jQuery("<td/>",{"data-title":g.attributes.string}).append(jQuery("<div/>",{"aria-hidden":!0})),d.css("overflow","hidden"),d.on("click keypress",{column:f,td:d},Sao.common.click_press(this.select_row.bind(this),!0)),this.tree.editable||d.dblclick(this.switch_row.bind(this));var h=this.build_widgets(),i=h[0],j=h[1];if(d.append(i),0===f&&this.children_field){var k="glyphicon-plus";(this.is_expanded()||~b.indexOf(this.record.id))&&(k="glyphicon-minus"),this.expander=jQuery("<span/>",{class:"glyphicon "+k,tabindex:0}),this.expander.html(" "),this.expander.css("margin-left",e-1+"em"),this.expander.css("float","left"),this.expander.on("click keypress",Sao.common.click_press(this.toggle_row.bind(this))),j.append(jQuery("<td/>",{class:"expander"}).append(this.expander).css("width",1))}var l;if(g.prefixes)for(l=0;l<g.prefixes.length;l++){g.prefixes[l];j.append(jQuery("<td/>",{class:"prefix"}).css("width",1))}if(j.append(jQuery("<td/>",{class:"widget"})),g.suffixes)for(l=0;l<g.suffixes.length;l++){g.suffixes[l];j.append(jQuery("<td/>",{class:"suffix"}).css("width",1))}this.el.append(d)}if(this.parent_){var m=this.parent_.get_last_child();m.el.after(this.el)}else this.tree.tbody.append(this.el);var n=this.get_id_path();(this.is_expanded()||Sao.common.contains(b,n))&&(this.tree.expanded[this.path]=this,this.expand_children(a,b))},_get_column_td:function(a,b){b=b||this.el;var c=0;return this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(c+=1),jQuery(b.children()[a+c])},redraw:function(b,c){b=b||[],c=c||[];for(var d=function(){jQuery.isEmptyObject(this.record.field_get(this.children_field))&&this.expander.css("visibility","hidden")},e=this.tree.thead.is(":visible"),f=0;f<this.tree.columns.length;f++){0===f&&this.children_field&&this.record.load(this.children_field).done(d.bind(this));var g,h=this.tree.columns[f],i=this._get_column_td(f),j=i.find("tr");if(h.prefixes)for(var k=0;k<h.prefixes.length;k++){var l=h.prefixes[k],m=jQuery(j.children(".prefix")[k]);g=m.children(),g.length?l.render(this.record,g):m.html(l.render(this.record))}var n=j.children(".widget");if(g=n.children(),g.length?h.render(this.record,g):n.html(h.render(this.record)),h.suffixes)for(var o=0;o<h.suffixes.length;o++){var p=h.suffixes[o],q=jQuery(j.children(".suffix")[o]);g=q.children(),g.length?p.render(this.record,g):q.html(p.render(this.record))}h.header.is(":hidden")&&e||"none"==h.header.css("display")?i.hide():i.show()}var r=this.get_id_path();this.set_selection(Sao.common.contains(b,r)),this.is_expanded()||Sao.common.contains(c,r)?(this.tree.expanded[this.path]=this,!this.record._values[this.children_field]||this.record._values[this.children_field].length>0&&0===this.rows.length?this.expand_children(b,c):a(this.rows,b,c),this.expander&&this.update_expander(!0)):this.expander&&this.update_expander(!1),this.record.deleted()||this.record.removed()?this.el.css("text-decoration","line-through"):this.el.css("text-decoration","inherit")},toggle_row:function(){return this.is_expanded()?(this.update_expander(!1),delete this.tree.expanded[this.path],this.collapse_children()):(this.update_expander(!0),this.tree.expanded[this.path]=this,this.expand_children()),!1},update_expander:function(a){a?(this.expander.removeClass("glyphicon-plus"),this.expander.addClass("glyphicon-minus")):(this.expander.removeClass("glyphicon-minus"),this.expander.addClass("glyphicon-plus"))},collapse_children:function(){this.rows.forEach(function(a,b,c){a.collapse_children();var d=a.el[0];d.parentNode.removeChild(d)}),this.rows=[]},expand_children:function(b,c){var d=function(){if(jQuery.isEmptyObject(this.rows)){var d=[],e=function(a,e,f){var g=new this.Class(this.tree,a,e,this);g.construct(b,c),this.rows.push(g),d.push(g)},f=this.record.field_get_client(this.children_field);f.forEach(e.bind(this)),a(d,b,c)}};return this.record.load(this.children_field).done(d.bind(this))},switch_row:function(){window.getSelection?window.getSelection().empty?window.getSelection().empty():window.getSelection().removeAllRanges&&window.getSelection().removeAllRanges():document.selection&&document.selection.empty(),(this.tree.selection_mode==Sao.common.SELECTION_NONE||(this.set_selection(!0),this.selection_changed(),this.is_selected()))&&this.tree.switch_(this.path)},select_row:function(a){this.tree.selection_mode==Sao.common.SELECTION_NONE?(this.tree.select_changed(this.record),this.switch_row()):(a.ctrlKey||this.tree.selection_mode!=Sao.common.SELECTION_SINGLE||this.tree.rows.forEach(function(a){a.set_selection(!1)}.bind(this)),this.set_selection(!this.is_selected()),this.selection_changed());var b=a.data.td,c=a.data.column;b.on("click keypress",{column:c,td:b},Sao.common.click_press(this.select_row.bind(this),!0))},is_selected:function(){return this.tree.selection_mode!=Sao.common.SELECTION_NONE&&this.selection.prop("checked")},set_selection:function(a){this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(this.selection.prop("checked",a),a||this.tree.selection.prop("checked",!1))},selection_changed:function(){var a=this.is_selected();this.set_selection(a),a?this.tree.select_changed(this.record):this.tree.select_changed(this.tree.selected_records()[0]||null),this.tree.update_selection()},record_to_path:function(a){var b,c;if(a==this.record)return[];for(b=0;b<this.rows.length;b++)if(c=this.rows[b].record_to_path(a))return c.unshift(b),c},expand_to_path:function(a){var b,c;b=a[0],c=a.slice(1),c.length>0&&this.rows[b].expand_children().done(function(){this.rows[b].expand_to_path(c)}.bind(this))},next_column:function(a,b,c){var d,e,f,g,h,i;for(c=c||1,null===a&&c>0?a=-1:null===a&&(a=0),h=0,d=0;d<this.tree.columns.length;d++)if(h=(a+c*(d+1))%this.tree.columns.length,h<0&&(h+=this.tree.columns.length),g=this.tree.columns[h],i=g.field.get_state_attrs(this.record),f=i.invisible,g.header.is(":hidden")&&(f=!0),e=!!b&&(g.attributes.readonly||i.readonly),!f&&!e)return h}}),Sao.View.Tree.RowEditable=Sao.class_(Sao.View.Tree.Row,{init:function(a,b,c,d){Sao.View.Tree.RowEditable._super.init.call(this,a,b,c,d),this.edited_column=null},redraw:function(a,b){var c,d,e,f,g;for(Sao.View.Tree.RowEditable._super.redraw.call(this,a,b),c=0;c<this.tree.columns.length;c++)e=this._get_column_td(c),d=e.find("tr"),f=jQuery(d.children(".widget-editable")).data("widget"),f&&(g=this.record.model.fields[f.field_name],f.display(this.record,g))},select_row:function(a){function b(a,d){var e,f;for(e=0;e<a.length;e++)f=a[e],f.is_selected()&&(c=f),f!=d&&f.set_selection(!1),b(f.rows,d)}var c,d,e,f,g;b(this.tree.rows,this),this.selection_changed();var h;h=c&&c!=this&&!this.tree.screen.group.parent?c.record.save():jQuery.when(),h.done(function(){if(c&&null!==c.edited_column){d=c.get_active_td(),d.on("click keypress",{td:d,column:c.edited_column},Sao.common.click_press(c.select_row.bind(c),!0));var b=this.tree.columns[c.edited_column];c.get_static_el().html(b.render(c.record)).show(),c.empty_editable_el()}var h=this.is_selected(),i=a.data.column,j=this.tree.columns[i],k=j.field.get_state_attrs(this.record),l=j.attributes.readonly||k.readonly;if(h&&!l){this.edited_column=i,e=this.get_active_td();var m=j.attributes,n=Sao.View.editabletree_widget_get(m.widget);g=new n(m.name,this.tree.screen.model,m),g.view=this.tree,g.el.on("focusin",function(){jQuery(this).parents(".treeview td").css("overflow","visible")}),g.el.on("focusout",function(){jQuery(this).parents(".treeview td").css("overflow","hidden")});var o=this.get_editable_el();o.append(g.el),o.data("widget",g),g.el.on("keydown",this.key_press.bind(this)),f=this.record.model.fields[g.field_name],g.display(this.record,f),this.get_static_el().hide(),this.get_editable_el().show(),g.el.focus()}else if(!h){this.set_selection(!0),this.selection_changed();var p=a.data.td;p.on("click keypress",{column:i,td:p},Sao.common.click_press(this.select_row.bind(this),!0))}}.bind(this))},get_static_el:function(){var a=this.get_active_td();return a.find(".widget")},get_editable_el:function(){var a=this.get_active_td(),b=a.find(".widget-editable");return b.length||(b=jQuery("<td/>",{class:"widget-editable"}).insertAfter(a.find(".widget"))),b},empty_editable_el:function(){var a;a=this.get_editable_el(),a.empty(),a.data("widget",null),this.edited_column=null},get_active_td:function(){return this._get_column_td(this.edited_column)},key_press:function(a){var b,c,d,e,f;if(a.which==Sao.common.TAB_KEYCODE||a.which==Sao.common.UP_KEYCODE||a.which==Sao.common.DOWN_KEYCODE||a.which==Sao.common.ESC_KEYCODE||a.which==Sao.common.RETURN_KEYCODE){var g=this.tree.columns[this.edited_column];if(g.field.validate(this.record))if(a.which==Sao.common.TAB_KEYCODE){var h=1;a.shiftKey&&(h=-1),a.preventDefault(),d=this.next_column(this.edited_column,!0,h),null!==d&&window.setTimeout(function(){var a=this._get_column_td(d);a.triggerHandler("click",{column:d,td:a})}.bind(this),0)}else if(a.which==Sao.common.UP_KEYCODE||a.which==Sao.common.DOWN_KEYCODE)f=a.which==Sao.common.UP_KEYCODE?this.el.prev("tr"):this.el.next("tr"),c=this.edited_column,this.record.validate(this.tree.get_fields()).then(function(a){if(a){if(this.tree.screen.attributes.pre_validate)return this.record.pre_validate().fail(function(){f=null});if(!this.tree.screen.model.parent)return this.record.save().fail(function(){f=null})}else{f=null;var b=this.record.invalid_fields();for(e=0;e<this.tree.columns.length;e++){var d=this.tree.columns[e];d.attributes.name in b&&(c=e)}}}.bind(this)).then(function(){window.setTimeout(function(){this._get_column_td(c,f).trigger("click").trigger("click")}.bind(this),0)}.bind(this));else if(a.which==Sao.common.ESC_KEYCODE)this.get_static_el().show(),b=this.get_active_td(),b.on("click keypress",{column:this.edited_column,td:b},Sao.common.click_press(this.select_row.bind(this),!0)),this.empty_editable_el();else if(a.which==Sao.common.RETURN_KEYCODE){var i=function(a){var b=this._get_column_td(this.edited_column,a);b.triggerHandler("click"),b.triggerHandler("click")}.bind(this);if(f="bottom"==this.tree.attributes.editable?this.el.next("tr"):this.el.prev("tr"),f.length)i(f);else{var j,k=this.tree.screen.group,l=Sao.common.MODELACCESS.get(this.tree.screen.model_name),m=null!==this.tree.screen.size_limit&&k.length>=this.tree.screen.size_limit;j=!l.create||m?jQuery.when():this.tree.screen.new_(),j.done(function(){var a,b=this.tree.tbody.children("tr");a="bottom"==this.tree.attributes.editable?b.last():b.first(),i(a)}.bind(this))}}}}}),Sao.View.Tree.Affix=Sao.class_(Object,{init:function(a,b){this.attributes=a,this.protocol=b||null,this.icon=a.icon,this.protocol&&!this.icon&&(this.icon="tryton-web-browser")},get_cell:function(){var a;return this.protocol?(a=jQuery("<a/>",{target:"_new"}),a.append(jQuery("<img/>")),a.click({cell:a},this.clicked.bind(this))):this.icon?a=jQuery("<img/>"):(a=jQuery("<span/>"),a.attr("tabindex",0)),a.addClass("column-affix"),a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){var c,d,e=a.model.fields[this.attributes.name],f=e.get_state_attrs(a).invisible;if(f?b.hide():b.show(),this.protocol){if(c=e.get(a),!jQuery.isEmptyObject(c))switch(this.protocol){case"email":c="mailto:"+c;break;case"callto":c="callto:"+c;break;case"sip":c="sip:"+c}b.attr("src",c)}if(this.icon){if(this.icon in a.model.fields){var g=a.model.fields[this.icon];c=g.get_client(a)}else c=this.icon;d=Sao.common.ICONFACTORY.register_icon(c),d.done(function(a){var c;c=b.children("img").length?b.children("img"):b,c.attr("src",a)}.bind(this))}else c=this.attributes.string||"",c||(c=e.get_client(a)||""),b.text(c)}.bind(this)),b},clicked:function(a){a.preventDefault(),window.open(a.data.cell.attr("src"),"_blank")}}),Sao.View.Tree.CharColumn=Sao.class_(Object,{class_:"column-char",init:function(a,b){this.type="field",this.model=a,this.field=a.fields[b.name],this.attributes=b,this.prefixes=[],this.suffixes=[],this.header=null},get_cell:function(){var a=jQuery("<div/>",{class:this.class_,tabindex:0});return a},update_text:function(a,b){a.text(this.field.get_client(b))},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){this.update_text(b,a),this.field.set_state(a);var c=this.field.get_state_attrs(a);c.invisible?b.hide():b.show()}.bind(this)),b}}),Sao.View.Tree.TextColum=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-text"}),Sao.View.Tree.IntegerColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-integer",init:function(a,b){Sao.View.Tree.IntegerColumn._super.init.call(this,a,b),this.factor=Number(b.factor||1)},get_cell:function(){return Sao.View.Tree.IntegerColumn._super.get_cell.call(this)},update_text:function(a,b){a.text(this.field.get_client(b,this.factor))}}),Sao.View.Tree.FloatColumn=Sao.class_(Sao.View.Tree.IntegerColumn,{class_:"column-float"}),Sao.View.Tree.BooleanColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-boolean",get_cell:function(){return jQuery("<input/>",{type:"checkbox",disabled:!0,class:this.class_,tabindex:0})},update_text:function(a,b){a.prop("checked",this.field.get(b))}}),Sao.View.Tree.Many2OneColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-many2one"}),Sao.View.Tree.One2OneColumn=Sao.class_(Sao.View.Tree.Many2OneColumn,{class_:"column-one2one"}),Sao.View.Tree.SelectionColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-selection",init:function(a,b){Sao.View.Tree.SelectionColumn._super.init.call(this,a,b),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a)},update_selection:function(a,b){Sao.common.selection_mixin.update_selection.call(this,a,this.field,b)},update_text:function(a,b){this.update_selection(b,function(){for(var c,d,e=this.field.get(b),f=!1,g=0,h=this.selection.length;g<h;g++)if(this.selection[g][0]===e){f=!0,d=this.selection[g][1];break}c=f?jQuery.when(d):Sao.common.selection_mixin.get_inactive_selection.call(this,e).then(function(a){return a[1]}),c.done(function(b){a.text(b)}.bind(this))}.bind(this))}}),Sao.View.Tree.ReferenceColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-reference",init:function(a,b){Sao.View.Tree.ReferenceColumn._super.init.call(this,a,b),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a)},update_selection:function(a,b){Sao.common.selection_mixin.update_selection.call(this,a,this.field,b)},update_text:function(a,b){this.update_selection(b,function(){var c,d,e=this.field.get_client(b);if(e?(c=e[0],d=e[1]):(c="",d=""),c){for(var f=0,g=this.selection.length;f<g;f++)if(this.selection[f][0]===c){c=this.selection[f][1];break}a.text(c+","+d)}else a.text(d)}.bind(this))}}),Sao.View.Tree.DateColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-date",update_text:function(a,b){var c=this.field.get_client(b),d=this.field.date_format(b);a.text(Sao.common.format_date(d,c))}}),Sao.View.Tree.TimeColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-time",update_text:function(a,b){var c=this.field.get_client(b);a.text(Sao.common.format_time(this.field.time_format(b),c))}}),Sao.View.Tree.TimeDeltaColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-timedelta"}),Sao.View.Tree.One2ManyColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-one2many",update_text:function(a,b){a.text("( "+this.field.get_client(b).length+" )")}}),Sao.View.Tree.Many2ManyColumn=Sao.class_(Sao.View.Tree.One2ManyColumn,{class_:"column-many2many"}),Sao.View.Tree.BinaryColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-binary",update_text:function(a,b){var c;c=this.field.get_size?this.field.get_size(b):this.field.get(b).length,a.text(Sao.common.humanize(c))}}),Sao.View.Tree.ImageColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-image",get_cell:function(){var a=jQuery("<img/>",{class:this.class_,tabindex:0});return a.css("width","100%"),a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){var c=this.field.get_client(a);c=c?c>Sao.common.BIG_IMAGE_SIZE?jQuery.when(null):this.field.get_data(a):jQuery.when(null),c.done(function(a){var c,d;a?(d=new Blob([a]),c=window.URL.createObjectURL(d)):c=null,b.attr("src",c)}.bind(this))}.bind(this)),b}}),Sao.View.Tree.URLColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-url",render:function(a,b){b=Sao.View.Tree.URLColumn._super.render.call(this,a,b),this.field.set_state(a);var c=this.field.get_state_attrs(a);return c.readonly?b.hide():b.show(),b}}),Sao.View.Tree.ProgressBar=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-progressbar",get_cell:function(){var a=jQuery("<div/>",{class:this.class_+" progress",tabindex:0}),b=jQuery("<div/>",{class:"progress-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100}).appendTo(a);return b.css("min-width: 2em"),a},update_text:function(a,b){var c=this.field.get_client(b,100);c&&(c=Sao.i18n.gettext("%1%",c));var d=this.field.get(b)||0,e=a.find(".progress-bar");e.attr("aria-valuenow",100*d),e.css("width",100*d+"%"),e.text(c)}}),Sao.View.Tree.ButtonColumn=Sao.class_(Object,{init:function(a,b){this.screen=a,this.type="button",this.attributes=b},render:function(a,b){var c=new Sao.common.Button(this.attributes,b);b||c.el.click([a,c],this.button_clicked.bind(this));var d=jQuery.map(this.screen.model.fields,function(a,b){return"eager"==(a.description.loading||"eager")?b:void 0});return a.load(d[0]).done(function(){c.set_state(a)}),c.el},button_clicked:function(a){var b=a.data[0],c=a.data[1];if(b==this.screen.current_record){var d=b.expr_eval(this.attributes.states||{});if(!d.invisible&&!d.readonly){c.el.prop("disabled",!0);try{this.screen.button(this.attributes)}finally{c.el.prop("disabled",!1)}}}}}),Sao.View.editabletree_widget_get=function(a){switch(a){case"char":case"text":case"url":case"email":case"callto":case"sip":return Sao.View.EditableTree.Char;case"date":return Sao.View.EditableTree.Date;case"time":return Sao.View.EditableTree.Time;case"timedelta":return Sao.View.EditableTree.TimeDelta;case"integer":case"biginteger":return Sao.View.EditableTree.Integer;case"float":case"numeric":return Sao.View.EditableTree.Float;case"selection":return Sao.View.EditableTree.Selection;case"boolean":return Sao.View.EditableTree.Boolean;case"many2one":return Sao.View.EditableTree.Many2One;case"reference":return Sao.View.EditableTree.Reference;case"one2one":return Sao.View.EditableTree.One2One;case"one2many":case"many2many":return Sao.View.EditableTree.One2Many;case"binary":return Sao.View.EditableTree.Binary}},Sao.View.EditableTree={},Sao.View.EditableTree.editable_mixin=function(a){var b=function(a){a.which!=Sao.common.TAB_KEYCODE&&a.which!=Sao.common.UP_KEYCODE&&a.which!=Sao.common.DOWN_KEYCODE&&a.which!=Sao.common.ESC_KEYCODE&&a.which!=Sao.common.RETURN_KEYCODE||this.focus_out()};a.el.on("keydown",b.bind(a))},Sao.View.EditableTree.Char=Sao.class_(Sao.View.Form.Char,{
-class_:"editabletree-char",init:function(a,b,c){Sao.View.EditableTree.Char._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Date=Sao.class_(Sao.View.Form.Date,{class_:"editabletree-date",init:function(a,b,c){Sao.View.EditableTree.Date._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Time=Sao.class_(Sao.View.Form.Time,{class_:"editabletree-time",init:function(a,b,c){Sao.View.EditableTree.Time._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.TimeDelta=Sao.class_(Sao.View.Form.TimeDelta,{class_:"editabletree-timedelta",init:function(a,b,c){Sao.View.EditableTree.TimeDelta._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Integer=Sao.class_(Sao.View.Form.Integer,{class_:"editabletree-integer",init:function(a,b,c){Sao.View.EditableTree.Integer._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Float=Sao.class_(Sao.View.Form.Float,{class_:"editabletree-float",init:function(a,b,c){Sao.View.EditableTree.Float._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Selection=Sao.class_(Sao.View.Form.Selection,{class_:"editabletree-selection",init:function(a,b,c){Sao.View.EditableTree.Selection._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Boolean=Sao.class_(Sao.View.Form.Boolean,{class_:"editabletree-boolean",init:function(a,b,c){Sao.View.EditableTree.Boolean._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Many2One=Sao.class_(Sao.View.Form.Many2One,{class_:"editabletree-many2one",init:function(a,b,c){Sao.View.EditableTree.Many2One._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.Many2One._super.key_press.call(this,a)}}),Sao.View.EditableTree.Reference=Sao.class_(Sao.View.Form.Reference,{class_:"editabletree-reference",init:function(a,b,c){Sao.View.EditableTree.Reference._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.Reference._super.key_press.call(this,a)}}),Sao.View.EditableTree.One2One=Sao.class_(Sao.View.Form.One2One,{class_:"editabletree-one2one",init:function(a,b,c){Sao.View.EditableTree.One2One._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.One2One._super.key_press.call(this,a)}}),Sao.View.EditableTree.One2Many=Sao.class_(Sao.View.EditableTree.Char,{class_:"editabletree-one2many",init:function(a,b,c){Sao.View.EditableTree.One2Many._super.init.call(this,a,b,c)},display:function(a,b){a?this.el.val("("+b.get_client(a).length+")"):this.el.val("")},key_press:function(a){a.which==Sao.common.TAB_KEYCODE&&this.focus_out()},set_value:function(a,b){}}),Sao.View.EditableTree.Binary=Sao.class_(Sao.View.Form.Binary,{class_:"editabletree-binary",init:function(a,b,c){Sao.View.EditableTree.Binary._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}})}(),function(){"use strict";Sao.View.Graph=Sao.class_(Sao.View,{init:function(a,b){Sao.View.Graph._super.init.call(this,a,b),this.view_type="graph",this.el=jQuery("<div/>",{class:"graph"}),this.widgets={},this.widget=this.parse(b.children()[0]),this.widgets.root=this.widget,this.el.append(this.widget.el)},parse:function(a){var b,c,d,e,f,g,h,i=null,j=[],k=function(a){for(var b,c={},d=0,e=a.attributes.length;d<e;d++)b=a.attributes[d],c[b.name]=b.value;return c};for(e=0,f=a.children.length;e<f;e++)switch(d=a.children[e],d.tagName){case"x":for(g=0,h=d.children.length;g<h;g++)i=k(d.children[g]),b=this.screen.model.fields[i.name],i.string||(i.string=b.description.string);break;case"y":for(g=0,h=d.children.length;g<h;g++)c=k(d.children[g]),c.string||"#"==c.name||(b=this.screen.model.fields[c.name],c.string=b.description.string),j.push(c)}var l;switch(this.attributes.type){case"hbar":l=Sao.View.Graph.HorizontalBar;break;case"line":l=Sao.View.Graph.Line;break;case"pie":l=Sao.View.Graph.Pie;break;default:l=Sao.View.Graph.VerticalBar}return new l(this,i,j)},display:function(){return this.widget.display(this.screen.group)}}),Sao.View.Graph.Chart=Sao.class_(Object,{_chart_type:void 0,init:function(a,b,c){this.view=a,this.xfield=b,this.yfields=c,this.el=jQuery("<div/>"),this.el.uniqueId()},update_data:function(a){var b,c,d,e,f,g,h,i={};this.ids={},i.columns=[["labels"]],i.names={};var j={},k=[this.xfield.name];for(e=0,f=this.yfields.length;e<f;e++)c=this.yfields[e],i.columns.push([c.name]),i.names[c.name]=c.string,j[c.key||c.name]=e+1,k.push(c.name);var l=[],m=function(e){return function(){b=a[e];var f=b.field_get_client(this.xfield.name);i.columns[0][e+1]=f,this._add_id(f,b.id);var k;for(g=0,h=this.yfields.length;g<h;g++){if(c=this.yfields[g],d=c.key||c.name,k=i.columns[j[d]],c.domain){var l=jQuery.extend({},Sao.session.current_session.context);l.context=l,l._user=Sao.session.current_session.user_id;for(var m in a.model.fields)l[m]=b.field_get(m);var n=new Sao.PYSON.Decoder(l);if(!n.decode(c.domain)){k[e+1]=0;continue}}if("#"==c.name)k[e+1]=1;else{var o=b.field_get(c.name);o&&o.isTimeDelta&&(o=o.asSeconds()),k[e+1]=o||0}}}.bind(this)}.bind(this),n=function(a){return function(b){l.push(a.load(b))}},o=[];for(e=0,f=a.length;e<f;e++){for(b=a[e],k.forEach(n(a[e])),g=0,h=i.columns.length;g<h;g++)i.columns[g].push(void 0);o.push(jQuery.when.apply(jQuery,l).then(m(e)))}return jQuery.when.apply(jQuery,o).then(function(){return i})},_add_id:function(a,b){var c=a.isDate||a.isDateTime?a._d:a;c in this.ids||(this.ids[c]=[]),this.ids[c].push(b)},display:function(a){var b=this.update_data(a);return b.done(function(a){c3.generate(this._c3_config(a))}.bind(this)),b},_c3_config:function(a){var b={};b.bindto="#"+this.el.attr("id"),b.data=a,b.data.type=this._chart_type,b.data.x="labels",b.data.onclick=this.action.bind(this);var c,d,e,f;for(c=0,d=a.columns.length;c<d;c++)if(f=a.columns[c],"labels"==f[0]){e=!0;break}if(e&&f.length>1&&f[1]&&(f[1].isDateTime||f[1].isDate)){var g,h,i;h=this.view.screen.context.date_format||"%x",i="%X",g=f[1].isDateTime?function(a){return Sao.common.format_datetime(h,i,moment(a))}:function(a){return Sao.common.format_date(h,moment(a))},b.axis={x:{type:"timeseries",tick:{format:g}}}}else b.axis={x:{type:"category"}};return b},action:function(a,b){var c=this.ids[this._action_key(a)],d=jQuery.extend({},this.view.screen.context);delete d.active_ids,delete d.active_id,Sao.Action.exec_keyword("graph_open",{model:this.view.screen.model_name,id:c[0],ids:c},d,!1)},_action_key:function(a){return a.x}}),Sao.View.Graph.VerticalBar=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"bar"}),Sao.View.Graph.HorizontalBar=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"bar",_c3_config:function(a){var b=Sao.View.Graph.HorizontalBar._super._c3_config.call(this,a);b.axis.rotated=!0}}),Sao.View.Graph.Line=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"line"}),Sao.View.Graph.Pie=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"pie",_c3_config:function(a){var b,c,d,e,f=Sao.View.Graph.Pie._super._c3_config.call(this,a),g=[],h={};for(b=0,c=a.columns.length;b<c;b++)"labels"==a.columns[b][0]?d=a.columns[b].slice(1):e=a.columns[b].slice(1);delete f.axis,delete f.data.x;var i,j,k;d.length>0&&(d[0].isDateTime||d[0].isDate)&&(j=this.view.screen.context.date_format||"%x",k=j+" %X",i=d[1].isDateTime?function(a){return Sao.common.format_datetime(k,a)}:function(a){return Sao.common.format_date(j,a)});var l;for(b=0,c=d.length;b<c;b++)l=d[b],i&&(l=i(l)),g.push([b,e[b]]),h[b]=l;return f.data.columns=g,f.data.names=h,f},_add_id:function(a,b){var c=a;if(a.isDateTime||a.isDate){var d=this.view.screen.context.date_format||"%x",e=d+" %X";c=a.isDateTime?Sao.common.format_datetime(e,a):Sao.common.format_date(d,a)}c in this.ids||(this.ids[c]=[]),this.ids[c].push(b)},_action_key:function(a){return a.id}})}(),function(){"use strict";Sao.View.Calendar=Sao.class_(Sao.View,{init:function(a,b){Sao.View.Calendar._super.init.call(this,a,b),this.processing=!0,this.view_type="calendar",this.el=jQuery("<div/>",{class:"calendar"});var c=Sao.i18n.getlang();c=c.slice(0,2);var d="month";"week"==this.attributes.mode&&(d=this.get_week_view()),this.el.fullCalendar({defaultView:d,header:{left:"prev,next",center:"title",right:" month,"+this.get_week_view()},timeFormat:"H:mm",events:this.get_events.bind(this),locale:c,buttonIcons:!1,eventRender:this.event_render.bind(this),eventResize:this.event_resize.bind(this),eventDrop:this.event_drop.bind(this),eventClick:this.event_click.bind(this),dayClick:this.day_click.bind(this)}),this.fields=[],b.find("calendar").children().each(function(a,b){"field"==b.tagName&&this.fields.push(b.attributes.name.value)}.bind(this)),this.el.fullCalendar("changeView",d)},get_colors:function(a){var b={};return b.text_color="black",this.attributes.color&&(b.text_color=a.field_get(this.attributes.color)),b.background_color="lightblue",this.attributes.background_color&&(b.background_color=a.field_get(this.attributes.background_color)),b},display:function(){this.el.fullCalendar("render"),this.processing||this.el.fullCalendar("refetchEvents")},insert_event:function(a){var b=this.screen.model.fields[this.fields[0]].get_client(a),c=a.field_get_client(this.attributes.dtstart),d=null;this.attributes.dtend&&(d=a.field_get_client(this.attributes.dtend));for(var e=!0,f=[],g=1;g<this.fields.length;g++)f.push(this.screen.model.fields[this.fields[g]].get_client(a));if(f=f.join("\n"),c){if(d&&d.isDateTime?e=!1:d&&!d.isSame(c)&&"calendar"==this.screen.current_view.view_type&&d.add(1,"day"),d&&c>d)return;var h=this.get_colors(a),i={title:b,start:c,end:d,allDay:e,editable:!0,color:h.background_color,textColor:h.text_color,record:a,description:f};this.events.push(i)}},get_events:function(a,b,c,d){this.processing=!0,this.start=Sao.DateTime(a.utc()),this.end=Sao.DateTime(b.utc());var e=jQuery.when();if("form"!=this.screen.current_view.view_type){var f=this.screen.screen_container.get_text();e=this.screen.search_filter(f)}this.events=[];var g=[];e.then(function(){return this.screen.group.forEach(function(a){var b=[];this.fields.forEach(function(c){b.push(a.load(c))});var c=jQuery.when.apply(jQuery,b).then(function(){this.insert_event(a)}.bind(this));g.push(c)}.bind(this)),jQuery.when.apply(jQuery,g).then(function(){d(this.events)}.bind(this)).always(function(){this.processing=!1}.bind(this))}.bind(this))},get_week_view:function(){return"datetime"==this.screen.model.fields[this.attributes.dtstart].description.type?"agendaWeek":"basicWeek"},event_click:function(a,b,c){this.clicked_event||(this.clicked_event=!0,this.screen.set_current_record(a.record),this.screen.switch_view().always(function(){this.clicked_event=!1}.bind(this)))},event_drop:function(a,b,c,d,e,f){var g=this.attributes.dtstart,h=this.attributes.dtend,i=a.record,j=(i.group,i.field_get(g)),k=j;h&&(k=i.field_get(h));var l=a.start,m=a.end;m!=j&&m||(m=l),j.isDateTime?(m=Sao.DateTime(m.format()).utc(),l=Sao.DateTime(l.format()).utc()):j.isSame(k)||(m.subtract(1,"day"),this.el.fullCalendar("refetchEvents")),j<=l?(h&&i.field_set_client(h,m),i.field_set_client(g,l)):(i.field_set_client(g,l),h&&i.field_set_client(h,m)),i.save()},event_resize:function(a,b,c,d,e,f){var g=this.attributes.dtend,h=a.record,i=(h.group,h.field_get(g)),j=a.end;i.isDateTime===!0?j=Sao.DateTime(j.format()).utc():(j.subtract(1,"day"),this.el.fullCalendar("refetchEvents")),j!=i&&j||(j=i),h.field_set_client(g,j),h.save()},event_render:function(a,b,c){this.screen.model.fields.date&&"calendar"==this.screen.view_name&&b.find(".fc-time").remove(),b.append(a.description),b.css("white-space","pre");var d=Sao.common.MODELACCESS.get(this.screen.model_name);d.write||(a.editable=!1)},day_click:function(a,b,c){var d=Sao.common.MODELACCESS.get(this.screen.model_name);d.create&&(this.date=a,this.screen.set_current_record(null),this.screen.new_())},current_domain:function(){if(!this.start&&!this.end)return[["id","=",-1]];var a=Sao.DateTime(this.start),b=Sao.DateTime(this.end),c=this.attributes.dtstart,d=this.attributes.dtend||c;return["OR",["AND",[c,">=",a],[c,"<",b]],["AND",[d,">=",a],[d,"<",b]],["AND",[c,"<",a],[d,">",b]]]},get_displayed_period:function(){var a=[];return this.start&&this.end&&a.push(this.start,this.end),a},set_default_date:function(a,b){var c=this.attributes.dtstart;"datetime"==a.model.fields[c].description.type&&(b=Sao.DateTime(b.format()).utc()),a.field_set_client(c,b)}})}(),function(){"use strict";Sao.Action={report_blob_url:void 0},Sao.Action.exec_action=function(a,b,c){function d(a){if(!b.model||!b.ids)return jQuery.when(a);var d=5,e=b.ids.slice(0,d);return Sao.rpc({method:"model."+b.model+".read",params:[e,["rec_name"],c]},Sao.Session.current_session).then(function(c){var e=c.map(function(a){return a.rec_name}).join(Sao.i18n.gettext(", "));return b.ids.length>d&&(e+=Sao.i18n.gettext(",…")),Sao.i18n.gettext("%1 (%2)",a,e)})}c=void 0===c?{}:jQuery.extend({},c);var e=Sao.Session.current_session;"date_format"in c||e.context.locale&&e.context.locale.date&&(c.date_format=e.context.locale.date),b=void 0===b?{}:jQuery.extend({},b),b.action_id=a.id;var f,g={};switch(a.type){case"ir.action.act_window":g.view_ids=!1,g.mode=null,jQuery.isEmptyObject(a.views)?jQuery.isEmptyObject(a.view_id)||(g.view_ids=[a.view_id[0]]):(g.view_ids=[],g.mode=[],a.views.forEach(function(a){g.view_ids.push(a[0]),g.mode.push(a[1])})),void 0===a.pyson_domain&&(a.pyson_domain="[]");var h={active_model:b.model||null,active_id:b.id||null,active_ids:b.ids};h=jQuery.extend(h,e.context);var i=jQuery.extend({},h);i._user=e.user_id,g.context=jQuery.extend({},c,new Sao.PYSON.Decoder(i).decode(a.pyson_context||"{}")),h=jQuery.extend(h,g.context),h=jQuery.extend(h,c);var j=jQuery.extend({},h);j.context=h,j._user=e.user_id;var k=new Sao.PYSON.Decoder(j);return g.domain=k.decode(a.pyson_domain),g.order=k.decode(a.pyson_order),g.search_value=k.decode(a.pyson_search_value||"[]"),g.tab_domain=[],a.domains.forEach(function(a,b){g.tab_domain.push([a[0],k.decode(a[1]),a[2]])}),f=jQuery.when(a.name),g.model=a.res_model||b.res_model,g.res_id=a.res_id||b.res_id,g.context_model=a.context_model,g.limit=a.limit,g.icon=a["icon.rec_name"]||"","form_relate"===(a.keyword||"")&&(f=d(a.name)),void f.then(function(a){g.name=a,Sao.Tab.create(g)});case"ir.action.wizard":return g.action=a.wiz_name,g.data=b,g.context=c,g.window=a.window,f=jQuery.when(a.name),"form_action"===(a.keyword||"form_action")&&(f=d(a.name)),void f.done(function(a){g.name=a,Sao.Wizard.create(g)});case"ir.action.report":return g.name=a.report_name,g.data=b,g.direct_print=a.direct_print,g.email_print=a.email_print,g.email=a.email,g.context=c,void Sao.Action.exec_report(g);case"ir.action.url":return void window.open(a.url,"_blank")}},Sao.Action.exec_keyword=function(a,b,c,d,e){void 0===d&&(d=!0),void 0===e&&(e=!1);var f=b.id,g={method:"model.ir.action.keyword.get_keyword",params:[a,[b.model,f],{}]},h=Sao.rpc(g,Sao.Session.current_session),i=function(a){var f={};for(var g in a){var h=a[g];f[h.name.replace(/_/g,"")]=h}var i=Sao.common.selection(Sao.i18n.gettext("Select your action"),f,e);return i.then(function(a){Sao.Action.exec_action(a,b,c)},function(){jQuery.isEmptyObject(f)&&d&&alert(Sao.i18n.gettext("No action defined."))})};return h.pipe(i)},Sao.Action.exec_report=function(a){a.context||(a.context={}),a.email||(a.email={});var b=jQuery.extend({},a.data),c=jQuery.extend({},Sao.Session.current_session.context);jQuery.extend(c,a.context),c.direct_print=a.direct_print,c.email_print=a.email_print,c.email=a.email;var d=Sao.rpc({method:"report."+a.name+".execute",params:[b.ids||[],b,c]},Sao.Session.current_session);d.done(function(a){var b=a[0],c=a[1],d=(a[2],a[3],new Blob([c],{type:Sao.common.guess_mimetype(b)})),e=window.URL.createObjectURL(d);Sao.Action.report_blob_url&&window.URL.revokeObjectURL(Sao.Action.report_blob_url),Sao.Action.report_blob_url=e,window.open(e)})},Sao.Action.execute=function(a,b,c,d){c?Sao.rpc({method:"model."+c+".search_read",params:[[["action","=",a]],0,1,null,null,d]},Sao.Session.current_session).done(function(a){Sao.Action.exec_action(a[0],b,d)}):Sao.rpc({method:"model.ir.action.read",params:[[a],["type"],d]},Sao.Session.current_session).done(function(c){Sao.Action.execute(a,b,c[0].type,d)})},Sao.Action.evaluate=function(a,b,c){a=jQuery.extend({},a);var d={};return"pyson_email"in a&&(d=c.expr_eval(a.pyson_email),jQuery.isEmptyObject(d)&&(d={})),"subject"in d||(d.subject=a.name.replace(/_/g,"")),a.email=d,a}}(),function(){"use strict";Sao.common={},Sao.common.BACKSPACE_KEYCODE=8,Sao.common.TAB_KEYCODE=9,Sao.common.RETURN_KEYCODE=13,Sao.common.ESC_KEYCODE=27,Sao.common.UP_KEYCODE=38,Sao.common.DOWN_KEYCODE=40,Sao.common.DELETE_KEYCODE=46,Sao.common.F2_KEYCODE=113,Sao.common.F3_KEYCODE=114,Sao.common.SELECTION_NONE=1,Sao.common.SELECTION_SINGLE=2,Sao.common.SELECTION_MULTIPLE=3,Sao.common.BIG_IMAGE_SIZE=Math.pow(10,6),Sao.common.compare=function(a,b){if(a.length!=b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]instanceof Array&&b[c]instanceof Array){if(!Sao.common.compare(a[c],b[c]))return!1}else if(a[c]!=b[c])return!1;return!0},Sao.common.contains=function(a,b){for(var c=0;c<a.length;c++)if(Sao.common.compare(a[c],b))return!0;return!1},Sao.common.intersect=function(a,b){for(var c=0,d=0,e=[];c<a.length&&d<b.length;)a[c]<b[d]?c++:a[c]>b[d]?d++:(e.push(a[c]),c++,d++);return e},Sao.common.click_press=function(a,b){return function c(d){if("keypress"!=d.type||d.which==Sao.common.RETURN_KEYCODE)return b&&jQuery(this).off("click keypress",null,c),a(d)}},Sao.common.product=function(a,b){b=b||1;for(var c=[],d=0;d<b;)c=c.concat(a),d++;var e=[[]];return c.forEach(function(a){var b=[];e.forEach(function(c){a.forEach(function(a){b.push(c.concat([a]))})}),e=b}),e},Sao.common.selection=function(a,b,c){void 0===c&&(c=!1);var d=jQuery.Deferred();if(jQuery.isEmptyObject(b))return d.fail(),d;var e=Object.keys(b).sort();if(1==e.length&&!c){var f=e[0];return d.resolve(b[f]),d}var g=new Sao.Dialog(a||Sao.i18n.gettext("Your selection:"),"selection-dialog");return e.forEach(function(a,b){jQuery("<div/>",{class:"checkbox"}).append(jQuery("<label/>").append(jQuery("<input/>",{type:"radio",name:"selection",value:b})).append(" "+a)).appendTo(g.body)}),g.body.find("input").first().prop("checked",!0),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){g.modal.modal("hide"),d.fail()}).appendTo(g.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){var a=g.body.find("input:checked").attr("value");g.modal.modal("hide"),d.resolve(b[e[a]])}).appendTo(g.footer),g.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),g.modal.modal("show"),d},Sao.common.moment_format=function(a){return a.replace("%a","ddd").replace("%A","dddd").replace("%w","d").replace("%d","DD").replace("%b","MMM").replace("%B","MMMM").replace("%m","MM").replace("%y","YY").replace("%Y","YYYY").replace("%H","HH").replace("%I","hh").replace("%p","A").replace("%M","mm").replace("%S","ss").replace("%f","SSS").replace("%z","ZZ").replace("%Z","zz").replace("%j","DDDD").replace("%U","ww").replace("%W","WW").replace("%c","llll").replace("%x","L").replace("%X","LTS").replace("%","%%")},Sao.common.date_format=function(a){if(jQuery.isEmptyObject(a)&&(a="%Y-%m-%d",Sao.Session.current_session)){var b=Sao.Session.current_session.context;b.locale&&b.locale.date&&(a=b.locale.date)}return Sao.common.moment_format(a)},Sao.common.format_time=function(a,b){return b?b.format(Sao.common.moment_format(a)):""},Sao.common.parse_time=function(a,b){if(jQuery.isEmptyObject(b))return null;var c=function(c){var d=a.indexOf(c);if(~d){var e=parseInt(b.slice(d,d+c.length),10);if(!isNaN(e))return e}return 0};return Sao.Time(c("%H"),c("%M"),c("%S"),c("%f"))},Sao.common.format_date=function(a,b){return b?b.format(Sao.common.moment_format(a)):""},Sao.common.parse_date=function(a,b){var c=moment(b,Sao.common.moment_format(a));return c=c.isValid()?Sao.Date(c.year(),c.month(),c.date()):null},Sao.common.format_datetime=function(a,b,c){return c?c.format(Sao.common.moment_format(a+" "+b)):""},Sao.common.parse_datetime=function(a,b,c){var d=moment(c,Sao.common.moment_format(a+" "+b));return d=d.isValid()?Sao.DateTime(d.year(),d.month(),d.date(),d.hour(),d.minute(),d.second(),d.millisecond()):null},Sao.common.timedelta={},Sao.common.timedelta.DEFAULT_CONVERTER={s:1},Sao.common.timedelta.DEFAULT_CONVERTER.m=60*Sao.common.timedelta.DEFAULT_CONVERTER.s,Sao.common.timedelta.DEFAULT_CONVERTER.h=60*Sao.common.timedelta.DEFAULT_CONVERTER.m,Sao.common.timedelta.DEFAULT_CONVERTER.d=24*Sao.common.timedelta.DEFAULT_CONVERTER.h,Sao.common.timedelta.DEFAULT_CONVERTER.w=7*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta.DEFAULT_CONVERTER.M=30*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta.DEFAULT_CONVERTER.Y=365*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta._get_separator=function(){return{Y:Sao.i18n.gettext("Y"),M:Sao.i18n.gettext("M"),w:Sao.i18n.gettext("w"),d:Sao.i18n.gettext("d"),h:Sao.i18n.gettext("h"),m:Sao.i18n.gettext("m"),s:Sao.i18n.gettext("s")}},Sao.common.timedelta.format=function(a,b){if(!a)return"";b||(b=Sao.common.timedelta.DEFAULT_CONVERTER);var c=[];a=a.asSeconds();var d="";a<0&&(d="-"),a=Math.abs(a),b=Object.keys(b).map(function(a){return[a,b[a]]}),b.sort(function(a,b){return b[1]-a[1]});for(var e,f,g=[],h=0;h<b.length;h++){e=b[h][0],f=b[h][1];var i=Math.floor(a/f);a-=i*f,g.push(i)}for(h=0;h<b.length-3;h++)e=b[h][0],f=g[h],f&&c.push(f+Sao.common.timedelta._get_separator()[e]);if(jQuery(g.slice(-3)).is(function(a,b){return b})||jQuery.isEmptyObject(c)){var j=g.slice(-3,-1);j=("00"+j[0]).slice(-2)+":"+("00"+j[1]).slice(-2),(g.slice(-1)[0]||a)&&(j+=":"+("00"+g.slice(-1)[0]).slice(-2)),c.push(j)}return c=d+c.reduce(function(a,b){return a?a+" "+b:b}),a&&(jQuery(g.slice(-3)).is(function(a,b){return b})||(c+=" "),c+=(""+a.toFixed(6)).slice(1)),c},Sao.common.timedelta.parse=function(a,b){if(!a)return null;b||(b=Sao.common.timedelta.DEFAULT_CONVERTER);var c,d=Sao.common.timedelta._get_separator();for(var e in d)c=d[e],a=a.replace(c,c+" ");for(var f,g=0,h=a.split(" "),i=0;i<h.length;i++){var j=h[i];if(j.contains(":"))for(var k=j.split(":"),l=[b.h,b.m,b.s],m=0;m<Math.min(k.length,l.length);m++){var n=k[m],o=l[m];f=Math.abs(Number(n))*o,isNaN(f)||(g+=f)}else{var p=!1;for(var q in d)if(c=d[q],j.endsWith(c)){j=j.slice(0,-c.length),f=Math.abs(parseInt(j,10))*b[q],isNaN(f)||(g+=f),p=!0;break}p||(f=Math.abs(Number(j)),isNaN(f)||(g+=f))}}return a.contains("-")&&(g*=-1),Sao.TimeDelta(null,g)},Sao.common.ModelAccess=Sao.class_(Object,{init:function(){this.batchnum=100,this._access={}},load_models:function(a){var b=jQuery.Deferred();return a||(this._access={}),Sao.rpc({method:"model.ir.model.list_models",params:[{}]},Sao.Session.current_session).then(function(a){for(var c=[],d=function(a){this._access=jQuery.extend(this._access,a)},e=0;e<a.length;e+=this.batchnum){var f=a.slice(e,e+this.batchnum);c.push(Sao.rpc({method:"model.ir.model.access.get_access",params:[f,{}]},Sao.Session.current_session).then(d.bind(this)))}jQuery.when.apply(jQuery,c).then(b.resolve,b.reject)}.bind(this)),b},get:function(a){return this._access[a]||{}}}),Sao.common.MODELACCESS=new Sao.common.ModelAccess,Sao.common.ModelHistory=Sao.class_(Object,{init:function(){this._models=[]},load_history:function(){return this._models=[],Sao.rpc({method:"model.ir.model.list_history",params:[{}]},Sao.Session.current_session).then(function(a){this._models=a}.bind(this))},contains:function(a){return~this._models.indexOf(a)}}),Sao.common.MODELHISTORY=new Sao.common.ModelHistory,Sao.common.ViewSearch=Sao.class_(Object,{load_searches:function(){return this.searches={},Sao.rpc({method:"model.ir.ui.view_search.get_search",params:[{}]},Sao.Session.current_session).then(function(a){this.searches=a}.bind(this))},get:function(a){return this.searches[a]||[]},add:function(a,b,c){return Sao.rpc({method:"model.ir.ui.view_search.create",params:[[{model:a,name:b,domain:(new Sao.PYSON.Encoder).encode(c)}],{}]},Sao.Session.current_session).then(function(d){var e=d[0];void 0===this.searches[a]&&(this.searches[a]=[]),this.searches[a].push([e,b,c])}.bind(this))},remove:function(a,b){return Sao.rpc({method:"model.ir.ui.view_search.delete",params:[[b],{}]},Sao.Session.current_session).then(function(){for(var c=0;c<this.searches[a].length;c++){var d=this.searches[a][c];if(d[0]===b){this.searches[a].splice(c,1);break}}}.bind(this))}}),Sao.common.VIEW_SEARCH=new Sao.common.ViewSearch,Sao.common.humanize=function(a){for(var b=["bytes","KB","MB","GB","TB","PB"],c=0,d=b.length;c<d;c++){if(a<1e3)return a.toPrecision(4)+" "+b[c];a/=1e3}},Sao.common.EvalEnvironment=function(a,b){void 0===b&&(b="eval");var c;if("eval"==b)c=a.get_eval();else{c={};for(var d in a.model.fields){var e=a.model.fields[d];c[d]=e.get_on_change_value(a)}}return c.id=a.id,a.group.parent&&Object.defineProperty(c,"_parent_"+a.group.parent_name,{enumerable:!0,get:function(){return Sao.common.EvalEnvironment(a.group.parent,b)}}),c.get=function(a,b){return this.hasOwnProperty(a)?this[a]:b},c},Sao.common.selection_mixin={},Sao.common.selection_mixin.init=function(){this.selection=null,this.inactive_selection=[],this._last_domain=null,this._values2selection={},this._domain_cache={},void 0===this.nullable_widget&&(this.nullable_widget=!0)},Sao.common.selection_mixin.init_selection=function(a,b){a||(a={},(this.attributes.selection_change_with||[]).forEach(function(b){a[b]=null}));var c,d=JSON.stringify(a),e=this.attributes.selection||[],f=function(a){a=jQuery.extend([],a),(void 0===this.attributes.sort||this.attributes.sort)&&a.sort(function(a,b){return a[1].localeCompare(b[1])}),this.selection=jQuery.extend([],a),b&&b(this.selection)};e instanceof Array||d in this._values2selection?(d in this._values2selection&&(e=this._values2selection[d]),f.call(this,e),c=jQuery.when()):(c=jQuery.isEmptyObject(this.attributes.selection_change_with)?this.model.execute(e,[]):this.model.execute(e,[a]),c=c.then(function(a){return this._values2selection[d]=a,a}.bind(this)),c=c.then(f.bind(this))),this.inactive_selection=[],this._selection_prm=c},Sao.common.selection_mixin.update_selection=function(a,b,c){var d=function(){if(!b)return void(c&&c(this.selection));var d=b.get_domain(a);if("reference"==b.description.type&&(d=[]),"relation"in this.attributes){var e=b.get_context(a),f=JSON.stringify([d,e]);if(f in this._domain_cache&&(this.selection=this._domain_cache[f],this._last_domain=[d,e]),null!==this._last_domain&&Sao.common.compare(d,this._last_domain[0])&&JSON.stringify(e)==JSON.stringify(this._last_domain[1]))return void(c&&c(this.selection));var g=Sao.rpc({method:"model."+this.attributes.relation+".search_read",params:[d,0,null,null,["rec_name"],e]},a.model.session);g.done(function(a){var b=[];a.forEach(function(a){b.push([a.id,a.rec_name])}),this.nullable_widget&&b.push([null,""]),this._last_domain=d,this._domain_cache[f]=b,this.selection=jQuery.extend([],b),c&&c(this.selection)}.bind(this)),g.fail(function(){this._last_domain=null,this.selection=[],c&&c(this.selection)}.bind(this))}else{var h=this.attributes.selection_change_with||[],i=a._get_on_change_args(h);delete i.id,Sao.common.selection_mixin.init_selection.call(this,i,function(){Sao.common.selection_mixin.filter_selection.call(this,d,a,b),c&&c(this.selection)}.bind(this))}};this._selection_prm.done(d.bind(this))},Sao.common.selection_mixin.filter_selection=function(a,b,c){if(!jQuery.isEmptyObject(a)){var d=new Sao.common.DomainInversion;this.selection=this.selection.filter(function(b){var c={};return c[this.field_name]=b[0],d.eval_domain(a,c)}.bind(this))}},Sao.common.selection_mixin.get_inactive_selection=function(a){if(!this.attributes.relation)return jQuery.when([]);for(var b=0,c=this.inactive_selection.length;b<c;b++)if(a==this.inactive_selection[b][0])return jQuery.when(this.inactive_selection[b]);var d=Sao.rpc({method:"model."+this.attributes.relation+".read",params:[[a],["rec_name"],{}]},Sao.Session.current_session);return d.then(function(a){return this.inactive_selection.push([a[0].id,a[0].rec_name]),[a[0].id,a[0].rec_name]}.bind(this))},Sao.common.Button=Sao.class_(Object,{init:function(a,b){this.attributes=a,b?this.el=b:(this.el=jQuery("<button/>"),this.el.append(a.string||""),this.attributes.rule&&this.el.append(" ").append(jQuery("<span/>",{class:"badge"}))),this.icon=this.el.children("img"),this.icon.length||(this.icon=jQuery("<img/>").prependTo(this.el),this.icon.hide()),this.el.addClass("btn btn-default"),this.el.attr("type","button"),this.icon.addClass("icon"),this.icon.attr("aria-hidden",!0),this.set_icon(a.icon)},set_icon:function(a){if(!a)return this.icon.attr("src",""),void this.icon.hide();var b=Sao.common.ICONFACTORY.register_icon(a);b.done(function(a){this.icon.attr("src",a),this.icon.show()}.bind(this))},set_state:function(a){var b;if(b=a?a.expr_eval(this.attributes.states||{}):{},b.invisible?this.el.hide():this.el.show(),this.el.prop("disabled",b.readonly),this.set_icon(b.icon||this.attributes.icon),this.attributes.rule){var c;c=a?a.get_button_clicks(this.attributes.name):jQuery.when(),c.then(function(a){var b=this.el.children(".badge"),c=[],d="";if(!jQuery.isEmptyObject(a)){for(var e in a)c.push(a[e]);d=Sao.i18n.gettext("By: ")+c.join(Sao.i18n.gettext(", "))}b.data("toggle","tooltip"),b.text(c.length||""),b.attr("title",d),b.tooltip()}.bind(this))}if((void 0===this.attributes.type||"class"===this.attributes.type)&&a)for(var d=a.group.parent;d;){if(d.has_changed()){this.el.prop("disabled",!1);break}d=d.group.parent}}}),Sao.common.udlex=Sao.class_(Object,{init:function(a){var b=Sao.class_(Object,{init:function(a){this.stream=a.split(""),this.i=0},read:function(a){if(void 0===a&&(a=1),this.i>=this.stream.length)return null;var b=this.stream.slice(this.i,this.i+a).join();return this.i+=a,b}});this.instream=new b(a),this.eof=null,this.commenters="",this.nowordchars=[":",">","<","=","!",'"',";","(",")"],this.whitespace=" \t\r\n",this.whitespace_split=!1,this.quotes='"',this.escape="\\",this.escapedquotes='"',this.state=" ",this.pushback=[],this.token=""},get_token:function(){if(this.pushback.length>0)return this.pushback.shift();var a=this.read_token();return a},read_token:function(){for(var a=!1,b=" ";;){var c=this.instream.read(1);if(null===this.state){this.token="";break}if(" "==this.state){if(!c){this.state=null;break}if(this.whitespace.contains(c)){if(this.token||a)break;continue}if(this.commenters.contains(c));else if(this.escape.contains(c))b="a",this.state=c;else if(~this.nowordchars.indexOf(c))if(this.quotes.contains(c))this.state=c;else{if(!this.whitespace_split){if(this.token=c,this.token||a)break;continue}this.token=c,this.state="a"}else this.token=c,this.state="a"}else if(this.quotes.contains(this.state)){if(a=!0,!c)throw"no closing quotation";c==this.state?this.state="a":this.escape.contains(c)&&this.escapedquotes.contains(this.state)?(b=this.state,this.state=c):this.token=this.token+c}else if(this.escape.contains(this.state)){if(!c)throw"no escaped character";this.quotes.contains(b)&&c!=this.state&&c!=b&&(this.token=this.token+this.state),this.token=this.token+c,this.state=b}else if("a"==this.state){if(!c){this.state=null;break}if(this.whitespace.contains(c)){if(this.state=" ",this.token||a)break;continue}if(this.commenters.contains(c));else if(this.quotes.contains(c))this.state=c;else if(this.escape.contains(c))b="a",this.state=c;else{if(~this.nowordchars.indexOf(c)&&!this.quotes.contains(c)&&!this.whitespace_split){if(this.pushback.unshift(c),this.state=" ",this.token)break;continue}this.token=this.token+c;
-}}}var d=this.token;return this.token="",a||""!==d||(d=null),d},next:function(){var a=this.get_token();return a==this.eof?null:a}}),Sao.common.DomainParser=Sao.class_(Object,{OPERATORS:["!=","<=",">=","=","!","<",">"],init:function(a,b){this.fields={},this.strings={},this.update_fields(a),this.context=b},update_fields:function(a){for(var b in a){var c=a[b];(c.searchable||void 0===c.searchable)&&(this.fields[b]=c,this.strings[c.string.toLowerCase()]=c)}},parse:function(a){try{for(var b=new Sao.common.udlex(a),c=[];;){var d=b.next();if(null===d)break;c.push(d)}return c=this.group_operator(c),c=this.parenthesize(c),c=this.group(c),c=this.operatorize(c,"or"),c=this.operatorize(c,"and"),c=this.parse_clause(c),this.simplify(c)}catch(e){if("no closing quotation"==e)return this.parse(a+'"');throw e}},stringable:function(a){var b=function(a){if(!a)return!0;var b=function(a){return a instanceof Array};return(~["AND","OR"].indexOf(a[0])||b(a[0]))&&a.slice(1).every(b)?this.stringable(a):a[0]in this.fields||"rec_name"==a[0]}.bind(this);return!a||(~["AND","OR"].indexOf(a[0])&&(a=a.slice(1)),a.every(b))},string:function(a){var b=function(a){if(jQuery.isEmptyObject(a))return"";if("string"!=typeof a[0]||~["AND","OR"].indexOf(a[0]))return"("+this.string(a)+")";var b,c=a[0],d=a[1],e=a[2];if(c.endsWith(".rec_name")&&(c=c.slice(0,-9)),!(c in this.fields))return b=e.replace("%%","__"),b.startsWith("%")&&b.endsWith("%")&&(e=e.slice(1,-1)),this.quote(e);var f=this.fields[c],g=null;a.length>3&&(g=a[3]),d.contains("ilike")&&(b=e.replace("%%","__"),b.startsWith("%")&&b.endsWith("%")?e=e.slice(1,-1):b.contains("%")||(d="ilike"==d?"=":"!",e=e.replace("%%","%")));var h=this.default_operator(f);h==d.trim()?(d="",~this.OPERATORS.indexOf(e)&&(d='"" ')):d.contains(h)&&(d.contains("not")||d.contains("!"))&&(d=d.replace(h,"").replace("not","!").trim()),d.endsWith("in")&&(d="not in"==d?"!":"");var i=this.format_value(f,e,g);return~this.OPERATORS.indexOf(d)&&~["char","text","selection"].indexOf(f.type)&&""===e&&(i='""'),this.quote(f.string)+": "+d+i};if(b=b.bind(this),jQuery.isEmptyObject(a))return"";var c=" ";return"AND"!=a[0]&&"OR"!=a[0]||("OR"==a[0]&&(c=" or "),a=a.slice(1)),a.map(b).join(c)},completion:function(a){var b,c,d=[],e=this.parse(a),f=0;for(b=a.length;b>0&&(")"!=a[b]&&" "!=a[b]);b--)")"==a[b]&&(f+=1);var g=this.ending_clause(e),h=g[0],i=g[1],j=i-f,k=this.string(e);j>0&&(k=k.substring(0,k.length-j)),k!=a&&d.push(k);var l,m,n=function(a,b){return b>0?a.substring(0,b):a};if(null!==h&&0===f){var o=this.complete(h);for(b=0,c=o.length;b<c;b++)l=o[b],m=this.string(this.replace_ending_clause(e,l)),d.push(n(m,j))}if(a.length>0){if(" "!=a.substr(a.length-1,1))return d;if(a.length>=2||":"==a.substr(a.length-2,1))return d}var p,q,r;for(var s in this.strings){p=this.strings[s],q=this.default_operator(p),r="","ilike"!=q&&"not ilike"!=q||(r=this.likify(r));var t=this.append_ending_clause(e,[p.name,q,r],j),u=this.string(t);d.push(n(u,j))}return d},complete:function(a){var b,c,d,e,f=[];1==a.length?b=a[0]:3==a.length?(b=a[0],c=a[1],d=a[2]):(b=a[0],c=a[1],d=a[2],e=a[3],b.endsWith(".rec_name")&&(b=b.substring(0,b.length-9)));var g;"rec_name"==b&&("ilike"==c&&(g=d.replace(/%%/g,"__"),g.startsWith("%")||g.endsWith("%")?d=g.substring(1,g.length-1):~g.indexOf("%")&&(d=d.replace(/%%/g,"%")),c=null),b=d,d=""),void 0!==b&&null!==b||(b="");var h;if(!(b.toLowerCase()in this.strings||b in this.fields)){for(var i in this.strings)h=this.strings[i],h.string.toLowerCase().startsWith(b.toLowerCase())&&(c=this.default_operator(h),d="","ilike"==c&&(d=this.likify(d)),f.push([h.name,c,d]));return f}if(h=b in this.fields?this.fields[b]:this.strings[b.toLowerCase()],c)for(var j=this.complete_value(h,d),k=0,l=j.length;k<l;k++)f.push([h.name,c,j[k]]);else c=this.default_operator(h),d="","ilike"!=c&&"not ilike"!=c||(d=this.likify(d)),f.push([h.name,c,d]);return f},is_leaf:function(a){return a instanceof Array&&a.clause},ending_clause:function(a,b){if(void 0===b&&(b=0),0===a.length)return[null,b];var c=a[a.length-1];return this.is_leaf(c)?[c,b]:this.ending_clause(c,b+1)},replace_ending_clause:function(a,b){var c,d,e=[];for(c=0,d=a.length-1;c<d;c++)e.push(a[c]);return this.is_leaf(a[c])?e.push(b):e=e.concat(this.replace_ending_clause(a[c],b)),e},append_ending_clause:function(a,b,c){if(0===a.length)return[b];var d=a.slice(0,-1),e=a[a.length-1];return this.is_leaf(e)?(d.push(e),0===c&&d.push(b)):d.push(this.append_ending_clause(e,b,c-1)),d},complete_value:function(a,b){var c=function(){return b?[!0]:[!1]},d=function(){var c=[],d=null!==b?b:"";b instanceof Array&&(d=b[b.length-1]),d=d.replace(/^%*|%*$/g,"");var e,f,g,h;for(e=0,f=a.selection.length;e<f;e++)g=a.selection[e][0],h=a.selection[e][1].toLowerCase(),h.startsWith(d.toLowerCase())&&(b instanceof Array?c.push(b.slice(0,-1).concat([g])):c.push(g));return c},e=function(){var c=[],d=null!==b?b:"";b instanceof Array&&(d=b[b.length-1]),d=d.replace(/^%*|%*$/g,"");var e,f,g,h;for(e=0,f=a.selection.length;e<f;e++)g=a.selection[e][0],h=a.selection[e][1].toLowerCase(),h.startsWith(d.toLowerCase())&&(b instanceof Array?c.push(b.slice(0,-1).concat([g])):c.push(this.likify(g)));return c}.bind(this),f=function(){return[Sao.Date(),Sao.DateTime().utc()]},g=function(){return[Sao.Date()]},h=function(){return[Sao.Time()]},i={boolean:c,selection:d,reference:e,datetime:f,date:g,time:h};return a.type in i?i[a.type]():[]},group_operator:function(a){var b=a[0],c=[];return a.slice(1).forEach(function(a){"="==a&&b&&~this.OPERATORS.indexOf(b+a)?(c.push(b+a),b=null):(null!==b&&c.push(b),b=a)}.bind(this)),null!==b&&c.push(b),c},parenthesize:function(a){var b=[],c=b,d=[];return a.forEach(function(a,b){void 0!==c&&("("==a?(d.push(c),c=c[c.push([])-1]):")"==a?c=d.pop():c.push(a))}),b},group:function(a){var b=[],c=function(a){var b=[],d=function(a){b.push([a])},e=a.indexOf(":");if(!~e)return a.forEach(d),b.forEach(function(a){a.clause=!0}),b;for(var f=function(a,c){return function(d){if(jQuery.isEmptyObject(a))b.push(d);else{var e;jQuery.isEmptyObject(c)?(e=a.concat(d),e.clause=!0,b.push(e)):(null!==d[0]&&c.push(d[0]),e=a.concat([c]),e.clause=!0,b.push(e)),a.splice(0,a.length)}}},g=0;g<e;g++){var h=a.slice(g,e).join(" ");if(h.toLowerCase()in this.strings){jQuery.isEmptyObject(a.slice(0,g))?d(null):a.slice(0,g).forEach(d),h=[h];var i=[""].concat(this.OPERATORS);e+1<a.length&&~i.indexOf(a[e+1])?(h=h.concat([a[e+1]]),e+=1):h=h.concat([null]);for(var j=[];e+2<a.length&&";"==a[e+2];)j.push(a[e+1]),e+=2;if(c(a.slice(e+1)).forEach(f(h,j)),!jQuery.isEmptyObject(h)){var k;jQuery.isEmptyObject(j)?(k=h.concat([null]),k.clause=!0,b.push(k)):(k=h.concat([j]),k.clause=!0,b.push(k))}break}}return b};c=c.bind(this);var d=[];return a.forEach(function(a){this.is_generator(a)?(c(d).forEach(function(a){Sao.common.compare(a,[null])||b.push(a)}),d=[],b.push(this.group(a))):d.push(a)}.bind(this)),c(d).forEach(function(a){Sao.common.compare(a,[null])||b.push(a)}),b},is_generator:function(a){return a instanceof Array&&void 0===a.clause},operatorize:function(a,b){var c=[];b=b||"or",a=jQuery.extend([],a);for(var d=function(a){return a instanceof Array?Sao.common.compare(a,[b]):a==b},e=a.shift();d(e);)e=a.shift();if(void 0===e)return c;this.is_generator(e)&&(e=this.operatorize(e,b));for(var f=null;!jQuery.isEmptyObject(a);)if(f=a.shift(),this.is_generator(f)&&!d(f)&&(f=this.operatorize(f,b)),d(f)){for(f=a.shift();d(f);)f=a.shift();this.is_generator(f)&&(f=this.operatorize(f,b)),void 0!==f?e=[b.toUpperCase(),e,f]:d(e)||(c.push([b.toUpperCase(),e]),e=null),f=null}else d(e)||c.push(e),e=f;return jQuery.isEmptyObject(a)&&(null===f||d(f)?null===e||d(e)||c.push(e):c.push(f)),c},_clausify:function(a){return a.clause=!0,a},parse_clause:function(a){var b=[];return a.forEach(function(a){if(this.is_generator(a))jQuery.merge(b,this.parse_clause(a));else if("OR"==a||"AND"==a)b.push(a);else if(1!=a.length||a[0]instanceof Array){if(3==a.length&&a[0].toLowerCase()in this.strings){var c=(a[0],a[1]),d=a[2],e=this.strings[a[0].toLowerCase()],f=null;if("reference"==e.type){var g=this.split_target_value(e,d);f=g[0],d=g[1]}if(c||(c=this.default_operator(e)),d instanceof Array&&(c="!"==c?"not in":"in"),"!"==c&&(c=this.negate_operator(this.default_operator(e))),~["integer","float","numeric","datetime","date","time"].indexOf(e.type)&&d&&d.contains("..")){var h=d.split("..",2),i=this.convert_value(e,h[0]),j=this.convert_value(e,h[1]);return void b.push([this._clausify([e.name,">=",i]),this._clausify([e.name,"<=",j])])}d=d instanceof Array?d.map(function(a){return this.convert_value(e,a)}.bind(this)):this.convert_value(e,d),c.contains("like")&&(d=this.likify(d)),f?b.push(this._clausify([e.name+".rec_name",c,d,f])):b.push(this._clausify([e.name,c,d]))}}else b.push(this._clausify(["rec_name","ilike",this.likify(a[0])]))}.bind(this)),b},likify:function(a){if(!a)return"%";var b=a.replace("%%","__");return b.contains("%")?a:"%"+a+"%"},quote:function(a){if("string"!=typeof a)return a;a.contains("\\")&&(a=a.replace(new RegExp("\\\\","g"),"\\\\")),a.contains('"')&&(a=a.replace(new RegExp('"',"g"),'\\"'));for(var b=[":"," ","(",")"].concat(this.OPERATORS),c=0;c<b.length;c++){var d=b[c];if(a.contains(d))return'"'+a+'"'}return a},default_operator:function(a){return~["char","text","many2one","many2many","one2many","reference"].indexOf(a.type)?"ilike":"="},negate_operator:function(a){switch(a){case"ilike":return"not ilike";case"=":return"!=";case"in":return"not in"}},time_format:function(a){return new Sao.PYSON.Decoder({}).decode(a.format)},split_target_value:function(a,b){var c=null;if("string"==typeof b)for(var d=0;d<a.selection.length;d++){var e=a.selection[d],f=e[0],g=e[1];if(b.toLowerCase().startsWith(g.toLowerCase()+",")){c=f,b=b.slice(g.length+1);break}}return[c,b]},convert_value:function(a,b){var c=function(){if("string"==typeof b)for(var c=0;c<a.selection.length;c++){var d=a.selection[c],e=d[0],f=d[1];if(b.toLowerCase()==f.toLowerCase())return e}return b},d={boolean:function(){return"string"==typeof b?[Sao.i18n.gettext("y"),Sao.i18n.gettext("Yes"),Sao.i18n.gettext("True"),Sao.i18n.gettext("t"),"1"].some(function(a){return a.toLowerCase().startsWith(b.toLowerCase())}):Boolean(b)},float:function(){var a=Number(b);return isNaN(a)||""===b||null===b?null:a},integer:function(){var a=parseInt(b,10);return isNaN(a)?null:a},numeric:function(){var a=new Sao.Decimal(b);return isNaN(a.valueOf())||""===b||null===b?null:a},selection:c,reference:c,datetime:function(){var c=Sao.common.parse_datetime(Sao.common.date_format(),this.time_format(a),b);return c||(c=Sao.common.parse_date(Sao.common.date_format(),b)),c}.bind(this),date:function(){return Sao.common.parse_date(Sao.common.date_format(),b)},time:function(){try{return Sao.common.parse_time(this.time_format(a),b)}catch(c){return null}}.bind(this),timedelta:function(){var c=null;return a.converter&&(c=this.context[a.converter]),Sao.common.timedelta.parse(b,c)}.bind(this),many2one:function(){return""===b?null:b}},e=d[a.type];return e?e():b},format_value:function(a,b,c){void 0===c&&(c=null);var d=function(){if(!b&&0!==b&&b!==new Sao.Decimal(0))return"";var a=String(b).split(".")[1];return a=a?a.length:0,b.toFixed(a)},e=function(){for(var c=0;c<a.selection.length;c++)if(a.selection[c][0]==b)return a.selection[c][1];return b||""},f=function(){if(!c)return e();for(var d=0;d<a.selection.length;d++)if(a.selection[d][0]==c){c=a.selection[d][1];break}return c+","+b},g={boolean:function(){return b?Sao.i18n.gettext("True"):Sao.i18n.gettext("False")},integer:function(){return b||0===b?""+parseInt(b,10):""},float:d,numeric:d,selection:e,reference:f,datetime:function(){return b?b.isDate||!(b.hour()||b.minute()||b.second())?Sao.common.format_date(Sao.common.date_format(),b):Sao.common.format_datetime(Sao.common.date_format(),this.time_format(a),b):""}.bind(this),date:function(){return Sao.common.format_date(Sao.common.date_format(),b)},time:function(){return b?Sao.common.format_time(this.time_format(a),b):""}.bind(this),timedelta:function(){if(!b||!b.valueOf())return"";var c=null;return a.converter&&(c=this.context[a.converter]),Sao.common.timedelta.format(b,c)}.bind(this),many2one:function(){return null===b?"":b}};if(b instanceof Array)return b.map(function(b){return this.format_value(a,b)}.bind(this)).join(";");var h=g[a.type];return h?this.quote(h(b)):null===b?"":this.quote(b)},simplify:function(a){return a instanceof Array&&!this.is_leaf(a)?1==a.length&&a[0]instanceof Array&&("AND"==a[0][0]||"OR"==a[0][0]||a[0][0]instanceof Array)?this.simplify(a[0]):2==a.length&&("AND"==a[0]||"OR"==a[0])&&a[1]instanceof Array?this.simplify(a[1]):(3==a.length&&("AND"==a[0]||"OR"==a[0])&&a[1]instanceof Array&&a[0]==a[1][0]&&(a=this.simplify(a[1]).concat([a[2]])),a.map(this.simplify.bind(this))):a}}),Sao.common.DomainInversion=Sao.class_(Object,{and:function(a,b){return a&&b},or:function(a,b){return a||b},OPERATORS:{"=":function(a,b){return a instanceof Array&&b instanceof Array?Sao.common.compare(a,b):a===b},">":function(a,b){return a>b},"<":function(a,b){return a<b},"<=":function(a,b){return a<=b},">=":function(a,b){return a>=b},"!=":function(a,b){return a instanceof Array&&b instanceof Array?!Sao.common.compare(a,b):a!==b},in:function(a,b){return Sao.common.DomainInversion.in_(a,b)},"not in":function(a,b){return!Sao.common.DomainInversion.in_(a,b)},like:function(){return!0},ilike:function(){return!0},"not like":function(){return!0},"not ilike":function(){return!0},child_of:function(){return!0},"not child_of":function(){return!0}},locale_part:function(a,b,c){return void 0===c&&(c="id"),a===b?c:a.contains(".")?a.split(".").slice(1).join("."):a},is_leaf:function(a){return a instanceof Array&&a.length>2&&"string"==typeof a[1]},eval_leaf:function(a,b,c){void 0===c&&(c=this.and);var d=a[0],e=a[1],f=a[2];if(d.contains("."))return Boolean(b[d.split(".")[0]]);if("="==e&&(null===b[d]||void 0===b[d])&&c===this.and)return!0;var g=b[d];return g&&g._isAMomentObject&&!f&&(f=g.isDateTime?Sao.DateTime.min:Sao.Date.min),f&&f._isAMomentObject&&!g&&(g=f.isDateTime?Sao.DateTime.min:Sao.Date.min),"string"==typeof g&&f instanceof Array&&2==f.length?f=f.join(","):g instanceof Array&&"string"==typeof f&&2==g.length&&(g=g.join(",")),~["=","!="].indexOf(e)&&g instanceof Array&&"number"==typeof f&&(e={"=":"in","!=":"not in"}[e]),!(e in this.OPERATORS)||this.OPERATORS[e](g,f)},inverse_leaf:function(a){return~["AND","OR"].indexOf(a)?a:this.is_leaf(a)?a[1].contains("child_of")?3==a.length?a:[a[3]].concat(a.slice(1)):a:a.map(this.inverse_leaf.bind(this))},filter_leaf:function(a,b,c){return~["AND","OR"].indexOf(a)?a:this.is_leaf(a)?a[0].startsWith(b)&&a.length>3&&a[3]!==c?["id","=",null]:a:a.map(function(a){return this.filter_leaf(a,b,c)}.bind(this))},eval_domain:function(a,b,c){return void 0===c&&(c=this.and),this.is_leaf(a)?this.eval_leaf(a,b,c):!(!jQuery.isEmptyObject(a)||c!=this.and)||(!jQuery.isEmptyObject(a)||c!=this.or)&&("AND"==a[0]?this.eval_domain(a.slice(1),b):"OR"==a[0]?this.eval_domain(a.slice(1),b,this.or):c(this.eval_domain(a[0],b),this.eval_domain(a.slice(1),b,c)))},localize_domain:function(a,b,c){if(~["AND","OR",!0,!1].indexOf(a))return a;if(this.is_leaf(a)){if(a[1].contains("child_of"))return 3==a.length?a:[a[3]].concat(a.slice(1,-1));var d="id";"string"==typeof a[2]&&(d="rec_name");var e=c?3:4;return[this.locale_part(a[0],b,d)].concat(a.slice(1,e)).concat(a.slice(4))}return a.map(function(a){return this.localize_domain(a,b,c)}.bind(this))},simplify:function(a){return this.is_leaf(a)?a:~["OR","AND"].indexOf(a)?a:a instanceof Array&&1==a.length&&~["OR","AND"].indexOf(a[0])?[]:a instanceof Array&&1==a.length&&!this.is_leaf(a[0])?this.simplify(a[0]):a instanceof Array&&2==a.length&&~["AND","OR"].indexOf(a[0])?[this.simplify(a[1])]:a.map(this.simplify.bind(this))},merge:function(a,b){if(jQuery.isEmptyObject(a)||~["AND","OR"].indexOf(a))return[];var c="OR"==a[0]?"OR":"AND";return this.is_leaf(a)?[a]:void 0===b?[c].concat([].concat.apply([],a.map(function(a){return this.merge(a,c)}.bind(this)))):c==b?[].concat.apply([],a.map(function(a){return this.merge(a,c)}.bind(this))):[this.merge(a)]},concat:function(a,b){var c=[];return b&&c.push(b),a.forEach(function(a){jQuery.isEmptyObject(a)||c.push(a)}),this.simplify(this.merge(c))},unique_value:function(a){return a instanceof Array&&1==a.length&&!a[0][0].contains(".")&&"="==a[0][1]?[!0,a[0][1],a[0][2]]:[!1,null,null]},parse:function(a){var b=Sao.common.DomainInversion.And,c=Sao.common.DomainInversion.Or;if(this.is_leaf(a))return a;if(jQuery.isEmptyObject(a))return new b([]);if("OR"===a[0])return new c(a.slice(1));var d=0;return"AND"===a[0]&&(d=1),new b(a.slice(d))},domain_inversion:function(a,b,c){void 0===c&&(c={});var d=this.parse(a);return!~d.variables.indexOf(b)||d.inverse(b,c)}}),Sao.common.DomainInversion.in_=function(a,b){if(a instanceof Array){if(b instanceof Array){for(var c=0,d=a.length;c<d;c++)if(~b.indexOf(a[c]))return!0;return!1}return Boolean(~a.indexOf(b))}return Boolean(~b.indexOf(a))},Sao.common.DomainInversion.And=Sao.class_(Object,{init:function(a){this.domain_inversion=new Sao.common.DomainInversion,this.branches=a.map(this.domain_inversion.parse.bind(this.domain_inversion)),this.variables=[];for(var b=0,c=this.branches.length;b<c;b++){var d=this.branches[b];this.domain_inversion.is_leaf(d)?this.variables.push(this.base(d[0])):d instanceof Sao.common.DomainInversion.And&&(this.variables=this.variables.concat(d.variables))}},base:function(a){return a.contains(".")?a.split(".")[0]:a},inverse:function(a,b){for(var c=Sao.common.DomainInversion,d=[],e=0,f=this.branches.length;e<f;e++){var g=this.branches[e];if(g instanceof c.And){var h=g.inverse(a,b),i="boolean"==typeof h;if(i){if(h)continue;return!1}d.push(h)}else if(this.domain_inversion.is_leaf(g)&&this.base(g[0])===a)d.push(g);else{var j=g[0];if(j in b&&!(j in b&&this.domain_inversion.eval_leaf(g,b,this.domain_inversion.and)))return!1;d.push(!0)}}return d=d.filter(function(a){return a!==!0}),!!jQuery.isEmptyObject(d)||this.domain_inversion.simplify(d)}}),Sao.common.DomainInversion.Or=Sao.class_(Sao.common.DomainInversion.And,{inverse:function(a,b){var c=Sao.common.DomainInversion,d=[];if(!~this.variables.indexOf(a)&&!jQuery.isEmptyObject(this.variables.filter(function(a){return!(a in b)})))return!0;for(var e=0,f=this.branches.length;e<f;e++){var g=this.branches[e];if(g instanceof c.And){var h=g.inverse(a,b),i="boolean"==typeof h;if(!~this.variables.indexOf(a)){if(i&&h)return!0;continue}if(i){if(h)return!0;continue}d.push(h)}else if(this.domain_inversion.is_leaf(g)&&this.base(g[0])==a)d.push(g);else{var j=g[0];if(j=this.base(j),j in b&&this.domain_inversion.eval_leaf(g,b,this.domain_inversion.or))return!0;j in b&&!this.domain_inversion.eval_leaf(g,b,this.domain_inversion.or)&&d.push(!1)}}return d=d.filter(function(a){return a!==!1}),!jQuery.isEmptyObject(d)&&this.domain_inversion.simplify(["OR"].concat(d))}}),Sao.common.guess_mimetype=function(a){return/.*odt$/.test(a)?"application/vnd.oasis.opendocument.text":/.*ods$/.test(a)?"application/vnd.oasis.opendocument.spreadsheet":/.*pdf$/.test(a)?"application/pdf":/.*docx$/.test(a)?"application/vnd.openxmlformats-officedocument.wordprocessingml.document":/.*doc/.test(a)?"application/msword":/.*xlsx$/.test(a)?"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":/.*xls/.test(a)?"application/vnd.ms-excel":"application/octet-binary"},Sao.common.LOCAL_ICONS=["tryton-attachment-hi","tryton-attachment","tryton-bookmark","tryton-cancel","tryton-clear","tryton-close","tryton-connect","tryton-copy","tryton-delete","tryton-dialog-error","tryton-dialog-information","tryton-dialog-warning","tryton-disconnect","tryton-executable","tryton-find-replace","tryton-find","tryton-folder-new","tryton-fullscreen","tryton-go-home","tryton-go-jump","tryton-go-next","tryton-go-previous","tryton-help","tryton-icon","tryton-list-add","tryton-list-remove","tryton-locale","tryton-lock","tryton-log-out","tryton-mail-message-new","tryton-mail-message","tryton-new","tryton-ok","tryton-open","tryton-preferences-system-session","tryton-preferences-system","tryton-preferences","tryton-print-email","tryton-print-open","tryton-print","tryton-refresh","tryton-save-as","tryton-save","tryton-star","tryton-start-here","tryton-system-file-manager","tryton-system","tryton-text-background","tryton-text-foreground","tryton-text-markup","tryton-undo","tryton-unstar","tryton-web-browser"],Sao.common.IconFactory=Sao.class_(Object,{batchnum:10,name2id:{},loaded_icons:{},tryton_icons:[],register_prm:jQuery.when(),load_icons:function(a){if(a=a||!1,!a)for(var b in this.load_icons)this.load_icons.hasOwnProperty(b)&&window.URL.revokeObjectURL(this.load_icons[b]);var c=new Sao.Model("ir.ui.icon");return c.execute("list_icons",[],{}).then(function(b){a||(this.name2id={},this.loaded_icons={}),this.tryton_icons=[];for(var c,d,e=0,f=b.length;e<f;e++)c=b[e][0],d=b[e][1],a&&d in this.loaded_icons||(this.tryton_icons.push([c,d]),this.name2id[d]=c)}.bind(this))},register_icon:function(a){if(!a)return jQuery.Deferred().reject();if(a in this.loaded_icons||~Sao.common.LOCAL_ICONS.indexOf(a))return jQuery.when(this.get_icon_url(a));if("pending"==this.register_prm.state()){var b=jQuery.Deferred();return this.register_prm.then(function(){this.register_icon(a).then(b.resolve,b.reject)}.bind(this)),b}var c;c=a in this.name2id?jQuery.when():this.load_icons(!0);var d=new Sao.Model("ir.ui.icon");return this.register_prm=c.then(function(){var b=function(a){var b,c;for(b=0,c=this.tryton_icons.length;b<c;b++){var d=this.tryton_icons[b];if(Sao.common.compare(d,a))break}return b}.bind(this),c=b([this.name2id[a],a]),e=Math.round(c-this.batchnum/2);e=e<0?0:e;var f=Math.round(c+this.batchnum/2),g=[];this.tryton_icons.slice(e,f).forEach(function(a){g.push(a[0])});var h=d.execute("read",[g,["name","icon"]],{});return h.then(function(c){return c.forEach(function(a){var c;if(navigator.userAgent.match(/firefox/i)){c="data:image/svg+xml;base64,"+window.btoa(unescape(encodeURIComponent(a.icon)));var d=new Image;d.src=c,d.onload=function(){var b=document.createElement("canvas");b.width=d.width,b.height=d.height;var e=b.getContext("2d");e.drawImage(d,0,0),b.toBlob(function(d){var e=c;c=window.URL.createObjectURL(d),this.loaded_icons[a.name]=c,jQuery(document).find("img").each(function(a,b){b.src==e&&(b.src=c)}),b.remove()}.bind(this),"image/png")}.bind(this)}else{var e=new Blob([a.icon],{type:"image/svg+xml"});c=window.URL.createObjectURL(e)}this.loaded_icons[a.name]=c,delete this.name2id[a.name],this.tryton_icons.splice(b([a.id,a.name]),1)}.bind(this)),this.get_icon_url(a)}.bind(this))}.bind(this)),this.register_prm},get_icon_url:function(a){return a in this.loaded_icons?this.loaded_icons[a]:"images/"+a+".svg"}}),Sao.common.ICONFACTORY=new Sao.common.IconFactory,Sao.common.UniqueDialog=Sao.class_(Object,{init:function(){this.running=!1},build_dialog:function(){var a=new Sao.Dialog("",this.class_);return a},run:function(){if(this.running)return jQuery.when();var a=Array.prototype.slice.call(arguments),b=jQuery.Deferred();a.push(b);var c=this.build_dialog.apply(this,a);return c.content.submit(function(a){c.footer.find("button.btn-primary").first().click(),a.preventDefault()}.bind(this)),this.running=!0,c.modal.modal("show"),c.modal.on("shown.bs.modal",function(){c.modal.find("input,select").filter(":visible").first().focus()}),b},close:function(a){a.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),a.modal.modal("hide"),this.running=!1}}),Sao.common.MessageDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"message-dialog",build_dialog:function(a,b,c){var d=Sao.common.MessageDialog._super.build_dialog.call(this);return d.header.remove(),d.body.append(jQuery("<div/>",{class:"alert alert-info",role:"alert"}).append(jQuery("<span/>",{class:"glyphicon "+b,"aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Message: "))).append(jQuery("<span/>").append(a).css("white-space","pre-wrap"))),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve("ok")}.bind(this)).appendTo(d.footer),d},run:function(a,b){return Sao.common.MessageDialog._super.run.call(this,a,b||"glyphicon-info-sign")}}),Sao.common.message=new Sao.common.MessageDialog,Sao.common.WarningDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"warning-dialog",build_dialog:function(a,b,c){var d=Sao.common.WarningDialog._super.build_dialog.call(this);return d.add_title(b),d.body.append(jQuery("<div/>",{class:"alert alert-warning",role:"alert"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-alert","aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Warning: "))).append(jQuery("<span/>").append(a).css("white-space","pre-wrap"))),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve("ok")}.bind(this)).appendTo(d.footer),d}}),Sao.common.warning=new Sao.common.WarningDialog,Sao.common.UserWarningDialog=Sao.class_(Sao.common.WarningDialog,{class_:"user-warning-dialog",always:!1,_set_always:function(){this.always=jQuery(this).prop("checked")},build_dialog:function(a,b,c){var d=Sao.common.UserWarningDialog._super.build_dialog.call(this,a,b,c);return d.body.append(jQuery("<div/>").append(jQuery("<input/>",{type:"checkbox"}).change(this._set_always.bind(this))).append(jQuery("<span/>").text(Sao.i18n.gettext("Always ignore this warning.")))),d.body.append(jQuery("<p/>").text(Sao.i18n.gettext("Do you want to proceed?"))),d.footer.children().remove(),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("No")).click(function(){this.close(d),c.reject()}.bind(this)).appendTo(d.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Yes")).click(function(){this.close(d),this.always&&c.resolve("always"),c.resolve("ok")}.bind(this)).appendTo(d.footer),d}}),Sao.common.userwarning=new Sao.common.UserWarningDialog,Sao.common.ConfirmationDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"confirmation-dialog",build_dialog:function(a){var b=Sao.common.ConfirmationDialog._super.build_dialog.call(this);return b.header.remove(),b.body.append(jQuery("<div/>",{class:"alert alert-info",role:"alert"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-info-sign","aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Confirmation: "))).append(jQuery("<span/>").append(a).css("white-space","pre-wrap"))),b}}),Sao.common.SurDialog=Sao.class_(Sao.common.ConfirmationDialog,{build_dialog:function(a,b){var c=Sao.common.SurDialog._super.build_dialog.call(this,a);return jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c),b.reject()}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(c),b.resolve()}.bind(this)).appendTo(c.footer),c}}),Sao.common.sur=new Sao.common.SurDialog,Sao.common.Sur3BDialog=Sao.class_(Sao.common.ConfirmationDialog,{build_dialog:function(a,b){var c=Sao.common.SurDialog._super.build_dialog.call(this,a);return jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c),b.resolve("cancel")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("No")).click(function(){this.close(c),b.resolve("ko")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Yes")).click(function(){this.close(c),b.resolve("ok")}.bind(this)).appendTo(c.footer),c}}),Sao.common.sur_3b=new Sao.common.Sur3BDialog,Sao.common.AskDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"ask-dialog",run:function(){var a=Array.prototype.slice.call(arguments);return 1==a.length&&a.push(!0),Sao.common.AskDialog._super.run.apply(this,a)},build_dialog:function(a,b,c){var d=Sao.common.AskDialog._super.build_dialog.call(this);d.header.remove();var e=jQuery("<input/>",{class:"form-control",type:b?"input":"password",id:"ask-dialog-entry"});return d.body.append(jQuery("<div/>",{class:"form-group"}).append(jQuery("<label/>",{for:"ask-dialog-entry"}).append(a)).append(e)),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(d),c.reject()}.bind(this)).appendTo(d.footer),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve(e.val())}.bind(this)).appendTo(d.footer),d}}),Sao.common.ask=new Sao.common.AskDialog,Sao.common.ConcurrencyDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"ask-dialog",build_dialog:function(a,b,c,d){var e=Sao.common.ConcurrencyDialog._super.build_dialog.call(this);return e.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),e.add_title(Sao.i18n.gettext("Concurrency Exception")),e.body.append(jQuery("<div/>",{class:"alert alert-warning",role:"alert"}).append(jQuery("<p/>").append(jQuery("<span/>",{class:"glyphicon glyphicon-info-sign","aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Write Concurrency Warning: "))).append(Sao.i18n.gettext("This record has been modified while you were editing it."))).append(jQuery("<p/>").text(Sao.i18n.gettext("Choose:"))).append(jQuery("<ul/>").append(jQuery("<li/>").text(Sao.i18n.gettext('"Cancel" to cancel saving;'))).append(jQuery("<li/>").text(Sao.i18n.gettext('"Compare" to see the modified version;'))).append(jQuery("<li/>").text(Sao.i18n.gettext('"Write Anyway" to save your current version.'))))),jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(e),d.reject()}.bind(this)).appendTo(e.footer),jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Compare")).click(function(){this.close(e),Sao.Tab.create({model:a,res_id:b,domain:[["id","=",b]],context:c,mode:["form","tree"]}),d.reject()}.bind(this)).appendTo(e.footer),jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Write Anyway")).click(function(){this.close(e),d.resolve()}.bind(this)).appendTo(e.footer),e}}),Sao.common.concurrency=new Sao.common.ConcurrencyDialog,Sao.common.ErrorDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"error-dialog",build_dialog:function(a,b,c){var d=Sao.common.ConcurrencyDialog._super.build_dialog.call(this);return d.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),d.add_title(Sao.i18n.gettext("Application Error")),d.body.append(jQuery("<div/>",{class:"alert alert-warning",role:"alert"}).append(jQuery("<span/>",{class:"glyphicon glyphicon-alert","aria-hidden":!0})).append(jQuery("<span/>",{class:"sr-only"}).append(Sao.i18n.gettext("Warning: "))).append(jQuery("<p/>").append(jQuery("<pre/>").text(b))).append(jQuery("<p/>").append(jQuery("<a/>",{class:"btn btn-link",href:Sao.config.roundup.url,target:"_blank"}).text(Sao.i18n.gettext("Report Bug"))))),jQuery("<button/>",{class:"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Close")).click(function(){this.close(d),c.resolve()}.bind(this)).appendTo(d.footer),d}}),Sao.common.error=new Sao.common.ErrorDialog,Sao.common.Processing=Sao.class_(Object,{queries:0,timeout:500,init:function(){this.el=jQuery("<div/>",{id:"processing",class:"text-center"}),this.el.append(jQuery("<span/>",{class:"label label-info",text:"Processing..."})),this.el.hide(),jQuery(function(){this.el.appendTo("body")}.bind(this))},show:function(){return window.setTimeout(function(){this.queries+=1,this.el.show()}.bind(this),this.timeout)},hide:function(a){window.clearTimeout(a),this.queries>0&&(this.queries-=1),this.queries<=0&&(this.queries=0,this.el.hide())}}),Sao.common.processing=new Sao.common.Processing,Sao.common.InputCompletion=Sao.class_(Object,{
-init:function(a,b,c,d){a.is("input")?(a.wrap('<div class="dropdown"/>'),this.dropdown=a.parent()):(a.addClass("dropdown"),this.dropdown=a),this.input=a.find("input").add(a.filter("input")).first(),this.input.attr("autocomplete","off"),jQuery("<span/>",{"data-toggle":"dropdown"}).appendTo(this.dropdown),this.menu=jQuery("<ul/>",{class:"dropdown-menu",role:"listbox"}).appendTo(this.dropdown),this.separator=jQuery("<li/>",{role:"separator",class:"divider"}).appendTo(this.menu),this.separator.hide(),this.source=b,this.match_selected=c,this.format=d,this.action_activated=null,this._search_text=null,this.input.on("input",function(){window.setTimeout(this._input.bind(this),300,this.input.val())}.bind(this)),this.input.keydown(function(a){a.which==Sao.common.ESC_KEYCODE?this.dropdown.hasClass("open")&&this.menu.dropdown("toggle"):a.which==Sao.common.RETURN_KEYCODE&&(this.dropdown.hasClass("open")||this.menu.dropdown("toggle"))}.bind(this)),this.dropdown.on("hide.bs.dropdown",function(){this.input.focus(),this.input.closest(".treeview").css("overflow","")}.bind(this)),this.dropdown.on("show.bs.dropdown",function(){this.input.closest(".treeview").css("overflow","visible")}.bind(this))},set_actions:function(a,b){return void 0!==b&&(this.action_activated=b),this.menu.find("li.action").remove(),jQuery.isEmptyObject(a)?void this.separator.hide():(this.separator.show(),void a.forEach(function(a){var b=a[0],c=a[1];jQuery("<li/>",{class:"action action-"+b}).append(jQuery("<a/>",{href:"#"}).append(this._format_action(c))).click(function(){this.action_activated&&this.action_activated(b),this.input.val("")}.bind(this)).appendTo(this.menu)},this))},_format:function(a){return this.format?this.format(a):a},_format_action:function(a){return this.format_action?this.format_action(a):a},_input:function(a){if(a==this.input.val()){var b;b=this.source instanceof Array?jQuery.when(source.filter(function(b){return b.toLowerCase().startsWith(a.toLowerCase())})):this.source(a),b.then(function(b){a==this.input.val()&&this._set_selection(b)}.bind(this))}},_set_selection:function(a){void 0===a&&(a=[]),this.menu.find("li.completion").remove(),a.reverse().forEach(function(a){jQuery("<li/>",{class:"completion"}).append(jQuery("<a/>",{href:"#"}).append(this._format(a))).click(function(){this.match_selected&&this.match_selected(a),this.input.focus()}.bind(this)).prependTo(this.menu)},this),this.input.val()?this.dropdown.hasClass("open")||this.menu.dropdown("toggle"):this.dropdown.hasClass("open")&&this.menu.dropdown("toggle")}}),Sao.common.get_completion=function(a,b,c,d){var e=function(a){return a.rec_name},f=new Sao.common.InputCompletion(a,b,c,e);f.set_actions([["search",Sao.i18n.gettext("Search...")],["create",Sao.i18n.gettext("Create...")]],d)},Sao.common.update_completion=function(a,b,c,d,e){var f=a.val();if(!f||!d)return jQuery.when();void 0===e&&(e=c.get_domain(b));var g=c.get_context(b);e=[["rec_name","ilike","%"+f+"%"],e];var h=new Sao.Model(d);return h.execute("search_read",[e,0,Sao.config.limit,null,["rec_name"]],g)},Sao.common.Paned=Sao.class_(Object,{init:function(a){var b;this._orientation=a,this.el=jQuery("<div/>"),"horizontal"==a?(b=jQuery("<div/>",{class:"row"}).appendTo(this.el),this.child1=jQuery("<div/>",{class:"col-md-6"}).appendTo(b),this.child2=jQuery("<div/>",{class:"col-md-6"}).appendTo(b)):"vertical"==a&&(this.child1=jQuery("<div/>",{class:"row"}).appendTo(this.el),this.child2=jQuery("<div/>",{class:"row"}).appendTo(this.el))},get_child1:function(){return this.child1},get_child2:function(){return this.child2}}),Sao.common.get_focus_chain=function(a){var b=a.find("input","textarea");return b.sort(function(a,b){if("tabindex"in a.attributes&&"tabindex"in b.attributes){var c=parseInt(a.attributes.tabindex.value),d=parseInt(b.attributes.tabindex.value);return c-d}return"tabindex"in a.attributes?-1:"tabindex"in b.attributes?1:0}),b},Sao.common.find_focusable_child=function(a){var b,c,d,e;if(!a.is(":visible"))return null;if(~["input","select","textarea"].indexOf(a[0].tagName.toLowerCase()))return a;for(d=Sao.common.get_focus_chain(a),b=0,c=d.length;b<c;b++)if(e=Sao.common.find_focusable_child(jQuery(d[b])))return e},Sao.common.find_first_focus_widget=function(a,b){var c,d,e,f,g;if(1==b.length)return jQuery(b[0]);for(e=Sao.common.get_focus_chain(a),c=0;c<e.length;c++){for(f=[],d=0;d<b.length;d++)g=jQuery(b[d]).closest(e[c]).length>0,g&&f.push(b[d]);if(f.length>0)return Sao.common.find_first_focus_widget(jQuery(e[c]),f)}},Sao.common.apply_label_attributes=function(a,b,c){b?a.removeClass("editable required"):(a.addClass("editable"),c?a.addClass("required"):a.removeClass("required"))}}(),function(){"use strict";Sao.Window={},Sao.Window.InfoBar=Sao.class_(Object,{init:function(){this.text=jQuery("<span/>"),this.text.css("white-space","pre-wrap"),this.el=jQuery("<div/>",{class:"alert infobar",role:"alert"}).append(jQuery("<button/>",{type:"button",class:"close","aria-label":Sao.i18n.gettext("Close")}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).click(function(){this.el.hide()}.bind(this))).append(this.text),this.el.hide()},message:function(a,b){a?(this.el.removeClass("alert-success alert-info alert-warning alert-danger"),this.el.addClass("alert-"+(b||"info")),this.text.text(a),this.el.show()):this.el.hide()}}),Sao.Window.Form=Sao.class_(Object,{init:function(a,b,c){c=c||{},this.screen=a,this.callback=b,this.many=c.many||0,this.domain=c.domain||null,this.context=c.context||null,this.save_current=c.save_current;var d=jQuery.when(c.title||"");d.then(function(a){this.title=a}.bind(this)),this.prev_view=a.current_view,this.screen.screen_container.alternate_view=!0,this.info_bar=new Sao.Window.InfoBar;for(var e=c.view_type||"form",f=jQuery.when(),g=[],h=0,i=this.screen.views.length;h<i;h++)g.push(this.screen.views[h].view_type);~g.indexOf(e)||~this.screen.view_to_load.indexOf(e)||(f=this.screen.add_view_id(null,e));var j=f.then(function(){return this.screen.switch_view(e).done(function(){c.new_&&this.screen.new_(void 0,c.rec_name)}.bind(this))}.bind(this)),k=new Sao.Dialog("","","lg");this.el=k.modal;var l=this.screen.attributes.readonly||this.screen.group.get_readonly();if("form"==e&&k.footer.append(jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(!c.new_&&this.screen.current_record.id<0?Sao.i18n.gettext("Delete"):Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this))),c.new_&&this.many&&k.footer.append(jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("New")).click(function(){this.response("RESPONSE_ACCEPT")}.bind(this))),this.save_current?k.footer.append(jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Save"))):k.footer.append(jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK"))),k.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),"tree"==e){var m=jQuery("<div/>").appendTo(k.body),n=jQuery("<div/>",{class:"input-group input-group-sm"}).appendTo(m);this.wid_text=jQuery("<input/>",{type:"input"}).appendTo(m),this.wid_text.hide();var o=jQuery("<div/>",{class:"input-group-btn"}).appendTo(n),p=Sao.common.MODELACCESS.get(this.screen.model_name);this.domain&&(this.wid_text.show(),this.but_add=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-plus"})).appendTo(o),this.but_add.click(this.add.bind(this)),this.but_add.prop("disabled",!p.read||l),this.but_remove=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-minus"})).appendTo(o),this.but_remove.click(this.remove.bind(this)),this.but_remove.prop("disabled",!p.read||l)),this.but_new=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("New")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-edit"})).appendTo(o),this.but_new.click(this.new_.bind(this)),this.but_new.prop("disabled",!p.create||l),this.but_del=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Delete")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-trash"})).appendTo(o),this.but_del.click(this.delete_.bind(this)),this.but_del.prop("disabled",!p.delete||l),this.but_undel=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Undelete")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-repeat"})).appendTo(o),this.but_undel.click(this.undelete.bind(this)),this.but_undel.prop("disabled",!p.delete||l),this.but_previous=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-chevron-left"})).appendTo(o),this.but_previous.click(this.previous.bind(this)),this.label=jQuery("<span/>",{class:"btn"}).appendTo(o),this.label.text("(0, 0)"),this.but_next=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-chevron-right"})).appendTo(o),this.but_next.click(this.next.bind(this)),this.but_switch=jQuery("<button/>",{class:"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Switch")}).append(jQuery("<span/>",{class:"glyphicon glyphicon-list-alt"})).appendTo(o),this.but_switch.click(this.switch_.bind(this))}var q=jQuery("<div/>").appendTo(k.body);k.body.append(this.info_bar.el),j.done(function(){d.done(k.add_title.bind(k)),q.append(this.screen.screen_container.alternate_viewport),this.el.modal("show")}.bind(this)),this.el.on("shown.bs.modal",function(a){this.screen.display().done(function(){this.screen.set_cursor()}.bind(this))}.bind(this)),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},add:function(){var a=jQuery.extend([],this.domain),b=this.screen.model_name,c=this.wid_text.val(),d=function(a){var b=jQuery.when();if(!jQuery.isEmptyObject(a)){for(var c=[],d=0,e=a.length;d<e;d++)c.push(a[d][0]);this.screen.group.load(c,!0),b=this.screen.display()}b.done(function(){this.screen.set_cursor()}.bind(this)),this.entry.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(b,d,{sel_multi:!0,context:this.context,domain:a,search_filter:e.quote(c)})},remove:function(){this.screen.remove(!1,!0,!1)},new_:function(){this.screen.new_()},delete_:function(){this.screen.remove(!1,!1,!1)},undelete:function(){this.screen.unremove()},previous:function(){this.screen.display_previous()},next:function(){this.screen.display_next()},switch_:function(){this.screen.switch_view()},response:function(a){var b;this.screen.current_view.set_value();var c=this.screen.group.get_readonly();if(~["RESPONSE_OK","RESPONSE_ACCEPT"].indexOf(a)&&!c&&this.screen.current_record)return void this.screen.current_record.validate().then(function(a){return a&&this.screen.attributes.pre_validate?this.screen.current_record.pre_validate():a}.bind(this)).then(function(c){var d=jQuery.Deferred();if(c&&this.save_current)this.screen.save_current().then(d.resolve,d.reject);else if(c&&"form"==this.screen.current_view.view_type){var e=this.screen.current_view,f=[];for(var g in e.widgets){var h=e.widgets[g];if(h.screen&&h.screen.attributes.pre_validate){var i=h.screen.current_record;i&&f.push(i.pre_validate())}}jQuery.when.apply(jQuery,f).then(d.resolve,d.reject)}else c?(this.info_bar.message(),d.resolve()):(this.info_bar.message(this.screen.invalid_message(),"danger"),d.reject());d.fail(function(){this.screen.display().done(function(){this.screen.set_cursor()}.bind(this))}.bind(this)),d.done(function(){"RESPONSE_ACCEPT"==a?(this.screen.new_(),this.screen.current_view.display().done(function(){this.screen.set_cursor()}.bind(this)),this.many-=1,0===this.many&&this.but_new.prop("disabled",!0)):(b=!0,this.callback(b),this.destroy())}.bind(this))}.bind(this));if("RESPONSE_CANCEL"==a&&!c&&this.screen.current_record){if(b=!1,this.screen.current_record.id<0||this.save_current)this.screen.cancel_current();else if(this.screen.current_record.has_changed())return this.screen.current_record.cancel(),void this.screen.current_record.reload().always(function(){this.callback(b),this.destroy()}.bind(this))}else b="RESPONSE_CANCEL"!=a;this.callback(b),this.destroy()},destroy:function(){this.screen.screen_container.alternate_view=!1,this.screen.screen_container.alternate_viewport.children().detach(),this.prev_view&&this.screen.switch_view(this.prev_view.view_type),this.el.modal("hide")}}),Sao.Window.Attachment=Sao.class_(Sao.Window.Form,{init:function(a,b){this.resource=a.model.name+","+a.id,this.attachment_callback=b;var c=jQuery.extend({},a.get_context()),d=new Sao.Screen("ir.attachment",{domain:[["resource","=",this.resource]],mode:["tree","form"],context:c,exclude_field:"resource"});d.switch_view().done(function(){d.search_filter()});var e=a.rec_name().then(function(a){return Sao.i18n.gettext("Attachments (%1)",a)});Sao.Window.Attachment._super.init.call(this,d,this.callback,{view_type:"tree",title:e})},callback:function(a){var b=jQuery.when();if(a){var c=this.screen.group.model.fields.resource;this.screen.group.forEach(function(a){c.set_client(a,this.resource)}.bind(this)),b=this.screen.group.save()}this.attachment_callback&&b.always(this.attachment_callback.bind(this))}}),Sao.Window.Note=Sao.class_(Sao.Window.Form,{init:function(a,b){this.resource=a.model.name+","+a.id,this.note_callback=b;var c=jQuery.extend({},a.get_context()),d=new Sao.Screen("ir.note",{domain:[["resource","=",this.resource]],mode:["tree","form"],context:c,exclude_field:"resource"});d.switch_view().done(function(){d.search_filter()});var e=a.rec_name().then(function(a){return Sao.i18n.gettext("Notes (%1)",a)});Sao.Window.Note._super.init.call(this,d,this.callback,{view_type:"tree",title:e})},callback:function(a){var b=jQuery.when();if(a){var c=this.screen.group.model.fields.resource,d=this.screen.group.model.fields.unread;this.screen.group.forEach(function(a){(a.get_loaded()||a.id<0)&&(c.set_client(a,this.resource),a._changed.unread||d.set_client(a,!1))}.bind(this)),b=this.screen.group.save()}this.note_callback&&b.always(this.note_callback.bind(this))}}),Sao.Window.Search=Sao.class_(Object,{init:function(a,b,c){c=c||{};var d=c.views_preload||{};this.model_name=a,this.domain=c.domain||[],this.context=c.context||{},this.sel_multi=c.sel_multi,this.callback=b,this.title=c.title||"";var e=new Sao.Dialog(Sao.i18n.gettext("Search %1",this.title),"","lg");this.el=e.modal,jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(e.footer),jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Find")).click(function(){this.response("RESPONSE_APPLY")}.bind(this)).appendTo(e.footer),c.new_&&Sao.common.MODELACCESS.get(a).create&&jQuery("<button/>",{class:"btn btn-default",type:"button"}).append(Sao.i18n.gettext("New")).click(function(){this.response("RESPONSE_ACCEPT")}.bind(this)).appendTo(e.footer),jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(e.footer),e.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),this.screen=new Sao.Screen(a,{mode:["tree"],context:this.context,domain:this.domain,view_ids:c.view_ids,views_preload:d,row_activate:this.activate.bind(this)}),this.screen.load_next_view().done(function(){this.screen.switch_view().done(function(){e.body.append(this.screen.screen_container.el),this.el.modal("show"),this.screen.display(),void 0!==c.search_filter&&this.screen.search_filter(c.search_filter)}.bind(this))}.bind(this)),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},activate:function(){this.response("RESPONSE_OK")},response:function(a){var b,c=[];if("RESPONSE_OK"==a)b=this.screen.current_view.selected_records();else{if("RESPONSE_APPLY"==a)return void this.screen.search_filter();if("RESPONSE_ACCEPT"==a){var d=new Sao.Screen(this.model_name,{domain:this.domain,context:this.context,mode:["form"]}),e=function(a){a?d.save_current().then(function(){var a=d.current_record;this.callback([[a.id,a._values.rec_name||""]])}.bind(this),function(){this.callback(null)}.bind(this)):this.callback(null)};return this.el.modal("hide"),void new Sao.Window.Form(d,e.bind(this),{new_:!0,title:this.title})}}if(b){var f,g;for(f in b)g=b[f],c.push([g.id,g._values.rec_name||""])}this.callback(c),this.el.modal("hide")}}),Sao.Window.Preferences=Sao.class_(Object,{init:function(a){this.callback=a;var b=new Sao.Dialog("Preferences","","lg");this.el=b.modal,jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(b.footer),jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(b.footer),b.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),this.screen=new Sao.Screen("res.user",{mode:[]}),this.screen.attributes.readonly=!1,this.screen.group.set_readonly(!1),this.screen.group.skip_model_access=!0;var c=function(a){this.screen.add_view(a),this.screen.switch_view().done(function(){this.screen.new_(!1),this.screen.model.execute("get_preferences",[!1],{}).then(d.bind(this),this.destroy)}.bind(this))},d=function(a){var c;this.screen.current_record.cancel(),c=this.screen.current_record.set(a),this.screen.current_record.id=this.screen.model.session.user_id,c.then(function(){this.screen.current_record.validate(null,!0).then(function(){this.screen.display(!0)}.bind(this))}.bind(this)),b.body.append(this.screen.screen_container.el),this.el.modal("show")};this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()}),this.screen.model.execute("get_preferences_fields_view",[],{}).then(c.bind(this),this.destroy)},response:function(a){var b=function(){this.destroy(),this.callback()}.bind(this),c=jQuery.when();"RESPONSE_OK"==a&&(c=this.screen.current_record.validate().then(function(a){if(a){var b=jQuery.extend({},this.screen.get()),c=jQuery.extend({},Sao.Session.current_session.context),d=function(a){return{id:0,method:"model.res.user.set_preferences",params:[b,a,c]}};return new Sao.Login(d).run()}}.bind(this))),c.done(b)},destroy:function(){this.el.modal("hide")}}),Sao.Window.Revision=Sao.class_(Object,{init:function(a,b){this.callback=b;var c=new Sao.Dialog(Sao.i18n.gettext("Revision"),"","lg");this.el=c.modal,jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(c.footer),c.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this));var d=jQuery("<div/>",{class:"form-group"}).appendTo(c.body);jQuery("<label/>",{for:"revision",text:"Revision"}).appendTo(d),this.select=jQuery("<select/>",{class:"form-control",id:"revision",placeholder:Sao.i18n.gettext("Revision")}).appendTo(d);var e=Sao.common.date_format(),f="%H:%M:%S.%f";this.select.append(jQuery("<option/>",{value:null,text:""})),a.forEach(function(a){a[2];a=a[0],this.select.append(jQuery("<option/>",{value:a.valueOf(),text:Sao.common.format_datetime(e,f,a)+" "+this.title}))}.bind(this)),this.el.modal("show"),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},response:function(a){var b=null;"RESPONSE_OK"==a&&(b=this.select.val(),b&&(b=Sao.DateTime(parseInt(b,10)))),this.el.modal("hide"),this.callback(b)}}),Sao.Window.CSV=Sao.class_(Object,{init:function(a){this.encodings=["866","ansi_x3.4-1968","arabic","ascii","asmo-708","big5","big5-hkscs","chinese","cn-big5","cp1250","cp1251","cp1252","cp1253","cp1254","cp1255","cp1256","cp1257","cp1258","cp819","cp866","csbig5","cseuckr","cseucpkdfmtjapanese","csgb2312","csibm866","csiso2022jp","csiso2022kr","csiso58gb231280","csiso88596e","csiso88596i","csiso88598e","csiso88598i","csisolatin1","csisolatin2","csisolatin3","csisolatin4","csisolatin5","csisolatin6","csisolatin9","csisolatinarabic","csisolatincyrillic","csisolatingreek","csisolatinhebrew","cskoi8r","csksc56011987","csmacintosh","csshiftjis","cyrillic","dos-874","ecma-114","ecma-118","elot_928","euc-jp","euc-kr","gb18030","gb2312","gb_2312","gb_2312-80","gbk","greek","greek8","hebrew","hz-gb-2312","ibm819","ibm866","iso-2022-cn","iso-2022-cn-ext","iso-2022-jp","iso-2022-kr","iso-8859-1","iso-8859-10","iso-8859-11","iso-8859-13","iso-8859-14","iso-8859-15","iso-8859-16","iso-8859-2","iso-8859-3","iso-8859-4","iso-8859-5","iso-8859-6","iso-8859-6-e","iso-8859-6-i","iso-8859-7","iso-8859-8","iso-8859-8-e","iso-8859-8-i","iso-8859-9","iso-ir-100","iso-ir-101","iso-ir-109","iso-ir-110","iso-ir-126","iso-ir-127","iso-ir-138","iso-ir-144","iso-ir-148","iso-ir-149","iso-ir-157","iso-ir-58","iso8859-1","iso8859-10","iso8859-11","iso8859-13","iso8859-14","iso8859-15","iso8859-2","iso8859-3","iso8859-4","iso8859-5","iso8859-6","iso8859-7","iso8859-8","iso8859-9","iso88591","iso885910","iso885911","iso885913","iso885914","iso885915","iso88592","iso88593","iso88594","iso88595","iso88596","iso88597","iso88598","iso88599","iso_8859-1","iso_8859-15","iso_8859-1:1987","iso_8859-2","iso_8859-2:1987","iso_8859-3","iso_8859-3:1988","iso_8859-4","iso_8859-4:1988","iso_8859-5","iso_8859-5:1988","iso_8859-6","iso_8859-6:1987","iso_8859-7","iso_8859-7:1987","iso_8859-8","iso_8859-8:1988","iso_8859-9","iso_8859-9:1989","koi","koi8","koi8-r","koi8-ru","koi8-u","koi8_r","korean","ks_c_5601-1987","ks_c_5601-1989","ksc5601","ksc_5601","l1","l2","l3","l4","l5","l6","l9","latin1","latin2","latin3","latin4","latin5","latin6","logical","mac","macintosh","ms932","ms_kanji","shift-jis","shift_jis","sjis","sun_eu_greek","tis-620","unicode-1-1-utf-8","us-ascii","utf-16","utf-16be","utf-16le","utf-8","utf8","visual","windows-1250","windows-1251","windows-1252","windows-1253","windows-1254","windows-1255","windows-1256","windows-1257","windows-1258","windows-31j","windows-874","windows-949","x-cp1250","x-cp1251","x-cp1252","x-cp1253","x-cp1254","x-cp1255","x-cp1256","x-cp1257","x-cp1258","x-euc-jp","x-gbk","x-mac-cyrillic","x-mac-roman","x-mac-ukrainian","x-sjis","x-user-defined","x-x-big5"],this.dialog=new Sao.Dialog(a,"csv","lg"),this.el=this.dialog.modal,this.fields={},this.fields_model={},jQuery("<button/>",{class:"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(this.dialog.footer),jQuery("<button/>",{class:"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).click(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)).appendTo(this.dialog.footer);var b=jQuery("<div/>",{class:"row"}).appendTo(this.dialog.body);jQuery("<hr/>").appendTo(this.dialog.body);var c=jQuery("<div/>",{class:"col-md-4 column-fields"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("All Fields")})).appendTo(b);this.fields_all=jQuery("<ul/>",{class:"list-unstyled"}).css("cursor","pointer").appendTo(c);var d=this.get_fields(this.screen.model_name).then(function(a){this.model_populate(a),this.view_populate(this.fields_model,this.fields_all)}.bind(this));this.column_buttons=jQuery("<div/>",{class:"col-md-4"}).append("<label/>").appendTo(b);jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-plus"})).click(function(){this.fields_all.find(".bg-primary").each(function(a,b){this.sig_sel_add(b)}.bind(this))}.bind(this)).append(" "+Sao.i18n.gettext("Add")).appendTo(this.column_buttons);jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-minus"})).click(function(){this.fields_selected.children("li.bg-primary").remove()}.bind(this)).append(" "+Sao.i18n.gettext("Remove")).appendTo(this.column_buttons),jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-remove"})).click(function(){this.fields_selected.empty()}.bind(this)).append(" "+Sao.i18n.gettext("Clear")).appendTo(this.column_buttons),jQuery("<hr>").appendTo(this.column_buttons);var e=jQuery("<div/>",{class:"col-md-4 column-fields"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("Fields Selected")})).appendTo(b);this.fields_selected=jQuery("<ul/>",{class:"list-unstyled"}).css("cursor","pointer").appendTo(e),this.chooser_form=jQuery("<div/>",{class:"form-inline"}).appendTo(this.dialog.body);var f=jQuery("<div/>",{class:"row"}).appendTo(this.dialog.body),g=jQuery("<span/>",{class:"glyphicon glyphicon-plus"}).css("cursor","pointer").html(" "),h=jQuery("<label/>",{text:Sao.i18n.gettext("CSV Parameters")}).css("cursor","pointer");jQuery("<div/>",{class:"col-md-12"}).append(g).append(h).on("click",function(){g.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),this.expander_csv.collapse("toggle")}.bind(this)).appendTo(f),this.expander_csv=jQuery("<div/>",{id:"expander_csv",class:"collapse"}).appendTo(f);var i=jQuery("<label/>",{text:Sao.i18n.gettext("Delimiter:"),class:"col-sm-2 control-label",for:"input-delimiter"});this.el_csv_delimiter=jQuery("<input/>",{type:"text",class:"form-control",id:"input-delimiter",size:"1",maxlength:"1",value:","}),jQuery("<div/>",{class:"form-group"}).append(i).append(jQuery("<div/>",{class:"col-sm-4"}).append(this.el_csv_delimiter)).appendTo(this.expander_csv);var j=jQuery("<label/>",{text:Sao.i18n.gettext("Quote Char:"),class:"col-sm-2 control-label",for:"input-quotechar"});this.el_csv_quotechar=jQuery("<input/>",{type:"text",class:"form-control",id:"input-quotechar",size:"1",maxlength:"1",value:'"',readonly:""}),jQuery("<div/>",{class:"form-group"}).append(j).append(jQuery("<div/>",{class:"col-sm-4"}).append(this.el_csv_quotechar)).appendTo(this.expander_csv);var k=jQuery("<label/>",{text:Sao.i18n.gettext("Encoding:"),class:"col-sm-2 control-label",for:"input-encoding"});this.el_csv_encoding=jQuery("<select/>",{class:"form-control",id:"input-encoding"});for(var l=0;l<this.encodings.length;l++)jQuery("<option/>",{val:this.encodings[l]}).html(this.encodings[l]).appendTo(this.el_csv_encoding);var m="utf-8";return"Win32"!=navigator.platform&&"Windows"!=navigator.platform||(m="cp1252"),this.el_csv_encoding.children('option[value="'+m+'"]').attr("selected","selected"),jQuery("<div/>",{class:"form-group"}).append(k).append(jQuery("<div/>",{class:"col-sm-4"}).append(this.el_csv_encoding)).appendTo(this.expander_csv),this.el.modal("show"),this.el.on("hidden.bs.modal",function(){jQuery(this).remove()}),d},get_fields:function(a){return Sao.rpc({method:"model."+a+".fields_get"},this.session)},on_row_expanded:function(a){var b=jQuery("<ul/>").css("list-style","none").insertAfter(a.view);this.children_expand(a).done(function(){this.view_populate(a.children,b)}.bind(this))},destroy:function(){this.el.modal("hide")}}),Sao.Window.Import=Sao.class_(Sao.Window.CSV,{init:function(a){this.screen=a,this.session=Sao.Session.current_session,this.fields_data={},this.fields_invert={},Sao.Window.Import._super.init.call(this,Sao.i18n.gettext("Import from CSV")),jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-search"})).click(function(){this.autodetect()}.bind(this)).append(" "+Sao.i18n.gettext("Auto-Detect")).appendTo(this.column_buttons);var b=jQuery("<label/>",{text:Sao.i18n.gettext("File to Import"),class:"col-sm-6 control-label",for:"input-csv-file"});this.file_input=jQuery("<input/>",{type:"file",id:"input-csv-file"}),jQuery("<div/>",{class:"form-group"}).append(b).append(jQuery("<div/>",{class:"col-sm-6"}).append(this.file_input)).appendTo(this.chooser_form),jQuery("<hr>").insertAfter(this.chooser_form);var c=jQuery("<label/>",{text:Sao.i18n.gettext("Lines to Skip:"),class:"col-sm-2 control-label",for:"input-skip"});this.el_csv_skip=jQuery("<input/>",{type:"number",class:"form-control",id:"input-skip",value:"0"}),jQuery("<div/>",{class:"form-group"}).append(c).append(jQuery("<div/>",{class:"col-sm-4"}).append(this.el_csv_skip)).appendTo(this.expander_csv)},sig_sel_add:function(a){a=jQuery(a);var b=a.attr("field"),c=jQuery("<li/>",{field:b}).html(a.attr("name")).click(function(a){a.ctrlKey?c.toggleClass("bg-primary"):jQuery(a.target).addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},view_populate:function(a,b){var c=Object.keys(a).sort(function(b,c){return a[c].string<a[b].string?-1:1}).reverse();c.forEach(function(c){var d=a[c].string||c,e=jQuery("<li/>",{field:a[c].field,name:a[c].name}).html(d).click(function(a){a.ctrlKey?e.toggleClass("bg-primary"):(this.fields_all.find("li").removeClass("bg-primary"),e.addClass("bg-primary"))}.bind(this)).appendTo(b);if(a[c].view=e,a[c].relation){e.prepend(" ");var f=jQuery("<i/>",{class:"glyphicon glyphicon-plus"}).click(function(b){b.stopPropagation(),f.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),f.hasClass("glyphicon-minus")?this.on_row_expanded(a[c]):e.next("ul").remove()}.bind(this)).prependTo(e)}}.bind(this))},model_populate:function(a,b,c,d){b=b||this.fields_model,c=c||"",d=d||"",Object.keys(a).forEach(function(e){if(!a[e].readonly){var f=a[e].string||e;f=d+f;var g;g="one2many"==a[e].type?a[e].relation:null;var h={name:f,field:c+e,relation:g,string:a[e].string};b[e]=h,this.fields[c+e]=h,this.fields_invert[f]=c+e,g&&(h.children={})}}.bind(this))},children_expand:function(a){var b=jQuery.Deferred();return jQuery.isEmptyObject(a.children)?this.get_fields(a.relation).done(function(c){this.model_populate(c,a.children,a.field+"/",a.name+"/"),b.resolve(this)}.bind(this)):b.resolve(this),b.promise()},autodetect:function(){var a=this.file_input.val();return a?(this.fields_selected.empty(),this.el_csv_skip.val(1),void Papa.parse(this.file_input[0].files[0],{config:{delimiter:this.el_csv_delimiter.val(),preview:1,encoding:this.el_csv_encoding.val()},error:function(a,b,c,d){Sao.common.warning(Sao.i18n.gettext("Error occured in loading the file"))},complete:function(a){a.data[0].forEach(function(a){if(a in this.fields_invert||a in this.fields)this.auto_select(a);else{var b=this.fields_model,c="",d=a.split("/");this.traverse(b,c,d,0)}}.bind(this))}.bind(this)})):void Sao.common.message.run(Sao.i18n.gettext("You must select an import file first"))},auto_select:function(a){var b,c;if(a in this.fields_invert)b=a,c=this.fields_invert[a];else{if(!(a in this.fields))return void Sao.common.warning.run(Sao.i18n.gettext("Error processing the file at field %1.",a),Sao.i18n.gettext("Error"));b=this.fields[a].name,c=[a]}var d=jQuery("<li/>",{field:c}).html(b).click(function(){d.addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},traverse:function(a,b,c,d){function e(e){a=f.children,b+=c[d]+"/",e.traverse(a,b,c,++d)}if(d>=c.length-1)return void this.auto_select(c.join("/"));var f,g,h=Object.keys(a);for(g=0;g<h.length;g++)if(f=a[h[g]],f.name==b+c[d]||f.field==b+c[d]){this.children_expand(f).done(e);break}return g==h.length?void this.auto_select(c.join("/")):void 0},response:function(a){if("RESPONSE_OK"==a){var b=[];this.fields_selected.children("li").each(function(a,c){b.push(c.getAttribute("field"))});var c=this.file_input.val();c?this.import_csv(c,b).then(function(){this.destroy()}.bind(this)):this.destroy()}else this.destroy()},import_csv:function(a,b){var c=this.el_csv_skip.val(),d=this.el_csv_encoding.val(),e=jQuery.Deferred();return Papa.parse(this.file_input[0].files[0],{config:{delimiter:this.el_csv_delimiter.val(),encoding:d},error:function(a,b,c,d){Sao.common.warning.run(Sao.i18n.gettext("Error occured in loading the file")).always(e.reject)},complete:function(a){function d(a){return unescape(encodeURIComponent(a));
-}var f=[];a.data.pop(""),a.data.forEach(function(a,b){if(!(b<c)){var e=[];a.forEach(function(a){e.push(d(a))}),f.push(e)}}),Sao.rpc({method:"model."+this.screen.model_name+".import_data",params:[b,f,{}]},this.session).then(function(a){return Sao.common.message.run(Sao.i18n.ngettext("%1 record imported","%1 records imported",a))}).then(e.resolve,e.reject)}.bind(this)}),e.promise()}}),Sao.Window.Export=Sao.class_(Sao.Window.CSV,{init:function(a,b,c){this.ids=b,this.screen=a,this.session=Sao.Session.current_session,Sao.Window.Export._super.init.call(this,Sao.i18n.gettext("Export to CSV")).then(function(){c.forEach(function(a){this.sel_field(a)}.bind(this))}.bind(this));var d=jQuery("<div/>",{class:"row"}).prependTo(this.dialog.body),e=jQuery("<div/>",{class:"col-md-12"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("Predefined Exports")})).appendTo(d);this.predef_exports_list=jQuery("<ul/>",{class:"list-unstyled predef-exports"}).css("cursor","pointer").appendTo(e),e.append("<hr/>"),this.predef_exports={},this.fill_predefwin(),jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-floppy-save"})).click(function(){this.addreplace_predef()}.bind(this)).append(" "+Sao.i18n.gettext("Save Export")).appendTo(this.column_buttons),jQuery("<button/>",{class:"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{class:"glyphicon glyphicon-floppy-remove"})).click(function(){this.remove_predef()}.bind(this)).append(" "+Sao.i18n.gettext("Delete Export")).appendTo(this.column_buttons),this.el_add_field_names=jQuery("<input/>",{type:"checkbox",checked:"checked"}),jQuery("<div/>",{class:"form-group"}).append(jQuery("<div/>",{class:"col-md-6"}).append(jQuery("<label/>",{text:" "+Sao.i18n.gettext("Add Field Names")}).prepend(this.el_add_field_names))).appendTo(this.expander_csv)},view_populate:function(a,b){var c=Object.keys(a).sort(function(b,c){return a[c].string<a[b].string?-1:1}).reverse();c.forEach(function(c){var d=a[c].path,e=jQuery("<li/>",{path:d}).html(a[c].string).click(function(a){a.ctrlKey?e.toggleClass("bg-primary"):(this.fields_all.find("li").removeClass("bg-primary"),e.addClass("bg-primary"))}.bind(this)).appendTo(b);if(a[c].view=e,a[c].children){e.prepend(" ");var f=jQuery("<i/>",{class:"glyphicon glyphicon-plus"}).click(function(b){b.stopPropagation(),f.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),f.hasClass("glyphicon-minus")?this.on_row_expanded(a[c]):e.next("ul").remove()}.bind(this)).prependTo(e)}}.bind(this))},model_populate:function(a,b,c,d){b=b||this.fields_model,c=c||"",d=d||"",Object.keys(a).forEach(function(e){var f=a[e],g=f.string||e,h=[{name:e,field:f,string:g}];"selection"==f.type&&h.push({name:e+".translated",field:f,string:Sao.i18n.gettext("%1 (string)",g)}),h.forEach(function(a){var e=c+a.name,f=a.string;c&&(f=d+a.string);var g={path:e,string:a.string,long_string:f,relation:a.field.relation};b[a.name]=g,this.fields[e]=g,a.name.indexOf(".")==-1&&a.field.relation&&(g.children={})}.bind(this))}.bind(this))},children_expand:function(a){var b=jQuery.Deferred();return jQuery.isEmptyObject(a.children)?this.get_fields(a.relation).done(function(c){this.model_populate(c,a.children,a.path+"/",a.string+"/"),b.resolve(this)}.bind(this)):b.resolve(this),b.promise()},sig_sel_add:function(a){a=jQuery(a);var b=a.attr("path");this.sel_field(b)},fill_predefwin:function(){Sao.rpc({method:"model.ir.export.search",params:[["resource","=",this.screen.model_name],{}]},this.session).done(function(a){Sao.rpc({method:"model.ir.export.read",params:[a,{}]},this.session).done(function(a){var b=[];a.forEach(function(a){for(var c=0;c<a.export_fields.length;b.push(a.export_fields[c++]));}),Sao.rpc({method:"model.ir.export.line.read",params:[b,{}]},this.session).done(function(b){var c={};b.forEach(function(a){c[a.export]=c[a.export]||[],c[a.export].push(a)}),a.forEach(function(a){this.predef_exports[a.id]=c[a.id].map(function(b){if(b.export==a.id)return b.name}),this.add_to_predef(a.id,a.name)}.bind(this)),this.predef_exports_list.children("li").first().focus()}.bind(this))}.bind(this))}.bind(this))},add_to_predef:function(a,b){var c=jQuery("<li/>",{text:b,export_id:a,tabindex:0}).on("keypress",function(a){var b=a.keyCode?a.keyCode:a.which;13!=b&&32!=b||c.click()}).click(function(a){c.addClass("bg-primary").siblings().removeClass("bg-primary"),this.sel_predef(jQuery(a.target).attr("export_id"))}.bind(this));this.predef_exports_list.append(c)},addreplace_predef:function(){for(var a=[],b=this.fields_selected.children("li"),c=0;c<b.length;c++)a.push(b[c].getAttribute("path"));if(0!==a.length){var d,e,f=this.predef_exports_list.children("li.bg-primary");0===f.length?(d=null,Sao.common.ask.run(Sao.i18n.gettext("What is the name of this export?")).then(function(b){b&&this.save_predef(b,a,f)}.bind(this))):(d=f.attr("export_id"),e=f.text(),Sao.common.sur.run(Sao.i18n.gettext("Override %1 definition?",e)).done(function(){this.save_predef(e,a,f),Sao.rpc({method:"model.ir.export.delete",params:[[d],{}]},this.session).then(function(){delete this.predef_exports[d]}.bind(this))}.bind(this)))}},save_predef:function(a,b,c){Sao.rpc({method:"model.ir.export.create",params:[[{name:a,resource:this.screen.model_name,export_fields:[["create",b.map(function(a){return{name:a}})]]}],{}]},this.session).then(function(d){this.predef_exports[d]=b,0===c.length?this.add_to_predef(d,a):(this.predef_exports[d]=b,c.attr("export_id",d))}.bind(this))},remove_predef:function(){var a=this.predef_exports_list.children("li.bg-primary");if(0!==a.length){var b=jQuery(a).attr("export_id");Sao.rpc({method:"model.ir.export.delete",params:[[b],{}]},this.session).then(function(){delete this.predef_exports[b],a.remove()}.bind(this))}},sel_predef:function(a){this.fields_selected.empty(),this.predef_exports[a].forEach(function(a){if(!(a in this.fields)){var b=this.fields_model,c="",d=a.split("/");this.traverse(b,c,d,0)}a in this.fields&&this.sel_field(a)}.bind(this))},traverse:function(a,b,c,d){function e(e){a=f.children,b+=c[d]+"/",e.traverse(a,b,c,++d)}if(d>=c.length-1)return void this.sel_field(c.join("/"));var f,g,h=Object.keys(a);for(g=0;g<h.length;g++)if(f=a[h[g]],f.path==b+c[d]){this.children_expand(f).done(e);break}return g==h.length?void this.sel_field(c.join("/")):void 0},sel_field:function(a){var b=this.fields[a].long_string,c=this.fields[a].relation;if(!c)var d=jQuery("<li/>",{path:a}).html(b).click(function(a){a.ctrlKey?d.toggleClass("bg-primary"):jQuery(a.target).addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},response:function(a){if("RESPONSE_OK"==a){var b=[],c=[];this.fields_selected.children("li").each(function(a,d){b.push(d.getAttribute("path")),c.push(d.innerText)}),Sao.rpc({method:"model."+this.screen.model_name+".export_data",params:[this.ids,b,{}]},this.session).then(function(a){this.export_csv(c,a).then(function(){this.destroy()}.bind(this))}.bind(this))}else this.destroy()},export_csv:function(a,b){var c=this.el_csv_encoding.val(),d={};d.data=b,this.el_add_field_names.is(":checked")&&(d.fields=a);var e=Papa.unparse(d,{delimiter:this.el_csv_delimiter.val()}),f=new Blob([e],{type:"text/csv;charset="+c}),g=window.URL.createObjectURL(f);return this.blob_url&&window.URL.revokeObjectURL(this.blob_url),this.blob_url=g,window.open(g),Sao.common.message.run(Sao.i18n.ngettext("%1 record saved","%1 records saved",b.length))}})}(),function(){"use strict";Sao.Wizard=Sao.class_(Object,{init:function(a){this.widget=jQuery("<div/>",{class:"wizard"}),this.name=a||"",this.action_id=null,this.id=null,this.ids=null,this.action=null,this.context=null,this.states={},this.session_id=null,this.start_state=null,this.end_state=null,this.screen=null,this.screen_state=null,this.state=null,this.session=Sao.Session.current_session,this.__processing=!1,this.__waiting_response=!1,this.info_bar=new Sao.Window.InfoBar},run:function(a){this.action=a.action,this.action_id=a.data.action_id,this.id=a.data.id,this.ids=a.data.ids,this.model=a.data.model,this.context=a.context,Sao.rpc({method:"wizard."+this.action+".create",params:[this.session.context]},this.session).then(function(a){this.session_id=a[0],this.start_state=this.state=a[1],this.end_state=a[2],this.process()}.bind(this),function(){this.destroy()}.bind(this))},process:function(){if(!this.__processing&&!this.__waiting_response){var a=function(){if(this.state==this.end_state)return void this.end();var a=jQuery.extend({},this.context);a.active_id=this.id,a.active_ids=this.ids,a.active_model=this.model,a.action_id=this.action_id;var b={};this.screen&&(b[this.screen_state]=this.screen.get_on_change_value()),Sao.rpc({method:"wizard."+this.action+".execute",params:[this.session_id,b,this.state,a]},this.session).then(function(a){if(a.view){this.clean();var b=a.view;this.update(b.fields_view,b.defaults,b.buttons),this.screen_state=b.state,this.__waiting_response=!0}else this.state=this.end_state;var c=function(){a.actions&&a.actions.forEach(function(a){Sao.Action.exec_action(a[0],a[1],jQuery.extend({},this.context))}.bind(this))}.bind(this);this.state==this.end_state?this.end().then(c):c(),this.__processing=!1}.bind(this),function(a){this.__processing=!1}.bind(this))};a.call(this)}},destroy:function(){},end:function(){return Sao.rpc({method:"wizard."+this.action+".delete",params:[this.session_id,this.session.context]},this.session)},clean:function(){this.widget.children().remove(),this.states={}},response:function(a){return this.__waiting_response=!1,this.screen.current_view.set_value(),this.screen.current_record.validate().then(function(b){return b||a==this.end_state?(this.info_bar.message(),this.state=a,void this.process()):(this.screen.display(!0),void this.info_bar.message(this.screen.invalid_message(),"danger"))}.bind(this))},_get_button:function(a){var b=new Sao.common.Button(a);return this.states[a.state]=b,a.default?b.el.addClass("btn-primary"):a.state==this.end_state&&b.el.addClass("btn-link"),b},update:function(a,b,c){c.forEach(function(a){this._get_button(a)}.bind(this)),this.screen=new Sao.Screen(a.model,{mode:[],context:this.context}),this.screen.add_view(a),this.screen.switch_view(),this.widget.append(this.screen.screen_container.el),this.screen.new_(!1),this.screen.current_record.set_default(b),this.screen.set_cursor()}}),Sao.Wizard.create=function(a){var b;if(a.window){b=new Sao.Wizard.Form(a.name);var c=new Sao.Tab.Wizard(b);Sao.Tab.add(c)}else b=new Sao.Wizard.Dialog(a.name);b.run(a)},Sao.Wizard.Form=Sao.class_(Sao.Wizard,{init:function(a){Sao.Wizard.Form._super.init.call(this),this.tab=null,this.name=a||"",this.form=jQuery("<div/>",{class:"wizard-form"}).append(this.widget),this.footer=jQuery("<div/>",{class:"modal-footer"}).appendTo(this.form)},clean:function(){Sao.Wizard.Form._super.clean.call(this),this.footer.children().remove()},_get_button:function(a){var b=Sao.Wizard.Form._super._get_button.call(this,a);return this.footer.append(b.el),b.el.click(function(){this.response(a.state)}.bind(this)),b},end:function(){return Sao.Wizard.Form._super.end.call(this).always(function(){return this.tab.close()}.bind(this))}}),Sao.Wizard.Dialog=Sao.class_(Sao.Wizard,{init:function(a){a||(a=Sao.i18n.gettext("Wizard")),Sao.Wizard.Dialog._super.init.call(this);var b=new Sao.Dialog(a,"wizard-dialog","lg");this.dialog=b.modal,this.dialog.on("shown.bs.modal",function(){Sao.View.resize(jQuery(this))}),this.content=b.content,this.footer=b.footer,b.body.append(this.widget).append(this.info_bar.el)},clean:function(){Sao.Wizard.Dialog._super.clean.call(this),this.footer.children().remove()},_get_button:function(a){var b=Sao.Wizard.Dialog._super._get_button.call(this,a);return this.footer.append(b.el),a.default?(this.content.unbind("submit"),this.content.submit(function(b){this.response(a.state),b.preventDefault()}.bind(this)),b.el.attr("type","submit")):b.el.click(function(){this.response(a.state)}.bind(this)),b},update:function(a,b,c){this.content.unbind("submit"),Sao.Wizard.Dialog._super.update.call(this,a,b,c),this.dialog.modal("show")},destroy:function(a){Sao.Wizard.Dialog._super.destroy.call(this),this.dialog.on("hidden.bs.modal",function(b){this.dialog.remove();var c,d=jQuery(".wizard-dialog").filter(":visible")[0],e=!1;if(d||(d=Sao.Tab.tabs.get_current(),d?d.screen&&d.screen.model_name!=this.model&&(e=!0,c=Sao.main_menu_screen):(e=!0,c=Sao.main_menu_screen)),d&&d.screen&&(c=d.screen),c){if(c.current_record&&!e){var f;f=c.model_name==this.model?this.ids:[c.current_record.id],c.reload(f,!0)}a&&c.client_action(a)}}.bind(this)),this.dialog.modal("hide")},end:function(){return Sao.Wizard.Dialog._super.end.call(this).then(this.destroy.bind(this))},show:function(){this.dialog.modal("show")},hide:function(){this.dialog.modal("hide")},state_changed:function(){this.process()}})}(),function(){"use strict";Sao.View.Board=Sao.class_(Object,{init:function(a,b){var c,d,e,f;this.context=b,this.actions=[],this.el=jQuery("<div/>",{class:"board"}),c={},e=a.children()[0];for(var g=0,h=e.attributes.length;g<h;g++)d=e.attributes[g],c[d.name]=d.value;for(this.attributes=c,this.el.append(this.parse(e).el),f=[],g=0,h=this.actions.length;g<h;g++)f.push(this.actions[g].action_prm);this.actions_prms=jQuery.when.apply(jQuery,f)},_parse_node:function(a,b,c){switch(a.tagName){case"image":break;case"separator":this._parse_separator(a,b,c);break;case"label":this._parse_label(a,b,c);break;case"newline":b.add_row();break;case"notebook":this._parse_notebook(a,b,c);break;case"page":this._parse_page(a,b,c);break;case"group":this._parse_group(a,b,c);break;case"hpaned":this._parse_pane(a,b,c,"horizontal");break;case"vpaned":this._parse_pane(a,b,c,"vertical");break;case"child":this._parse_child(a,b,c);break;case"action":this._parse_action(a,b,c)}},parse:function(a,b){var c;return b||(b=new Sao.View.Form.Container(Number(a.getAttribute("col")||4))),c=function(a,c){var d,e,f,g;for(d={},f=0,g=c.attributes.length;f<g;f++)e=c.attributes[f],d[e.name]=e.value;["yexpand","yfill","xexpand","xfill","colspan","position"].forEach(function(a){d[a]&&(d[a]=Number(d[a]))}),this._parse_node(c,b,d)},jQuery(a).children().each(c.bind(this)),b},_parse_separator:function(a,b,c){var d,e;d=c.string,e=new Sao.view.Form.Separator(d,c),b.add(c,e)},_parse_label:function(a,b,c){var d,e;return(d=c.string)?(e=new Sao.View.Form.Label(d,c),void b.add(c,e)):void b.add(c)},_parse_notebook:function(a,b,c){var d;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),d=new Sao.View.Form.Notebook(c),b.add(c,d),this.parse(a,b)},_parse_page:function(a,b,c){var d;d=c.string,page=this.parse(a,b),page=new Sao.View.Form.Page(b.add(page.el,d),c)},_parse_group:function(a,b,c){var d;d=new Sao.View.Form.Group(c),b.add(c,d)},_parse_pane:function(a,b,c,d){var e;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),e=new Sao.common.Paned(d),b.add(c,e),this.parse(a,e)},_parse_child:function(a,b,c){var d,e,f;d=this.parse(a),e=b.get_child1(),e.children().length>0?(f=b.get_child2(),f.append(d.el)):e.append(d.el)},_parse_action:function(a,b,c){var d;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),d=new Sao.View.Board.Action(c,this.context),this.actions.push(d),b.add(c,d)},reload:function(){for(var a=0;a<this.actions.length;a++)this.actions[a].display()}}),Sao.View.Board.Action=Sao.class_(Object,{init:function(a,b){var c,d;this.name=a.name,this.context=b||{},c=new Sao.Model("ir.action.act_window"),this.action_prm=c.execute("get",[this.name],this.context),this.action_prm.done(function(b){var c,e,f,g,h,i;if(this.action=b,this.action.mode=[],f=[],(this.action.views||[]).length>0)for(c=0,e=this.action.views.length;c<e;c++)f.push(this.action.views[c][0]),this.action.mode.push(this.action.views[c][1]);else void 0!==this.action.view_id&&(f=[this.action.view_id[0]]);"mode"in a&&(this.action.mode=a.mode),"pyson_domain"in this.action||(this.action.pyson_domain="[]"),jQuery.extend(this.context,Sao.Session.current_session.context),this.context._user=Sao.Session.current_session.user_id,g=new Sao.PYSON.Decoder(this.context),jQuery.extend(this.context,g.decode(this.action.pyson_context||"{}")),g=new Sao.PYSON.Decoder(this.context),jQuery.extend(this.context,g.decode(this.action.pyson_context||"{}")),this.domain=[],this.update_domain([]),h=jQuery.extend({},this.context),h.context=this.context,h._user=Sao.Session.current_session.user_id,g=new Sao.PYSON.Decoder(h),d=g.decode(this.action.pyson_search_value||"{}"),i={mode:this.action.mode,context:this.context,view_ids:f,domain:this.domain,search_value:d,row_activate:this.row_activate.bind(this)},this.screen=new Sao.Screen(this.action.res_model,i),a.string?this.title.html(a.string):this.title.html(this.action.name),this.screen.switch_view().done(function(){this.body.append(this.screen.screen_container.el),this.screen.search_filter()}.bind(this))}.bind(this)),this.el=jQuery("<div/>",{class:"board-action panel panel-default"}),this.title=jQuery("<div/>",{class:"panel-heading"}),this.el.append(this.title),this.body=jQuery("<div/>",{class:"panel-body"}),this.el.append(this.body)},row_activate:function(){var a,b;this.screen.current_record&&("tree"==this.screen.current_view.view_type&&1==this.screen.current_view.attributes.keyword_open?(a=this.screen.current_view.selected_records().map(function(a){return a.id}),Sao.Action.exec_keyword("tree_open",{model:this.screen.model_name,id:this.screen.current_record.id,ids:a},jQuery.extend({},this.context),!1)):b=new Sao.Window.Form(this.screen,function(a){a?this.screen.current_record.save():this.screen.current_record.cancel()}.bind(this)))},set_value:function(){},display:function(){this.screen.search_filter(this.screen.screen_container.get_text())},get_active:function(){if(this.screen&&this.screen.current_record)return Sao.common.EvalEnvironment(this.screen.current_record)},update_domain:function(a){var b,c,d,e,f,g;for(e=jQuery.extend({},this.context),e.context=e,e._user=Sao.Session.current_session.user_id,b=0,c=a.length;b<c;b++)d=a[b].get_active(),d&&(e[a[b].name]=d);f=new Sao.PYSON.Decoder(e),g=f.decode(this.action.pyson_domain),Sao.common.compare(this.domain,g)||(this.domain.splice(0,this.domain.length),jQuery.extend(this.domain,g),this.screen&&this.display())}})}();
\ No newline at end of file
+function eval_pyson(value){with(Sao.PYSON.eval)return eval(value)}var Sao={};!function(){"use strict";function a(){var a=1040;jQuery(".modal.in").each(function(b){var c=jQuery(this);a++,c.css("zIndex",a),c.next(".modal-backdrop.in").addClass("hidden").css("zIndex",a-1)}),jQuery(".modal.in:visible:last").focus().next(".modal-backdrop.in").removeClass("hidden")}"contains"in String.prototype||(String.prototype.contains=function(a,b){return-1!==String.prototype.indexOf.call(this,a,b)}),String.prototype.startsWith||Object.defineProperty(String.prototype,"startsWith",{enumerable:!1,configurable:!1,writable:!1,value:function(a,b){return b=b||0,this.indexOf(a,b)===b}}),String.prototype.endsWith||Object.defineProperty(String.prototype,"endsWith",{enumerable:!1,configurable:!1,writable:!1,value:function(a,b){b=b||this.length,b-=a.length;var c=this.lastIndexOf(a);return-1!==c&&c===b}}),Array.prototype.some||(Array.prototype.some=function(a){if(null===this)throw new TypeError;var b,c,d=Object(this),e=d.length>>>0;if("function"!=typeof a)throw new TypeError;for(b=arguments[1],c=0;e>c;c++)if(c in d&&a.call(b,d[c],c,d))return!0;return!1});try{document.execCommand("styleWithCSS",!1,!1)}catch(b){}try{document.execCommand("useCSS",!1,!0)}catch(b){}jQuery.fn.extend({uniqueId:function(){var a=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})}}()}),Sao.class_=function(a,b){var c=function(){if(!(this instanceof c))throw new Error("Constructor function requires new operator");this.Class=c,this.init&&this.init.apply(this,arguments)};if(c.prototype=Object.create(a.prototype),c._super=a.prototype,b)for(var d in b)c.prototype[d]=b[d];return c},Sao.Decimal=Number,Sao.Date=function(a,b,c){var d=moment();return d.year(a),d.month(b),d.date(c),d.set({hour:0,minute:0,second:0,millisecond:0}),d.isDate=!0,d},Sao.Date.min=moment(new Date(-864e13)),Sao.Date.min.set({hour:0,minute:0,second:0,millisecond:0}),Sao.Date.min.isDate=!0,Sao.Date.max=moment(new Date(864e13)),Sao.Date.max.set({hour:0,minute:0,second:0,millisecond:0}),Sao.Date.max.isDate=!0,Sao.DateTime=function(a,b,c,d,e,f,g,h){var i;return void 0===b?(i=moment(a),a=void 0):i=moment(),h&&i.utc(),i.year(a),i.month(b),i.date(c),void 0!==b&&(i.hour(d||0),i.minute(e||0),i.second(f||0),i.milliseconds(g||0)),i.isDateTime=!0,i.local(),i},Sao.DateTime.combine=function(a,b){var c=a.clone();return c.set({hour:b.hour(),minute:b.minute(),second:b.second(),millisecond:b.millisecond()}),c.isDateTime=!0,c},Sao.DateTime.min=moment(new Date(-864e13)).local(),Sao.DateTime.min.isDateTime=!0,Sao.DateTime.max=moment(new Date(864e13)).local(),Sao.DateTime.max.isDateTime=!0,Sao.Time=function(a,b,c,d){var e=moment({hour:a,minute:b,second:c,millisecond:d||0});return e.isTime=!0,e},Sao.TimeDelta=function(a,b,c,d,e,f){var g=moment.duration({days:a,seconds:b,milliseconds:c,minutes:d,hours:e,weeks:f});return g.isTimeDelta=!0,g},Sao.config={},Sao.config.limit=1e3,Sao.config.display_size=20,Sao.config.roundup={},Sao.config.roundup.url="http://bugs.tryton.org/roundup/",Sao.config.title="Tryton",Sao.i18n=i18n(),Sao.i18n.setlang=function(a){return a||(a=(navigator.language||navigator.browserLanguage||navigator.userLanguage||"en").replace("-","_")),Sao.i18n.setLocale(a),moment.locale(a.slice(0,2)),jQuery.getJSON("locale/"+a+".json",function(b){b[""].language||(b[""].language=a),b[""]["plural-forms"]||(b[""]["plural-forms"]="nplurals=2; plural=(n!=1);");for(var c in b)""!==c&&(b[c]=2==b[c].length?b[c][1]:b[c].slice(1));Sao.i18n.loadJSON(b)})},Sao.i18n.getlang=function(){return Sao.i18n.getLocale()},Sao.i18n.setlang(),Sao.get_preferences=function(){var a=Sao.Session.current_session;return a.reload_context().then(function(){return Sao.rpc({method:"model.res.user.get_preferences",params:[!1,{}]},a).then(function(a){var b=[];return b.push(Sao.common.MODELACCESS.load_models()),b.push(Sao.common.ICONFACTORY.load_icons()),b.push(Sao.common.MODELHISTORY.load_history()),b.push(Sao.common.VIEW_SEARCH.load_searches()),jQuery.when.apply(jQuery,b).then(function(){(a.actions||[]).forEach(function(a){Sao.Action.execute(a,{},null,{})});var b=Sao.config.title;jQuery.isEmptyObject(a.status_bar)||(b+=" - "+a.status_bar),document.title=b;var c=a.language!=Sao.i18n.getLocale(),d=jQuery.Deferred();return Sao.i18n.setlang(a.language).always(function(){c&&Sao.user_menu(a),d.resolve(a)}),d})})})},Sao.login=function(){Sao.Session.get_credentials().then(function(a){return Sao.Session.current_session=a,a.reload_context()}).then(Sao.get_preferences).then(function(a){Sao.menu(a),Sao.user_menu(a)})},Sao.logout=function(){var a=Sao.Session.current_session;Sao.Tab.tabs.close(!0).done(function(){jQuery("#user-preferences").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#menu").children().remove(),document.title=Sao.config.title,a.do_logout().always(Sao.login)})},Sao.preferences=function(){Sao.Tab.tabs.close(!0).done(function(){jQuery("#user-preferences").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#menu").children().remove(),new Sao.Window.Preferences(function(){Sao.get_preferences().then(function(a){Sao.menu(a),Sao.user_menu(a)})})})},Sao.favorites_menu=function(){var a=function(){e&&e.remove()};if(jQuery(window).click(function(){a()}),0!==jQuery("#user-favorites").children(".dropdown-menu").length)a();else{var b=Sao.main_menu_screen.model_name+".favorite",c=Sao.Session.current_session,d={method:"model."+b+".get"},e=jQuery("<ul/>",{"class":"dropdown-menu","aria-expanded":"false"});jQuery("#user-favorites").append(e),Sao.rpc(d,c).then(function(b){b.forEach(function(b){var c=jQuery("<a/>",{href:"#"}),d=b[0],f=jQuery("<li/>",{role:"presentation"}),g=jQuery("<img/>",{"class":"favorite-icon"});c.append(g),f.append(c),g.attr("src",Sao.common.ICONFACTORY.get_icon_url(b[2])),c.append(b[1]),c.click(function(){a(),Sao.Action.exec_keyword("tree_open",{model:Sao.main_menu_screen.model_name,id:d,ids:[d]})}),e.append(f)}),e.append(jQuery("<li/>",{"class":"divider"})),jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{href:"#"}).click(function(){a(),Sao.Tab.create({model:Sao.main_menu_screen.model_name+".favorite",mode:["tree","form"],name:Sao.i18n.gettext("Manage favorites")})}).text(Sao.i18n.gettext("Manage favorites"))).appendTo(e)})}},Sao.user_menu=function(a){jQuery("#user-preferences").children().remove(),jQuery("#user-favorites").children().remove(),jQuery("#user-logout").children().remove(),jQuery("#user-preferences").append(jQuery("<a/>",{href:"#"}).click(Sao.preferences).append(a.status_bar)),jQuery("#user-logout").append(jQuery("<a/>",{href:"#"}).click(Sao.logout).append(Sao.i18n.gettext("Logout"))),jQuery("#user-favorites").append(jQuery("<a/>",{href:"#","data-toggle":"dropdown"}).click(Sao.favorites_menu).append(Sao.i18n.gettext("Favorites")))},Sao.menu=function(a){var b=new Sao.PYSON.Decoder,d=b.decode(a.pyson_menu),e=!1;jQuery.isEmptyObject(d.views)?d.view_id&&(e=[d.view_id[0]]):e=d.views.map(function(a){return a[0]}),b=new Sao.PYSON.Decoder(Sao.Session.current_session.context);var f=b.decode(d.pyson_context||"{}"),g=b.decode(d.pyson_domain),h=new Sao.Tab.Form(d.res_model,{mode:["tree"],view_ids:e,domain:g,context:f,selection_mode:Sao.common.SELECTION_NONE,limit:null});Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(h),1),h.view_prm.done(function(){Sao.main_menu_screen=h.screen;var a=h.screen.current_view;a.table.find("thead").hide(),jQuery("#menu").children().remove();var b=new Sao.GlobalSearch;jQuery("#menu").append(b.el),jQuery("#menu").append(h.screen.screen_container.content_box.detach()),h.screen.views[0].columns.push(new c(h.screen.model.fields.favorite))})},Sao.main_menu_screen=null;var c=Sao.class_(Object,{init:function(a){this.field=a,this.header=jQuery("<th/>"),this.attributes=jQuery.extend({},this.field.description),this.attributes.name=this.field.name},get_cell:function(){var a=jQuery("<span/>",{tabindex:0});return a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.field.name).done(function(){if(null!==a._values.favorite){var c="glyphicon glyphicon-star";a._values.favorite||(c+="-empty"),b.addClass(c),b.click({record:a,button:b},this.favorite_click)}}.bind(this)),b},favorite_click:function(a){a.stopImmediatePropagation();var b,c=a.data.button;c.hasClass("glyphicon-star-empty")?(c.removeClass("glyphicon-star-empty"),c.addClass("glyphicon-star"),b="set"):(c.removeClass("glyphicon-star"),c.addClass("glyphicon-star-empty"),b="unset");var d=Sao.main_menu_screen.model_name+".favorite",e=Sao.Session.current_session,f={method:"model."+d+"."+b,params:[a.data.record.id,e.context]};Sao.rpc(f,e)}});Sao.Dialog=Sao.class_(Object,{init:function(a,b,c){c=c||"sm",this.modal=jQuery("<div/>",{"class":b+" modal fade",role:"dialog","data-backdrop":"static"}),this.content=jQuery("<form/>",{"class":"modal-content"}).appendTo(jQuery("<div/>",{"class":"modal-dialog modal-"+c}).appendTo(this.modal)),this.header=jQuery("<div/>",{"class":"modal-header"}).appendTo(this.content),a&&this.add_title(a),this.body=jQuery("<div/>",{"class":"modal-body"}).appendTo(this.content),this.footer=jQuery("<div/>",{"class":"modal-footer"}).appendTo(this.content)},add_title:function(a){this.header.append(jQuery("<h4/>",{"class":"modal-title"}).append(a))}}),Sao.GlobalSearch=Sao.class_(Object,{init:function(){this.el=jQuery("<div/>",{"class":"global-search-container"}),this.search_entry=jQuery("<input>",{"class":"form-control",placeholder:Sao.i18n.gettext("Search...")}),this.el.append(this.search_entry);new Sao.common.InputCompletion(this.search_entry,this.update.bind(this),this.match_selected.bind(this),this.format.bind(this))},format:function(a){var b=jQuery("<div/>"),c=jQuery("<img/>",{"class":"global-search-icon"}).appendTo(b);return Sao.common.ICONFACTORY.register_icon(a.icon).then(function(a){c.attr("src",a)}),jQuery("<span/>",{"class":"global-search-text"}).text(a.record_name).appendTo(b),b},update:function(a){var b=new Sao.Model("ir.model");return b.execute("global_search",[a,Sao.config.limit,Sao.main_menu_screen.model_name],Sao.main_menu_screen.context).then(function(a){for(var b=[],c=0,d=a.length;d>c;c++)b.push({model:a[c][1],model_name:a[c][2],record_id:a[c][3],record_name:a[c][4],icon:a[c][5]});return b}.bind(this))},match_selected:function(a){if(a.model==Sao.main_menu_screen.model_name)Sao.Action.exec_keyword("tree_open",{model:a.model,id:a.record_id,ids:[a.record_id]},Sao.main_menu_screen.context);else{var b={model:a.model,res_id:a.record_id,mode:["form","tree"],name:a.model_name};Sao.Tab.create(b)}this.search_entry.val("")}}),jQuery(document).on("show.bs.modal",".modal",function(a){jQuery(this).appendTo(jQuery("body"))}).on("shown.bs.modal",".modal.in",function(b){a()}).on("hidden.bs.modal",".modal",function(b){a()})}(),function(){"use strict";Sao.rpc=function(a,b){var c=jQuery.Deferred();b||(b=new Sao.Session);var d=jQuery.extend([],a.params);d.push(jQuery.extend({},b.context,d.pop()));var e=Sao.common.processing.show(),f=jQuery.ajax({headers:{Authorization:"Session "+b.get_auth()},contentType:"application/json",data:JSON.stringify(Sao.rpc.prepareObject({id:Sao.rpc.id++,method:a.method,params:d})),dataType:"json",url:"/"+(b.database||"")+"/",type:"post",complete:[function(){Sao.common.processing.hide(e)}]}),g=function(d){if(null===d)Sao.common.warning.run("",Sao.i18n.gettext("Unable to reach the server")),c.reject();else if(d.error){var e,f,g;if("UserWarning"==d.error[0])return e=d.error[1][0],f=d.error[1][1],g=d.error[1][2],void Sao.common.userwarning.run(f,g).done(function(d){return~["always","ok"].indexOf(d)?void Sao.rpc({method:"model.res.user.warning.create",params:[[{user:b.user_id,name:e,always:"always"==d}],{}]},b).done(function(){Sao.rpc(a,b).then(c.resolve,c.reject)}):void c.reject()});if("UserError"==d.error[0])return f=d.error[1][0],g=d.error[1][1],void Sao.common.warning.run(g,f).always(c.reject);if("ConcurrencyException"==d.error[0]){if(a.method.startsWith("model.")&&(a.method.endsWith(".write")||a.method.endsWith(".delete"))){var h=a.method.split(".").slice(1,-1).join(".");return void Sao.common.concurrency.run(h,a.params[0][0],a.params.slice(-1)[0]).then(function(){delete a.params.slice(-1)[0]._timestamp,Sao.rpc(a,b).then(c.resolve,c.reject)},c.reject)}return void Sao.common.message.run("Concurrency Exception","glyphicon-alert").always(c.reject)}Sao.common.error.run(d.error[0],d.error[1]),c.reject()}else c.resolve(d.result)},h=function(d,e,f){return 403==d.status?void Sao.Session.renew(b).then(function(){Sao.rpc(a,b).then(c.resolve,c.reject)},c.reject):(Sao.common.error.run(e,f),void c.reject())};return f.success(g),f.error(h),c.promise()},Sao.rpc.id=0,Sao.rpc.convertJSONObject=function(a,b,c){if(a instanceof Array)for(var d=0,e=a.length;e>d;d++)Sao.rpc.convertJSONObject(a[d],d,a);else if("string"!=typeof a&&"number"!=typeof a&&null!==a)if(a&&a.__class__){switch(a.__class__){case"datetime":a=Sao.DateTime(a.year,a.month-1,a.day,a.hour,a.minute,a.second,a.microsecond/1e3,!0);break;case"date":a=Sao.Date(a.year,a.month-1,a.day);break;case"time":a=Sao.Time(a.hour,a.minute,a.second,a.microsecond/1e3);break;case"timedelta":a=Sao.TimeDelta(null,a.seconds);break;case"bytes":for(var f=atob(a.base64.replace(/\s/g,"")),g=new ArrayBuffer(f.length),h=new Uint8Array(g),i=0;i<f.length;i++)h[i]=f.charCodeAt(i);a=h;break;case"Decimal":a=new Sao.Decimal(a.decimal)}c&&(c[b]=a)}else for(var j in a)Sao.rpc.convertJSONObject(a[j],j,a);return c||a},Sao.rpc.prepareObject=function(a,b,c){if(a instanceof Array){a=jQuery.extend([],a);for(var d=0,e=a.length;e>d;d++)Sao.rpc.prepareObject(a[d],d,a)}else if("string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a&&null!==a&&void 0!==a)if(a.isDate)a={__class__:"date",year:a.year(),month:a.month()+1,day:a.date()};else if(a.isDateTime)a=a.clone(),a={__class__:"datetime",year:a.utc().year(),month:a.utc().month()+1,day:a.utc().date(),hour:a.utc().hour(),minute:a.utc().minute(),second:a.utc().second(),microsecond:1e3*a.utc().millisecond()};else if(a.isTime)a={__class__:"time",hour:a.hour(),minute:a.minute(),second:a.second(),microsecond:1e3*a.millisecond()};else if(a.isTimeDelta)a={__class__:"timedelta",seconds:a.asSeconds()};else if(a instanceof Sao.Decimal)a={__class__:"Decimal",decimal:a.toString()};else if(a instanceof Uint8Array){for(var f=[],g=65535,h=0;h*g<a.length;h++)f.push(String.fromCharCode.apply(null,a.subarray(h*g,(h+1)*g)));a={__class__:"bytes",base64:btoa(f.join(""))}}else{a=jQuery.extend({},a);for(var i in a)Sao.rpc.prepareObject(a[i],i,a)}return c&&(c[b]=a),c||a},jQuery.ajaxSetup({converters:{"text json":function(a){return Sao.rpc.convertJSONObject(jQuery.parseJSON(a))}}})}(),function(){"use strict";Sao.PYSON={},Sao.PYSON.eval={},Sao.PYSON.PYSON=Sao.class_(Object,{init:function(){},pyson:function(){throw"NotImplementedError"},types:function(){throw"NotImplementedError"},toString:function(){var a=this.pyson().__class__,b=this.__string_params__().map(function(a){return a instanceof Sao.PYSON.PYSON?a.toString():JSON.stringify(a)});return a+"("+b.join(", ")+")"},__string_params__:function(){throw"NotImplementedError"}}),Sao.PYSON.PYSON.eval_=function(a,b){throw"NotImplementedError"},Sao.PYSON.PYSON.init_from_object=function(a){throw"NotImplementedError"},Sao.PYSON.Encoder=Sao.class_(Object,{prepare:function(a,b,c){if(null!==a&&void 0!==a)if(a instanceof Array){a=jQuery.extend([],a);for(var d=0,e=a.length;e>d;d++)this.prepare(a[d],d,a)}else a._isAMomentObject&&(a=a.isDate?new Sao.PYSON.Date(a.year(),a.month()+1,a.date()).pyson():new Sao.PYSON.DateTime(a.year(),a.month()+1,a.date(),a.hours(),a.minutes(),a.seconds(),1e3*a.milliseconds()).pyson());return c&&(c[b]=a),c||a},encode:function(a){return a=this.prepare(a),JSON.stringify(a,function(a,b){return b instanceof Sao.PYSON.PYSON?b.pyson():null===b||void 0===b?null:b})}}),Sao.PYSON.Decoder=Sao.class_(Object,{init:function(a,b){this.__context=a||{},this.noeval=b||!1},decode:function(a){var b=function(a,b){if("object"==typeof b&&null!==b){var c=Sao.PYSON[b.__class__];if(c){if(this.noeval){var d=jQuery.extend({},b);return delete d.__class__,Sao.PYSON[b.__class__].init_from_object(d)}return c.eval_(b,this.__context)}}return b};return JSON.parse(a,b.bind(this))}}),Sao.PYSON.eval.Eval=function(a,b){return new Sao.PYSON.Eval(a,b)},Sao.PYSON.Eval=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){void 0===b&&(b=""),Sao.PYSON.Eval._super.init.call(this),this._value=a,this._default=b},pyson:function(){return{__class__:"Eval",v:this._value,d:this._default}},types:function(){return this._default instanceof Sao.PYSON.PYSON?this._default.types():[typeof this._default]},__string_params__:function(){return[this._value,this._default]}}),Sao.PYSON.Eval.eval_=function(a,b){return a.v in b?b[a.v]:a.d},Sao.PYSON.Eval.init_from_object=function(a){return new Sao.PYSON.Eval(a.v,a.d)},Sao.PYSON.eval.Not=function(a){return new Sao.PYSON.Not(a)},Sao.PYSON.Not=Sao.class_(Sao.PYSON.PYSON,{init:function(a){if(Sao.PYSON.Not._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["boolean","object"]).length||jQuery(["boolean"]).not(a.types()).length)throw"value must be boolean"}else if("boolean"!=typeof a)throw"value must be boolean";this._value=a},pyson:function(){return{__class__:"Not",v:this._value}},types:function(){return["boolean"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Not.eval_=function(a,b){return!a.v},Sao.PYSON.Not.init_from_object=function(a){return new Sao.PYSON.Not(a.v)},Sao.PYSON.eval.Bool=function(a){return new Sao.PYSON.Bool(a)},Sao.PYSON.Bool=Sao.class_(Sao.PYSON.PYSON,{init:function(a){Sao.PYSON.Bool._super.init.call(this),this._value=a},pyson:function(){return{__class__:"Bool",v:this._value}},types:function(){return["boolean"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Bool.eval_=function(a,b){return moment.isMoment(a.v)&&a.v.isTime?Boolean(a.v.hour()||a.v.minute()||a.v.second()||a.v.millisecond()):moment.isDuration(a.v)?Boolean(a.v.valueOf()):a.v instanceof Object?!jQuery.isEmptyObject(a.v):Boolean(a.v)},Sao.PYSON.Bool.init_from_object=function(a){return new Sao.PYSON.Bool(a.v)},Sao.PYSON.eval.And=function(a){return new Sao.PYSON.And(a)},Sao.PYSON.And=Sao.class_(Sao.PYSON.PYSON,{init:function(a){void 0===a&&(a=[]),Sao.PYSON.And._super.init.call(this);for(var b=0,c=a.length;c>b;b++){var d=a[b];if(d instanceof Sao.PYSON.PYSON){if(jQuery(d.types()).not(["boolean"]).length||jQuery(["boolean"]).not(d.types()).length)throw"statement must be boolean"}else if("boolean"!=typeof d)throw"statement must be boolean"}if(a.length<2)throw"must have at least 2 statements";this._statements=a},pyson:function(){return{__class__:"And",s:this._statements}},types:function(){return["boolean"]},__string_params__:function(){return this._statements}}),Sao.PYSON.And.eval_=function(a,b){for(var c=!0,d=0,e=a.s.length;e>d;d++){var f=a.s[d];c=c&&f}return c},Sao.PYSON.And.init_from_object=function(a){return new Sao.PYSON.And(a.s)},Sao.PYSON.eval.Or=function(a){return new Sao.PYSON.Or(a)},Sao.PYSON.Or=Sao.class_(Sao.PYSON.And,{pyson:function(){var a=Sao.PYSON.Or._super.pyson.call(this);return a.__class__="Or",a}}),Sao.PYSON.Or.eval_=function(a,b){for(var c=!1,d=0,e=a.s.length;e>d;d++){var f=a.s[d];c=c||f}return c},Sao.PYSON.Or.init_from_object=function(a){return new Sao.PYSON.Or(a.s)},Sao.PYSON.eval.Equal=function(a,b){return new Sao.PYSON.Equal(a,b)},Sao.PYSON.Equal=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){Sao.PYSON.Equal._super.init.call(this);var c,d;if(c=a instanceof Sao.PYSON.PYSON?a.types():[typeof a],d=b instanceof Sao.PYSON.PYSON?b.types():[typeof b],jQuery(c).not(d).length||jQuery(d).not(c).length)throw"statements must have the same type";this._statement1=a,this._statement2=b},pyson:function(){return{__class__:"Equal",s1:this._statement1,s2:this._statement2}},types:function(){return["boolean"]},__string_params__:function(){return[this._statement1,this._statement2]}}),Sao.PYSON.Equal.eval_=function(a,b){return a.s1 instanceof Array&&a.s2 instanceof Array?Sao.common.compare(a.s1,a.s2):a.s1==a.s2},Sao.PYSON.Equal.init_from_object=function(a){return new Sao.PYSON.Equal(a.s1,a.s2)},Sao.PYSON.eval.Greater=function(a,b,c){return new Sao.PYSON.Greater(a,b,c)},Sao.PYSON.Greater=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){Sao.PYSON.Greater._super.init.call(this);for(var d=[a,b],e=0;2>e;e++){var f=d[e];if(f instanceof Sao.PYSON.PYSON){if(jQuery(f).not(["number"]).length)throw"statement must be an integer or a float"}else if(!~["number","object"].indexOf(typeof f))throw"statement must be an integer or a float"}if(void 0===c&&(c=!1),c instanceof Sao.PYSON.PYSON){if(jQuery(c.types()).not(["boolean"]).length||jQuery(["boolean"]).not(c.types()).length)throw"equal must be boolean"}else if("boolean"!=typeof c)throw"equal must be boolean";this._statement1=a,this._statement2=b,this._equal=c},pyson:function(){return{__class__:"Greater",s1:this._statement1,s2:this._statement2,e:this._equal}},types:function(){return["boolean"]},__string_params__:function(){return[this._statement1,this._statement2,this._equal]}}),Sao.PYSON.Greater._convert=function(a){return a=jQuery.extend({},a),a.s1=Number(a.s1),a.s2=Number(a.s2),a},Sao.PYSON.Greater.eval_=function(a,b){return a=Sao.PYSON.Greater._convert(a),a.e?a.s1>=a.s2:a.s1>a.s2},Sao.PYSON.Greater.init_from_object=function(a){return new Sao.PYSON.Greater(a.s1,a.s2,a.e)},Sao.PYSON.eval.Less=function(a,b,c){return new Sao.PYSON.Less(a,b,c)},Sao.PYSON.Less=Sao.class_(Sao.PYSON.Greater,{pyson:function(){var a=Sao.PYSON.Less._super.pyson.call(this);return a.__class__="Less",a}}),Sao.PYSON.Less._convert=Sao.PYSON.Greater._convert,Sao.PYSON.Less.eval_=function(a,b){return a=Sao.PYSON.Less._convert(a),a.e?a.s1<=a.s2:a.s1<a.s2},Sao.PYSON.Less.init_from_object=function(a){return new Sao.PYSON.Less(a.s1,a.s2,a.e)},Sao.PYSON.eval.If=function(a,b,c){return new Sao.PYSON.If(a,b,c)},Sao.PYSON.If=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){if(Sao.PYSON.If._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["boolean"]).length||jQuery(["boolean"]).not(a.types()).length)throw"condition must be boolean"}else if("boolean"!=typeof a)throw"condition must be boolean";var d,e;if(d=b instanceof Sao.PYSON.PYSON?b.types():[typeof b],void 0===c&&(c=null),e=c instanceof Sao.PYSON.PYSON?c.types():[typeof c],jQuery(d).not(e).length||jQuery(e).not(d).length)throw"then and else statements must be the same type";this._condition=a,this._then_statement=b,this._else_statement=c},pyson:function(){return{__class__:"If",c:this._condition,t:this._then_statement,e:this._else_statement}},types:function(){return this._then_statement instanceof Sao.PYSON.PYSON?this._then_statement.types():[typeof this._then_statement]},__string_params__:function(){return[this._condition,this._then_statement,this._else_statement]}}),Sao.PYSON.If.eval_=function(a,b){return a.c?a.t:a.e},Sao.PYSON.If.init_from_object=function(a){return new Sao.PYSON.If(a.c,a.t,a.e)},Sao.PYSON.eval.Get=function(a,b,c){return new Sao.PYSON.Get(a,b,c)},Sao.PYSON.Get=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c){if(Sao.PYSON.Get._super.init.call(this),void 0===c&&(c=null),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["object"]).length||jQuery(["object"]).not(a.types()).length)throw"obj must be a dict"}else if(!(a instanceof Object))throw"obj must be a dict";if(this._obj=a,b instanceof Sao.PYSON.PYSON){if(jQuery(b.types()).not(["string"]).length||jQuery(["string"]).not(b.types()).length)throw"key must be a string"}else if("string"!=typeof b)throw"key must be a string";this._key=b,this._default=c},pyson:function(){return{__class__:"Get",v:this._obj,k:this._key,d:this._default}},types:function(){return this._default instanceof Sao.PYSON.PYSON?this._default.types():[typeof this._default]},__string_params__:function(){return[this._obj,this._key,this._default]}}),Sao.PYSON.Get.eval_=function(a,b){return a.k in a.v?a.v[a.k]:a.d},Sao.PYSON.Get.init_from_object=function(a){return new Sao.PYSON.Get(a.v,a.k,a.d)},Sao.PYSON.eval.In=function(a,b){return new Sao.PYSON.In(a,b)},Sao.PYSON.In=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b){if(Sao.PYSON.In._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["string","number"]).length)throw"key must be a string or a number"}else if(!~["string","number"].indexOf(typeof a))throw"key must be a string or a number";if(b instanceof Sao.PYSON.PYSON){if(jQuery(b.types()).not(["object"]).length||jQuery(["object"]).not(b.types()).length)throw"obj must be a dict or a list"}else if(!(b instanceof Object))throw"obj must be a dict or a list";this._key=a,this._obj=b},pyson:function(){return{__class__:"In",k:this._key,v:this._obj}},types:function(){return["boolean"]},__string_params__:function(){return[this._key,this._obj]}}),Sao.PYSON.In.eval_=function(a,b){return a.v.indexOf?Boolean(~a.v.indexOf(a.k)):!!a.v[a.k]},Sao.PYSON.In.init_from_object=function(a){return new Sao.PYSON.In(a.k,a.v)},Sao.PYSON.eval.Date=function(a,b,c,d,e,f){return new Sao.PYSON.Date(a,b,c,d,e,f)},Sao.PYSON.Date=Sao.class_(Sao.PYSON.PYSON,{init:function(a,b,c,d,e,f){Sao.PYSON.Date._super.init.call(this),void 0===a&&(a=null),void 0===b&&(b=null),void 0===c&&(c=null),void 0===d&&(d=0),void 0===e&&(e=0),void 0===f&&(f=0),this._test(a,"year"),this._test(b,"month"),this._test(c,"day"),this._test(d,"delta_years"),this._test(f,"delta_days"),this._test(e,"delta_months"),this._year=a,this._month=b,this._day=c,this._delta_years=d,this._delta_months=e,this._delta_days=f},pyson:function(){return{__class__:"Date",y:this._year,M:this._month,d:this._day,dy:this._delta_years,dM:this._delta_months,dd:this._delta_days}},types:function(){return["object"]},_test:function(a,b){if(a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["number","object"]).length)throw b+" must be an integer or None"}else if("number"!=typeof a&&null!==a)throw b+" must be an integer or None"},__string_params__:function(){return[this._year,this._month,this._day,this._delta_years,this._delta_months,this._delta_days]}}),Sao.PYSON.Date.eval_=function(a,b){var c=Sao.Date(a.y,a.M&&a.M-1,a.d);return a.dy&&c.add(a.dy,"y"),a.dM&&c.add(a.dM,"M"),a.dd&&c.add(a.dd,"d"),c},Sao.PYSON.Date.init_from_object=function(a){return new Sao.PYSON.Date(a.y,a.M,a.d,a.dy,a.dM,a.dd)},Sao.PYSON.eval.DateTime=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){return new Sao.PYSON.DateTime(a,b,c,d,e,f,g,h,i,j,k,l,m,n)},Sao.PYSON.DateTime=Sao.class_(Sao.PYSON.Date,{init:function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){Sao.PYSON.DateTime._super.init.call(this,a,b,c,h,i,j),void 0===d&&(d=null),void 0===e&&(e=null),void 0===f&&(f=null),void 0===g&&(g=null),void 0===k&&(k=0),void 0===l&&(l=0),void 0===m&&(m=0),void 0===n&&(n=0),this._test(d,"hour"),this._test(e,"minute"),this._test(f,"second"),this._test(g,"microsecond"),this._test(k,"delta_hours"),this._test(l,"delta_minutes"),this._test(m,"delta_seconds"),this._test(n,"delta_microseconds"),this._hour=d,this._minute=e,this._second=f,this._microsecond=g,this._delta_hours=k,this._delta_minutes=l,this._delta_seconds=m,this._delta_microseconds=n},pyson:function(){var a=Sao.PYSON.DateTime._super.pyson.call(this);return a.__class__="DateTime",a.h=this._hour,a.m=this._minute,a.s=this._second,a.ms=this._microsecond,a.dh=this._delta_hours,a.dm=this._delta_minutes,a.ds=this._delta_seconds,a.dms=this._delta_microseconds,a},__string_params__:function(){var a=Sao.PYSON.DateTime._super.__string_params__.call(this);return[a[0],a[1],a[2],this._hour,this._minute,this._second,this._microsecond,a[3],a[4],a[5],this._delta_hours,this._delta_minutes,this._delta_seconds,this._delta_microseconds]}}),Sao.PYSON.DateTime.eval_=function(a,b){var c=Sao.DateTime(a.y,a.M&&a.M-1,a.d,a.h,a.m,a.s,a.ms&&a.ms/1e3);return a.dy&&c.add(a.dy,"y"),a.dM&&c.add(a.dM,"M"),a.dd&&c.add(a.dd,"d"),a.dh&&c.add(a.dh,"h"),a.dm&&c.add(a.dm,"m"),a.ds&&c.add(a.ds,"s"),a.dms&&c.add(a.dms/1e3,"ms"),c},Sao.PYSON.DateTime.init_from_object=function(a){return new Sao.PYSON.DateTime(a.y,a.M,a.d,a.h,a.m,a.s,a.ms,a.dy,a.dM,a.dd,a.dh,a.dm,a.ds,a.dms)},Sao.PYSON.eval.Len=function(a){return new Sao.PYSON.Len(a)},Sao.PYSON.Len=Sao.class_(Sao.PYSON.PYSON,{init:function(a){if(Sao.PYSON.Len._super.init.call(this),a instanceof Sao.PYSON.PYSON){if(jQuery(a.types()).not(["object","string"]).length||jQuery(["object","string"]).not(a.types()).length)throw"value must be an object or a string"}else if("object"!=typeof a&&"string"!=typeof a)throw"value must be an object or a string";this._value=a},pyson:function(){return{__class__:"Len",v:this._value}},types:function(){return["integer"]},__string_params__:function(){return[this._value]}}),Sao.PYSON.Len.eval_=function(a,b){return"object"==typeof a.v?Object.keys(a.v).length:a.v.length},Sao.PYSON.Len.init_from_object=function(a){return new Sao.PYSON.Len(a.v)}}(),function(){"use strict";Sao.Session=Sao.class_(Object,{init:function(a,b){this.user_id=null,this.session=null,this.prm=jQuery.when(),this.database=a,this.login=b,this.context={},Sao.Session.current_session||(Sao.Session.current_session=this)},get_auth:function(){return btoa(this.login+":"+this.user_id+":"+this.session)},do_login:function(a,b){var c=jQuery.Deferred(),d=function(b){return{method:"common.db.login",params:[a,b,Sao.i18n.getlang()]}};return new Sao.Login(d,this).run().then(function(a){this.user_id=a[0],this.session=a[1],c.resolve()}.bind(this),function(){this.user_id=null,this.session=null,c.reject()}),c.promise()},do_logout:function(){if(!this.user_id||!this.session)return jQuery.when();var a={id:0,method:"common.db.logout",params:[]},b=jQuery.ajax({headers:{Authorization:"Session "+this.get_auth()},contentType:"application/json",data:JSON.stringify(a),dataType:"json",url:"/"+this.database+"/",type:"post"});return this.database=null,this.login=null,this.user_id=null,this.session=null,Sao.Session.current_session===this&&(Sao.Session.current_session=null),b},reload_context:function(){var a={method:"model.res.user.get_preferences",params:[!0,{}]},b=jQuery.extend({},this);b.context={};var c=Sao.rpc(a,b);return c.then(function(a){this.context=a}.bind(this))}}),Sao.Session.login_dialog=function(){var a=new Sao.Dialog(Sao.i18n.gettext("Login"),"lg");return a.database_select=jQuery("<select/>",{"class":"form-control",id:"login-database"}).hide(),a.database_input=jQuery("<input/>",{"class":"form-control",id:"login-database"}).hide(),a.login_input=jQuery("<input/>",{"class":"form-control",id:"login-login",placeholder:Sao.i18n.gettext("User name")}),a.body.append(jQuery("<div/>",{"class":"form-group"}).append(jQuery("<label/>",{"class":"control-label","for":"login-database"}).append(Sao.i18n.gettext("Database"))).append(a.database_select).append(a.database_input)).append(jQuery("<div/>",{"class":"form-group"}).append(jQuery("<label/>",{"class":"control-label","for":"login-login"}).append(Sao.i18n.gettext("User name"))).append(a.login_input)),a.button=jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Login")).appendTo(a.footer),a},Sao.Session.get_credentials=function(){var a=jQuery.Deferred(),b=window.location.hash.replace(/^(#(!|))/,"")||null,c=Sao.Session.login_dialog(),d=function(){return c.modal.find("input,select").filter(":visible").filter(function(){return!jQuery(this).val()})},e=function(){var b=c.login_input.val(),e=e||c.database_select.val()||c.database_input.val();if(c.modal.find(".has-error").removeClass("has-error"),!b||!e)return void d().closest(".form-group").addClass("has-error");c.button.focus(),c.button.prop("disabled",!0),c.modal.modal("hide");var f=new Sao.Session(e,b);f.do_login(b).then(function(){a.resolve(f),c.modal.remove()},function(){c.button.prop("disabled",!1),c.modal.modal("show"),d().closest(".form-group").addClass("has-error"),d().first().focus()})};return c.modal.modal({backdrop:!1,keyboard:!1}),c.modal.find("form").unbind().submit(function(a){e(),a.preventDefault()}),jQuery.when(Sao.DB.list()).then(function(a){
+var e;a=a||[],a.length<=1?(b=a[0],e=c.database_input):(e=c.database_select,a.forEach(function(a){e.append(jQuery("<option/>",{value:a,text:a}))})),e.prop("readonly",1==a.length),e.show(),e.val(b||""),d().first().focus()}),a.promise()},Sao.Session.renew=function(a){if("pending"==a.prm.state())return a.prm;var b=jQuery.Deferred();return a.prm=b.promise(),a.login?(a.do_login(a.login).then(b.resolve,b.reject),a.prm):(b.reject(),a.prm)},Sao.Session.current_session=null,Sao.Login=Sao.class_(Object,{init:function(a,b){this.func=a,this.session=b||Sao.Session.current_session},run:function(a){void 0===a&&(a={});var b=jQuery.Deferred(),c=Sao.common.processing.show(),d=this.func(a);d.id=0;var e={contentType:"application/json",data:JSON.stringify(d),dataType:"json",url:"/"+this.session.database+"/",type:"post",complete:[function(){Sao.common.processing.hide(c)}]};this.session.user_id&&this.session.session&&(e.headers={Authorization:"Session "+this.session.get_auth()});var f=jQuery.ajax(e),g=function(c){if(null===c)Sao.common.warning.run("",Sao.i18n.gettext("Unable to reach the server.")),b.reject();else if(c.error){if(c.error[0].startsWith("403"))return this.run({}).then(b.resolve,b.reject);if(c.error[0].startsWith("404"))b.reject();else if("LoginException"!=c.error[0])Sao.common.error.run(c.error[0],c.error[1]),b.reject();else{var d=c.error[1],e=d[0],f=d[1],g=d[2];this["get_"+g](f).then(function(c){return a[e]=c,this.run(a).then(b.resolve,b.reject)}.bind(this),b.reject)}}else b.resolve(c.result)};return f.success(g.bind(this)),f.error(b.reject),b.promise()},get_char:function(a){return Sao.common.ask.run(a)},get_password:function(a){return Sao.common.ask.run(a,!1)}}),Sao.DB={},Sao.DB.list=function(){var a=Sao.common.processing.show();return jQuery.ajax({contentType:"application/json",data:JSON.stringify({id:0,method:"common.db.list",params:[]}),dataType:"json",url:"/",type:"post",complete:[function(){Sao.common.processing.hide(a)}]}).then(function(a){return a.result})}}(),function(){"use strict";Sao.Model=Sao.class_(Object,{init:function(a,b){b=b||{},this.name=a,this.session=Sao.Session.current_session,this.fields={}},add_fields:function(a){var b=[];for(var c in a)if(a.hasOwnProperty(c)&&!(c in this.fields)){var d=a[c],e=Sao.field.get(d.type);this.fields[c]=new e(d),b.push(c)}return b},execute:function(a,b,c){void 0===c&&(c={});var d={method:"model."+this.name+"."+a,params:b.concat(c)};return Sao.rpc(d,this.session)},find:function(a,b,c,d,e){b||(b=0);var f=this,g=this.execute("search",[a,b,c,d],e),h=function(a){return Sao.Group(f,e,a.map(function(a){return new Sao.Record(f,a)}))};return g.pipe(h)},delete_:function(a){if(jQuery.isEmptyObject(a))return jQuery.when();var b=a[0],c=b.group.root_group();console.assert(a.every(function(a){return a.model.name==b.model.name}),"records not from the same model"),console.assert(a.every(function(a){return a.group.root_group()==b.group.root_group()}),"records not from the same root group"),a=a.filter(function(a){return a.id>=0});var d={};d._timestamp={},a.forEach(function(a){jQuery.extend(d._timestamp,a.get_timestamp())});var e=a.map(function(a){return a.id});return c.on_write_ids(e).then(function(a){return a=a.filter(function(a){return!~e.indexOf(a)}),this.execute("delete",[e],d).then(function(){c.reload(a)})}.bind(this))},copy:function(a,b){if(jQuery.isEmptyObject(a))return jQuery.when();var c=a.map(function(a){return a.id});return this.execute("copy",[c,{}],b)}}),Sao.Group=function(a,b,c){return c.prm=jQuery.when(),c.model=a,c._context=b,c.on_write=[],c.parent=void 0,c.screens=[],c.parent_name="",c.children=[],c.child_name="",c.parent_datetime_field=void 0,c.record_removed=[],c.record_deleted=[],c.__readonly=!1,c.skip_model_access=!1,c.forEach(function(a,b,c){a.group=c}),c.get_readonly=function(){var a=Sao.common.MODELACCESS.get(this.model.name);return this.context._datetime||!a.write&&!a.create&&!this.skip_model_access?!0:this.__readonly},c.set_readonly=function(a){this.__readonly=a},c.load=function(a,b){var c,d,e=[];for(c=0,d=a.length;d>c;c++){var f=a[c],g=this.get(f);g||(g=new Sao.Record(this.model,f),g.group=this,this.push(g)),e.push(g)}var h,i=[];for(c=0,d=this.record_removed.length;d>c;c++)h=this.record_removed[c],~a.indexOf(h.id)||i.push(h);this.record_removed=i;var j=[];for(c=0,d=this.record_deleted.length;d>c;c++)h=this.record_deleted[c],~a.indexOf(h.id)||j.push(h);this.record_deleted=j,e.length&&b&&this.changed()},c.get=function(a){for(var b=0,c=this.length;c>b;b++){var d=this[b];if(d.id==a)return d}},c.new_=function(a,b,c){var d=new Sao.Record(this.model,b);return d.group=this,a&&d.default_get(c),d},c.add=function(a,b,c){void 0!==b&&-1!=b||(b=this.length),void 0===c&&(c=!0),a.group!=this&&(a.group=this),this.splice(b,0,a);for(var d in this.record_removed)d.id==a.id&&this.record_removed.splice(this.record_removed.indexOf(d),1);for(var e in this.record_deleted)e.id==a.id&&this.record_deleted.splice(this.record_deleted.indexOf(e),1);if(a._changed.id=!0,c&&(this.changed(),this.parent&&this.model.fields[this.parent_name])){var f=this.model.fields[this.parent_name];if(f instanceof Sao.field.Many2One||f instanceof Sao.field.Reference){var g=[this.parent.id,""];f instanceof Sao.field.Reference&&(g=[this.parent.model.name,g]),f.set_client(a,g)}}return a},c.remove=function(a,b,c,d){void 0===c&&(c=!0);this.indexOf(a);a.id>=0&&(b?(~this.record_deleted.indexOf(a)&&this.record_deleted.splice(this.record_deleted.indexOf(a),1),this.record_removed.push(a)):(~this.record_removed.indexOf(a)&&this.record_removed.splice(this.record_removed.indexOf(a),1),this.record_deleted.push(a))),a.group.parent&&(a.group.parent._changed.id=!0),c&&(a._changed.id=!0),(a.id<0||d)&&this._remove(a),a.group.changed(),a.group.root_group().screens.forEach(function(a){a.display()})},c._remove=function(a){var b=this.indexOf(a);this.splice(b,1)},c.unremove=function(a){this.record_removed.splice(this.record_removed.indexOf(a),1),this.record_deleted.splice(this.record_deleted.indexOf(a),1),a.group.changed(),a.group.root_group().screens.forEach(function(a){a.display()})},c.changed=function(){if(!this.parent)return jQuery.when();this.parent._changed[this.child_name]=!0;var a=jQuery.Deferred(),b=this.parent.model.fields[this.child_name].changed(this.parent);return b?b.then(function(){this.parent.validate(null,!0).done(function(){this.parent.group.changed().done(a.resolve)}.bind(this))}.bind(this)):a.resolve(),a},c.root_group=function(){for(var a=this,b=this.parent;b;)a=b.group,b=b.parent;return a},c.save=function(){var a=[];return this.forEach(function(b){a.push(b.save())}),jQuery.isEmptyObject(this.record_deleted)||(this.record_deleted.forEach(function(a){this._remove(a)}.bind(this)),a.push(this.model.delete_(this.record_deleted)),this.record_deleted.splice(0,this.record_deleted.length)),jQuery.when.apply(jQuery,a)},c.written=function(a){return"number"==typeof a&&(a=[a]),this.on_write_ids(a).then(function(b){b=b.filter(function(b){return!~a.indexOf(b)}),this.root_group().reload(b)}.bind(this))},c.reload=function(a){this.children.forEach(function(b){b.reload(a)}),a.forEach(function(a){var b=this.get(a);b&&jQuery.isEmptyObject(b._changed)&&b.cancel()}.bind(this))},c.on_write_ids=function(a){var b=[],c=[];return this.on_write.forEach(function(d){var e=this.model.execute(d,[a],this._context).then(function(a){jQuery.extend(c,a)});b.push(e)}.bind(this)),jQuery.when.apply(jQuery,b).then(function(){return c.filter(function(a,b,c){return b==c.indexOf(a)})})},c.set_parent=function(a){this.parent=a,a&&a.model.name==this.model.name&&this.parent.group.children.push(this)},c.add_fields=function(a){var b=this.model.add_fields(a);if(!jQuery.isEmptyObject(this)){var c=[];this.forEach(function(a){a.id<0&&c.push(a)}),c.length&&b.length&&this.model.execute("default_get",[b,this.context()]).then(function(a){c.forEach(function(b){b.set_default(a)})})}},c.destroy=function(){if(this.parent){var a=this.parent.group.children.indexOf(this);~a&&this.parent.group.children.splice(a,1)}this.parent=null},c.domain=function(){var a=[];if(this.screens.forEach(function(b){b.attributes.domain&&a.push(b.attributes.domain)}),this.parent&&this.child_name){var b=this.parent.model.fields[this.child_name];return[a,b.get_domain(this.parent)]}return a},c.context=function(){var a=jQuery.extend({},this._context);if(this.parent&&(jQuery.extend(a,this.parent.get_context()),this.child_name in this.parent.model.fields)){var b=this.parent.model.fields[this.child_name];jQuery.extend(a,b.get_context(this.parent))}return jQuery.extend(a,this._context),this.parent_datetime_field&&(a._datetime=this.parent.get_eval()[this.parent_datetime_field]),a},c.set_context=function(a){this._context=jQuery.extend({},a)},c.clean4inversion=function(a){if(jQuery.isEmptyObject(a))return[];var b=new Sao.common.DomainInversion,c=a[0],d=a.slice(1);if(~["AND","OR"].indexOf(c));else if(b.is_leaf(c)){var e=c[0];e in this.model.fields&&this.model.fields[e].description.readonly&&(c=[])}else c=this.clean4inversion(c);return[c].concat(this.clean4inversion(d))},c.domain4inversion=function(){var a=this.domain();return this.__domain4inversion&&Sao.common.compare(this.__domain4inversion[0],a)||(this.__domain4inversion=[a,this.clean4inversion(a)]),this.__domain4inversion[1]},c.get_by_path=function(a){a=jQuery.extend([],a);var b=null,c=this,d=function(){if(jQuery.isEmptyObject(a))return b;var e=a[0][0],f=a[0][1];return a.splice(0,1),b=c.get(f),b?e?b.load(e).then(function(){return c=b._values[e],c?d():null}):d():null};return jQuery.when().then(d)},c.sort=function(a){var b={};this.forEach(function(a){b[a.id]=a}),a.forEach(function(a,c){this[c]=b[a.id]}.bind(this))},c},Sao.Record=Sao.class_(Object,{id_counter:-1,init:function(a,b){this.model=a,this.group=Sao.Group(a,{},[]),this.id=b||Sao.Record.prototype.id_counter--,this._values={},this._changed={},this._loaded={},this.fields={},this._timestamp=null,this.attachment_count=-1,this.unread_note=-1,this.button_clicks={},this.state_attrs={},this.autocompletion={},this.exception=!1},has_changed:function(){return!jQuery.isEmptyObject(this._changed)},save:function(a){void 0===a&&(a=!1);var b=this.get_context(),c=jQuery.when(),d=this.get();if(this.id<0||!jQuery.isEmptyObject(d)){if(this.id<0){c=this.model.execute("create",[[d]],b);var e=function(a){this.id=a[0]};c.done(e.bind(this))}else jQuery.isEmptyObject(d)||(b._timestamp=this.get_timestamp(),c=this.model.execute("write",[[this.id],d],b));c=c.done(function(){return this.cancel(),a?this.reload():void 0}.bind(this)),this.group&&(c=c.done(function(){return this.group.written(this.id)}.bind(this)))}return this.group.parent&&(delete this.group.parent._changed[this.group.child_name],c=c.done(function(){return this.group.parent.save(a)}.bind(this))),c},reload:function(a){if(this.id<0)return jQuery.when();if(a){var b=a.map(function(a){return this.load(a)}.bind(this));return jQuery.when.apply(jQuery,b)}return this.load("*")},load:function(a){var b,c;if(this.id<0||a in this._loaded)return jQuery.when();if("pending"==this.group.prm.state())return c=jQuery.Deferred(),this.group.prm.then(function(){this.load(a).then(c.resolve,c.reject)}.bind(this)),c;var d={};d[this.id]=this;var e;if("*"==a){e="eager";for(b in this.model.fields)if(this.model.fields.hasOwnProperty(b)){var f=this.model.fields[b].description.loading||"eager";if("eager"!=f){e="lazy";break}}}else e=this.model.fields[a].description.loading||"eager";var g=[];if("eager"==e)for(b in this.model.fields)this.model.fields.hasOwnProperty(b)&&"eager"==(this.model.fields[b].description.loading||"eager")&&g.push(b);else g=Object.keys(this.model.fields);g=g.filter(function(a,b,c){return!(a in this._loaded)}.bind(this));var h=g.slice(),i=["many2one","one2one","reference"];for(var j in g){b=g[j];var k=this.model.fields[b].description;~i.indexOf(k.type)&&h.push(b+".rec_name")}~g.indexOf("rec_name")||h.push("rec_name"),h.push("_timestamp");var l=jQuery.extend({},this.get_context());if("eager"==e){var m,n,o=parseInt(Sao.config.limit/h.length,10),p=function(b){return!(a in b._loaded)&&b.id>=0},q=function(a){return p(a)&&void 0===d[a.id]&&(a.group===this.group||JSON.stringify(a.get_context())===JSON.stringify(l))}.bind(this);this.group.parent&&this.group.parent.model.name==this.model.name?(m=[],m=m.concat.apply(m,this.group.parent.group.children),n=q):(m=this.group,n=p);var r=m.indexOf(this);if(~r)for(var s=m.length,t=1;Object.keys(d).length<o&&(r-t>=0||s>r+t)&&2*o>t;){var u;r-t>=0&&(u=m[r-t],n(u)&&(d[u.id]=u)),s>r+t&&(u=m[r+t],n(u)&&(d[u.id]=u)),t++}}for(b in this.model.fields)this.model.fields.hasOwnProperty(b)&&"binary"==this.model.fields[b].description.type&&~h.indexOf(b,h)&&(l[this.model.name+"."+b]="size");c=this.model.execute("read",[Object.keys(d).map(function(a){return parseInt(a,10)}),h],l);var v=function(a,b){void 0===b&&(b=!1);var c={},e=[];a.forEach(function(a,b,d){c[a.id]=a});for(var f in d)if(d.hasOwnProperty(f)){var g=d[f];g.exception||(g.exception=b);var h=c[f];if(g&&h){for(var i in this._changed)this._changed.hasOwnProperty(i)&&delete h[i];e.push(g.set(h))}}return jQuery.when.apply(jQuery,e)}.bind(this),w=function(){var a,b=[];for(var c in d){a={id:c};for(var e in h)a[h[e]]=null;b.push(a)}return v(b,!0)};return this.group.prm=c.then(v,w),this.group.prm},set:function(a,b){void 0===b&&(b=!0);var c,d,e={},f=[];for(c in a)if(a.hasOwnProperty(c))if(d=a[c],"_timestamp"!=c)if(c in this.model.fields){if(this.model.fields[c]instanceof Sao.field.One2Many&&(e[c]=d),this.model.fields[c]instanceof Sao.field.Many2One||this.model.fields[c]instanceof Sao.field.Reference){var g=c+".rec_name";a.hasOwnProperty(g)?this._values[g]=a[g]:this._values.hasOwnProperty(g)&&delete this._values[g]}this.model.fields[c].set(this,d),this._loaded[c]=!0,f.push(c)}else"rec_name"==c&&(this._values[c]=d);else this._timestamp||(this._timestamp=d);for(c in e)d=e[c],this.model.fields[c].set(this,d),this._loaded[c]=!0;return b?this.validate(f,!0):jQuery.when()},get:function(){var a={};for(var b in this.model.fields)if(this.model.fields.hasOwnProperty(b)){var c=this.model.fields[b];(!c.description.readonly||c instanceof Sao.field.One2Many)&&(void 0===this._changed[b]&&this.id>=0||(a[b]=c.get(this)))}return a},invalid_fields:function(){var a={};for(var b in this.model.fields){var c=this.model.fields[b],d=c.get_state_attrs(this).invalid;d&&(a[b]=d)}return a},get_context:function(){return this.group.context()},field_get:function(a){return this.model.fields[a].get(this)},field_set:function(a,b){this.model.fields[a].set(this,b)},field_get_client:function(a){return this.model.fields[a].get_client(this)},field_set_client:function(a,b,c){this.model.fields[a].set_client(this,b,c)},default_get:function(a){if(!jQuery.isEmptyObject(this.model.fields)){var b=this.get_context();void 0===b.default_rec_name&&(b.default_rec_name=a);var c=this.model.execute("default_get",[Object.keys(this.model.fields)],b);return c.then(function(a){if(this.group.parent&&this.group.parent_name in this.group.model.fields){var b=this.group.model.fields[this.group.parent_name];b instanceof Sao.field.Reference?a[this.group.parent_name]=[this.group.parent.model.name,this.group.parent.id]:b.description.relation==this.group.parent.model.name&&(a[this.group.parent_name]=this.group.parent.id)}return this.set_default(a)}.bind(this))}return jQuery.when()},set_default:function(a,b){void 0===b&&(b=!0);var c=[],d=[];for(var e in a)if(a.hasOwnProperty(e)){var f=a[e];if(e in this.model.fields){if(this.model.fields[e]instanceof Sao.field.Many2One||this.model.fields[e]instanceof Sao.field.Reference){var g=e+".rec_name";a.hasOwnProperty(g)?this._values[g]=a[g]:this._values.hasOwnProperty(g)&&delete this._values[g]}c.push(this.model.fields[e].set_default(this,f)),this._loaded[e]=!0,d.push(e)}}return jQuery.when.apply(jQuery,c).then(function(){return this.on_change(d).then(function(){return this.on_change_with(d).then(function(){var a=function(){return this.group.root_group().screens.forEach(function(a){return a.display()})}.bind(this);return b?this.validate(null,!0).then(a):a()}.bind(this))}.bind(this))}.bind(this))},get_timestamp:function(){var a={};a[this.model.name+","+this.id]=this._timestamp;for(var b in this.model.fields)this.model.fields.hasOwnProperty(b)&&b in this._loaded&&jQuery.extend(a,this.model.fields[b].get_timestamp(this));return a},get_eval:function(){var a={};for(var b in this.model.fields)!this.model.fields.hasOwnProperty(b)&&this.id>=0||(a[b]=this.model.fields[b].get_eval(this));return a},get_on_change_value:function(a){var b={};for(var c in this.model.fields)a&&~a.indexOf(c)||(!(this.id>=0)||this._loaded[c]&&this._changed[c])&&(b[c]=this.model.fields[c].get_on_change_value(this));return b.id=this.id,b},_get_on_change_args:function(a){var b={},c=Sao.common.EvalEnvironment(this,"on_change");return a.forEach(function(a){var d=c;a.split(".").forEach(function(a){void 0!==d&&(d=d[a])}),b[a]=d}),b.id=this.id,b},on_change:function(a){var b={};if(a.forEach(function(a){var c=this.model.fields[a].description.on_change;jQuery.isEmptyObject(c)||(b=jQuery.extend(b,this._get_on_change_args(c)))}.bind(this)),jQuery.isEmptyObject(b))return jQuery.when();var c=this.model.execute("on_change",[b,a],this.get_context());return c.then(function(a){a.forEach(this.set_on_change.bind(this))}.bind(this))},on_change_with:function(a){var b,c,d={},e={},f={};for(b in this.model.fields)if(this.model.fields.hasOwnProperty(b)&&(c=this.model.fields[b].description.on_change_with,!jQuery.isEmptyObject(c))){for(var g=0;g<a.length&&!~c.indexOf(a[g]);g++);g>=a.length||(jQuery.isEmptyObject(Sao.common.intersect(Object.keys(d).sort(),c.sort()))?(d[b]=!0,e=jQuery.extend(e,this._get_on_change_args(c)),(this.model.fields[b]instanceof Sao.field.Many2One||this.model.fields[b]instanceof Sao.field.Reference)&&delete this._values[b+".rec_name"]):f[b]=!0)}var h,i=[];jQuery.isEmptyObject(d)||(h=this.model.execute("on_change_with",[e,Object.keys(d)],this.get_context()),i.push(h.then(this.set_on_change.bind(this))));var j=function(a){return function(b){this.model.fields[a].set_on_change(this,b)}};for(b in f)f.hasOwnProperty(b)&&(c=this.model.fields[b].description.on_change_with,e=this._get_on_change_args(c),h=this.model.execute("on_change_with_"+b,[e],this.get_context()),i.push(h.then(j(b).bind(this))));return jQuery.when.apply(jQuery,i)},set_on_change:function(a){var b,c;for(b in a)if(a.hasOwnProperty(b)&&(c=a[b],b in this.model.fields)){if(this.model.fields[b]instanceof Sao.field.Many2One||this.model.fields[b]instanceof Sao.field.Reference){var d=b+".rec_name";a.hasOwnProperty(d)?this._values[d]=a[d]:this._values.hasOwnProperty(d)&&delete this._values[d]}this.model.fields[b].set_on_change(this,c)}},autocomplete_with:function(a){var b=[];for(var c in this.model.fields){var d=this.model.fields[c],e=d.description.autocomplete||[];~e.indexOf(a)&&b.push(this.do_autocomplete(c))}return jQuery.when.apply(jQuery,b)},do_autocomplete:function(a){this.autocompletion[a]=[];var b=this.model.fields[a],c=b.description.autocomplete,d=this._get_on_change_args(c),e=this.model.execute("autocomplete_"+a,[d],this.get_context());return e.then(function(b){this.autocompletion[a]=b}.bind(this))},expr_eval:function(a){if("string"!=typeof a)return a;var b=jQuery.extend({},this.model.session.context);if(b.context=jQuery.extend({},b),jQuery.extend(b.context,this.get_context()),jQuery.extend(b,this.get_eval()),b.active_model=this.model.name,b.active_id=this.id,b._user=this.model.session.user_id,this.group.parent&&this.group.parent_name){var c=Sao.common.EvalEnvironment(this.group.parent);b["_parent_"+this.group.parent_name]=c}return new Sao.PYSON.Decoder(b).decode(a)},rec_name:function(){var a=this.model.execute("read",[[this.id],["rec_name"]],this.get_context());return a.then(function(a){return a[0].rec_name})},validate:function(a,b,c,d){var e=function(){var e=!0,f=[];this.group.screens.forEach(function(a){a.exclude_field&&f.push(a.exclude_field)});for(var g in this.model.fields)if((!(d&&this.id>=0)||g in this._loaded)&&this.model.fields.hasOwnProperty(g)){var h=this.model.fields[g];a&&!~a.indexOf(g)||h.description.readonly||~f.indexOf(g)||h.validate(this,b,c)||(e=!1)}return e}.bind(this);return d?e():this._check_load(a).then(e)},pre_validate:function(){if(jQuery.isEmptyObject(this._changed))return jQuery.Deferred().resolve(!0);var a=this._get_on_change_args(Object.keys(this._changed));return this.model.execute("pre_validate",[a],this.get_context()).then(function(){return!0},function(){return!1})},cancel:function(){this._loaded={},this._changed={},this._timestamp=null,this.button_clicks={}},_check_load:function(a){return this.get_loaded(a)?jQuery.when():this.reload(a)},get_loaded:function(a){if(!jQuery.isEmptyObject(a)){var b=!0;return a.forEach(function(a){a in this._loaded||a in this._changed||(b=!1)}.bind(this)),b}return Sao.common.compare(Object.keys(this.model.fields).sort(),Object.keys(this._loaded).sort())},root_parent:function(){for(var a=this;a.group.parent;)a=a.group.parent;return a},get_path:function(a){for(var b=[],c=this,d="";c&&(b.push([d,c.id]),c.group!==a);)d=c.group.child_name,c=c.group.parent;return b.reverse(),b},deleted:function(){return Boolean(~this.group.record_deleted.indexOf(this))},removed:function(){return Boolean(~this.group.record_removed.indexOf(this))},readonly:function(){return this.deleted()||this.removed()||this.exception},set_field_context:function(){for(var a in this.model.fields)if(this.model.fields.hasOwnProperty(a)){var b=this.model.fields[a],c=this._values[a];if(c&&c.set_context){var d=b.description.context;d&&c.set_context(this.expr_eval(d))}}},get_attachment_count:function(a){var b=jQuery.Deferred();return this.id<0?(b.resolve(0),b):(this.attachment_count<0||a?b=Sao.rpc({method:"model.ir.attachment.search_count",params:[[["resource","=",this.model.name+","+this.id]],this.get_context()]},this.model.session).then(function(a){return this.attachment_count=a,a}.bind(this)):b.resolve(this.attachment_count),b)},get_unread_note:function(a){var b=jQuery.Deferred();return this.id<0?(b.resolve(0),b):(this.unread_note<0||a?b=Sao.rpc({method:"model.ir.note.search_count",params:[[["resource","=",this.model.name+","+this.id],["unread","=",!0]],this.get_context()]},this.model.session).then(function(a){return this.unread_note=a,a}.bind(this)):b.resolve(this.unread_note),b)},get_button_clicks:function(a){if(this.id<0)return jQuery.when();var b=this.button_clicks[a];return void 0!==b?jQuery.when(b):Sao.rpc({method:"model.ir.model.button.click.get_click",params:[this.model.name,a,this.id,{}]},this.model.session).then(function(b){return this.button_clicks[a]=b,b}.bind(this))}}),Sao.field={},Sao.field.get=function(a){switch(a){case"char":return Sao.field.Char;case"selection":return Sao.field.Selection;case"datetime":return Sao.field.DateTime;case"date":return Sao.field.Date;case"time":return Sao.field.Time;case"timedelta":return Sao.field.TimeDelta;case"float":return Sao.field.Float;case"numeric":return Sao.field.Numeric;case"integer":return Sao.field.Integer;case"boolean":return Sao.field.Boolean;case"many2one":return Sao.field.Many2One;case"one2one":return Sao.field.One2One;case"one2many":return Sao.field.One2Many;case"many2many":return Sao.field.Many2Many;case"reference":return Sao.field.Reference;case"binary":return Sao.field.Binary;case"dict":return Sao.field.Dict;default:return Sao.field.Char}},Sao.field.Field=Sao.class_(Object,{_default:null,init:function(a){this.description=a,this.name=a.name},set:function(a,b){a._values[this.name]=b},get:function(a){var b=a._values[this.name];return void 0===b&&(b=this._default),b},set_client:function(a,b,c){var d=this.get(a);this.set(a,b),JSON.stringify(d)!=JSON.stringify(this.get(a))?(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.changed().done(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})})})):c&&(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})}))},get_client:function(a){return this.get(a)},set_default:function(a,b){a._values[this.name]=b,a._changed[this.name]=!0},set_on_change:function(a,b){a._values[this.name]=b,a._changed[this.name]=!0},changed:function(a){var b=[];return b.push(a.on_change([this.name])),b.push(a.on_change_with([this.name])),b.push(a.autocomplete_with(this.name)),a.set_field_context(),jQuery.when.apply(jQuery,b)},get_timestamp:function(a){return{}},get_context:function(a){var b=jQuery.extend({},a.get_context());return a.group.parent&&jQuery.extend(b,a.group.parent.get_context()),jQuery.extend(b,a.expr_eval(this.description.context||{})),b},get_domains:function(a,b){var c=new Sao.common.DomainInversion,d=c.domain_inversion([a.group.domain4inversion(),b||[]],this.name,Sao.common.EvalEnvironment(a));"boolean"!=typeof d||d?"boolean"==typeof d&&d&&(d=[]):d=[["id","=",null]];var e=a.expr_eval(this.description.domain||[]);return[d,e]},get_domain:function(a){var b=this.get_domains(a),c=b[0],d=b[1],e=new Sao.common.DomainInversion;return e.concat([e.localize_domain(c),d])},validation_domains:function(a,b){var c=new Sao.common.DomainInversion;return c.concat(this.get_domains(a,b))},get_eval:function(a){return this.get(a)},get_on_change_value:function(a){return this.get_eval(a)},set_state:function(a,b){void 0===b&&(b=["readonly","required","invisible"]);var c=a.expr_eval(this.description.states||{});b.forEach(function(b){"readonly"==b&&this.description.readonly||(void 0!==c[b]?this.get_state_attrs(a)[b]=c[b]:void 0!==this.description[b]&&(this.get_state_attrs(a)[b]=this.description[b]))}.bind(this)),(a.group.get_readonly()||this.get_state_attrs(a).domain_readonly)&&(this.get_state_attrs(a).readonly=!0)},get_state_attrs:function(a){return this.name in a.state_attrs||(a.state_attrs[this.name]=jQuery.extend({},this.description)),(a.group.get_readonly()||a.readonly())&&(a.state_attrs[this.name].readonly=!0),a.state_attrs[this.name]},check_required:function(a){var b=this.get_state_attrs(a);return!(1==b.required&&!this.get(a)&&1!=b.readonly)},validate:function(a,b,c){if(this.description.readonly)return!0;var d=!1;this.get_state_attrs(a).domain_readonly=!1;var e=new Sao.common.DomainInversion,f=e.simplify(this.validation_domains(a,c));if(b||this.check_required(a)||(d="required"),"boolean"==typeof f)f||(d="domain");else if(Sao.common.compare(f,[["id","=",null]]))d="domain";else{var g=e.unique_value(f),h=g[0],i=g[1],j=g[2];if(h){j===!1&&(j=null);var k,l=!0;k=jQuery.isEmptyObject(a.group.domain())?e.merge(f):e.merge(a.group.domain());var m="AND"==k[0];if(i.contains(".")){var n=i.split(".",1)[0],o=i.split(".",1)[1],p=[];m&&e.localize_domain(k.slice(1)).forEach(function(a){p.push(a)}),"id"==o&&~p.indexOf(n)||(l=!1)}l&&!c&&(this.set_client(a,j),this.get_state_attrs(a).domain_readonly=m)}e.eval_domain(f,Sao.common.EvalEnvironment(a))||(d=f)}return this.get_state_attrs(a).invalid=d,!d}}),Sao.field.Char=Sao.class_(Sao.field.Field,{_default:"",get:function(a){return Sao.field.Char._super.get.call(this,a)||this._default}}),Sao.field.Selection=Sao.class_(Sao.field.Field,{_default:null}),Sao.field.DateTime=Sao.class_(Sao.field.Field,{_default:null,time_format:function(a){return a.expr_eval(this.description.format)},set_client:function(a,b,c){var d;b&&(b.isTime?(d=this.get(a),b=d?Sao.DateTime.combine(d,b):null):b.isDate&&(d=this.get(a),d&&(b=Sao.DateTime.combine(b,d)))),Sao.field.DateTime._super.set_client.call(this,a,b,c)},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)}}),Sao.field.Date=Sao.class_(Sao.field.Field,{_default:null,set_client:function(a,b,c){b&&!b.isDate&&(b.isDate=!0,b.isDateTime=!1),Sao.field.Date._super.set_client.call(this,a,b,c)},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)}}),Sao.field.Time=Sao.class_(Sao.field.Field,{_default:null,time_format:function(a){return a.expr_eval(this.description.format)},set_client:function(a,b,c){b&&(b.isDate||b.isDateTime)&&(b=Sao.Time(b.hour(),b.minute(),b.second(),b.millisecond())),Sao.field.Time._super.set_client.call(this,a,b,c)}}),Sao.field.TimeDelta=Sao.class_(Sao.field.Field,{_default:null,converter:function(a){return a.model.session.context[this.description.converter]},set_client:function(a,b,c){"string"==typeof b&&(b=Sao.common.timedelta.parse(b,this.converter(a))),Sao.field.TimeDelta._super.set_client.call(this,a,b,c)},get_client:function(a){var b=Sao.field.TimeDelta._super.get_client.call(this,a);return Sao.common.timedelta.format(b,this.converter(a))}}),Sao.field.Float=Sao.class_(Sao.field.Field,{_default:null,digits:function(a,b){void 0===b&&(b=1);var c=a.expr_eval(this.description.digits);if(c&&c.every(function(a){return null!==a})){var d=Math.round(Math.log(Math.abs(b))/Math.LN10);return[c[0]+d,c[1]-d]}},check_required:function(a){var b=this.get_state_attrs(a);return 1!=b.required||null!==this.get(a)||1==b.readonly},convert:function(a){return a?(a=Number(a),isNaN(a)&&(a=this._default),a):null},apply_factor:function(a,b){return null!==a&&(a/=b),a},set_client:function(a,b,c,d){void 0===d&&(d=1),b=this.apply_factor(this.convert(b),d),Sao.field.Float._super.set_client.call(this,a,b,c)},get_client:function(a,b){void 0===b&&(b=1);var c=this.get(a);if(null!==c){var d=this.digits(a,b);return d?(c*b).toFixed(d[1]):""+c*b}return""}}),Sao.field.Numeric=Sao.class_(Sao.field.Float,{convert:function(a){return a?(a=new Sao.Decimal(a),isNaN(a.valueOf())&&(a=this._default),a):null},apply_factor:function(a,b){return a=Sao.field.Numeric._super.apply_factor(a,b),null!==a&&(a=new Sao.Decimal(a)),a}}),Sao.field.Integer=Sao.class_(Sao.field.Float,{convert:function(a){return a=parseInt(a,10),isNaN(a)&&(a=this._default),a}}),Sao.field.Boolean=Sao.class_(Sao.field.Field,{_default:!1,set_client:function(a,b,c){b=Boolean(b),Sao.field.Boolean._super.set_client.call(this,a,b,c)},get:function(a){return Boolean(a._values[this.name])},get_client:function(a){return Boolean(a._values[this.name])}}),Sao.field.Many2One=Sao.class_(Sao.field.Field,{_default:null,check_required:function(a){var b=this.get_state_attrs(a);return 1!=b.required||null!==this.get(a)||1==b.readonly},get_client:function(a){var b=a._values[this.name+".rec_name"];return void 0===b&&(this.set(a,this.get(a)),b=a._values[this.name+".rec_name"]||""),b},set:function(a,b){var c=a._values[this.name+".rec_name"]||"",d=function(b){a._values[this.name+".rec_name"]=b[0].rec_name};if(!c&&b>=0&&null!==b){var e=a.model.fields[this.name].description.relation;Sao.rpc({method:"model."+e+".read",params:[[b],["rec_name"],a.get_context()]},a.model.session).done(d.bind(this)).done(function(){a.group.root_group().screens.forEach(function(a){a.display()})})}else d.call(this,[{rec_name:c}]);a._values[this.name]=b},set_client:function(a,b,c){var d;b instanceof Array?(d=b[1],b=b[0]):d=b==this.get(a)?a._values[this.name+".rec_name"]||"":"",a._values[this.name+".rec_name"]=d,Sao.field.Many2One._super.set_client.call(this,a,b,c)},get_context:function(a){var b=Sao.field.Many2One._super.get_context.call(this,a);return this.description.datetime_field&&(b._datetime=a.get_eval()[this.description.datetime_field]),b},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=this.get_domains(a),c=b[0],d=b[1],e=new Sao.common.DomainInversion;return e.concat([e.localize_domain(e.inverse_leaf(c),this.name),d])},get_on_change_value:function(a){return a.group.parent_name==this.name&&a.group.parent?a.group.parent.get_on_change_value([a.group.child_name]):Sao.field.Many2One._super.get_on_change_value.call(this,a)}}),Sao.field.One2One=Sao.class_(Sao.field.Many2One,{}),Sao.field.One2Many=Sao.class_(Sao.field.Field,{init:function(a){Sao.field.One2Many._super.init.call(this,a)},_default:null,_set_value:function(a,b,c){this._set_default_value(a);var d=a._values[this.name],e=jQuery.when();jQuery.isEmptyObject(b)&&(b=[]);var f;if(f=jQuery.isEmptyObject(b)||!isNaN(parseInt(b[0],10))?"list ids":"list values",
+"list values"==f){var g=this.get_context(a),h={};if(b.forEach(function(a){for(var b in a)a.hasOwnProperty(b)&&(b in d.model.fields||~b.indexOf(".")||(h[b]=!0))}),!jQuery.isEmptyObject(h)){var i={method:"model."+this.description.relation+".fields_get",params:[Object.keys(h),g]};e=Sao.rpc(i,a.model.session)}}var j=function(e){var g=[];if(jQuery.isEmptyObject(e)||d.add_fields(e),a._values[this.name]=d,"list ids"==f){for(var h=0,i=d.length;i>h;h++){var j=d[h];~b.indexOf(j.id)||d.remove(j,!0)}d.load(b)}else b.forEach(function(a){var b=d.new_(!1);c?(g.push(b.set_default(a,!1)),d.add(b)):(g.push(b.set(a)),d.push(b))});return jQuery.when.apply(jQuery,g)};return e.then(j)},set:function(a,b,c){void 0===c&&(c=!1);var d,e=a._values[this.name];return void 0!==e?(d=e.model,e.destroy()):d=a.model.name==this.description.relation?a.model:new Sao.Model(this.description.relation),a._values[this.name]=void 0,this._set_default_value(a,d),this._set_value(a,b,c)},get:function(a){var b=a._values[this.name];if(void 0===b)return[];for(var c=b.record_removed,d=b.record_deleted,e=[],f=this.description.relation_field||"",g=[],h=[],i=[],j=0,k=b.length;k>j;j++){var l=b[j];if(!~c.indexOf(l)&&!~d.indexOf(l)){var m;l.id>=0?(m=l.get(),delete m[f],l.has_changed()&&!jQuery.isEmptyObject(m)&&(i.push([l.id]),i.push(m)),g.push(l.id)):(m=l.get(),delete m[f],h.push(m))}}return jQuery.isEmptyObject(g)||e.push(["add",g]),jQuery.isEmptyObject(h)||e.push(["create",h]),jQuery.isEmptyObject(i)||e.push(["write"].concat(i)),jQuery.isEmptyObject(c)||e.push(["remove",c.map(function(a){return a.id})]),jQuery.isEmptyObject(d)||e.push(["delete",d.map(function(a){return a.id})]),e},set_client:function(a,b,c){null===b&&(b=[]),"number"==typeof b&&(b=[b]);var d=this.get_eval(a);this._set_value(a,b),Sao.common.compare(d.sort(),b.sort())?c&&(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})})):(a._changed[this.name]=!0,this.changed(a).done(function(){a.validate(null,!0).then(function(){a.group.changed().done(function(){var b=a.group.root_group();b.screens.forEach(function(a){a.display()})})})}))},get_client:function(a){return this._set_default_value(a),a._values[this.name]},set_default:function(a,b){return a._changed[this.name]=!0,this.set(a,b,!0)},set_on_change:function(a,b){if(a._changed[this.name]=!0,this._set_default_value(a),b instanceof Array)return void this._set_value(a,b);var c=jQuery.when();if(b.add||b.update){var d=this.get_context(a),e=a._values[this.name].model.fields,f={},g=[];if(b.add)for(var h=0;h<b.add.length;h++)g.push(b.add[h][1]);if([g,b.update].forEach(function(a){jQuery.isEmptyObject(a)||a.forEach(function(a){Object.keys(a).forEach(function(a){a in e||"id"==a||(f[a]=!0)})})}),!jQuery.isEmptyObject(f)){var i={method:"model."+this.description.relation+".fields_get",params:[Object.keys(f),d]};c=Sao.rpc(i,a.model.session)}}var j=[],k=a._values[this.name];k.forEach(function(a){a.id||j.push(a)}),b.remove&&b.remove.forEach(function(a){var b=k.get(a);b&&j.push(b)}.bind(this)),j.forEach(function(a){k.remove(a,!1,!0,!1)}.bind(this)),(b.add||b.update)&&c.then(function(a){k.add_fields(a),b.add&&b.add.forEach(function(a){var b=a[0],c=a[1],d=k.new_(!1);k.add(d,b,!1),d.set_on_change(c)}),b.update&&b.update.forEach(function(a){if(a.id){var b=k.get(a.id);b&&b.set_on_change(a)}})}.bind(this))},_set_default_value:function(a,b){if(void 0===a._values[this.name]){b||(b=new Sao.Model(this.description.relation)),a.model.name==this.description.relation&&(b=a.model);var c=a.expr_eval(this.description.context||{}),d=Sao.Group(b,c,[]);d.set_parent(a),d.parent_name=this.description.relation_field,d.child_name=this.name,a._values[this.name]=d}},get_timestamp:function(a){var b=a._values[this.name];if(void 0===b)return{};for(var c,d={},e=0,f=b.length;f>e;e++)c=b[e],jQuery.extend(d,c.get_timestamp());return d},get_eval:function(a){var b=[],c=a._values[this.name];if(void 0===c)return b;for(var d=c.record_removed,e=c.record_deleted,f=0,g=a._values[this.name].length;g>f;f++){var h=c[f];~d.indexOf(h)||~e.indexOf(h)||b.push(h.id)}return b},get_on_change_value:function(a){var b=[],c=a._values[this.name];if(void 0===c)return b;for(var d=0,e=a._values[this.name].length;e>d;d++){var f=c[d];f.deleted()&&f.removed()||b.push(f.get_on_change_value([this.description.relation_field||""]))}return b},get_removed_ids:function(a){return a._values[this.name].record_removed.map(function(a){return a.id})},get_domain:function(a){var b=this.get_domains(a),c=b[1];return c},validation_domains:function(a,b){return this.get_domains(a,b)[0]},validate:function(a,b,c){var d=!1,e=new Sao.common.DomainInversion,f=e.localize_domain(e.domain_inversion(a.group.clean4inversion(c||[]),this.name,Sao.common.EvalEnvironment(a)),this.name);"boolean"==typeof f&&(f=f?[]:[["id","=",null]]);for(var g=0,h=(a._values[this.name]||[]).length;h>g;g++){var i=a._values[this.name][g];!i.get_loaded()&&i.id>=0&&!c||i.validate(null,b,f,!0)||(d="children")}var j=Sao.field.One2Many._super.validate.call(this,a,b,c);return j&&d?(this.get_state_attrs(a).invalid=d,!1):j},set_state:function(a,b){this._set_default_value(a),Sao.field.One2Many._super.set_state.call(this,a,b)}}),Sao.field.Many2Many=Sao.class_(Sao.field.One2Many,{get_on_change_value:function(a){return this.get_eval(a)}}),Sao.field.Reference=Sao.class_(Sao.field.Field,{_default:null,get_client:function(a){if(a._values[this.name]){var b=a._values[this.name][0],c=a._values[this.name+".rec_name"]||"";return[b,c]}return null},get:function(a){return a._values[this.name]&&a._values[this.name][0]&&a._values[this.name][1]>=-1?a._values[this.name].join(","):null},set_client:function(a,b,c){if(b){"string"==typeof b&&(b=b.split(","));var d,e=b[0],f=b[1];f instanceof Array?(d=f[1],f=f[0]):(f&&!isNaN(parseInt(f,10))&&(f=parseInt(f,10)),d=[e,f].join(",")==this.get(a)?a._values[this.name+".rec_name"]||"":""),a._values[this.name+".rec_name"]=d,b=[e,f]}Sao.field.Reference._super.set_client.call(this,a,b,c)},set:function(a,b){if(!b)return void(a._values[this.name]=this._default);var c,d;"string"==typeof b?(c=b.split(",")[0],d=b.split(",")[1],d?isNaN(parseInt(d,10))||(d=parseInt(d,10)):d=null):(c=b[0],d=b[1]);var e=a._values[this.name+".rec_name"]||"",f=function(b){a._values[this.name+".rec_name"]=b}.bind(this);c&&null!==d&&d>=0?!e&&d>=0&&Sao.rpc({method:"model."+c+".read",params:[[d],["rec_name"],a.get_context()]},a.model.session).done(function(a){f(a[0].rec_name)}):e=c?"":d,a._values[this.name]=[c,d],f(e)},get_on_change_value:function(a){return a.group.parent_name==this.name&&a.group.parent?[a.group.parent.model.name,a.group.parent.get_on_change_value([a.group.child_name])]:Sao.field.Reference._super.get_on_change_value.call(this,a)},get_context:function(a){var b=Sao.field.Reference._super.get_context.call(this,a);return this.description.datetime_field&&(b._datetime=a.get_eval()[this.description.datetime_field]),b},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=null;a._values[this.name]&&(b=a._values[this.name][0]);var c=this.get_domains(a),d=c[0],e=c[1],f=new Sao.common.DomainInversion;return f.concat([f.localize_domain(f.filter_leaf(d,this.name,b),!0),e])}}),Sao.field.Binary=Sao.class_(Sao.field.Field,{_default:null,get_size:function(a){var b=a._values[this.name]||0;return b instanceof Uint8Array?b.length:b},get_data:function(a){var b=a._values[this.name]||[],c=jQuery.when(b);if(!(b instanceof Uint8Array)){if(a.id<0)return c;var d=a.get_context();c=a.model.execute("read",[[a.id],[this.name]],d).then(function(a){return a[0][this.name]}.bind(this))}return c}}),Sao.field.Dict=Sao.class_(Sao.field.Field,{_default:{},set:function(a,b){if(b){var c=[];for(var d in b)c.push(d);c.sort();var e={};for(var f in c)d=c[f],e[d]=b[d];b=e}Sao.field.Dict._super.set.call(this,a,b)},get:function(a){return Sao.field.Dict._super.get.call(this,a)||this._default},get_client:function(a){return Sao.field.Dict._super.get_client.call(this,a)||this._default},validation_domains:function(a,b){return this.get_domains(a,b)[0]},get_domain:function(a){var b=new Sao.common.DomainInversion,c=this.get_domains(a),d=c[0],e=c[1];return b.concat([b.localize_domain(b.inverse_leaf(d)),e])},date_format:function(a){var b=this.get_context(a);return Sao.common.date_format(b.date_format)},time_format:function(a){return"%X"}})}(),function(){"use strict";Sao.Tab=Sao.class_(Object,{init:function(){Sao.Tab.tabs.push(this),this.buttons={},this.id="tab-"+Sao.Tab.counter++,this.name="",this.name_el=jQuery("<span/>")},create_tabcontent:function(){this.el=jQuery("<div/>",{"class":this.class_});var a=this.create_toolbar().appendTo(this.el);this.title=a.find(".title"),this.content=jQuery("<div/>").appendTo(this.el),this.info_bar&&this.el.append(this.info_bar.el)},set_menu:function(a){this.menu_def().forEach(function(b){var c=b[0],d=b[1],e=b[2],f=jQuery("<li/>",{role:"presentation"}).appendTo(a),g=jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(jQuery("<span/>",{"class":"glyphicon "+c,"aria-hidden":"true"})).append(" "+d).appendTo(f);e?g.click(function(){this[e]()}.bind(this)):f.addClass("disabled")}.bind(this))},create_toolbar:function(){var a=jQuery("<nav/>",{"class":"toolbar navbar navbar-default",role:"toolbar"}).append(jQuery("<div/>",{"class":"container-fluid"}).append(jQuery("<div/>",{"class":"dropdown navbar-header navbar-left"}).append(jQuery("<a/>",{href:"#","class":"navbar-brand dropdown-toggle","data-toggle":"dropdown",role:"button","aria-expanded":!1,"aria-haspopup":!0}).append(jQuery("<span/>",{"class":"title"})).append(jQuery("<span/>",{"class":"caret"}))).append(jQuery("<ul/>",{"class":"dropdown-menu",role:"menu"})).append(jQuery("<button/>",{type:"button","class":"close visible-xs visible-sm","aria-label":Sao.i18n.gettext("Close")}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).click(function(){this.close()}.bind(this)))).append(jQuery("<div/>",{"class":"btn-toolbar navbar-right",role:"toolbar"}))),b=jQuery("<div/>",{"class":"toolbar-wrapper"}).append(a);this.set_menu(a.find('ul[role*="menu"]'));var c,d=function(b){return b?(c||(c=jQuery("<div/>",{"class":"btn-group",role:"group"}).appendTo(a.find(".btn-toolbar"))),this.buttons[b[0]]=jQuery("<button/>",{type:"button","class":"btn btn-default navbar-btn",title:b[2],id:b[0]}).append(jQuery("<span/>",{"class":"glyphicon "+b[1],"aria-hidden":"true"})).appendTo(c).data("toggle","tooltip").data("placement","bottom").tooltip(),void(b[3]?this.buttons[b[0]].click(this[b[3]].bind(this)):item.addClass("disabled"))):void(c=null)};this.toolbar_def().forEach(d.bind(this)),a.find(".btn-toolbar > .btn-group").last().addClass("hidden-xs");var e=jQuery("#tabs");return a.affix({target:e.parent(),offset:{top:function(){return jQuery("#main_navbar").height()}}}),a.on("affix.bs.affix",function(){b.height(jQuery("#main_navbar").height())}),a.on("affix-top.bs.affix affix-bottom.bs.affix",function(){b.height("")}),a.on("affixed.bs.affix",function(){Sao.Tab.affix_set_with(a)}),a.on("affixed-top.bs.affix affixed-bottom.bs.affix",function(){Sao.Tab.affix_unset_width(a)}),b},close:function(){var a=jQuery("#tabs"),b=jQuery("#tablist"),c=b.find("#nav-"+this.id),d=a.find("#"+this.id);return b.find('a[href="#'+this.id+'"]').tab("show"),this._close_allowed().then(function(){var b=c.nextAll("li").first();b.length||(b=c.prevAll("li").first()),c.tooltip("destroy").remove(),d.remove(),Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(this),1),b&&b.find("a").tab("show"),a.trigger("ready")}.bind(this))},_close_allowed:function(){return jQuery.when()},set_name:function(a){this.name=a,this.name_el.text(Sao.common.ellipsize(a,20)),this.name_el.parents("li").first().attr("title",a).tooltip()}}),Sao.Tab.affix_set_with=function(a){var b=jQuery(a.parent()).width();a.css("width",b)},Sao.Tab.affix_unset_width=function(a){a.css("width","")},jQuery(window).resize(function(){jQuery(".toolbar").each(function(a,b){b=jQuery(b),b.affix("checkPosition"),b.hasClass("affix")?Sao.Tab.affix_set_with(b):Sao.Tab.affix_unset_width(b)})}),Sao.Tab.counter=0,Sao.Tab.tabs=[],Sao.Tab.tabs.close=function(a){if(a&&Sao.Tab.tabs.length)return Sao.common.sur.run(Sao.i18n.gettext("The following action requires to close all tabs.\nDo you want to continue?")).then(function(){return Sao.Tab.tabs.close(!1)});if(Sao.Tab.tabs.length){var b=Sao.Tab.tabs[0];return b.close().then(function(){return~Sao.Tab.tabs.indexOf(b)?jQuery.Deferred().reject():Sao.Tab.tabs.close()})}return Sao.main_menu_screen?Sao.main_menu_screen.save_tree_state().then(function(){Sao.main_menu_screen=null}):jQuery.when()},Sao.Tab.tabs.get_current=function(){var a=jQuery("#tablist"),b=a.find("li").index(a.find("li.active"));return Sao.Tab.tabs[b]},Sao.Tab.tabs.close_current=function(){var a=this.get_current();a.close()},Sao.Tab.create=function(a){void 0===a.context&&(a.context={});var b;b=a.model?new Sao.Tab.Form(a.model,a):new Sao.Tab.Board(a),Sao.Tab.add(b)},Sao.Tab.add=function(a){var b=jQuery("#tabs"),c=jQuery("#tablist"),d=jQuery("#tabcontent"),e=jQuery("<a/>",{"aria-controls":a.id,role:"tab","data-toggle":"tab",href:"#"+a.id}).append(jQuery("<button/>",{"class":"close"}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Close"))).click(function(){a.close()})).append(a.name_el);jQuery("<li/>",{role:"presentation","data-toggle":"tooltip","data-placement":"bottom",id:"nav-"+a.id}).append(e).appendTo(c),jQuery("<div/>",{role:"tabpanel","class":"tab-pane",id:a.id}).html(a.el).appendTo(d),e.on("shown.bs.tab",function(){Sao.View.resize(a.el)}),e.tab("show"),b.trigger("ready")},Sao.Tab.Form=Sao.class_(Sao.Tab,{class_:"tab-form",init:function(a,b){Sao.Tab.Form._super.init.call(this);var c=new Sao.Screen(a,b);c.tab=this,this.screen=c,this.attributes=jQuery.extend({},b),this.info_bar=new Sao.Window.InfoBar,this.create_tabcontent(),this.set_buttons_sensitive(),this.view_prm=this.screen.switch_view().done(function(){this.set_name(b.name||""),this.content.append(c.screen_container.el),b.res_id?(jQuery.isArray(b.res_id)||(b.res_id=[b.res_id]),c.group.load(b.res_id),c.set_current_record(c.group.get(b.res_id)),c.display()):("form"==c.current_view.view_type&&c.new_(),~["tree","graph","calendar"].indexOf(c.current_view.view_type)&&c.search_filter()),this.update_revision()}.bind(this))},toolbar_def:function(){return[["new","glyphicon-edit",Sao.i18n.gettext("Create a new record"),"new_"],["save","glyphicon-save",Sao.i18n.gettext("Save this record"),"save"],["switch","glyphicon-list-alt",Sao.i18n.gettext("Switch view"),"switch_"],["reload","glyphicon-refresh",Sao.i18n.gettext("Reload"),"reload"],null,["previous","glyphicon-chevron-left",Sao.i18n.gettext("Previous Record"),"previous"],["next","glyphicon-chevron-right",Sao.i18n.gettext("Next Record"),"next"],null,["attach","glyphicon-paperclip",Sao.i18n.gettext("Add an attachment to the record"),"attach"],["note","glyphicon-comment",Sao.i18n.gettext("Add a note to the record"),"note"]]},menu_def:function(){return[["glyphicon-edit",Sao.i18n.gettext("New"),"new_"],["glyphicon-save",Sao.i18n.gettext("Save"),"save"],["glyphicon-list-alt",Sao.i18n.gettext("Switch"),"switch_"],["glyphicon-refresh",Sao.i18n.gettext("Reload/Undo"),"reload"],["glyphicon-duplicate",Sao.i18n.gettext("Duplicate"),"copy"],["glyphicon-trash",Sao.i18n.gettext("Delete"),"delete_"],["glyphicon-chevron-left",Sao.i18n.gettext("Previous"),"previous"],["glyphicon-chevron-right",Sao.i18n.gettext("Next"),"next"],["glyphicon-search",Sao.i18n.gettext("Search"),"search"],["glyphicon-time",Sao.i18n.gettext("View Logs..."),"logs"],["glyphicon-time",Sao.i18n.gettext("Show revisions..."),Sao.common.MODELHISTORY.contains(this.screen.model_name)?"revision":null],["glyphicon-remove",Sao.i18n.gettext("Close Tab"),"close"],["glyphicon-paperclip",Sao.i18n.gettext("Attachment"),"attach"],["glyphicon-comment",Sao.i18n.gettext("Note"),"note"],["glyphicon-cog",Sao.i18n.gettext("Action"),"action"],["glyphicon-share-alt",Sao.i18n.gettext("Relate"),"relate"],["glyphicon-print",Sao.i18n.gettext("Print"),"print"],["glyphicon-export",Sao.i18n.gettext("Export"),"export"],["glyphicon-import",Sao.i18n.gettext("Import"),"import"]]},create_toolbar:function(){var a=Sao.Tab.Form._super.create_toolbar.call(this),b=this.screen,c=this.buttons,d=b.model.execute("view_toolbar_get",[],b.context);return d.done(function(d){[["action","glyphicon-cog",Sao.i18n.gettext("Launch action")],["relate","glyphicon-share-alt",Sao.i18n.gettext("Open related records")],["print","glyphicon-print",Sao.i18n.gettext("Print report")]].forEach(function(e){var f=jQuery("<div/>",{"class":"btn-group",role:"group"}).append(jQuery("<button/>",{type:"button","class":"btn btn-default navbar-btn dropdown-toggle","data-toggle":"dropdown","aria-expanded":!1,"aria-haspopup":!0,title:e[2],id:e[0],disabled:!d[e[0]].length}).append(jQuery("<span/>",{"class":"glyphicon "+e[1],"aria-hidden":"true"})).append(jQuery("<span/>",{"class":"caret"})).data("toggle","tooltip").data("placement","bottom").tooltip()).append(jQuery("<ul/>",{"class":"dropdown-menu",role:"menu","aria-labelledby":e[0]})).appendTo(a.find(".btn-toolbar > .btn-group").last());c[e[0]]=f;var g=(f.on("show.bs.dropdown",function(){jQuery(this).parents(".btn-group").removeClass("hidden-xs")}).on("hide.bs.dropdown",function(){jQuery(this).parents(".btn-group").addClass("hidden-xs")}),f.find('ul[role*="menu"]'));"action"==e[0]&&f.click(function(){g.find(".action_button").remove();var a=b.get_buttons();a.forEach(function(a){jQuery("<li/>",{role:"presentation","class":"action_button"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(a.attributes.string||"")).click(function(){b.button(a.attributes)}).appendTo(g)})}),d[e[0]].forEach(function(a){jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(a.name)).click(function(){b.save_current().then(function(){var c=jQuery.extend({},a),d=null;b.current_record&&(d=b.current_record.id);var f=b.current_view.selected_records().map(function(a){return a.id});c=Sao.Action.evaluate(c,e[0],b.current_record);var g={model:b.model_name,id:d,ids:f};Sao.Action.exec_action(c,g,b.context)})}).appendTo(g)})})}),a},_close_allowed:function(){return this.modified_save()},modified_save:function(){return this.screen.save_tree_state(),this.screen.current_view.set_value(),this.screen.modified()?Sao.common.sur_3b.run(Sao.i18n.gettext("This record has been modified\ndo you want to save it?")).then(function(a){switch(a){case"ok":return this.save();case"ko":return this.reload(!1);default:return jQuery.Deferred().reject()}}.bind(this)):jQuery.when()},new_:function(){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.modified_save().done(function(){this.screen.new_().then(function(){this.info_bar.message()}.bind(this))}.bind(this))},save:function(){var a=Sao.common.MODELACCESS.get(this.screen.model_name);return a.write||a.create?this.screen.save_current().then(function(){this.info_bar.message(Sao.i18n.gettext("Record saved."),"info"),this.screen.count_tab_domain()}.bind(this),function(){this.info_bar.message(this.screen.invalid_message(),"danger")}.bind(this)):jQuery.when()},switch_:function(){this.modified_save().done(function(){this.screen.switch_view()}.bind(this))},reload:function(a){void 0===a&&(a=!0);var b=function(){return this.screen.cancel_current().then(function(){return this.screen.save_tree_state(!1),"form"!=this.screen.current_view.view_type&&this.screen.search_filter(this.screen.screen_container.search_entry.val()),this.screen.count_tab_domain(),this.screen.display().then(function(){this.info_bar.message()}.bind(this))}.bind(this))}.bind(this);return a?this.modified_save().then(b):b()},copy:function(){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.modified_save().done(function(){this.screen.copy().then(function(){this.info_bar.message(Sao.i18n.gettext("Working now on the duplicated record(s)."),"info"),this.screen.count_tab_domain()}.bind(this))}.bind(this))},delete_:function(){if(Sao.common.MODELACCESS.get(this.screen.model_name)["delete"]){var a;a="form"==this.screen.current_view.view_type?Sao.i18n.gettext("Are you sure to remove this record?"):Sao.i18n.gettext("Are you sure to remove those records?"),Sao.common.sur.run(a).done(function(){this.screen.remove(!0,!1,!0).then(function(){this.info_bar.message(Sao.i18n.gettext("Records removed."),"info"),this.screen.count_tab_domain()}.bind(this),function(){this.info_bar.message(Sao.i18n.gettext("Records not removed."),"danger")}.bind(this))}.bind(this))}},previous:function(){this.modified_save().done(function(){this.screen.display_previous(),this.info_bar.message()}.bind(this))},next:function(){this.modified_save().done(function(){this.screen.display_next(),this.info_bar.message()}.bind(this))},search:function(){var a=this.screen.screen_container.search_entry;a.is(":visible")&&window.setTimeout(function(){a.focus()},0)},logs:function(){var a=this.screen.current_record;if(!a||a.id<0)return void this.info_bar.message(Sao.i18n.gettext("You have to select one record."),"info");var b=[["id",Sao.i18n.gettext("ID:")],["create_uid.rec_name",Sao.i18n.gettext("Creation User:")],["create_date",Sao.i18n.gettext("Creation Date:")],["write_uid.rec_name",Sao.i18n.gettext("Latest Modification by:")],["write_date",Sao.i18n.gettext("Latest Modification Date:")]];this.screen.model.execute("read",[[a.id],b.map(function(a){return a[0]})],this.screen.context).then(function(a){a=a[0];var c="";b.forEach(function(b){var d=b[0],e=b[1],f=a[d]||"/";a[d]&&~["create_date","write_date"].indexOf(d)&&(f=Sao.common.format_datetime(Sao.common.date_format(),"%H:%M:%S",f)),c+=e+" "+f+"\n"}),c+=Sao.i18n.gettext("Model: ")+this.screen.model.name,Sao.common.message.run(c)}.bind(this))},revision:function(){var a=null;this.screen.current_record&&(a=this.screen.current_record.id);var b=function(b){return function(c){c&&c.add(1,"milliseconds"),"form"==this.screen.current_view.view_type&&c<b[b.length-1][0]&&(c=b[b.length-1][0]),c!=this.screen.context._datetime&&(this.screen.context._datetime=c,"form"!=this.screen.current_view.view_type?this.screen.search_filter(this.screen.screen_container.search_entry.val()):this.screen.new_group([a]),this.screen.display(!0),this.update_revision())}.bind(this)}.bind(this);this.modified_save().done(function(){var a=this.screen.current_view.selected_records().map(function(a){return a.id});this.screen.model.execute("history_revisions",[a],this.screen.context).then(function(a){new Sao.Window.Revision(a,b(a))})}.bind(this))},update_revision:function(){var a,b=this.screen.context._datetime;if(b){var c=Sao.common.date_format(),d="%H:%M:%S.%f";b=Sao.common.format_datetime(c,d,b),a=this.name+" @ "+b}else a=this.name;this.title.html(a),this.set_buttons_sensitive(b)},set_buttons_sensitive:function(a){if(a)["new","save"].forEach(function(a){this.buttons[a].parent().addClass("disabled")}.bind(this));else{var b=Sao.common.MODELACCESS.get(this.screen.model_name);[["new",b.create],["save",b.create||b.write]].forEach(function(a){var b=a[0],c=a[1];c?this.buttons[b].parent().removeClass("disabled"):this.buttons[b].parent().addClass("disabled")}.bind(this))}},attach:function(){var a=this.screen.current_record;!a||a.id<0||new Sao.Window.Attachment(a,function(){this.update_attachment_count(!0)}.bind(this))},update_attachment_count:function(a){var b=this.screen.current_record;b?b.get_attachment_count(a).always(this.attachment_count.bind(this)):this.attachment_count(0)},attachment_count:function(a){var b=this.buttons.attach.find(".badge");b.length||(b=jQuery("<span/>",{"class":"badge"}).appendTo(this.buttons.attach)),b.text(a);var c=this.screen.get_id();this.buttons.attach.prop("disabled",0>c||null===c)},note:function(){var a=this.screen.current_record;!a||a.id<0||new Sao.Window.Note(a,function(){this.update_unread_note(!0)}.bind(this))},update_unread_note:function(a){var b=this.screen.current_record;b?b.get_unread_note(a).always(this._unread_note.bind(this)):this._unread_note(0)},_unread_note:function(a){var b=this.buttons.note.find(".badge");b.length||(b=jQuery("<span/>",{"class":"badge"}).appendTo(this.buttons.note)),b.text(a);var c=this.screen.get_id();this.buttons.note.prop("disabled",0>c||null===c)},record_message:function(){this.info_bar.message()},action:function(){window.setTimeout(function(){this.buttons.action.find("button").click()}.bind(this))},relate:function(){window.setTimeout(function(){this.buttons.relate.find("button").click()}.bind(this))},print:function(){window.setTimeout(function(){this.buttons.print.find("button").click()}.bind(this))},"export":function(){new Sao.Window.Export(this.screen,this.screen.current_view.selected_records().map(function(a){return a.id}),this.screen.current_view.get_fields(),this.screen.context)},"import":function(){new Sao.Window.Import(this.screen)}}),Sao.Tab.Board=Sao.class_(Sao.Tab,{class_:"tab-board",init:function(a){var b,c;Sao.Tab.Board._super.init.call(this),this.model=a.model,this.view_id=a.view_ids.length>0?a.view_ids[0]:null,this.context=a.context,this.name=a.name||"",this.dialogs=[],this.board=null,b=new Sao.Model("ir.ui.view"),c=b.execute("read",[[this.view_id],["arch"]],this.context),c.done(function(a){var b;b=jQuery(jQuery.parseXML(a[0].arch)),this.board=new Sao.View.Board(b,this.context),this.board.actions_prms.done(function(){var a,b,c;for(a=0,b=this.board.actions.length;b>a;a++)c=this.board.actions[a],c.screen.tab=this}.bind(this)),this.el.append(this.board.el)}.bind(this)),this.create_tabcontent(),this.set_name(this.name),this.title.html(this.name_el.text())},toolbar_def:function(){return[["reload","glyphicon-refresh",Sao.i18n.gettext("Reload"),"reload"]]},menu_def:function(){return[["glyphicon-refresh",Sao.i18n.gettext("Reload/Undo"),"reload"]]},reload:function(){this.board.reload()},record_message:function(){var a,b,c;for(b=this.board.actions.length,a=0,b=b;b>a;a++)c=this.board.actions[a],c.update_domain(this.board.actions)},attachment_count:function(){},note:function(){},update_unread_note:function(){}}),Sao.Tab.Wizard=Sao.class_(Sao.Tab,{class_:"tab-wizard",init:function(a){Sao.Tab.Wizard._super.init.call(this),this.wizard=a,this.set_name(a.name),a.tab=this,this.create_tabcontent(),this.title.html(this.name_el.text()),this.el.append(a.form)},create_toolbar:function(){return jQuery("<span/>")},_close_allowed:function(){var a=this.wizard,b=jQuery.when();a.state!==a.end_state&&a.end_state in a.states&&(b=a.response(a.end_state));var c=jQuery.Deferred();return b.always(function(){a.state===a.end_state?c.resolve():c.reject()}),c.promise()}})}(),function(){"use strict";Sao.ScreenContainer=Sao.class_(Object,{init:function(a){this.alternate_viewport=jQuery("<div/>",{"class":"screen-container"}),this.alternate_view=!1,this.search_modal=null,this.search_form=null,this.last_search_text="",this.tab_domain=a||[],this.tab_counter=[],this.el=jQuery("<div/>",{"class":"screen-container"}),this.filter_box=jQuery("<form/>",{"class":"filter-box"}).submit(function(a){this.do_search(),a.preventDefault()}.bind(this));var b=jQuery("<div/>",{"class":"row"}).appendTo(this.filter_box);this.el.append(this.filter_box),this.filter_button=jQuery("<button/>",{type:"button","class":"btn btn-default"}).append(Sao.i18n.gettext("Filters")),this.filter_button.click(this.search_box.bind(this)),this.search_entry=jQuery("<input/>",{"class":"form-control",placeholder:Sao.i18n.gettext("Search")}),this.search_list=jQuery("<datalist/>"),this.search_list.uniqueId(),this.search_entry.attr("list",this.search_list.attr("id")),this.search_entry.keypress(this.key_press.bind(this)),this.search_entry.on("input",this.update.bind(this));var c=jQuery("<button/>",{type:"submit","class":"btn btn-default","aria-label":Sao.i18n.gettext("Search")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-search"}));this.but_bookmark=jQuery("<button/>",{type:"button","class":"btn btn-default dropdown-toggle","data-toggle":"dropdown","aria-expanded":!1,"aria-label":Sao.i18n.gettext("Bookmarks"),id:"bookmarks"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-bookmark","aria-hidden":!0}));var d=jQuery("<ul/>",{"class":"dropdown-menu",role:"menu","aria-labelledby":"bookmarks"});if(this.but_bookmark.click(function(){d.children().remove();for(var a=this.bookmarks(),b=0;b<a.length;b++){var c=a[b][1],e=a[b][2];jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{role:"menuitem",href:"#",tabindex:-1}).append(c).click(e,this.bookmark_activate.bind(this))).appendTo(d)}}.bind(this)),this.but_star=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon","aria-hidden":!0})).click(this.star_click.bind(this)),this.set_star(),jQuery("<div/>",{"class":"input-group"}).append(jQuery("<span/>",{"class":"input-group-btn"}).append(this.filter_button)).append(this.search_entry).append(this.search_list).append(jQuery("<span/>",{"class":"input-group-btn"}).append(c).append(this.but_star).append(this.but_bookmark).append(d)).appendTo(jQuery("<div/>",{"class":"col-sm-10 col-xs-12"}).appendTo(b)),this.but_prev=jQuery("<button/>",{type:"button","class":"btn btn-default","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-menu-left","aria-hidden":!0})),this.but_prev.click(this.search_prev.bind(this)),this.but_next=jQuery("<button/>",{type:"button","class":"btn btn-default","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-menu-right","aria-hidden":!0})),this.but_next.click(this.search_next.bind(this)),jQuery("<div/>",{"class":"btn-group",role:"group"}).append(this.but_prev).append(this.but_next).appendTo(jQuery("<div/>",{"class":"col-sm-2 pull-right"}).appendTo(b)),this.content_box=jQuery("<div/>",{"class":"content-box"}),jQuery.isEmptyObject(this.tab_domain))this.tab=null;else{this.tab=jQuery("<div/>",{"class":"tab-domain"}).appendTo(this.el);var e=jQuery("<ul/>",{"class":"nav nav-tabs",role:"tablist"}).appendTo(this.tab);jQuery("<div/>",{"class":"tab-content"}).appendTo(this.tab);this.tab_domain.forEach(function(a,b){var c=a[0],d=jQuery("<span/>",{"class":"badge"});jQuery("<li/>",{role:"presentation",id:"nav-"+b}).append(jQuery("<a/>",{"aria-controls":b,role:"tab","data-toggle":"tab",href:"#"+b}).append(c+" ").append(d)).appendTo(e);this.tab_counter.push(d)}.bind(this)),e.find("a:first").tab("show");var f=this;e.find("a").click(function(a){a.preventDefault(),jQuery(this).tab("show"),f.do_search(),f.screen.count_tab_domain()})}this.el.append(this.content_box)},set_text:function(a){this.search_entry.val(a),this.bookmark_match()},update:function(){var a=this.screen.domain_parser().completion(this.get_text());this.search_list.children().remove(),a.forEach(function(a){jQuery("<option/>",{value:a.trim()}).appendTo(this.search_list)},this)},set_star:function(a){var b=this.but_star.children("span.glyphicon");a?(b.removeClass("glyphicon-star-empty"),b.addClass("glyphicon-star"),this.but_star.attr("aria-label",Sao.i18n.gettext("Remove this bookmark"))):(b.removeClass("glyphicon-star"),b.addClass("glyphicon-star-empty"),this.but_star.attr("aria-label",Sao.i18n.gettext("Bookmark this filter")))},get_star:function(){var a=this.but_star.children("span.glyphicon");return a.hasClass("glyphicon-star")},star_click:function(){var a=this.get_star(),b=this.screen.model_name,c=function(){this.bookmark_match(),this.but_bookmark.prop("disabled",jQuery.isEmptyObject(this.bookmarks()))}.bind(this);if(a){var d=this.bookmark_match();Sao.common.VIEW_SEARCH.remove(b,d).then(function(){c()})}else{var e=this.get_text();if(!e)return;Sao.common.ask.run(Sao.i18n.gettext("Bookmark Name:")).then(function(a){if(a){var d=this.screen.domain_parser().parse(e);Sao.common.VIEW_SEARCH.add(b,a,d).then(function(){c()}),this.set_text(this.screen.domain_parser().string(d))}}.bind(this))}},bookmarks:function(){
+var a=Sao.common.VIEW_SEARCH.get(this.screen.model_name);return a.filter(function(a){return this.screen.domain_parser().stringable(a[2])}.bind(this))},bookmark_activate:function(a){var b=a.data;this.set_text(this.screen.domain_parser().string(b)),this.do_search()},bookmark_match:function(){var a=this.get_text();if(a){var b=this.screen.domain_parser().parse(a);this.but_star.prop("disabled",!a);for(var c=(this.get_star(),this.bookmarks()),d=0;d<c.length;d++){var e=c[d][0],f=(c[d][1],c[d][2]),g=this.screen.domain_parser().string(f);if(g===a||Sao.common.compare(f,b))return this.set_star(!0),e}}this.set_star(!1)},search_prev:function(){this.screen.search_prev(this.get_text())},search_next:function(){this.screen.search_next(this.get_text())},get_tab_domain:function(){if(!this.tab)return[];var a=this.tab.find("li").index(this.tab.find("li.active"));return this.tab_domain[a][1]},set_tab_counter:function(a,b){if(!jQuery.isEmptyObject(this.tab_counter)&&this.tab&&(void 0!==b&&null!==b||(b=this.tab.find("li").index(this.tab.find("li.active"))),!(0>b))){var c=this.tab_counter[b];if(c.data("toggle","tooltip"),null===a)c.attr("title",""),c.text("");else{c.attr("title",a);var d=a;a>99&&(d="99+"),c.text(d)}c.tooltip()}},do_search:function(){return this.screen.search_filter(this.get_text())},key_press:function(a){window.setTimeout(function(){this.bookmark_match()}.bind(this))},set_screen:function(a){this.screen=a,this.but_bookmark.prop("disabled",jQuery.isEmptyObject(this.bookmarks())),this.bookmark_match()},show_filter:function(){this.filter_box.show(),this.tab&&this.tab.show()},hide_filter:function(){this.filter_box.hide(),this.tab&&this.tab.hide()},set:function(a){this.alternate_view?(this.alternate_viewport.children().detach(),this.alternate_viewport.append(a)):(this.content_box.children().detach(),this.content_box.append(a))},get_text:function(){return this.search_entry.val()},search_box:function(){var a=this.screen.domain_parser(),b=function(){this.search_modal.modal("hide");for(var b="",c=a.quote.bind(a),d=0;d<this.search_form.fields.length;d++){var e,f=this.search_form.fields[d][0],g=this.search_form.fields[d][1];switch(g.type){case"selection":case"date":case"datetime":case"time":e=g.get_value(c);break;default:e=c(g.val())}e&&(b+=c(f)+": "+e+" ")}this.set_text(b),this.do_search().then(function(){this.last_search_text=this.get_text()}.bind(this))}.bind(this);if(!this.search_modal){var c=new Sao.Dialog(Sao.i18n.gettext("Filters"),"","lg");this.search_modal=c.modal,this.search_form=c.content,this.search_form.addClass("form-horizontal"),this.search_form.submit(function(a){b(),a.preventDefault()});var d,e=[];for(var f in a.fields)d=a.fields[f],(d.searchable||void 0===d.searchable)&&e.push(d);var g=function(a){return function(b){jQuery("<option/>",{value:b,text:b}).appendTo(a)}},h="filter-"+this.screen.model_name+"-";this.search_form.fields=[];for(var i=0;i<e.length;i++){d=e[i];var j,k,l=jQuery("<div/>",{"class":"form-group form-group-sm"}).append(jQuery("<label/>",{"class":"col-sm-4 control-label","for":h+d.name,text:d.string})).appendTo(c.body);switch(d.type){case"boolean":k=j=jQuery("<select/>",{"class":"form-control input-sm",id:h+d.name}),["",Sao.i18n.gettext("True"),Sao.i18n.gettext("False")].forEach(g(j));break;case"selection":k=new Sao.ScreenContainer.Selection(d.selection,h+d.name),j=k.el;break;case"date":case"datetime":case"time":var m,n=Sao.common.date_format();if("date"==d.type)m=n;else{var o=new Sao.PYSON.Decoder({}).decode(d.format);o=Sao.common.moment_format(o),"time"==d.type?m=o:"datetime"==d.type&&(m=n+" "+o)}k=new Sao.ScreenContainer.DateTimes(m,h+d.name),j=k.el;break;default:k=j=jQuery("<input/>",{"class":"form-control input-sm",type:"text",placeholder:d.string,id:h+d.name})}jQuery("<div/>",{"class":"col-sm-8"}).append(j).appendTo(l),this.search_form.fields.push([d.string,k,j])}jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Find")).click(b).appendTo(c.footer)}if(this.search_modal.modal("show"),this.last_search_text.trim()!==this.get_text().trim()){for(var p=0;p<this.search_form.fields.length;p++){var q=this.search_form.fields[p][1];switch(q.type){case"selection":q.set_value([]);break;case"date":case"datetime":case"time":q.set_value(null,null);break;default:q.val("")}}this.search_form.fields[0][2].focus()}}}),Sao.ScreenContainer.DateTimes=Sao.class_(Object,{type:"date",init:function(a,b){this.el=jQuery("<div/>",{"class":"row",id:b});var c=function(c){var d=jQuery("<div/>",{"class":"input-group input-group-sm"});return jQuery("<input/>",{"class":"form-control input-sm",type:"text",placeholder:c,id:b+"-from"}).appendTo(d),jQuery("<span/>",{"class":"input-group-btn"}).append(jQuery("<button/>",{"class":"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-calendar"}))).appendTo(d),d.datetimepicker({locale:moment.locale()}),d.data("DateTimePicker").format(a),d};this.from=c("From").appendTo(jQuery("<div/>",{"class":"col-md-5"}).appendTo(this.el)),jQuery("<p/>",{"class":"text-center"}).append("..").appendTo(jQuery("<div/>",{"class":"col-md-1"}).appendTo(this.el)),this.to=c("To").appendTo(jQuery("<div/>",{"class":"col-md-5"}).appendTo(this.el))},_get_value:function(a){return a.find("input").val()},get_value:function(a){var b=this._get_value(this.from),c=this._get_value(this.to);return b&&c?b!==c?a(b)+".."+a(c):a(b):b?">="+a(b):c?"<="+a(c):void 0},set_value:function(a,b){this.from.data("DateTimePicker").date(a),this.to.data("DateTimePicker").date(b)}}),Sao.ScreenContainer.Selection=Sao.class_(Object,{type:"selection",init:function(a,b){this.el=jQuery("<select/>",{"class":"form-control input-sm",multiple:!0,id:b}),a.forEach(function(a){jQuery("<option/>",{value:a[1],text:a[1]}).appendTo(this.el)}.bind(this))},get_value:function(a){var b=this.el.val();return b&&(b=jQuery.map(b,a).reduce(function(a,b){return a&&(a+=";"),a+b})),b},set_value:function(a){this.el.val(a)}}),Sao.Screen=Sao.class_(Object,{init:function(a,b){this.model_name=a,this.model=new Sao.Model(a,b),this.attributes=jQuery.extend({},b),this.view_ids=jQuery.extend([],b.view_ids),this.view_to_load=jQuery.extend([],b.mode||["tree","form"]),this.views=[],this.views_preload=b.views_preload||{},this.exclude_field=b.exclude_field,this.context=b.context||{},this.new_group(),this.current_view=null,this.current_record=null,this.domain=b.domain||[],this.context_domain=b.context_domain,this.size_limit=null,void 0===this.attributes.limit?this.limit=Sao.config.limit:this.limit=b.limit,this.offset=0,this.order=this.default_order=b.order;var c=Sao.common.MODELACCESS.get(a);c.write||c.create||(this.attributes.readonly=!0),this.search_count=0,this.screen_container=new Sao.ScreenContainer(b.tab_domain),this.context_screen=null,b.context_model&&(this.context_screen=new Sao.Screen(b.context_model,{mode:["form"],context:b.context}),this.context_screen_prm=this.context_screen.switch_view().then(function(){return jQuery("<div/>",{"class":"row"}).append(jQuery("<div/>",{"class":"col-md-12"}).append(this.context_screen.screen_container.el)).prependTo(this.screen_container.filter_box),this.context_screen.new_(!1).then(function(a){return a.default_get()})}.bind(this))),b.row_activate?this.row_activate=b.row_activate:this.row_activate=this.default_row_activate,this.tree_states={},this.tree_states_done=[],this.fields_view_tree={},this._domain_parser={},this.pre_validate=!1,this.tab=null,this.count_tab_domain()},load_next_view:function(){if(!jQuery.isEmptyObject(this.view_to_load)){var a;jQuery.isEmptyObject(this.view_ids)||(a=this.view_ids.shift());var b=this.view_to_load.shift();return this.add_view_id(a,b)}return jQuery.when()},add_view_id:function(a,b){var c;if(a&&this.views_preload[String(a)])c=this.views_preload[String(a)];else{if(a||!this.views_preload[b]){var d=this.model.execute("fields_view_get",[a,b],this.context);return d.pipe(this.add_view.bind(this))}c=this.views_preload[b]}return this.add_view(c),jQuery.when()},add_view:function(a){var b=a.arch,c=a.fields,d=a.view_id,e=jQuery(jQuery.parseXML(b));"tree"==e.children().prop("tagName")&&(this.fields_view_tree[d]=a);var f="eager";"form"==e.children().prop("tagName")&&(f="lazy");for(var g in c)g in this.model.fields&&"eager"!=f?c[g].loading=this.model.fields[g].description.loading:c[g].loading=f;this.group.add_fields(c);var h=Sao.View.parse(this,e,a.field_childs);return h.view_id=d,this.views.push(h),h},number_of_views:function(){return this.views.length+this.view_to_load.length},switch_view:function(a){if(this.current_view){this.current_view.set_value(),this.current_record&&!~this.current_record.group.indexOf(this.current_record)&&(this.current_record=null);var b=this.current_view.get_fields();if(this.current_record&&this.current_view.editable&&!this.current_record.validate(b,!1,!1,!0))return this.screen_container.set(this.current_view.el),this.current_view.display().done(function(){this.set_cursor()}.bind(this))}var c=function(){if(!a||!this.current_view||this.current_view.view_type!=a)for(var b=function(){return this.current_view=this.views[this.views.length-1],c()}.bind(this),d=0;d<this.number_of_views();d++){if(this.view_to_load.length)return a||(a=this.view_to_load[0]),this.load_next_view().then(b);if(this.current_view=this.views[(this.views.indexOf(this.current_view)+1)%this.views.length],!a)break;if(this.current_view.view_type==a)break}return this.screen_container.set(this.current_view.el),this.display().done(function(){this.set_cursor()}.bind(this))}.bind(this);return c()},search_filter:function(a,b){if(b=b||!1,this.context_screen){if("pending"==this.context_screen_prm.state())return this.context_screen_prm.then(function(){return this.search_filter(a)}.bind(this));var c=this.context_screen.current_record;if(c&&!c.validate(null,!1,null,!0))return this.new_group([]),this.context_screen.display(!0),jQuery.when();this.context=jQuery.extend({},this.context,this.context_screen.get_on_change_value())}var d=this.search_domain(a,!0);if(this.context_domain){var e=new Sao.PYSON.Decoder(this.context);d=["AND",d,e.decode(this.context_domain)]}var f=this.screen_container.get_tab_domain();jQuery.isEmptyObject(f)||(d=["AND",d,f]);var g=this.model.find(d,this.offset,this.limit,this.order,this.context),h=jQuery.when(this.search_count);return b||(h=this.model.execute("search_count",[d],this.context)),h.done(function(a){this.search_count=a}.bind(this)),g.done(this.set_group.bind(this)),g.done(this.display.bind(this)),jQuery.when(g,h).done(function(a,b){this.screen_container.but_next.prop("disabled",!(void 0!==this.limit&&a.length==this.limit&&b>this.limit+this.offset))}.bind(this)),this.screen_container.but_prev.prop("disabled",this.offset<=0),this.count_tab_domain(),g},search_domain:function(a,b){b=b||!1;var c=[];if(!this.group.parent&&this.domain_parser()){var d=this.domain_parser();c=a||""===a?d.parse(a):this.attributes.search_value,b&&this.screen_container.set_text(d.string(c))}else c=[["id","in",this.group.map(function(a){return a.id})]];return jQuery.isEmptyObject(c)?c=this.attributes.domain||[]:jQuery.isEmptyObject(this.attributes.domain)||(c=["AND",c,this.attributes.domain]),this.current_view&&"calendar"==this.current_view.view_type&&(c=jQuery.isEmptyObject(c)?this.current_view.current_domain():["AND",c,this.current_view.current_domain()]),c},count_tab_domain:function(){var a=this.search_domain(this.screen_container.get_text());this.screen_container.tab_domain.forEach(function(b,c){if(b[2]){var d=["AND",b[1],a];this.screen_container.set_tab_counter(null,c),this.group.model.execute("search_count",[d],this.context).then(function(a){this.screen_container.set_tab_counter(a,c)}.bind(this))}}.bind(this))},set_group:function(a){var b={};if(this.group){for(var c in this.group.model.fields)this.group.model.fields.hasOwnProperty(c)&&(b[c]=this.group.model.fields[c].description);this.group.screens.splice(this.group.screens.indexOf(this),1),jQuery.extend(a.on_write,this.group.on_write),a.on_write=a.on_write.filter(function(a,b,c){return b==c.indexOf(a)}),this.group.parent&&!a.parent&&(a.parent=this.group.parent)}a.screens.push(this),this.tree_states_done=[],this.group=a,this.model=a.model,a&&a.length?this.set_current_record(a[0]):this.set_current_record(null),this.group.add_fields(b)},new_group:function(a){var b=new Sao.Group(this.model,this.context,[]);b.set_readonly(this.attributes.readonly||!1),a&&b.load(a),this.set_group(b)},set_current_record:function(a){this.current_record=a,this.tab&&(a?(a.get_attachment_count().always(this.tab.attachment_count.bind(this.tab)),a.get_unread_note().always(this.tab.update_unread_note.bind(this.tab))):(this.tab.attachment_count(0),this.tab.update_unread_note(0)),this.tab.record_message())},display:function(a){var b=[];if(this.current_record&&~this.current_record.group.indexOf(this.current_record)||(this.group&&this.group.length&&"calendar"!=this.current_view.view_type?this.current_record=this.group[0]:this.current_record=null),this.views){var c=this.search_active(~["tree","graph","calendar"].indexOf(this.current_view.view_type));b.push(c);for(var d=0;d<this.views.length;d++)this.views[d]&&b.push(this.views[d].display())}return jQuery.when.apply(jQuery,b).then(function(){this.set_tree_state(),this.set_current_record(this.current_record),a&&this.set_cursor(!1,!1)}.bind(this))},display_next:function(){var a=this.current_view;if(a.set_value(),this.set_cursor(!1,!1),~["tree","form"].indexOf(a.view_type)&&this.current_record&&this.current_record.group){for(var b=this.current_record.group,c=this.current_record;b;){var d=b.indexOf(c);if(d<b.length-1){c=b[d+1];break}if(!b.parent||c.group.model_name!=b.parent.group.model_name)break;c=b.parent,b=b.parent.group}this.set_current_record(c)}else this.set_current_record(this.group[0]);this.set_cursor(!1,!1),a.display()},display_previous:function(){var a=this.current_view;if(a.set_value(),this.set_cursor(!1,!1),~["tree","form"].indexOf(a.view_type)&&this.current_record&&this.current_record.group){for(var b=this.current_record.group,c=this.current_record;b;){var d=b.indexOf(c);if(d>0){c=b[d-1];break}if(!b.parent||c.group.model_name!=b.parent.group.model_name)break;c=b.parent,b=b.parent.group}this.set_current_record(c)}else this.set_current_record(this.group[0]);this.set_cursor(!1,!1),a.display()},default_row_activate:function(){"tree"==this.current_view.view_type&&1==this.current_view.attributes.keyword_open?Sao.Action.exec_keyword("tree_open",{model:this.model_name,id:this.get_id(),ids:[this.get_id()]},jQuery.extend({},this.context),!1):this.modified()||this.switch_view("form")},get_id:function(){return this.current_record?this.current_record.id:void 0},new_:function(a,b){var c=this.current_view;void 0===a&&(a=!0);var d=jQuery.when();if("calendar"==this.current_view.view_type){var e=this.current_view.date;d=this.switch_view("form")}return this.current_view&&("tree"==this.current_view.view_type&&!this.current_view.editable||"graph"==this.current_view.view_type)&&(d=this.switch_view("form")),d.then(function(){var d;d=this.current_record?this.current_record.group:this.group;var f,g=d.new_(!1,void 0,b);return f=a?g.default_get(b):jQuery.when(),f.then(function(){return d.add(g,this.new_model_position()),this.set_current_record(g),"calendar"==c.view_type&&c.set_default_date(g,e),this.display().done(function(){this.set_cursor(!0,!0)}.bind(this)),g}.bind(this))}.bind(this))},new_model_position:function(){var a=-1;return this.current_view&&"tree"==this.current_view.view_type&&"top"==this.current_view.attributes.editable&&(a=0),a},set_on_write:function(a){a&&(~this.group.on_write.indexOf(a)||this.group.on_write.push(a))},cancel_current:function(){var a=[];return this.current_record&&(this.current_record.cancel(),this.current_record.id<0&&a.push(this.remove(!1,!1,!1,[this.current_record]))),jQuery.when.apply(jQuery,a)},save_current:function(){var a=this.current_record;if(!a){if("tree"!=this.current_view.view_type||!this.group||!this.group.length)return jQuery.when();this.set_current_record(this.group[0])}this.current_view.set_value();var b=this.current_view.get_fields(),c=a.get_path(this.group),d=jQuery.Deferred();"tree"==this.current_view.view_type?d=this.group.save().then(function(){return this.current_record}.bind(this)):a.validate(b).then(function(b){b?a.save().then(function(){d.resolve(a)},d.reject):(this.current_view.display().done(this.set_cursor.bind(this)),d.reject())}.bind(this));var e=jQuery.Deferred();return d.then(function(a){return c&&a&&a.id&&c.splice(-1,1,[c[c.length-1][0],a.id]),this.group.get_by_path(c).then(function(a){this.set_current_record(a)}.bind(this))}.bind(this)).then(function(){this.display().always(e.resolve)}.bind(this),function(){this.display().always(e.reject)}.bind(this)),e.promise()},set_cursor:function(a,b){this.current_view&&~["tree","form"].indexOf(this.current_view.view_type)&&this.current_view.set_cursor(a,b)},modified:function(){var a=function(a){return a.has_changed()||a.id<0};if("tree"!=this.current_view.view_type){if(this.current_record&&a(this.current_record))return!0}else if(this.group.some(a))return!0;return!1},unremove:function(){var a=this.current_view.selected_records();a.forEach(function(a){a.group.unremove(a)})},remove:function(a,b,c,d){var e=jQuery.when();if(d=d||this.current_view.selected_records(),jQuery.isEmptyObject(d))return e;a&&(e=this.model.delete_(d));var f=d[0],g=f.group,h=g.indexOf(f),i=f.get_path(this.group);return e.then(function(){d.forEach(function(a){a.group.remove(a,b,!0,c)});var e=[];if(a&&d.forEach(function(a){a.group.parent&&e.push(a.group.parent.save(!1)),~a.group.record_deleted.indexOf(a)&&a.group.record_deleted.splice(a.group.record_deleted.indexOf(a),1),~a.group.record_removed.indexOf(a)&&a.group.record_removed.splice(a.group.record_removed.indexOf(a),1)}),h>0){var f=g[h-1];i.splice(-1,1,[i[i.length-1][0],f.id])}else i.splice(-1,1);return jQuery.isEmptyObject(i)?this.group.length&&this.set_current_record(this.group[0]):e.push(this.group.get_by_path(i).then(function(a){this.set_current_record(a)}.bind(this))),jQuery.when.apply(jQuery,e).then(function(){this.display().done(function(){this.set_cursor()}.bind(this))}.bind(this))}.bind(this))},copy:function(){var a=jQuery.Deferred(),b=this.current_view.selected_records();return this.model.copy(b,this.context).then(function(b){this.group.load(b),jQuery.isEmptyObject(b)||this.set_current_record(this.group.get(b[0])),this.display().always(a.resolve)}.bind(this),a.reject),a.promise()},search_active:function(a){return a&&!this.group.parent?(this.screen_container.set_screen(this),this.screen_container.show_filter()):this.screen_container.hide_filter(),jQuery.when()},domain_parser:function(){var a,b,c;if(a=this.current_view?this.current_view.view_id:null,a in this._domain_parser)return this._domain_parser[a];a in this.fields_view_tree?b=this.fields_view_tree[a]:(this.model.execute("fields_view_get",[!1,"tree"],this.context).then(function(b){this.fields_view_tree[a]=b,c.update_fields(b.fields)}.bind(this)),b={},b.fields={});var d=jQuery.extend({},b.fields),e=function(a){return function(b){a.selection=b}};for(var f in d){var g=d[f];"selection"!=g.type&&"reference"!=g.type||g.selection instanceof Array||this.get_selection(g).then(e(g))}if("arch"in b){var h=jQuery(jQuery.parseXML(b.arch)),i=h.find("tree").children().filter(function(a,b){return"field"==b.tagName}).map(function(a,b){return b.getAttribute("name")}),j={};i.each(function(a,b){j[b]=d[b]}),d=j}[["id",Sao.i18n.gettext("ID"),"integer"],["create_uid",Sao.i18n.gettext("Creation User"),"many2one"],["create_date",Sao.i18n.gettext("Creation Date"),"datetime"],["write_uid",Sao.i18n.gettext("Modification User"),"many2one"],["write_date",Sao.i18n.gettext("Modification Date"),"datetime"]].forEach(function(a){var b=a[0],c=a[1],e=a[2];b in d||(d[b]={string:c,name:b,type:e},"datetime"==e&&(d[b].format='"%H:%M:%S"'))});var k=jQuery.extend({},this.model.session.context,this.context);return c=new Sao.common.DomainParser(d,k),this._domain_parser[a]=c,c},get_selection:function(a){var b,c=a.selection_change_with;if(jQuery.isEmptyObject(c))b=this.model.execute(a.selection,[]);else{var d={};c.forEach(function(a){d[a]=null}),b=this.model.execute(a.selection,[d])}return b.then(function(a){return a.sort(function(a,b){return a[1].localeCompare(b[1])})})},search_prev:function(a){this.limit&&(this.offset-=this.limit),this.search_filter(a)},search_next:function(a){this.limit&&(this.offset+=this.limit),this.search_filter(a)},invalid_message:function(a){a||(a=this.current_record);var b={};for(var c in a.model.fields){var d=a.model.fields[c];b[c]=d.description}var e=new Sao.common.DomainParser(b),f=[],g=a.invalid_fields();return Object.keys(g).sort().forEach(function(b){var c=g[b],d=a.model.fields[b].description.string;"required"==c||Sao.common.compare(c,[[b,"!=",null]])?f.push(Sao.i18n.gettext('"%1" is required',d)):"domain"==c?f.push(Sao.i18n.gettext('"%1" is not valid according to its domain',d)):"children"==c?f.push(Sao.i18n.gettext('The values of "%1" are not valid',d)):e.stringable(c)?f.push(e.string(c)):f.push(Sao.i18n.gettext('"%1" is not valid according to its domain'),d)}),f.length>5&&(f.splice(5,f.length),f.push("...")),f.join("\n")},get:function(){return this.current_record?(this.current_view.set_value(),this.current_record.get()):null},get_on_change_value:function(){return this.current_record?(this.current_view.set_value(),this.current_record.get_on_change_value()):null},reload:function(a,b){this.group.reload(a),b&&this.group.written(a),this.group.parent&&this.group.parent.root_parent().reload(),this.display()},get_buttons:function(){var a=this.current_view.selected_records();if(jQuery.isEmptyObject(a))return[];var b=this.current_view.get_buttons();return a.forEach(function(a){b=b.filter(function(b){if(a.group.get_readonly()||a.readonly())return!1;if("instance"===b.attributes.type)return!1;var c=a.expr_eval(b.attributes.states||{});return!(c.invisible||c.readonly)})}),b},button:function(a){var b,c=function(a){this.reload(b,!0),"string"==typeof a?this.client_action(a):a&&Sao.Action.execute(a,{model:this.model_name,id:this.current_record.id,ids:b},null,this.context,!0)},d=this.current_view.selected_records();this.current_view.set_value();for(var e=this.current_view.get_fields(),f=[],g=function(a){return function(){this.display(!0),a.validate(e)}.bind(this)}.bind(this),h=0;h<d.length;h++){var i=d[h],j=i.expr_eval(a.states||{}).pre_validate||[];f.push(i.validate(e,!1,j))}jQuery.when.apply(jQuery,f).then(function(){for(var e,f=0;f<d.length;f++){e=d[f];var h=arguments[f];if(!h)return void Sao.common.warning.run(this.invalid_message(e),Sao.i18n.gettext("Pre-validation")).then(g(e))}var i=jQuery.when();void 0!==a.confirm&&(i=Sao.common.sur.run(a.confirm)),i.then(function(){var e=this.current_record;if("instance"===a.type){var g=e.expr_eval(a.change||[]),h=e._get_on_change_args(g);e.model.execute(a.name,[h],this.context).then(function(a){e.set_on_change(a),e.group.root_group().screens.forEach(function(a){a.display()})})}else e.save(!1).done(function(){var g=jQuery.extend({},this.context);for(g._timestamp={},b=[],f=0;f<d.length;f++)e=d[f],jQuery.extend(g._timestamp,e.get_timestamp()),b.push(e.id);e.model.execute(a.name,[b],g).then(c.bind(this))}.bind(this))}.bind(this))}.bind(this))},client_action:function(a){var b=Sao.common.MODELACCESS.get(this.model_name);if("new"==a)b.create&&this.new_();else if("delete"==a)b["delete"]&&this.remove(!this.group.parent,!1,!this.group.parent);else if("remove"==a)b.write&&b.read&&this.group.parent&&this.remove(!1,!0,!1);else if("copy"==a)b.create&&this.copy();else if("next"==a)this.display_next();else if("previous"==a)this.display_previous();else if("close"==a)Sao.Tab.close_current();else if(a.startsWith("switch")){var c=a.split(" ")[1];this.switch_view(c)}else"reload"==a?~["tree","graph","calendar"].indexOf(this.current_view.view_type)&&!this.group.parent&&this.search_filter():"reload menu"==a?Sao.get_preferences().then(function(a){Sao.menu(a)}):"reload context"==a&&Sao.get_preferences()},save_tree_state:function(a){var b,c=[];a=void 0===a?!0:a;var d,e,f,g,h,i,j=this.group.parent?this.group.parent.id:null,k=this.group.parent?this.group.parent._timestamp:null;for(d=0,e=this.views.length;e>d;d++)if(f=this.views[d],"form"==f.view_type){for(var l in f.widgets)if(f.widgets.hasOwnProperty(l))for(g=f.widgets[l],h=0,i=g.length;i>h;h++)g[h].screen&&(b=g[h].screen.save_tree_state(a),c.push(b));1==this.views.length&&this.current_record&&(j in this.tree_states||(this.tree_states[j]={}),this.tree_states[j][f.children_field||null]=[k,[],[[this.current_record.id]]])}else if("tree"==f.view_type){var m=f.get_expanded_paths(),n=f.get_selected_paths();if(j in this.tree_states||(this.tree_states[j]={}),this.tree_states[j][f.children_field||null]=[k,m,n],a&&f.attributes.tree_state){var o=new Sao.Model("ir.ui.view_tree_state");b=o.execute("set",[this.model_name,this.get_tree_domain(j),f.children_field,JSON.stringify(m),JSON.stringify(n)],{}),c.push(b)}}return jQuery.when.apply(jQuery,c)},get_tree_domain:function(a){var b;return b=a?(this.domain||[]).concat([[this.exclude_field,"=",a]]):this.domain,JSON.stringify(Sao.rpc.prepareObject(b))},set_tree_state:function(){var a,b,c,d,e,f=this.current_view;~["tree","form"].indexOf(f.view_type)&&(~this.tree_states_done.indexOf(f)||("form"!=f.view_type||jQuery.isEmptyObject(this.tree_states_done))&&("tree"!=f.view_type||f.attributes.tree_state)&&(a=this.group.parent?this.group.parent.id:null,0>a||(b=parent?parent._timestamp:null,a in this.tree_states||(this.tree_states[a]={}),c=this.tree_states[a][f.children_field||null],c&&b!=c[0]&&(c=void 0),void 0===c?(e=new Sao.Model("ir.ui.view_tree_state"),d=e.execute("get",[this.model_name,this.get_tree_domain(a),f.children_field],{}).then(function(a){return[b,JSON.parse(a[0]),JSON.parse(a[1])]})):d=jQuery.when(c),d.done(function(b){var c,d,e;if(this.tree_states[a][f.children_field||null]=b,c=b[1],d=b[2],"tree"==f.view_type)f.display(d,c);else if(!jQuery.isEmptyObject(d)){for(var g=0;g<d[0].length;g++){var h=this.group.get(d[0][g]);if(!h)break;e=h}e&&e!=this.current_record&&(this.set_current_record(e),f.display())}}.bind(this)),this.tree_states_done.push(f))))}})}(),function(){"use strict";Sao.View=Sao.class_(Object,{init:function(a,b){this.screen=a,this.view_type=null,this.el=null,this.view_id=null,this.fields={};var c=b.children()[0].attributes;this.attributes={};for(var d=0,e=c.length;e>d;d++){var f=c[d];this.attributes[f.name]=f.value}a.set_on_write(this.attributes.on_write)},set_value:function(){},get_fields:function(){return Object.keys(this.fields)},selected_records:function(){return[]},get_buttons:function(){return[]}}),Sao.View.idpath2path=function(a,b){var c,d=[];if(!b)return[];for(var e=0,f=a.rows.length;f>e;e++)if(a.rows[e].record.id==b[0]){d.push(e),c=Sao.View.idpath2path(a.rows[e],b.slice(1,b.length)),d=d.concat(c);break}return d},Sao.View.parse=function(a,b,c){switch(b.children().prop("tagName")){case"tree":return new Sao.View.Tree(a,b,c);case"form":return new Sao.View.Form(a,b);case"graph":return new Sao.View.Graph(a,b);case"calendar":return new Sao.View.Calendar(a,b)}},Sao.View.resize=function(a){a||(a=jQuery(document)),a.find(".treeview").each(function(){var a=jQuery(this);a.css("width","100%"),a.children(".tree").css("table-layout","fixed")}),a.find(".treeview").each(function(){var a=jQuery(this);a.width()&&(a.css("width",a.width()),a.children(".tree").css("table-layout","auto"))})},jQuery(window).resize(function(){Sao.View.resize()})}(),function(){"use strict";Sao.View.Form=Sao.class_(Sao.View,{editable:!0,init:function(a,b){Sao.View.Form._super.init.call(this,a,b),this.view_type="form",this.el=jQuery("<div/>",{"class":"form"}),this.widgets={},this.widget_id=0,this.state_widgets=[],this.containers=[],this.notebooks=[];var c=b.children()[0],d=this.parse(a.model,c);this.el.append(d.el)},_parse_node:function(a,b,c,d,e){var f;switch(b.tagName){case"image":this._parse_image(a,b,c,d);break;case"separator":this._parse_separator(a,b,c,d);break;case"label":f=this._parse_label(a,b,c,d),d.name&&f&&(e[d.name]=f);break;case"newline":c.add_row();break;case"button":this._parse_button(b,c,d);break;case"notebook":this._parse_notebook(a,b,c,d);break;case"page":this._parse_page(a,b,c,d);break;case"field":if(f=this._parse_field(a,b,c,d),d.name in e&&f&&f.labelled){var g=e[d.name];g.el.uniqueId(),f.labelled.uniqueId(),f.labelled.attr("aria-labelledby",g.el.attr("id")),g.el.attr("for",f.labelled.attr("id"))}break;case"group":this._parse_group(a,b,c,d);break;case"hpaned":this._parse_paned(a,b,c,d,"horizontal");break;case"vpaned":this._parse_paned(a,b,c,d,"vertical");break;case"child":this._parse_child(a,b,c,d)}},parse:function(a,b,c){void 0===c&&(c=new Sao.View.Form.Container(Number(b.getAttribute("col")||4)),this.containers.push(c));var d={},e=function(b,e){for(var f={},g=0,h=e.attributes.length;h>g;g++){var i=e.attributes[g];f[i.name]=i.value}["readonly","invisible"].forEach(function(a){f[a]&&(f[a]=1==f[a])}),["yexpand","yfill","xexpand","xfill","colspan"].forEach(function(a){f[a]&&(f[a]=Number(f[a]))}),this._parse_node(a,e,c,f,d)};return jQuery(b).children().each(e.bind(this)),c},_parse_image:function(a,b,c,d){var e=new Sao.View.Form.Image_(d);this.state_widgets.push(e),c.add(d,e)},_parse_separator:function(a,b,c,d){var e=d.name,f=d.string;e in a.fields&&(!d.states&&e in a.fields&&(d.states=a.fields[e].description.states),f||(f=a.fields[e].description.string));var g=new Sao.View.Form.Separator(f,d);this.state_widgets.push(g),c.add(d,g)},_parse_label:function(a,b,c,d){var e=d.name,f=d.string;if(void 0===d.xexpand&&(d.xexpand=0),e in a.fields){if(e==this.screen.exclude_field)return void c.add(d);!d.states&&e in a.fields&&(d.states=a.fields[e].description.states),f||(f=a.fields[e].description.string+": "),void 0===d.xalign&&(d.xalign=1)}var g;return f&&(g=new Sao.View.Form.Label(f,d),this.state_widgets.push(g)),c.add(d,g),g},_parse_button:function(a,b,c){var d=new Sao.common.Button(c);this.state_widgets.push(d),b.add(c,d),d.el.click(d,this.button_clicked.bind(this))},_parse_notebook:function(a,b,c,d){void 0===d.colspan&&(d.colspan=4);var e=new Sao.View.Form.Notebook(d);this.notebooks.push(e),this.state_widgets.push(e),c.add(d,e),this.parse(a,b,e)},_parse_page:function(a,b,c,d){d.string;if(d.name in a.fields){var e=a.fields[d.name];if(d.name==this.screen.exclude_field)return;["states","string"].forEach(function(a){void 0===d[a]&&void 0!==e.description[a]&&(d[a]=e.description[a])})}var f=this.parse(a,b);f=new Sao.View.Form.Page(c.add(f.el,d.string),d),this.state_widgets.push(f)},_parse_field:function(a,b,c,d){var e=d.name;if(!(e in a.fields)||e==this.screen.exclude_field)return void c.add(d);d.widget||(d.widget=a.fields[e].description.type);var f=["relation","domain","selection","help","relation_field","string","views","add_remove","sort","context","size","filename","autocomplete","translate","create","delete","selection_change_with","schema_model"];for(var g in f){var h=f[g];h in a.fields[e].description&&null===b.getAttribute(h)&&(d[h]=a.fields[e].description[h])}var i=Sao.View.form_widget_get(d.widget);if(!i)return void c.add(d);var j=new i(e,a,d);return j.position=this.widget_id+=1,j.view=this,c.add(d,j),void 0===this.widgets[e]&&(this.widgets[e]=[]),this.widgets[e].push(j),this.fields[e]=!0,j},_parse_group:function(a,b,c,d){var e=new Sao.View.Form.Group(d);e.add(this.parse(a,b)),this.state_widgets.push(e),c.add(d,e)},_parse_paned:function(a,b,c,d,e){void 0===d.yexpand&&(d.yexpand=!0),void 0===d.yfill&&(d.yfill=!0);var f=new Sao.common.Paned(e);c.add(d,f),this.parse(a,b,f)},_parse_child:function(a,b,c,d){var e,f=this.parse(a,b);e=c.get_child1().children().length?c.get_child2():c.get_child1(),e.append(f.el)},get_buttons:function(){var a=[];for(var b in this.state_widgets){var c=this.state_widgets[b];c instanceof Sao.common.Button&&a.push(c)}return a},display:function(){var a,b,c=this.screen.current_record,d={};if(c){var e=[];for(b in c.model.fields)a=c.model.fields[b],
+e.push([b,a.description.loading||"eager"]);e.sort(function(a,b){return a[1].localeCompare(b[1])}),e.forEach(function(a){var b=a[0];d[b]=c.load(b)})}var f=function(a,b,c){var e=jQuery.when();c in d&&(e=d[c]),e.done(function(){b.set_state(a)})},g=function(a,b,c){return function(e){var f=jQuery.when();c in d&&(f=d[c]),f.done(function(){e.display(a,b)})}};for(b in this.widgets){var h=this.widgets[b];a=null,c&&(a=c.model.fields[b]),a&&f(c,a,b),h.forEach(g(c,a,b))}return jQuery.when.apply(jQuery,jQuery.map(d,function(a){return a})).done(function(){var a;for(a in this.state_widgets){var b=this.state_widgets[a];b.set_state(c)}for(a in this.containers){var d=this.containers[a];d.resize()}Sao.View.resize(this.el)}.bind(this))},set_value:function(){var a=this.screen.current_record;if(a){var b=function(b){b.set_value(a,this)};for(var c in this.widgets)if(c in a.model.fields){var d=this.widgets[c],e=a.model.fields[c];d.forEach(b,e)}}},button_clicked:function(a){var b=a.data;b.el.prop("disabled",!0);try{this.screen.button(b.attributes)}finally{b.el.prop("disabled",!1)}},selected_records:function(){return this.screen.current_record?[this.screen.current_record]:[]},set_cursor:function(a,b){var c,d,e,f,g,h,i,j,k,l,m=jQuery(document.activeElement),n=m.closest(this.el)>0;if(b||n){if(b)for(c=0;c<this.notebooks.length;c++)g=this.notebooks[c],g.set_current_page(0);this.attributes.cursor in this.widgets?f=Sao.common.find_focusable_child(this.widgets[this.attributes.cursor][0].el):(h=Sao.common.find_focusable_child(this.el),h&&h.focus())}var o=this.screen.current_record;if(o){var p=[],q=this.el.find(".has-error"),r=o.invalid_fields();for(d in r)for(i=this.widgets[d],c=0;c<q.length;c++)for(j=jQuery(q[c]),e=0;e<i.length;e++)if(j.closest(i[e].el).length>0){p.push(j);break}p.length>0&&(f=Sao.common.find_first_focus_widget(this.el,p))}if(f){for(c=0;c<this.notebooks.length;c++)for(g=this.notebooks[c],k=g.get_n_pages(),e=0;k>e;e++)if(h=g.get_nth_page(e),l=jQuery(f).closest(h).length>0){g.set_current_page(e);break}jQuery(f).find("input,select,textarea").focus()}}}),Sao.View.Form.Container=Sao.class_(Object,{init:function(a){void 0===a&&(a=4),0>a&&(a=0),this.col=a,this.el=jQuery("<table/>",{"class":"form-container responsive responsive-noheader"}),this.add_row()},add_row:function(){this.el.append(jQuery("<tr/>"))},rows:function(){return this.el.children().children("tr")},row:function(){return this.rows().last()},add:function(a,b){var c=a.colspan;void 0===c&&(c=1);var d=a.xfill;void 0===d&&(d=1);var e=a.xexpand;void 0===e&&(e=1);var f=this.row();if(this.col>0){var g=0;f.children().map(function(a,b){g+=Number(jQuery(b).attr("colspan")||1)}),g+c>this.col&&(this.add_row(),f=this.row())}var h;b&&(h=b.el);var i=jQuery("<td/>",{colspan:c,"class":b?b.class_||"":""}).append(h);f.append(i),b&&(a.yfill&&i.css("vertical-align","top"),void 0!==a.xalign&&i.css("text-align",a.xalign>=.5?"right":"left"),e&&(i.addClass("xexpand"),i.css("width","100%")),d&&(i.addClass("xfill"),e&&h.css("width","100%")),a.help&&(b.el.data("toggle","tooltip"),b.el.attr("title",a.help),b.el.tooltip()))},resize:function(){var a,b,c=this.rows().toArray(),d=[],e=this.col,f=!1,g=function(b){b=jQuery(b);var c=[];return a=0,b.children().map(function(){var b=jQuery(this),d=Math.min(Number(b.attr("colspan")),e);b.hasClass("xexpand")&&!jQuery.isEmptyObject(b.children())&&"none"!=b.children(":not(.tooltip)").css("display")&&c.push([b,a]),a+=d}),c};c.sort(function(a,b){if(a=g(a),b=g(b),a.length==b.length){var c=function(a,b){var c=b[0],d=Math.min(Number(c.attr("colspan")),e);return a+d};return a.reduce(c,0)-b.reduce(c,0)}return b.length-a.length}),c.forEach(function(c){c=jQuery(c);var h=g(c),i=100/h.length;h.forEach(function(c){var f=c[0];a=c[1];var g=Math.min(Number(f.attr("colspan")),e),h=0;for(b=0;g>b;b++)h+=d[a+b]||0;for(b=0;g>b;b++)if(h){if(h>i){var j=h-i;d[a+b]&&(d[a+b]-=j/(h/d[a+b]))}}else d[a+b]=i/g}),jQuery.isEmptyObject(h)||(f=!0)}),c.forEach(function(c){c=jQuery(c),a=0,c.children().map(function(){var c=jQuery(this),f=Math.min(Number(c.attr("colspan")),e);if(c.hasClass("xexpand")&&"none"!=c.children(":not(.tooltip)").css("display")){var g=0;for(b=0;f>b;b++)g+=d[a+b]||0;c.css("width",g+"%")}else c.css("width","");"none"==c.children().css("display")?c.css("visibility","collapse"):c.css("visibility","visible"),a+=f})}),f?this.el.css("width","100%"):this.el.css("width","")}}),Sao.View.Form.StateWidget=Sao.class_(Object,{init:function(a){this.attributes=a},set_state:function(a){var b;b=a?a.expr_eval(this.attributes.states||{}):{};var c=b.invisible;void 0===c&&(c=this.attributes.invisible),c?this.hide():this.show()},show:function(){this.el.show()},hide:function(){this.el.hide()}}),Sao.View.Form.LabelMixin=Sao.class_(Sao.View.Form.StateWidget,{set_state:function(a){Sao.View.Form.LabelMixin._super.set_state.call(this,a);var b;if(this.attributes.name&&a&&(b=a.model.fields[this.attributes.name]),void 0===this.attributes.string&&b){var c="";a&&(c=b.get_client(a)||""),this.label_el.val(c)}var d;d=a?a.expr_eval(this.attributes.states||{}):{},b&&b.description.readonly||d.readonly,Sao.common.apply_label_attributes(this.label_el,b&&b.description.readonly||d.readonly,b&&b.description.required||d.required)}}),Sao.View.Form.Separator=Sao.class_(Sao.View.Form.LabelMixin,{init:function(a,b){Sao.View.Form.Separator._super.init.call(this,b),this.el=jQuery("<div/>",{"class":"form-separator"}),this.label_el=jQuery("<label/>"),a&&this.label_el.text(a),this.el.append(this.label_el),this.el.append(jQuery("<hr/>"))}}),Sao.View.Form.Label=Sao.class_(Sao.View.Form.LabelMixin,{class_:"form-label",init:function(a,b){Sao.View.Form.Label._super.init.call(this,b),this.el=this.label_el=jQuery("<label/>",{text:a,"class":this.class_})}}),Sao.View.Form.Notebook=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-notebook",init:function(a){Sao.View.Form.Notebook._super.init.call(this,a),this.el=jQuery("<div/>",{"class":this.class_}),this.nav=jQuery("<ul/>",{"class":"nav nav-tabs",role:"tablist"}).appendTo(this.el),this.panes=jQuery("<div/>",{"class":"tab-content"}).appendTo(this.el),this.selected=!1},add:function(a,b){var c=jQuery("<div/>",{role:"tabpanel","class":"tab-pane"}).uniqueId(),d=c.attr("id"),e=jQuery("<li/>",{role:"presentation"}).append(jQuery("<a/>",{"aria-controls":d,role:"tab","data-toggle":"tab",href:"#"+d}).append(b).on("shown.bs.tab",function(){Sao.View.resize(a)})).appendTo(this.nav);return c.html(a).appendTo(this.panes),this.selected||(e.addClass("active"),c.addClass("active"),this.selected=!0),e},set_current_page:function(a){var b=this.nav.find('li[role="presentation"]:eq('+a+") a");b.tab("show")},get_n_pages:function(){return this.nav.find("li[role='presentation']").length},get_nth_page:function(a){return jQuery(this.panes.find("div[role='tabpanel']")[a])}}),Sao.View.Form.Page=Sao.class_(Sao.View.Form.StateWidget,{init:function(a,b){Sao.View.Form.Page._super.init.call(this,b),this.el=a}}),Sao.View.Form.Group=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-group_",init:function(a){Sao.View.Form.Group._super.init.call(this,a),this.el=jQuery("<div/>",{"class":this.class_})},add:function(a){this.el.append(a.el)}}),Sao.View.Form.Image_=Sao.class_(Sao.View.Form.StateWidget,{class_:"form-image_",init:function(a){Sao.View.Form.Image_._super.init.call(this,a),this.el=jQuery("<div/>",{class_:this.class_}),this.img=jQuery("<img/>",{"class":"center-block"}).appendTo(this.el),Sao.common.ICONFACTORY.register_icon(a.name).done(function(a){this.img.attr("src",a)}.bind(this))}}),Sao.View.form_widget_get=function(a){switch(a){case"char":return Sao.View.Form.Char;case"password":return Sao.View.Form.Password;case"date":return Sao.View.Form.Date;case"datetime":return Sao.View.Form.DateTime;case"time":return Sao.View.Form.Time;case"timedelta":return Sao.View.Form.TimeDelta;case"integer":case"biginteger":return Sao.View.Form.Integer;case"float":case"numeric":return Sao.View.Form.Float;case"selection":return Sao.View.Form.Selection;case"boolean":return Sao.View.Form.Boolean;case"text":return Sao.View.Form.Text;case"richtext":return Sao.View.Form.RichText;case"many2one":return Sao.View.Form.Many2One;case"one2one":return Sao.View.Form.One2One;case"reference":return Sao.View.Form.Reference;case"one2many":return Sao.View.Form.One2Many;case"many2many":return Sao.View.Form.Many2Many;case"binary":return Sao.View.Form.Binary;case"multiselection":return Sao.View.Form.MultiSelection;case"image":return Sao.View.Form.Image;case"url":return Sao.View.Form.URL;case"email":return Sao.View.Form.Email;case"callto":return Sao.View.Form.CallTo;case"sip":return Sao.View.Form.SIP;case"progressbar":return Sao.View.Form.ProgressBar;case"dict":return Sao.View.Form.Dict;case"pyson":return Sao.View.Form.PYSON}},Sao.View.Form.Widget=Sao.class_(Object,{init:function(a,b,c){this.field_name=a,this.model=b,this.view=null,this.attributes=c,this.el=null,this.position=0,this.visible=!0,this.labelled=null},display:function(a,b){var c=this.attributes.readonly,d=this.attributes.invisible,e=this.attributes.required;if(!b)return void 0===c&&(c=!0),void 0===d&&(d=!1),void 0===e&&(e=!1),this.set_readonly(c),this.set_invisible(d),void this.set_required(e);var f=b.get_state_attrs(a);void 0===c&&(c=f.readonly,void 0===c&&(c=!1)),void 0===e&&(e=f.required,void 0===e&&(e=!1)),this.view.screen.attributes.readonly&&(c=!0),this.set_readonly(c),this.set_required(e);var g=f.invalid;!c&&g?this.el.addClass("has-error"):this.el.removeClass("has-error"),void 0===d&&(d=b.get_state_attrs(a).invisible,void 0===d&&(d=!1)),this.set_invisible(d)},record:function(){return this.view&&this.view.screen?this.view.screen.current_record:void 0},field:function(){var a=this.record();return a?a.model.fields[this.field_name]:void 0},focus_out:function(){this.field()&&this.visible&&this.set_value(this.record(),this.field())},set_value:function(a,b){},set_readonly:function(a){this._readonly=a,this.el.prop("disabled",a)},set_required:function(a){},set_invisible:function(a){this.visible=!a,a?this.el.hide():this.el.show()}}),Sao.View.Form.TranslateDialog=Sao.class_(Object,{init:function(a,b){var c=new Sao.Dialog(Sao.i18n.gettext("Translate"),this.class_,this,a);c.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),this.languages=a,this.read(b,c),jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c)}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(this.write.bind(this,b,c)).appendTo(c.footer),c.content.submit(function(a){a.preventDefault(),c.footer.find("button.btn-primary").first().click()}),c.modal.modal("show"),c.modal.on("shown.bs.modal",function(){c.modal.find("input,select").filter(":visible").first().focus()})},close:function(a){a.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),a.modal.modal("hide")},read:function(a,b){this.languages.forEach(function(c){var d={};d.language=c.code;var e,f=[[a.record().id],[a.field_name],d],g={method:"model."+a.model.name+".read",params:f},h=jQuery("<div/>",{"class":"row form-group"}),i=a.translate_widget();i.attr("data-lang-id",c.id);var j=jQuery("<input/>",{type:"checkbox",title:Sao.i18n.gettext("Edit")});a._readonly&&j.attr("disabled",!0);var k=jQuery("<input/>",{type:"checkbox",disabled:!0,title:Sao.i18n.gettext("Fuzzy")}),l=Sao.rpc(g,a.model.session).then(function(b){e=b[0][a.field_name]}.bind(this));f=[[a.record().id],[a.field_name],d],d.fuzzy_translation=!0,g={method:"model."+a.model.name+".read",params:f},l.then(function(){Sao.rpc(g,a.model.session).then(function(b){e=b[0][a.field_name],a.translate_widget_set(i,e),k.attr("checked",b[0].name!=e)}.bind(this))}.bind(this)),j.click(function(){a.translate_widget_set_readonly(i)}),b.body.append(h),h.append(jQuery("<div/>",{"class":"col-sm-3"}).append(c.name)),h.append(jQuery("<div/>",{"class":"col-sm-6"}).append(i)),h.append(jQuery("<div/>",{"class":"col-sm-1"}).append(j)),h.append(jQuery("<div/>",{"class":"col-sm-1"}).append(k))}.bind(this))},write:function(a,b){var c=[];this.languages.forEach(function(b){var d=jQuery("[data-lang-id="+b.id+"]");if(!d.attr("readonly")){var e=a.model.session.context.language,f={};f.language=b.code,f.fuzzy_translation=!1;var g={};g[a.field_name]=d.val();var h=[[a.record().id],g,f],i={method:"model."+a.model.name+".write",params:h},j=Sao.rpc(i,a.model.session).then(function(){b.code==e&&a.view.display()});c.push(j)}}.bind(this)),this.close(b),jQuery.when.apply(jQuery,c).then(function(){a.record().cancel()})}}),Sao.View.Form.TranslateMixin={},Sao.View.Form.TranslateMixin.init=function(){this.translate=Sao.View.Form.TranslateMixin.translate.bind(this),this.translate_widget_set_readonly=Sao.View.Form.TranslateMixin.translate_widget_set_readonly.bind(this),this.translate_widget_set=Sao.View.Form.TranslateMixin.translate_widget_set.bind(this)},Sao.View.Form.TranslateMixin.translate=function(){if(this.record().id<0||this.record().has_changed()){var a=Sao.i18n.gettext("You need to save the record before adding translations.");return void Sao.common.message.run(a)}var b=this.model.session,c=[[["translatable","=","true"]]],d={method:"model.ir.lang.search",params:c.concat({})};Sao.rpc(d,b).then(function(a){if(jQuery.isEmptyObject(a))return void Sao.common.message.run(Sao.i18n.gettext("No other language available."));var c=[a,["code","name"]],d={method:"model.ir.lang.read",params:c.concat({})};Sao.rpc(d,b).then(function(a){new Sao.View.Form.TranslateDialog(a,this)}.bind(this))}.bind(this))},Sao.View.Form.TranslateMixin.translate_widget_set_readonly=function(a,b){a.attr("readonly")?a.removeAttr("readonly"):a.attr("readonly",!0)},Sao.View.Form.TranslateMixin.translate_widget_set=function(a,b){a.val(b||"")},Sao.View.Form.Char=Sao.class_(Sao.View.Form.Widget,{class_:"form-char",init:function(a,b,c){if(Sao.View.Form.Char._super.init.call(this,a,b,c),Sao.View.Form.TranslateMixin.init.call(this),this.el=jQuery("<div/>",{"class":this.class_}),this.group=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el),this.input=this.labelled=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(this.group),jQuery.isEmptyObject(c.autocomplete)||(this.datalist=jQuery("<datalist/>").appendTo(this.el),this.datalist.uniqueId(),this.input.attr("list",this.datalist.attr("id"))),this.el.change(this.focus_out.bind(this)),c.size||this.group.css("width","100%"),this.attributes.translate){var d=jQuery("<button/>",{"class":"btn btn-default btn-sm form-control",type:"button","aria-label":Sao.i18n.gettext("Translate")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-flag"})).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.group));d.click(this.translate.bind(this))}},get_client_value:function(a,b){var c="";return b&&(c=b.get_client(a)),c},display:function(a,b){if(Sao.View.Form.Char._super.display.call(this,a,b),this.datalist){this.datalist.children().remove();var c=function(){var b=[];a&&(b=a.autocompletion[this.field_name]||[]),b.forEach(function(a){jQuery("<option/>",{value:a}).appendTo(this.datalist)}.bind(this))}.bind(this);!a||this.field_name in a.autocompletion?c():a.do_autocomplete(this.field_name).done(c)}var d="",e="100%";a&&(d=a.expr_eval(this.attributes.size),d>0&&(e=null)),this.input.val(this.get_client_value(a,b)),this.input.attr("maxlength",d),this.input.attr("size",d),this.group.css("width",e)},set_value:function(a,b){b.set_client(a,this.input.val())},set_readonly:function(a){this.input.prop("readonly",a)},focus:function(){this.input.focus()},translate_widget:function(){return jQuery("<input/>",{"class":"form-control",readonly:"readonly"})}}),Sao.View.Form.Password=Sao.class_(Sao.View.Form.Char,{class_:"form-password",init:function(a,b,c){Sao.View.Form.Password._super.init.call(this,a,b,c),this.input.prop("type","password"),this.button=jQuery("<button/>",{"class":"btn btn-default btn-sm form-control",type:"button"}).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.group)),this._set_password_label(),this.button.click(this.toggle_visibility.bind(this))},toggle_visibility:function(){"password"==this.input.prop("type")?(this.input.prop("type","text"),this.input.attr("autocomplete","off")):(this.input.prop("type","password"),this.input.removeAttr("autocomplete")),this._set_password_label()},_set_password_label:function(){"password"==this.input.prop("type")?this.button.text(Sao.i18n.gettext("Show")):this.button.text(Sao.i18n.gettext("Hide"))}}),Sao.View.Form.Date=Sao.class_(Sao.View.Form.Widget,{class_:"form-date",_width:"12em",init:function(a,b,c){Sao.View.Form.Date._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.date=this.labelled=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el),this.input=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(this.date),jQuery("<span/>",{"class":"input-group-btn"}).append(jQuery("<button/>",{"class":"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-calendar"}))).appendTo(this.date),this.date.datetimepicker({locale:moment.locale()}),this.date.css("width",this._width),this.date.on("dp.change",this.focus_out.bind(this))},get_format:function(a,b){return b.date_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isDate=!0),c},display:function(a,b){a&&b&&this.date.data("DateTimePicker").format(Sao.common.moment_format(this.get_format(a,b))),Sao.View.Form.Date._super.display.call(this,a,b);var c;c=a?b.get_client(a):null,this.date.data("DateTimePicker").date(c)},focus:function(){this.input.focus()},set_value:function(a,b){b.set_client(a,this.get_value(a,b))},set_readonly:function(a){this.date.find("button").prop("disabled",a),this.date.find("input").prop("readonly",a)}}),Sao.View.Form.DateTime=Sao.class_(Sao.View.Form.Date,{class_:"form-datetime",_width:"25em",get_format:function(a,b){return b.date_format(a)+" "+b.time_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isDateTime=!0),c}}),Sao.View.Form.Time=Sao.class_(Sao.View.Form.Date,{class_:"form-time",_width:"10em",get_format:function(a,b){return b.time_format(a)},get_value:function(a,b){var c=this.date.data("DateTimePicker").date();return c&&(c.isTime=!0),c}}),Sao.View.Form.TimeDelta=Sao.class_(Sao.View.Form.Widget,{class_:"form-timedelta",init:function(a,b,c){Sao.View.Form.TimeDelta._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.input=this.labelled=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(this.el),this.el.change(this.focus_out.bind(this))},display:function(a,b){if(Sao.View.Form.TimeDelta._super.display.call(this,a,b),a){var c=a.field_get_client(this.field_name);this.input.val(c||"")}else this.input.val("")},focus:function(){this.input.focus()},set_value:function(a,b){b.set_client(a,this.input.val())},set_readonly:function(a){this.input.prop("readonly",a)}}),Sao.View.Form.Integer=Sao.class_(Sao.View.Form.Char,{class_:"form-integer",init:function(a,b,c){Sao.View.Form.Integer._super.init.call(this,a,b,c),this.input.attr("type","text"),this.input.attr("width",8),this.group.css("width",""),this.factor=Number(c.factor||1)},set_value:function(a,b){b.set_client(a,this.input.val(),void 0,this.factor)},get_client_value:function(a,b){var c="";return b&&(c=b.get_client(a,this.factor)),c}}),Sao.View.Form.Float=Sao.class_(Sao.View.Form.Integer,{class_:"form-float"}),Sao.View.Form.Selection=Sao.class_(Sao.View.Form.Widget,{class_:"form-selection",init:function(a,b,c){Sao.View.Form.Selection._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.select=this.labelled=jQuery("<select/>",{"class":"form-control input-sm"}),this.el.append(this.select),this.select.change(this.focus_out.bind(this)),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a,this.set_selection.bind(this))},update_selection:function(a,b,c){Sao.common.selection_mixin.update_selection.call(this,a,b,function(a){this.set_selection(a),c&&c()}.bind(this))},set_selection:function(a){var b=this.select;b.empty(),a.forEach(function(a){b.append(jQuery("<option/>",{value:JSON.stringify(a[0]),text:a[1]}))})},display_update_selection:function(a,b){this.update_selection(a,b,function(){if(!b)return void this.select.val("");for(var c,d=b.get(a),e=!1,f=0,g=this.selection.length;g>f;f++)if(this.selection[f][0]===d){e=!0;break}e?c=jQuery.when():(c=Sao.common.selection_mixin.get_inactive_selection.call(this,d),c.done(function(a){this.select.append(jQuery("<option/>",{value:JSON.stringify(a[0]),text:a[1],disabled:!0}))}.bind(this))),c.done(function(){this.select.val(JSON.stringify(d))}.bind(this))}.bind(this))},display:function(a,b){Sao.View.Form.Selection._super.display.call(this,a,b),this.display_update_selection(a,b)},focus:function(){this.select.focus()},value_get:function(){return JSON.parse(this.select.val())},set_value:function(a,b){var c=this.value_get();b.set_client(a,c)},set_readonly:function(a){this.select.prop("disabled",a)}}),Sao.View.Form.Boolean=Sao.class_(Sao.View.Form.Widget,{class_:"form-boolean",init:function(a,b,c){Sao.View.Form.Boolean._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.input=this.labelled=jQuery("<input/>",{type:"checkbox","class":"form-control input-sm"}).appendTo(this.el),this.input.change(this.focus_out.bind(this)),this.input.click(function(){return!jQuery(this).prop("readonly")})},display:function(a,b){Sao.View.Form.Boolean._super.display.call(this,a,b),a?this.input.prop("checked",a.field_get(this.field_name)):this.input.prop("checked",!1)},focus:function(){this.input.focus()},set_value:function(a,b){var c=this.input.prop("checked");b.set_client(a,c)},set_readonly:function(a){this.input.prop("readonly",a)}}),Sao.View.Form.Text=Sao.class_(Sao.View.Form.Widget,{class_:"form-text",init:function(a,b,c){if(Sao.View.Form.Text._super.init.call(this,a,b,c),Sao.View.Form.TranslateMixin.init.call(this),this.el=jQuery("<div/>",{"class":this.class_}),this.input=this.labelled=jQuery("<textarea/>",{"class":"form-control input-sm"}).appendTo(this.el),this.input.change(this.focus_out.bind(this)),this.attributes.translate){var d=jQuery("<button/>",{"class":"btn btn-default btn-sm form-control",type:"button","aria-label":Sao.i18n.gettext("Translate")}).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.el));d.append(jQuery("<span/>",{"class":"glyphicon glyphicon-flag"})),d.click(this.translate.bind(this))}},display:function(a,b){if(Sao.View.Form.Text._super.display.call(this,a,b),a){var c=a.field_get_client(this.field_name);this.input.val(c)}else this.input.val("")},focus:function(){this.input.focus()},set_value:function(a,b){var c=this.input.val()||"";b.set_client(a,c)},set_readonly:function(a){this.input.prop("readonly",a)},translate_widget:function(){return jQuery("<textarea/>",{"class":"form-control",readonly:"readonly"})}}),Sao.View.Form.RichText=Sao.class_(Sao.View.Form.Widget,{class_:"form-richtext",init:function(a,b,c){Sao.View.Form.RichText._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_+" panel panel-default"}),parseInt(c.toolbar||"1",10)&&this.get_toolbar().appendTo(this.el),this.input=this.labelled=jQuery("<div/>",{"class":"richtext",contenteditable:!0}).appendTo(jQuery("<div/>",{"class":"panel-body"}).appendTo(this.el)),this.el.focusout(this.focus_out.bind(this))},get_toolbar:function(){var a,b,c,d=jQuery("<div/>",{"class":"btn-toolbar",role:"toolbar"}).appendTo(jQuery("<div/>",{"class":"panel-heading"})),e=function(a){document.execCommand(a.data)},f=function(f){var g=jQuery("<div/>",{"class":"btn-group",role:"group"}).appendTo(d);for(a in f)b=f[a],c=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-"+b.icon})).appendTo(g),c.click(b.command,e)};f([{icon:"bold",command:"bold"},{icon:"italic",command:"italic"},{icon:"text-color",command:"underline"}]);var g=[{heading:Sao.i18n.gettext("Font"),options:["Normal","Serif","Sans","Monospace"],command:"fontname"},{heading:Sao.i18n.gettext("Size"),options:[1,2,3,4,5,6,7],command:"fontsize"}],h=function(a,b){return function(c){a.append(jQuery("<li/>").append(jQuery("<a/>",{href:"#"}).append(c).click(function(){document.execCommand(b.command,!1,c)})))}};for(a in g){b=g[a];var i=jQuery("<div/>",{"class":"btn-group",role:"group"}).appendTo(d);c=jQuery("<button/>",{"class":"btn btn-default dropdown-toggle",type:"button","data-toggle":"dropdown","aria-expanded":!1,"aria-haspopup":!0}).append(b.heading).append(jQuery("<span/>",{"class":"caret"})).appendTo(i);var j=jQuery("<ul/>",{"class":"dropdown-menu"}).appendTo(i);b.options.forEach(h(j,b))}return f([{icon:"align-left",command:"justifyLeft"},{icon:"align-center",command:"justifyCenter"},{icon:"align-right",command:"justifyRight"},{icon:"align-justify",command:"justifyFull"}]),[["foreColor","#000000"]].forEach(function(a){var b=a[0],c=a[1];jQuery("<input/>",{"class":"btn btn-default",type:"color"}).appendTo(d).change(function(){document.execCommand(b,!1,jQuery(this).val())}).focusin(function(){document.execCommand(b,!1,jQuery(this).val())}).val(c)}),d},focus_out:function(){window.setTimeout(function(){0===this.el.find(":focus").length&&Sao.View.Form.RichText._super.focus_out.call(this)}.bind(this),0)},display:function(a,b){Sao.View.Form.RichText._super.display.call(this,a,b);var c="";a&&(c=a.field_get_client(this.field_name)),this.input.html(c)},focus:function(){this.input.focus()},set_value:function(a,b){this.input.find("div").each(function(a,b){if(b=jQuery(b),b.css("text-align")){var c=b.css("text-align").split("-").pop();b.attr("align",c),b.css("text-align","")}"start"==b.attr("align")&&b.attr("align","left")});var c=this.input.html()||"";b.set_client(a,c)},set_readonly:function(a){this.input.prop("contenteditable",!a),this.toolbar&&this.toolbar.find("button,select").prop("disabled",a)}}),Sao.View.Form.Many2One=Sao.class_(Sao.View.Form.Widget,{class_:"form-many2one",init:function(a,b,c){Sao.View.Form.Many2One._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_});var d=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el);this.entry=this.labelled=jQuery("<input/>",{type:"input","class":"form-control input-sm"}).appendTo(d),this.entry.on("keydown",this.key_press.bind(this)),c.completion&&"1"!=c.completion||(Sao.common.get_completion(d,this._update_completion.bind(this),this._completion_match_selected.bind(this),this._completion_action_activated.bind(this)),this.wid_completion=!0),this.but_primary=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon"})).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).prependTo(d)),this.but_secondary=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon"})).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(d)),this.but_primary.click("primary",this.edit.bind(this)),this.but_secondary.click("secondary",this.edit.bind(this)),this.el.change(this.focus_out.bind(this)),this._readonly=!1},get_screen:function(){var a=this.field().get_domain(this.record()),b=this.field().get_context(this.record());return new Sao.Screen(this.get_model(),{context:b,domain:a,mode:["form"],view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views,readonly:this._readonly})},set_text:function(a){jQuery.isEmptyObject(a)&&(a=""),this.entry.val(a)},get_text:function(){var a=this.record();return a?a.field_get_client(this.field_name):""},focus_out:function(){(this.attributes.completion&&"1"!=this.attributes.completion||!this.el.find(".dropdown").hasClass("open"))&&Sao.View.Form.Many2One._super.focus_out.call(this)},set_value:function(a,b){b.get_client(a)!=this.entry.val()&&(b.set_client(a,this.value_from_id(null,"")),this.entry.val(""))},display:function(a,b){var c=this.record();if(!c||!a||c.id==a.id){var d;if(Sao.View.Form.Many2One._super.display.call(this,a,b),this._set_button_sensitive(),this._set_completion(),!a)return void this.entry.val("");this.set_text(b.get_client(a));var e,f;d=b.get(a),this.has_target(d)?(e="glyphicon-folder-open",f="glyphicon-erase"):(e=null,f="glyphicon-search"),this.entry.prop("readonly")&&(f=null),[[e,this.but_primary],[f,this.but_secondary]].forEach(function(a){var b=a[0],c=a[1],d=c.find(".glyphicon");d.removeClass().addClass("glyphicon"),b?(c.parent().css("display","table-cell"),d.addClass(b)):c.parent().css("display","none")})}},focus:function(){this.entry.focus()},set_readonly:function(a){this._readonly=a,this._set_button_sensitive()},_set_button_sensitive:function(){this.entry.prop("readonly",this._readonly),this.but_primary.prop("disabled",!this.read_access()),this.but_secondary.prop("disabled",this._readonly)},get_access:function(a){var b=this.get_model();return b?Sao.common.MODELACCESS.get(b)[a]:!0},read_access:function(){return this.get_access("read")},create_access:function(){return this.attributes.create&&this.get_access("create")},id_from_value:function(a){return a},value_from_id:function(a,b){return void 0===b&&(b=""),[a,b]},get_model:function(){return this.attributes.relation},has_target:function(a){return void 0!==a&&null!==a},edit:function(a){var b=this.get_model();if(b&&Sao.common.MODELACCESS.get(b).read){var c,d,e=this.record(),f=e.field_get(this.field_name);if(a&&"secondary"==a.data&&!this._readonly&&this.has_target(f))return this.record().field_set_client(this.field_name,this.value_from_id(null,"")),void this.entry.val("");if(this.has_target(f)){var g=this.get_screen(),h=this.id_from_value(e.field_get(this.field_name));return g.new_group([h]),d=function(a){if(a){var b=g.current_record.rec_name();b.done(function(a){var b=this.value_from_id(g.current_record.id,a);this.record().field_set_client(this.field_name,b,!0)}.bind(this))}},void(c=new Sao.Window.Form(g,d.bind(this),{save_current:!0,title:this.attributes.string}))}if(b){var i=this.field().get_domain(e),j=this.field().get_context(e),k=this.entry.val();d=function(a){if(!jQuery.isEmptyObject(a)){var b=this.value_from_id(a[0][0],a[0][1]);this.record().field_set_client(this.field_name,b,!0)}};var l=new Sao.common.DomainParser;return void(c=new Sao.Window.Search(b,d.bind(this),{sel_multi:!1,context:j,domain:i,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.create_access(),search_filter:l.quote(k),title:this.attributes.string}))}}},new_:function(a){var b=this.get_model();if(b&&Sao.common.MODELACCESS.get(b).create){var c=this.get_screen(),d=function(a){if(a){var b=c.current_record.rec_name();b.done(function(a){var b=this.value_from_id(c.current_record.id,a);this.record().field_set_client(this.field_name,b)}.bind(this))}};new Sao.Window.Form(c,d.bind(this),{new_:!0,save_current:!0,title:this.attributes.string,rec_name:this.entry.val()})}},key_press:function(a){var b=!this.entry.prop("readonly"),c=[Sao.common.TAB_KEYCODE],d=[Sao.common.BACKSPACE_KEYCODE,Sao.common.DELETE_KEYCODE];if(this.wid_completion||c.push(Sao.common.RETURN_KEYCODE),a.which==Sao.common.F3_KEYCODE&&b&&this.create_access())this.new_(),a.preventDefault();else if(a.which==Sao.common.F2_KEYCODE&&this.read_access())this.edit(),a.preventDefault();else if(~c.indexOf(a.which)&&b){if((!this.attributes.completion||"1"==this.attributes.completion)&&this.el.find(".dropdown").hasClass("open"))return;this.activate()}else if(this.has_target(this.record().field_get(this.field_name))&&b){var e=this.get_text();(e!=this.entry.val()||~d.indexOf(a.which))&&(this.entry.val(""),this.record().field_set_client(this.field_name,this.value_from_id(null,"")))}},activate:function(){var a=this.get_model();if(a&&Sao.common.MODELACCESS.get(a).read){var b=this.record(),c=b.field_get(this.field_name);
+new Sao.Model(a);if(a&&!this.has_target(c)){var d=this.entry.val();if(!this._readonly&&(d||this.field().get_state_attrs(this.record()).required)){var e=this.field().get_domain(b),f=this.field().get_context(b),g=function(a){if(jQuery.isEmptyObject(a))this.entry.val("");else{var b=this.value_from_id(a[0][0],a[0][1]);this.record().field_set_client(this.field_name,b,!0)}},h=new Sao.common.DomainParser;new Sao.Window.Search(a,g.bind(this),{sel_multi:!1,context:f,domain:e,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.create_access(),search_filter:h.quote(d),title:this.attributes.string})}}}},_set_completion:function(){var a=this.el.find(".action-search");this.read_access()?a.removeClass("disabled"):a.addClass("disabled");var b=this.el.find(".action-create");this.create_access()?b.removeClass("disabled"):b.addClass("disabled")},_update_completion:function(a){var b=this.record();if(b){var c=this.field(),d=c.get(b);if(this.has_target(d)){var e=this.id_from_value(d);if(void 0!==e&&e>0)return jQuery.when()}var f=this.get_model();return Sao.common.update_completion(this.entry,b,c,f)}},_completion_match_selected:function(a){this.record().field_set_client(this.field_name,this.value_from_id(a.id,a.rec_name),!0)},_completion_action_activated:function(a){"search"==a?this.edit():"create"==a&&this.new_()}}),Sao.View.Form.One2One=Sao.class_(Sao.View.Form.Many2One,{class_:"form-one2one"}),Sao.View.Form.Reference=Sao.class_(Sao.View.Form.Many2One,{class_:"form-reference",init:function(a,b,c){Sao.View.Form.Reference._super.init.call(this,a,b,c),this.el.addClass("form-inline"),this.select=jQuery("<select/>",{"class":"form-control input-sm","aria-label":c.string}),this.el.prepend(jQuery("<span/>").text("-")),this.el.prepend(this.select),this.select.change(this.select_changed.bind(this)),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a,this.set_selection.bind(this))},update_selection:function(a,b,c){Sao.common.selection_mixin.update_selection.call(this,a,b,function(a){this.set_selection(a),c&&c()}.bind(this))},set_selection:function(a){var b=this.select;b.empty(),a.forEach(function(a){b.append(jQuery("<option/>",{value:a[0],text:a[1]}))})},id_from_value:function(a){return parseInt(a.split(",")[1],10)},value_from_id:function(a,b){return b||(b=""),[this.get_model(),[a,b]]},get_text:function(){var a=this.record();return a?a.field_get_client(this.field_name)[1]:""},get_model:function(){return this.select.val()},has_target:function(a){if(null===a)return!1;var b=a.split(",")[0];return a=a.split(",")[1],jQuery.isEmptyObject(a)?a=null:(a=parseInt(a,10),isNaN(a)&&(a=null)),b==this.get_model()&&a>=0},_set_button_sensitive:function(){Sao.View.Form.Reference._super._set_button_sensitive.call(this),this.select.prop("disabled",this.entry.prop("readonly"))},select_changed:function(){this.entry.val("");var a,b=this.get_model();a=b?[b,[-1,""]]:["",""],this.record().field_set_client(this.field_name,a)},set_value:function(a,b){var c;if(this.get_model()){c=b.get_client(a,this.field_name);var d,e;c instanceof Array?(d=c[0],e=c[1]):(d="",e=""),d==this.get_model()&&e==this.entry.val()||(b.set_client(a,null),this.entry.val(""))}else c=this.entry.val(),jQuery.isEmptyObject(c)?b.set_client(a,null):b.set_client(a,["",c])},set_text:function(a){var b;a?(b=a[0],a=a[1]):(b=null,a=null),Sao.View.Form.Reference._super.set_text.call(this,a),b?this.select.val(b):this.select.val("")},display:function(a,b){this.update_selection(a,b,function(){Sao.View.Form.Reference._super.display.call(this,a,b)}.bind(this))},set_readonly:function(a){Sao.View.Form.Reference._super.set_readonly.call(this,a),this.select.prop("disabled",a)}}),Sao.View.Form.One2Many=Sao.class_(Sao.View.Form.Widget,{class_:"form-one2many",init:function(a,b,c){Sao.View.Form.One2Many._super.init.call(this,a,b,c),this._readonly=!0,this._required=!1,this.el=jQuery("<div/>",{"class":this.class_+" panel panel-default"}),this.menu=jQuery("<div/>",{"class":this.class_+"-menu panel-heading"}),this.el.append(this.menu),this.title=jQuery("<label/>",{"class":this.class_+"-string",text:c.string}),this.menu.append(this.title),this.title.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",this.title.attr("id")),this.title.attr("for",this.el.attr("id"));var d=jQuery("<div/>",{"class":this.class_+"-toolbar"});this.menu.append(d);var e=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(d);this.wid_text=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(e),this.wid_text.hide();var f=jQuery("<div/>",{"class":"input-group-btn"}).appendTo(e);c.add_remove&&(this.wid_text.show(),this.but_add=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-plus"})).appendTo(f),this.but_add.click(this.add.bind(this)),this.but_remove=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-minus"})).appendTo(f),this.but_remove.click(this.remove.bind(this))),this.but_new=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("New")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-edit"})).appendTo(f),this.but_new.click(this.new_.bind(this)),this.but_open=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Open")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-folder-open"})).appendTo(f),this.but_open.click(this.open.bind(this)),this.but_del=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Delete")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-trash"})).appendTo(f),this.but_del.click(this.delete_.bind(this)),this.but_undel=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Undelete")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-repeat"})).appendTo(f),this.but_undel.click(this.undelete.bind(this)),this.but_previous=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-chevron-left"})).appendTo(f),this.but_previous.click(this.previous.bind(this)),this.label=jQuery("<span/>",{"class":"btn"}).appendTo(f),this.label.text("(0, 0)"),this.but_next=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-chevron-right"})).appendTo(f),this.but_next.click(this.next.bind(this)),this.but_switch=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Switch")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-list-alt"})).appendTo(f),this.but_switch.click(this.switch_.bind(this)),this.content=jQuery("<div/>",{"class":this.class_+"-content panel-body"}),this.el.append(this.content);var g=(c.mode||"tree,form").split(",");this.screen=new Sao.Screen(c.relation,{mode:g,view_ids:(c.view_ids||"").split(","),views_preload:c.views||{},row_activate:this.activate.bind(this),exclude_field:c.relation_field||null,limit:null,pre_validate:c.pre_validate}),this.screen.pre_validate=1==c.pre_validate,this.prm=this.screen.switch_view(g[0]).done(function(){this.content.append(this.screen.screen_container.el)}.bind(this)),this.but_switch.prop("disabled",this.screen.number_of_views()<=0)},set_readonly:function(a){this._readonly=a,this._set_button_sensitive(),this._set_label_state()},set_required:function(a){this._required=a,this._set_label_state()},_set_label_state:function(){Sao.common.apply_label_attributes(this.title,this._readonly,this._required)},_set_button_sensitive:function(){var a,b,c=Sao.common.MODELACCESS.get(this.screen.model_name),d=this.record(),e=this.field();if(d&&e){var f=d.expr_eval(this.attributes.size);b=e.get_eval(d).length,a=void 0!==f&&null!==f&&b>=f>=0}else b=null,a=!1;var g=this.attributes.create;void 0===g&&(g=!0),this.but_new.prop("disabled",this._readonly||!g||a||!c.create);var h=this.attributes["delete"];void 0===h&&(h=!0),this.but_del.prop("disabled",this._readonly||!h||!c["delete"]),this.but_undel.prop("disabled",this._readonly||a),this.but_open.prop("disabled",!c.read),this.attributes.add_remove&&(this.wid_text.prop("disabled",this._readonly),this.but_add.prop("disabled",this._readonly||a||!c.write||!c.read),this.but_remove.prop("disabled",this._readonly||!c.write||!c.read))},display:function(a,b){Sao.View.Form.One2Many._super.display.call(this,a,b),this._set_button_sensitive(),this.prm.done(function(){if(a){if(void 0===b)return this.screen.new_group(),this.screen.set_current_record(null),this.screen.group.parent=null,void this.screen.display();var c=a.field_get_client(this.field_name);c!=this.screen.group&&(this.screen.set_group(c),"tree"==this.screen.current_view.view_type&&this.screen.current_view.editable&&this.screen.set_current_record(null));var d=[],e=null;a&&(d=b.get_domain(a),e=a.expr_eval(this.attributes.size)),this._readonly&&(e=null===e?this.screen.group.length:Math.min(e,this.screen.group.length)),Sao.common.compare(this.screen.domain,d)||(this.screen.domain=d),this.screen.size_limit=e,this.screen.display()}}.bind(this))},focus:function(){this.wid_text.is(":visible")&&this.wid_text.focus()},activate:function(a){this.edit()},add:function(a){var b=Sao.common.MODELACCESS.get(this.screen.model_name);if(b.write&&b.read){this.view.set_value();var c=this.field().get_domain(this.record()),d=this.field().get_context(this.record());c=[c,this.record().expr_eval(this.attributes.add_remove)];var e=this.field().get_removed_ids(this.record());c=["OR",c,["id","in",e]];var f=this.wid_text.val(),g=function(a){var b=jQuery.when();if(!jQuery.isEmptyObject(a)){var c,d,e=[];for(c=0,d=a.length;d>c;c++)e.push(a[c][0]);this.screen.group.load(e,!0),b=this.screen.display()}b.done(function(){this.screen.set_cursor()}.bind(this)),this.wid_text.val("")}.bind(this),h=new Sao.common.DomainParser;new Sao.Window.Search(this.attributes.relation,g,{sel_multi:!0,context:d,domain:c,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:!this.but_new.prop("disabled"),search_filter:h.quote(f),title:this.attributes.string})}},remove:function(a){var b=Sao.common.MODELACCESS.get(this.screen.model_name);b.write&&b.read&&this.screen.remove(!1,!0,!1)},new_:function(a){Sao.common.MODELACCESS.get(this.screen.model_name).create&&this.validate().done(function(){this.attributes.product?this.new_product():this.new_single()}.bind(this))},new_single:function(){var a=jQuery.extend({},this.field().get_context(this.record()));if("form"==this.screen.current_view.type||this.screen.current_view.editable)this.screen.new_(),this.screen.current_view.el.prop("disabled",!1);else{var b=this.record(),c=b.expr_eval(this.attributes.size)||-1;c-=this.field().get_eval(b);new Sao.Window.Form(this.screen,function(){},{new_:!0,many:c,context:a,title:this.attributes.string})}},new_product:function(){var a=this.attributes.product.split(","),b={},c=this.screen;c.new_(!1).then(function(d){d.default_get().then(function(e){d.set_default(e);var f=function(){if(jQuery.isEmptyObject(a))return g();var e=c.model.fields[a.pop()],h=e.description.relation;h||f();var i=e.get_domain(d),j=e.get_context(d),k=function(a){jQuery.isEmptyObject(a)||(b[e.name]=a),f()};new Sao.Window.Search(h,k,{sel_multi:!0,context:j,domain:i,search_filter:"",title:this.attributes.string})}.bind(this),g=function(){if(jQuery.isEmptyObject(b))return void c.group.remove(d,!0);var a=Object.keys(b),f=a.map(function(a){return b[a]});Sao.common.product(f).forEach(function(b){var f=function(c){var d=jQuery.extend({},e);a.forEach(function(a,c){d[a]=b[c][0],d[a+".rec_name"]=b[c][1]}),c.set_default(d)};d?(f(d),d=null):c.new_(!1).then(f)})};f()}.bind(this))}.bind(this))},open:function(a){this.edit()},delete_:function(a){Sao.common.MODELACCESS.get(this.screen.model_name)["delete"]&&this.screen.remove(!1,!1,!1)},undelete:function(a){this.screen.unremove()},previous:function(a){this.validate().done(function(){this.screen.display_previous()}.bind(this))},next:function(a){this.validate().done(function(){this.screen.display_next()}.bind(this))},switch_:function(a){this.screen.switch_view()},edit:function(){Sao.common.MODELACCESS.get(this.screen.model_name).read&&this.validate().done(function(){var a=this.screen.current_record;if(a){new Sao.Window.Form(this.screen,function(){},{title:this.attributes.string})}}.bind(this))},validate:function(){var a=jQuery.Deferred();this.view.set_value();var b=this.screen.current_record;if(b){var c=this.screen.current_view.get_fields();b.validate(c).then(function(c){return c?this.screen.pre_validate?b.pre_validate().then(function(b){return b?void a.resolve():void a.reject()}):void a.resolve():(this.screen.display(!0),void a.reject())}.bind(this))}else a.resolve();return a},set_value:function(a,b){this.screen.save_tree_state()}}),Sao.View.Form.Many2Many=Sao.class_(Sao.View.Form.Widget,{class_:"form-many2many",init:function(a,b,c){Sao.View.Form.Many2Many._super.init.call(this,a,b,c),this._readonly=!0,this._required=!1,this.el=jQuery("<div/>",{"class":this.class_+" panel panel-default"}),this.menu=jQuery("<div/>",{"class":this.class_+"-menu panel-heading"}),this.el.append(this.menu),this.title=jQuery("<label/>",{"class":this.class_+"-string",text:c.string}),this.menu.append(this.title),this.title.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",this.title.attr("id")),this.title.attr("for",this.el.attr("id"));var d=jQuery("<div/>",{"class":this.class_+"-toolbar"});this.menu.append(d);var e=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(d);this.entry=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(e),this.entry.on("keydown",this.key_press.bind(this));var f=jQuery("<div/>",{"class":"input-group-btn"}).appendTo(e);this.but_add=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-plus"})).appendTo(f),this.but_add.click(this.add.bind(this)),this.but_remove=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-minus"})).appendTo(f),this.but_remove.click(this.remove.bind(this)),this.content=jQuery("<div/>",{"class":this.class_+"-content panel-body"}),this.el.append(this.content),this.screen=new Sao.Screen(c.relation,{mode:["tree"],view_ids:(c.view_ids||"").split(","),views_preload:c.views||{},row_activate:this.activate.bind(this),limit:null}),this.prm=this.screen.switch_view("tree").done(function(){this.content.append(this.screen.screen_container.el)}.bind(this))},set_readonly:function(a){this._readonly=a,this._set_button_sensitive(),this._set_label_state()},set_required:function(a){this._required=a,this._set_label_state()},_set_label_state:function(){Sao.common.apply_label_attributes(this.title,this._readonly,this._required)},_set_button_sensitive:function(){var a=!1,b=this.record(),c=this.field();if(b&&c){var d=b.expr_eval(this.attributes.size),e=c.get_eval(b).length;a=void 0!==d&&null!==d&&e>=d>=0}this.entry.prop("disabled",this._readonly),this.but_add.prop("disabled",this._readonly||a),this.but_remove.prop("disabled",this._readonly)},display:function(a,b){Sao.View.Form.Many2Many._super.display.call(this,a,b),this.prm.done(function(){if(a){if(void 0===b)return this.screen.new_group(),this.screen.set_current_record(null),this.screen.group.parent=null,void this.screen.display();var c=a.field_get_client(this.field_name);c!=this.screen.group&&this.screen.set_group(c),this.screen.display()}}.bind(this))},focus:function(){this.entry.focus()},activate:function(){this.edit()},add:function(){var a=this.field().get_domain(this.record()),b=this.field().get_context(this.record()),c=this.entry.val(),d=function(a){if(!jQuery.isEmptyObject(a)){var b,c,d=[];for(b=0,c=a.length;c>b;b++)d.push(a[b][0]);this.screen.group.load(d,!0),this.screen.display()}this.entry.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(this.attributes.relation,d,{sel_multi:!0,context:b,domain:a,view_ids:(this.attributes.view_ids||"").split(","),views_preload:this.attributes.views||{},new_:this.attributes.create,search_filter:e.quote(c),title:this.attributes.string})},remove:function(){this.screen.remove(!1,!0,!1)},key_press:function(a){var b=[Sao.common.TAB_KEYCODE];this.wid_completion||b.push(Sao.common.RETURN_KEYCODE),a.which==Sao.common.F3_KEYCODE?(this.new_(),a.preventDefault()):a.which==Sao.common.F2_KEYCODE?(this.add(),a.preventDefault()):~b.indexOf(a.which)&&this.entry.val()&&this.add()},_get_screen_form:function(){var a=this.field().get_domain(this.record()),b=this.record().expr_eval(this.attributes.add_remove);jQuery.isEmptyObject(b)||(a=[a,b]);var c=this.field().get_context(this.record()),d=(this.attributes.view_ids||"").split(",");return jQuery.isEmptyObject(d)||d.shift(),new Sao.Screen(this.attributes.relation,{domain:a,view_ids:d,mode:["form"],views_preload:this.attributes.views,context:c})},edit:function(){if(!jQuery.isEmptyObject(this.screen.current_record)){var a=this._get_screen_form();a.new_group([this.screen.current_record.id]);var b=function(b){b&&a.current_record.save().done(function(){this.screen.current_record.cancel()}.bind(this))}.bind(this);a.switch_view().done(function(){new Sao.Window.Form(a,b,{title:this.attributes.string})}.bind(this))}},new_:function(){var a=this._get_screen_form(),b=function(b){if(b){var c=a.current_record;this.screen.group.load([c.id],!0)}this.entry.val("")}.bind(this);a.switch_view().done(function(){new Sao.Window.Form(a,b,{new_:!0,save_current:!0,title:this.attributes.string,rec_name:this.entry.val()})}.bind(this))}}),Sao.View.Form.BinaryMixin=Sao.class_(Sao.View.Form.Widget,{init:function(a,b,c){Sao.View.Form.BinaryMixin._super.init.call(this,a,b,c),this.filename=c.filename||null},toolbar:function(a){var b=jQuery("<div/>",{"class":a,role:"group"});return this.but_select=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-search"})).appendTo(b),this.but_select.click(this.select.bind(this)),this.filename&&(this.but_open=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-folder-open"})).appendTo(b),this.but_open.click(this.open.bind(this))),this.but_save_as=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-save"})).appendTo(b),this.but_save_as.click(this.save_as.bind(this)),this.but_clear=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-erase"})).appendTo(b),this.but_clear.click(this.clear.bind(this)),b},filename_field:function(){var a=this.record();return a?a.model.fields[this.filename]:void 0},select:function(){var a=this.record(),b=function(){d.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),d.modal.modal("hide")},c=function(){var c=new FileReader;c.onload=function(b){var d,e=this.field(),f=new Uint8Array(c.result);d=e.get_size?f:String.fromCharCode.apply(null,f),e.set_client(a,d)}.bind(this),c.onloadend=function(a){b()};var d=e[0].files[0];c.readAsArrayBuffer(d),this.filename&&this.filename_field().set_client(a,d.name)}.bind(this),d=new Sao.Dialog(Sao.i18n.gettext("Select"),"file-dialog");d.footer.append(jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(b)).append(jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).click(c)),d.content.submit(function(a){c(),a.preventDefault()});var e=jQuery("<input/>",{type:"file"}).appendTo(d.body);d.modal.modal("show")},open:function(){var a={},b=this.filename_field();if(b){var c=b.get_client(this.record());a.mimetype=Sao.common.guess_mimetype(c)}this.save_as(a)},save_as:function(a){var b,c=(a.mimetype||"application/octet-binary",this.field()),d=this.record();b=c.get_data?c.get_data(d):jQuery.when(c.get(d)),b.done(function(a){var b,c=this.filename_field();c&&(b=c.get(this.record())),Sao.common.download_file(a,b)}.bind(this))},clear:function(){var a=this.filename_field();a&&a.set_client(this.record(),null),this.field().set_client(this.record(),null)}}),Sao.View.Form.Binary=Sao.class_(Sao.View.Form.BinaryMixin,{class_:"form-binary",blob_url:"",init:function(a,b,c){Sao.View.Form.Binary._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_}),this.filename&&c.filename_visible&&(this.text=jQuery("<input/>",{type:"input","class":"form-control input-sm"}).appendTo(this.el),this.text.change(this.focus_out.bind(this)),this.text.on("keydown",this.key_press.bind(this)));var d=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el);this.size=jQuery("<input/>",{type:"input","class":"form-control input-sm",readonly:!0}).appendTo(d),this.toolbar("input-group-btn").appendTo(d)},display:function(a,b){if(Sao.View.Form.Binary._super.display.call(this,a,b),!b)return this.size.val(""),this.filename&&this.but_open.button("disable"),this.text&&this.text.val(""),void this.but_save_as.button("disable");var c;c=b.get_size?b.get_size(a):b.get(a).length;var d;d=c?"enable":"disable",this.filename&&(this.text&&this.text.val(this.filename_field().get(a)||""),this.but_open.button(d)),this.size.val(Sao.common.humanize(c)),this.but_save_as.button(d)},key_press:function(a){var b=!this.wid_text.prop("readonly");a.which==Sao.common.F3_KEYCODE&&b?(this.new_(),a.preventDefault()):a.which==Sao.common.F2_KEYCODE&&(this.open(),a.preventDefault())},set_value:function(a,b){this.text&&this.filename_field().set_client(a,this.text.val()||"")},set_readonly:function(a){a?(this.but_select.hide(),this.but_clear.hide()):(this.but_select.show(),this.but_clear.show()),this.wid_text&&this.wid_text.prop("readonly",a)}}),Sao.View.Form.MultiSelection=Sao.class_(Sao.View.Form.Selection,{class_:"form-multiselection",expand:!0,init:function(a,b,c){this.nullable_widget=!1,Sao.View.Form.MultiSelection._super.init.call(this,a,b,c),this.select.prop("multiple",!0)},display_update_selection:function(a,b){var c,d,e;this.update_selection(a,b,function(){var f=this.attributes.yexpand;if(void 0===f&&(f=this.expand),f||this.select.prop("size",this.select.children().length),b){var g=[],h=a.field_get_client(this.field_name);for(c=0,d=h.length;d>c;c++)e=h[c],~h.record_removed.indexOf(e)||~h.record_deleted.indexOf(e)||g.push(e.id);this.select.val(g)}}.bind(this))},set_value:function(a,b){var c=this.select.val();c=c?c.map(function(a){return parseInt(a,10)}):[],b.set_client(a,c)}}),Sao.View.Form.Image=Sao.class_(Sao.View.Form.BinaryMixin,{class_:"form-image",init:function(a,b,c){Sao.View.Form.Image._super.init.call(this,a,b,c),this.height=parseInt(c.height||100,10),this.width=parseInt(c.width||300,10),this.el=jQuery("<div/>"),this.image=jQuery("<img/>",{"class":"center-block"}).appendTo(this.el),this.image.css("max-height",this.height),this.image.css("max-width",this.width),this.image.css("height","auto"),this.image.css("width","auto");var d=this.toolbar("btn-group");c.readonly||jQuery("<div/>",{"class":"text-center"}).append(d).appendTo(this.el),this.update_img()},set_readonly:function(a){[this.but_select,this.but_open,this.but_save_as,this.but_clear].forEach(function(b){b&&b.prop("disable",a)})},clear:function(){Sao.View.Form.Image._super.clear.call(this),this.update_img()},update_img:function(){var a,b=this.record();b&&(a=b.field_get_client(this.field_name)),a=a?a>Sao.common.BIG_IMAGE_SIZE?jQuery.when(null):b.model.fields[this.field_name].get_data(b):jQuery.when(null),a.done(function(a){var b,c;a?(c=new Blob([a]),b=window.URL.createObjectURL(c)):b=null,this.image.attr("src",b)}.bind(this))},display:function(a,b){Sao.View.Form.Image._super.display.call(this,a,b),this.update_img()}}),Sao.View.Form.URL=Sao.class_(Sao.View.Form.Char,{class_:"form-url",init:function(a,b,c){Sao.View.Form.URL._super.init.call(this,a,b,c),this.button=jQuery("<a/>",{"class":"btn btn-default",target:"_new"}).appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.group)),this.icon=jQuery("<img/>").appendTo(this.button),this.set_icon()},display:function(a,b){Sao.View.Form.URL._super.display.call(this,a,b);var c="";if(a&&(c=a.field_get_client(this.field_name)),this.set_url(c),a&this.attributes.icon){var d,e=this.attributes.icon;d=e in a.model.fields?a.field_get_client(e):e,this.set_icon(d)}},set_icon:function(a){a=a||"tryton-web-browser",Sao.common.ICONFACTORY.register_icon(a).done(function(a){this.icon.attr("src",a)}.bind(this))},set_url:function(a){this.button.attr("href",a)},set_readonly:function(a){Sao.View.Form.URL._super.set_readonly.call(this,a),a?(this.input.hide(),this.button.removeClass("btn-default"),this.button.addClass("btn-link")):(this.input.show(),this.button.removeClass("btn-link"),this.button.addClass("btn-default"))}}),Sao.View.Form.Email=Sao.class_(Sao.View.Form.URL,{class_:"form-email",set_url:function(a){Sao.View.Form.Email._super.set_url.call(this,"mailto:"+a)}}),Sao.View.Form.CallTo=Sao.class_(Sao.View.Form.URL,{class_:"form-callto",set_url:function(a){Sao.View.Form.CallTo._super.set_url.call(this,"callto:"+a)}}),Sao.View.Form.SIP=Sao.class_(Sao.View.Form.URL,{class_:"form-sip",set_url:function(a){Sao.View.Form.SIP._super.set_url.call(this,"sip:"+a)}}),Sao.View.Form.ProgressBar=Sao.class_(Sao.View.Form.Widget,{class_:"form-char",init:function(a,b,c){Sao.View.Form.ProgressBar._super.init.call(this,a,b,c),this.el=jQuery("<div/>",{"class":this.class_+" progress"}),this.progressbar=jQuery("<div/>",{"class":"progress-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100}).appendTo(this.el),this.progressbar.css("min-width: 2em")},display:function(a,b){Sao.View.Form.ProgressBar._super.display.call(this,a,b);var c,d;b?(c=b.get(a),d=b.get_client(a,100),d&&(d=Sao.i18n.gettext("%1%",d))):(c=0,d=""),this.progressbar.attr("aria-valuenow",100*c),this.progressbar.css("width",100*c+"%"),this.progressbar.text(d)}}),Sao.View.Form.Dict=Sao.class_(Sao.View.Form.Widget,{class_:"form-dict",init:function(a,b,c){Sao.View.Form.Dict._super.init.call(this,a,b,c),this.schema_model=new Sao.Model(c.schema_model),this.keys={},this.fields={},this.rows={},this.el=jQuery("<div/>",{"class":this.class_+" panel panel-default"});var d=jQuery("<div/>",{"class":this.class_+"-heading panel-heading"}).appendTo(this.el),e=jQuery("<label/>",{"class":this.class_+"-string",text:c.string}).appendTo(d);e.uniqueId(),this.el.uniqueId(),this.el.attr("aria-labelledby",e.attr("id")),e.attr("for",this.el.attr("id"));var f=jQuery("<div/>",{"class":this.class_+"-body panel-body"}).appendTo(this.el);this.container=jQuery("<div/>",{"class":this.class_+"-container"}).appendTo(f);var g=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(jQuery("<div>",{"class":"col-md-12"}).appendTo(jQuery("<div/>",{"class":"row"}).appendTo(jQuery("<div/>",{"class":"container-fluid"}).appendTo(f))));this.wid_text=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(g),this.but_add=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-plus"})).appendTo(jQuery("<div/>",{"class":"input-group-btn"}).appendTo(g)),this.but_add.click(this.add.bind(this)),this._readonly=!1,this._record_id=null},add:function(){var a=this.field().get_context(this.record()),b=this.wid_text.val(),c=this.field().get_domain(this.record()),d=function(a){if(!jQuery.isEmptyObject(a)){var b=a.map(function(a){return a[0]});this.add_new_keys(b)}this.wid_text.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(this.schema_model.name,d,{sel_multi:!0,context:a,domain:c,new_:!1,search_filter:e.quote(b),title:this.attributes.string})},add_new_keys:function(a){var b=this.field().get_context(this.record());this.schema_model.execute("get_keys",[a],b).then(function(a){var b=!1;a.forEach(function(a){this.fields[a.name]||(this.keys[a.name]=a,this.add_line(a.name),b||(this.fields[a.name].input.focus(),b=!0))}.bind(this))}.bind(this))},remove:function(a,b){void 0===b&&(b=!0),delete this.fields[a],this.rows[a].remove(),delete this.rows[a],b&&this.set_value(this.record(),this.field())},set_value:function(a,b){b.set_client(a,this.get_value())},get_value:function(){var a={};for(var b in this.fields){var c=this.fields[b];a[b]=c.get_value()}return a},set_readonly:function(a){this._readonly=a,this._set_button_sensitive();for(var b in this.fields){var c=this.fields[b];c.set_readonly(a)}this.wid_text.prop("disabled",a)},_set_button_sensitive:function(){var a=this.attributes.create;void 0===a&&(a=!0);var b=this.attributes["delete"];void 0===b&&(b=!0),this.but_add.prop("disabled",this._readonly||!a);for(var c in this.fields){var d=this.fields[c].button;d.prop("disabled",this._readonly||!b)}},add_line:function(a){var b,c;this.fields[a]=b=new(this.get_entries(this.keys[a].type_))(a,this),this.rows[a]=c=jQuery("<div/>",{"class":"row"});var d=this.keys[a].string+Sao.i18n.gettext(":"),e=jQuery("<label/>",{text:d}).appendTo(jQuery("<div/>",{"class":"dict-label col-md-4"}).appendTo(c));b.el.addClass("col-md-8").appendTo(c),e.uniqueId(),b.labelled.uniqueId(),b.labelled.attr("aria-labelledby",e.attr("id")),e.attr("for",b.labelled.attr("id")),b.button.click(function(){this.remove(a,!0)}.bind(this)),c.appendTo(this.container)},add_keys:function(a){var b=this.field().get_context(this.record()),c=this.field().get_domain(this.record()),d=Math.min(10,Sao.config.limit);a=jQuery.extend([],a);for(var e=function(a){return this.schema_model.execute("get_keys",[a],b).then(f)}.bind(this),f=function(a){for(var b=0,c=a.length;c>b;b++){var d=a[b];this.keys[d.name]=d}}.bind(this),g=[];a.length>0;){var h=a.splice(0,d);g.push(this.schema_model.execute("search",[[["name","in",h],c],0,Sao.config.limit,null],b).then(e))}return jQuery.when.apply(jQuery,g)},display:function(a,b){if(Sao.View.Form.Dict._super.display.call(this,a,b),b){var c,d=a?a.id:null;if(d!=this._record_id){for(c in this.fields)this.remove(c,!1);this._record_id=d}var e,f=b.get_client(a),g=Object.keys(f).filter(function(a){return!this.keys[a]}.bind(this));e=jQuery.isEmptyObject(g)?jQuery.when():this.add_keys(g),e.then(function(){var a,b,c,d=Object.keys(f).sort();for(a=0,b=d.length;b>a;a++){c=d[a];var e=f[c];if(this.keys[c]){this.fields[c]||this.add_line(c);var g=this.fields[c];g.set_value(e),g.set_readonly(this._readonly)}}var h=Object.keys(this.fields).filter(function(a){return!f[a]});for(a=0,b=h.length;b>a;a++)c=h[a],this.remove(c,!1)}.bind(this)),this._set_button_sensitive()}},get_entries:function(a){switch(a){case"char":return Sao.View.Form.Dict.Entry;case"boolean":return Sao.View.Form.Dict.Boolean;case"selection":return Sao.View.Form.Dict.Selection;case"integer":return Sao.View.Form.Dict.Integer;case"float":return Sao.View.Form.Dict.Float;case"numeric":return Sao.View.Form.Dict.Numeric;case"date":return Sao.View.Form.Dict.Date;case"datetime":return Sao.View.Form.Dict.DateTime}}}),Sao.View.Form.Dict.Entry=Sao.class_(Object,{class_:"dict-char",init:function(a,b){this.name=a,this.definition=b.keys[a],this.parent_widget=b,this.create_widget()},create_widget:function(){this.el=jQuery("<div/>",{"class":this.class_});var a=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(this.el);this.input=this.labelled=jQuery("<input/>",{type:"text","class":"form-control input-sm"}).appendTo(a),this.button=jQuery("<button/>",{"class":"btn btn-default",type:"button","arial-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-minus"})).appendTo(jQuery("<div/>",{
+"class":"input-group-btn"}).appendTo(a)),this.el.change(this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){return this.input.val()},set_value:function(a){this.input.val(a||"")},set_readonly:function(a){this._readonly=a,this.input.prop("readonly",a)}}),Sao.View.Form.Dict.Boolean=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-boolean",create_widget:function(){Sao.View.Form.Dict.Boolean._super.create_widget.call(this),this.input.attr("type","checkbox"),this.input.change(this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){return this.input.prop("checked")},set_value:function(a){this.input.prop("checked",a)}}),Sao.View.Form.Dict.Selection=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-selection",create_widget:function(){Sao.View.Form.Dict.Selection._super.create_widget.call(this);var a=jQuery("<select/>",{"class":"form-control input-sm"});a.change(this.parent_widget.focus_out.bind(this.parent_widget)),this.input.replaceWith(a),this.input=this.labelled=a;var b=jQuery.extend([],this.definition.selection);b.splice(0,0,[null,""]),b.forEach(function(b){a.append(jQuery("<option/>",{value:JSON.stringify(b[0]),text:b[1]}))})},get_value:function(){return JSON.parse(this.input.val())},set_value:function(a){this.input.val(JSON.stringify(a))}}),Sao.View.Form.Dict.Integer=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-integer",get_value:function(){var a=parseInt(this.input.val(),10);return isNaN(a)?null:a}}),Sao.View.Form.Dict.Float=Sao.class_(Sao.View.Form.Dict.Integer,{class_:"dict-float",get_value:function(){var a=Number(this.input.val());return isNaN(a)?null:a}}),Sao.View.Form.Dict.Numeric=Sao.class_(Sao.View.Form.Dict.Float,{class_:"dict-numeric",get_value:function(){var a=new Sao.Decimal(this.input.val());return isNaN(a.valueOf())?null:a}}),Sao.View.Form.Dict.Date=Sao.class_(Sao.View.Form.Dict.Entry,{class_:"dict-date",format:"%x",create_widget:function(){Sao.View.Form.Dict.Date._super.create_widget.call(this);var a=this.button.parent();jQuery("<button/>",{"class":"datepickerbutton btn btn-default",type:"button"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-calendar"})).prependTo(a),this.input.datetimepicker({format:Sao.common.moment_format(this.format),locale:moment.locale()}),this.input.on("dp.change",this.parent_widget.focus_out.bind(this.parent_widget))},get_value:function(){var a=this.input.data("DateTimePicker").date();return a&&(a.isDate=!0),a},set_value:function(a){this.input.data("DateTimePicker").date(a)}}),Sao.View.Form.Dict.DateTime=Sao.class_(Sao.View.Form.Dict.Date,{class_:"dict-datetime",format:"%x %X",get_value:function(){var a=this.input.data("DateTimePicker").date();return a&&(a.isDateTime=!0),a}}),Sao.View.Form.PYSON=Sao.class_(Sao.View.Form.Char,{class_:"form-pyson",init:function(a,b,c){Sao.View.Form.PYSON._super.init.call(this,a,b,c),this.encoder=new Sao.PYSON.Encoder({}),this.decoder=new Sao.PYSON.Decoder({},!0),this.el.keyup(this.validate_pyson.bind(this));var d=jQuery("<button/>",{"class":"btn btn-default",type:"button"});this.icon=jQuery("<span/>",{"class":"glyphicon"}),d.append(this.icon),d.appendTo(jQuery("<span/>",{"class":"input-group-btn"}).appendTo(this.group))},get_encoded_value:function(){var a=this.input.val();if(!a)return a;try{return this.encoder.encode(eval_pyson(a))}catch(b){return null}},set_value:function(a,b){b.set_client(a,this.get_encoded_value())},get_client_value:function(a,b){var c=Sao.View.Form.PYSON._super.get_client_value.call(this,a,b);return c&&(c=this.decoder.decode(c).toString()),c},validate_pyson:function(){var a="ok";null===this.get_encoded_value()&&(a="remove"),this.icon.removeClass().addClass("glyphicon").addClass(" glyphicon-"+a+"-sign")},focus_out:function(){this.validate_pyson(),Sao.View.Form.PYSON._super.focus_out.call(this)}})}(),function(){"use strict";function a(a,b,c){var d=Sao.config.display_size,e=jQuery.Deferred(),f=function(g){a.slice(g,g+d).forEach(function(a){a.redraw(b,c)}),g+=d,g<a.length?setTimeout(f,0,g):e.resolve()};return setTimeout(f,0,0),e}Sao.View.tree_column_get=function(a){switch(a){case"char":return Sao.View.Tree.CharColumn;case"text":return Sao.View.Tree.TextColum;case"many2one":return Sao.View.Tree.Many2OneColumn;case"one2one":return Sao.View.Tree.One2OneColumn;case"date":return Sao.View.Tree.DateColumn;case"time":return Sao.View.Tree.TimeColumn;case"timedelta":return Sao.View.Tree.TimeDeltaColumn;case"one2many":return Sao.View.Tree.One2ManyColumn;case"many2many":return Sao.View.Tree.Many2ManyColumn;case"selection":return Sao.View.Tree.SelectionColumn;case"reference":return Sao.View.Tree.ReferenceColumn;case"float":case"numeric":return Sao.View.Tree.FloatColumn;case"integer":case"biginteger":return Sao.View.Tree.IntegerColumn;case"boolean":return Sao.View.Tree.BooleanColumn;case"binary":return Sao.View.Tree.BinaryColumn;case"image":return Sao.View.Tree.ImageColumn;case"url":case"email":case"callto":case"sip":return Sao.View.Tree.URLColumn;case"progressbar":return Sao.View.Tree.ProgressBar}},Sao.View.Tree=Sao.class_(Sao.View,{init:function(a,b,c){Sao.View.Tree._super.init.call(this,a,b),this.view_type="tree",this.selection_mode=a.attributes.selection_mode||Sao.common.SELECTION_SINGLE,this.el=jQuery("<div/>",{"class":"treeview responsive"}),this.expanded={},this.children_field=c,this.editable=Boolean(this.attributes.editable),this.columns=[],this.create_columns(a.model,b),this.rows=[],this.table=jQuery("<table/>",{"class":"tree table table-hover table-striped"}),this.el.append(this.table),this.thead=jQuery("<thead/>").appendTo(this.table);var d=jQuery("<tr/>");if(this.selection_mode!=Sao.common.SELECTION_NONE){var e=jQuery("<th/>",{"class":"selection"});this.selection=jQuery("<input/>",{type:"checkbox","class":"selection"}),this.selection.change(this.selection_changed.bind(this)),e.append(this.selection),d.append(e)}this.thead.append(d),this.columns.forEach(function(a){e=jQuery("<th/>");var b=jQuery("<label/>").text(a.attributes.string);if(this.editable&&(a.attributes.required&&b.addClass("required"),a.attributes.readonly||b.addClass("editable")),a.attributes.help&&(b.data("toggle","tooltip"),b.attr("title",a.attributes.help),b.tooltip()),a.sortable){var c=jQuery("<span/>");b.append(c),a.arrow=c,e.click(a,this.sort_model.bind(this)),b.addClass("sortable")}d.append(e.append(b)),a.header=e},this),this.tbody=jQuery("<tbody/>"),this.table.append(this.tbody);var f=jQuery("<div/>",{"class":"treefooter"});this.more=jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("More")).click(function(){this.display_size+=Sao.config.display_size,this.display()}.bind(this)),f.append(this.more),this.more.hide(),this.display_size=Sao.config.display_size,this.el.append(f)},create_columns:function(a,b){b.find("tree").children().each(function(b,c){for(var d,e,f={},g=0,h=c.attributes.length;h>g;g++)e=c.attributes[g],f[e.name]=e.value;if(["readonly","expand","completion"].forEach(function(a){f[a]&&(f[a]=1==f[a])}),"field"==c.tagName){var i=f.name;f.widget||(f.widget=a.fields[i].description.type);var j=["relation","domain","selection","relation_field","string","views","invisible","add_remove","sort","context","filename","autocomplete","translate","create","delete","selection_change_with","schema_model","required","readonly","help"];for(g in j){var k=j[g];k in a.fields[i].description&&null===c.getAttribute(k)&&(f[k]=a.fields[i].description[k])}var l=Sao.View.tree_column_get(f.widget);d=new l(a,f);~["url","email","callto","sip"].indexOf(f.widget)&&d.prefixes.push(new Sao.View.Tree.Affix(f,f.widget)),"icon"in f&&d.prefixes.push(new Sao.View.Tree.Affix(f));var m,n,o=c.childNodes;for(g=0;g<o.length;g++){for(m=o[g],n={},g=0,h=m.attributes.length;h>g;g++)e=m.attributes[g],n[e.name]=e.value;n.name||(n.name=i),"prefix"==m.tagName?d.prefixes.push(new Sao.View.Tree.Affix(n)):d.suffixes.push(new Sao.View.Tree.Affix(n))}this.attributes.sequence||this.children_field||a.fields[i].description.sortable===!1||(d.sortable=!0),this.fields[i]=!0}else"button"==c.tagName&&(d=new Sao.View.Tree.ButtonColumn(this.screen,f));this.columns.push(d)}.bind(this))},sort_model:function(a){var b=a.data,c=b.arrow,d="glyphicon glyphicon-triangle-top",e="glyphicon glyphicon-triangle-bottom";this.columns.forEach(function(a){a.arrow&&a!=b&&a.arrow.hasClass("glyphicon")&&a.arrow.removeClass(d+" "+e)}),this.screen.order=this.screen.default_order,c.hasClass(e)?(c.removeClass(e),c.addClass(d),this.screen.order=[[b.attributes.name,"DESC"]]):c.hasClass(d)?c.removeClass(d):(c.addClass(e),this.screen.order=[[b.attributes.name,"ASC"]]);var f=[];this.screen.group.forEach(function(a){a.id<0&&(f=a.group)});var g=this.screen.screen_container.get_text();!jQuery.isEmptyObject(f)||this.screen.search_count==this.screen.group.length||this.screen.parent?this.screen.search_filter(g,!0).then(function(a){this.screen.group.sort(a)}.bind(this)):this.screen.search_filter(g)},get_buttons:function(){var a=[];return this.columns.forEach(function(b){b instanceof Sao.View.Tree.ButtonColumn&&a.push(b)}),a},display:function(a,b){var c=this.screen.current_record;if(!a)if(a=this.get_selected_paths(),c){var d=c.get_path(this.screen.group);d=d.map(function(a){return a[1]}),Sao.common.contains(a,d)||(a=[d])}else c||(a=[]);b=b||[];var e=function(){return this.rows.map(function(a){return a.record})}.bind(this),f=Math.min(this.screen.group.length,this.display_size);this.children_field?this.construct(a,b):f>this.rows.length&&Sao.common.compare(this.screen.group.slice(0,this.rows.length),e())?this.construct(a,b,!0):f==this.rows.length&&Sao.common.compare(this.screen.group,e())||this.construct(a,b);var g=[];jQuery.isEmptyObject(this.screen.domain)||g.push(this.screen.domain);var h=this.screen.screen_container.get_tab_domain();jQuery.isEmptyObject(h)||g.push(h);var i=new Sao.common.DomainInversion;g=i.simplify(g);var j=new Sao.PYSON.Decoder(this.screen.context);return this.columns.forEach(function(a){var b=a.attributes.name;if(b)if(j.decode(a.attributes.tree_invisible||"0")||b===this.screen.exclude_field)a.header.hide(),a.header.addClass("invisible");else{var c=i.domain_inversion(g,b);"boolean"!=typeof c&&(c=i.simplify(c));var d=i.unique_value(c)[0];d&&jQuery.isEmptyObject(this.children_field)?(a.header.hide(),a.header.addClass("invisible")):(a.header.show(),a.header.removeClass("invisible"))}}.bind(this)),this.columns.filter(function(a){return a.header.is(":visible")}).length>1?(this.table.addClass("responsive"),this.table.addClass("responsive-header")):(this.table.removeClass("responsive"),this.table.removeClass("responsive-header")),this.redraw(a,b)},construct:function(a,b,c){var d=this.tbody;c||(this.rows=[],this.tbody=jQuery("<tbody/>"));var e=this.rows.length,f=function(c,d,e){var f;f=this.editable?Sao.View.Tree.RowEditable:Sao.View.Tree.Row;var g=new f(this,c,this.rows.length);this.rows.push(g),g.construct(a,b)};this.screen.group.slice(e,this.display_size).forEach(f.bind(this)),this.display_size>=this.screen.group.length?this.more.hide():this.more.show(),c||d.replaceWith(this.tbody)},redraw:function(b,c){return a(this.rows,b,c)},switch_:function(a){this.screen.row_activate()},select_changed:function(a){var b=this.screen.current_record;if(this.screen.set_current_record(a),this.editable&&b){var c=function(){this.screen.set_current_record(b),this.set_cursor()}.bind(this);this.screen.group.parent||b===a?b!==a&&this.screen.attributes.pre_validate&&b.pre_validate().then(function(a){a||c()}):b.validate(this.get_fields()).then(function(a){a?b.save().fail(c):c()})}},selected_records:function(){if(this.selection_mode==Sao.common.SELECTION_NONE)return[];var a=[],b=function(c){c.is_selected()&&a.push(c.record),c.rows.forEach(b)};return this.rows.forEach(b),this.selection.prop("checked")&&!this.selection.prop("indeterminate")&&this.screen.group.slice(this.rows.length).forEach(function(b){a.push(b)}),a},selection_changed:function(){var a=this.selection.prop("checked"),b=function(c){c.set_selection(a),c.rows.forEach(b)};this.rows.forEach(b),a&&this.rows[0]?this.select_changed(this.rows[0].record):this.select_changed(null)},update_selection:function(){if(!this.selection.prop("checked")){var a=this.selected_records();this.selection.prop("indeterminate",!1),jQuery.isEmptyObject(a)?this.selection.prop("checked",!1):a.length==this.tbody.children().length&&this.display_size>=this.screen.group.length?this.selection.prop("checked",!0):(this.selection.prop("indeterminate",!0),this.selection.prop("checked",!0))}},get_selected_paths:function(){function a(c,d){var e,f,g,h;for(e=0,g=c.rows.length;g>e;e++)f=c.rows[e],h=d.concat([f.record.id]),f.is_selected()&&b.push(h),a(f,h)}var b=[];return a(this,[]),b},get_expanded_paths:function(a,b){var c,d,e,f,g;void 0===a&&(a=[]),void 0===b&&(b=[]),d=[],e=this.find_row(a),f=e?e.rows:this.rows;for(var h=0,i=this.n_children(e);i>h;h++)g=a.concat([h]),e=f[h],e&&e.is_expanded()&&(c=b.concat(e.record.id),d.push(c),d=d.concat(this.get_expanded_paths(g,c)));return d},find_row:function(a){for(var b,c=null,d=this.rows,e=0,f=a.length;f>e;e++){if(b=a[e],!d||b>=d.length)return null;if(c=d[b],d=c.rows,!this.children_field)break}return c},n_children:function(a){return a&&this.children_field?a.record._values[this.children_field].length:this.rows.length},set_cursor:function(a,b){var c,d,e,f,g,h,i,j;if(this.screen.current_record){for(d=null,c=0;c<this.rows.length;c++)if(e=this.rows[c].record_to_path(this.screen.current_record)){e.unshift(c),d=e;break}f=null,d?(h=d[0],i=d.slice(1),i.length>0&&this.rows[h].expand_to_path(i),f=this.find_row(d)):this.rows.length>0&&(f=this.rows[0]),f&&(g=f.next_column(null,a),null!==g&&(j=f._get_column_td(g),this.editable?(j.triggerHandler("click"),a?j.triggerHandler("click"):j.find(":input,[tabindex=0]").focus()):j.find(":input,[tabindex=0]").focus()))}}}),Sao.View.Tree.Row=Sao.class_(Object,{init:function(a,b,c,d){this.tree=a,this.rows=[],this.record=b,this.parent_=d,this.children_field=a.children_field,this.expander=null;var e=[];d&&(e=jQuery.extend([],d.path.split("."))),e.push(c),this.path=e.join("."),this.el=jQuery("<tr/>")},is_expanded:function(){return this.path in this.tree.expanded},get_last_child:function(){return this.children_field&&this.is_expanded()&&!jQuery.isEmptyObject(this.rows)?this.rows[this.rows.length-1].get_last_child():this},get_id_path:function(){return this.parent_?this.parent_.get_id_path().concat([this.record.id]):[this.record.id]},build_widgets:function(){var a=jQuery("<table/>");a.css("width","100%");var b=jQuery("<tr/>");return a.append(b),[a,b]},construct:function(a,b){a=a||[],b=b||[];for(var c=this.el[0];c.firstChild;)c.removeChild(c.firstChild);var d;this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(d=jQuery("<td/>"),this.el.append(d),this.selection=jQuery("<input/>",{type:"checkbox","class":"selection"}),this.selection.change(this.selection_changed.bind(this)),d.append(this.selection));for(var e=this.path.split(".").length,f=0;f<this.tree.columns.length;f++){var g=this.tree.columns[f];d=jQuery("<td/>",{"data-title":g.attributes.string+Sao.i18n.gettext(": ")}).append(jQuery("<div/>",{"aria-hidden":!0})),d.css("overflow","hidden"),d.on("click keypress",{column:f,td:d},Sao.common.click_press(this.select_row.bind(this),!0)),this.tree.editable?(g.attributes.required&&d.addClass("required"),g.attributes.readonly||d.addClass("editable")):d.dblclick(this.switch_row.bind(this));var h=this.build_widgets(),i=h[0],j=h[1];if(d.append(i),0===f&&this.children_field){var k="glyphicon-plus";(this.is_expanded()||~b.indexOf(this.record.id))&&(k="glyphicon-minus"),this.expander=jQuery("<span/>",{"class":"glyphicon "+k,tabindex:0}),this.expander.html(" "),this.expander.css("margin-left",e-1+"em"),this.expander.css("float","left"),this.expander.on("click keypress",Sao.common.click_press(this.toggle_row.bind(this))),j.append(jQuery("<td/>",{"class":"expander"}).append(this.expander).css("width",1))}var l;if(g.prefixes)for(l=0;l<g.prefixes.length;l++){g.prefixes[l];j.append(jQuery("<td/>",{"class":"prefix"}).css("width",1))}if(j.append(jQuery("<td/>",{"class":"widget"})),g.suffixes)for(l=0;l<g.suffixes.length;l++){g.suffixes[l];j.append(jQuery("<td/>",{"class":"suffix"}).css("width",1))}this.el.append(d)}if(this.parent_){var m=this.parent_.get_last_child();m.el.after(this.el)}else this.tree.tbody.append(this.el);var n=this.get_id_path();(this.is_expanded()||Sao.common.contains(b,n))&&(this.tree.expanded[this.path]=this,this.expand_children(a,b))},_get_column_td:function(a,b){b=b||this.el;var c=0;return this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(c+=1),jQuery(b.children()[a+c])},redraw:function(b,c){b=b||[],c=c||[];for(var d=function(){jQuery.isEmptyObject(this.record.field_get(this.children_field))&&this.expander.css("visibility","hidden")},e=this.tree.thead.is(":visible"),f=0;f<this.tree.columns.length;f++){0===f&&this.children_field&&this.record.load(this.children_field).done(d.bind(this));var g,h=this.tree.columns[f],i=this._get_column_td(f),j=i.find("tr");if(h.prefixes)for(var k=0;k<h.prefixes.length;k++){var l=h.prefixes[k],m=jQuery(j.children(".prefix")[k]);g=m.children(),g.length?l.render(this.record,g):m.html(l.render(this.record))}var n=j.children(".widget");if(g=n.children(),g.length?h.render(this.record,g):n.html(h.render(this.record)),h.suffixes)for(var o=0;o<h.suffixes.length;o++){var p=h.suffixes[o],q=jQuery(j.children(".suffix")[o]);g=q.children(),g.length?p.render(this.record,g):q.html(p.render(this.record))}h.header.is(":hidden")&&e||"none"==h.header.css("display")?(i.hide(),i.addClass("invisible")):(i.show(),i.removeClass("invisible"))}var r=this.get_id_path();this.set_selection(Sao.common.contains(b,r)),this.is_expanded()||Sao.common.contains(c,r)?(this.tree.expanded[this.path]=this,!this.record._values[this.children_field]||this.record._values[this.children_field].length>0&&0===this.rows.length?this.expand_children(b,c):a(this.rows,b,c),this.expander&&this.update_expander(!0)):this.expander&&this.update_expander(!1),this.record.deleted()||this.record.removed()?this.el.css("text-decoration","line-through"):this.el.css("text-decoration","inherit")},toggle_row:function(){return this.is_expanded()?(this.update_expander(!1),delete this.tree.expanded[this.path],this.collapse_children()):(this.update_expander(!0),this.tree.expanded[this.path]=this,this.expand_children()),!1},update_expander:function(a){a?(this.expander.removeClass("glyphicon-plus"),this.expander.addClass("glyphicon-minus")):(this.expander.removeClass("glyphicon-minus"),this.expander.addClass("glyphicon-plus"))},collapse_children:function(){this.rows.forEach(function(a,b,c){a.collapse_children();var d=a.el[0];d.parentNode.removeChild(d)}),this.rows=[]},expand_children:function(b,c){var d=function(){if(jQuery.isEmptyObject(this.rows)){var d=[],e=function(a,e,f){var g=new this.Class(this.tree,a,e,this);g.construct(b,c),this.rows.push(g),d.push(g)},f=this.record.field_get_client(this.children_field);f.forEach(e.bind(this)),a(d,b,c)}};return this.record.load(this.children_field).done(d.bind(this))},switch_row:function(){window.getSelection?window.getSelection().empty?window.getSelection().empty():window.getSelection().removeAllRanges&&window.getSelection().removeAllRanges():document.selection&&document.selection.empty(),(this.tree.selection_mode==Sao.common.SELECTION_NONE||(this.set_selection(!0),this.selection_changed(),this.is_selected()))&&this.tree.switch_(this.path)},select_row:function(a){this.tree.selection_mode==Sao.common.SELECTION_NONE?(this.tree.select_changed(this.record),this.switch_row()):(a.ctrlKey||this.tree.selection_mode!=Sao.common.SELECTION_SINGLE||this.tree.rows.forEach(function(a){a.set_selection(!1)}.bind(this)),this.set_selection(!this.is_selected()),this.selection_changed());var b=a.data.td,c=a.data.column;b.on("click keypress",{column:c,td:b},Sao.common.click_press(this.select_row.bind(this),!0))},is_selected:function(){return this.tree.selection_mode==Sao.common.SELECTION_NONE?!1:this.selection.prop("checked")},set_selection:function(a){this.tree.selection_mode!=Sao.common.SELECTION_NONE&&(this.selection.prop("checked",a),a||this.tree.selection.prop("checked",!1))},selection_changed:function(){var a=this.is_selected();this.set_selection(a),a?this.tree.select_changed(this.record):this.tree.select_changed(this.tree.selected_records()[0]||null),this.tree.update_selection()},record_to_path:function(a){var b,c;if(a==this.record)return[];for(b=0;b<this.rows.length;b++)if(c=this.rows[b].record_to_path(a))return c.unshift(b),c},expand_to_path:function(a){var b,c;b=a[0],c=a.slice(1),c.length>0&&this.rows[b].expand_children().done(function(){this.rows[b].expand_to_path(c)}.bind(this))},next_column:function(a,b,c){var d,e,f,g,h,i;for(c=c||1,null===a&&c>0?a=-1:null===a&&(a=0),h=0,d=0;d<this.tree.columns.length;d++)if(h=(a+c*(d+1))%this.tree.columns.length,0>h&&(h+=this.tree.columns.length),g=this.tree.columns[h],i=g.field.get_state_attrs(this.record),f=i.invisible,g.header.is(":hidden")&&(f=!0),e=b?g.attributes.readonly||i.readonly:!1,!f&&!e)return h}}),Sao.View.Tree.RowEditable=Sao.class_(Sao.View.Tree.Row,{init:function(a,b,c,d){Sao.View.Tree.RowEditable._super.init.call(this,a,b,c,d),this.edited_column=null},redraw:function(a,b){var c,d,e,f,g;for(Sao.View.Tree.RowEditable._super.redraw.call(this,a,b),c=0;c<this.tree.columns.length;c++)e=this._get_column_td(c),d=e.find("tr"),f=jQuery(d.children(".widget-editable")).data("widget"),f&&(g=this.record.model.fields[f.field_name],f.display(this.record,g))},select_row:function(a){function b(a,d){var e,f;for(e=0;e<a.length;e++)f=a[e],f.is_selected()&&(c=f),f!=d&&f.set_selection(!1),b(f.rows,d)}var c,d,e,f,g;b(this.tree.rows,this),this.selection_changed();var h;h=c&&c!=this&&!this.tree.screen.group.parent?c.record.save():jQuery.when(),h.done(function(){if(c&&null!==c.edited_column){d=c.get_active_td(),d.on("click keypress",{td:d,column:c.edited_column},Sao.common.click_press(c.select_row.bind(c),!0));var b=this.tree.columns[c.edited_column];c.get_static_el().html(b.render(c.record)).show(),c.empty_editable_el()}var h=this.is_selected(),i=a.data.column,j=this.tree.columns[i],k=j.field.get_state_attrs(this.record),l=j.attributes.readonly||k.readonly;if(h&&!l){this.edited_column=i,e=this.get_active_td();var m=j.attributes,n=Sao.View.editabletree_widget_get(m.widget);g=new n(m.name,this.tree.screen.model,m),g.view=this.tree,g.el.on("focusin",function(){jQuery(this).parents(".treeview td").css("overflow","visible")}),g.el.on("focusout",function(){jQuery(this).parents(".treeview td").css("overflow","hidden")});var o=this.get_editable_el();o.append(g.el),o.data("widget",g),g.el.on("keydown",this.key_press.bind(this)),f=this.record.model.fields[g.field_name],g.display(this.record,f),this.get_static_el().hide(),this.get_editable_el().show(),g.el.focus()}else if(!h){this.set_selection(!0),this.selection_changed();var p=a.data.td;p.on("click keypress",{column:i,td:p},Sao.common.click_press(this.select_row.bind(this),!0))}}.bind(this))},get_static_el:function(){var a=this.get_active_td();return a.find(".widget")},get_editable_el:function(){var a=this.get_active_td(),b=a.find(".widget-editable");return b.length||(b=jQuery("<td/>",{"class":"widget-editable"}).insertAfter(a.find(".widget"))),b},empty_editable_el:function(){var a;a=this.get_editable_el(),a.empty(),a.data("widget",null),this.edited_column=null},get_active_td:function(){return this._get_column_td(this.edited_column)},key_press:function(a){var b,c,d,e,f;if(a.which==Sao.common.TAB_KEYCODE||a.which==Sao.common.UP_KEYCODE||a.which==Sao.common.DOWN_KEYCODE||a.which==Sao.common.ESC_KEYCODE||a.which==Sao.common.RETURN_KEYCODE){var g=this.tree.columns[this.edited_column];if(g.field.validate(this.record))if(a.which==Sao.common.TAB_KEYCODE){var h=1;a.shiftKey&&(h=-1),a.preventDefault(),d=this.next_column(this.edited_column,!0,h),null!==d&&window.setTimeout(function(){var a=this._get_column_td(d);a.triggerHandler("click",{column:d,td:a})}.bind(this),0)}else if(a.which==Sao.common.UP_KEYCODE||a.which==Sao.common.DOWN_KEYCODE)f=a.which==Sao.common.UP_KEYCODE?this.el.prev("tr"):this.el.next("tr"),c=this.edited_column,this.record.validate(this.tree.get_fields()).then(function(a){if(a){if(this.tree.screen.attributes.pre_validate)return this.record.pre_validate().fail(function(){f=null});if(!this.tree.screen.model.parent)return this.record.save().fail(function(){f=null})}else{f=null;var b=this.record.invalid_fields();for(e=0;e<this.tree.columns.length;e++){var d=this.tree.columns[e];d.attributes.name in b&&(c=e)}}}.bind(this)).then(function(){window.setTimeout(function(){this._get_column_td(c,f).trigger("click").trigger("click")}.bind(this),0)}.bind(this));else if(a.which==Sao.common.ESC_KEYCODE)this.get_static_el().show(),b=this.get_active_td(),b.on("click keypress",{column:this.edited_column,td:b},Sao.common.click_press(this.select_row.bind(this),!0)),this.empty_editable_el();else if(a.which==Sao.common.RETURN_KEYCODE){var i=function(a){var b=this._get_column_td(this.edited_column,a);b.triggerHandler("click"),b.triggerHandler("click")}.bind(this);if(f="bottom"==this.tree.attributes.editable?this.el.next("tr"):this.el.prev("tr"),f.length)i(f);else{var j,k=this.tree.screen.group,l=Sao.common.MODELACCESS.get(this.tree.screen.model_name),m=null!==this.tree.screen.size_limit&&k.length>=this.tree.screen.size_limit;j=!l.create||m?jQuery.when():this.tree.screen.new_(),j.done(function(){var a,b=this.tree.tbody.children("tr");a="bottom"==this.tree.attributes.editable?b.last():b.first(),i(a)}.bind(this))}}}}}),Sao.View.Tree.Affix=Sao.class_(Object,{init:function(a,b){this.attributes=a,this.protocol=b||null,this.icon=a.icon,this.protocol&&!this.icon&&(this.icon="tryton-web-browser")},get_cell:function(){var a;return this.protocol?(a=jQuery("<a/>",{target:"_new"}),a.append(jQuery("<img/>")),a.click({cell:a},this.clicked.bind(this))):this.icon?a=jQuery("<img/>"):(a=jQuery("<span/>"),a.attr("tabindex",0)),a.addClass("column-affix"),a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){var c,d,e=a.model.fields[this.attributes.name],f=e.get_state_attrs(a).invisible;if(f?b.hide():b.show(),this.protocol){if(c=e.get(a),!jQuery.isEmptyObject(c))switch(this.protocol){case"email":c="mailto:"+c;break;case"callto":c="callto:"+c;break;case"sip":c="sip:"+c}b.attr("src",c)}if(this.icon){if(this.icon in a.model.fields){var g=a.model.fields[this.icon];c=g.get_client(a)}else c=this.icon;d=Sao.common.ICONFACTORY.register_icon(c),d.done(function(a){var c;c=b.children("img").length?b.children("img"):b,c.attr("src",a)}.bind(this))}else c=this.attributes.string||"",c||(c=e.get_client(a)||""),b.text(c)}.bind(this)),b},clicked:function(a){a.preventDefault(),window.open(a.data.cell.attr("src"),"_blank")}}),Sao.View.Tree.CharColumn=Sao.class_(Object,{class_:"column-char",init:function(a,b){this.type="field",this.model=a,this.field=a.fields[b.name],this.attributes=b,this.prefixes=[],this.suffixes=[],this.header=null},get_cell:function(){var a=jQuery("<div/>",{"class":this.class_,tabindex:0});return a},update_text:function(a,b){a.text(this.field.get_client(b))},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){this.update_text(b,a),this.field.set_state(a);var c=this.field.get_state_attrs(a);c.invisible?b.hide():b.show()}.bind(this)),b}}),Sao.View.Tree.TextColum=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-text"}),Sao.View.Tree.IntegerColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-integer",init:function(a,b){Sao.View.Tree.IntegerColumn._super.init.call(this,a,b),this.factor=Number(b.factor||1)},get_cell:function(){return Sao.View.Tree.IntegerColumn._super.get_cell.call(this)},update_text:function(a,b){a.text(this.field.get_client(b,this.factor))}}),Sao.View.Tree.FloatColumn=Sao.class_(Sao.View.Tree.IntegerColumn,{class_:"column-float"}),Sao.View.Tree.BooleanColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-boolean",get_cell:function(){return jQuery("<input/>",{type:"checkbox",disabled:!0,"class":this.class_,tabindex:0})},update_text:function(a,b){a.prop("checked",this.field.get(b))}}),Sao.View.Tree.Many2OneColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-many2one"}),Sao.View.Tree.One2OneColumn=Sao.class_(Sao.View.Tree.Many2OneColumn,{class_:"column-one2one"}),Sao.View.Tree.SelectionColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-selection",init:function(a,b){Sao.View.Tree.SelectionColumn._super.init.call(this,a,b),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a)},update_selection:function(a,b){Sao.common.selection_mixin.update_selection.call(this,a,this.field,b)},update_text:function(a,b){this.update_selection(b,function(){for(var c,d,e=this.field.get(b),f=!1,g=0,h=this.selection.length;h>g;g++)if(this.selection[g][0]===e){f=!0,d=this.selection[g][1];break}c=f?jQuery.when(d):Sao.common.selection_mixin.get_inactive_selection.call(this,e).then(function(a){return a[1]}),c.done(function(b){a.text(b)}.bind(this))}.bind(this))}}),Sao.View.Tree.ReferenceColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-reference",init:function(a,b){Sao.View.Tree.ReferenceColumn._super.init.call(this,a,b),Sao.common.selection_mixin.init.call(this),this.init_selection()},init_selection:function(a){Sao.common.selection_mixin.init_selection.call(this,a)},update_selection:function(a,b){Sao.common.selection_mixin.update_selection.call(this,a,this.field,b)},update_text:function(a,b){this.update_selection(b,function(){var c,d,e=this.field.get_client(b);if(e?(c=e[0],d=e[1]):(c="",d=""),c){for(var f=0,g=this.selection.length;g>f;f++)if(this.selection[f][0]===c){c=this.selection[f][1];break}a.text(c+","+d)}else a.text(d)}.bind(this))}}),Sao.View.Tree.DateColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-date",update_text:function(a,b){var c=this.field.get_client(b),d=this.field.date_format(b);a.text(Sao.common.format_date(d,c))}}),Sao.View.Tree.TimeColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-time",update_text:function(a,b){var c=this.field.get_client(b);a.text(Sao.common.format_time(this.field.time_format(b),c))}}),Sao.View.Tree.TimeDeltaColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-timedelta"}),Sao.View.Tree.One2ManyColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-one2many",update_text:function(a,b){a.text("( "+this.field.get_client(b).length+" )")}}),Sao.View.Tree.Many2ManyColumn=Sao.class_(Sao.View.Tree.One2ManyColumn,{class_:"column-many2many"}),Sao.View.Tree.BinaryColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-binary",update_text:function(a,b){var c;c=this.field.get_size?this.field.get_size(b):this.field.get(b).length,a.text(Sao.common.humanize(c))}}),Sao.View.Tree.ImageColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-image",get_cell:function(){var a=jQuery("<img/>",{"class":this.class_,tabindex:0});return a.css("width","100%"),a},render:function(a,b){return b||(b=this.get_cell()),a.load(this.attributes.name).done(function(){var c=this.field.get_client(a);c=c?c>Sao.common.BIG_IMAGE_SIZE?jQuery.when(null):this.field.get_data(a):jQuery.when(null),c.done(function(a){var c,d;a?(d=new Blob([a]),c=window.URL.createObjectURL(d)):c=null,b.attr("src",c)}.bind(this))}.bind(this)),b}}),Sao.View.Tree.URLColumn=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-url",render:function(a,b){b=Sao.View.Tree.URLColumn._super.render.call(this,a,b),this.field.set_state(a);var c=this.field.get_state_attrs(a);return c.readonly?b.hide():b.show(),b}}),Sao.View.Tree.ProgressBar=Sao.class_(Sao.View.Tree.CharColumn,{class_:"column-progressbar",get_cell:function(){var a=jQuery("<div/>",{"class":this.class_+" progress",tabindex:0}),b=jQuery("<div/>",{"class":"progress-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100}).appendTo(a);return b.css("min-width: 2em"),a},update_text:function(a,b){
+var c=this.field.get_client(b,100);c&&(c=Sao.i18n.gettext("%1%",c));var d=this.field.get(b)||0,e=a.find(".progress-bar");e.attr("aria-valuenow",100*d),e.css("width",100*d+"%"),e.text(c)}}),Sao.View.Tree.ButtonColumn=Sao.class_(Object,{init:function(a,b){this.screen=a,this.type="button",this.attributes=b},render:function(a,b){var c=new Sao.common.Button(this.attributes,b);b||c.el.click([a,c],this.button_clicked.bind(this));var d=jQuery.map(this.screen.model.fields,function(a,b){return"eager"==(a.description.loading||"eager")?b:void 0});return a.load(d[0]).done(function(){c.set_state(a)}),c.el},button_clicked:function(a){var b=a.data[0],c=a.data[1];if(b==this.screen.current_record){var d=b.expr_eval(this.attributes.states||{});if(!d.invisible&&!d.readonly){c.el.prop("disabled",!0);try{this.screen.button(this.attributes)}finally{c.el.prop("disabled",!1)}}}}}),Sao.View.editabletree_widget_get=function(a){switch(a){case"char":case"text":case"url":case"email":case"callto":case"sip":return Sao.View.EditableTree.Char;case"date":return Sao.View.EditableTree.Date;case"time":return Sao.View.EditableTree.Time;case"timedelta":return Sao.View.EditableTree.TimeDelta;case"integer":case"biginteger":return Sao.View.EditableTree.Integer;case"float":case"numeric":return Sao.View.EditableTree.Float;case"selection":return Sao.View.EditableTree.Selection;case"boolean":return Sao.View.EditableTree.Boolean;case"many2one":return Sao.View.EditableTree.Many2One;case"reference":return Sao.View.EditableTree.Reference;case"one2one":return Sao.View.EditableTree.One2One;case"one2many":case"many2many":return Sao.View.EditableTree.One2Many;case"binary":return Sao.View.EditableTree.Binary}},Sao.View.EditableTree={},Sao.View.EditableTree.editable_mixin=function(a){var b=function(a){a.which!=Sao.common.TAB_KEYCODE&&a.which!=Sao.common.UP_KEYCODE&&a.which!=Sao.common.DOWN_KEYCODE&&a.which!=Sao.common.ESC_KEYCODE&&a.which!=Sao.common.RETURN_KEYCODE||this.focus_out()};a.el.on("keydown",b.bind(a))},Sao.View.EditableTree.Char=Sao.class_(Sao.View.Form.Char,{class_:"editabletree-char",init:function(a,b,c){Sao.View.EditableTree.Char._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Date=Sao.class_(Sao.View.Form.Date,{class_:"editabletree-date",init:function(a,b,c){Sao.View.EditableTree.Date._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Time=Sao.class_(Sao.View.Form.Time,{class_:"editabletree-time",init:function(a,b,c){Sao.View.EditableTree.Time._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.TimeDelta=Sao.class_(Sao.View.Form.TimeDelta,{class_:"editabletree-timedelta",init:function(a,b,c){Sao.View.EditableTree.TimeDelta._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Integer=Sao.class_(Sao.View.Form.Integer,{class_:"editabletree-integer",init:function(a,b,c){Sao.View.EditableTree.Integer._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Float=Sao.class_(Sao.View.Form.Float,{class_:"editabletree-float",init:function(a,b,c){Sao.View.EditableTree.Float._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Selection=Sao.class_(Sao.View.Form.Selection,{class_:"editabletree-selection",init:function(a,b,c){Sao.View.EditableTree.Selection._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Boolean=Sao.class_(Sao.View.Form.Boolean,{class_:"editabletree-boolean",init:function(a,b,c){Sao.View.EditableTree.Boolean._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}}),Sao.View.EditableTree.Many2One=Sao.class_(Sao.View.Form.Many2One,{class_:"editabletree-many2one",init:function(a,b,c){Sao.View.EditableTree.Many2One._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.Many2One._super.key_press.call(this,a)}}),Sao.View.EditableTree.Reference=Sao.class_(Sao.View.Form.Reference,{class_:"editabletree-reference",init:function(a,b,c){Sao.View.EditableTree.Reference._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.Reference._super.key_press.call(this,a)}}),Sao.View.EditableTree.One2One=Sao.class_(Sao.View.Form.One2One,{class_:"editabletree-one2one",init:function(a,b,c){Sao.View.EditableTree.One2One._super.init.call(this,a,b,c),this.el.on("keydown",this.key_press.bind(this))},key_press:function(a){a.which==Sao.common.TAB_KEYCODE?this.focus_out():Sao.View.EditableTree.One2One._super.key_press.call(this,a)}}),Sao.View.EditableTree.One2Many=Sao.class_(Sao.View.EditableTree.Char,{class_:"editabletree-one2many",init:function(a,b,c){Sao.View.EditableTree.One2Many._super.init.call(this,a,b,c)},display:function(a,b){a?this.el.val("("+b.get_client(a).length+")"):this.el.val("")},key_press:function(a){a.which==Sao.common.TAB_KEYCODE&&this.focus_out()},set_value:function(a,b){}}),Sao.View.EditableTree.Binary=Sao.class_(Sao.View.Form.Binary,{class_:"editabletree-binary",init:function(a,b,c){Sao.View.EditableTree.Binary._super.init.call(this,a,b,c),Sao.View.EditableTree.editable_mixin(this)}})}(),function(){"use strict";Sao.View.Graph=Sao.class_(Sao.View,{init:function(a,b){Sao.View.Graph._super.init.call(this,a,b),this.view_type="graph",this.el=jQuery("<div/>",{"class":"graph"}),this.widgets={},this.widget=this.parse(b.children()[0]),this.widgets.root=this.widget,this.el.append(this.widget.el)},parse:function(a){var b,c,d,e,f,g,h,i=null,j=[],k=function(a){for(var b,c={},d=0,e=a.attributes.length;e>d;d++)b=a.attributes[d],c[b.name]=b.value;return c};for(e=0,f=a.children.length;f>e;e++)switch(d=a.children[e],d.tagName){case"x":for(g=0,h=d.children.length;h>g;g++)i=k(d.children[g]),b=this.screen.model.fields[i.name],i.type=b.description.type,i.string||(i.string=b.description.string);break;case"y":for(g=0,h=d.children.length;h>g;g++)c=k(d.children[g]),c.string||"#"==c.name||(b=this.screen.model.fields[c.name],c.string=b.description.string),j.push(c)}var l;switch(this.attributes.type){case"hbar":l=Sao.View.Graph.HorizontalBar;break;case"line":l=Sao.View.Graph.Line;break;case"pie":l=Sao.View.Graph.Pie;break;default:l=Sao.View.Graph.VerticalBar}return new l(this,i,j)},display:function(){return this.widget.display(this.screen.group)}}),Sao.View.Graph.Chart=Sao.class_(Object,{_chart_type:void 0,init:function(a,b,c){this.view=a,this.xfield=b,this.yfields=c,this.el=jQuery("<div/>"),this.el.uniqueId()},update_data:function(a){var b,c,d,e,f,g,h,i={};this.ids={},i.columns=[["labels"]],i.names={};var j={},k=[this.xfield.name];for(e=0,f=this.yfields.length;f>e;e++)c=this.yfields[e],i.columns.push([c.name]),i.names[c.name]=c.string,j[c.key||c.name]=e+1,k.push(c.name);var l=[],m=function(e){return function(){b=a[e];var f=b.field_get_client(this.xfield.name);f&&(f.isDate||f.isDateTime)&&(f=f.toDate()),i.columns[0][e+1]=f,this._add_id(f,b.id);var k;for(g=0,h=this.yfields.length;h>g;g++){if(c=this.yfields[g],d=c.key||c.name,k=i.columns[j[d]],c.domain){var l=jQuery.extend({},Sao.session.current_session.context);l.context=l,l._user=Sao.session.current_session.user_id;for(var m in a.model.fields)l[m]=b.field_get(m);var n=new Sao.PYSON.Decoder(l);if(!n.decode(c.domain)){k[e+1]=0;continue}}if("#"==c.name)k[e+1]=1;else{var o=b.field_get(c.name);o&&o.isTimeDelta&&(o=o.asSeconds()),k[e+1]=o||0}}}.bind(this)}.bind(this),n=function(a){return function(b){l.push(a.load(b))}},o=[];for(e=0,f=a.length;f>e;e++){for(b=a[e],k.forEach(n(a[e])),g=0,h=i.columns.length;h>g;g++)i.columns[g].push(void 0);o.push(jQuery.when.apply(jQuery,l).then(m(e)))}return jQuery.when.apply(jQuery,o).then(function(){return i})},_add_id:function(a,b){a in this.ids||(this.ids[a]=[]),this.ids[a].push(b)},display:function(a){var b=this.update_data(a);return b.done(function(a){c3.generate(this._c3_config(a))}.bind(this)),b},_c3_config:function(a){var b={};b.bindto="#"+this.el.attr("id"),b.data=a,b.data.type=this._chart_type,b.data.x="labels",b.data.onclick=this.action.bind(this);var c=this.xfield.type;if("date"==c||"datetime"==c){var d,e,f;e=this.view.screen.context.date_format||"%x",f="%X",d="datetime"==c?function(a){return Sao.common.format_datetime(e,f,moment(a))}:function(a){return Sao.common.format_date(e,moment(a))},b.axis={x:{type:"timeseries",tick:{format:d}}}}else b.axis={x:{type:"category"}};for(var g={},h=0;h<this.yfields.length;h++){var i=this.yfields[h];i.color&&(g[i.name]=i.color)}return b.data.color=function(a,b){var c=b.id||b;return g[c]||a},b},action:function(a,b){var c=this.ids[this._action_key(a)],d=jQuery.extend({},this.view.screen.context);delete d.active_ids,delete d.active_id,Sao.Action.exec_keyword("graph_open",{model:this.view.screen.model_name,id:c[0],ids:c},d,!1)},_action_key:function(a){return a.x}}),Sao.View.Graph.VerticalBar=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"bar"}),Sao.View.Graph.HorizontalBar=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"bar",_c3_config:function(a){var b=Sao.View.Graph.HorizontalBar._super._c3_config.call(this,a);b.axis.rotated=!0}}),Sao.View.Graph.Line=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"line"}),Sao.View.Graph.Pie=Sao.class_(Sao.View.Graph.Chart,{_chart_type:"pie",_c3_config:function(a){var b,c,d,e,f=Sao.View.Graph.Pie._super._c3_config.call(this,a),g=[],h={};for(b=0,c=a.columns.length;c>b;b++)"labels"==a.columns[b][0]?d=a.columns[b].slice(1):e=a.columns[b].slice(1);delete f.axis,delete f.data.x;var i,j=this.xfield.type;if("date"==j||"datetime"==j){var k=this.view.screen.context.date_format||"%x",l=k+" %X";i="datetime"==j?function(a){return Sao.common.format_datetime(l,a)}:function(a){return Sao.common.format_date(k,a)}}var m;for(b=0,c=d.length;c>b;b++)m=d[b],i&&(m=i(m)),g.push([b,e[b]]),h[b]=m;return f.data.columns=g,f.data.names=h,f},_add_id:function(a,b){var c=this.xfield.type;if("date"==c||"datetime"==c){var d=this.view.screen.context.date_format||"%x",e=d+" %X";a="datetime"==c?Sao.common.format_datetime(e,a):Sao.common.format_date(d,a)}Sao.View.Graph.Pie._super._add_id.call(this,a,b)},_action_key:function(a){return a.id}})}(),function(){"use strict";Sao.View.Calendar=Sao.class_(Sao.View,{init:function(a,b){Sao.View.Calendar._super.init.call(this,a,b),this.processing=!0,this.view_type="calendar",this.el=jQuery("<div/>",{"class":"calendar"});var c=Sao.i18n.getlang();c=c.slice(0,2);var d="month";"week"==this.attributes.mode&&(d=this.get_week_view()),this.el.fullCalendar({defaultView:d,header:{left:"prev,next",center:"title",right:" month,"+this.get_week_view()},timeFormat:"H:mm",events:this.get_events.bind(this),locale:c,buttonIcons:!1,eventRender:this.event_render.bind(this),eventResize:this.event_resize.bind(this),eventDrop:this.event_drop.bind(this),eventClick:this.event_click.bind(this),dayClick:this.day_click.bind(this)}),this.fields=[],b.find("calendar").children().each(function(a,b){"field"==b.tagName&&this.fields.push(b.attributes.name.value)}.bind(this)),this.el.fullCalendar("changeView",d)},get_colors:function(a){var b={};return b.text_color="black",this.attributes.color&&(b.text_color=a.field_get(this.attributes.color)),b.background_color="lightblue",this.attributes.background_color&&(b.background_color=a.field_get(this.attributes.background_color)),b},display:function(){this.el.fullCalendar("render"),this.processing||this.el.fullCalendar("refetchEvents")},insert_event:function(a){var b=this.screen.model.fields[this.fields[0]].get_client(a),c=a.field_get_client(this.attributes.dtstart),d=null;this.attributes.dtend&&(d=a.field_get_client(this.attributes.dtend));for(var e=!0,f=[],g=1;g<this.fields.length;g++)f.push(this.screen.model.fields[this.fields[g]].get_client(a));if(f=f.join("\n"),c){if(d&&d.isDateTime?e=!1:d&&!d.isSame(c)&&"calendar"==this.screen.current_view.view_type&&d.add(1,"day"),d&&c>d)return;var h=this.get_colors(a),i={title:b,start:c,end:d,allDay:e,editable:!0,color:h.background_color,textColor:h.text_color,record:a,description:f};this.events.push(i)}},get_events:function(a,b,c,d){this.processing=!0,this.start=Sao.DateTime(a.utc()),this.end=Sao.DateTime(b.utc());var e=jQuery.when();if("form"!=this.screen.current_view.view_type){var f=this.screen.screen_container.get_text();e=this.screen.search_filter(f)}this.events=[];var g=[];e.then(function(){return this.screen.group.forEach(function(a){var b=[];this.fields.forEach(function(c){b.push(a.load(c))});var c=jQuery.when.apply(jQuery,b).then(function(){this.insert_event(a)}.bind(this));g.push(c)}.bind(this)),jQuery.when.apply(jQuery,g).then(function(){d(this.events)}.bind(this)).always(function(){this.processing=!1}.bind(this))}.bind(this))},get_week_view:function(){return"datetime"==this.screen.model.fields[this.attributes.dtstart].description.type?"agendaWeek":"basicWeek"},event_click:function(a,b,c){this.clicked_event||(this.clicked_event=!0,this.screen.set_current_record(a.record),this.screen.switch_view().always(function(){this.clicked_event=!1}.bind(this)))},event_drop:function(a,b,c,d,e,f){var g=this.attributes.dtstart,h=this.attributes.dtend,i=a.record,j=(i.group,i.field_get(g)),k=j;h&&(k=i.field_get(h));var l=a.start,m=a.end;m!=j&&m||(m=l),j.isDateTime?(m=Sao.DateTime(m.format()).utc(),l=Sao.DateTime(l.format()).utc()):j.isSame(k)||(m.subtract(1,"day"),this.el.fullCalendar("refetchEvents")),l>=j?(h&&i.field_set_client(h,m),i.field_set_client(g,l)):(i.field_set_client(g,l),h&&i.field_set_client(h,m)),i.save()},event_resize:function(a,b,c,d,e,f){var g=this.attributes.dtend,h=a.record,i=(h.group,h.field_get(g)),j=a.end;i.isDateTime===!0?j=Sao.DateTime(j.format()).utc():(j.subtract(1,"day"),this.el.fullCalendar("refetchEvents")),j!=i&&j||(j=i),h.field_set_client(g,j),h.save()},event_render:function(a,b,c){this.screen.model.fields.date&&"calendar"==this.screen.view_name&&b.find(".fc-time").remove(),b.append(a.description),b.css("white-space","pre");var d=Sao.common.MODELACCESS.get(this.screen.model_name);d.write||(a.editable=!1)},day_click:function(a,b,c){var d=Sao.common.MODELACCESS.get(this.screen.model_name);d.create&&(this.date=a,this.screen.set_current_record(null),this.screen.new_())},current_domain:function(){if(!this.start&&!this.end)return[["id","=",-1]];var a=Sao.DateTime(this.start),b=Sao.DateTime(this.end),c=this.attributes.dtstart,d=this.attributes.dtend||c;return["OR",["AND",[c,">=",a],[c,"<",b]],["AND",[d,">=",a],[d,"<",b]],["AND",[c,"<",a],[d,">",b]]]},get_displayed_period:function(){var a=[];return this.start&&this.end&&a.push(this.start,this.end),a},set_default_date:function(a,b){var c=this.attributes.dtstart;"datetime"==a.model.fields[c].description.type&&(b=Sao.DateTime(b.format()).utc()),a.field_set_client(c,b)}})}(),function(){"use strict";Sao.Action={report_blob_url:void 0},Sao.Action.exec_action=function(a,b,c){function d(a){if(!b.model||!b.ids)return jQuery.when(a);var d=5,e=b.ids.slice(0,d);return Sao.rpc({method:"model."+b.model+".read",params:[e,["rec_name"],c]},Sao.Session.current_session).then(function(c){var e=c.map(function(a){return a.rec_name}).join(Sao.i18n.gettext(", "));return b.ids.length>d&&(e+=Sao.i18n.gettext(",…")),Sao.i18n.gettext("%1 (%2)",a,e)})}c=void 0===c?{}:jQuery.extend({},c);var e=Sao.Session.current_session;"date_format"in c||e.context.locale&&e.context.locale.date&&(c.date_format=e.context.locale.date),b=void 0===b?{}:jQuery.extend({},b),b.action_id=a.id;var f,g={};switch(a.type){case"ir.action.act_window":g.view_ids=!1,g.mode=null,jQuery.isEmptyObject(a.views)?jQuery.isEmptyObject(a.view_id)||(g.view_ids=[a.view_id[0]]):(g.view_ids=[],g.mode=[],a.views.forEach(function(a){g.view_ids.push(a[0]),g.mode.push(a[1])})),void 0===a.pyson_domain&&(a.pyson_domain="[]");var h={active_model:b.model||null,active_id:b.id||null,active_ids:b.ids};h=jQuery.extend(h,e.context);var i=jQuery.extend({},h);i._user=e.user_id,g.context=jQuery.extend({},c,new Sao.PYSON.Decoder(i).decode(a.pyson_context||"{}")),h=jQuery.extend(h,g.context),h=jQuery.extend(h,c);var j=jQuery.extend({},h);j.context=h,j._user=e.user_id;var k=new Sao.PYSON.Decoder(j);return g.domain=k.decode(a.pyson_domain),g.order=k.decode(a.pyson_order),g.search_value=k.decode(a.pyson_search_value||"[]"),g.tab_domain=[],a.domains.forEach(function(a,b){g.tab_domain.push([a[0],k.decode(a[1]),a[2]])}),f=jQuery.when(a.name),g.model=a.res_model||b.res_model,g.res_id=a.res_id||b.res_id,g.context_model=a.context_model,g.context_domain=a.context_domain,g.limit=a.limit,g.icon=a["icon.rec_name"]||"","form_relate"===(a.keyword||"")&&(f=d(a.name)),void f.then(function(a){g.name=a,Sao.Tab.create(g)});case"ir.action.wizard":return g.action=a.wiz_name,g.data=b,g.context=c,g.window=a.window,f=jQuery.when(a.name),"form_action"===(a.keyword||"form_action")&&(f=d(a.name)),void f.done(function(a){g.name=a,Sao.Wizard.create(g)});case"ir.action.report":return g.name=a.report_name,g.data=b,g.direct_print=a.direct_print,g.email_print=a.email_print,g.email=a.email,g.context=c,void Sao.Action.exec_report(g);case"ir.action.url":return void window.open(a.url,"_blank")}},Sao.Action.exec_keyword=function(a,b,c,d,e){void 0===d&&(d=!0),void 0===e&&(e=!1);var f=b.id,g={method:"model.ir.action.keyword.get_keyword",params:[a,[b.model,f],{}]},h=Sao.rpc(g,Sao.Session.current_session),i=function(a){var f={};for(var g in a){var h=a[g];f[h.name.replace(/_/g,"")]=h}var i=Sao.common.selection(Sao.i18n.gettext("Select your action"),f,e);return i.then(function(a){Sao.Action.exec_action(a,b,c)},function(){jQuery.isEmptyObject(f)&&d&&alert(Sao.i18n.gettext("No action defined."))})};return h.pipe(i)},Sao.Action.exec_report=function(a){a.context||(a.context={}),a.email||(a.email={});var b=jQuery.extend({},a.data),c=jQuery.extend({},Sao.Session.current_session.context);jQuery.extend(c,a.context),c.direct_print=a.direct_print,c.email_print=a.email_print,c.email=a.email;var d=Sao.rpc({method:"report."+a.name+".execute",params:[b.ids||[],b,c]},Sao.Session.current_session);d.done(function(a){var b=a[0],c=a[1],d=(a[2],a[3]),e=d+"."+b;Sao.common.download_file(c,e)})},Sao.Action.execute=function(a,b,c,d,e){c?Sao.rpc({method:"model."+c+".search_read",params:[[["action","=",a]],0,1,null,null,d]},Sao.Session.current_session).done(function(a){var f=a[0];if(e){var g={"ir.action.report":"form_report","ir.action.wizard":"form_action","ir.action.act_window":"form_relate"};f.keyword||(f.keyword=g[c])}Sao.Action.exec_action(f,b,d)}):Sao.rpc({method:"model.ir.action.read",params:[[a],["type"],d]},Sao.Session.current_session).done(function(c){Sao.Action.execute(a,b,c[0].type,d,e)})},Sao.Action.evaluate=function(a,b,c){a=jQuery.extend({},a);var d={};return"pyson_email"in a&&(d=c.expr_eval(a.pyson_email),jQuery.isEmptyObject(d)&&(d={})),"subject"in d||(d.subject=a.name.replace(/_/g,"")),a.email=d,a}}(),function(){"use strict";Sao.common={},Sao.common.BACKSPACE_KEYCODE=8,Sao.common.TAB_KEYCODE=9,Sao.common.RETURN_KEYCODE=13,Sao.common.ESC_KEYCODE=27,Sao.common.UP_KEYCODE=38,Sao.common.DOWN_KEYCODE=40,Sao.common.DELETE_KEYCODE=46,Sao.common.F2_KEYCODE=113,Sao.common.F3_KEYCODE=114,Sao.common.SELECTION_NONE=1,Sao.common.SELECTION_SINGLE=2,Sao.common.SELECTION_MULTIPLE=3,Sao.common.BIG_IMAGE_SIZE=Math.pow(10,6),Sao.common.compare=function(a,b){if(a.length!=b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]instanceof Array&&b[c]instanceof Array){if(!Sao.common.compare(a[c],b[c]))return!1}else if(a[c]!=b[c])return!1;return!0},Sao.common.contains=function(a,b){for(var c=0;c<a.length;c++)if(Sao.common.compare(a[c],b))return!0;return!1},Sao.common.intersect=function(a,b){for(var c=0,d=0,e=[];c<a.length&&d<b.length;)a[c]<b[d]?c++:a[c]>b[d]?d++:(e.push(a[c]),c++,d++);return e},Sao.common.click_press=function(a,b){return function c(d){return"keypress"!=d.type||d.which==Sao.common.RETURN_KEYCODE?(b&&jQuery(this).off("click keypress",null,c),a(d)):void 0}},Sao.common.product=function(a,b){b=b||1;for(var c=[],d=0;b>d;)c=c.concat(a),d++;var e=[[]];return c.forEach(function(a){var b=[];e.forEach(function(c){a.forEach(function(a){b.push(c.concat([a]))})}),e=b}),e},Sao.common.selection=function(a,b,c){void 0===c&&(c=!1);var d=jQuery.Deferred();if(jQuery.isEmptyObject(b))return d.fail(),d;var e=Object.keys(b).sort();if(1==e.length&&!c){var f=e[0];return d.resolve(b[f]),d}var g=new Sao.Dialog(a||Sao.i18n.gettext("Your selection:"),"selection-dialog");return e.forEach(function(a,b){jQuery("<div/>",{"class":"checkbox"}).append(jQuery("<label/>").append(jQuery("<input/>",{type:"radio",name:"selection",value:b})).append(" "+a)).appendTo(g.body)}),g.body.find("input").first().prop("checked",!0),jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){g.modal.modal("hide"),d.fail()}).appendTo(g.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){var a=g.body.find("input:checked").attr("value");g.modal.modal("hide"),d.resolve(b[e[a]])}).appendTo(g.footer),g.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),g.modal.modal("show"),d},Sao.common.moment_format=function(a){return a.replace("%a","ddd").replace("%A","dddd").replace("%w","d").replace("%d","DD").replace("%b","MMM").replace("%B","MMMM").replace("%m","MM").replace("%y","YY").replace("%Y","YYYY").replace("%H","HH").replace("%I","hh").replace("%p","A").replace("%M","mm").replace("%S","ss").replace("%f","SSS").replace("%z","ZZ").replace("%Z","zz").replace("%j","DDDD").replace("%U","ww").replace("%W","WW").replace("%c","llll").replace("%x","L").replace("%X","LTS").replace("%","%%")},Sao.common.date_format=function(a){if(jQuery.isEmptyObject(a)&&(a="%Y-%m-%d",Sao.Session.current_session)){var b=Sao.Session.current_session.context;b.locale&&b.locale.date&&(a=b.locale.date)}return Sao.common.moment_format(a)},Sao.common.format_time=function(a,b){return b?b.format(Sao.common.moment_format(a)):""},Sao.common.parse_time=function(a,b){if(jQuery.isEmptyObject(b))return null;var c=function(c){var d=a.indexOf(c);if(~d){var e=parseInt(b.slice(d,d+c.length),10);if(!isNaN(e))return e}return 0};return Sao.Time(c("%H"),c("%M"),c("%S"),c("%f"))},Sao.common.format_date=function(a,b){return b?b.format(Sao.common.moment_format(a)):""},Sao.common.parse_date=function(a,b){var c=moment(b,Sao.common.moment_format(a));return c=c.isValid()?Sao.Date(c.year(),c.month(),c.date()):null},Sao.common.format_datetime=function(a,b,c){return c?c.format(Sao.common.moment_format(a+" "+b)):""},Sao.common.parse_datetime=function(a,b,c){var d=moment(c,Sao.common.moment_format(a+" "+b));return d=d.isValid()?Sao.DateTime(d.year(),d.month(),d.date(),d.hour(),d.minute(),d.second(),d.millisecond()):null},Sao.common.timedelta={},Sao.common.timedelta.DEFAULT_CONVERTER={s:1},Sao.common.timedelta.DEFAULT_CONVERTER.m=60*Sao.common.timedelta.DEFAULT_CONVERTER.s,Sao.common.timedelta.DEFAULT_CONVERTER.h=60*Sao.common.timedelta.DEFAULT_CONVERTER.m,Sao.common.timedelta.DEFAULT_CONVERTER.d=24*Sao.common.timedelta.DEFAULT_CONVERTER.h,Sao.common.timedelta.DEFAULT_CONVERTER.w=7*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta.DEFAULT_CONVERTER.M=30*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta.DEFAULT_CONVERTER.Y=365*Sao.common.timedelta.DEFAULT_CONVERTER.d,Sao.common.timedelta._get_separator=function(){return{Y:Sao.i18n.gettext("Y"),M:Sao.i18n.gettext("M"),w:Sao.i18n.gettext("w"),d:Sao.i18n.gettext("d"),h:Sao.i18n.gettext("h"),m:Sao.i18n.gettext("m"),s:Sao.i18n.gettext("s")}},Sao.common.timedelta.format=function(a,b){if(!a)return"";b||(b=Sao.common.timedelta.DEFAULT_CONVERTER);var c=[];a=a.asSeconds();var d="";0>a&&(d="-"),a=Math.abs(a),b=Object.keys(b).map(function(a){return[a,b[a]]}),b.sort(function(a,b){return b[1]-a[1]});for(var e,f,g=[],h=0;h<b.length;h++){e=b[h][0],f=b[h][1];var i=Math.floor(a/f);a-=i*f,g.push(i)}for(h=0;h<b.length-3;h++)e=b[h][0],f=g[h],f&&c.push(f+Sao.common.timedelta._get_separator()[e]);if(jQuery(g.slice(-3)).is(function(a,b){return b})||jQuery.isEmptyObject(c)){var j=g.slice(-3,-1);j=("00"+j[0]).slice(-2)+":"+("00"+j[1]).slice(-2),(g.slice(-1)[0]||a)&&(j+=":"+("00"+g.slice(-1)[0]).slice(-2)),c.push(j)}return c=d+c.reduce(function(a,b){return a?a+" "+b:b}),a&&(jQuery(g.slice(-3)).is(function(a,b){return b})||(c+=" "),c+=(""+a.toFixed(6)).slice(1)),c},Sao.common.timedelta.parse=function(a,b){if(!a)return null;b||(b=Sao.common.timedelta.DEFAULT_CONVERTER);var c,d=Sao.common.timedelta._get_separator();for(var e in d)c=d[e],a=a.replace(c,c+" ");for(var f,g=0,h=a.split(" "),i=0;i<h.length;i++){var j=h[i];if(j.contains(":"))for(var k=j.split(":"),l=[b.h,b.m,b.s],m=0;m<Math.min(k.length,l.length);m++){var n=k[m],o=l[m];f=Math.abs(Number(n))*o,isNaN(f)||(g+=f)}else{var p=!1;for(var q in d)if(c=d[q],j.endsWith(c)){j=j.slice(0,-c.length),f=Math.abs(parseInt(j,10))*b[q],isNaN(f)||(g+=f),p=!0;break}p||(f=Math.abs(Number(j)),isNaN(f)||(g+=f))}}return a.contains("-")&&(g*=-1),Sao.TimeDelta(null,g)},Sao.common.ModelAccess=Sao.class_(Object,{init:function(){this.batchnum=100,this._access={}},load_models:function(a){var b=jQuery.Deferred();return a||(this._access={}),Sao.rpc({method:"model.ir.model.list_models",params:[{}]},Sao.Session.current_session).then(function(a){for(var c=[],d=function(a){this._access=jQuery.extend(this._access,a)},e=0;e<a.length;e+=this.batchnum){var f=a.slice(e,e+this.batchnum);c.push(Sao.rpc({method:"model.ir.model.access.get_access",params:[f,{}]},Sao.Session.current_session).then(d.bind(this)))}jQuery.when.apply(jQuery,c).then(b.resolve,b.reject)}.bind(this)),b},get:function(a){return this._access[a]||{}}}),Sao.common.MODELACCESS=new Sao.common.ModelAccess,Sao.common.ModelHistory=Sao.class_(Object,{init:function(){this._models=[]},load_history:function(){return this._models=[],Sao.rpc({method:"model.ir.model.list_history",params:[{}]},Sao.Session.current_session).then(function(a){this._models=a}.bind(this))},contains:function(a){return~this._models.indexOf(a)}}),Sao.common.MODELHISTORY=new Sao.common.ModelHistory,Sao.common.ViewSearch=Sao.class_(Object,{load_searches:function(){return this.searches={},Sao.rpc({method:"model.ir.ui.view_search.get_search",params:[{}]},Sao.Session.current_session).then(function(a){this.searches=a}.bind(this))},get:function(a){return this.searches[a]||[]},add:function(a,b,c){return Sao.rpc({method:"model.ir.ui.view_search.create",params:[[{model:a,name:b,domain:(new Sao.PYSON.Encoder).encode(c)}],{}]},Sao.Session.current_session).then(function(d){var e=d[0];void 0===this.searches[a]&&(this.searches[a]=[]),this.searches[a].push([e,b,c])}.bind(this))},remove:function(a,b){return Sao.rpc({method:"model.ir.ui.view_search.delete",params:[[b],{}]},Sao.Session.current_session).then(function(){for(var c=0;c<this.searches[a].length;c++){var d=this.searches[a][c];if(d[0]===b){this.searches[a].splice(c,1);break}}}.bind(this))}}),Sao.common.VIEW_SEARCH=new Sao.common.ViewSearch,Sao.common.humanize=function(a){for(var b=["bytes","KB","MB","GB","TB","PB"],c=0,d=b.length;d>c;c++){if(1e3>a)return a.toPrecision(4)+" "+b[c];a/=1e3}},Sao.common.EvalEnvironment=function(a,b){void 0===b&&(b="eval");var c;if("eval"==b)c=a.get_eval();else{c={};for(var d in a.model.fields){var e=a.model.fields[d];c[d]=e.get_on_change_value(a)}}return c.id=a.id,a.group.parent&&Object.defineProperty(c,"_parent_"+a.group.parent_name,{enumerable:!0,get:function(){return Sao.common.EvalEnvironment(a.group.parent,b)}}),c.get=function(a,b){return this.hasOwnProperty(a)?this[a]:b},c},Sao.common.selection_mixin={},Sao.common.selection_mixin.init=function(){this.selection=null,this.inactive_selection=[],this._last_domain=null,this._values2selection={},this._domain_cache={},void 0===this.nullable_widget&&(this.nullable_widget=!0)},Sao.common.selection_mixin.init_selection=function(a,b){a||(a={},(this.attributes.selection_change_with||[]).forEach(function(b){a[b]=null}));var c,d=JSON.stringify(a),e=this.attributes.selection||[],f=function(a){a=jQuery.extend([],a),(void 0===this.attributes.sort||this.attributes.sort)&&a.sort(function(a,b){return a[1].localeCompare(b[1])}),this.selection=jQuery.extend([],a),b&&b(this.selection)};e instanceof Array||d in this._values2selection?(d in this._values2selection&&(e=this._values2selection[d]),f.call(this,e),c=jQuery.when()):(c=jQuery.isEmptyObject(this.attributes.selection_change_with)?this.model.execute(e,[]):this.model.execute(e,[a]),c=c.then(function(a){return this._values2selection[d]=a,a}.bind(this)),c=c.then(f.bind(this))),this.inactive_selection=[],this._selection_prm=c},Sao.common.selection_mixin.update_selection=function(a,b,c){var d=function(){if(!b)return void(c&&c(this.selection));var d=b.get_domain(a);if("reference"==b.description.type&&(d=[]),"relation"in this.attributes){var e=b.get_context(a),f=JSON.stringify([d,e]);if(f in this._domain_cache&&(this.selection=this._domain_cache[f],this._last_domain=[d,e]),null!==this._last_domain&&Sao.common.compare(d,this._last_domain[0])&&JSON.stringify(e)==JSON.stringify(this._last_domain[1]))return void(c&&c(this.selection));var g=Sao.rpc({method:"model."+this.attributes.relation+".search_read",params:[d,0,null,null,["rec_name"],e]},a.model.session);g.done(function(a){var b=[];a.forEach(function(a){b.push([a.id,a.rec_name])}),this.nullable_widget&&b.push([null,""]),this._last_domain=d,this._domain_cache[f]=b,this.selection=jQuery.extend([],b),c&&c(this.selection)}.bind(this)),g.fail(function(){this._last_domain=null,this.selection=[],c&&c(this.selection)}.bind(this))}else{var h=this.attributes.selection_change_with||[],i=a._get_on_change_args(h);delete i.id,Sao.common.selection_mixin.init_selection.call(this,i,function(){Sao.common.selection_mixin.filter_selection.call(this,d,a,b),c&&c(this.selection)}.bind(this))}};this._selection_prm.done(d.bind(this))},Sao.common.selection_mixin.filter_selection=function(a,b,c){if(!jQuery.isEmptyObject(a)){var d=new Sao.common.DomainInversion;this.selection=this.selection.filter(function(b){var c={};return c[this.field_name]=b[0],d.eval_domain(a,c)}.bind(this))}},Sao.common.selection_mixin.get_inactive_selection=function(a){if(!this.attributes.relation)return jQuery.when([]);for(var b=0,c=this.inactive_selection.length;c>b;b++)if(a==this.inactive_selection[b][0])return jQuery.when(this.inactive_selection[b]);var d=Sao.rpc({method:"model."+this.attributes.relation+".read",params:[[a],["rec_name"],{}]},Sao.Session.current_session);return d.then(function(a){return this.inactive_selection.push([a[0].id,a[0].rec_name]),[a[0].id,a[0].rec_name]}.bind(this))},Sao.common.Button=Sao.class_(Object,{init:function(a,b){this.attributes=a,b?this.el=b:(this.el=jQuery("<button/>"),this.el.append(a.string||""),this.attributes.rule&&this.el.append(" ").append(jQuery("<span/>",{"class":"badge"}))),this.icon=this.el.children("img"),this.icon.length||(this.icon=jQuery("<img/>").prependTo(this.el),this.icon.hide()),this.el.addClass("btn btn-default"),this.el.attr("type","button"),this.icon.addClass("icon"),this.icon.attr("aria-hidden",!0),this.set_icon(a.icon)},set_icon:function(a){if(!a)return this.icon.attr("src",""),void this.icon.hide();var b=Sao.common.ICONFACTORY.register_icon(a);b.done(function(a){this.icon.attr("src",a),this.icon.show()}.bind(this))},set_state:function(a){var b;if(b=a?a.expr_eval(this.attributes.states||{}):{},b.invisible?this.el.hide():this.el.show(),this.el.prop("disabled",b.readonly),this.set_icon(b.icon||this.attributes.icon),this.attributes.rule){var c;c=a?a.get_button_clicks(this.attributes.name):jQuery.when(),c.then(function(a){var b=this.el.children(".badge"),c=[],d="";if(!jQuery.isEmptyObject(a)){for(var e in a)c.push(a[e]);d=Sao.i18n.gettext("By: ")+c.join(Sao.i18n.gettext(", "))}b.data("toggle","tooltip"),b.text(c.length||""),b.attr("title",d),b.tooltip()}.bind(this))}if((void 0===this.attributes.type||"class"===this.attributes.type)&&a)for(var d=a.group.parent;d;){
+if(d.has_changed()){this.el.prop("disabled",!1);break}d=d.group.parent}}}),Sao.common.udlex=Sao.class_(Object,{init:function(a){var b=Sao.class_(Object,{init:function(a){this.stream=a.split(""),this.i=0},read:function(a){if(void 0===a&&(a=1),this.i>=this.stream.length)return null;var b=this.stream.slice(this.i,this.i+a).join();return this.i+=a,b}});this.instream=new b(a),this.eof=null,this.commenters="",this.nowordchars=[":",">","<","=","!",'"',";","(",")"],this.whitespace=" 	\r\n",this.whitespace_split=!1,this.quotes='"',this.escape="\\",this.escapedquotes='"',this.state=" ",this.pushback=[],this.token=""},get_token:function(){if(this.pushback.length>0)return this.pushback.shift();var a=this.read_token();return a},read_token:function(){for(var a=!1,b=" ";;){var c=this.instream.read(1);if(null===this.state){this.token="";break}if(" "==this.state){if(!c){this.state=null;break}if(this.whitespace.contains(c)){if(this.token||a)break;continue}if(this.commenters.contains(c));else if(this.escape.contains(c))b="a",this.state=c;else if(~this.nowordchars.indexOf(c))if(this.quotes.contains(c))this.state=c;else{if(!this.whitespace_split){if(this.token=c,this.token||a)break;continue}this.token=c,this.state="a"}else this.token=c,this.state="a"}else if(this.quotes.contains(this.state)){if(a=!0,!c)throw"no closing quotation";c==this.state?this.state="a":this.escape.contains(c)&&this.escapedquotes.contains(this.state)?(b=this.state,this.state=c):this.token=this.token+c}else if(this.escape.contains(this.state)){if(!c)throw"no escaped character";this.quotes.contains(b)&&c!=this.state&&c!=b&&(this.token=this.token+this.state),this.token=this.token+c,this.state=b}else if("a"==this.state){if(!c){this.state=null;break}if(this.whitespace.contains(c)){if(this.state=" ",this.token||a)break;continue}if(this.commenters.contains(c));else if(this.quotes.contains(c))this.state=c;else if(this.escape.contains(c))b="a",this.state=c;else{if(~this.nowordchars.indexOf(c)&&!this.quotes.contains(c)&&!this.whitespace_split){if(this.pushback.unshift(c),this.state=" ",this.token)break;continue}this.token=this.token+c}}}var d=this.token;return this.token="",a||""!==d||(d=null),d},next:function(){var a=this.get_token();return a==this.eof?null:a}}),Sao.common.DomainParser=Sao.class_(Object,{OPERATORS:["!=","<=",">=","=","!","<",">"],init:function(a,b){this.fields={},this.strings={},this.update_fields(a),this.context=b},update_fields:function(a){for(var b in a){var c=a[b];(c.searchable||void 0===c.searchable)&&(this.fields[b]=c,this.strings[c.string.toLowerCase()]=c)}},parse:function(a){try{for(var b=new Sao.common.udlex(a),c=[];;){var d=b.next();if(null===d)break;c.push(d)}return c=this.group_operator(c),c=this.parenthesize(c),c=this.group(c),c=this.operatorize(c,"or"),c=this.operatorize(c,"and"),c=this.parse_clause(c),this.simplify(c)}catch(e){if("no closing quotation"==e)return this.parse(a+'"');throw e}},stringable:function(a){var b=function(a){if(!a)return!0;var b=function(a){return a instanceof Array};return(~["AND","OR"].indexOf(a[0])||b(a[0]))&&a.slice(1).every(b)?this.stringable(a):a[0]in this.fields||"rec_name"==a[0]}.bind(this);return a?(~["AND","OR"].indexOf(a[0])&&(a=a.slice(1)),a.every(b)):!0},string:function(a){var b=function(a){if(jQuery.isEmptyObject(a))return"";if("string"!=typeof a[0]||~["AND","OR"].indexOf(a[0]))return"("+this.string(a)+")";var b,c=a[0],d=a[1],e=a[2];if(c.endsWith(".rec_name")&&(c=c.slice(0,-9)),!(c in this.fields))return b=e.replace("%%","__"),b.startsWith("%")&&b.endsWith("%")&&(e=e.slice(1,-1)),this.quote(e);var f=this.fields[c],g=null;a.length>3&&(g=a[3]),d.contains("ilike")&&(b=e.replace("%%","__"),b.startsWith("%")&&b.endsWith("%")?e=e.slice(1,-1):b.contains("%")||(d="ilike"==d?"=":"!",e=e.replace("%%","%")));var h=this.default_operator(f);h==d.trim()?(d="",~this.OPERATORS.indexOf(e)&&(d='"" ')):d.contains(h)&&(d.contains("not")||d.contains("!"))&&(d=d.replace(h,"").replace("not","!").trim()),d.endsWith("in")&&(d="not in"==d?"!":"");var i=this.format_value(f,e,g);return~this.OPERATORS.indexOf(d)&&~["char","text","selection"].indexOf(f.type)&&""===e&&(i='""'),this.quote(f.string)+": "+d+i};if(b=b.bind(this),jQuery.isEmptyObject(a))return"";var c=" ";return"AND"!=a[0]&&"OR"!=a[0]||("OR"==a[0]&&(c=" or "),a=a.slice(1)),a.map(b).join(c)},completion:function(a){var b,c,d=[],e=this.parse(a),f=0;for(b=a.length;b>0&&(")"!=a[b]&&" "!=a[b]);b--)")"==a[b]&&(f+=1);var g=this.ending_clause(e),h=g[0],i=g[1],j=i-f,k=this.string(e);j>0&&(k=k.substring(0,k.length-j)),k!=a&&d.push(k);var l,m,n=function(a,b){return b>0?a.substring(0,b):a};if(null!==h&&0===f){var o=this.complete(h);for(b=0,c=o.length;c>b;b++)l=o[b],m=this.string(this.replace_ending_clause(e,l)),d.push(n(m,j))}if(a.length>0){if(" "!=a.substr(a.length-1,1))return d;if(a.length>=2||":"==a.substr(a.length-2,1))return d}var p,q,r;for(var s in this.strings){p=this.strings[s],q=this.default_operator(p),r="","ilike"!=q&&"not ilike"!=q||(r=this.likify(r));var t=this.append_ending_clause(e,[p.name,q,r],j),u=this.string(t);d.push(n(u,j))}return d},complete:function(a){var b,c,d,e,f=[];1==a.length?b=a[0]:3==a.length?(b=a[0],c=a[1],d=a[2]):(b=a[0],c=a[1],d=a[2],e=a[3],b.endsWith(".rec_name")&&(b=b.substring(0,b.length-9)));var g;"rec_name"==b&&("ilike"==c&&(g=d.replace(/%%/g,"__"),g.startsWith("%")||g.endsWith("%")?d=g.substring(1,g.length-1):~g.indexOf("%")&&(d=d.replace(/%%/g,"%")),c=null),b=d,d=""),void 0!==b&&null!==b||(b="");var h;if(!(b.toLowerCase()in this.strings||b in this.fields)){for(var i in this.strings)h=this.strings[i],h.string.toLowerCase().startsWith(b.toLowerCase())&&(c=this.default_operator(h),d="","ilike"==c&&(d=this.likify(d)),f.push([h.name,c,d]));return f}if(h=b in this.fields?this.fields[b]:this.strings[b.toLowerCase()],c)for(var j=this.complete_value(h,d),k=0,l=j.length;l>k;k++)f.push([h.name,c,j[k]]);else c=this.default_operator(h),d="","ilike"!=c&&"not ilike"!=c||(d=this.likify(d)),f.push([h.name,c,d]);return f},is_leaf:function(a){return a instanceof Array&&a.clause},ending_clause:function(a,b){if(void 0===b&&(b=0),0===a.length)return[null,b];var c=a[a.length-1];return this.is_leaf(c)?[c,b]:this.ending_clause(c,b+1)},replace_ending_clause:function(a,b){var c,d,e=[];for(c=0,d=a.length-1;d>c;c++)e.push(a[c]);return this.is_leaf(a[c])?e.push(b):e=e.concat(this.replace_ending_clause(a[c],b)),e},append_ending_clause:function(a,b,c){if(0===a.length)return[b];var d=a.slice(0,-1),e=a[a.length-1];return this.is_leaf(e)?(d.push(e),0===c&&d.push(b)):d.push(this.append_ending_clause(e,b,c-1)),d},complete_value:function(a,b){var c=function(){return b?[!0]:[!1]},d=function(){var c=[],d=null!==b?b:"";b instanceof Array&&(d=b[b.length-1]),d=d.replace(/^%*|%*$/g,"");var e,f,g,h;for(e=0,f=a.selection.length;f>e;e++)g=a.selection[e][0],h=a.selection[e][1].toLowerCase(),h.startsWith(d.toLowerCase())&&(b instanceof Array?c.push(b.slice(0,-1).concat([g])):c.push(g));return c},e=function(){var c=[],d=null!==b?b:"";b instanceof Array&&(d=b[b.length-1]),d=d.replace(/^%*|%*$/g,"");var e,f,g,h;for(e=0,f=a.selection.length;f>e;e++)g=a.selection[e][0],h=a.selection[e][1].toLowerCase(),h.startsWith(d.toLowerCase())&&(b instanceof Array?c.push(b.slice(0,-1).concat([g])):c.push(this.likify(g)));return c}.bind(this),f=function(){return[Sao.Date(),Sao.DateTime().utc()]},g=function(){return[Sao.Date()]},h=function(){return[Sao.Time()]},i={"boolean":c,selection:d,reference:e,datetime:f,date:g,time:h};return a.type in i?i[a.type]():[]},group_operator:function(a){var b=a[0],c=[];return a.slice(1).forEach(function(a){"="==a&&b&&~this.OPERATORS.indexOf(b+a)?(c.push(b+a),b=null):(null!==b&&c.push(b),b=a)}.bind(this)),null!==b&&c.push(b),c},parenthesize:function(a){var b=[],c=b,d=[];return a.forEach(function(a,b){void 0!==c&&("("==a?(d.push(c),c=c[c.push([])-1]):")"==a?c=d.pop():c.push(a))}),b},group:function(a){var b=[],c=function(a){var b=[],d=function(a){b.push([a])},e=a.indexOf(":");if(!~e)return a.forEach(d),b.forEach(function(a){a.clause=!0}),b;for(var f=function(a,c){return function(d){if(jQuery.isEmptyObject(a))b.push(d);else{var e;jQuery.isEmptyObject(c)?(e=a.concat(d),e.clause=!0,b.push(e)):(null!==d[0]&&c.push(d[0]),e=a.concat([c]),e.clause=!0,b.push(e)),a.splice(0,a.length)}}},g=0;e>g;g++){var h=a.slice(g,e).join(" ");if(h.toLowerCase()in this.strings){jQuery.isEmptyObject(a.slice(0,g))?d(null):a.slice(0,g).forEach(d),h=[h];var i=[""].concat(this.OPERATORS);e+1<a.length&&~i.indexOf(a[e+1])?(h=h.concat([a[e+1]]),e+=1):h=h.concat([null]);for(var j=[];e+2<a.length&&";"==a[e+2];)j.push(a[e+1]),e+=2;if(c(a.slice(e+1)).forEach(f(h,j)),!jQuery.isEmptyObject(h)){var k;jQuery.isEmptyObject(j)?(k=h.concat([null]),k.clause=!0,b.push(k)):(k=h.concat([j]),k.clause=!0,b.push(k))}break}}return b};c=c.bind(this);var d=[];return a.forEach(function(a){this.is_generator(a)?(c(d).forEach(function(a){Sao.common.compare(a,[null])||b.push(a)}),d=[],b.push(this.group(a))):d.push(a)}.bind(this)),c(d).forEach(function(a){Sao.common.compare(a,[null])||b.push(a)}),b},is_generator:function(a){return a instanceof Array&&void 0===a.clause},operatorize:function(a,b){var c=[];b=b||"or",a=jQuery.extend([],a);for(var d=function(a){return a instanceof Array?Sao.common.compare(a,[b]):a==b},e=a.shift();d(e);)e=a.shift();if(void 0===e)return c;this.is_generator(e)&&(e=this.operatorize(e,b));for(var f=null;!jQuery.isEmptyObject(a);)if(f=a.shift(),this.is_generator(f)&&!d(f)&&(f=this.operatorize(f,b)),d(f)){for(f=a.shift();d(f);)f=a.shift();this.is_generator(f)&&(f=this.operatorize(f,b)),void 0!==f?e=[b.toUpperCase(),e,f]:d(e)||(c.push([b.toUpperCase(),e]),e=null),f=null}else d(e)||c.push(e),e=f;return jQuery.isEmptyObject(a)&&(null===f||d(f)?null===e||d(e)||c.push(e):c.push(f)),c},_clausify:function(a){return a.clause=!0,a},parse_clause:function(a){var b=[];return a.forEach(function(a){if(this.is_generator(a))jQuery.merge(b,this.parse_clause(a));else if("OR"==a||"AND"==a)b.push(a);else if(1!=a.length||a[0]instanceof Array){if(3==a.length&&a[0].toLowerCase()in this.strings){var c=(a[0],a[1]),d=a[2],e=this.strings[a[0].toLowerCase()],f=null;if("reference"==e.type){var g=this.split_target_value(e,d);f=g[0],d=g[1]}if(c||(c=this.default_operator(e)),d instanceof Array&&(c="!"==c?"not in":"in"),"!"==c&&(c=this.negate_operator(this.default_operator(e))),~["integer","float","numeric","datetime","date","time"].indexOf(e.type)&&d&&d.contains("..")){var h=d.split("..",2),i=this.convert_value(e,h[0]),j=this.convert_value(e,h[1]);return void b.push([this._clausify([e.name,">=",i]),this._clausify([e.name,"<=",j])])}d=d instanceof Array?d.map(function(a){return this.convert_value(e,a)}.bind(this)):this.convert_value(e,d),c.contains("like")&&(d=this.likify(d)),f?b.push(this._clausify([e.name+".rec_name",c,d,f])):b.push(this._clausify([e.name,c,d]))}}else b.push(this._clausify(["rec_name","ilike",this.likify(a[0])]))}.bind(this)),b},likify:function(a){if(!a)return"%";var b=a.replace("%%","__");return b.contains("%")?a:"%"+a+"%"},quote:function(a){if("string"!=typeof a)return a;a.contains("\\")&&(a=a.replace(new RegExp("\\\\","g"),"\\\\")),a.contains('"')&&(a=a.replace(new RegExp('"',"g"),'\\"'));for(var b=[":"," ","(",")"].concat(this.OPERATORS),c=0;c<b.length;c++){var d=b[c];if(a.contains(d))return'"'+a+'"'}return a},default_operator:function(a){return~["char","text","many2one","many2many","one2many","reference"].indexOf(a.type)?"ilike":"="},negate_operator:function(a){switch(a){case"ilike":return"not ilike";case"=":return"!=";case"in":return"not in"}},time_format:function(a){return new Sao.PYSON.Decoder({}).decode(a.format)},split_target_value:function(a,b){var c=null;if("string"==typeof b)for(var d=0;d<a.selection.length;d++){var e=a.selection[d],f=e[0],g=e[1];if(b.toLowerCase().startsWith(g.toLowerCase()+",")){c=f,b=b.slice(g.length+1);break}}return[c,b]},convert_value:function(a,b){var c=function(){if("string"==typeof b)for(var c=0;c<a.selection.length;c++){var d=a.selection[c],e=d[0],f=d[1];if(b.toLowerCase()==f.toLowerCase())return e}return b},d={"boolean":function(){return"string"==typeof b?[Sao.i18n.gettext("y"),Sao.i18n.gettext("Yes"),Sao.i18n.gettext("True"),Sao.i18n.gettext("t"),"1"].some(function(a){return a.toLowerCase().startsWith(b.toLowerCase())}):Boolean(b)},"float":function(){var a=Number(b);return isNaN(a)||""===b||null===b?null:a},integer:function(){var a=parseInt(b,10);return isNaN(a)?null:a},numeric:function(){var a=new Sao.Decimal(b);return isNaN(a.valueOf())||""===b||null===b?null:a},selection:c,reference:c,datetime:function(){var c=Sao.common.parse_datetime(Sao.common.date_format(),this.time_format(a),b);return c||(c=Sao.common.parse_date(Sao.common.date_format(),b)),c}.bind(this),date:function(){return Sao.common.parse_date(Sao.common.date_format(),b)},time:function(){try{return Sao.common.parse_time(this.time_format(a),b)}catch(c){return null}}.bind(this),timedelta:function(){var c=null;return a.converter&&(c=this.context[a.converter]),Sao.common.timedelta.parse(b,c)}.bind(this),many2one:function(){return""===b?null:b}},e=d[a.type];return e?e():b},format_value:function(a,b,c){void 0===c&&(c=null);var d=function(){if(!b&&0!==b&&b!==new Sao.Decimal(0))return"";var a=String(b).split(".")[1];return a=a?a.length:0,b.toFixed(a)},e=function(){for(var c=0;c<a.selection.length;c++)if(a.selection[c][0]==b)return a.selection[c][1];return b||""},f=function(){if(!c)return e();for(var d=0;d<a.selection.length;d++)if(a.selection[d][0]==c){c=a.selection[d][1];break}return c+","+b},g={"boolean":function(){return b?Sao.i18n.gettext("True"):Sao.i18n.gettext("False")},integer:function(){return b||0===b?""+parseInt(b,10):""},"float":d,numeric:d,selection:e,reference:f,datetime:function(){return b?b.isDate||!(b.hour()||b.minute()||b.second())?Sao.common.format_date(Sao.common.date_format(),b):Sao.common.format_datetime(Sao.common.date_format(),this.time_format(a),b):""}.bind(this),date:function(){return Sao.common.format_date(Sao.common.date_format(),b)},time:function(){return b?Sao.common.format_time(this.time_format(a),b):""}.bind(this),timedelta:function(){if(!b||!b.valueOf())return"";var c=null;return a.converter&&(c=this.context[a.converter]),Sao.common.timedelta.format(b,c)}.bind(this),many2one:function(){return null===b?"":b}};if(b instanceof Array)return b.map(function(b){return this.format_value(a,b)}.bind(this)).join(";");var h=g[a.type];return h?this.quote(h(b)):null===b?"":this.quote(b)},simplify:function(a){return a instanceof Array&&!this.is_leaf(a)?1==a.length&&a[0]instanceof Array&&("AND"==a[0][0]||"OR"==a[0][0]||a[0][0]instanceof Array)?this.simplify(a[0]):2==a.length&&("AND"==a[0]||"OR"==a[0])&&a[1]instanceof Array?this.simplify(a[1]):(3==a.length&&("AND"==a[0]||"OR"==a[0])&&a[1]instanceof Array&&a[0]==a[1][0]&&(a=this.simplify(a[1]).concat([a[2]])),a.map(this.simplify.bind(this))):a}}),Sao.common.DomainInversion=Sao.class_(Object,{and:function(a,b){return a&&b},or:function(a,b){return a||b},OPERATORS:{"=":function(a,b){return a instanceof Array&&b instanceof Array?Sao.common.compare(a,b):a===b},">":function(a,b){return a>b},"<":function(a,b){return b>a},"<=":function(a,b){return b>=a},">=":function(a,b){return a>=b},"!=":function(a,b){return a instanceof Array&&b instanceof Array?!Sao.common.compare(a,b):a!==b},"in":function(a,b){return Sao.common.DomainInversion.in_(a,b)},"not in":function(a,b){return!Sao.common.DomainInversion.in_(a,b)},like:function(){return!0},ilike:function(){return!0},"not like":function(){return!0},"not ilike":function(){return!0},child_of:function(){return!0},"not child_of":function(){return!0}},locale_part:function(a,b,c){return void 0===c&&(c="id"),a===b?c:a.contains(".")?a.split(".").slice(1).join("."):a},is_leaf:function(a){return a instanceof Array&&a.length>2&&"string"==typeof a[1]},eval_leaf:function(a,b,c){void 0===c&&(c=this.and);var d=a[0],e=a[1],f=a[2];if(d.contains("."))return Boolean(b[d.split(".")[0]]);if("="==e&&(null===b[d]||void 0===b[d])&&c===this.and)return!0;var g=b[d];return g&&g._isAMomentObject&&!f&&(f=g.isDateTime?Sao.DateTime.min:Sao.Date.min),f&&f._isAMomentObject&&!g&&(g=f.isDateTime?Sao.DateTime.min:Sao.Date.min),"string"==typeof g&&f instanceof Array&&2==f.length?f=f.join(","):g instanceof Array&&"string"==typeof f&&2==g.length&&(g=g.join(",")),~["=","!="].indexOf(e)&&g instanceof Array&&"number"==typeof f&&(e={"=":"in","!=":"not in"}[e]),e in this.OPERATORS?this.OPERATORS[e](g,f):!0},inverse_leaf:function(a){return~["AND","OR"].indexOf(a)?a:this.is_leaf(a)?a[1].contains("child_of")?3==a.length?a:[a[3]].concat(a.slice(1)):a:a.map(this.inverse_leaf.bind(this))},filter_leaf:function(a,b,c){return~["AND","OR"].indexOf(a)?a:this.is_leaf(a)?a[0].startsWith(b)&&a.length>3&&a[3]!==c?["id","=",null]:a:a.map(function(a){return this.filter_leaf(a,b,c)}.bind(this))},eval_domain:function(a,b,c){return void 0===c&&(c=this.and),this.is_leaf(a)?this.eval_leaf(a,b,c):jQuery.isEmptyObject(a)&&c==this.and?!0:jQuery.isEmptyObject(a)&&c==this.or?!1:"AND"==a[0]?this.eval_domain(a.slice(1),b):"OR"==a[0]?this.eval_domain(a.slice(1),b,this.or):c(this.eval_domain(a[0],b),this.eval_domain(a.slice(1),b,c))},localize_domain:function(a,b,c){if(~["AND","OR",!0,!1].indexOf(a))return a;if(this.is_leaf(a)){if(a[1].contains("child_of"))return 3==a.length?a:[a[3]].concat(a.slice(1,-1));var d="id";"string"==typeof a[2]&&(d="rec_name");var e=c?3:4;return[this.locale_part(a[0],b,d)].concat(a.slice(1,e)).concat(a.slice(4))}return a.map(function(a){return this.localize_domain(a,b,c)}.bind(this))},simplify:function(a){return this.is_leaf(a)?a:~["OR","AND"].indexOf(a)?a:a instanceof Array&&1==a.length&&~["OR","AND"].indexOf(a[0])?[]:a instanceof Array&&1==a.length&&!this.is_leaf(a[0])?this.simplify(a[0]):a instanceof Array&&2==a.length&&~["AND","OR"].indexOf(a[0])?[this.simplify(a[1])]:a.map(this.simplify.bind(this))},merge:function(a,b){if(jQuery.isEmptyObject(a)||~["AND","OR"].indexOf(a))return[];var c="OR"==a[0]?"OR":"AND";return this.is_leaf(a)?[a]:void 0===b?[c].concat([].concat.apply([],a.map(function(a){return this.merge(a,c)}.bind(this)))):c==b?[].concat.apply([],a.map(function(a){return this.merge(a,c)}.bind(this))):[this.merge(a)]},concat:function(a,b){var c=[];return b&&c.push(b),a.forEach(function(a){jQuery.isEmptyObject(a)||c.push(a)}),this.simplify(this.merge(c))},unique_value:function(a){return a instanceof Array&&1==a.length&&!a[0][0].contains(".")&&"="==a[0][1]?[!0,a[0][1],a[0][2]]:[!1,null,null]},parse:function(a){var b=Sao.common.DomainInversion.And,c=Sao.common.DomainInversion.Or;if(this.is_leaf(a))return a;if(jQuery.isEmptyObject(a))return new b([]);if("OR"===a[0])return new c(a.slice(1));var d=0;return"AND"===a[0]&&(d=1),new b(a.slice(d))},domain_inversion:function(a,b,c){void 0===c&&(c={});var d=this.parse(a);return~d.variables.indexOf(b)?d.inverse(b,c):!0}}),Sao.common.DomainInversion.in_=function(a,b){if(a instanceof Array){if(b instanceof Array){for(var c=0,d=a.length;d>c;c++)if(~b.indexOf(a[c]))return!0;return!1}return Boolean(~a.indexOf(b))}return Boolean(~b.indexOf(a))},Sao.common.DomainInversion.And=Sao.class_(Object,{init:function(a){this.domain_inversion=new Sao.common.DomainInversion,this.branches=a.map(this.domain_inversion.parse.bind(this.domain_inversion)),this.variables=[];for(var b=0,c=this.branches.length;c>b;b++){var d=this.branches[b];this.domain_inversion.is_leaf(d)?this.variables.push(this.base(d[0])):d instanceof Sao.common.DomainInversion.And&&(this.variables=this.variables.concat(d.variables))}},base:function(a){return a.contains(".")?a.split(".")[0]:a},inverse:function(a,b){for(var c=Sao.common.DomainInversion,d=[],e=0,f=this.branches.length;f>e;e++){var g=this.branches[e];if(g instanceof c.And){var h=g.inverse(a,b),i="boolean"==typeof h;if(i){if(h)continue;return!1}d.push(h)}else if(this.domain_inversion.is_leaf(g)&&this.base(g[0])===a)d.push(g);else{var j=g[0];if(j in b&&!(j in b&&this.domain_inversion.eval_leaf(g,b,this.domain_inversion.and)))return!1;d.push(!0)}}return d=d.filter(function(a){return a!==!0}),jQuery.isEmptyObject(d)?!0:this.domain_inversion.simplify(d)}}),Sao.common.DomainInversion.Or=Sao.class_(Sao.common.DomainInversion.And,{inverse:function(a,b){var c=Sao.common.DomainInversion,d=[];if(!~this.variables.indexOf(a)&&!jQuery.isEmptyObject(this.variables.filter(function(a){return!(a in b)})))return!0;for(var e=0,f=this.branches.length;f>e;e++){var g=this.branches[e];if(g instanceof c.And){var h=g.inverse(a,b),i="boolean"==typeof h;if(!~this.variables.indexOf(a)){if(i&&h)return!0;continue}if(i){if(h)return!0;continue}d.push(h)}else if(this.domain_inversion.is_leaf(g)&&this.base(g[0])==a)d.push(g);else{var j=g[0];if(j=this.base(j),j in b&&this.domain_inversion.eval_leaf(g,b,this.domain_inversion.or))return!0;j in b&&!this.domain_inversion.eval_leaf(g,b,this.domain_inversion.or)&&d.push(!1)}}return d=d.filter(function(a){return a!==!1}),jQuery.isEmptyObject(d)?!1:this.domain_inversion.simplify(["OR"].concat(d))}}),Sao.common.guess_mimetype=function(a){return/.*odt$/.test(a)?"application/vnd.oasis.opendocument.text":/.*ods$/.test(a)?"application/vnd.oasis.opendocument.spreadsheet":/.*pdf$/.test(a)?"application/pdf":/.*docx$/.test(a)?"application/vnd.openxmlformats-officedocument.wordprocessingml.document":/.*doc/.test(a)?"application/msword":/.*xlsx$/.test(a)?"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":/.*xls/.test(a)?"application/vnd.ms-excel":"application/octet-binary"},Sao.common.LOCAL_ICONS=["tryton-attachment-hi","tryton-attachment","tryton-bookmark","tryton-cancel","tryton-clear","tryton-close","tryton-connect","tryton-copy","tryton-delete","tryton-dialog-error","tryton-dialog-information","tryton-dialog-warning","tryton-disconnect","tryton-executable","tryton-find-replace","tryton-find","tryton-folder-new","tryton-fullscreen","tryton-go-home","tryton-go-jump","tryton-go-next","tryton-go-previous","tryton-help","tryton-icon","tryton-list-add","tryton-list-remove","tryton-locale","tryton-lock","tryton-log-out","tryton-mail-message-new","tryton-mail-message","tryton-new","tryton-ok","tryton-open","tryton-preferences-system-session","tryton-preferences-system","tryton-preferences","tryton-print-email","tryton-print-open","tryton-print","tryton-refresh","tryton-save-as","tryton-save","tryton-star","tryton-start-here","tryton-system-file-manager","tryton-system","tryton-text-background","tryton-text-foreground","tryton-text-markup","tryton-undo","tryton-unstar","tryton-web-browser"],Sao.common.IconFactory=Sao.class_(Object,{batchnum:10,name2id:{},loaded_icons:{},tryton_icons:[],register_prm:jQuery.when(),load_icons:function(a){if(a=a||!1,!a)for(var b in this.load_icons)this.load_icons.hasOwnProperty(b)&&window.URL.revokeObjectURL(this.load_icons[b]);var c=new Sao.Model("ir.ui.icon");return c.execute("list_icons",[],{}).then(function(b){a||(this.name2id={},this.loaded_icons={}),this.tryton_icons=[];for(var c,d,e=0,f=b.length;f>e;e++)c=b[e][0],d=b[e][1],a&&d in this.loaded_icons||(this.tryton_icons.push([c,d]),this.name2id[d]=c)}.bind(this))},register_icon:function(a){if(!a)return jQuery.Deferred().reject();if(a in this.loaded_icons||~Sao.common.LOCAL_ICONS.indexOf(a))return jQuery.when(this.get_icon_url(a));if("pending"==this.register_prm.state()){var b=jQuery.Deferred();return this.register_prm.then(function(){this.register_icon(a).then(b.resolve,b.reject)}.bind(this)),b}var c;c=a in this.name2id?jQuery.when():this.load_icons(!0);var d=new Sao.Model("ir.ui.icon");return this.register_prm=c.then(function(){var b=function(a){var b,c;for(b=0,c=this.tryton_icons.length;c>b;b++){var d=this.tryton_icons[b];if(Sao.common.compare(d,a))break}return b}.bind(this),c=b([this.name2id[a],a]),e=Math.round(c-this.batchnum/2);e=0>e?0:e;var f=Math.round(c+this.batchnum/2),g=[];this.tryton_icons.slice(e,f).forEach(function(a){g.push(a[0])});var h=d.execute("read",[g,["name","icon"]],{});return h.then(function(c){return c.forEach(function(a){var c;if(navigator.userAgent.match(/firefox/i)){c="data:image/svg+xml;base64,"+window.btoa(unescape(encodeURIComponent(a.icon)));var d=new Image;d.src=c,d.onload=function(){var b=document.createElement("canvas");b.width=d.width,b.height=d.height;var e=b.getContext("2d");e.drawImage(d,0,0),b.toBlob(function(d){var e=c;c=window.URL.createObjectURL(d),this.loaded_icons[a.name]=c,jQuery(document).find("img").each(function(a,b){b.src==e&&(b.src=c)}),b.remove()}.bind(this),"image/png")}.bind(this)}else{var e=new Blob([a.icon],{type:"image/svg+xml"});c=window.URL.createObjectURL(e)}this.loaded_icons[a.name]=c,delete this.name2id[a.name],this.tryton_icons.splice(b([a.id,a.name]),1)}.bind(this)),this.get_icon_url(a)}.bind(this))}.bind(this)),this.register_prm},get_icon_url:function(a){return a in this.loaded_icons?this.loaded_icons[a]:"images/"+a+".svg"}}),Sao.common.ICONFACTORY=new Sao.common.IconFactory,Sao.common.UniqueDialog=Sao.class_(Object,{init:function(){this.running=!1},build_dialog:function(){var a=new Sao.Dialog("",this.class_);return a},run:function(){if(this.running)return jQuery.when();var a=Array.prototype.slice.call(arguments),b=jQuery.Deferred();a.push(b);var c=this.build_dialog.apply(this,a);return c.content.submit(function(a){c.footer.find("button.btn-primary").first().click(),a.preventDefault()}.bind(this)),this.running=!0,c.modal.modal("show"),c.modal.on("shown.bs.modal",function(){c.modal.find("input,select").filter(":visible").first().focus()}),b},close:function(a){a.modal.on("hidden.bs.modal",function(a){jQuery(this).remove()}),a.modal.modal("hide"),this.running=!1}}),Sao.common.MessageDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"message-dialog",build_dialog:function(a,b,c){var d=Sao.common.MessageDialog._super.build_dialog.call(this);return d.header.remove(),d.body.append(jQuery("<div/>",{"class":"alert alert-info",role:"alert"}).append(jQuery("<span/>",{"class":"glyphicon "+b,"aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Message: "))).append(jQuery("<span/>").append(a).css("white-space","pre-wrap"))),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve("ok")}.bind(this)).appendTo(d.footer),d},run:function(a,b){return Sao.common.MessageDialog._super.run.call(this,a,b||"glyphicon-info-sign")}}),Sao.common.message=new Sao.common.MessageDialog,Sao.common.WarningDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"warning-dialog",build_dialog:function(a,b,c){var d=Sao.common.WarningDialog._super.build_dialog.call(this),e=jQuery("<div/>",{"class":"alert alert-warning",role:"alert"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-alert","aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Warning: "))).append(jQuery("<h4/>").append(b).css("white-space","pre-wrap"));return a&&e.append(jQuery("<span/>").append(a).css("white-space","pre-wrap")),d.body.append(e),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve("ok")}.bind(this)).appendTo(d.footer),d}}),Sao.common.warning=new Sao.common.WarningDialog,Sao.common.UserWarningDialog=Sao.class_(Sao.common.WarningDialog,{class_:"user-warning-dialog",always:!1,_set_always:function(){this.always=jQuery(this).prop("checked")},build_dialog:function(a,b,c){var d=Sao.common.UserWarningDialog._super.build_dialog.call(this,a,b,c);return d.body.append(jQuery("<div/>").append(jQuery("<input/>",{type:"checkbox"}).change(this._set_always.bind(this))).append(jQuery("<span/>").text(Sao.i18n.gettext("Always ignore this warning.")))),d.body.append(jQuery("<p/>").text(Sao.i18n.gettext("Do you want to proceed?"))),d.footer.children().remove(),jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("No")).click(function(){this.close(d),c.reject()}.bind(this)).appendTo(d.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Yes")).click(function(){this.close(d),this.always&&c.resolve("always"),c.resolve("ok")}.bind(this)).appendTo(d.footer),d}}),Sao.common.userwarning=new Sao.common.UserWarningDialog,Sao.common.ConfirmationDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"confirmation-dialog",build_dialog:function(a){var b=Sao.common.ConfirmationDialog._super.build_dialog.call(this);return b.header.remove(),b.body.append(jQuery("<div/>",{"class":"alert alert-info",role:"alert"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-info-sign","aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Confirmation: "))).append(jQuery("<span/>").append(a).css("white-space","pre-wrap"))),b}}),Sao.common.SurDialog=Sao.class_(Sao.common.ConfirmationDialog,{build_dialog:function(a,b){var c=Sao.common.SurDialog._super.build_dialog.call(this,a);return jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c),b.reject()}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(c),b.resolve()}.bind(this)).appendTo(c.footer),c}}),Sao.common.sur=new Sao.common.SurDialog,Sao.common.Sur3BDialog=Sao.class_(Sao.common.ConfirmationDialog,{build_dialog:function(a,b){var c=Sao.common.SurDialog._super.build_dialog.call(this,a);return jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(c),b.resolve("cancel")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("No")).click(function(){this.close(c),b.resolve("ko")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Yes")).click(function(){this.close(c),b.resolve("ok")}.bind(this)).appendTo(c.footer),c}}),Sao.common.sur_3b=new Sao.common.Sur3BDialog,Sao.common.AskDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"ask-dialog",run:function(){var a=Array.prototype.slice.call(arguments);return 1==a.length&&a.push(!0),Sao.common.AskDialog._super.run.apply(this,a)},build_dialog:function(a,b,c){var d=Sao.common.AskDialog._super.build_dialog.call(this);d.header.remove();var e=jQuery("<input/>",{"class":"form-control",type:b?"input":"password",id:"ask-dialog-entry"});return d.body.append(jQuery("<div/>",{"class":"form-group"}).append(jQuery("<label/>",{"for":"ask-dialog-entry"}).append(a)).append(e)),jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(d),c.reject()}.bind(this)).appendTo(d.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("OK")).click(function(){this.close(d),c.resolve(e.val())}.bind(this)).appendTo(d.footer),d}}),Sao.common.ask=new Sao.common.AskDialog,Sao.common.ConcurrencyDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"ask-dialog",build_dialog:function(a,b,c,d){var e=Sao.common.ConcurrencyDialog._super.build_dialog.call(this);return e.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),e.add_title(Sao.i18n.gettext("Concurrency Exception")),e.body.append(jQuery("<div/>",{"class":"alert alert-warning",role:"alert"}).append(jQuery("<p/>").append(jQuery("<span/>",{"class":"glyphicon glyphicon-info-sign","aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Write Concurrency Warning: "))).append(Sao.i18n.gettext("This record has been modified while you were editing it."))).append(jQuery("<p/>").text(Sao.i18n.gettext("Choose:"))).append(jQuery("<ul/>").append(jQuery("<li/>").text(Sao.i18n.gettext('"Cancel" to cancel saving;'))).append(jQuery("<li/>").text(Sao.i18n.gettext('"Compare" to see the modified version;'))).append(jQuery("<li/>").text(Sao.i18n.gettext('"Write Anyway" to save your current version.'))))),jQuery("<button/>",{
+"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.close(e),d.reject()}.bind(this)).appendTo(e.footer),jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Compare")).click(function(){this.close(e),Sao.Tab.create({model:a,res_id:b,domain:[["id","=",b]],context:c,mode:["form","tree"]}),d.reject()}.bind(this)).appendTo(e.footer),jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Write Anyway")).click(function(){this.close(e),d.resolve()}.bind(this)).appendTo(e.footer),e}}),Sao.common.concurrency=new Sao.common.ConcurrencyDialog,Sao.common.ErrorDialog=Sao.class_(Sao.common.UniqueDialog,{class_:"error-dialog",build_dialog:function(a,b,c){var d=Sao.common.ConcurrencyDialog._super.build_dialog.call(this);return d.modal.find(".modal-dialog").removeClass("modal-sm").addClass("modal-lg"),d.add_title(Sao.i18n.gettext("Application Error")),d.body.append(jQuery("<div/>",{"class":"alert alert-warning",role:"alert"}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-alert","aria-hidden":!0})).append(jQuery("<span/>",{"class":"sr-only"}).append(Sao.i18n.gettext("Warning: "))).append(jQuery("<p/>").append(jQuery("<pre/>").text(b))).append(jQuery("<p/>").append(jQuery("<a/>",{"class":"btn btn-link",href:Sao.config.roundup.url,target:"_blank"}).text(Sao.i18n.gettext("Report Bug"))))),jQuery("<button/>",{"class":"btn btn-primary",type:"button"}).append(Sao.i18n.gettext("Close")).click(function(){this.close(d),c.resolve()}.bind(this)).appendTo(d.footer),d}}),Sao.common.error=new Sao.common.ErrorDialog,Sao.common.Processing=Sao.class_(Object,{queries:0,timeout:500,init:function(){this.el=jQuery("<div/>",{id:"processing","class":"text-center"}),this.el.append(jQuery("<span/>",{"class":"label label-info",text:Sao.i18n.gettext("Processing...")})),this.el.hide(),jQuery(function(){this.el.appendTo("body")}.bind(this))},show:function(){return window.setTimeout(function(){this.queries+=1,this.el.show()}.bind(this),this.timeout)},hide:function(a){window.clearTimeout(a),this.queries>0&&(this.queries-=1),this.queries<=0&&(this.queries=0,this.el.hide())}}),Sao.common.processing=new Sao.common.Processing,Sao.common.InputCompletion=Sao.class_(Object,{init:function(a,b,c,d){a.is("input")?(a.wrap('<div class="dropdown"/>'),this.dropdown=a.parent()):(a.addClass("dropdown"),this.dropdown=a),this.input=a.find("input").add(a.filter("input")).first(),this.input.attr("autocomplete","off"),jQuery("<span/>",{"data-toggle":"dropdown"}).appendTo(this.dropdown),this.menu=jQuery("<ul/>",{"class":"dropdown-menu",role:"listbox"}).appendTo(this.dropdown),this.separator=jQuery("<li/>",{role:"separator","class":"divider"}).appendTo(this.menu),this.separator.hide(),this.source=b,this.match_selected=c,this.format=d,this.action_activated=null,this._search_text=null,this.input.on("input",function(){window.setTimeout(this._input.bind(this),300,this.input.val())}.bind(this)),this.input.keydown(function(a){a.which==Sao.common.ESC_KEYCODE?this.dropdown.hasClass("open")&&this.menu.dropdown("toggle"):a.which==Sao.common.RETURN_KEYCODE&&(this.dropdown.hasClass("open")||this.menu.dropdown("toggle"))}.bind(this)),this.dropdown.on("hide.bs.dropdown",function(){this.input.focus(),this.input.closest(".treeview").css("overflow","")}.bind(this)),this.dropdown.on("show.bs.dropdown",function(){this.input.closest(".treeview").css("overflow","visible")}.bind(this))},set_actions:function(a,b){return void 0!==b&&(this.action_activated=b),this.menu.find("li.action").remove(),jQuery.isEmptyObject(a)?void this.separator.hide():(this.separator.show(),void a.forEach(function(a){var b=a[0],c=a[1];jQuery("<li/>",{"class":"action action-"+b}).append(jQuery("<a/>",{href:"#"}).append(this._format_action(c))).click(function(){this.action_activated&&this.action_activated(b),this.input.val("")}.bind(this)).appendTo(this.menu)},this))},_format:function(a){return this.format?this.format(a):a},_format_action:function(a){return this.format_action?this.format_action(a):a},_input:function(a){if(a==this.input.val()){var b;b=this.source instanceof Array?jQuery.when(source.filter(function(b){return b.toLowerCase().startsWith(a.toLowerCase())})):this.source(a),b.then(function(b){a==this.input.val()&&this._set_selection(b)}.bind(this))}},_set_selection:function(a){void 0===a&&(a=[]),this.menu.find("li.completion").remove(),a.reverse().forEach(function(a){jQuery("<li/>",{"class":"completion"}).append(jQuery("<a/>",{href:"#"}).append(this._format(a))).click(function(){this.match_selected&&this.match_selected(a),this.input.focus()}.bind(this)).prependTo(this.menu)},this),this.input.val()?this.dropdown.hasClass("open")||this.menu.dropdown("toggle"):this.dropdown.hasClass("open")&&this.menu.dropdown("toggle")}}),Sao.common.get_completion=function(a,b,c,d){var e=function(a){return a.rec_name},f=new Sao.common.InputCompletion(a,b,c,e);f.set_actions([["search",Sao.i18n.gettext("Search...")],["create",Sao.i18n.gettext("Create...")]],d)},Sao.common.update_completion=function(a,b,c,d,e){var f=a.val();if(!f||!d)return jQuery.when();void 0===e&&(e=c.get_domain(b));var g=c.get_context(b);e=[["rec_name","ilike","%"+f+"%"],e];var h=new Sao.Model(d);return h.execute("search_read",[e,0,Sao.config.limit,null,["rec_name"]],g)},Sao.common.Paned=Sao.class_(Object,{init:function(a){var b;this._orientation=a,this.el=jQuery("<div/>"),"horizontal"==a?(b=jQuery("<div/>",{"class":"row"}).appendTo(this.el),this.child1=jQuery("<div/>",{"class":"col-md-6"}).appendTo(b),this.child2=jQuery("<div/>",{"class":"col-md-6"}).appendTo(b)):"vertical"==a&&(this.child1=jQuery("<div/>",{"class":"row"}).appendTo(this.el),this.child2=jQuery("<div/>",{"class":"row"}).appendTo(this.el))},get_child1:function(){return this.child1},get_child2:function(){return this.child2}}),Sao.common.get_focus_chain=function(a){var b=a.find("input","textarea");return b.sort(function(a,b){if("tabindex"in a.attributes&&"tabindex"in b.attributes){var c=parseInt(a.attributes.tabindex.value),d=parseInt(b.attributes.tabindex.value);return c-d}return"tabindex"in a.attributes?-1:"tabindex"in b.attributes?1:0}),b},Sao.common.find_focusable_child=function(a){var b,c,d,e;if(!a.is(":visible"))return null;if(~["input","select","textarea"].indexOf(a[0].tagName.toLowerCase()))return a;for(d=Sao.common.get_focus_chain(a),b=0,c=d.length;c>b;b++)if(e=Sao.common.find_focusable_child(jQuery(d[b])))return e},Sao.common.find_first_focus_widget=function(a,b){var c,d,e,f,g;if(1==b.length)return jQuery(b[0]);for(e=Sao.common.get_focus_chain(a),c=0;c<e.length;c++){for(f=[],d=0;d<b.length;d++)g=jQuery(b[d]).closest(e[c]).length>0,g&&f.push(b[d]);if(f.length>0)return Sao.common.find_first_focus_widget(jQuery(e[c]),f)}},Sao.common.apply_label_attributes=function(a,b,c){b?a.removeClass("editable required"):(a.addClass("editable"),c?a.addClass("required"):a.removeClass("required"))},Sao.common.download_file=function(a,b){var c=Sao.common.guess_mimetype(b?b.split(".").pop():void 0),d=new Blob([a],{type:c}),e=window.URL.createObjectURL(d),f=new Sao.Dialog(Sao.i18n.gettext("Download")),g=function(){f.modal.modal("hide")},h=jQuery("<a/>",{href:e,download:b,text:b,target:"_blank"}).appendTo(f.body).append(jQuery("<span/>",{"class":"glyphicon glyphicon-download-alt"})).click(g);jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Close")).click(g).appendTo(f.footer);f.modal.on("shown.bs.modal",function(){h[0].click()}),f.modal.modal("show"),f.modal.on("hidden.bs.modal",function(){jQuery(this).remove(),window.URL.revokeObjectURL(this.blob_url)})},Sao.common.ellipsize=function(a,b){if(a.length<=b)return a;var c=Sao.i18n.gettext("...");return a.slice(0,b-c.length)+c}}(),function(){"use strict";Sao.Window={},Sao.Window.InfoBar=Sao.class_(Object,{init:function(){this.text=jQuery("<span/>"),this.text.css("white-space","pre-wrap"),this.el=jQuery("<div/>",{"class":"alert infobar",role:"alert"}).append(jQuery("<button/>",{type:"button","class":"close","aria-label":Sao.i18n.gettext("Close")}).append(jQuery("<span/>",{"aria-hidden":!0}).append("×")).click(function(){this.el.hide()}.bind(this))).append(this.text),this.el.hide()},message:function(a,b){a?(this.el.removeClass("alert-success alert-info alert-warning alert-danger"),this.el.addClass("alert-"+(b||"info")),this.text.text(a),this.el.show()):this.el.hide()}}),Sao.Window.Form=Sao.class_(Object,{init:function(a,b,c){c=c||{},this.screen=a,this.callback=b,this.many=c.many||0,this.domain=c.domain||null,this.context=c.context||null,this.save_current=c.save_current;var d=jQuery.when(c.title||"");d.then(function(a){this.title=a}.bind(this)),this.prev_view=a.current_view,this.screen.screen_container.alternate_view=!0,this.info_bar=new Sao.Window.InfoBar;for(var e=c.view_type||"form",f=jQuery.when(),g=[],h=0,i=this.screen.views.length;i>h;h++)g.push(this.screen.views[h].view_type);~g.indexOf(e)||~this.screen.view_to_load.indexOf(e)||(f=this.screen.add_view_id(null,e));var j=f.then(function(){return this.screen.switch_view(e).done(function(){c.new_&&this.screen.new_(void 0,c.rec_name)}.bind(this))}.bind(this)),k=new Sao.Dialog("","window-form","lg");this.el=k.modal;var l=this.screen.attributes.readonly||this.screen.group.get_readonly();if("form"==e&&k.footer.append(jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(!c.new_&&this.screen.current_record.id<0?Sao.i18n.gettext("Delete"):Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this))),c.new_&&this.many&&k.footer.append(jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("New")).click(function(){this.response("RESPONSE_ACCEPT")}.bind(this))),this.save_current?k.footer.append(jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("Save"))):k.footer.append(jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK"))),k.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),"tree"==e){var m=jQuery("<div/>",{"class":"window-form-toolbar"}).appendTo(k.body),n=jQuery("<div/>",{"class":"input-group input-group-sm"}).appendTo(m);this.wid_text=jQuery("<input/>",{type:"input"}).appendTo(m),this.wid_text.hide();var o=jQuery("<div/>",{"class":"input-group-btn"}).appendTo(n),p=Sao.common.MODELACCESS.get(this.screen.model_name);this.domain&&(this.wid_text.show(),this.but_add=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Add")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-plus"})).appendTo(o),this.but_add.click(this.add.bind(this)),this.but_add.prop("disabled",!p.read||l),this.but_remove=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Remove")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-minus"})).appendTo(o),this.but_remove.click(this.remove.bind(this)),this.but_remove.prop("disabled",!p.read||l)),this.but_new=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("New")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-edit"})).appendTo(o),this.but_new.click(this.new_.bind(this)),this.but_new.prop("disabled",!p.create||l),this.but_del=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Delete")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-trash"})).appendTo(o),this.but_del.click(this.delete_.bind(this)),this.but_del.prop("disabled",!p["delete"]||l),this.but_undel=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Undelete")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-repeat"})).appendTo(o),this.but_undel.click(this.undelete.bind(this)),this.but_undel.prop("disabled",!p["delete"]||l),this.but_previous=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Previous")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-chevron-left"})).appendTo(o),this.but_previous.click(this.previous.bind(this)),this.label=jQuery("<span/>",{"class":"btn"}).appendTo(o),this.label.text("(0, 0)"),this.but_next=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Next")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-chevron-right"})).appendTo(o),this.but_next.click(this.next.bind(this)),this.but_switch=jQuery("<button/>",{"class":"btn btn-default btn-sm",type:"button","aria-label":Sao.i18n.gettext("Switch")}).append(jQuery("<span/>",{"class":"glyphicon glyphicon-list-alt"})).appendTo(o),this.but_switch.click(this.switch_.bind(this))}var q=jQuery("<div/>").appendTo(k.body);k.body.append(this.info_bar.el),j.done(function(){d.done(k.add_title.bind(k)),q.append(this.screen.screen_container.alternate_viewport),this.el.modal("show")}.bind(this)),this.el.on("shown.bs.modal",function(a){this.screen.display().done(function(){this.screen.set_cursor()}.bind(this))}.bind(this)),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},add:function(){var a=jQuery.extend([],this.domain),b=this.screen.model_name,c=this.wid_text.val(),d=function(a){var b=jQuery.when();if(!jQuery.isEmptyObject(a)){for(var c=[],d=0,e=a.length;e>d;d++)c.push(a[d][0]);this.screen.group.load(c,!0),b=this.screen.display()}b.done(function(){this.screen.set_cursor()}.bind(this)),this.entry.val("")}.bind(this),e=new Sao.common.DomainParser;new Sao.Window.Search(b,d,{sel_multi:!0,context:this.context,domain:a,search_filter:e.quote(c)})},remove:function(){this.screen.remove(!1,!0,!1)},new_:function(){this.screen.new_()},delete_:function(){this.screen.remove(!1,!1,!1)},undelete:function(){this.screen.unremove()},previous:function(){this.screen.display_previous()},next:function(){this.screen.display_next()},switch_:function(){this.screen.switch_view()},response:function(a){var b;this.screen.current_view.set_value();var c=this.screen.group.get_readonly();if(~["RESPONSE_OK","RESPONSE_ACCEPT"].indexOf(a)&&!c&&this.screen.current_record)return void this.screen.current_record.validate().then(function(a){return a&&this.screen.attributes.pre_validate?this.screen.current_record.pre_validate():a}.bind(this)).then(function(c){var d=jQuery.Deferred();if(c&&this.save_current)this.screen.save_current().then(d.resolve,d.reject);else if(c&&"form"==this.screen.current_view.view_type){var e=this.screen.current_view,f=[];for(var g in e.widgets){var h=e.widgets[g];if(h.screen&&h.screen.attributes.pre_validate){var i=h.screen.current_record;i&&f.push(i.pre_validate())}}jQuery.when.apply(jQuery,f).then(d.resolve,d.reject)}else c?(this.info_bar.message(),d.resolve()):(this.info_bar.message(this.screen.invalid_message(),"danger"),d.reject());d.fail(function(){this.screen.display().done(function(){this.screen.set_cursor()}.bind(this))}.bind(this)),d.done(function(){"RESPONSE_ACCEPT"==a?(this.screen.new_(),this.screen.current_view.display().done(function(){this.screen.set_cursor()}.bind(this)),this.many-=1,0===this.many&&this.but_new.prop("disabled",!0)):(b=!0,this.callback(b),this.destroy())}.bind(this))}.bind(this));if("RESPONSE_CANCEL"==a&&!c&&this.screen.current_record){if(b=!1,this.screen.current_record.id<0||this.save_current)this.screen.cancel_current();else if(this.screen.current_record.has_changed())return this.screen.current_record.cancel(),void this.screen.current_record.reload().always(function(){this.callback(b),this.destroy()}.bind(this))}else b="RESPONSE_CANCEL"!=a;this.callback(b),this.destroy()},destroy:function(){this.screen.screen_container.alternate_view=!1,this.screen.screen_container.alternate_viewport.children().detach(),this.prev_view&&this.screen.switch_view(this.prev_view.view_type),this.el.modal("hide")}}),Sao.Window.Attachment=Sao.class_(Sao.Window.Form,{init:function(a,b){this.resource=a.model.name+","+a.id,this.attachment_callback=b;var c=jQuery.extend({},a.get_context()),d=new Sao.Screen("ir.attachment",{domain:[["resource","=",this.resource]],mode:["tree","form"],context:c,exclude_field:"resource"});d.switch_view().done(function(){d.search_filter()});var e=a.rec_name().then(function(a){return Sao.i18n.gettext("Attachments (%1)",a)});Sao.Window.Attachment._super.init.call(this,d,this.callback,{view_type:"tree",title:e})},callback:function(a){var b=jQuery.when();if(a){var c=this.screen.group.model.fields.resource;this.screen.group.forEach(function(a){c.set_client(a,this.resource)}.bind(this)),b=this.screen.save_current()}this.attachment_callback&&b.always(this.attachment_callback.bind(this))}}),Sao.Window.Note=Sao.class_(Sao.Window.Form,{init:function(a,b){this.resource=a.model.name+","+a.id,this.note_callback=b;var c=jQuery.extend({},a.get_context()),d=new Sao.Screen("ir.note",{domain:[["resource","=",this.resource]],mode:["tree","form"],context:c,exclude_field:"resource"});d.switch_view().done(function(){d.search_filter()});var e=a.rec_name().then(function(a){return Sao.i18n.gettext("Notes (%1)",a)});Sao.Window.Note._super.init.call(this,d,this.callback,{view_type:"tree",title:e})},callback:function(a){var b=jQuery.when();if(a){var c=this.screen.group.model.fields.resource,d=this.screen.group.model.fields.unread;this.screen.group.forEach(function(a){(a.get_loaded()||a.id<0)&&(c.set_client(a,this.resource),a._changed.unread||d.set_client(a,!1))}.bind(this)),b=this.screen.save_current()}this.note_callback&&b.always(this.note_callback.bind(this))}}),Sao.Window.Search=Sao.class_(Object,{init:function(a,b,c){c=c||{};var d=c.views_preload||{};this.model_name=a,this.domain=c.domain||[],this.context=c.context||{},this.sel_multi=c.sel_multi,this.callback=b,this.title=c.title||"";var e=new Sao.Dialog(Sao.i18n.gettext("Search %1",this.title),"","lg");this.el=e.modal,jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(e.footer),jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("Find")).click(function(){this.response("RESPONSE_APPLY")}.bind(this)).appendTo(e.footer),c.new_&&Sao.common.MODELACCESS.get(a).create&&jQuery("<button/>",{"class":"btn btn-default",type:"button"}).append(Sao.i18n.gettext("New")).click(function(){this.response("RESPONSE_ACCEPT")}.bind(this)).appendTo(e.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(e.footer),e.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),this.screen=new Sao.Screen(a,{mode:["tree"],context:this.context,domain:this.domain,view_ids:c.view_ids,views_preload:d,row_activate:this.activate.bind(this)}),this.screen.load_next_view().done(function(){this.screen.switch_view().done(function(){e.body.append(this.screen.screen_container.el),this.el.modal("show"),this.screen.display(),void 0!==c.search_filter&&this.screen.search_filter(c.search_filter)}.bind(this))}.bind(this)),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},activate:function(){this.response("RESPONSE_OK")},response:function(a){var b,c=[];if("RESPONSE_OK"==a)b=this.screen.current_view.selected_records();else{if("RESPONSE_APPLY"==a)return void this.screen.search_filter();if("RESPONSE_ACCEPT"==a){var d=new Sao.Screen(this.model_name,{domain:this.domain,context:this.context,mode:["form"]}),e=function(a){if(a){var b=d.current_record;this.callback([[b.id,b._values.rec_name||""]])}else this.callback(null)};return this.el.modal("hide"),void new Sao.Window.Form(d,e.bind(this),{new_:!0,save_current:!0,title:this.title})}}if(b){var f,g;for(f in b)g=b[f],c.push([g.id,g._values.rec_name||""])}this.callback(c),this.el.modal("hide")}}),Sao.Window.Preferences=Sao.class_(Object,{init:function(a){this.callback=a;var b=new Sao.Dialog("Preferences","","lg");this.el=b.modal,jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(b.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(b.footer),b.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)),this.screen=new Sao.Screen("res.user",{mode:[]}),this.screen.attributes.readonly=!1,this.screen.group.set_readonly(!1),this.screen.group.skip_model_access=!0;var c=function(a){this.screen.add_view(a),this.screen.switch_view().done(function(){this.screen.new_(!1),this.screen.model.execute("get_preferences",[!1],{}).then(d.bind(this),this.destroy)}.bind(this))},d=function(a){var c;this.screen.current_record.cancel(),c=this.screen.current_record.set(a),this.screen.current_record.id=this.screen.model.session.user_id,c.then(function(){this.screen.current_record.validate(null,!0).then(function(){this.screen.display(!0)}.bind(this))}.bind(this)),b.body.append(this.screen.screen_container.el),this.el.modal("show")};this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()}),this.screen.model.execute("get_preferences_fields_view",[],{}).then(c.bind(this),this.destroy)},response:function(a){var b=function(){this.destroy(),this.callback()}.bind(this),c=jQuery.when();"RESPONSE_OK"==a&&(c=this.screen.current_record.validate().then(function(a){if(a){var b=jQuery.extend({},this.screen.get()),c=jQuery.extend({},Sao.Session.current_session.context),d=function(a){return{id:0,method:"model.res.user.set_preferences",params:[b,a,c]}};return new Sao.Login(d).run()}}.bind(this))),c.done(b)},destroy:function(){this.el.modal("hide")}}),Sao.Window.Revision=Sao.class_(Object,{init:function(a,b){this.callback=b;var c=new Sao.Dialog(Sao.i18n.gettext("Revision"),"","lg");this.el=c.modal,jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(c.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).appendTo(c.footer),c.content.submit(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this));var d=jQuery("<div/>",{"class":"form-group"}).appendTo(c.body);jQuery("<label/>",{"for":"revision",text:"Revision"}).appendTo(d),this.select=jQuery("<select/>",{"class":"form-control",id:"revision",placeholder:Sao.i18n.gettext("Revision")}).appendTo(d);var e=Sao.common.date_format(),f="%H:%M:%S.%f";this.select.append(jQuery("<option/>",{value:null,text:""})),a.forEach(function(a){a[2];a=a[0],this.select.append(jQuery("<option/>",{value:a.valueOf(),text:Sao.common.format_datetime(e,f,a)+" "+this.title}))}.bind(this)),this.el.modal("show"),this.el.on("hidden.bs.modal",function(a){jQuery(this).remove()})},response:function(a){var b=null;"RESPONSE_OK"==a&&(b=this.select.val(),b&&(b=Sao.DateTime(parseInt(b,10)))),this.el.modal("hide"),this.callback(b)}}),Sao.Window.CSV=Sao.class_(Object,{init:function(a){this.encodings=["866","ansi_x3.4-1968","arabic","ascii","asmo-708","big5","big5-hkscs","chinese","cn-big5","cp1250","cp1251","cp1252","cp1253","cp1254","cp1255","cp1256","cp1257","cp1258","cp819","cp866","csbig5","cseuckr","cseucpkdfmtjapanese","csgb2312","csibm866","csiso2022jp","csiso2022kr","csiso58gb231280","csiso88596e","csiso88596i","csiso88598e","csiso88598i","csisolatin1","csisolatin2","csisolatin3","csisolatin4","csisolatin5","csisolatin6","csisolatin9","csisolatinarabic","csisolatincyrillic","csisolatingreek","csisolatinhebrew","cskoi8r","csksc56011987","csmacintosh","csshiftjis","cyrillic","dos-874","ecma-114","ecma-118","elot_928","euc-jp","euc-kr","gb18030","gb2312","gb_2312","gb_2312-80","gbk","greek","greek8","hebrew","hz-gb-2312","ibm819","ibm866","iso-2022-cn","iso-2022-cn-ext","iso-2022-jp","iso-2022-kr","iso-8859-1","iso-8859-10","iso-8859-11","iso-8859-13","iso-8859-14","iso-8859-15","iso-8859-16","iso-8859-2","iso-8859-3","iso-8859-4","iso-8859-5","iso-8859-6","iso-8859-6-e","iso-8859-6-i","iso-8859-7","iso-8859-8","iso-8859-8-e","iso-8859-8-i","iso-8859-9","iso-ir-100","iso-ir-101","iso-ir-109","iso-ir-110","iso-ir-126","iso-ir-127","iso-ir-138","iso-ir-144","iso-ir-148","iso-ir-149","iso-ir-157","iso-ir-58","iso8859-1","iso8859-10","iso8859-11","iso8859-13","iso8859-14","iso8859-15","iso8859-2","iso8859-3","iso8859-4","iso8859-5","iso8859-6","iso8859-7","iso8859-8","iso8859-9","iso88591","iso885910","iso885911","iso885913","iso885914","iso885915","iso88592","iso88593","iso88594","iso88595","iso88596","iso88597","iso88598","iso88599","iso_8859-1","iso_8859-15","iso_8859-1:1987","iso_8859-2","iso_8859-2:1987","iso_8859-3","iso_8859-3:1988","iso_8859-4","iso_8859-4:1988","iso_8859-5","iso_8859-5:1988","iso_8859-6","iso_8859-6:1987","iso_8859-7","iso_8859-7:1987","iso_8859-8","iso_8859-8:1988","iso_8859-9","iso_8859-9:1989","koi","koi8","koi8-r","koi8-ru","koi8-u","koi8_r","korean","ks_c_5601-1987","ks_c_5601-1989","ksc5601","ksc_5601","l1","l2","l3","l4","l5","l6","l9","latin1","latin2","latin3","latin4","latin5","latin6","logical","mac","macintosh","ms932","ms_kanji","shift-jis","shift_jis","sjis","sun_eu_greek","tis-620","unicode-1-1-utf-8","us-ascii","utf-16","utf-16be","utf-16le","utf-8","utf8","visual","windows-1250","windows-1251","windows-1252","windows-1253","windows-1254","windows-1255","windows-1256","windows-1257","windows-1258","windows-31j","windows-874","windows-949","x-cp1250","x-cp1251","x-cp1252","x-cp1253","x-cp1254","x-cp1255","x-cp1256","x-cp1257","x-cp1258","x-euc-jp","x-gbk","x-mac-cyrillic","x-mac-roman","x-mac-ukrainian","x-sjis","x-user-defined","x-x-big5"],this.dialog=new Sao.Dialog(a,"csv","lg"),this.el=this.dialog.modal,this.fields={},this.fields_model={},jQuery("<button/>",{"class":"btn btn-link",type:"button"}).append(Sao.i18n.gettext("Cancel")).click(function(){this.response("RESPONSE_CANCEL")}.bind(this)).appendTo(this.dialog.footer),jQuery("<button/>",{"class":"btn btn-primary",type:"submit"}).append(Sao.i18n.gettext("OK")).click(function(a){this.response("RESPONSE_OK"),a.preventDefault()}.bind(this)).appendTo(this.dialog.footer);var b=jQuery("<div/>",{"class":"row"}).appendTo(this.dialog.body);jQuery("<hr/>").appendTo(this.dialog.body);var c=jQuery("<div/>",{"class":"col-md-4 column-fields"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("All Fields")})).appendTo(b);this.fields_all=jQuery("<ul/>",{"class":"list-unstyled"}).css("cursor","pointer").appendTo(c);var d=this.get_fields(this.screen.model_name).then(function(a){this.model_populate(a),this.view_populate(this.fields_model,this.fields_all)}.bind(this));this.column_buttons=jQuery("<div/>",{"class":"col-md-4"}).append("<label/>").appendTo(b);jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-plus"})).click(function(){this.fields_all.find(".bg-primary").each(function(a,b){this.sig_sel_add(b)}.bind(this))}.bind(this)).append(" "+Sao.i18n.gettext("Add")).appendTo(this.column_buttons);jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-minus"})).click(function(){this.fields_selected.children("li.bg-primary").remove()}.bind(this)).append(" "+Sao.i18n.gettext("Remove")).appendTo(this.column_buttons),jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-remove"})).click(function(){this.fields_selected.empty()}.bind(this)).append(" "+Sao.i18n.gettext("Clear")).appendTo(this.column_buttons),jQuery("<hr>").appendTo(this.column_buttons);var e=jQuery("<div/>",{"class":"col-md-4 column-fields"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("Fields Selected")})).appendTo(b);this.fields_selected=jQuery("<ul/>",{"class":"list-unstyled"}).css("cursor","pointer").appendTo(e),this.chooser_form=jQuery("<div/>",{"class":"form-inline"}).appendTo(this.dialog.body);var f=jQuery("<div/>",{"class":"row"}).appendTo(this.dialog.body),g=jQuery("<span/>",{"class":"glyphicon glyphicon-plus"}).css("cursor","pointer").html(" "),h=jQuery("<label/>",{text:Sao.i18n.gettext("CSV Parameters")}).css("cursor","pointer");jQuery("<div/>",{"class":"col-md-12"}).append(g).append(h).on("click",function(){g.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),this.expander_csv.collapse("toggle")}.bind(this)).appendTo(f),this.expander_csv=jQuery("<div/>",{id:"expander_csv","class":"collapse"}).appendTo(f);var i=jQuery("<label/>",{text:Sao.i18n.gettext("Delimiter:"),"class":"col-sm-2 control-label","for":"input-delimiter"});this.el_csv_delimiter=jQuery("<input/>",{type:"text","class":"form-control",id:"input-delimiter",size:"1",maxlength:"1",value:","}),jQuery("<div/>",{"class":"form-group"}).append(i).append(jQuery("<div/>",{"class":"col-sm-4"}).append(this.el_csv_delimiter)).appendTo(this.expander_csv);var j=jQuery("<label/>",{text:Sao.i18n.gettext("Quote Char:"),"class":"col-sm-2 control-label","for":"input-quotechar"});this.el_csv_quotechar=jQuery("<input/>",{type:"text","class":"form-control",id:"input-quotechar",size:"1",maxlength:"1",value:'"'}),jQuery("<div/>",{"class":"form-group"}).append(j).append(jQuery("<div/>",{"class":"col-sm-4"}).append(this.el_csv_quotechar)).appendTo(this.expander_csv);var k=jQuery("<label/>",{text:Sao.i18n.gettext("Encoding:"),"class":"col-sm-2 control-label","for":"input-encoding"});this.el_csv_encoding=jQuery("<select/>",{"class":"form-control",id:"input-encoding"});for(var l=0;l<this.encodings.length;l++)jQuery("<option/>",{val:this.encodings[l]}).html(this.encodings[l]).appendTo(this.el_csv_encoding);var m="utf-8";return"Win32"!=navigator.platform&&"Windows"!=navigator.platform||(m="cp1252"),this.el_csv_encoding.children('option[value="'+m+'"]').attr("selected","selected"),jQuery("<div/>",{"class":"form-group"}).append(k).append(jQuery("<div/>",{"class":"col-sm-4"}).append(this.el_csv_encoding)).appendTo(this.expander_csv),this.el.modal("show"),this.el.on("hidden.bs.modal",function(){jQuery(this).remove()}),d},get_fields:function(a){return Sao.rpc({method:"model."+a+".fields_get"},this.session)},on_row_expanded:function(a){var b=jQuery("<ul/>").css("list-style","none").insertAfter(a.view);this.children_expand(a).done(function(){this.view_populate(a.children,b)}.bind(this))},destroy:function(){this.el.modal("hide")}}),Sao.Window.Import=Sao.class_(Sao.Window.CSV,{init:function(a){this.screen=a,this.session=Sao.Session.current_session,this.fields_data={},this.fields_invert={},Sao.Window.Import._super.init.call(this,Sao.i18n.gettext("Import from CSV")),jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-search"})).click(function(){this.autodetect()}.bind(this)).append(" "+Sao.i18n.gettext("Auto-Detect")).appendTo(this.column_buttons);var b=jQuery("<label/>",{text:Sao.i18n.gettext("File to Import"),"class":"col-sm-6 control-label","for":"input-csv-file"});this.file_input=jQuery("<input/>",{type:"file",id:"input-csv-file"}),jQuery("<div/>",{"class":"form-group"}).append(b).append(jQuery("<div/>",{"class":"col-sm-6"}).append(this.file_input)).appendTo(this.chooser_form),jQuery("<hr>").insertAfter(this.chooser_form);var c=jQuery("<label/>",{text:Sao.i18n.gettext("Lines to Skip:"),"class":"col-sm-2 control-label","for":"input-skip"});this.el_csv_skip=jQuery("<input/>",{type:"number","class":"form-control",id:"input-skip",value:"0"}),jQuery("<div/>",{"class":"form-group"}).append(c).append(jQuery("<div/>",{"class":"col-sm-4"}).append(this.el_csv_skip)).appendTo(this.expander_csv)},sig_sel_add:function(a){a=jQuery(a);var b=a.attr("field"),c=jQuery("<li/>",{field:b}).html(a.attr("name")).click(function(a){a.ctrlKey?c.toggleClass("bg-primary"):jQuery(a.target).addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},view_populate:function(a,b){var c=Object.keys(a).sort(function(b,c){return a[c].string<a[b].string?-1:1}).reverse();c.forEach(function(c){
+var d=a[c].string||c,e=jQuery("<li/>",{field:a[c].field,name:a[c].name}).html(d).click(function(a){a.ctrlKey?e.toggleClass("bg-primary"):(this.fields_all.find("li").removeClass("bg-primary"),e.addClass("bg-primary"))}.bind(this)).appendTo(b);if(a[c].view=e,a[c].relation){e.prepend(" ");var f=jQuery("<i/>",{"class":"glyphicon glyphicon-plus"}).click(function(b){b.stopPropagation(),f.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),f.hasClass("glyphicon-minus")?this.on_row_expanded(a[c]):e.next("ul").remove()}.bind(this)).prependTo(e)}}.bind(this))},model_populate:function(a,b,c,d){b=b||this.fields_model,c=c||"",d=d||"",Object.keys(a).forEach(function(e){if(!a[e].readonly){var f=a[e].string||e;f=d+f;var g;g="one2many"==a[e].type?a[e].relation:null;var h={name:f,field:c+e,relation:g,string:a[e].string};b[e]=h,this.fields[c+e]=h,this.fields_invert[f]=c+e,g&&(h.children={})}}.bind(this))},children_expand:function(a){var b=jQuery.Deferred();return jQuery.isEmptyObject(a.children)?this.get_fields(a.relation).done(function(c){this.model_populate(c,a.children,a.field+"/",a.name+"/"),b.resolve(this)}.bind(this)):b.resolve(this),b.promise()},autodetect:function(){var a=this.file_input.val();return a?(this.fields_selected.empty(),this.el_csv_skip.val(1),void Papa.parse(this.file_input[0].files[0],{config:{delimiter:this.el_csv_delimiter.val(),quoteChar:this.el_csv_quotechar.val(),preview:1,encoding:this.el_csv_encoding.val()},error:function(a,b,c,d){Sao.common.warning(Sao.i18n.gettext("Error occured in loading the file"))},complete:function(a){a.data[0].forEach(function(a){if(a in this.fields_invert||a in this.fields)this.auto_select(a);else{var b=this.fields_model,c="",d=a.split("/");this.traverse(b,c,d,0)}}.bind(this))}.bind(this)})):void Sao.common.message.run(Sao.i18n.gettext("You must select an import file first"))},auto_select:function(a){var b,c;if(a in this.fields_invert)b=a,c=this.fields_invert[a];else{if(!(a in this.fields))return void Sao.common.warning.run(Sao.i18n.gettext("Error processing the file at field %1.",a),Sao.i18n.gettext("Error"));b=this.fields[a].name,c=[a]}var d=jQuery("<li/>",{field:c}).html(b).click(function(){d.addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},traverse:function(a,b,c,d){function e(e){a=f.children,b+=c[d]+"/",e.traverse(a,b,c,++d)}if(d>=c.length-1)return void this.auto_select(c.join("/"));var f,g,h=Object.keys(a);for(g=0;g<h.length;g++)if(f=a[h[g]],f.name==b+c[d]||f.field==b+c[d]){this.children_expand(f).done(e);break}return g==h.length?void this.auto_select(c.join("/")):void 0},response:function(a){if("RESPONSE_OK"==a){var b=[];this.fields_selected.children("li").each(function(a,c){b.push(c.getAttribute("field"))});var c=this.file_input.val();c?this.import_csv(c,b).then(function(){this.destroy()}.bind(this)):this.destroy()}else this.destroy()},import_csv:function(a,b){var c=this.el_csv_skip.val(),d=this.el_csv_encoding.val(),e=jQuery.Deferred();return Papa.parse(this.file_input[0].files[0],{config:{delimiter:this.el_csv_delimiter.val(),quoteChar:this.el_csv_quotechar.val(),encoding:d},error:function(a,b,c,d){Sao.common.warning.run(Sao.i18n.gettext("Error occured in loading the file")).always(e.reject)},complete:function(a){function d(a){return unescape(encodeURIComponent(a))}var f=[];a.data.pop(""),a.data.forEach(function(a,b){if(!(c>b)){var e=[];a.forEach(function(a){e.push(d(a))}),f.push(e)}}),Sao.rpc({method:"model."+this.screen.model_name+".import_data",params:[b,f,{}]},this.session).then(function(a){return Sao.common.message.run(Sao.i18n.ngettext("%1 record imported","%1 records imported",a))}).then(e.resolve,e.reject)}.bind(this)}),e.promise()}}),Sao.Window.Export=Sao.class_(Sao.Window.CSV,{init:function(a,b,c,d){this.ids=b,this.screen=a,this.session=Sao.Session.current_session,this.context=d,Sao.Window.Export._super.init.call(this,Sao.i18n.gettext("Export to CSV")).then(function(){c.forEach(function(a){this.sel_field(a)}.bind(this))}.bind(this));var e=jQuery("<div/>",{"class":"row"}).prependTo(this.dialog.body),f=jQuery("<div/>",{"class":"col-md-12"}).append(jQuery("<label/>",{text:Sao.i18n.gettext("Predefined Exports")})).appendTo(e);this.predef_exports_list=jQuery("<ul/>",{"class":"list-unstyled predef-exports"}).css("cursor","pointer").appendTo(f),f.append("<hr/>"),this.predef_exports={},this.fill_predefwin(),jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-floppy-save"})).click(function(){this.addreplace_predef()}.bind(this)).append(" "+Sao.i18n.gettext("Save Export")).appendTo(this.column_buttons),jQuery("<button/>",{"class":"btn btn-default btn-block",type:"button"}).append(jQuery("<i/>",{"class":"glyphicon glyphicon-floppy-remove"})).click(function(){this.remove_predef()}.bind(this)).append(" "+Sao.i18n.gettext("Delete Export")).appendTo(this.column_buttons),this.el_add_field_names=jQuery("<input/>",{type:"checkbox",checked:"checked"}),jQuery("<div/>",{"class":"form-group"}).append(jQuery("<div/>",{"class":"col-md-6"}).append(jQuery("<label/>",{text:" "+Sao.i18n.gettext("Add Field Names")}).prepend(this.el_add_field_names))).appendTo(this.expander_csv)},view_populate:function(a,b){var c=Object.keys(a).sort(function(b,c){return a[c].string<a[b].string?-1:1}).reverse();c.forEach(function(c){var d=a[c].path,e=jQuery("<li/>",{path:d}).html(a[c].string).click(function(a){a.ctrlKey?e.toggleClass("bg-primary"):(this.fields_all.find("li").removeClass("bg-primary"),e.addClass("bg-primary"))}.bind(this)).appendTo(b);if(a[c].view=e,a[c].children){e.prepend(" ");var f=jQuery("<i/>",{"class":"glyphicon glyphicon-plus"}).click(function(b){b.stopPropagation(),f.toggleClass("glyphicon-plus").toggleClass("glyphicon-minus"),f.hasClass("glyphicon-minus")?this.on_row_expanded(a[c]):e.next("ul").remove()}.bind(this)).prependTo(e)}}.bind(this))},model_populate:function(a,b,c,d){b=b||this.fields_model,c=c||"",d=d||"",Object.keys(a).forEach(function(e){var f=a[e],g=f.string||e,h=[{name:e,field:f,string:g}];"selection"==f.type&&h.push({name:e+".translated",field:f,string:Sao.i18n.gettext("%1 (string)",g)}),h.forEach(function(a){var e=c+a.name,f=a.string;c&&(f=d+a.string);var g={path:e,string:a.string,long_string:f,relation:a.field.relation};b[a.name]=g,this.fields[e]=g,-1==a.name.indexOf(".")&&a.field.relation&&(g.children={})}.bind(this))}.bind(this))},children_expand:function(a){var b=jQuery.Deferred();return jQuery.isEmptyObject(a.children)?this.get_fields(a.relation).done(function(c){this.model_populate(c,a.children,a.path+"/",a.string+"/"),b.resolve(this)}.bind(this)):b.resolve(this),b.promise()},sig_sel_add:function(a){a=jQuery(a);var b=a.attr("path");this.sel_field(b)},fill_predefwin:function(){Sao.rpc({method:"model.ir.export.search",params:[["resource","=",this.screen.model_name],{}]},this.session).done(function(a){Sao.rpc({method:"model.ir.export.read",params:[a,{}]},this.session).done(function(a){var b=[];a.forEach(function(a){for(var c=0;c<a.export_fields.length;b.push(a.export_fields[c++]));}),Sao.rpc({method:"model.ir.export.line.read",params:[b,{}]},this.session).done(function(b){var c={};b.forEach(function(a){c[a["export"]]=c[a["export"]]||[],c[a["export"]].push(a)}),a.forEach(function(a){this.predef_exports[a.id]=c[a.id].map(function(b){return b["export"]==a.id?b.name:void 0}),this.add_to_predef(a.id,a.name)}.bind(this)),this.predef_exports_list.children("li").first().focus()}.bind(this))}.bind(this))}.bind(this))},add_to_predef:function(a,b){var c=jQuery("<li/>",{text:b,export_id:a,tabindex:0}).on("keypress",function(a){var b=a.keyCode?a.keyCode:a.which;13!=b&&32!=b||c.click()}).click(function(a){c.addClass("bg-primary").siblings().removeClass("bg-primary"),this.sel_predef(jQuery(a.target).attr("export_id"))}.bind(this));this.predef_exports_list.append(c)},addreplace_predef:function(){for(var a=[],b=this.fields_selected.children("li"),c=0;c<b.length;c++)a.push(b[c].getAttribute("path"));if(0!==a.length){var d,e,f=this.predef_exports_list.children("li.bg-primary");0===f.length?(d=null,Sao.common.ask.run(Sao.i18n.gettext("What is the name of this export?")).then(function(b){b&&this.save_predef(b,a,f)}.bind(this))):(d=f.attr("export_id"),e=f.text(),Sao.common.sur.run(Sao.i18n.gettext("Override %1 definition?",e)).done(function(){this.save_predef(e,a,f),Sao.rpc({method:"model.ir.export.delete",params:[[d],{}]},this.session).then(function(){delete this.predef_exports[d]}.bind(this))}.bind(this)))}},save_predef:function(a,b,c){Sao.rpc({method:"model.ir.export.create",params:[[{name:a,resource:this.screen.model_name,export_fields:[["create",b.map(function(a){return{name:a}})]]}],{}]},this.session).then(function(d){this.predef_exports[d]=b,0===c.length?this.add_to_predef(d,a):(this.predef_exports[d]=b,c.attr("export_id",d))}.bind(this))},remove_predef:function(){var a=this.predef_exports_list.children("li.bg-primary");if(0!==a.length){var b=jQuery(a).attr("export_id");Sao.rpc({method:"model.ir.export.delete",params:[[b],{}]},this.session).then(function(){delete this.predef_exports[b],a.remove()}.bind(this))}},sel_predef:function(a){this.fields_selected.empty(),this.predef_exports[a].forEach(function(a){if(!(a in this.fields)){var b=this.fields_model,c="",d=a.split("/");this.traverse(b,c,d,0)}a in this.fields&&this.sel_field(a)}.bind(this))},traverse:function(a,b,c,d){function e(e){a=f.children,b+=c[d]+"/",e.traverse(a,b,c,++d)}if(d>=c.length-1)return void this.sel_field(c.join("/"));var f,g,h=Object.keys(a);for(g=0;g<h.length;g++)if(f=a[h[g]],f.path==b+c[d]){this.children_expand(f).done(e);break}return g==h.length?void this.sel_field(c.join("/")):void 0},sel_field:function(a){var b=this.fields[a].long_string,c=this.fields[a].relation;if(!c)var d=jQuery("<li/>",{path:a}).html(b).click(function(a){a.ctrlKey?d.toggleClass("bg-primary"):jQuery(a.target).addClass("bg-primary").siblings().removeClass("bg-primary")}).appendTo(this.fields_selected)},response:function(a){if("RESPONSE_OK"==a){var b=[],c=[];this.fields_selected.children("li").each(function(a,d){b.push(d.getAttribute("path")),c.push(d.innerText)}),Sao.rpc({method:"model."+this.screen.model_name+".export_data",params:[this.ids,b,this.context]},this.session).then(function(a){this.export_csv(c,a).then(function(){this.destroy()}.bind(this))}.bind(this))}else this.destroy()},export_csv:function(a,b){var c=this.el_csv_encoding.val(),d={};d.data=b,this.el_add_field_names.is(":checked")&&(d.fields=a);var e=Papa.unparse(d,{quoteChar:this.el_csv_quotechar.val(),delimiter:this.el_csv_delimiter.val()}),f=new Blob([e],{type:"text/csv;charset="+c}),g=window.URL.createObjectURL(f);return this.blob_url&&window.URL.revokeObjectURL(this.blob_url),this.blob_url=g,window.open(g),Sao.common.message.run(Sao.i18n.ngettext("%1 record saved","%1 records saved",b.length))}})}(),function(){"use strict";Sao.Wizard=Sao.class_(Object,{init:function(a){this.widget=jQuery("<div/>",{"class":"wizard"}),this.name=a||"",this.action_id=null,this.id=null,this.ids=null,this.action=null,this.context=null,this.states={},this.session_id=null,this.start_state=null,this.end_state=null,this.screen=null,this.screen_state=null,this.state=null,this.session=Sao.Session.current_session,this.__processing=!1,this.__waiting_response=!1,this.info_bar=new Sao.Window.InfoBar},run:function(a){this.action=a.action,this.action_id=a.data.action_id,this.id=a.data.id,this.ids=a.data.ids,this.model=a.data.model,this.context=a.context,Sao.rpc({method:"wizard."+this.action+".create",params:[this.session.context]},this.session).then(function(a){this.session_id=a[0],this.start_state=this.state=a[1],this.end_state=a[2],this.process()}.bind(this),function(){this.destroy()}.bind(this))},process:function(){if(!this.__processing&&!this.__waiting_response){var a=function(){if(this.state==this.end_state)return void this.end();var a=jQuery.extend({},this.context);a.active_id=this.id,a.active_ids=this.ids,a.active_model=this.model,a.action_id=this.action_id;var b={};this.screen&&(b[this.screen_state]=this.screen.get_on_change_value()),Sao.rpc({method:"wizard."+this.action+".execute",params:[this.session_id,b,this.state,a]},this.session).then(function(a){if(a.view){this.clean();var b=a.view;this.update(b.fields_view,b.defaults,b.buttons),this.screen_state=b.state,this.__waiting_response=!0}else this.state=this.end_state;var c=function(){a.actions&&a.actions.forEach(function(a){Sao.Action.exec_action(a[0],a[1],jQuery.extend({},this.context))}.bind(this))}.bind(this);this.state==this.end_state?this.end().then(c):c(),this.__processing=!1}.bind(this),function(a){this.__processing=!1}.bind(this))};a.call(this)}},destroy:function(){},end:function(){return Sao.rpc({method:"wizard."+this.action+".delete",params:[this.session_id,this.session.context]},this.session)},clean:function(){this.widget.children().remove(),this.states={}},response:function(a){return this.__waiting_response=!1,this.screen.current_view.set_value(),this.screen.current_record.validate().then(function(b){return b||a==this.end_state?(this.info_bar.message(),this.state=a,void this.process()):(this.screen.display(!0),void this.info_bar.message(this.screen.invalid_message(),"danger"))}.bind(this))},_get_button:function(a){var b=new Sao.common.Button(a);return this.states[a.state]=b,a["default"]?b.el.addClass("btn-primary"):a.state==this.end_state&&b.el.addClass("btn-link"),b},update:function(a,b,c){c.forEach(function(a){this._get_button(a)}.bind(this)),this.screen=new Sao.Screen(a.model,{mode:[],context:this.context}),this.screen.add_view(a),this.screen.switch_view(),this.widget.append(this.screen.screen_container.el),this.screen.new_(!1),this.screen.current_record.set_default(b),this.screen.set_cursor()}}),Sao.Wizard.create=function(a){var b;if(a.window){b=new Sao.Wizard.Form(a.name);var c=new Sao.Tab.Wizard(b);Sao.Tab.add(c)}else b=new Sao.Wizard.Dialog(a.name);b.run(a)},Sao.Wizard.Form=Sao.class_(Sao.Wizard,{init:function(a){Sao.Wizard.Form._super.init.call(this),this.tab=null,this.name=a||"",this.form=jQuery("<div/>",{"class":"wizard-form"}).append(this.widget),this.footer=jQuery("<div/>",{"class":"modal-footer"}).appendTo(this.form)},clean:function(){Sao.Wizard.Form._super.clean.call(this),this.footer.children().remove()},_get_button:function(a){var b=Sao.Wizard.Form._super._get_button.call(this,a);return this.footer.append(b.el),b.el.click(function(){this.response(a.state)}.bind(this)),b},end:function(){return Sao.Wizard.Form._super.end.call(this).always(function(){return this.tab.close()}.bind(this))}}),Sao.Wizard.Dialog=Sao.class_(Sao.Wizard,{init:function(a){a||(a=Sao.i18n.gettext("Wizard")),Sao.Wizard.Dialog._super.init.call(this);var b=new Sao.Dialog(a,"wizard-dialog","lg");this.dialog=b.modal,this.dialog.on("shown.bs.modal",function(){Sao.View.resize(jQuery(this))}),this.content=b.content,this.footer=b.footer,b.body.append(this.widget).append(this.info_bar.el)},clean:function(){Sao.Wizard.Dialog._super.clean.call(this),this.footer.children().remove()},_get_button:function(a){var b=Sao.Wizard.Dialog._super._get_button.call(this,a);return this.footer.append(b.el),a["default"]?(this.content.unbind("submit"),this.content.submit(function(b){this.response(a.state),b.preventDefault()}.bind(this)),b.el.attr("type","submit")):b.el.click(function(){this.response(a.state)}.bind(this)),b},update:function(a,b,c){this.content.unbind("submit"),Sao.Wizard.Dialog._super.update.call(this,a,b,c),this.dialog.modal("show")},destroy:function(a){Sao.Wizard.Dialog._super.destroy.call(this),this.dialog.on("hidden.bs.modal",function(b){this.dialog.remove();var c,d=jQuery(".wizard-dialog").filter(":visible")[0],e=!1;if(d||(d=Sao.Tab.tabs.get_current(),d?d.screen&&d.screen.model_name!=this.model&&(e=!0,c=Sao.main_menu_screen):(e=!0,c=Sao.main_menu_screen)),d&&d.screen&&(c=d.screen),c){if(c.current_record&&!e){var f;f=c.model_name==this.model?this.ids:[c.current_record.id],c.reload(f,!0)}a&&c.client_action(a)}}.bind(this)),this.dialog.modal("hide")},end:function(){return Sao.Wizard.Dialog._super.end.call(this).then(this.destroy.bind(this))},show:function(){this.dialog.modal("show")},hide:function(){this.dialog.modal("hide")},state_changed:function(){this.process()}})}(),function(){"use strict";Sao.View.Board=Sao.class_(Object,{init:function(a,b){var c,d,e,f;this.context=b,this.actions=[],this.el=jQuery("<div/>",{"class":"board"}),c={},e=a.children()[0];for(var g=0,h=e.attributes.length;h>g;g++)d=e.attributes[g],c[d.name]=d.value;for(this.attributes=c,this.el.append(this.parse(e).el),f=[],g=0,h=this.actions.length;h>g;g++)f.push(this.actions[g].action_prm);this.actions_prms=jQuery.when.apply(jQuery,f)},_parse_node:function(a,b,c){switch(a.tagName){case"image":break;case"separator":this._parse_separator(a,b,c);break;case"label":this._parse_label(a,b,c);break;case"newline":b.add_row();break;case"notebook":this._parse_notebook(a,b,c);break;case"page":this._parse_page(a,b,c);break;case"group":this._parse_group(a,b,c);break;case"hpaned":this._parse_pane(a,b,c,"horizontal");break;case"vpaned":this._parse_pane(a,b,c,"vertical");break;case"child":this._parse_child(a,b,c);break;case"action":this._parse_action(a,b,c)}},parse:function(a,b){var c;return b||(b=new Sao.View.Form.Container(Number(a.getAttribute("col")||4))),c=function(a,c){var d,e,f,g;for(d={},f=0,g=c.attributes.length;g>f;f++)e=c.attributes[f],d[e.name]=e.value;["yexpand","yfill","xexpand","xfill","colspan","position"].forEach(function(a){d[a]&&(d[a]=Number(d[a]))}),this._parse_node(c,b,d)},jQuery(a).children().each(c.bind(this)),b},_parse_separator:function(a,b,c){var d,e;d=c.string,e=new Sao.view.Form.Separator(d,c),b.add(c,e)},_parse_label:function(a,b,c){var d,e;return(d=c.string)?(e=new Sao.View.Form.Label(d,c),void b.add(c,e)):void b.add(c)},_parse_notebook:function(a,b,c){var d;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),d=new Sao.View.Form.Notebook(c),b.add(c,d),this.parse(a,b)},_parse_page:function(a,b,c){var d;d=c.string,page=this.parse(a,b),page=new Sao.View.Form.Page(b.add(page.el,d),c)},_parse_group:function(a,b,c){var d;d=new Sao.View.Form.Group(c),b.add(c,d)},_parse_pane:function(a,b,c,d){var e;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),e=new Sao.common.Paned(d),b.add(c,e),this.parse(a,e)},_parse_child:function(a,b,c){var d,e,f;d=this.parse(a),e=b.get_child1(),e.children().length>0?(f=b.get_child2(),f.append(d.el)):e.append(d.el)},_parse_action:function(a,b,c){var d;void 0===c.yexpand&&(c.yexpand=!0),void 0===c.yfill&&(c.yfill=!0),d=new Sao.View.Board.Action(c,this.context),this.actions.push(d),b.add(c,d)},reload:function(){for(var a=0;a<this.actions.length;a++)this.actions[a].display()}}),Sao.View.Board.Action=Sao.class_(Object,{init:function(a,b){void 0===b&&(b={});var c,d;this.name=a.name,this.context=jQuery.extend({},b),c=new Sao.Model("ir.action.act_window"),this.action_prm=c.execute("get",[this.name],this.context),this.action_prm.done(function(b){var c,e,f,g,h,i;if(this.action=b,this.action.mode=[],f=[],(this.action.views||[]).length>0)for(c=0,e=this.action.views.length;e>c;c++)f.push(this.action.views[c][0]),this.action.mode.push(this.action.views[c][1]);else void 0!==this.action.view_id&&(f=[this.action.view_id[0]]);"mode"in a&&(this.action.mode=a.mode),"pyson_domain"in this.action||(this.action.pyson_domain="[]"),jQuery.extend(this.context,Sao.Session.current_session.context),this.context._user=Sao.Session.current_session.user_id,g=new Sao.PYSON.Decoder(this.context),jQuery.extend(this.context,g.decode(this.action.pyson_context||"{}")),g=new Sao.PYSON.Decoder(this.context),jQuery.extend(this.context,g.decode(this.action.pyson_context||"{}")),this.domain=[],this.update_domain([]),h=jQuery.extend({},this.context),h.context=this.context,h._user=Sao.Session.current_session.user_id,g=new Sao.PYSON.Decoder(h),d=g.decode(this.action.pyson_search_value||"{}"),i={mode:this.action.mode,context:this.context,view_ids:f,domain:this.domain,search_value:d,row_activate:this.row_activate.bind(this)},this.screen=new Sao.Screen(this.action.res_model,i),a.string?this.title.html(a.string):this.title.html(this.action.name),this.screen.switch_view().done(function(){this.body.append(this.screen.screen_container.el),this.screen.search_filter()}.bind(this))}.bind(this)),this.el=jQuery("<div/>",{"class":"board-action panel panel-default"}),this.title=jQuery("<div/>",{"class":"panel-heading"}),this.el.append(this.title),this.body=jQuery("<div/>",{"class":"panel-body"}),this.el.append(this.body)},row_activate:function(){var a,b;this.screen.current_record&&("tree"==this.screen.current_view.view_type&&1==this.screen.current_view.attributes.keyword_open?(a=this.screen.current_view.selected_records().map(function(a){return a.id}),Sao.Action.exec_keyword("tree_open",{model:this.screen.model_name,id:this.screen.current_record.id,ids:a},jQuery.extend({},this.context),!1)):b=new Sao.Window.Form(this.screen,function(a){a?this.screen.current_record.save():this.screen.current_record.cancel()}.bind(this)))},set_value:function(){},display:function(){this.screen.search_filter(this.screen.screen_container.get_text())},get_active:function(){return this.screen&&this.screen.current_record?Sao.common.EvalEnvironment(this.screen.current_record):void 0},update_domain:function(a){var b,c,d,e,f,g;for(e=jQuery.extend({},this.context),e.context=e,e._user=Sao.Session.current_session.user_id,b=0,c=a.length;c>b;b++)d=a[b].get_active(),d&&(e[a[b].name]=d);f=new Sao.PYSON.Decoder(e),g=f.decode(this.action.pyson_domain),Sao.common.compare(this.domain,g)||(this.domain.splice(0,this.domain.length),jQuery.extend(this.domain,g),this.screen&&this.display())}})}();
\ No newline at end of file
diff --git a/index.html b/index.html
index 7f788ec..d6afce7 100644
--- a/index.html
+++ b/index.html
@@ -38,11 +38,11 @@ this repository contains the full copyright notices and license terms. -->
         </script>
         </head>
         <body>
-        <nav class="navbar navbar-default" role="navigation" style="margin-bottom: 1px;">
+        <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 1px;">
             <div class="container-fluid">
                 <div class="navbar-header">
                     <button type="button" class="navbar-toggle collapsed"
-                        data-toggle="collapse" data-target="#user_menu_collapse">
+                        data-toggle="collapse" data-target="#main_navbar">
                         <span class="icon-bar"></span>
                         <span class="icon-bar"></span>
                         <span class="icon-bar"></span>
@@ -55,7 +55,7 @@ this repository contains the full copyright notices and license terms. -->
                         </button>
                     </p>
                 </div>
-                <div class="collapse navbar-collapse" id="user_menu_collapse">
+                <div class="collapse navbar-collapse" id="main_navbar">
                     <ul class="nav navbar-nav">
                         <li id="user-preferences"></li>
                         <li id="user-favorites"></li>
@@ -63,6 +63,8 @@ this repository contains the full copyright notices and license terms. -->
                     <ul class="nav navbar-nav navbar-right">
                         <li id="user-logout"></li>
                     </ul>
+                    <ul id="tablist" class="nav navbar-nav nav-tabs nav-tabs-justified" role="tablist">
+                    </ul>
                 </div>
             </div>
         </nav>
@@ -73,9 +75,7 @@ this repository contains the full copyright notices and license terms. -->
                     style="overflow-y: auto; height: 100%;"></div>
                 <div class="col-xs-12 col-md-9" style="overflow-y: auto; height: 100%;">
                     <div id="tabs" role="tabpanel">
-                        <ul class="nav nav-tabs" role="tablist">
-                        </ul>
-                        <div class="tab-content">
+                        <div id="tabcontent" class="tab-content">
                         </div>
                     </div>
                 </div>
@@ -87,7 +87,7 @@ this repository contains the full copyright notices and license terms. -->
                         jQuery('.row-offcanvas').toggleClass('active');
                         });
                     jQuery('#tabs').on('ready', function() {
-                        if (jQuery(this).find('> .nav-tabs').children().length) {
+                        if (jQuery('#tablist').children().length) {
                             jQuery('.row-offcanvas').removeClass('active');
                         } else {
                             jQuery('.row-offcanvas').addClass('active');
diff --git a/locale/bg.json b/locale/bg.json
index c4bdbb4..207155f 100644
--- a/locale/bg.json
+++ b/locale/bg.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"User name":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Close":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Create a new record":[null,""],"Save this record":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous Record":[null,""],"Next Record":[null,""],"Add an attachment to the record":[null,""],"Add a note to the record":[null,""],"New":[null,""],"Save":[null,""],"Switch":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Previous":[null,""],"Next":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Attachment":[null,""],"Note":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Processing...":[null,""],"Create...":[null,""],"Download":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/bg.po b/locale/bg.po
index 3766150..6c93eb0 100644
--- a/locale/bg.po
+++ b/locale/bg.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -21,16 +21,16 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
+msgid "User name"
 msgstr ""
 
-msgid "Unable to reach the server."
+msgid "Database"
 msgstr ""
 
-msgid "Toggle navigation"
+msgid "Unable to reach the server."
 msgstr ""
 
-msgid "Menu"
+msgid "Close"
 msgstr ""
 
 msgid ""
@@ -38,52 +38,37 @@ msgid ""
 "Do you want to continue?"
 msgstr ""
 
-msgid "Close"
-msgstr ""
-
-msgid "New"
-msgstr ""
-
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -95,6 +80,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -107,6 +98,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -175,12 +172,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -253,6 +244,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -284,6 +281,10 @@ msgid "More"
 msgstr ""
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -387,9 +388,19 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/bg_BG.json b/locale/bg_BG.json
new file mode 100644
index 0000000..9fb066f
--- /dev/null
+++ b/locale/bg_BG.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/ca.json b/locale/ca.json
index 87a62ff..5b22f11 100644
--- a/locale/ca.json
+++ b/locale/ca.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Gestiona els preferits"],"Logout":[null,"Sortir"],"Favorites":[null,"Preferits"],"Search...":[null,"Cerca..."],"Unable to reach the server":[null,"No ha estat possible connectar amb el servidor."],"Login":[null,"Identificació"],"Database":[null,"Base de dades"],"Unable to reach the server.":[null,"No ha estat possible connectar amb el servidor."],"Toggle navigation":[null,"Commuta navegació"],"Menu":[null,"Menú"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"L'acció seleccionada requereix tancar totes les pestanyes.\nVoleu continuar?"],"Close":[null,"Tanca"],"New":[null,"Nou"],"Create a new record":[null,"Crea un nou registre"],"Save":[null,"Desa"],"Save this record":[null,"Desa aquest registre"],"Switch":[null,"Canvia"],"Switch view":[null,"Canvia la vista"],"Reload":[null,"Recarrega"],"Previous":[null,"Anterior"],"Previous Record":[null,"Registre anterior"],"Next":[null,"Registre següent"],"Next Record":[null,"Següent registre"],"Attachment":[null,"Adjunt"],"Add an attachment to the record":[null,"Afegeix un adjunt en el registre"],"Note":[null,"Nota"],"Add a note to the record":[null,"Afegeix una nota al registre"],"Reload/Undo":[null,"Refresca/Desfés"],"Duplicate":[null,"Duplica"],"Delete":[null,"Elimina"],"Search":[null,"Cerca"],"View Logs...":[null,"Veure registre..."],"Show revisions...":[null,"Mostra revisions..."],"Close Tab":[null,"Tanca pestanya"],"Action":[null,"Acció"],"Relate":[null,"Relacionat"],"Print":[null,"Imprimeix"],"Export":[null,"Exporta"],"Import":[null,"Importa"],"Launch action":[null,"Executa acció"],"Open related records":[null,"Obra registres relacionats"],"Print report":[null,"Imprimeix informe"],"This record has been modified\ndo you want to save it?":[null,"Aquest registre ha estat modificat mentre l'editàveu\nel voleu desar?"],"Record saved.":[null,"Registre desat"],"Working now on the duplicated record(s).":[null,"Està treballant amb un registre(s) duplicat."],"Are you sure to remove this record?":[null,"Esteu segurs d'eliminar aquest registre?"],"Are you sure to remove those records?":[null,"Esteu segurs d'eliminar aquests registres?"],"Records removed.":[null,"Registres eliminats"],"Records not removed.":[null,"Registres no eliminats"],"You have to select one record.":[null,"Ha de seleccionar un registre"],"ID:":[null,"Identificador:"],"Creation User:":[null,"Creat per:"],"Creation Date:":[null,"Data creació:"],"Latest Modification by:":[null,"Última modificació per:"],"Latest Modification Date:":[null,"Última data de modificació:"],"Model: ":[null,"Model:"],"Attachment(%1)":[null,"Adjunt(%1)"],"Note(%1)":[null,"Nota(%1)"],"Filters":[null,"Filtres"],"Bookmarks":[null,"Cerques preferides"],"Remove this bookmark":[null,"Elimina de les cerques preferides"],"Bookmark this filter":[null,"Desa com a cerca preferida"],"Bookmark Name:":[null,"Nom de la cerca preferida"],"True":[null,"Verdader"],"False":[null,"Fals"],"Find":[null,"Cerca"],"ID":[null,"ID"],"Creation User":[null,"Creat per:"],"Creation Date":[null,"Data creació:"],"Modification User":[null,"Modificat per"],"Modification Date":[null,"Última data de modificació:"],"\"%1\" is required":[null,"\"%1\" és obligatori."],"\"%1\" is not valid according to its domain":[null,"\"%1\" no és vàlid segons el seu domini."],"The values of \"%1\" are not valid":[null,"Els valors de \"%1\" no són vàlids."],"Pre-validation":[null,"Prevalidació"],"Translate":[null,"Tradueix"],"Cancel":[null,"Cancel·la"],"OK":[null,"OK"],"Edit":[null,"Edita"],"Fuzzy":[null,"Dubtosa"],"You need to save the record before adding translations.":[null,"Heu de desar el registre abans d'afegir traduccions."],"No other language available.":[null,"No hi ha cap altre idioma disponible."],"Font":[null,"Tipus de lletra"],"Size":[null,"Mida"],"Add":[null,"Afegeix"],"Remove":[null,"Elimina"],"Open":[null,"Obre"],"Undelete":[null,"Recupera"],"Select":[null,"Selecciona"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Més"],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Seleccioneu la vostra acció"],"No action defined.":[null,"No s'ha definit cap acció."],"Your selection:":[null,"La vostra selecció:"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Per: "],"y":[null,"a"],"Yes":[null,"Sí"],"t":[null,"c"],"Message: ":[null,"Missatge: "],"Warning: ":[null,"Avís: "],"Always ignore this warning.":[null,"Ignora sempre aquest advertiment."],"Do you want to proceed?":[null,"Voleu continuar?"],"No":[null,"No"],"Confirmation: ":[null,"Confirmació: "],"Concurrency Exception":[null,"Excepció de concurrència"],"Write Concurrency Warning: ":[null,"Avís de concurrència d'escriptura: "],"This record has been modified while you were editing it.":[null,"Aquest registre ha estat modificat mentre l'editàveu."],"Choose:":[null,"Trieu:"],"\"Cancel\" to cancel saving;":[null,"\"Cancel·la\" per no desar;"],"\"Compare\" to see the modified version;":[null,"\"Compara\" per veure la versió modificada;"],"\"Write Anyway\" to save your current version.":[null,"\"Desa de totes formes\" per desar els vostres canvis."],"Compare":[null,"Compara"],"Write Anyway":[null,"Desa de totes formes"],"Application Error":[null,"Error d'aplicació."],"Report Bug":[null,"Informa de l'error"],"Create...":[null,"Crea..."],"Attachments (%1)":[null,"Adjunts (%1)"],"Notes (%1)":[null,"Notes (%1)"],"Search %1":[null,"Cerca %1"],"Revision":[null,"Revisió"],"All Fields":[null,"Tots els camps"],"Clear":[null,"Neteja"],"Fields Selected":[null,"Camps seleccionats"],"CSV Parameters":[null,"Paràmetres CSV"],"Delimiter:":[null,"Separador de camp:"],"Quote Char:":[null,"Delimitador de text:"],"Encoding:":[null,"Codificació:"],"Import from CSV":[null,"Importa des de CSV"],"Auto-Detect":[null,"Detecta automàticament"],"File to Import":[null,"Fitxer a importar"],"Lines to Skip:":[null,"Línies a ometre:"],"You must select an import file first":[null,"Primer heu de seleccionar un fitxer a importar."],"Error occured in loading the file":[null,"S'ha produït un error al carregar el fitxer"],"Error processing the file at field %1.":[null,"S'ha produït un error al processar el fitxer al camp %1."],"Error":[null,"Error"],"Export to CSV":[null,"Exporta a CSV"],"Predefined Exports":[null,"Exportacions predefinides"],"Save Export":[null,"Desa l'exportació"],"Delete Export":[null,"Elimina l'exportació"],"Add Field Names":[null,"Afegeix noms dels camps"],"%1 (string)":[null,"%1 (string)"],"What is the name of this export?":[null,"Quin és el nom d'aquesta exportació?"],"Override %1 definition?":[null,"Voleu sobreescriure la definició %1? "],"Wizard":[null,"Assistent"]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Gestiona els preferits"],"Logout":[null,"Sortir"],"Favorites":[null,"Preferits"],"Search...":[null,"Cerca..."],"Unable to reach the server":[null,"No ha estat possible connectar amb el servidor."],"Login":[null,"Identificació"],"User name":[null,"Nom d'usuari"],"Database":[null,"Base de dades"],"Unable to reach the server.":[null,"No ha estat possible connectar amb el servidor."],"Close":[null,"Tanca"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"L'acció seleccionada requereix tancar totes les pestanyes.\nVoleu continuar?"],"Create a new record":[null,"Crea un nou registre"],"Save this record":[null,"Desa aquest registre"],"Switch view":[null,"Canvia la vista"],"Reload":[null,"Recarrega"],"Previous Record":[null,"Registre anterior"],"Next Record":[null,"Següent registre"],"Add an attachment to the record":[null,"Afegeix un adjunt en el registre"],"Add a note to the record":[null,"Afegeix una nota al registre"],"New":[null,"Nou"],"Save":[null,"Desa"],"Switch":[null,"Canvia"],"Reload/Undo":[null,"Refresca/Desfés"],"Duplicate":[null,"Duplica"],"Delete":[null,"Elimina"],"Previous":[null,"Anterior"],"Next":[null,"Registre següent"],"Search":[null,"Cerca"],"View Logs...":[null,"Veure registre..."],"Show revisions...":[null,"Mostra revisions..."],"Close Tab":[null,"Tanca pestanya"],"Attachment":[null,"Adjunt"],"Note":[null,"Nota"],"Action":[null,"Acció"],"Relate":[null,"Relacionat"],"Print":[null,"Imprimeix"],"Export":[null,"Exporta"],"Import":[null,"Importa"],"Launch action":[null,"Executa acció"],"Open related records":[null,"Obra registres relacionats"],"Print report":[null,"Imprimeix informe"],"This record has been modified\ndo you want to save it?":[null,"Aquest registre ha estat modificat mentre l'editàveu\nel voleu desar?"],"Record saved.":[null,"Registre desat"],"Working now on the duplicated record(s).":[null,"Està treballant amb un registre(s) duplicat."],"Are you sure to remove this record?":[null,"Esteu segurs d'eliminar aquest registre?"],"Are you sure to remove those records?":[null,"Esteu segurs d'eliminar aquests registres?"],"Records removed.":[null,"Registres eliminats"],"Records not removed.":[null,"Registres no eliminats"],"You have to select one record.":[null,"Ha de seleccionar un registre"],"ID:":[null,"Identificador:"],"Creation User:":[null,"Creat per:"],"Creation Date:":[null,"Data creació:"],"Latest Modification by:":[null,"Última modificació per:"],"Latest Modification Date:":[null,"Última data de modificació:"],"Model: ":[null,"Model:"],"Filters":[null,"Filtres"],"Bookmarks":[null,"Cerques preferides"],"Remove this bookmark":[null,"Elimina de les cerques preferides"],"Bookmark this filter":[null,"Desa com a cerca preferida"],"Bookmark Name:":[null,"Nom de la cerca preferida"],"True":[null,"Verdader"],"False":[null,"Fals"],"Find":[null,"Cerca"],"ID":[null,"ID"],"Creation User":[null,"Creat per:"],"Creation Date":[null,"Data creació:"],"Modification User":[null,"Modificat per"],"Modification Date":[null,"Última data de modificació:"],"\"%1\" is required":[null,"\"%1\" és obligatori."],"\"%1\" is not valid according to its domain":[null,"\"%1\" no és vàlid segons el seu domini."],"The values of \"%1\" are not valid":[null,"Els valors de \"%1\" no són vàlids."],"Pre-validation":[null,"Prevalidació"],"Translate":[null,"Tradueix"],"Cancel":[null,"Cancel·la"],"OK":[null,"OK"],"Edit":[null,"Edita"],"Fuzzy":[null,"Dubtosa"],"You need to save the record before adding translations.":[null,"Heu de desar el registre abans d'afegir traduccions."],"No other language available.":[null,"No hi ha cap altre idioma disponible."],"Show":[null,"Mostra"],"Hide":[null,"Amaga"],"Font":[null,"Tipus de lletra"],"Size":[null,"Mida"],"Add":[null,"Afegeix"],"Remove":[null,"Elimina"],"Open":[null,"Obre"],"Undelete":[null,"Recupera"],"Select":[null,"Selecciona"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Més"],": ":[null,": "],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Seleccioneu la vostra acció"],"No action defined.":[null,"No s'ha definit cap acció."],"Your selection:":[null,"La vostra selecció:"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Per: "],"y":[null,"a"],"Yes":[null,"Sí"],"t":[null,"c"],"Message: ":[null,"Missatge: "],"Warning: ":[null,"Avís: "],"Always ignore this warning.":[null,"Ignora sempre aquest advertiment."],"Do you want to proceed?":[null,"Voleu continuar?"],"No":[null,"No"],"Confirmation: ":[null,"Confirmació: "],"Concurrency Exception":[null,"Excepció de concurrència"],"Write Concurrency Warning: ":[null,"Avís de concurrència d'escriptura: "],"This record has been modified while you were editing it.":[null,"Aquest registre ha estat modificat mentre l'editàveu."],"Choose:":[null,"Trieu:"],"\"Cancel\" to cancel saving;":[null,"\"Cancel·la\" per no desar;"],"\"Compare\" to see the modified version;":[null,"\"Compara\" per veure la versió modificada;"],"\"Write Anyway\" to save your current version.":[null,"\"Desa de totes formes\" per desar els vostres canvis."],"Compare":[null,"Compara"],"Write Anyway":[null,"Desa de totes formes"],"Application Error":[null,"Error d'aplicació."],"Report Bug":[null,"Informa de l'error"],"Processing...":[null,"Processant..."],"Create...":[null,"Crea..."],"Download":[null,"Baixa"],"...":[null,"..."],"Attachments (%1)":[null,"Adjunts (%1)"],"Notes (%1)":[null,"Notes (%1)"],"Search %1":[null,"Cerca %1"],"Revision":[null,"Revisió"],"All Fields":[null,"Tots els camps"],"Clear":[null,"Neteja"],"Fields Selected":[null,"Camps seleccionats"],"CSV Parameters":[null,"Paràmetres CSV"],"Delimiter:":[null,"Separador de camp:"],"Quote Char:":[null,"Delimitador de text:"],"Encoding:":[null,"Codificació:"],"Import from CSV":[null,"Importa des de CSV"],"Auto-Detect":[null,"Detecta automàticament"],"File to Import":[null,"Fitxer a importar"],"Lines to Skip:":[null,"Línies a ometre:"],"You must select an import file first":[null,"Primer heu de seleccionar un fitxer a importar."],"Error occured in loading the file":[null,"S'ha produït un error al carregar el fitxer"],"Error processing the file at field %1.":[null,"S'ha produït un error al processar el fitxer al camp %1."],"Error":[null,"Error"],"Export to CSV":[null,"Exporta a CSV"],"Predefined Exports":[null,"Exportacions predefinides"],"Save Export":[null,"Desa l'exportació"],"Delete Export":[null,"Elimina l'exportació"],"Add Field Names":[null,"Afegeix noms dels camps"],"%1 (string)":[null,"%1 (string)"],"What is the name of this export?":[null,"Quin és el nom d'aquesta exportació?"],"Override %1 definition?":[null,"Voleu sobreescriure la definició %1? "],"Wizard":[null,"Assistent"]}
\ No newline at end of file
diff --git a/locale/ca.po b/locale/ca.po
index 0ff4d2b..746f61d 100644
--- a/locale/ca.po
+++ b/locale/ca.po
@@ -2,6 +2,9 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 15 2017 01:03:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Apr 04 2017 10:44:30 GMT+0200 (CEST)
 # Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
 # Generated by grunt-xgettext on Tue Nov 01 2016 15:18:23 GMT+0100 (CET)
 msgid "Manage favorites"
@@ -24,17 +27,17 @@ msgstr "No ha estat possible connectar amb el servidor."
 msgid "Login"
 msgstr "Identificació"
 
+msgid "User name"
+msgstr "Nom d'usuari"
+
 msgid "Database"
 msgstr "Base de dades"
 
 msgid "Unable to reach the server."
 msgstr "No ha estat possible connectar amb el servidor."
 
-msgid "Toggle navigation"
-msgstr "Commuta navegació"
-
-msgid "Menu"
-msgstr "Menú"
+msgid "Close"
+msgstr "Tanca"
 
 msgid ""
 "The following action requires to close all tabs.\n"
@@ -43,54 +46,39 @@ msgstr ""
 "L'acció seleccionada requereix tancar totes les pestanyes.\n"
 "Voleu continuar?"
 
-msgid "Close"
-msgstr "Tanca"
-
-msgid "New"
-msgstr "Nou"
-
 msgid "Create a new record"
 msgstr "Crea un nou registre"
 
-msgid "Save"
-msgstr "Desa"
-
 msgid "Save this record"
 msgstr "Desa aquest registre"
 
-msgid "Switch"
-msgstr "Canvia"
-
 msgid "Switch view"
 msgstr "Canvia la vista"
 
 msgid "Reload"
 msgstr "Recarrega"
 
-msgid "Previous"
-msgstr "Anterior"
-
 msgid "Previous Record"
 msgstr "Registre anterior"
 
-msgid "Next"
-msgstr "Registre següent"
-
 msgid "Next Record"
 msgstr "Següent registre"
 
-msgid "Attachment"
-msgstr "Adjunt"
-
 msgid "Add an attachment to the record"
 msgstr "Afegeix un adjunt en el registre"
 
-msgid "Note"
-msgstr "Nota"
-
 msgid "Add a note to the record"
 msgstr "Afegeix una nota al registre"
 
+msgid "New"
+msgstr "Nou"
+
+msgid "Save"
+msgstr "Desa"
+
+msgid "Switch"
+msgstr "Canvia"
+
 msgid "Reload/Undo"
 msgstr "Refresca/Desfés"
 
@@ -100,6 +88,12 @@ msgstr "Duplica"
 msgid "Delete"
 msgstr "Elimina"
 
+msgid "Previous"
+msgstr "Anterior"
+
+msgid "Next"
+msgstr "Registre següent"
+
 msgid "Search"
 msgstr "Cerca"
 
@@ -112,6 +106,12 @@ msgstr "Mostra revisions..."
 msgid "Close Tab"
 msgstr "Tanca pestanya"
 
+msgid "Attachment"
+msgstr "Adjunt"
+
+msgid "Note"
+msgstr "Nota"
+
 msgid "Action"
 msgstr "Acció"
 
@@ -182,12 +182,6 @@ msgstr "Última data de modificació:"
 msgid "Model: "
 msgstr "Model:"
 
-msgid "Attachment(%1)"
-msgstr "Adjunt(%1)"
-
-msgid "Note(%1)"
-msgstr "Nota(%1)"
-
 msgid "Filters"
 msgstr "Filtres"
 
@@ -260,6 +254,12 @@ msgstr "Heu de desar el registre abans d'afegir traduccions."
 msgid "No other language available."
 msgstr "No hi ha cap altre idioma disponible."
 
+msgid "Show"
+msgstr "Mostra"
+
+msgid "Hide"
+msgstr "Amaga"
+
 msgid "Font"
 msgstr "Tipus de lletra"
 
@@ -290,6 +290,9 @@ msgstr ":"
 msgid "More"
 msgstr "Més"
 
+msgid ": "
+msgstr ": "
+
 msgid ", "
 msgstr ", "
 
@@ -392,9 +395,18 @@ msgstr "Error d'aplicació."
 msgid "Report Bug"
 msgstr "Informa de l'error"
 
+msgid "Processing..."
+msgstr "Processant..."
+
 msgid "Create..."
 msgstr "Crea..."
 
+msgid "Download"
+msgstr "Baixa"
+
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr "Adjunts (%1)"
 
diff --git a/locale/ca_ES.json b/locale/ca_ES.json
new file mode 100644
index 0000000..2e73d63
--- /dev/null
+++ b/locale/ca_ES.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,"Sortir"],"Search...":[null,"Cerca..."],"Unable to reach the server":[null,"No ha estat possible connectar-se al servidor."],"Unable to reach the server.":[null,"No ha estat possible connectar-se al servidor."],"Login":[null,"Identificació"],"Password":[null,"Contrasenya"],"Database":[null,"Base de dades"],"OK":[null,"OK"],"Toggle navigation":[null,"Commuta navegació"],"Menu":[null,"Menú"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"L'acció seleccionada requereix tancar totes les pestanyes.\nVoleu continuar?"],"Close":[null,"Tanca"],"New":[null,"Nou"],"Create a new record":[null,"Crea un nou registre"],"Save":[null,"Desa"],"Save this record":[null,"Desa aquest registre"],"Switch":[null,"Canvia"],"Switch view":[null,"Canvia la vista"],"Reload":[null,"Recarrega"],"Previous":[null,"Registre anterior"],"Previous Record":[null,"Registre següent"],"Next":[null,"Següent"],"Next Record":[null,"Següent registre"],"Attachment":[null,"Adjunt"],"Add an attachment to the record":[null,"Afegeix un adjunt en el registre"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"Refresca/Desfés"],"Duplicate":[null,"Duplica"],"Delete":[null,"Elimina"],"Search":[null,"Cerca"],"View Logs...":[null,"Veure registre..."],"Show revisions...":[null,"Mostra revisions..."],"Close Tab":[null,"Tanca pestanya"],"Action":[null,"Acció"],"Relate":[null,"Relacionat"],"Print":[null,"Imprimeix"],"Launch action":[null,"Executa acció"],"Open related records":[null,"Obra registres relacionats"],"Print report":[null,"Imprimeix informe"],"This record has been modified\ndo you want to save it?":[null,"Aquest registre ha estat modificat mentre l'editàveu\nel voleu desar?"],"Record saved.":[null,"Registre desat"],"Working now on the duplicated record(s).":[null,"Està treballant amb un registre(s) duplicat."],"Are you sure to remove this record?":[null,"Esteu segurs d'eliminar aquest registre?"],"Are you sure to remove those records?":[null,"Esteu segurs d'eliminar aquests registres?"],"Records removed.":[null,"Registres eliminats"],"Records not removed.":[null,"Registres no eliminats"],"You have to select one record.":[null,"Ha de seleccionar un registre"],"ID:":[null,"ID:"],"Creation User:":[null,"Creat per:"],"Creation Date:":[null,"Data de creació:"],"Latest Modification by:":[null,"Última modificació per:"],"Latest Modification Date:":[null,"Última data de modificació:"],"Model: ":[null,"Model:"],"Attachment(%1)":[null,"Adjunt(%1)"],"Note(%1)":[null,""],"Filters":[null,"Filtres"],"Bookmarks":[null,"Cerques preferides"],"Remove this bookmark":[null,"Elimina de les cerques preferides"],"Bookmark this filter":[null,"Desa com a cerca preferida"],"Bookmark Name:":[null,"Nom de la cerca preferida"],"True":[null,"Verdader"],"False":[null,"Fals"],"Find":[null,"Cerca"],"ID":[null,"ID"],"Creation User":[null,"Creat per:"],"Creation Date":[null,"Data de creació:"],"Modification User":[null,"Modificat per"],"Modification Date":[null,"Última data de modificació:"],"\"%1\" is required":[null,"\"%1\" és obligatori."],"\"%1\" is not valid according to its domain":[null,"\"%1\" no és vàlid segons el seu domini."],"The values of \"%1\" are not valid":[null,"Els valors de \"%1\" no són vàlids."],"Pre-validation":[null,"Prevalidació"],"Font":[null,"Tipus de lletra"],"Size":[null,"Mida"],"Add":[null,"Afegeix"],"Remove":[null,"Elimina"],"Open":[null,"Obre"],"Undelete":[null,"Recupera"],"Select":[null,"Selecciona"],"Cancel":[null,"Cancel·la"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Més"],"Calendar view not yet implemented":[null,"La vista de calendari encara no està implementada."],"Warning":[null,"Avís"],"Select your action":[null,"Seleccioneu la vostra acció"],"No action defined!":[null,"No s'ha definit cap acció."],"Your selection:":[null,"La vostra selecció:"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"y":[null,"a"],"yes":[null,"sí"],"true":[null,"cert"],"t":[null,"c"],"Message: ":[null,"Missatge: "],"Warning: ":[null,"Avís: "],"Always ignore this warning.":[null,"Ignora sempre aquest advertiment."],"Do you want to proceed?":[null,"Voleu continuar?"],"No":[null,"No"],"Yes":[null,"Sí"],"Confirmation: ":[null,"Confirmació: "],"Concurrency Exception":[null,"Excepció de concurrència"],"Write Concurrency Warning: ":[null,"Avís de concurrència d'escriptura: "],"This record has been modified while you were editing it.":[null,"Aquest registre ha estat modificat mentre l'editàveu."],"Choose:":[null,"Trieu:"],"\"Cancel\" to cancel saving;":[null,"\"Cancel·la\" per no desar;"],"\"Compare\" to see the modified version;":[null,"\"Compara\" per veure la versió modificada;"],"\"Write Anyway\" to save your current version.":[null,"\"Desa de totes formes\" per desar els vostres canvis."],"Compare":[null,"Compara"],"Write Anyway":[null,"Desa de totes formes"],"Application Error":[null,"Error d'aplicació."],"Report Bug":[null,"Informa de l'error"],"Revision":[null,"Revisió"],"Wizard":[null,"Assistent"]}
\ No newline at end of file
diff --git a/locale/cs.json b/locale/cs.json
index c4bdbb4..207155f 100644
--- a/locale/cs.json
+++ b/locale/cs.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"User name":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Close":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Create a new record":[null,""],"Save this record":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous Record":[null,""],"Next Record":[null,""],"Add an attachment to the record":[null,""],"Add a note to the record":[null,""],"New":[null,""],"Save":[null,""],"Switch":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Previous":[null,""],"Next":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Attachment":[null,""],"Note":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Processing...":[null,""],"Create...":[null,""],"Download":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/cs.po b/locale/cs.po
index 3766150..6c93eb0 100644
--- a/locale/cs.po
+++ b/locale/cs.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -21,16 +21,16 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
+msgid "User name"
 msgstr ""
 
-msgid "Unable to reach the server."
+msgid "Database"
 msgstr ""
 
-msgid "Toggle navigation"
+msgid "Unable to reach the server."
 msgstr ""
 
-msgid "Menu"
+msgid "Close"
 msgstr ""
 
 msgid ""
@@ -38,52 +38,37 @@ msgid ""
 "Do you want to continue?"
 msgstr ""
 
-msgid "Close"
-msgstr ""
-
-msgid "New"
-msgstr ""
-
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -95,6 +80,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -107,6 +98,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -175,12 +172,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -253,6 +244,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -284,6 +281,10 @@ msgid "More"
 msgstr ""
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -387,9 +388,19 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/cs_CZ.json b/locale/cs_CZ.json
new file mode 100644
index 0000000..9fb066f
--- /dev/null
+++ b/locale/cs_CZ.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/de.json b/locale/de.json
index 984e212..18f23c3 100644
--- a/locale/de.json
+++ b/locale/de.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Lesezeichen verwalten"],"Logout":[null,"Abmelden"],"Favorites":[null,"Favoriten"],"Search...":[null,"Suche..."],"Unable to reach the server":[null,"Kann nicht zum Server verbinden"],"Login":[null,"Anmeldename"],"Database":[null,"Datenbank"],"Unable to reach the server.":[null,"Kann nicht zum Server verbinden."],"Toggle navigation":[null,"Navigation umschalten"],"Menu":[null,"Menü"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"Die folgende Aktion erfordert die Schließung aller Registerkarten.\nFortfahren?"],"Close":[null,"Schließen"],"New":[null,"Neu"],"Create a new record":[null,"Einen neuen Datensatz erstellen"],"Save":[null,"Speichern"],"Save this record":[null,"Diesen Datensatz speichern"],"Switch":[null,"Ansicht wechseln"],"Switch view":[null,"Ansicht wechseln"],"Reload":[null,"Neu laden"],"Previous":[null,"Vorheriger"],"Previous Record":[null,"Vorheriger Datensatz"],"Next":[null,"Nächster"],"Next Record":[null,"Nächster Datensatz"],"Attachment":[null,"Anhang"],"Add an attachment to the record":[null,"Einen Anhang zum Datensatz hinzufügen"],"Note":[null,"Notiz"],"Add a note to the record":[null,"Eine Notiz zu einem Datensatz hinzufügen"],"Reload/Undo":[null,"Neu laden/Rückgängig"],"Duplicate":[null,"Duplizieren"],"Delete":[null,"Löschen"],"Search":[null,"Suchen"],"View Logs...":[null,"Protokoll ansehen..."],"Show revisions...":[null,"Bearbeitungen anzeigen..."],"Close Tab":[null,"Registerkarte schließen"],"Action":[null,"Aktion"],"Relate":[null,"Beziehung"],"Print":[null,"Drucken"],"Export":[null,"Export"],"Import":[null,"Import"],"Launch action":[null,"Aktion ausführen"],"Open related records":[null,"Datensätze einer Beziehung öffnen"],"Print report":[null,"Bericht drucken"],"This record has been modified\ndo you want to save it?":[null,"Datensatz geändert.\nSoll der Datensatz gespeichert werden?"],"Record saved.":[null,"Der Datensatz wurde gespeichert."],"Working now on the duplicated record(s).":[null,"Sie arbeiten nun an dem/den duplizierten Datensatz/Datensätzen."],"Are you sure to remove this record?":[null,"Möchten Sie diesen Datensatz wirklich löschen?"],"Are you sure to remove those records?":[null,"Möchten Sie diese Datensätze wirklich löschen?"],"Records removed.":[null,"Die Datensätze wurden gelöscht."],"Records not removed.":[null,"Die Datensätze wurden nicht gelöscht."],"You have to select one record.":[null,"Ein Datensatz muss ausgewählt werden."],"ID:":[null,"ID:"],"Creation User:":[null,"Erstellt von:"],"Creation Date:":[null,"Erstellt am:"],"Latest Modification by:":[null,"Zuletzt verändert von"],"Latest Modification Date:":[null,"Zuletzt verändert am"],"Model: ":[null,"Modell:"],"Attachment(%1)":[null,"Anhang(%1)"],"Note(%1)":[null,"Notiz(%1)"],"Filters":[null,"Filter"],"Bookmarks":[null,"Lesezeichen"],"Remove this bookmark":[null,"Dieses Lesezeichen entfernen"],"Bookmark this filter":[null,"Diesen Filter als Lesezeichen hinzufügen"],"Bookmark Name:":[null,"Lesezeichenname:"],"True":[null,"Wahr"],"False":[null,"Falsch"],"Find":[null,"Suchen"],"ID":[null,"ID"],"Creation User":[null,"Erstellt von"],"Creation Date":[null,"Erstellt am:"],"Modification User":[null,"Zuletzt verändert von"],"Modification Date":[null,"Zuletzt verändert am"],"\"%1\" is required":[null,"In Feld \"%1\" ist ein Eintrag erforderlich."],"\"%1\" is not valid according to its domain":[null,"\"%1\" liegt nicht im gültigen Wertebereich (Domain)."],"The values of \"%1\" are not valid":[null,"Die Werte von \"%1\" sind ungültig."],"Pre-validation":[null,"Vorvalidierung"],"Translate":[null,"Übersetzen"],"Cancel":[null,"Abbrechen"],"OK":[null,"OK"],"Edit":[null,"Bearbeiten"],"Fuzzy":[null,"Fuzzy"],"You need to save the record before adding translations.":[null,"Der Datensatz muss gespeichert werden, bevor eine Übersetzung hinzugefügt werden kann."],"No other language available.":[null,"Keine weitere Sprache verfügbar"],"Font":[null,"Schriftart"],"Size":[null,"Größe"],"Add":[null,"Hinzufügen"],"Remove":[null,"Entfernen"],"Open":[null,"Öffnen"],"Undelete":[null,"Löschung rückgängig machen"],"Select":[null,"Auswählen"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Mehr"],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Wählen Sie eine Aktion"],"No action defined.":[null,"Keine Aktion definiert."],"Your selection:":[null,"Ihre Auswahl:"],"Y":[null,"J"],"M":[null,"M"],"w":[null,"W"],"d":[null,"t"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Von:"],"y":[null,"j"],"Yes":[null,"Ja"],"t":[null,"W"],"Message: ":[null,"Nachricht: "],"Warning: ":[null,"Warnung: "],"Always ignore this warning.":[null,"Diese Warnung immer ignorieren."],"Do you want to proceed?":[null,"Fortfahren?"],"No":[null,"Nein"],"Confirmation: ":[null,"Bestätigung: "],"Concurrency Exception":[null,"Aktualisierungskonflikt"],"Write Concurrency Warning: ":[null,"Aktualisierungskonflikt beim Schreiben des aktuellen Datensatzes: "],"This record has been modified while you were editing it.":[null,"Dieser Datensatz wurde anderweitig geändert, während Sie ihn bearbeitet haben."],"Choose:":[null,"Lösungsmöglichkeiten:"],"\"Cancel\" to cancel saving;":[null,"- \"Abbrechen\" um den Speichervorgang abzubrechen,"],"\"Compare\" to see the modified version;":[null,"- \"Vergleichen\" um die geänderte Version des Datensatzes zu betrachten,"],"\"Write Anyway\" to save your current version.":[null,"- \"Überschreiben\" um die gespeicherte Version mit Ihrer Version zu überschreiben."],"Compare":[null,"Vergleichen"],"Write Anyway":[null,"Überschreiben"],"Application Error":[null,"Anwendungsfehler"],"Report Bug":[null,"Fehler berichten"],"Create...":[null,"Erstellen..."],"Attachments (%1)":[null,"Anhänge (%1)"],"Notes (%1)":[null,"Notizen (%1)"],"Search %1":[null,"Suche %1"],"Revision":[null,"Bearbeitung"],"All Fields":[null,"Alle Felder"],"Clear":[null,"Leeren"],"Fields Selected":[null,"Ausgewählte Felder"],"CSV Parameters":[null,"CSV Parameter"],"Delimiter:":[null,"Trennzeichen:"],"Quote Char:":[null,"Anführungszeichen:"],"Encoding:":[null,"Zeichenkodierung:"],"Import from CSV":[null,"Aus CSV Datei importieren"],"Auto-Detect":[null,"Automatische Erkennung"],"File to Import":[null,"Zu importierende Datei"],"Lines to Skip:":[null,"Zu überspringende Zeilen:"],"You must select an import file first":[null,"Zuerst muss eine Importdatei ausgewählt werden."],"Error occured in loading the file":[null,"Fehler beim Öffnen der CSV-Datei"],"Error processing the file at field %1.":[null,"Fehler bei der Verarbeitung der Datei in Feld %1."],"Error":[null,"Fehler"],"Export to CSV":[null,"Als CSV exportieren"],"Predefined Exports":[null,"Vordefinierte Exporte"],"Save Export":[null,"Exportkonfiguration speichern"],"Delete Export":[null,"Exportkonfiguration löschen"],"Add Field Names":[null,"Feldnamen hinzufügen"],"%1 (string)":[null,"%1 (string)"],"What is the name of this export?":[null,"Wie soll der Name des Exports lauten?"],"Override %1 definition?":[null,"Definition von %1 nicht berücksichtigen?"],"Wizard":[null,"Assistent"]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Lesezeichen verwalten"],"Logout":[null,"Abmelden"],"Favorites":[null,"Favoriten"],"Search...":[null,"Suche..."],"Unable to reach the server":[null,"Kann nicht zum Server verbinden"],"Login":[null,"Anmeldename"],"User name":[null,"Benutzername"],"Database":[null,"Datenbank"],"Unable to reach the server.":[null,"Kann nicht zum Server verbinden."],"Close":[null,"Schließen"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"Die folgende Aktion erfordert die Schließung aller Registerkarten.\nFortfahren?"],"Create a new record":[null,"Einen neuen Datensatz erstellen"],"Save this record":[null,"Diesen Datensatz speichern"],"Switch view":[null,"Ansicht wechseln"],"Reload":[null,"Neu laden"],"Previous Record":[null,"Vorheriger Datensatz"],"Next Record":[null,"Nächster Datensatz"],"Add an attachment to the record":[null,"Einen Anhang zum Datensatz hinzufügen"],"Add a note to the record":[null,"Eine Notiz zu einem Datensatz hinzufügen"],"New":[null,"Neu"],"Save":[null,"Speichern"],"Switch":[null,"Ansicht wechseln"],"Reload/Undo":[null,"Neu laden/Rückgängig"],"Duplicate":[null,"Duplizieren"],"Delete":[null,"Löschen"],"Previous":[null,"Vorheriger"],"Next":[null,"Nächster"],"Search":[null,"Suchen"],"View Logs...":[null,"Protokoll ansehen..."],"Show revisions...":[null,"Bearbeitungen anzeigen..."],"Close Tab":[null,"Registerkarte schließen"],"Attachment":[null,"Anhang"],"Note":[null,"Notiz"],"Action":[null,"Aktion"],"Relate":[null,"Beziehung"],"Print":[null,"Drucken"],"Export":[null,"Export"],"Import":[null,"Import"],"Launch action":[null,"Aktion ausführen"],"Open related records":[null,"Datensätze einer Beziehung öffnen"],"Print report":[null,"Bericht drucken"],"This record has been modified\ndo you want to save it?":[null,"Datensatz geändert.\nSoll der Datensatz gespeichert werden?"],"Record saved.":[null,"Der Datensatz wurde gespeichert."],"Working now on the duplicated record(s).":[null,"Sie arbeiten nun an dem/den duplizierten Datensatz/Datensätzen."],"Are you sure to remove this record?":[null,"Möchten Sie diesen Datensatz wirklich löschen?"],"Are you sure to remove those records?":[null,"Möchten Sie diese Datensätze wirklich löschen?"],"Records removed.":[null,"Die Datensätze wurden gelöscht."],"Records not removed.":[null,"Die Datensätze wurden nicht gelöscht."],"You have to select one record.":[null,"Ein Datensatz muss ausgewählt werden."],"ID:":[null,"ID:"],"Creation User:":[null,"Erstellt von:"],"Creation Date:":[null,"Erstellt am:"],"Latest Modification by:":[null,"Zuletzt verändert von"],"Latest Modification Date:":[null,"Zuletzt verändert am"],"Model: ":[null,"Modell:"],"Filters":[null,"Filter"],"Bookmarks":[null,"Lesezeichen"],"Remove this bookmark":[null,"Dieses Lesezeichen entfernen"],"Bookmark this filter":[null,"Diesen Filter als Lesezeichen hinzufügen"],"Bookmark Name:":[null,"Lesezeichenname:"],"True":[null,"Wahr"],"False":[null,"Falsch"],"Find":[null,"Suchen"],"ID":[null,"ID"],"Creation User":[null,"Erstellt von"],"Creation Date":[null,"Erstellt am:"],"Modification User":[null,"Zuletzt verändert von"],"Modification Date":[null,"Zuletzt verändert am"],"\"%1\" is required":[null,"In Feld \"%1\" ist ein Eintrag erforderlich."],"\"%1\" is not valid according to its domain":[null,"\"%1\" liegt nicht im gültigen Wertebereich (Domain)."],"The values of \"%1\" are not valid":[null,"Die Werte von \"%1\" sind ungültig."],"Pre-validation":[null,"Vorvalidierung"],"Translate":[null,"Übersetzen"],"Cancel":[null,"Abbrechen"],"OK":[null,"OK"],"Edit":[null,"Bearbeiten"],"Fuzzy":[null,"Fuzzy"],"You need to save the record before adding translations.":[null,"Der Datensatz muss gespeichert werden, bevor eine Übersetzung hinzugefügt werden kann."],"No other language available.":[null,"Keine weitere Sprache verfügbar"],"Show":[null,"Anzeigen"],"Hide":[null,"Ausblenden"],"Font":[null,"Schriftart"],"Size":[null,"Größe"],"Add":[null,"Hinzufügen"],"Remove":[null,"Entfernen"],"Open":[null,"Öffnen"],"Undelete":[null,"Löschung rückgängig machen"],"Select":[null,"Auswählen"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Mehr"],": ":[null,": "],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Wählen Sie eine Aktion"],"No action defined.":[null,"Keine Aktion definiert."],"Your selection:":[null,"Ihre Auswahl:"],"Y":[null,"J"],"M":[null,"M"],"w":[null,"W"],"d":[null,"t"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Von:"],"y":[null,"j"],"Yes":[null,"Ja"],"t":[null,"W"],"Message: ":[null,"Nachricht: "],"Warning: ":[null,"Warnung: "],"Always ignore this warning.":[null,"Diese Warnung immer ignorieren."],"Do you want to proceed?":[null,"Fortfahren?"],"No":[null,"Nein"],"Confirmation: ":[null,"Bestätigung: "],"Concurrency Exception":[null,"Aktualisierungskonflikt"],"Write Concurrency Warning: ":[null,"Aktualisierungskonflikt beim Schreiben des aktuellen Datensatzes: "],"This record has been modified while you were editing it.":[null,"Dieser Datensatz wurde anderweitig geändert, während Sie ihn bearbeitet haben."],"Choose:":[null,"Lösungsmöglichkeiten:"],"\"Cancel\" to cancel saving;":[null,"- \"Abbrechen\" um den Speichervorgang abzubrechen,"],"\"Compare\" to see the modified version;":[null,"- \"Vergleichen\" um die geänderte Version des Datensatzes zu betrachten,"],"\"Write Anyway\" to save your current version.":[null,"- \"Überschreiben\" um die gespeicherte Version mit Ihrer Version zu überschreiben."],"Compare":[null,"Vergleichen"],"Write Anyway":[null,"Überschreiben"],"Application Error":[null,"Anwendungsfehler"],"Report Bug":[null,"Fehler berichten"],"Processing...":[null,"Verarbeitung läuft…"],"Create...":[null,"Erstellen..."],"Download":[null,"Herunterladen"],"...":[null,"..."],"Attachments (%1)":[null,"Anhänge (%1)"],"Notes (%1)":[null,"Notizen (%1)"],"Search %1":[null,"Suche %1"],"Revision":[null,"Bearbeitung"],"All Fields":[null,"Alle Felder"],"Clear":[null,"Leeren"],"Fields Selected":[null,"Ausgewählte Felder"],"CSV Parameters":[null,"CSV Parameter"],"Delimiter:":[null,"Trennzeichen:"],"Quote Char:":[null,"Anführungszeichen:"],"Encoding:":[null,"Zeichenkodierung:"],"Import from CSV":[null,"Aus CSV Datei importieren"],"Auto-Detect":[null,"Automatische Erkennung"],"File to Import":[null,"Zu importierende Datei"],"Lines to Skip:":[null,"Zu überspringende Zeilen:"],"You must select an import file first":[null,"Zuerst muss eine Importdatei ausgewählt werden."],"Error occured in loading the file":[null,"Fehler beim Öffnen der CSV-Datei"],"Error processing the file at field %1.":[null,"Fehler bei der Verarbeitung der Datei in Feld %1."],"Error":[null,"Fehler"],"Export to CSV":[null,"Als CSV exportieren"],"Predefined Exports":[null,"Vordefinierte Exporte"],"Save Export":[null,"Exportkonfiguration speichern"],"Delete Export":[null,"Exportkonfiguration löschen"],"Add Field Names":[null,"Feldnamen hinzufügen"],"%1 (string)":[null,"%1 (string)"],"What is the name of this export?":[null,"Wie soll der Name des Exports lauten?"],"Override %1 definition?":[null,"Definition von %1 nicht berücksichtigen?"],"Wizard":[null,"Assistent"]}
\ No newline at end of file
diff --git a/locale/de.po b/locale/de.po
index 0a5681f..69160cc 100644
--- a/locale/de.po
+++ b/locale/de.po
@@ -2,6 +2,9 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 15 2017 01:03:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Apr 04 2017 10:44:30 GMT+0200 (CEST)
 # Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
 msgid "Manage favorites"
 msgstr "Lesezeichen verwalten"
@@ -23,17 +26,17 @@ msgstr "Kann nicht zum Server verbinden"
 msgid "Login"
 msgstr "Anmeldename"
 
+msgid "User name"
+msgstr "Benutzername"
+
 msgid "Database"
 msgstr "Datenbank"
 
 msgid "Unable to reach the server."
 msgstr "Kann nicht zum Server verbinden."
 
-msgid "Toggle navigation"
-msgstr "Navigation umschalten"
-
-msgid "Menu"
-msgstr "Menü"
+msgid "Close"
+msgstr "Schließen"
 
 msgid ""
 "The following action requires to close all tabs.\n"
@@ -42,54 +45,39 @@ msgstr ""
 "Die folgende Aktion erfordert die Schließung aller Registerkarten.\n"
 "Fortfahren?"
 
-msgid "Close"
-msgstr "Schließen"
-
-msgid "New"
-msgstr "Neu"
-
 msgid "Create a new record"
 msgstr "Einen neuen Datensatz erstellen"
 
-msgid "Save"
-msgstr "Speichern"
-
 msgid "Save this record"
 msgstr "Diesen Datensatz speichern"
 
-msgid "Switch"
-msgstr "Ansicht wechseln"
-
 msgid "Switch view"
 msgstr "Ansicht wechseln"
 
 msgid "Reload"
 msgstr "Neu laden"
 
-msgid "Previous"
-msgstr "Vorheriger"
-
 msgid "Previous Record"
 msgstr "Vorheriger Datensatz"
 
-msgid "Next"
-msgstr "Nächster"
-
 msgid "Next Record"
 msgstr "Nächster Datensatz"
 
-msgid "Attachment"
-msgstr "Anhang"
-
 msgid "Add an attachment to the record"
 msgstr "Einen Anhang zum Datensatz hinzufügen"
 
-msgid "Note"
-msgstr "Notiz"
-
 msgid "Add a note to the record"
 msgstr "Eine Notiz zu einem Datensatz hinzufügen"
 
+msgid "New"
+msgstr "Neu"
+
+msgid "Save"
+msgstr "Speichern"
+
+msgid "Switch"
+msgstr "Ansicht wechseln"
+
 msgid "Reload/Undo"
 msgstr "Neu laden/Rückgängig"
 
@@ -99,6 +87,12 @@ msgstr "Duplizieren"
 msgid "Delete"
 msgstr "Löschen"
 
+msgid "Previous"
+msgstr "Vorheriger"
+
+msgid "Next"
+msgstr "Nächster"
+
 msgid "Search"
 msgstr "Suchen"
 
@@ -111,6 +105,12 @@ msgstr "Bearbeitungen anzeigen..."
 msgid "Close Tab"
 msgstr "Registerkarte schließen"
 
+msgid "Attachment"
+msgstr "Anhang"
+
+msgid "Note"
+msgstr "Notiz"
+
 msgid "Action"
 msgstr "Aktion"
 
@@ -181,12 +181,6 @@ msgstr "Zuletzt verändert am"
 msgid "Model: "
 msgstr "Modell:"
 
-msgid "Attachment(%1)"
-msgstr "Anhang(%1)"
-
-msgid "Note(%1)"
-msgstr "Notiz(%1)"
-
 msgid "Filters"
 msgstr "Filter"
 
@@ -261,6 +255,12 @@ msgstr ""
 msgid "No other language available."
 msgstr "Keine weitere Sprache verfügbar"
 
+msgid "Show"
+msgstr "Anzeigen"
+
+msgid "Hide"
+msgstr "Ausblenden"
+
 msgid "Font"
 msgstr "Schriftart"
 
@@ -291,6 +291,9 @@ msgstr ":"
 msgid "More"
 msgstr "Mehr"
 
+msgid ": "
+msgstr ": "
+
 msgid ", "
 msgstr ", "
 
@@ -397,9 +400,18 @@ msgstr "Anwendungsfehler"
 msgid "Report Bug"
 msgstr "Fehler berichten"
 
+msgid "Processing..."
+msgstr "Verarbeitung läuft…"
+
 msgid "Create..."
 msgstr "Erstellen..."
 
+msgid "Download"
+msgstr "Herunterladen"
+
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr "Anhänge (%1)"
 
diff --git a/locale/de_DE.json b/locale/de_DE.json
new file mode 100644
index 0000000..a4ec096
--- /dev/null
+++ b/locale/de_DE.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,"Abmelden"],"Search...":[null,"Suche..."],"Unable to reach the server":[null,"Kann nicht zum Server verbinden"],"Unable to reach the server.":[null,"Kann nicht zum Server verbinden."],"Login":[null,"Anmelden"],"Password":[null,"Passwort"],"Database":[null,"Datenbank"],"OK":[null,"OK"],"Toggle navigation":[null,"Navigation umschalten"],"Menu":[null,"Menü"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"Die folgende Aktion erfordert die Schließung aller Registerkarten.\nFortfahren?"],"Close":[null,"Schließen"],"New":[null,"Neu"],"Create a new record":[null,"Einen neuen Datensatz erstellen"],"Save":[null,"Speichern"],"Save this record":[null,"Diesen Datensatz speichern"],"Switch":[null,"Ansicht wechseln"],"Switch view":[null,"Ansicht wechseln"],"Reload":[null,"Neu laden"],"Previous":[null,"Vorheriger"],"Previous Record":[null,"Vorheriger Datensatz"],"Next":[null,"Nächster"],"Next Record":[null,"Nächster Datensatz"],"Attachment":[null,"Anhang"],"Add an attachment to the record":[null,"Einen Anhang zum Datensatz hinzufügen"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"Neu laden/Rückgängig"],"Duplicate":[null,"Duplizieren"],"Delete":[null,"Löschen"],"Search":[null,"Suchen"],"View Logs...":[null,"Protokoll ansehen..."],"Show revisions...":[null,"Bearbeitungen anzeigen..."],"Close Tab":[null,"Registerkarte schließen"],"Action":[null,"Aktion"],"Relate":[null,"Beziehung"],"Print":[null,"Drucken"],"Launch action":[null,"Aktion ausführen"],"Open related records":[null,"Datensätze einer Beziehung öffnen"],"Print report":[null,"Bericht drucken"],"This record has been modified\ndo you want to save it?":[null,"Datensatz geändert.\nSoll der Datensatz gespeichert werden?"],"Record saved.":[null,"Der Datensatz wurde gespeichert."],"Working now on the duplicated record(s).":[null,"Sie arbeiten nun an dem/den duplizierten Datensatz/Datensätzen."],"Are you sure to remove this record?":[null,"Möchten Sie diesen Datensatz wirklich löschen?"],"Are you sure to remove those records?":[null,"Möchten Sie diese Datensätze wirklich löschen?"],"Records removed.":[null,"Die Datensätze wurden gelöscht."],"Records not removed.":[null,"Die Datensätze wurden nicht gelöscht."],"You have to select one record.":[null,"Ein Datensatz muss ausgewählt werden."],"ID:":[null,"ID:"],"Creation User:":[null,"Erstellt von:"],"Creation Date:":[null,"Erstellt am:"],"Latest Modification by:":[null,"Zuletzt verändert von"],"Latest Modification Date:":[null,"Zuletzt verändert am"],"Model: ":[null,"Modell:"],"Attachment(%1)":[null,"Anhang(%1)"],"Note(%1)":[null,""],"Filters":[null,"Filter"],"Bookmarks":[null,"Lesezeichen"],"Remove this bookmark":[null,"Dieses Lesezeichen entfernen"],"Bookmark this filter":[null,"Diesen Filter als Lesezeichen hinzufügen"],"Bookmark Name:":[null,"Lesezeichenname:"],"True":[null,"Wahr"],"False":[null,"Falsch"],"Find":[null,"Suchen"],"ID":[null,"ID"],"Creation User":[null,"Erstellt von"],"Creation Date":[null,"Erstellt am:"],"Modification User":[null,"Zuletzt verändert von"],"Modification Date":[null,"Zuletzt verändert am"],"\"%1\" is required":[null,"In Feld \"%1\" ist ein Eintrag erforderlich."],"\"%1\" is not valid according to its domain":[null,"\"%1\" liegt nicht im gültigen Wertebereich (Domain)."],"The values of \"%1\" are not valid":[null,"Die Werte von \"%1\" sind ungültig."],"Pre-validation":[null,"Vorvalidierung"],"Font":[null,"Schriftart"],"Size":[null,"Größe"],"Add":[null,"Hinzufügen"],"Remove":[null,"Entfernen"],"Open":[null,"Öffnen"],"Undelete":[null,"Löschung rückgängig machen"],"Select":[null,"Auswählen"],"Cancel":[null,"Abbrechen"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Mehr"],"Calendar view not yet implemented":[null,"Kalenderansicht noch nicht verfügbar"],"Warning":[null,"Warnung"],"Select your action":[null,"Wählen Sie eine Aktion"],"No action defined!":[null,"Keine Aktion angegeben."],"Your selection:":[null,"Ihre Auswahl:"],"Y":[null,"J"],"M":[null,"M"],"w":[null,"W"],"d":[null,"t"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"y":[null,"j"],"yes":[null,"Ja"],"true":[null,"Wahr"],"t":[null,"W"],"Message: ":[null,"Nachricht: "],"Warning: ":[null,"Warnung: "],"Always ignore this warning.":[null,"Diese Warnung immer ignorieren."],"Do you want to proceed?":[null,"Fortfahren?"],"No":[null,"Nein"],"Yes":[null,"Ja"],"Confirmation: ":[null,"Bestätigung: "],"Concurrency Exception":[null,"Aktualisierungskonflikt"],"Write Concurrency Warning: ":[null,"Aktualisierungskonflikt beim Schreiben des aktuellen Datensatzes: "],"This record has been modified while you were editing it.":[null,"Dieser Datensatz wurde anderweitig geändert, während Sie ihn bearbeitet haben."],"Choose:":[null,"Lösungsmöglichkeiten:"],"\"Cancel\" to cancel saving;":[null,"- \"Abbrechen\" um den Speichervorgang abzubrechen,"],"\"Compare\" to see the modified version;":[null,"- \"Vergleichen\" um die geänderte Version des Datensatzes zu betrachten,"],"\"Write Anyway\" to save your current version.":[null,"- \"Überschreiben\" um die gespeicherte Version mit Ihrer Version zu überschreiben."],"Compare":[null,"Vergleichen"],"Write Anyway":[null,"Überschreiben"],"Application Error":[null,"Anwendungsfehler"],"Report Bug":[null,"Fehler berichten"],"Revision":[null,"Bearbeitung"],"Wizard":[null,"Assistent"]}
\ No newline at end of file
diff --git a/locale/es.json b/locale/es.json
index 8297435..21c47c9 100644
--- a/locale/es.json
+++ b/locale/es.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Gestionar los favoritos"],"Logout":[null,"Cerrar sesión"],"Favorites":[null,"Favoritos"],"Search...":[null,"Buscar…"],"Unable to reach the server":[null,"No es posible conectar con el servidor."],"Login":[null,"Usuario"],"Database":[null,"Base de datos"],"Unable to reach the server.":[null,"No es posible conectar con el servidor."],"Toggle navigation":[null,"Conmuta navegación"],"Menu":[null,"Menú"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"La acción seleccionada requiere cerrar todas las pestañas.\n¿Desea continuar?"],"Close":[null,"Cerrar"],"New":[null,"Nuevo"],"Create a new record":[null,"Crea un registro nuevo"],"Save":[null,"Guardar"],"Save this record":[null,"Guarda este registro"],"Switch":[null,"Cambiar"],"Switch view":[null,"Cambiar de vista"],"Reload":[null,"Recargar"],"Previous":[null,"Anterior"],"Previous Record":[null,"Registro anterior"],"Next":[null,"Siguiente"],"Next Record":[null,"Registro siguiente"],"Attachment":[null,"Adjunto"],"Add an attachment to the record":[null,"Añadir un adjunto al registro"],"Note":[null,"Nota"],"Add a note to the record":[null,"Añadir una nota al registro"],"Reload/Undo":[null,"Recargar/Deshacer"],"Duplicate":[null,"Duplicar"],"Delete":[null,"Eliminar"],"Search":[null,"Buscar"],"View Logs...":[null,"Ver registro..."],"Show revisions...":[null,"Mostrar revisiones..."],"Close Tab":[null,"Cerrar pestaña"],"Action":[null,"Acción"],"Relate":[null,"Relacionado"],"Print":[null,"Imprimir"],"Export":[null,"Exportar"],"Import":[null,"Importar"],"Launch action":[null,"Ejecutar acción"],"Open related records":[null,"Abrir registros relacionados"],"Print report":[null,"Imprimir informe"],"This record has been modified\ndo you want to save it?":[null,"Este registro ha sido modificado.\n¿Desea guardarlo?"],"Record saved.":[null,"Registro guardado."],"Working now on the duplicated record(s).":[null,"Ahora está trabajando en el/los registro(s) duplicado(s)."],"Are you sure to remove this record?":[null,"¿Está seguro que quiere eliminar este registro?"],"Are you sure to remove those records?":[null,"¿Está seguro que quiere eliminar estos registros?"],"Records removed.":[null,"Los registros se han eliminado."],"Records not removed.":[null,"Los registros no se han eliminado."],"You have to select one record.":[null,"Debe elegir un registro."],"ID:":[null,"ID:"],"Creation User:":[null,"Creado por:"],"Creation Date:":[null,"Fecha creación:"],"Latest Modification by:":[null,"Última modificación por:"],"Latest Modification Date:":[null,"Última fecha de modificación:"],"Model: ":[null,"Modelo: "],"Attachment(%1)":[null,"Adjunto(%1)"],"Note(%1)":[null,"Nota(%1)"],"Filters":[null,"Filtros"],"Bookmarks":[null,"Búsquedas favoritas"],"Remove this bookmark":[null,"Eliminar de las búsquedas favoritas"],"Bookmark this filter":[null,"Guardar como búsqueda favorita"],"Bookmark Name:":[null,"Nombre de la búsqueda favorita:"],"True":[null,"Verdadero"],"False":[null,"Falso"],"Find":[null,"Buscar"],"ID":[null,"ID"],"Creation User":[null,"Creado por:"],"Creation Date":[null,"Fecha creación:"],"Modification User":[null,"Última modificación por:"],"Modification Date":[null,"Última fecha de modificación:"],"\"%1\" is required":[null,"\"%1\" es obligatorio."],"\"%1\" is not valid according to its domain":[null,"\"%1\" no es válido según su dominio."],"The values of \"%1\" are not valid":[null,"Los valores de \"%1\" no son válidos."],"Pre-validation":[null,"Prevalidación"],"Translate":[null,"Traducir"],"Cancel":[null,"Cancelar"],"OK":[null,"Aceptar"],"Edit":[null,"Editar"],"Fuzzy":[null,"Dudoso"],"You need to save the record before adding translations.":[null,"Debe guardar el registro antes de agregar traducciones."],"No other language available.":[null,"No hay otros lenguajes disponibles."],"Font":[null,"Tipo de letra"],"Size":[null,"Tamaño"],"Add":[null,"Añadir"],"Remove":[null,"Eliminar"],"Open":[null,"Abrir"],"Undelete":[null,"Recuperar"],"Select":[null,"Seleccionar"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Más"],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Seleccione su acción"],"No action defined.":[null,"No se ha definido ninguna acción."],"Your selection:":[null,"Su selección:"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Por: "],"y":[null,"a"],"Yes":[null,"Si"],"t":[null,"v"],"Message: ":[null,"Mensaje: "],"Warning: ":[null,"Aviso: "],"Always ignore this warning.":[null,"Ignorar siempre esta advertencia."],"Do you want to proceed?":[null,"¿Desea continuar?"],"No":[null,"No"],"Confirmation: ":[null,"Confirmación: "],"Concurrency Exception":[null,"Excepción de concurrencia"],"Write Concurrency Warning: ":[null,"Aviso de concurrencia de escritura: "],"This record has been modified while you were editing it.":[null,"Este registro ha sido modificado mientras lo editaba."],"Choose:":[null,"Elija:"],"\"Cancel\" to cancel saving;":[null,"\"Cancelar\" para no guardar;"],"\"Compare\" to see the modified version;":[null,"\"Comparar\" para ver la versión modificada;"],"\"Write Anyway\" to save your current version.":[null,"\"Guardar de todas formas\" para guardar sus cambios."],"Compare":[null,"Comparar"],"Write Anyway":[null,"Guardar de todas formas"],"Application Error":[null,"Error de aplicación."],"Report Bug":[null,"Informar del error"],"Create...":[null,"Crear..."],"Attachments (%1)":[null,"Adjuntos (%1)"],"Notes (%1)":[null,"Notas (%1)"],"Search %1":[null,"Buscar %1"],"Revision":[null,"Revisión"],"All Fields":[null,"Todos los campos"],"Clear":[null,"Limpiar"],"Fields Selected":[null,"Campos selecionados"],"CSV Parameters":[null,"Parámetros CSV"],"Delimiter:":[null,"Separador:"],"Quote Char:":[null,"Delimitador del texto:"],"Encoding:":[null,"Codificación:"],"Import from CSV":[null,"Importar desde CSV"],"Auto-Detect":[null,"Detectar automáticamente"],"File to Import":[null,"Fichero a importar"],"Lines to Skip:":[null,"Líneas a omitir:"],"You must select an import file first":[null,"Primero debe seleccionar el fichero a importar."],"Error occured in loading the file":[null,"Ha ocurrido un al cargar el fichero"],"Error processing the file at field %1.":[null,"Error procesando el fichero en el campo %1."],"Error":[null,"Error"],"Export to CSV":[null,"Exportar a CSV"],"Predefined Exports":[null,"Exportaciones predefinidas"],"Save Export":[null,"Guardar exportación"],"Delete Export":[null,"Eliminar exportación"],"Add Field Names":[null,"Añadir nombres de los campos"],"%1 (string)":[null,"%1 (string)"],"What is the name of this export?":[null,"Cuál es el nombre de esta exportación?"],"Override %1 definition?":[null,"Queréis sobrescribir la definición de %1?"],"Wizard":[null,"Asistente"]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Gestionar los favoritos"],"Logout":[null,"Cerrar sesión"],"Favorites":[null,"Favoritos"],"Search...":[null,"Buscar…"],"Unable to reach the server":[null,"No es posible conectar con el servidor."],"Login":[null,"Usuario"],"User name":[null,"Nombre de usuario"],"Database":[null,"Base de datos"],"Unable to reach the server.":[null,"No es posible conectar con el servidor."],"Close":[null,"Cerrar"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"La acción seleccionada requiere cerrar todas las pestañas.\n¿Desea continuar?"],"Create a new record":[null,"Crea un registro nuevo"],"Save this record":[null,"Guarda este registro"],"Switch view":[null,"Cambiar de vista"],"Reload":[null,"Recargar"],"Previous Record":[null,"Registro anterior"],"Next Record":[null,"Registro siguiente"],"Add an attachment to the record":[null,"Añadir un adjunto al registro"],"Add a note to the record":[null,"Añadir una nota al registro"],"New":[null,"Nuevo"],"Save":[null,"Guardar"],"Switch":[null,"Cambiar"],"Reload/Undo":[null,"Recargar/Deshacer"],"Duplicate":[null,"Duplicar"],"Delete":[null,"Eliminar"],"Previous":[null,"Anterior"],"Next":[null,"Siguiente"],"Search":[null,"Buscar"],"View Logs...":[null,"Ver registro..."],"Show revisions...":[null,"Mostrar revisiones..."],"Close Tab":[null,"Cerrar pestaña"],"Attachment":[null,"Adjunto"],"Note":[null,"Nota"],"Action":[null,"Acción"],"Relate":[null,"Relacionado"],"Print":[null,"Imprimir"],"Export":[null,"Exportar"],"Import":[null,"Importar"],"Launch action":[null,"Ejecutar acción"],"Open related records":[null,"Abrir registros relacionados"],"Print report":[null,"Imprimir informe"],"This record has been modified\ndo you want to save it?":[null,"Este registro ha sido modificado.\n¿Desea guardarlo?"],"Record saved.":[null,"Registro guardado."],"Working now on the duplicated record(s).":[null,"Ahora está trabajando en el/los registro(s) duplicado(s)."],"Are you sure to remove this record?":[null,"¿Está seguro que quiere eliminar este registro?"],"Are you sure to remove those records?":[null,"¿Está seguro que quiere eliminar estos registros?"],"Records removed.":[null,"Los registros se han eliminado."],"Records not removed.":[null,"Los registros no se han eliminado."],"You have to select one record.":[null,"Debe elegir un registro."],"ID:":[null,"ID:"],"Creation User:":[null,"Creado por:"],"Creation Date:":[null,"Fecha creación:"],"Latest Modification by:":[null,"Última modificación por:"],"Latest Modification Date:":[null,"Última fecha de modificación:"],"Model: ":[null,"Modelo: "],"Filters":[null,"Filtros"],"Bookmarks":[null,"Búsquedas favoritas"],"Remove this bookmark":[null,"Eliminar de las búsquedas favoritas"],"Bookmark this filter":[null,"Guardar como búsqueda favorita"],"Bookmark Name:":[null,"Nombre de la búsqueda favorita:"],"True":[null,"Verdadero"],"False":[null,"Falso"],"Find":[null,"Buscar"],"ID":[null,"ID"],"Creation User":[null,"Creado por:"],"Creation Date":[null,"Fecha creación:"],"Modification User":[null,"Última modificación por:"],"Modification Date":[null,"Última fecha de modificación:"],"\"%1\" is required":[null,"\"%1\" es obligatorio."],"\"%1\" is not valid according to its domain":[null,"\"%1\" no es válido según su dominio."],"The values of \"%1\" are not valid":[null,"Los valores de \"%1\" no son válidos."],"Pre-validation":[null,"Prevalidación"],"Translate":[null,"Traducir"],"Cancel":[null,"Cancelar"],"OK":[null,"Aceptar"],"Edit":[null,"Editar"],"Fuzzy":[null,"Dudoso"],"You need to save the record before adding translations.":[null,"Debe guardar el registro antes de agregar traducciones."],"No other language available.":[null,"No hay otros lenguajes disponibles."],"Show":[null,"Mostrar"],"Hide":[null,"Ocultar"],"Font":[null,"Tipo de letra"],"Size":[null,"Tamaño"],"Add":[null,"Añadir"],"Remove":[null,"Eliminar"],"Open":[null,"Abrir"],"Undelete":[null,"Recuperar"],"Select":[null,"Seleccionar"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Más"],": ":[null,": "],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Seleccione su acción"],"No action defined.":[null,"No se ha definido ninguna acción."],"Your selection:":[null,"Su selección:"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Por: "],"y":[null,"a"],"Yes":[null,"Si"],"t":[null,"v"],"Message: ":[null,"Mensaje: "],"Warning: ":[null,"Aviso: "],"Always ignore this warning.":[null,"Ignorar siempre esta advertencia."],"Do you want to proceed?":[null,"¿Desea continuar?"],"No":[null,"No"],"Confirmation: ":[null,"Confirmación: "],"Concurrency Exception":[null,"Excepción de concurrencia"],"Write Concurrency Warning: ":[null,"Aviso de concurrencia de escritura: "],"This record has been modified while you were editing it.":[null,"Este registro ha sido modificado mientras lo editaba."],"Choose:":[null,"Elija:"],"\"Cancel\" to cancel saving;":[null,"\"Cancelar\" para no guardar;"],"\"Compare\" to see the modified version;":[null,"\"Comparar\" para ver la versión modificada;"],"\"Write Anyway\" to save your current version.":[null,"\"Guardar de todas formas\" para guardar sus cambios."],"Compare":[null,"Comparar"],"Write Anyway":[null,"Guardar de todas formas"],"Application Error":[null,"Error de aplicación."],"Report Bug":[null,"Informar del error"],"Processing...":[null,"Procesando…"],"Create...":[null,"Crear..."],"Download":[null,"Descargar"],"...":[null,"..."],"Attachments (%1)":[null,"Adjuntos (%1)"],"Notes (%1)":[null,"Notas (%1)"],"Search %1":[null,"Buscar %1"],"Revision":[null,"Revisión"],"All Fields":[null,"Todos los campos"],"Clear":[null,"Limpiar"],"Fields Selected":[null,"Campos selecionados"],"CSV Parameters":[null,"Parámetros CSV"],"Delimiter:":[null,"Separador:"],"Quote Char:":[null,"Delimitador del texto:"],"Encoding:":[null,"Codificación:"],"Import from CSV":[null,"Importar desde CSV"],"Auto-Detect":[null,"Detectar automáticamente"],"File to Import":[null,"Fichero a importar"],"Lines to Skip:":[null,"Líneas a omitir:"],"You must select an import file first":[null,"Primero debe seleccionar el fichero a importar."],"Error occured in loading the file":[null,"Ha ocurrido un al cargar el fichero"],"Error processing the file at field %1.":[null,"Error procesando el fichero en el campo %1."],"Error":[null,"Error"],"Export to CSV":[null,"Exportar a CSV"],"Predefined Exports":[null,"Exportaciones predefinidas"],"Save Export":[null,"Guardar exportación"],"Delete Export":[null,"Eliminar exportación"],"Add Field Names":[null,"Añadir nombres de los campos"],"%1 (string)":[null,"%1 (string)"],"What is the name of this export?":[null,"Cuál es el nombre de esta exportación?"],"Override %1 definition?":[null,"Queréis sobrescribir la definición de %1?"],"Wizard":[null,"Asistente"]}
\ No newline at end of file
diff --git a/locale/es.po b/locale/es.po
index 0fe4853..6d51823 100644
--- a/locale/es.po
+++ b/locale/es.po
@@ -2,6 +2,9 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 15 2017 01:03:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Apr 04 2017 10:44:30 GMT+0200 (CEST)
 # Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
 # Generated by grunt-xgettext on Tue Nov 01 2016 15:18:23 GMT+0100 (CET)
 msgid "Manage favorites"
@@ -24,17 +27,17 @@ msgstr "No es posible conectar con el servidor."
 msgid "Login"
 msgstr "Usuario"
 
+msgid "User name"
+msgstr "Nombre de usuario"
+
 msgid "Database"
 msgstr "Base de datos"
 
 msgid "Unable to reach the server."
 msgstr "No es posible conectar con el servidor."
 
-msgid "Toggle navigation"
-msgstr "Conmuta navegación"
-
-msgid "Menu"
-msgstr "Menú"
+msgid "Close"
+msgstr "Cerrar"
 
 msgid ""
 "The following action requires to close all tabs.\n"
@@ -43,54 +46,39 @@ msgstr ""
 "La acción seleccionada requiere cerrar todas las pestañas.\n"
 "¿Desea continuar?"
 
-msgid "Close"
-msgstr "Cerrar"
-
-msgid "New"
-msgstr "Nuevo"
-
 msgid "Create a new record"
 msgstr "Crea un registro nuevo"
 
-msgid "Save"
-msgstr "Guardar"
-
 msgid "Save this record"
 msgstr "Guarda este registro"
 
-msgid "Switch"
-msgstr "Cambiar"
-
 msgid "Switch view"
 msgstr "Cambiar de vista"
 
 msgid "Reload"
 msgstr "Recargar"
 
-msgid "Previous"
-msgstr "Anterior"
-
 msgid "Previous Record"
 msgstr "Registro anterior"
 
-msgid "Next"
-msgstr "Siguiente"
-
 msgid "Next Record"
 msgstr "Registro siguiente"
 
-msgid "Attachment"
-msgstr "Adjunto"
-
 msgid "Add an attachment to the record"
 msgstr "Añadir un adjunto al registro"
 
-msgid "Note"
-msgstr "Nota"
-
 msgid "Add a note to the record"
 msgstr "Añadir una nota al registro"
 
+msgid "New"
+msgstr "Nuevo"
+
+msgid "Save"
+msgstr "Guardar"
+
+msgid "Switch"
+msgstr "Cambiar"
+
 msgid "Reload/Undo"
 msgstr "Recargar/Deshacer"
 
@@ -100,6 +88,12 @@ msgstr "Duplicar"
 msgid "Delete"
 msgstr "Eliminar"
 
+msgid "Previous"
+msgstr "Anterior"
+
+msgid "Next"
+msgstr "Siguiente"
+
 msgid "Search"
 msgstr "Buscar"
 
@@ -112,6 +106,12 @@ msgstr "Mostrar revisiones..."
 msgid "Close Tab"
 msgstr "Cerrar pestaña"
 
+msgid "Attachment"
+msgstr "Adjunto"
+
+msgid "Note"
+msgstr "Nota"
+
 msgid "Action"
 msgstr "Acción"
 
@@ -182,12 +182,6 @@ msgstr "Última fecha de modificación:"
 msgid "Model: "
 msgstr "Modelo: "
 
-msgid "Attachment(%1)"
-msgstr "Adjunto(%1)"
-
-msgid "Note(%1)"
-msgstr "Nota(%1)"
-
 msgid "Filters"
 msgstr "Filtros"
 
@@ -260,6 +254,12 @@ msgstr "Debe guardar el registro antes de agregar traducciones."
 msgid "No other language available."
 msgstr "No hay otros lenguajes disponibles."
 
+msgid "Show"
+msgstr "Mostrar"
+
+msgid "Hide"
+msgstr "Ocultar"
+
 msgid "Font"
 msgstr "Tipo de letra"
 
@@ -290,6 +290,9 @@ msgstr ":"
 msgid "More"
 msgstr "Más"
 
+msgid ": "
+msgstr ": "
+
 msgid ", "
 msgstr ", "
 
@@ -392,9 +395,18 @@ msgstr "Error de aplicación."
 msgid "Report Bug"
 msgstr "Informar del error"
 
+msgid "Processing..."
+msgstr "Procesando…"
+
 msgid "Create..."
 msgstr "Crear..."
 
+msgid "Download"
+msgstr "Descargar"
+
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr "Adjuntos (%1)"
 
diff --git a/locale/es_419.json b/locale/es_419.json
index c4bdbb4..207155f 100644
--- a/locale/es_419.json
+++ b/locale/es_419.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"User name":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Close":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Create a new record":[null,""],"Save this record":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous Record":[null,""],"Next Record":[null,""],"Add an attachment to the record":[null,""],"Add a note to the record":[null,""],"New":[null,""],"Save":[null,""],"Switch":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Previous":[null,""],"Next":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Attachment":[null,""],"Note":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Processing...":[null,""],"Create...":[null,""],"Download":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/es_419.po b/locale/es_419.po
index 3766150..6c93eb0 100644
--- a/locale/es_419.po
+++ b/locale/es_419.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -21,16 +21,16 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
+msgid "User name"
 msgstr ""
 
-msgid "Unable to reach the server."
+msgid "Database"
 msgstr ""
 
-msgid "Toggle navigation"
+msgid "Unable to reach the server."
 msgstr ""
 
-msgid "Menu"
+msgid "Close"
 msgstr ""
 
 msgid ""
@@ -38,52 +38,37 @@ msgid ""
 "Do you want to continue?"
 msgstr ""
 
-msgid "Close"
-msgstr ""
-
-msgid "New"
-msgstr ""
-
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -95,6 +80,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -107,6 +98,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -175,12 +172,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -253,6 +244,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -284,6 +281,10 @@ msgid "More"
 msgstr ""
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -387,9 +388,19 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/fr.json b/locale/fr.json
index 64b918b..db21292 100644
--- a/locale/fr.json
+++ b/locale/fr.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Gérer les favoris"],"Logout":[null,"Déconnexion"],"Favorites":[null,"Favoris"],"Search...":[null,"Recherche..."],"Unable to reach the server":[null,"Impossible de joindre le serveur"],"Login":[null,"Connexion"],"Database":[null,"Base de données"],"Unable to reach the server.":[null,"Impossible de joindre le serveur."],"Toggle navigation":[null,"Basculer la navigation"],"Menu":[null,"Menu"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"L'action suivante nécessite de fermer tous les onglets.\nVoulez-vous continuer ?"],"Close":[null,"Fermer"],"New":[null,"Nouveau"],"Create a new record":[null,"Crée un nouvel enregistrement"],"Save":[null,"Sauver"],"Save this record":[null,"Sauver cet enregistrement"],"Switch":[null,"Basculer"],"Switch view":[null,"Basculer la vue"],"Reload":[null,"Recharger"],"Previous":[null,"Précédent"],"Previous Record":[null,"Enregistrement précédent"],"Next":[null,"Suivant"],"Next Record":[null,"Enregistrement suivant"],"Attachment":[null,"Attachement"],"Add an attachment to the record":[null,"Ajouter un attachement à l'enregistrement"],"Note":[null,"Note"],"Add a note to the record":[null,"Ajouter une note à l'enregistrement"],"Reload/Undo":[null,"Recharger/Annuler"],"Duplicate":[null,"Dupliquer"],"Delete":[null,"Supprimer"],"Search":[null,"Rechercher"],"View Logs...":[null,"Voir les Logs..."],"Show revisions...":[null,"Afficher les révisions..."],"Close Tab":[null,"Fermer l'onglet"],"Action":[null,"Actions"],"Relate":[null,"Relation"],"Print":[null,"Imprimer"],"Export":[null,"Exporter"],"Import":[null,"Importer"],"Launch action":[null,"Lancer une action"],"Open related records":[null,"Ouvrir les enregistrements liés"],"Print report":[null,"Imprimer un rapport"],"This record has been modified\ndo you want to save it?":[null,"Cet enregistrement a été modifié\nvoulez-vous le sauvegarder ?"],"Record saved.":[null,"Enregistrement sauvé."],"Working now on the duplicated record(s).":[null,"Sur les enregistrement(s) dupliqué(s) maintenant."],"Are you sure to remove this record?":[null,"Êtes-vous sûr de vouloir supprimer cet enregistrement ?"],"Are you sure to remove those records?":[null,"Êtes-vous sûr de vouloir supprimer ces enregistrements ?"],"Records removed.":[null,"Enregistrements supprimés."],"Records not removed.":[null,"Enregistrements non supprimés."],"You have to select one record.":[null,"Vous devez sélectionner un enregistrement."],"ID:":[null,"ID :"],"Creation User:":[null,"Créé par l'utilisateur :"],"Creation Date:":[null,"Date de création :"],"Latest Modification by:":[null,"Dernière modification par :"],"Latest Modification Date:":[null,"Date de dernière modification :"],"Model: ":[null,"Modèle : "],"Attachment(%1)":[null,"Attachement(%1)"],"Note(%1)":[null,"Note(%1)"],"Filters":[null,"Filtres"],"Bookmarks":[null,"Marques-pages"],"Remove this bookmark":[null,"Supprimer ce marque-page"],"Bookmark this filter":[null,"Sauver ce filtre"],"Bookmark Name:":[null,"Nom du marque-page :"],"True":[null,"Vrai"],"False":[null,"Faux"],"Find":[null,"Chercher"],"ID":[null,"ID"],"Creation User":[null,"Créé par l'utilisateur"],"Creation Date":[null,"Date de création"],"Modification User":[null,"Modifié par l'utilisateur"],"Modification Date":[null,"Date de modification"],"\"%1\" is required":[null,"« %1 » est requis"],"\"%1\" is not valid according to its domain":[null,"« %1 » n'est pas valide selon son domaine"],"The values of \"%1\" are not valid":[null,"Les valeurs de « %1 » ne sont pas valides"],"Pre-validation":[null,"Pré-validation"],"Translate":[null,"Traduire"],"Cancel":[null,"Annuler"],"OK":[null,"Valider"],"Edit":[null,"Éditer"],"Fuzzy":[null,"Floue"],"You need to save the record before adding translations.":[null,"Vous devez sauvegarder l'enregistrement avant d'ajouter des traductions."],"No other language available.":[null,"Pas d'autre langue disponible."],"Font":[null,"Police"],"Size":[null,"Taille"],"Add":[null,"Ajouter"],"Remove":[null,"Enlever"],"Open":[null,"Ouvrir"],"Undelete":[null,"Restaurer"],"Select":[null,"Sélectionner"],"%1%":[null,"%1%"],":":[null," :"],"More":[null,"Plus"],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Sélectionnez votre action"],"No action defined.":[null,"Pas d'action définie."],"Your selection:":[null,"Votre sélection :"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"j"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Par : "],"y":[null,"y"],"Yes":[null,"Oui"],"t":[null,"v"],"Message: ":[null,"Message : "],"Warning: ":[null,"Avertissement : "],"Always ignore this warning.":[null,"Toujours ignorer cet avertissement."],"Do you want to proceed?":[null,"Souhaitez-vous continuer ?"],"No":[null,"Non"],"Confirmation: ":[null,"Confirmation : "],"Concurrency Exception":[null,"Erreur d'accès concurrent"],"Write Concurrency Warning: ":[null,"Attention, accès en écriture concurrents : "],"This record has been modified while you were editing it.":[null,"Cet enregistrement a été édité pendant que vous étiez en train de le modifier."],"Choose:":[null,"Choisissez :"],"\"Cancel\" to cancel saving;":[null,"« Annuler » pour annuler vos modifications ;"],"\"Compare\" to see the modified version;":[null,"« Comparer » pour voir la nouvelle version ;"],"\"Write Anyway\" to save your current version.":[null,"« Écraser » pour sauver vos modifications."],"Compare":[null,"Comparer"],"Write Anyway":[null,"Écraser"],"Application Error":[null,"Erreur applicative"],"Report Bug":[null,"Rapporter un bogue"],"Create...":[null,"Créer..."],"Attachments (%1)":[null,"Attachements (%1)"],"Notes (%1)":[null,"Notes (%1)"],"Search %1":[null,"Recherche %1"],"Revision":[null,"Révision"],"All Fields":[null,"Tous les champs"],"Clear":[null,"Effacer"],"Fields Selected":[null,"Champs sélectionnés"],"CSV Parameters":[null,"Paramètres CSV"],"Delimiter:":[null,"Délimiteur :"],"Quote Char:":[null,"Caractère de guillemet :"],"Encoding:":[null,"Codage :"],"Import from CSV":[null,"Importer depuis un CSV"],"Auto-Detect":[null,"Détection automatique"],"File to Import":[null,"Fichier à importer :"],"Lines to Skip:":[null,"Lignes à ignorer :"],"You must select an import file first":[null,"Vous devez d'abord sélectionner un fichier d'import"],"Error occured in loading the file":[null,"Une erreur a eu lieu au chargement du fichier"],"Error processing the file at field %1.":[null,"Erreur lors du traitement du fichier du champ %1."],"Error":[null,"Erreur"],"Export to CSV":[null,"Exporter en CSV"],"Predefined Exports":[null,"Exportations prédéfinies"],"Save Export":[null,"Sauver l'exportation"],"Delete Export":[null,"Supprimer l'exportation"],"Add Field Names":[null,"Ajouter les noms des champs"],"%1 (string)":[null,"%1 (string)"],"What is the name of this export?":[null,"Quel est le nom de cet export ?"],"Override %1 definition?":[null,"Surcharger la définition %s ?"],"Wizard":[null,"Assistant"]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Gérer les favoris"],"Logout":[null,"Déconnexion"],"Favorites":[null,"Favoris"],"Search...":[null,"Recherche..."],"Unable to reach the server":[null,"Impossible de joindre le serveur"],"Login":[null,"Connexion"],"User name":[null,"Nom d'utilisateur"],"Database":[null,"Base de données"],"Unable to reach the server.":[null,"Impossible de joindre le serveur."],"Close":[null,"Fermer"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"L'action suivante nécessite de fermer tous les onglets.\nVoulez-vous continuer ?"],"Create a new record":[null,"Crée un nouvel enregistrement"],"Save this record":[null,"Sauver cet enregistrement"],"Switch view":[null,"Basculer la vue"],"Reload":[null,"Recharger"],"Previous Record":[null,"Enregistrement précédent"],"Next Record":[null,"Enregistrement suivant"],"Add an attachment to the record":[null,"Ajouter un attachement à l'enregistrement"],"Add a note to the record":[null,"Ajouter une note à l'enregistrement"],"New":[null,"Nouveau"],"Save":[null,"Sauver"],"Switch":[null,"Basculer"],"Reload/Undo":[null,"Recharger/Annuler"],"Duplicate":[null,"Dupliquer"],"Delete":[null,"Supprimer"],"Previous":[null,"Précédent"],"Next":[null,"Suivant"],"Search":[null,"Rechercher"],"View Logs...":[null,"Voir les Logs..."],"Show revisions...":[null,"Afficher les révisions..."],"Close Tab":[null,"Fermer l'onglet"],"Attachment":[null,"Attachement"],"Note":[null,"Note"],"Action":[null,"Actions"],"Relate":[null,"Relation"],"Print":[null,"Imprimer"],"Export":[null,"Exporter"],"Import":[null,"Importer"],"Launch action":[null,"Lancer une action"],"Open related records":[null,"Ouvrir les enregistrements liés"],"Print report":[null,"Imprimer un rapport"],"This record has been modified\ndo you want to save it?":[null,"Cet enregistrement a été modifié\nvoulez-vous le sauvegarder ?"],"Record saved.":[null,"Enregistrement sauvé."],"Working now on the duplicated record(s).":[null,"Sur les enregistrement(s) dupliqué(s) maintenant."],"Are you sure to remove this record?":[null,"Êtes-vous sûr de vouloir supprimer cet enregistrement ?"],"Are you sure to remove those records?":[null,"Êtes-vous sûr de vouloir supprimer ces enregistrements ?"],"Records removed.":[null,"Enregistrements supprimés."],"Records not removed.":[null,"Enregistrements non supprimés."],"You have to select one record.":[null,"Vous devez sélectionner un enregistrement."],"ID:":[null,"ID :"],"Creation User:":[null,"Créé par l'utilisateur :"],"Creation Date:":[null,"Date de création :"],"Latest Modification by:":[null,"Dernière modification par :"],"Latest Modification Date:":[null,"Date de dernière modification :"],"Model: ":[null,"Modèle : "],"Filters":[null,"Filtres"],"Bookmarks":[null,"Marques-pages"],"Remove this bookmark":[null,"Supprimer ce marque-page"],"Bookmark this filter":[null,"Sauver ce filtre"],"Bookmark Name:":[null,"Nom du marque-page :"],"True":[null,"Vrai"],"False":[null,"Faux"],"Find":[null,"Chercher"],"ID":[null,"ID"],"Creation User":[null,"Créé par l'utilisateur"],"Creation Date":[null,"Date de création"],"Modification User":[null,"Modifié par l'utilisateur"],"Modification Date":[null,"Date de modification"],"\"%1\" is required":[null,"« %1 » est requis"],"\"%1\" is not valid according to its domain":[null,"« %1 » n'est pas valide selon son domaine"],"The values of \"%1\" are not valid":[null,"Les valeurs de « %1 » ne sont pas valides"],"Pre-validation":[null,"Pré-validation"],"Translate":[null,"Traduire"],"Cancel":[null,"Annuler"],"OK":[null,"Valider"],"Edit":[null,"Éditer"],"Fuzzy":[null,"Floue"],"You need to save the record before adding translations.":[null,"Vous devez sauvegarder l'enregistrement avant d'ajouter des traductions."],"No other language available.":[null,"Pas d'autre langue disponible."],"Show":[null,"Afficher"],"Hide":[null,"Masquer"],"Font":[null,"Police"],"Size":[null,"Taille"],"Add":[null,"Ajouter"],"Remove":[null,"Enlever"],"Open":[null,"Ouvrir"],"Undelete":[null,"Restaurer"],"Select":[null,"Sélectionner"],"%1%":[null,"%1%"],":":[null," :"],"More":[null,"Plus"],": ":[null," : "],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Sélectionnez votre action"],"No action defined.":[null,"Pas d'action définie."],"Your selection:":[null,"Votre sélection :"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"j"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Par : "],"y":[null,"y"],"Yes":[null,"Oui"],"t":[null,"v"],"Message: ":[null,"Message : "],"Warning: ":[null,"Avertissement : "],"Always ignore this warning.":[null,"Toujours ignorer cet avertissement."],"Do you want to proceed?":[null,"Souhaitez-vous continuer ?"],"No":[null,"Non"],"Confirmation: ":[null,"Confirmation : "],"Concurrency Exception":[null,"Erreur d'accès concurrent"],"Write Concurrency Warning: ":[null,"Attention, accès en écriture concurrents : "],"This record has been modified while you were editing it.":[null,"Cet enregistrement a été édité pendant que vous étiez en train de le modifier."],"Choose:":[null,"Choisissez :"],"\"Cancel\" to cancel saving;":[null,"« Annuler » pour annuler vos modifications ;"],"\"Compare\" to see the modified version;":[null,"« Comparer » pour voir la nouvelle version ;"],"\"Write Anyway\" to save your current version.":[null,"« Écraser » pour sauver vos modifications."],"Compare":[null,"Comparer"],"Write Anyway":[null,"Écraser"],"Application Error":[null,"Erreur applicative"],"Report Bug":[null,"Rapporter un bogue"],"Processing...":[null,"Traitement en cours..."],"Create...":[null,"Créer..."],"Download":[null,"Télécharger"],"...":[null,"..."],"Attachments (%1)":[null,"Attachements (%1)"],"Notes (%1)":[null,"Notes (%1)"],"Search %1":[null,"Recherche %1"],"Revision":[null,"Révision"],"All Fields":[null,"Tous les champs"],"Clear":[null,"Effacer"],"Fields Selected":[null,"Champs sélectionnés"],"CSV Parameters":[null,"Paramètres CSV"],"Delimiter:":[null,"Délimiteur :"],"Quote Char:":[null,"Caractère de guillemet :"],"Encoding:":[null,"Codage :"],"Import from CSV":[null,"Importer depuis un CSV"],"Auto-Detect":[null,"Détection automatique"],"File to Import":[null,"Fichier à importer :"],"Lines to Skip:":[null,"Lignes à ignorer :"],"You must select an import file first":[null,"Vous devez d'abord sélectionner un fichier d'import"],"Error occured in loading the file":[null,"Une erreur a eu lieu au chargement du fichier"],"Error processing the file at field %1.":[null,"Erreur lors du traitement du fichier du champ %1."],"Error":[null,"Erreur"],"Export to CSV":[null,"Exporter en CSV"],"Predefined Exports":[null,"Exportations prédéfinies"],"Save Export":[null,"Sauver l'exportation"],"Delete Export":[null,"Supprimer l'exportation"],"Add Field Names":[null,"Ajouter les noms des champs"],"%1 (string)":[null,"%1 (string)"],"What is the name of this export?":[null,"Quel est le nom de cet export ?"],"Override %1 definition?":[null,"Surcharger la définition %s ?"],"Wizard":[null,"Assistant"]}
\ No newline at end of file
diff --git a/locale/fr.po b/locale/fr.po
index 85d3c59..e7a10e9 100644
--- a/locale/fr.po
+++ b/locale/fr.po
@@ -2,6 +2,9 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 15 2017 01:03:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Apr 04 2017 10:44:30 GMT+0200 (CEST)
 # Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
 msgid "Manage favorites"
 msgstr "Gérer les favoris"
@@ -23,17 +26,17 @@ msgstr "Impossible de joindre le serveur"
 msgid "Login"
 msgstr "Connexion"
 
+msgid "User name"
+msgstr "Nom d'utilisateur"
+
 msgid "Database"
 msgstr "Base de données"
 
 msgid "Unable to reach the server."
 msgstr "Impossible de joindre le serveur."
 
-msgid "Toggle navigation"
-msgstr "Basculer la navigation"
-
-msgid "Menu"
-msgstr "Menu"
+msgid "Close"
+msgstr "Fermer"
 
 msgid ""
 "The following action requires to close all tabs.\n"
@@ -42,54 +45,39 @@ msgstr ""
 "L'action suivante nécessite de fermer tous les onglets.\n"
 "Voulez-vous continuer ?"
 
-msgid "Close"
-msgstr "Fermer"
-
-msgid "New"
-msgstr "Nouveau"
-
 msgid "Create a new record"
 msgstr "Crée un nouvel enregistrement"
 
-msgid "Save"
-msgstr "Sauver"
-
 msgid "Save this record"
 msgstr "Sauver cet enregistrement"
 
-msgid "Switch"
-msgstr "Basculer"
-
 msgid "Switch view"
 msgstr "Basculer la vue"
 
 msgid "Reload"
 msgstr "Recharger"
 
-msgid "Previous"
-msgstr "Précédent"
-
 msgid "Previous Record"
 msgstr "Enregistrement précédent"
 
-msgid "Next"
-msgstr "Suivant"
-
 msgid "Next Record"
 msgstr "Enregistrement suivant"
 
-msgid "Attachment"
-msgstr "Attachement"
-
 msgid "Add an attachment to the record"
 msgstr "Ajouter un attachement à l'enregistrement"
 
-msgid "Note"
-msgstr "Note"
-
 msgid "Add a note to the record"
 msgstr "Ajouter une note à l'enregistrement"
 
+msgid "New"
+msgstr "Nouveau"
+
+msgid "Save"
+msgstr "Sauver"
+
+msgid "Switch"
+msgstr "Basculer"
+
 msgid "Reload/Undo"
 msgstr "Recharger/Annuler"
 
@@ -99,6 +87,12 @@ msgstr "Dupliquer"
 msgid "Delete"
 msgstr "Supprimer"
 
+msgid "Previous"
+msgstr "Précédent"
+
+msgid "Next"
+msgstr "Suivant"
+
 msgid "Search"
 msgstr "Rechercher"
 
@@ -111,6 +105,12 @@ msgstr "Afficher les révisions..."
 msgid "Close Tab"
 msgstr "Fermer l'onglet"
 
+msgid "Attachment"
+msgstr "Attachement"
+
+msgid "Note"
+msgstr "Note"
+
 msgid "Action"
 msgstr "Actions"
 
@@ -181,12 +181,6 @@ msgstr "Date de dernière modification :"
 msgid "Model: "
 msgstr "Modèle : "
 
-msgid "Attachment(%1)"
-msgstr "Attachement(%1)"
-
-msgid "Note(%1)"
-msgstr "Note(%1)"
-
 msgid "Filters"
 msgstr "Filtres"
 
@@ -260,6 +254,12 @@ msgstr ""
 msgid "No other language available."
 msgstr "Pas d'autre langue disponible."
 
+msgid "Show"
+msgstr "Afficher"
+
+msgid "Hide"
+msgstr "Masquer"
+
 msgid "Font"
 msgstr "Police"
 
@@ -290,6 +290,9 @@ msgstr " :"
 msgid "More"
 msgstr "Plus"
 
+msgid ": "
+msgstr " : "
+
 msgid ", "
 msgstr ", "
 
@@ -394,9 +397,18 @@ msgstr "Erreur applicative"
 msgid "Report Bug"
 msgstr "Rapporter un bogue"
 
+msgid "Processing..."
+msgstr "Traitement en cours..."
+
 msgid "Create..."
 msgstr "Créer..."
 
+msgid "Download"
+msgstr "Télécharger"
+
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr "Attachements (%1)"
 
diff --git a/locale/fr_FR.json b/locale/fr_FR.json
new file mode 100644
index 0000000..1ff54f9
--- /dev/null
+++ b/locale/fr_FR.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,"Déconnexion"],"Search...":[null,"Recherche..."],"Unable to reach the server":[null,"Impossible de joindre le serveur"],"Unable to reach the server.":[null,"Impossible de joindre le serveur."],"Login":[null,"Connexion"],"Password":[null,"Mot de passe"],"Database":[null,"Base de données"],"OK":[null,"Valider"],"Toggle navigation":[null,"Basculer la navigation"],"Menu":[null,"Menu"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"L'action suivante nécessite de fermer tous les onglets.\nVoulez-vous continuer ?"],"Close":[null,"Fermer"],"New":[null,"Nouveau"],"Create a new record":[null,"Crée un nouvel enregistrement"],"Save":[null,"Sauver"],"Save this record":[null,"Sauver cet enregistrement"],"Switch":[null,"Basculer"],"Switch view":[null,"Basculer la vue"],"Reload":[null,"Recharger"],"Previous":[null,"Précédent"],"Previous Record":[null,"Enregistrement précédent"],"Next":[null,"Suivant"],"Next Record":[null,"Enregistrement suivant"],"Attachment":[null,"Attachement"],"Add an attachment to the record":[null,"Ajouter un attachement à l'enregistrement"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"Recharger/Annuler"],"Duplicate":[null,"Dupliquer"],"Delete":[null,"Supprimer"],"Search":[null,"Rechercher"],"View Logs...":[null,"Voir les Logs..."],"Show revisions...":[null,"Afficher les révisions..."],"Close Tab":[null,"Fermer l'onglet"],"Action":[null,"Actions"],"Relate":[null,"Relation"],"Print":[null,"Imprimer"],"Launch action":[null,"Lancer une action"],"Open related records":[null,"Ouvrir les enregistrements liés"],"Print report":[null,"Imprimer un rapport"],"This record has been modified\ndo you want to save it?":[null,"Cet enregistrement a été modifié\nvoulez-vous le sauvegarder ?"],"Record saved.":[null,"Enregistrement sauvé."],"Working now on the duplicated record(s).":[null,"Sur les enregistrement(s) dupliqué(s) maintenant."],"Are you sure to remove this record?":[null,"Êtes-vous sûr de vouloir supprimer cet enregistrement ?"],"Are you sure to remove those records?":[null,"Êtes-vous sûr de vouloir supprimer ces enregistrements ?"],"Records removed.":[null,"Enregistrements supprimés."],"Records not removed.":[null,"Enregistrements non supprimés."],"You have to select one record.":[null,"Vous devez sélectionner un enregistrement."],"ID:":[null,"ID :"],"Creation User:":[null,"Créé par l'utilisateur :"],"Creation Date:":[null,"Date de création :"],"Latest Modification by:":[null,"Dernière modification par :"],"Latest Modification Date:":[null,"Date de dernière modification :"],"Model: ":[null,"Modèle : "],"Attachment(%1)":[null,"Attachement(%1)"],"Note(%1)":[null,""],"Filters":[null,"Filtres"],"Bookmarks":[null,"Marques-pages"],"Remove this bookmark":[null,"Supprimer ce marque-page"],"Bookmark this filter":[null,"Sauver ce filtre"],"Bookmark Name:":[null,"Nom du marque-page :"],"True":[null,"Vrai"],"False":[null,"Faux"],"Find":[null,"Chercher"],"ID":[null,"ID"],"Creation User":[null,"Créé par l'utilisateur"],"Creation Date":[null,"Date de création"],"Modification User":[null,"Modifié par l'utilisateur"],"Modification Date":[null,"Date de modification"],"\"%1\" is required":[null,"« %1 » est requis"],"\"%1\" is not valid according to its domain":[null,"« %1 » n'est pas valide selon son domaine"],"The values of \"%1\" are not valid":[null,"Les valeurs de « %1 » ne sont pas valides"],"Pre-validation":[null,"Pré-validation"],"Font":[null,"Police"],"Size":[null,"Taille"],"Add":[null,"Ajouter"],"Remove":[null,"Enlever"],"Open":[null,"Ouvrir"],"Undelete":[null,"Restaurer"],"Select":[null,"Sélectionner"],"Cancel":[null,"Annuler"],"%1%":[null,"%1%"],":":[null," :"],"More":[null,"Plus"],"Calendar view not yet implemented":[null,"La vue calendrier n'est pas encore implémentée"],"Warning":[null,"Avertissement"],"Select your action":[null,"Sélectionnez votre action"],"No action defined!":[null,"Pas d'action définie !"],"Your selection:":[null,"Votre sélection :"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"S"],"d":[null,"j"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"y":[null,"y"],"yes":[null,"oui"],"true":[null,"vrai"],"t":[null,"v"],"Message: ":[null,"Message : "],"Warning: ":[null,"Avertissement : "],"Always ignore this warning.":[null,"Toujours ignorer cet avertissement."],"Do you want to proceed?":[null,"Souhaitez-vous continuer ?"],"No":[null,"Non"],"Yes":[null,"Oui"],"Confirmation: ":[null,"Confirmation : "],"Concurrency Exception":[null,"Erreur d'accès concurrent"],"Write Concurrency Warning: ":[null,"Attention, accès en écriture concurrents : "],"This record has been modified while you were editing it.":[null,"Cet enregistrement a été édité pendant que vous étiez en train de le modifier."],"Choose:":[null,"Choisissez :"],"\"Cancel\" to cancel saving;":[null,"« Annuler » pour annuler vos modifications ;"],"\"Compare\" to see the modified version;":[null,"« Comparer » pour voir la nouvelle version ;"],"\"Write Anyway\" to save your current version.":[null,"« Écraser » pour sauver vos modifications."],"Compare":[null,"Comparer"],"Write Anyway":[null,"Écraser"],"Application Error":[null,"Erreur applicative"],"Report Bug":[null,"Rapporter un bogue"],"Revision":[null,"Révision"],"Wizard":[null,"Assistant"]}
\ No newline at end of file
diff --git a/locale/hu_HU.json b/locale/hu_HU.json
index c4bdbb4..207155f 100644
--- a/locale/hu_HU.json
+++ b/locale/hu_HU.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"User name":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Close":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Create a new record":[null,""],"Save this record":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous Record":[null,""],"Next Record":[null,""],"Add an attachment to the record":[null,""],"Add a note to the record":[null,""],"New":[null,""],"Save":[null,""],"Switch":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Previous":[null,""],"Next":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Attachment":[null,""],"Note":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Processing...":[null,""],"Create...":[null,""],"Download":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/hu_HU.po b/locale/hu_HU.po
index 3766150..6c93eb0 100644
--- a/locale/hu_HU.po
+++ b/locale/hu_HU.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -21,16 +21,16 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
+msgid "User name"
 msgstr ""
 
-msgid "Unable to reach the server."
+msgid "Database"
 msgstr ""
 
-msgid "Toggle navigation"
+msgid "Unable to reach the server."
 msgstr ""
 
-msgid "Menu"
+msgid "Close"
 msgstr ""
 
 msgid ""
@@ -38,52 +38,37 @@ msgid ""
 "Do you want to continue?"
 msgstr ""
 
-msgid "Close"
-msgstr ""
-
-msgid "New"
-msgstr ""
-
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -95,6 +80,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -107,6 +98,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -175,12 +172,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -253,6 +244,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -284,6 +281,10 @@ msgid "More"
 msgstr ""
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -387,9 +388,19 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/it_IT.json b/locale/it_IT.json
index ef6fbf9..171e577 100644
--- a/locale/it_IT.json
+++ b/locale/it_IT.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"gestione preferiti"],"Logout":[null,"Esci"],"Favorites":[null,"Preferiti"],"Search...":[null,"Cerca..."],"Unable to reach the server":[null,"server non raggiungibile"],"Login":[null,"Login"],"Database":[null,"Database"],"Unable to reach the server.":[null,"server non raggiungibile"],"Toggle navigation":[null,"navigazione a tratti"],"Menu":[null,"Menu"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"la seguente azione richiede la chiusura di tutte le finestre. Intendi continuare?"],"Close":[null,"Chiudi"],"New":[null,"Nuovo"],"Create a new record":[null,"Crea un nuovo record"],"Save":[null,"Salva"],"Save this record":[null,"salvare il record"],"Switch":[null,"Scambia"],"Switch view":[null,"cambia visualizzazione"],"Reload":[null,"Ricarica"],"Previous":[null,"Precedente"],"Previous Record":[null,"Record precedente"],"Next":[null,"Successivo"],"Next Record":[null,"Record successivo"],"Attachment":[null,"Allegato"],"Add an attachment to the record":[null,"aggiungere un allegato al record"],"Note":[null,"nota"],"Add a note to the record":[null,"aggiungere nota al record"],"Reload/Undo":[null,"ricarica / ripristina"],"Duplicate":[null,"Duplica"],"Delete":[null,"Elimina"],"Search":[null,"Cerca"],"View Logs...":[null,"vedi logs"],"Show revisions...":[null,"mostra revisioni"],"Close Tab":[null,"Chiudi la scheda"],"Action":[null,"Azione"],"Relate":[null,"collega"],"Print":[null,"Stampa"],"Export":[null,"Esporta"],"Import":[null,"Importa"],"Launch action":[null,"lancia applicazione"],"Open related records":[null,"apri record collegati"],"Print report":[null,"Stampa rapporto"],"This record has been modified\ndo you want to save it?":[null,"questo record è stato modificato, intendi salvarlo?"],"Record saved.":[null,"record salvato"],"Working now on the duplicated record(s).":[null,"stai ora lavorando nel record duplicato"],"Are you sure to remove this record?":[null,"sei sicuro di rimuovere questo record?"],"Are you sure to remove those records?":[null,"sei sicuro di rimuovere questi record?"],"Records removed.":[null,"record rimossi"],"Records not removed.":[null,"record non rimossi"],"You have to select one record.":[null,"va selezionato un record"],"ID:":[null,"ID:"],"Creation User:":[null,"creato da:"],"Creation Date:":[null,"creato il:"],"Latest Modification by:":[null,"ultima modifica da:"],"Latest Modification Date:":[null,"ultima modifica il:"],"Model: ":[null,"Modello: "],"Attachment(%1)":[null,"allegato (%1)"],"Note(%1)":[null,"nota (%1)"],"Filters":[null,"Filtri"],"Bookmarks":[null,"Segnalibri"],"Remove this bookmark":[null,"rimuovere questo segnalibro"],"Bookmark this filter":[null,"contrassegnare questo filtro "],"Bookmark Name:":[null,"nome del segnalibro"],"True":[null,"Vero"],"False":[null,"Falso"],"Find":[null,"Trova"],"ID":[null,"ID"],"Creation User":[null,"creato da"],"Creation Date":[null,"creato il "],"Modification Date":[null,"Data di modifica "],"\"%1\" is required":[null,"\"%1\" è obbligatorio"],"\"%1\" is not valid according to its domain":[null,"\"%1\" non è valido rispetto al dominio"],"The values of \"%1\" are not valid":[null,"i valori di \"%1\" non sono validi"],"Pre-validation":[null,"pre-validazione"],"Translate":[null,"Traduci"],"Cancel":[null,"Annulla"],"OK":[null,"OK"],"Edit":[null,"Modifica"],"Fuzzy":[null,"fuzzy"],"You need to save the record before adding translations.":[null,"devi salvare il record prima di inserire la traduzione"],"No other language available.":[null,"non sono disponibili altre lingue"],"Font":[null,"Carattere"],"Size":[null,"Dimensione"],"Add":[null,"Aggiungi"],"Remove":[null,"Rimuovi"],"Open":[null,"Apri"],"Undelete":[null,"Annullare l'eliminazione"],"Select":[null,"Seleziona"],"%1%":[null,"%1%"],":":[null,": "],"More":[null,"più"],", ":[null,", "],",…":[null,",… "],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"selezionare l azione"],"No action defined.":[null,"nessuna azione definita"],"Your selection:":[null,"la tua selezione"],"Y":[null,"Y"],"M":[null,"M"],"w":[null,"w"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"per:"],"y":[null,"y"],"Yes":[null,"Sì"],"t":[null,"t"],"Message: ":[null,"messaggio"],"Warning: ":[null,"Attenzione: "],"Always ignore this warning.":[null,"ignorare sempre questo avviso"],"Do you want to proceed?":[null,"Continuare?"],"No":[null,"no"],"Confirmation: ":[null,"conferma"],"Concurrency Exception":[null,"eccezione di concorrenza"],"Write Concurrency Warning: ":[null,"scrivi avviso di concorrenza"],"This record has been modified while you were editing it.":[null,"il record è stato modificato durante la scrittura"],"Choose:":[null,"scegliere:"],"\"Cancel\" to cancel saving;":[null,"\"cancel\" per annullare il salvataggio"],"\"Compare\" to see the modified version;":[null,"\"compare\" per vedere la versione modificata"],"\"Write Anyway\" to save your current version.":[null,"\"write anyway\" per salvare la versione corrente"],"Compare":[null,"Confrontare"],"Write Anyway":[null,"forza modifica"],"Application Error":[null,"errore dell'applicazione"],"Report Bug":[null,"Segnala un errore"],"Create...":[null,"Crea..."],"Attachments (%1)":[null,"allegati (%1)"],"Notes (%1)":[null,"note (%1)"],"Search %1":[null,"Cerca %1"],"Revision":[null,"Revisione"],"All Fields":[null,"Ogni Campo"],"Clear":[null,"Cancella"],"Fields Selected":[null,"campi selezionati"],"CSV Parameters":[null,"parametri CSV"],"Delimiter:":[null,"Delimitatore:"],"Quote Char:":[null,"Carattere tra virgolette:"],"Encoding:":[null,"Codifica:"],"Import from CSV":[null,"importare da CSV"],"Auto-Detect":[null,"Autorilevamento"],"File to Import":[null,"file da importare"],"Lines to Skip:":[null,"righe da saltare"],"You must select an import file first":[null,"va prima selezionato un file da importare"],"Error occured in loading the file":[null,"si è verificato un errore nel caricamento del file"],"Error processing the file at field %1.":[null,"errore nell'elaborazione del file nel campo %1"],"Error":[null,"Errore"],"Export to CSV":[null,"esportazione in CSV"],"Predefined Exports":[null,"esportazioni predefinite"],"Save Export":[null,"salvare esportazione"],"Delete Export":[null,"eliminare esportazione"],"Add Field Names":[null,"inserire nomi campo"],"%1 (string)":[null,"%1 (stringa)"],"What is the name of this export?":[null,"qual è il nome di questa esportazione?"],"Override %1 definition?":[null,"sovrascrivere definizione %1?"],"Wizard":[null,"wizard"]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"gestione preferiti"],"Logout":[null,"Esci"],"Favorites":[null,"Preferiti"],"Search...":[null,"Cerca..."],"Unable to reach the server":[null,"server non raggiungibile"],"Login":[null,"Login"],"User name":[null,""],"Database":[null,"Database"],"Unable to reach the server.":[null,"server non raggiungibile"],"Close":[null,"Chiudi"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"la seguente azione richiede la chiusura di tutte le finestre. Intendi continuare?"],"Create a new record":[null,"Crea un nuovo record"],"Save this record":[null,"salvare il record"],"Switch view":[null,"cambia visualizzazione"],"Reload":[null,"Ricarica"],"Previous Record":[null,"Record precedente"],"Next Record":[null,"Record successivo"],"Add an attachment to the record":[null,"aggiungere un allegato al record"],"Add a note to the record":[null,"aggiungere nota al record"],"New":[null,"Nuovo"],"Save":[null,"Salva"],"Switch":[null,"Scambia"],"Reload/Undo":[null,"ricarica / ripristina"],"Duplicate":[null,"Duplica"],"Delete":[null,"Elimina"],"Previous":[null,"Precedente"],"Next":[null,"Successivo"],"Search":[null,"Cerca"],"View Logs...":[null,"vedi logs"],"Show revisions...":[null,"mostra revisioni"],"Close Tab":[null,"Chiudi la scheda"],"Attachment":[null,"Allegato"],"Note":[null,"nota"],"Action":[null,"Azione"],"Relate":[null,"collega"],"Print":[null,"Stampa"],"Export":[null,"Esporta"],"Import":[null,"Importa"],"Launch action":[null,"lancia applicazione"],"Open related records":[null,"apri record collegati"],"Print report":[null,"Stampa rapporto"],"This record has been modified\ndo you want to save it?":[null,"questo record è stato modificato, intendi salvarlo?"],"Record saved.":[null,"record salvato"],"Working now on the duplicated record(s).":[null,"stai ora lavorando nel record duplicato"],"Are you sure to remove this record?":[null,"sei sicuro di rimuovere questo record?"],"Are you sure to remove those records?":[null,"sei sicuro di rimuovere questi record?"],"Records removed.":[null,"record rimossi"],"Records not removed.":[null,"record non rimossi"],"You have to select one record.":[null,"va selezionato un record"],"ID:":[null,"ID:"],"Creation User:":[null,"creato da:"],"Creation Date:":[null,"creato il:"],"Latest Modification by:":[null,"ultima modifica da:"],"Latest Modification Date:":[null,"ultima modifica il:"],"Model: ":[null,"Modello: "],"Filters":[null,"Filtri"],"Bookmarks":[null,"Segnalibri"],"Remove this bookmark":[null,"rimuovere questo segnalibro"],"Bookmark this filter":[null,"contrassegnare questo filtro "],"Bookmark Name:":[null,"nome del segnalibro"],"True":[null,"Vero"],"False":[null,"Falso"],"Find":[null,"Trova"],"ID":[null,"ID"],"Creation User":[null,"creato da"],"Creation Date":[null,"creato il "],"Modification Date":[null,"Data di modifica "],"\"%1\" is required":[null,"\"%1\" è obbligatorio"],"\"%1\" is not valid according to its domain":[null,"\"%1\" non è valido rispetto al dominio"],"The values of \"%1\" are not valid":[null,"i valori di \"%1\" non sono validi"],"Pre-validation":[null,"pre-validazione"],"Translate":[null,"Traduci"],"Cancel":[null,"Annulla"],"OK":[null,"OK"],"Edit":[null,"Modifica"],"Fuzzy":[null,"fuzzy"],"You need to save the record before adding translations.":[null,"devi salvare il record prima di inserire la traduzione"],"No other language available.":[null,"non sono disponibili altre lingue"],"Show":[null,""],"Hide":[null,""],"Font":[null,"Carattere"],"Size":[null,"Dimensione"],"Add":[null,"Aggiungi"],"Remove":[null,"Rimuovi"],"Open":[null,"Apri"],"Undelete":[null,"Annullare l'eliminazione"],"Select":[null,"Seleziona"],"%1%":[null,"%1%"],":":[null,": "],"More":[null,"più"],", ":[null,", "],",…":[null,",… "],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"selezionare l azione"],"No action defined.":[null,"nessuna azione definita"],"Your selection:":[null,"la tua selezione"],"Y":[null,"Y"],"M":[null,"M"],"w":[null,"w"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"per:"],"y":[null,"y"],"Yes":[null,"Sì"],"t":[null,"t"],"Message: ":[null,"messaggio"],"Warning: ":[null,"Attenzione: "],"Always ignore this warning.":[null,"ignorare sempre questo avviso"],"Do you want to proceed?":[null,"Continuare?"],"No":[null,"no"],"Confirmation: ":[null,"conferma"],"Concurrency Exception":[null,"eccezione di concorrenza"],"Write Concurrency Warning: ":[null,"scrivi avviso di concorrenza"],"This record has been modified while you were editing it.":[null,"il record è stato modificato durante la scrittura"],"Choose:":[null,"scegliere:"],"\"Cancel\" to cancel saving;":[null,"\"cancel\" per annullare il salvataggio"],"\"Compare\" to see the modified version;":[null,"\"compare\" per vedere la versione modificata"],"\"Write Anyway\" to save your current version.":[null,"\"write anyway\" per salvare la versione corrente"],"Compare":[null,"Confrontare"],"Write Anyway":[null,"forza modifica"],"Application Error":[null,"errore dell'applicazione"],"Report Bug":[null,"Segnala un errore"],"Processing...":[null,""],"Create...":[null,"Crea..."],"Download":[null,""],"Attachments (%1)":[null,"allegati (%1)"],"Notes (%1)":[null,"note (%1)"],"Search %1":[null,"Cerca %1"],"Revision":[null,"Revisione"],"All Fields":[null,"Ogni Campo"],"Clear":[null,"Cancella"],"Fields Selected":[null,"campi selezionati"],"CSV Parameters":[null,"parametri CSV"],"Delimiter:":[null,"Delimitatore:"],"Quote Char:":[null,"Carattere tra virgolette:"],"Encoding:":[null,"Codifica:"],"Import from CSV":[null,"importare da CSV"],"Auto-Detect":[null,"Autorilevamento"],"File to Import":[null,"file da importare"],"Lines to Skip:":[null,"righe da saltare"],"You must select an import file first":[null,"va prima selezionato un file da importare"],"Error occured in loading the file":[null,"si è verificato un errore nel caricamento del file"],"Error processing the file at field %1.":[null,"errore nell'elaborazione del file nel campo %1"],"Error":[null,"Errore"],"Export to CSV":[null,"esportazione in CSV"],"Predefined Exports":[null,"esportazioni predefinite"],"Save Export":[null,"salvare esportazione"],"Delete Export":[null,"eliminare esportazione"],"Add Field Names":[null,"inserire nomi campo"],"%1 (string)":[null,"%1 (stringa)"],"What is the name of this export?":[null,"qual è il nome di questa esportazione?"],"Override %1 definition?":[null,"sovrascrivere definizione %1?"],"Wizard":[null,"wizard"]}
\ No newline at end of file
diff --git a/locale/it_IT.po b/locale/it_IT.po
index 56a27ef..6772425 100644
--- a/locale/it_IT.po
+++ b/locale/it_IT.po
@@ -2,6 +2,9 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 15 2017 01:03:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Apr 04 2017 10:44:30 GMT+0200 (CEST)
 # Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
 msgid "Manage favorites"
 msgstr "gestione preferiti"
@@ -21,17 +24,17 @@ msgstr "server non raggiungibile"
 msgid "Login"
 msgstr "Login"
 
+msgid "User name"
+msgstr ""
+
 msgid "Database"
 msgstr "Database"
 
 msgid "Unable to reach the server."
 msgstr "server non raggiungibile"
 
-msgid "Toggle navigation"
-msgstr "navigazione a tratti"
-
-msgid "Menu"
-msgstr "Menu"
+msgid "Close"
+msgstr "Chiudi"
 
 msgid ""
 "The following action requires to close all tabs.\n"
@@ -40,54 +43,39 @@ msgstr ""
 "la seguente azione richiede la chiusura di tutte le finestre. Intendi "
 "continuare?"
 
-msgid "Close"
-msgstr "Chiudi"
-
-msgid "New"
-msgstr "Nuovo"
-
 msgid "Create a new record"
 msgstr "Crea un nuovo record"
 
-msgid "Save"
-msgstr "Salva"
-
 msgid "Save this record"
 msgstr "salvare il record"
 
-msgid "Switch"
-msgstr "Scambia"
-
 msgid "Switch view"
 msgstr "cambia visualizzazione"
 
 msgid "Reload"
 msgstr "Ricarica"
 
-msgid "Previous"
-msgstr "Precedente"
-
 msgid "Previous Record"
 msgstr "Record precedente"
 
-msgid "Next"
-msgstr "Successivo"
-
 msgid "Next Record"
 msgstr "Record successivo"
 
-msgid "Attachment"
-msgstr "Allegato"
-
 msgid "Add an attachment to the record"
 msgstr "aggiungere un allegato al record"
 
-msgid "Note"
-msgstr "nota"
-
 msgid "Add a note to the record"
 msgstr "aggiungere nota al record"
 
+msgid "New"
+msgstr "Nuovo"
+
+msgid "Save"
+msgstr "Salva"
+
+msgid "Switch"
+msgstr "Scambia"
+
 msgid "Reload/Undo"
 msgstr "ricarica / ripristina"
 
@@ -97,6 +85,12 @@ msgstr "Duplica"
 msgid "Delete"
 msgstr "Elimina"
 
+msgid "Previous"
+msgstr "Precedente"
+
+msgid "Next"
+msgstr "Successivo"
+
 msgid "Search"
 msgstr "Cerca"
 
@@ -109,6 +103,12 @@ msgstr "mostra revisioni"
 msgid "Close Tab"
 msgstr "Chiudi la scheda"
 
+msgid "Attachment"
+msgstr "Allegato"
+
+msgid "Note"
+msgstr "nota"
+
 msgid "Action"
 msgstr "Azione"
 
@@ -177,12 +177,6 @@ msgstr "ultima modifica il:"
 msgid "Model: "
 msgstr "Modello: "
 
-msgid "Attachment(%1)"
-msgstr "allegato (%1)"
-
-msgid "Note(%1)"
-msgstr "nota (%1)"
-
 msgid "Filters"
 msgstr "Filtri"
 
@@ -256,6 +250,12 @@ msgstr "devi salvare il record prima di inserire la traduzione"
 msgid "No other language available."
 msgstr "non sono disponibili altre lingue"
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr "Carattere"
 
@@ -286,6 +286,10 @@ msgstr ": "
 msgid "More"
 msgstr "più"
 
+#, fuzzy
+msgid ": "
+msgstr ": "
+
 msgid ", "
 msgstr ", "
 
@@ -388,9 +392,19 @@ msgstr "errore dell'applicazione"
 msgid "Report Bug"
 msgstr "Segnala un errore"
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr "Crea..."
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr "allegati (%1)"
 
diff --git a/locale/ja_JP.json b/locale/ja_JP.json
index c4bdbb4..207155f 100644
--- a/locale/ja_JP.json
+++ b/locale/ja_JP.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"User name":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Close":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Create a new record":[null,""],"Save this record":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous Record":[null,""],"Next Record":[null,""],"Add an attachment to the record":[null,""],"Add a note to the record":[null,""],"New":[null,""],"Save":[null,""],"Switch":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Previous":[null,""],"Next":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Attachment":[null,""],"Note":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Processing...":[null,""],"Create...":[null,""],"Download":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/ja_JP.po b/locale/ja_JP.po
index 3766150..6c93eb0 100644
--- a/locale/ja_JP.po
+++ b/locale/ja_JP.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -21,16 +21,16 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
+msgid "User name"
 msgstr ""
 
-msgid "Unable to reach the server."
+msgid "Database"
 msgstr ""
 
-msgid "Toggle navigation"
+msgid "Unable to reach the server."
 msgstr ""
 
-msgid "Menu"
+msgid "Close"
 msgstr ""
 
 msgid ""
@@ -38,52 +38,37 @@ msgid ""
 "Do you want to continue?"
 msgstr ""
 
-msgid "Close"
-msgstr ""
-
-msgid "New"
-msgstr ""
-
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -95,6 +80,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -107,6 +98,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -175,12 +172,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -253,6 +244,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -284,6 +281,10 @@ msgid "More"
 msgstr ""
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -387,9 +388,19 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/lo.json b/locale/lo.json
index 62dbba2..2ef19e6 100644
--- a/locale/lo.json
+++ b/locale/lo.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,"ອອກລະບົບ"],"Favorites":[null,""],"Search...":[null,"ຊອກຫາ..."],"Unable to reach the server":[null,"ບໍ່ສາມາດເຂົ້າເຖິງແມ່ຂ່າຍໄດ້"],"Login":[null,"ເຂົ້າລະບົບ"],"Database":[null,"ຖານຂໍ້ມູນ"],"Unable to reach the server.":[null,"ບໍ່ສາມາດເຂົ້າເຖິງແມ່ຂ່າຍໄດ້"],"Toggle navigation":[null,"ສະຫຼັບນໍາທາງ"],"Menu":[null,"ລາຍການຄຳສັ່ງ"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"ການດຳເນີນການຕໍ່ໄປນີ້ ຮຽກຮ້ອງໃຫ້ຕ້ອງອັດແຖບງານທັງໝົດລົງ\nເຈົ້າການດຳເນີນຕໍ່ບໍ່?"],"Close":[null,"ອັດ"],"New":[null,"ໃໝ່"],"Create a new record":[null,"ສ້າງແຖວຂໍ້ມູນໃໝ່"],"Save":[null,"ບັນທຶກ"],"Save this record":[null,"ບັນທຶກແຖວຂໍ້ມູນນີ້"],"Switch":[null,"ສະຫຼັບ"],"Switch view":[null,"ສະຫຼັບໜ້າເບິ່ງ"],"Reload":[null,"ໂຫຼດຄືນໃໝ່"],"Previous":[null,"ກ່ອນໜ້າ"],"Previous Record":[null,"ແຖວຂໍ້ມູນກ່ອນ"],"Next":[null,"ຕໍ່ໄປ"],"Next Record":[null,"ແຖວຂໍ້ມູນຕໍ່ໄປ"],"Attachment":[null,"ຄັດຕິດ"],"Add an attachment to the record":[null,"ເອົາຂໍ້ມູນຄັດຕິດເຂົ້າໃນແຖວຂໍ້ມູນນີ້"],"Note":[null,"ບັນທຶກຂໍ້ຄວາມ"],"Add a note to the record":[null,"ບັນທຶກຂໍ້ຄວາມໃສ່ແຖວຂໍ້ມູນນີ້"],"Reload/Undo":[null,"ໂຫຼດຄືນໃໝ່/ຍົກເລີກ"],"Duplicate":[null,"ຊໍ້າກັນ"],"Delete":[null,"ລຶບ"],"Search":[null,"ຊອກຫາ"],"View Logs...":[null,"ເບິ່ງບັນທຶກ..."],"Show revisions...":[null,"ສະແດງການແກ້ໄຂ"],"Close Tab":[null,"ອັດແຖບງານ"],"Action":[null,"ດຳເນີນການ"],"Relate":[null,"ກ່ຽວພັນກັບ"],"Print":[null,"ພິມອອກ"],"Export":[null,""],"Import":[null,""],"Launch action":[null,"ປະຕິບັດການ"],"Open related records":[null,"ໄຂແຖວຂໍ້ມູນທີ່ກ່ຽວພັນຂຶ້ນມາ"],"Print report":[null,"ພິມລາຍງານອອກ"],"This record has been modified\ndo you want to save it?":[null,"ແຖວຂໍ້ມູນນີ້ຖືກປ່ຽນແປງແລ້ວ\nທ່ານຕ້ອງການບັນທຶກໄວ້ບໍ່?"],"Record saved.":[null,"ແຖວຂໍ້ມູນຖືກບັນທຶກໄວ້ແລ້ວ"],"Working now on the duplicated record(s).":[null,"ປັດຈຸບັນເຮັດວຽກກັບແຖວຂໍ້ມູນທີ່ສ້າງຊໍ້າກັນໄວ້"],"Are you sure to remove this record?":[null,"ທ່ານແນ່ໃຈບໍ່ທີ່ຈະລຶບແຖວຂໍ້ມູນນີ້?"],"Are you sure to remove those records?":[null,"ທ່ານແນ່ໃຈບໍ່ທີ່ຈະລຶບແຖວຂໍ້ມູນເຫຼົ່ານີ້?"],"Records removed.":[null,"ແຖວຂໍ້ມູນເຫຼົ່ານີ້ຖືກລຶບອອກແລ້ວ"],"Records not removed.":[null,"ແຖວຂໍ້ມູນເຫຼົ່ານີ້ບໍ່ໄດ້ຖືກລຶບອອກ"],"You have to select one record.":[null,"ທ່ານຕ້ອງເລືອກເອົາໜຶ່ງແຖວຂໍ້ມູນ"],"ID:":[null,"ເລກກຳກັບ:"],"Creation User:":[null,"ການສ້າງຜູ້ໃຊ້ງານ:"],"Creation Date:":[null,"ການສ້າງວັນທີ:"],"Latest Modification by:":[null,"ການແກ້ໄຂລ້າສຸດ ໂດຍ:"],"Latest Modification Date:":[null,"ວັນທີການແກ້ໄຂລ້າສຸດ:"],"Model: ":[null,"ແມ່ແບບ:"],"Attachment(%1)":[null,"ຄັດຕິດ(%1)"],"Note(%1)":[null,"ບັນທຶກຂໍ້ຄວາມ(%1)"],"Filters":[null,"ກັ່ນຕອງ"],"Bookmarks":[null,"ໝາຍໜ້າ"],"Remove this bookmark":[null,"ເອົາໝາຍໜ້າອອກ"],"Bookmark this filter":[null,"ໝາຍໜ້າເອົາການກັ່ນຕອງນີ້"],"Bookmark Name:":[null,"ຊື່ໝາຍໜ້າ:"],"True":[null,"ຈິງ"],"False":[null,"ເທັດ"],"Find":[null,"ຄົ້ນຫາ"],"ID":[null,"ເລກລຳດັບ"],"Creation User":[null,"ຜູ້ສ້າງ"],"Creation Date":[null,"ວັນທີສ້າງ"],"Modification User":[null,"ຜູ້ແກ້ໄຂ"],"Modification Date":[null,"ວັນທີແກ້ໄຂ"],"\"%1\" is required":[null,"ຕ້ອງໃຫ້ມີ \"%1\""],"\"%1\" is not valid according to its domain":[null,"\"%1\" ບໍ່ມີຄ່າທີ່ຖຶກຕ້ອງກັບ ໂດເມນຂອງມັນ"],"The values of \"%1\" are not valid":[null,"ຄ່າ ຂອງ \"%1\" ນີ້ ບໍ່ຖືກຕ້ອງ"],"Pre-validation":[null,"ກ່ອນ-ການກວດສອບ"],"Translate":[null,""],"Cancel":[null,"ຍົກເລີກ"],"OK":[null,"ຕົກລົງ"],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,"ໂຕໜັງສື"],"Size":[null,"ຂະໜາດ"],"Add":[null,"ເອົາເຂົ້າ"],"Remove":[null,"ເອົາອອກ"],"Open":[null,"ໄຂ"],"Undelete":[null,"ເອົາກັບຄືນ"],"Select":[null,"ເລືອກ"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"ເພີ່ມຕື່ມ"],"%1 (%2)":[null,""],"Select your action":[null,"ເລືອກການດຳເນີນການ"],"Your selection:":[null,"ການເລືອກຂອງທ່ານ:"],"Y":[null,"ປ"],"M":[null,"ດ"],"w":[null,"ອ"],"d":[null,"ວ"],"h":[null,"ມ"],"m":[null,"ນ"],"s":[null,"ວ"],"By: ":[null,""],"y":[null,"ມ"],"Yes":[null,"ແມ່ນ"],"t":[null,"ຈ"],"Message: ":[null,"ຂໍ້ຄວາມ:"],"Warning: ":[null,"ຄຳເຕືອນ:"],"Always ignore this warning.":[null,"ບໍ່ສົນກັບຄຳເຕືອນນີ້."],"Do you want to proceed?":[null,"ທ່ານຕ້ອງການດຳເນີນບໍ່?"],"No":[null,"ບໍ່"],"Confirmation: ":[null,"ຄຳຢັ້ງຢືນ:"],"Concurrency Exception":[null,"ຍົກເວັ້ນສະກຸນເງິນ"],"Write Concurrency Warning: ":[null,"ຂຽນຄຳເຕືອນສະກຸນເງິນ:"],"This record has been modified while you were editing it.":[null,"ແຖວຂໍ້ມູນນີ້ຖືກດັດແປງແລ້ວໃນຂະນະທີ່ທ່ານແກ້ໄຂມັນ."],"Choose:":[null,"ເລືອກເອົາ:"],"\"Cancel\" to cancel saving;":[null,"\"ຍົກເລີກ\" ເພື່ອຍົກເລີກການບັນທຶກ;"],"\"Compare\" to see the modified version;":[null,"\"ສົມທຽບ\" ເພື່ອເບິ່ງທຽບກັບສະບັບດັດແປງແລ້ວ;"],"\"Write Anyway\" to save your current version.":[null,"\"ຂຽນລົງເລີຍ\" ເພື່ອບັນທຶກສະບັບປັດຈຸບັນນີ້."],"Compare":[null,"ສົມທຽບ"],"Write Anyway":[null,"ຂຽນລົງເລີຍ"],"Application Error":[null,"ໂປຣແກຣມຜິດພາດ"],"Report Bug":[null,"ລາຍງານຂໍ້ຜິດພາດ"],"Create...":[null,"ສ້າງ..."],"Search %1":[null,""],"Revision":[null,"ກວດກາຄືນ"],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,"ນໍາພາສ້າງ"]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"ຈັດການກ່ຽວກັບສິ່ງທີ່ມັກ"],"Logout":[null,"ອອກລະບົບ"],"Favorites":[null,"ທີ່ມັກ"],"Search...":[null,"ຄົ້ນຫາ..."],"Unable to reach the server":[null,"ບໍ່ສາມາດເຂົ້າເຖິງແມ່ຂ່າຍໄດ້"],"Login":[null,"ເຂົ້າສູ່ລະບົບ"],"User name":[null,"ຊື່ຜູ້ໃຊ້"],"Database":[null,"ຖານຂໍ້ມູນ"],"Unable to reach the server.":[null,"ບໍ່ສາມາດເຂົ້າເຖິງແມ່ຂ່າຍໄດ້"],"Close":[null,"ອັດ"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"ການດຳເນີນການຕໍ່ໄປນີ້ ຮຽກຮ້ອງໃຫ້ຕ້ອງອັດແຖບງານທັງໝົດລົງ\nເຈົ້າຕ້ອງການດຳເນີນຕໍ່ບໍ່?"],"Create a new record":[null,"ສ້າງແຖວຂໍ້ມູນໃໝ່"],"Save this record":[null,"ບັນທຶກແຖວຂໍ້ມູນນີ້"],"Switch view":[null,"ສະຫຼັບໜ້າເບິ່ງ"],"Reload":[null,"ໂຫຼດຄືນໃໝ່"],"Previous Record":[null,"ແຖວຂໍ້ມູນກ່ອນ"],"Next Record":[null,"ແຖວຂໍ້ມູນຕໍ່ໄປ"],"Add an attachment to the record":[null,"ເອົາຂໍ້ມູນຄັດຕິດເຂົ້າໃນແຖວຂໍ້ມູນນີ້"],"Add a note to the record":[null,"ບັນທຶກຂໍ້ຄວາມໃສ່ແຖວຂໍ້ມູນນີ້"],"New":[null,"ໃໝ່"],"Save":[null,"ບັນທຶກ"],"Switch":[null,"ສະຫຼັບ"],"Reload/Undo":[null,"ໂຫຼດຄືນໃໝ່/ຍົກເລີກ"],"Duplicate":[null,"ຊໍ້າກັນ"],"Delete":[null,"ລຶບ"],"Previous":[null,"ກ່ອນໜ້າ"],"Next":[null,"ຕໍ່ໄປ"],"Search":[null,"ຊອກຫາ"],"View Logs...":[null,"ເບິ່ງບັນທຶກ..."],"Show revisions...":[null,"ສະແດງການແກ້ໄຂ"],"Close Tab":[null,"ອັດແຖບງານ"],"Attachment":[null,"ຄັດຕິດ"],"Note":[null,"ບັນທຶກຂໍ້ຄວາມ"],"Action":[null,"ດຳເນີນການ"],"Relate":[null,"ກ່ຽວພັນກັບ"],"Print":[null,"ພິມອອກ"],"Export":[null,"ສ່ົງອອກ"],"Import":[null,"ນຳເຂົ້າ"],"Launch action":[null,"ປະຕິບັດການ"],"Open related records":[null,"ໄຂແຖວຂໍ້ມູນທີ່ກ່ຽວພັນຂຶ້ນມາ"],"Print report":[null,"ພິມລາຍງານອອກ"],"This record has been modified\ndo you want to save it?":[null,"ແຖວຂໍ້ມູນນີ້ຖືກປ່ຽນແປງແລ້ວ\nທ່ານຕ້ອງການບັນທຶກໄວ້ບໍ່?"],"Record saved.":[null,"ແຖວຂໍ້ມູນຖືກບັນທຶກໄວ້ແລ້ວ"],"Working now on the duplicated record(s).":[null,"ປັດຈຸບັນເຮັດວຽກກັບແຖວຂໍ້ມູນທີ່ສ້າງຊໍ້າກັນໄວ້"],"Are you sure to remove this record?":[null,"ທ່ານແນ່ໃຈບໍ່ທີ່ຈະລຶບແຖວຂໍ້ມູນນີ້?"],"Are you sure to remove those records?":[null,"ທ່ານແນ່ໃຈບໍ່ທີ່ຈະລຶບແຖວຂໍ້ມູນເຫຼົ່ານີ້?"],"Records removed.":[null,"ແຖວຂໍ້ມູນເຫຼົ່ານີ້ຖືກລຶບອອກແລ້ວ"],"Records not removed.":[null,"ແຖວຂໍ້ມູນເຫຼົ່ານີ້ບໍ່ໄດ້ຖືກລຶບອອກ"],"You have to select one record.":[null,"ທ່ານຕ້ອງເລືອກເອົາໜຶ່ງແຖວຂໍ້ມູນ"],"ID:":[null,"ເລກກຳກັບ:"],"Creation User:":[null,"ການສ້າງຜູ້ໃຊ້ງານ:"],"Creation Date:":[null,"ການສ້າງວັນທີ:"],"Latest Modification by:":[null,"ການແກ້ໄຂລ້າສຸດ ໂດຍ:"],"Latest Modification Date:":[null,"ວັນທີການແກ້ໄຂລ້າສຸດ:"],"Model: ":[null,"ແມ່ແບບ:"],"Filters":[null,"ກັ່ນຕອງ"],"Bookmarks":[null,"ໝາຍໜ້າ"],"Remove this bookmark":[null,"ເອົາໝາຍໜ້າອອກ"],"Bookmark this filter":[null,"ໝາຍໜ້າເອົາການກັ່ນຕອງນີ້"],"Bookmark Name:":[null,"ຊື່ໝາຍໜ້າ:"],"True":[null,"ຈິງ"],"False":[null,"ເທັດ"],"Find":[null,"ຄົ້ນຫາ"],"ID":[null,"ເລກລຳດັບ"],"Creation User":[null,"ຜູ້ສ້າງ"],"Creation Date":[null,"ວັນທີສ້າງ"],"Modification User":[null,"ຜູ້ແກ້ໄຂ"],"Modification Date":[null,"ວັນທີແກ້ໄຂ"],"\"%1\" is required":[null,"ຕ້ອງໃຫ້ມີ \"%1\""],"\"%1\" is not valid according to its domain":[null,"\"%1\" ບໍ່ມີຄ່າທີ່ຖຶກຕ້ອງກັບ ໂດເມນຂອງມັນ"],"The values of \"%1\" are not valid":[null,"ຄ່າ ຂອງ \"%1\" ນີ້ ບໍ່ຖືກຕ້ອງ"],"Pre-validation":[null,"ກ່ອນ-ການກວດສອບ"],"Translate":[null,"ແປ"],"Cancel":[null,"ຍົກເລີກ"],"OK":[null,"ຕົກລົງ"],"Edit":[null,"ແກ້ໄຂ"],"Fuzzy":[null,"ບໍ່ຈະແຈ້ງ"],"You need to save the record before adding translations.":[null,"ທ່ານຕ້ອງໄດ້ບັນທຶກແຖວຂໍ້ມູນໄວ້ກ່ອນຈຶ່ງຈະເພີ່ມການແປເຂົ້າໄປໄດ້"],"No other language available.":[null,"ບໍ່ມີພາສາອື່ນໃຫ້ໃຊ້ໄດ້."],"Show":[null,"ສະແດງ"],"Hide":[null,"ເຊື່ອງ"],"Font":[null,"ໂຕໜັງສື"],"Size":[null,"ຂະໜາດ"],"Add":[null,"ເອົາເຂົ້າ"],"Remove":[null,"ເອົາອອກ"],"Open":[null,"ໄຂ"],"Undelete":[null,"ເອົາກັບຄືນ"],"Select":[null,"ເລືອກ"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"ເພີ່ມຕື່ມ"],": ":[null,": "],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"ເລືອກການດຳເນີນການ"],"No action defined.":[null,"ບໍ່ມີການດຳເນີນການໃດຖືກກຳນົດໄວ້!"],"Your selection:":[null,"ການເລືອກຂອງທ່ານ:"],"Y":[null,"ປ"],"M":[null,"ດ"],"w":[null,"ອ"],"d":[null,"ວ"],"h":[null,"ມ"],"m":[null,"ນ"],"s":[null,"ວ"],"By: ":[null,"ໂດຍ: "],"y":[null,"ມ"],"Yes":[null,"ແມ່ນ"],"t":[null,"ຈ"],"Message: ":[null,"ຂໍ້ຄວາມ:"],"Warning: ":[null,"ຄຳເຕືອນ:"],"Always ignore this warning.":[null,"ບໍ່ສົນກັບຄຳເຕືອນນີ້."],"Do you want to proceed?":[null,"ທ່ານຕ້ອງການດຳເນີນບໍ່?"],"No":[null,"ບໍ່"],"Confirmation: ":[null,"ຄຳຢັ້ງຢືນ:"],"Concurrency Exception":[null,"ຍົກເວັ້ນສະກຸນເງິນ"],"Write Concurrency Warning: ":[null,"ຂຽນຄຳເຕືອນສະກຸນເງິນ:"],"This record has been modified while you were editing it.":[null,"ແຖວຂໍ້ມູນນີ້ຖືກດັດແປງແລ້ວໃນຂະນະທີ່ທ່ານແກ້ໄຂມັນ."],"Choose:":[null,"ເລືອກເອົາ:"],"\"Cancel\" to cancel saving;":[null,"\"ຍົກເລີກ\" ເພື່ອຍົກເລີກການບັນທຶກ;"],"\"Compare\" to see the modified version;":[null,"\"ສົມທຽບ\" ເພື່ອເບິ່ງທຽບກັບສະບັບດັດແປງແລ້ວ;"],"\"Write Anyway\" to save your current version.":[null,"\"ຂຽນລົງເລີຍ\" ເພື່ອບັນທຶກສະບັບປັດຈຸບັນນີ້."],"Compare":[null,"ສົມທຽບ"],"Write Anyway":[null,"ຂຽນລົງເລີຍ"],"Application Error":[null,"ໂປຣແກຣມຜິດພາດ"],"Report Bug":[null,"ລາຍງານຂໍ້ຜິດພາດ"],"Processing...":[null,"ກຳລັງປະມວນຜົນ..."],"Create...":[null,"ສ້າງ..."],"Download":[null,"ດາວໂຫຼດ"],"...":[null,"..."],"Attachments (%1)":[null,"ຄັດຕິດ(%1)"],"Notes (%1)":[null,"ບັນທຶກຂໍ້ຄວາມ(%1)"],"Search %1":[null,"ຊອກຫາ %1"],"Revision":[null,"ກວດກາຄືນ"],"All Fields":[null,"ຊ່ອງຂໍ້ມູນທັງໝົດ"],"Clear":[null,"ລຶບອອກ"],"Fields Selected":[null,"ຊ່ອງຂໍ້ມູນທີ່ເລືອກເອົາ"],"CSV Parameters":[null,"ປາຣາແມັດເຕີຣ໌ CSV"],"Delimiter:":[null,"ຂັ້ນ:"],"Quote Char:":[null,"Quote Char:"],"Encoding:":[null,"ການເຂົ້າລະຫັດ:"],"Import from CSV":[null,"ນຳເຂົ້າຈາກ CSV"],"Auto-Detect":[null,"ກວດພົບອັດຕະໂນມັດ"],"File to Import":[null,"ຟາຍລ໌ທີ່ຈະນຳເຂົ້າ"],"Lines to Skip:":[null,"ແຖວທີ່ຈະຂວ້າມ:"],"You must select an import file first":[null,"ທ່ານຕ້ອງໄດ້ເລືອກຟາຍລ໌ທີ່ຈະນຳເຂົ້ານັ້ນກ່ອນ"],"Error occured in loading the file":[null,"ມີຂໍ້ຜິດພາດເກີດຂຶ້ນໃນການດຶງເອົາຟາຍລ໌"],"Error processing the file at field %1.":[null,"ມີຂໍ້ຜິດພາດໃນການປະມວນຜົນຟາຍລ໌ ໃນຊ່ອງຂໍ້ມູນ %1."],"Error":[null,"ຜິດພາດ"],"Export to CSV":[null,"ສົ່ງອອກເປັນຟາຍລ໌ CSV"],"Predefined Exports":[null,"ການສົ່ງອອກທີ່ຈັດຕຽມໄວ້ກ່ອນ"],"Save Export":[null,"ບັນທຶກຟາຍລ໌ທີ່ສົ່ງອອກ"],"Delete Export":[null,"ລຶບຟາຍລ໌ທີ່ສົ່ງອອກ"],"Add Field Names":[null,"ເພີ່ມຊື່ຊ່ອງຂໍ້ມູນ"],"%1 (string)":[null,"%1 (string)"],"What is the name of this export?":[null,"ຊື່ຂອງການສົ່ງອອກນີ້ແມ່ນຫຍັງ?"],"Override %1 definition?":[null,"ຂຽນທັບຄຳອະທິບາຍ %1 ນີ້ບໍ?"],"Wizard":[null,"ນໍາພາສ້າງ"]}
\ No newline at end of file
diff --git a/locale/lo.po b/locale/lo.po
index 58681a0..e30a6e5 100644
--- a/locale/lo.po
+++ b/locale/lo.po
@@ -2,25 +2,30 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 15 2017 01:03:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Apr 04 2017 10:44:30 GMT+0200 (CEST)
 msgid "Manage favorites"
-msgstr ""
+msgstr "ຈັດການກ່ຽວກັບສິ່ງທີ່ມັກ"
 
 # Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
 msgid "Logout"
 msgstr "ອອກລະບົບ"
 
 msgid "Favorites"
-msgstr ""
+msgstr "ທີ່ມັກ"
 
 msgid "Search..."
-msgstr "ຊອກຫາ..."
+msgstr "ຄົ້ນຫາ..."
 
 msgid "Unable to reach the server"
 msgstr "ບໍ່ສາມາດເຂົ້າເຖິງແມ່ຂ່າຍໄດ້"
 
 msgid "Login"
-msgstr "ເຂົ້າລະບົບ"
+msgstr "ເຂົ້າສູ່ລະບົບ"
+
+msgid "User name"
+msgstr "ຊື່ຜູ້ໃຊ້"
 
 msgid "Database"
 msgstr "ຖານຂໍ້ມູນ"
@@ -28,67 +33,49 @@ msgstr "ຖານຂໍ້ມູນ"
 msgid "Unable to reach the server."
 msgstr "ບໍ່ສາມາດເຂົ້າເຖິງແມ່ຂ່າຍໄດ້"
 
-msgid "Toggle navigation"
-msgstr "ສະຫຼັບນໍາທາງ"
-
-msgid "Menu"
-msgstr "ລາຍການຄຳສັ່ງ"
+msgid "Close"
+msgstr "ອັດ"
 
 msgid ""
 "The following action requires to close all tabs.\n"
 "Do you want to continue?"
 msgstr ""
 "ການດຳເນີນການຕໍ່ໄປນີ້ ຮຽກຮ້ອງໃຫ້ຕ້ອງອັດແຖບງານທັງໝົດລົງ\n"
-"ເຈົ້າການດຳເນີນຕໍ່ບໍ່?"
-
-msgid "Close"
-msgstr "ອັດ"
-
-msgid "New"
-msgstr "ໃໝ່"
+"ເຈົ້າຕ້ອງການດຳເນີນຕໍ່ບໍ່?"
 
 msgid "Create a new record"
 msgstr "ສ້າງແຖວຂໍ້ມູນໃໝ່"
 
-msgid "Save"
-msgstr "ບັນທຶກ"
-
 msgid "Save this record"
 msgstr "ບັນທຶກແຖວຂໍ້ມູນນີ້"
 
-msgid "Switch"
-msgstr "ສະຫຼັບ"
-
 msgid "Switch view"
 msgstr "ສະຫຼັບໜ້າເບິ່ງ"
 
 msgid "Reload"
 msgstr "ໂຫຼດຄືນໃໝ່"
 
-msgid "Previous"
-msgstr "ກ່ອນໜ້າ"
-
 msgid "Previous Record"
 msgstr "ແຖວຂໍ້ມູນກ່ອນ"
 
-msgid "Next"
-msgstr "ຕໍ່ໄປ"
-
 msgid "Next Record"
 msgstr "ແຖວຂໍ້ມູນຕໍ່ໄປ"
 
-msgid "Attachment"
-msgstr "ຄັດຕິດ"
-
 msgid "Add an attachment to the record"
 msgstr "ເອົາຂໍ້ມູນຄັດຕິດເຂົ້າໃນແຖວຂໍ້ມູນນີ້"
 
-msgid "Note"
-msgstr "ບັນທຶກຂໍ້ຄວາມ"
-
 msgid "Add a note to the record"
 msgstr "ບັນທຶກຂໍ້ຄວາມໃສ່ແຖວຂໍ້ມູນນີ້"
 
+msgid "New"
+msgstr "ໃໝ່"
+
+msgid "Save"
+msgstr "ບັນທຶກ"
+
+msgid "Switch"
+msgstr "ສະຫຼັບ"
+
 msgid "Reload/Undo"
 msgstr "ໂຫຼດຄືນໃໝ່/ຍົກເລີກ"
 
@@ -98,6 +85,12 @@ msgstr "ຊໍ້າກັນ"
 msgid "Delete"
 msgstr "ລຶບ"
 
+msgid "Previous"
+msgstr "ກ່ອນໜ້າ"
+
+msgid "Next"
+msgstr "ຕໍ່ໄປ"
+
 msgid "Search"
 msgstr "ຊອກຫາ"
 
@@ -110,6 +103,12 @@ msgstr "ສະແດງການແກ້ໄຂ"
 msgid "Close Tab"
 msgstr "ອັດແຖບງານ"
 
+msgid "Attachment"
+msgstr "ຄັດຕິດ"
+
+msgid "Note"
+msgstr "ບັນທຶກຂໍ້ຄວາມ"
+
 msgid "Action"
 msgstr "ດຳເນີນການ"
 
@@ -120,10 +119,10 @@ msgid "Print"
 msgstr "ພິມອອກ"
 
 msgid "Export"
-msgstr ""
+msgstr "ສ່ົງອອກ"
 
 msgid "Import"
-msgstr ""
+msgstr "ນຳເຂົ້າ"
 
 msgid "Launch action"
 msgstr "ປະຕິບັດການ"
@@ -180,12 +179,6 @@ msgstr "ວັນທີການແກ້ໄຂລ້າສຸດ:"
 msgid "Model: "
 msgstr "ແມ່ແບບ:"
 
-msgid "Attachment(%1)"
-msgstr "ຄັດຕິດ(%1)"
-
-msgid "Note(%1)"
-msgstr "ບັນທຶກຂໍ້ຄວາມ(%1)"
-
 msgid "Filters"
 msgstr "ກັ່ນຕອງ"
 
@@ -238,7 +231,7 @@ msgid "Pre-validation"
 msgstr "ກ່ອນ-ການກວດສອບ"
 
 msgid "Translate"
-msgstr ""
+msgstr "ແປ"
 
 msgid "Cancel"
 msgstr "ຍົກເລີກ"
@@ -247,16 +240,22 @@ msgid "OK"
 msgstr "ຕົກລົງ"
 
 msgid "Edit"
-msgstr ""
+msgstr "ແກ້ໄຂ"
 
 msgid "Fuzzy"
-msgstr ""
+msgstr "ບໍ່ຈະແຈ້ງ"
 
 msgid "You need to save the record before adding translations."
-msgstr ""
+msgstr "ທ່ານຕ້ອງໄດ້ບັນທຶກແຖວຂໍ້ມູນໄວ້ກ່ອນຈຶ່ງຈະເພີ່ມການແປເຂົ້າໄປໄດ້"
 
 msgid "No other language available."
-msgstr ""
+msgstr "ບໍ່ມີພາສາອື່ນໃຫ້ໃຊ້ໄດ້."
+
+msgid "Show"
+msgstr "ສະແດງ"
+
+msgid "Hide"
+msgstr "ເຊື່ອງ"
 
 msgid "Font"
 msgstr "ໂຕໜັງສື"
@@ -288,23 +287,23 @@ msgstr ":"
 msgid "More"
 msgstr "ເພີ່ມຕື່ມ"
 
-#, fuzzy
+msgid ": "
+msgstr ": "
+
 msgid ", "
 msgstr ", "
 
-#, fuzzy
 msgid ",…"
 msgstr ",…"
 
 msgid "%1 (%2)"
-msgstr ""
+msgstr "%1 (%2)"
 
 msgid "Select your action"
 msgstr "ເລືອກການດຳເນີນການ"
 
-#, fuzzy
 msgid "No action defined."
-msgstr "ບໍ່ມີການດຳເນີນການໃດໆຖືກກຳນົດໄວ້!"
+msgstr "ບໍ່ມີການດຳເນີນການໃດຖືກກຳນົດໄວ້!"
 
 msgid "Your selection:"
 msgstr "ການເລືອກຂອງທ່ານ:"
@@ -331,7 +330,7 @@ msgid "s"
 msgstr "ວ"
 
 msgid "By: "
-msgstr ""
+msgstr "ໂດຍ: "
 
 msgid "y"
 msgstr "ມ"
@@ -393,91 +392,98 @@ msgstr "ໂປຣແກຣມຜິດພາດ"
 msgid "Report Bug"
 msgstr "ລາຍງານຂໍ້ຜິດພາດ"
 
+msgid "Processing..."
+msgstr "ກຳລັງປະມວນຜົນ..."
+
 msgid "Create..."
 msgstr "ສ້າງ..."
 
-#, fuzzy
+msgid "Download"
+msgstr "ດາວໂຫຼດ"
+
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr "ຄັດຕິດ(%1)"
 
-#, fuzzy
 msgid "Notes (%1)"
 msgstr "ບັນທຶກຂໍ້ຄວາມ(%1)"
 
 msgid "Search %1"
-msgstr ""
+msgstr "ຊອກຫາ %1"
 
 msgid "Revision"
 msgstr "ກວດກາຄືນ"
 
 msgid "All Fields"
-msgstr ""
+msgstr "ຊ່ອງຂໍ້ມູນທັງໝົດ"
 
 msgid "Clear"
-msgstr ""
+msgstr "ລຶບອອກ"
 
 msgid "Fields Selected"
-msgstr ""
+msgstr "ຊ່ອງຂໍ້ມູນທີ່ເລືອກເອົາ"
 
 msgid "CSV Parameters"
-msgstr ""
+msgstr "ປາຣາແມັດເຕີຣ໌ CSV"
 
 msgid "Delimiter:"
-msgstr ""
+msgstr "ຂັ້ນ:"
 
 msgid "Quote Char:"
-msgstr ""
+msgstr "Quote Char:"
 
 msgid "Encoding:"
-msgstr ""
+msgstr "ການເຂົ້າລະຫັດ:"
 
 msgid "Import from CSV"
-msgstr ""
+msgstr "ນຳເຂົ້າຈາກ CSV"
 
 msgid "Auto-Detect"
-msgstr ""
+msgstr "ກວດພົບອັດຕະໂນມັດ"
 
 msgid "File to Import"
-msgstr ""
+msgstr "ຟາຍລ໌ທີ່ຈະນຳເຂົ້າ"
 
 msgid "Lines to Skip:"
-msgstr ""
+msgstr "ແຖວທີ່ຈະຂວ້າມ:"
 
 msgid "You must select an import file first"
-msgstr ""
+msgstr "ທ່ານຕ້ອງໄດ້ເລືອກຟາຍລ໌ທີ່ຈະນຳເຂົ້ານັ້ນກ່ອນ"
 
 msgid "Error occured in loading the file"
-msgstr ""
+msgstr "ມີຂໍ້ຜິດພາດເກີດຂຶ້ນໃນການດຶງເອົາຟາຍລ໌"
 
 msgid "Error processing the file at field %1."
-msgstr ""
+msgstr "ມີຂໍ້ຜິດພາດໃນການປະມວນຜົນຟາຍລ໌ ໃນຊ່ອງຂໍ້ມູນ %1."
 
 msgid "Error"
-msgstr ""
+msgstr "ຜິດພາດ"
 
 msgid "Export to CSV"
-msgstr ""
+msgstr "ສົ່ງອອກເປັນຟາຍລ໌ CSV"
 
 msgid "Predefined Exports"
-msgstr ""
+msgstr "ການສົ່ງອອກທີ່ຈັດຕຽມໄວ້ກ່ອນ"
 
 msgid "Save Export"
-msgstr ""
+msgstr "ບັນທຶກຟາຍລ໌ທີ່ສົ່ງອອກ"
 
 msgid "Delete Export"
-msgstr ""
+msgstr "ລຶບຟາຍລ໌ທີ່ສົ່ງອອກ"
 
 msgid "Add Field Names"
-msgstr ""
+msgstr "ເພີ່ມຊື່ຊ່ອງຂໍ້ມູນ"
 
 msgid "%1 (string)"
-msgstr ""
+msgstr "%1 (string)"
 
 msgid "What is the name of this export?"
-msgstr ""
+msgstr "ຊື່ຂອງການສົ່ງອອກນີ້ແມ່ນຫຍັງ?"
 
 msgid "Override %1 definition?"
-msgstr ""
+msgstr "ຂຽນທັບຄຳອະທິບາຍ %1 ນີ້ບໍ?"
 
 msgid "Wizard"
 msgstr "ນໍາພາສ້າງ"
diff --git a/locale/lo_LA.json b/locale/lo_LA.json
new file mode 100644
index 0000000..9fb066f
--- /dev/null
+++ b/locale/lo_LA.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/lt.json b/locale/lt.json
index c4bdbb4..207155f 100644
--- a/locale/lt.json
+++ b/locale/lt.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"User name":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Close":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Create a new record":[null,""],"Save this record":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous Record":[null,""],"Next Record":[null,""],"Add an attachment to the record":[null,""],"Add a note to the record":[null,""],"New":[null,""],"Save":[null,""],"Switch":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Previous":[null,""],"Next":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Attachment":[null,""],"Note":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Processing...":[null,""],"Create...":[null,""],"Download":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/lt.po b/locale/lt.po
index 3766150..6c93eb0 100644
--- a/locale/lt.po
+++ b/locale/lt.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -21,16 +21,16 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
+msgid "User name"
 msgstr ""
 
-msgid "Unable to reach the server."
+msgid "Database"
 msgstr ""
 
-msgid "Toggle navigation"
+msgid "Unable to reach the server."
 msgstr ""
 
-msgid "Menu"
+msgid "Close"
 msgstr ""
 
 msgid ""
@@ -38,52 +38,37 @@ msgid ""
 "Do you want to continue?"
 msgstr ""
 
-msgid "Close"
-msgstr ""
-
-msgid "New"
-msgstr ""
-
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -95,6 +80,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -107,6 +98,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -175,12 +172,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -253,6 +244,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -284,6 +281,10 @@ msgid "More"
 msgstr ""
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -387,9 +388,19 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/lt_LT.json b/locale/lt_LT.json
new file mode 100644
index 0000000..9fb066f
--- /dev/null
+++ b/locale/lt_LT.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/messages.pot b/locale/messages.pot
index 9b8d373..0d48d4d 100644
--- a/locale/messages.pot
+++ b/locale/messages.pot
@@ -1,4 +1,4 @@
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 
 msgid "Manage favorites"
 msgstr ""
@@ -18,67 +18,52 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
-msgstr ""
-
-msgid "Unable to reach the server."
+msgid "User name"
 msgstr ""
 
-msgid "Toggle navigation"
-msgstr ""
-
-msgid "Menu"
+msgid "Database"
 msgstr ""
 
-msgid "The following action requires to close all tabs.\nDo you want to continue?"
+msgid "Unable to reach the server."
 msgstr ""
 
 msgid "Close"
 msgstr ""
 
-msgid "New"
+msgid "The following action requires to close all tabs.\nDo you want to continue?"
 msgstr ""
 
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -90,6 +75,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -102,6 +93,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -168,12 +165,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -246,6 +237,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -276,6 +273,9 @@ msgstr ""
 msgid "More"
 msgstr ""
 
+msgid ": "
+msgstr ""
+
 msgid ", "
 msgstr ""
 
@@ -378,9 +378,18 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+msgid "..."
+msgstr ""
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/nl.json b/locale/nl.json
index c4bdbb4..207155f 100644
--- a/locale/nl.json
+++ b/locale/nl.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"User name":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Close":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Create a new record":[null,""],"Save this record":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous Record":[null,""],"Next Record":[null,""],"Add an attachment to the record":[null,""],"Add a note to the record":[null,""],"New":[null,""],"Save":[null,""],"Switch":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Previous":[null,""],"Next":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Attachment":[null,""],"Note":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Processing...":[null,""],"Create...":[null,""],"Download":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/nl.po b/locale/nl.po
index 3766150..6c93eb0 100644
--- a/locale/nl.po
+++ b/locale/nl.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -21,16 +21,16 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
+msgid "User name"
 msgstr ""
 
-msgid "Unable to reach the server."
+msgid "Database"
 msgstr ""
 
-msgid "Toggle navigation"
+msgid "Unable to reach the server."
 msgstr ""
 
-msgid "Menu"
+msgid "Close"
 msgstr ""
 
 msgid ""
@@ -38,52 +38,37 @@ msgid ""
 "Do you want to continue?"
 msgstr ""
 
-msgid "Close"
-msgstr ""
-
-msgid "New"
-msgstr ""
-
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -95,6 +80,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -107,6 +98,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -175,12 +172,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -253,6 +244,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -284,6 +281,10 @@ msgid "More"
 msgstr ""
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -387,9 +388,19 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/nl_NL.json b/locale/nl_NL.json
new file mode 100644
index 0000000..9fb066f
--- /dev/null
+++ b/locale/nl_NL.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/pl.json b/locale/pl.json
index c4bdbb4..207155f 100644
--- a/locale/pl.json
+++ b/locale/pl.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"User name":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Close":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Create a new record":[null,""],"Save this record":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous Record":[null,""],"Next Record":[null,""],"Add an attachment to the record":[null,""],"Add a note to the record":[null,""],"New":[null,""],"Save":[null,""],"Switch":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Previous":[null,""],"Next":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Attachment":[null,""],"Note":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Processing...":[null,""],"Create...":[null,""],"Download":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/pl.po b/locale/pl.po
index 3766150..6c93eb0 100644
--- a/locale/pl.po
+++ b/locale/pl.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -21,16 +21,16 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
+msgid "User name"
 msgstr ""
 
-msgid "Unable to reach the server."
+msgid "Database"
 msgstr ""
 
-msgid "Toggle navigation"
+msgid "Unable to reach the server."
 msgstr ""
 
-msgid "Menu"
+msgid "Close"
 msgstr ""
 
 msgid ""
@@ -38,52 +38,37 @@ msgid ""
 "Do you want to continue?"
 msgstr ""
 
-msgid "Close"
-msgstr ""
-
-msgid "New"
-msgstr ""
-
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -95,6 +80,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -107,6 +98,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -175,12 +172,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -253,6 +244,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -284,6 +281,10 @@ msgid "More"
 msgstr ""
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -387,9 +388,19 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/pt_BR.json b/locale/pt_BR.json
index bc6fd36..4d66eae 100644
--- a/locale/pt_BR.json
+++ b/locale/pt_BR.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,"Sair"],"Favorites":[null,""],"Search...":[null,"Pesquisar..."],"Unable to reach the server":[null,"Pesquisar..."],"Login":[null,"Login"],"Database":[null,"Banco de dados"],"Unable to reach the server.":[null,"Não foi possível se conectar ao servidor."],"Toggle navigation":[null,"Exibir navegação"],"Menu":[null,"Menu"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"A seguinte ação requer que todas as abas sejam fechadas.\nVocê deseja continuar?"],"Close":[null,"Fechar"],"New":[null,"Novo"],"Create a new record":[null,"Criar um novo registro"],"Save":[null,"Gravar"],"Save this record":[null,"Gravar este registro"],"Switch":[null,"Trocar"],"Switch view":[null,"Trocar a visão"],"Reload":[null,"Recarregar"],"Previous":[null,"Anterior"],"Previous Record":[null,"Registro anterior"],"Next":[null,"Próximo"],"Next Record":[null,"Próximo registro"],"Attachment":[null,"Anexo"],"Add an attachment to the record":[null,"Adicionar um anexo ao registro"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"Recarregar/Desfazer"],"Duplicate":[null,"Recarregar/Desfazer"],"Delete":[null,"Apagar"],"Search":[null,"Buscar"],"View Logs...":[null,"Ver logs..."],"Show revisions...":[null,"Mostrar revisões..."],"Close Tab":[null,"Fechar aba"],"Action":[null,"Ação"],"Relate":[null,"Relacionar"],"Print":[null,"Imprimir"],"Export":[null,""],"Import":[null,""],"Launch action":[null,"Iniciar ação"],"Open related records":[null,"Abrir registros relacionados"],"Print report":[null,"Abrir registros relacionados"],"This record has been modified\ndo you want to save it?":[null,"Este registro foi modificado\nvocê deseja gravá-lo?"],"Record saved.":[null,"Registro gravado."],"Working now on the duplicated record(s).":[null,"Registro gravado."],"Are you sure to remove this record?":[null,"Você tem certeza que deseja apagar este registro?"],"Are you sure to remove those records?":[null,"Você tem certeza que deseja apagar estes registros?"],"Records removed.":[null,"Registros apagados."],"Records not removed.":[null,"Registros apagados."],"You have to select one record.":[null,"Você precisa selecionar um registro."],"ID:":[null,"ID:"],"Creation User:":[null,"Criado por:"],"Creation Date:":[null,"Data de criação:"],"Latest Modification by:":[null,"Última modificação por:"],"Latest Modification Date:":[null,"Data da última modificação:"],"Model: ":[null,"ID:"],"Attachment(%1)":[null,"Anexo(%1)"],"Note(%1)":[null,""],"Filters":[null,"Filtros"],"Bookmarks":[null,"Favoritos"],"Remove this bookmark":[null,"Remover favorito"],"Bookmark this filter":[null,"Adicionar este filtro aos favoritos"],"Bookmark Name:":[null,"Nome do favorito:"],"True":[null,"Verdadeiro"],"False":[null,"Falso"],"Find":[null,"Localizar"],"ID":[null,"ID"],"Creation User":[null,"Criado por"],"Creation Date":[null,"Data de criação"],"Modification User":[null,"Editado por"],"Modification Date":[null,"Data de modificação"],"\"%1\" is required":[null,"\"%1\" é obrigatório"],"\"%1\" is not valid according to its domain":[null,"\"%1\" não é válido de acordo com seu domínio"],"The values of \"%1\" are not valid":[null,"Os valores para \"%1\" não são válidos"],"Pre-validation":[null,"Pré-validação"],"Translate":[null,""],"Cancel":[null,"Cancelar"],"OK":[null,"OK"],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,"Fonte"],"Size":[null,"Tamanho"],"Add":[null,"Tamanho"],"Remove":[null,"Remover"],"Open":[null,"Abrir"],"Undelete":[null,"Recuperar"],"Select":[null,"Selecionar"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Mais"],"%1 (%2)":[null,""],"Select your action":[null,"Selecione sua ação"],"Your selection:":[null,"Sua seleção:"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"s"],"d":[null,"s"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,""],"y":[null,"a"],"Yes":[null,"Sim"],"t":[null,"t"],"Message: ":[null,"t"],"Warning: ":[null,"Alerta: "],"Always ignore this warning.":[null,"Sempre ignorar este alerta."],"Do you want to proceed?":[null,"Você deseja continuar?"],"No":[null,"Não"],"Confirmation: ":[null,"Confirmação:"],"Concurrency Exception":[null,"Exceção de concorrência"],"Write Concurrency Warning: ":[null,"Alerta de edição concorrente:"],"This record has been modified while you were editing it.":[null,"Este registro foi modificado enquanto você o editava."],"Choose:":[null,"Escolha:"],"\"Cancel\" to cancel saving;":[null,"\"Cancelar\" para cancelar a gravação;"],"\"Compare\" to see the modified version;":[null,"\"Comparar\" para ver a versão modificada;"],"\"Write Anyway\" to save your current version.":[null,"\"Forçar Escrita\" para salvar sua versão atual."],"Compare":[null,"\"Escrever mesmo assim\" para gravar sua versão atual."],"Write Anyway":[null,"Forçar Escrita"],"Application Error":[null,"Forçar Escrita"],"Report Bug":[null,"Relatar erro"],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,"Revisão"],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,"Assistente"]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Gerenciar favoritos"],"Logout":[null,"Sair"],"Favorites":[null,"Favoritos"],"Search...":[null,"Buscar..."],"Unable to reach the server":[null,"Não é possível se conectar ao servidor"],"Login":[null,"Entrar"],"User name":[null,"Usuário"],"Database":[null,"Banco de dados"],"Unable to reach the server.":[null,"Não foi possível se conectar ao servidor."],"Close":[null,"Fechar"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"A seguinte ação requer que todas as abas sejam fechadas.\nVocê deseja continuar?"],"Create a new record":[null,"Criar um novo registro"],"Save this record":[null,"Gravar este registro"],"Switch view":[null,"Alternar a visão"],"Reload":[null,"Recarregar"],"Previous Record":[null,"Registro anterior"],"Next Record":[null,"Próximo registro"],"Add an attachment to the record":[null,"Adicionar um anexo ao registro"],"Add a note to the record":[null,"Adicionar uma nota ao registro"],"New":[null,"Novo"],"Save":[null,"Gravar"],"Switch":[null,"Alternar"],"Reload/Undo":[null,"Recarregar/Desfazer"],"Duplicate":[null,"Duplicar"],"Delete":[null,"Apagar"],"Previous":[null,"Anterior"],"Next":[null,"Próximo"],"Search":[null,"Buscar"],"View Logs...":[null,"Ver logs..."],"Show revisions...":[null,"Mostrar revisões..."],"Close Tab":[null,"Fechar aba"],"Attachment":[null,"Anexo"],"Note":[null,"Nota"],"Action":[null,"Ação"],"Relate":[null,"Relacionar"],"Print":[null,"Imprimir"],"Export":[null,"Exportar"],"Import":[null,"Importar"],"Launch action":[null,"Iniciar ação"],"Open related records":[null,"Abrir registros relacionados"],"Print report":[null,"Imprimir relatório"],"This record has been modified\ndo you want to save it?":[null,"Este registro foi modificado\nvocê deseja gravá-lo?"],"Record saved.":[null,"Registro gravado."],"Working now on the duplicated record(s).":[null,"Trabalhando agora no(s) registro(s) duplicado(s)"],"Are you sure to remove this record?":[null,"Você tem certeza que deseja apagar este registro?"],"Are you sure to remove those records?":[null,"Você tem certeza que deseja apagar estes registros?"],"Records removed.":[null,"Registros apagados."],"Records not removed.":[null,"Registros não apagados."],"You have to select one record.":[null,"Você precisa selecionar um registro."],"ID:":[null,"ID:"],"Creation User:":[null,"Criado por:"],"Creation Date:":[null,"Data de criação:"],"Latest Modification by:":[null,"Última modificação por:"],"Latest Modification Date:":[null,"Data da última modificação:"],"Model: ":[null,"Modelo: "],"Filters":[null,"Filtros"],"Bookmarks":[null,"Favoritos"],"Remove this bookmark":[null,"Remover este favorito"],"Bookmark this filter":[null,"Adicionar este filtro aos favoritos"],"Bookmark Name:":[null,"Nome do favorito:"],"True":[null,"Verdadeiro"],"False":[null,"Falso"],"Find":[null,"Localizar"],"ID":[null,"ID"],"Creation User":[null,"Criado por"],"Creation Date":[null,"Data de criação"],"Modification User":[null,"Editado por"],"Modification Date":[null,"Data de modificação"],"\"%1\" is required":[null,"\"%1\" é obrigatório"],"\"%1\" is not valid according to its domain":[null,"\"%1\" não é válido de acordo com seu domínio"],"The values of \"%1\" are not valid":[null,"Os valores para \"%1\" não são válidos"],"Pre-validation":[null,"Pré-validação"],"Translate":[null,"Traduzir"],"Cancel":[null,"Cancelar"],"OK":[null,"OK"],"Edit":[null,"Editar"],"Fuzzy":[null,"Vago"],"You need to save the record before adding translations.":[null,"Você precisa gravar o registro antes de adicionar traduções."],"No other language available.":[null,"Não há outro idioma disponível."],"Show":[null,"Mostrar"],"Hide":[null,"Ocultar"],"Font":[null,"Fonte"],"Size":[null,"Tamanho"],"Add":[null,"Adicionar"],"Remove":[null,"Remover"],"Open":[null,"Abrir"],"Undelete":[null,"Recuperar"],"Select":[null,"Selecionar"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Mais"],": ":[null,": "],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Selecione sua ação"],"No action defined.":[null,"Nenhuma ação definida."],"Your selection:":[null,"Sua seleção:"],"Y":[null,"A"],"M":[null,"M"],"w":[null,"s"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Por: "],"y":[null,"a"],"Yes":[null,"Sim"],"t":[null,"v"],"Message: ":[null,"Mensagem: "],"Warning: ":[null,"Alerta: "],"Always ignore this warning.":[null,"Sempre ignorar este alerta."],"Do you want to proceed?":[null,"Você deseja continuar?"],"No":[null,"Não"],"Confirmation: ":[null,"Confirmação: "],"Concurrency Exception":[null,"Exceção de concorrência"],"Write Concurrency Warning: ":[null,"Alerta de edição concorrente: "],"This record has been modified while you were editing it.":[null,"Este registro foi modificado enquanto você o editava."],"Choose:":[null,"Escolha:"],"\"Cancel\" to cancel saving;":[null,"\"Cancelar\" para cancelar a gravação;"],"\"Compare\" to see the modified version;":[null,"\"Comparar\" para ver a versão modificada;"],"\"Write Anyway\" to save your current version.":[null,"\"Forçar Escrita\" para gravar sua versão atual."],"Compare":[null,"\"Escrever mesmo assim\" para gravar sua versão atual."],"Write Anyway":[null,"Forçar Escrita"],"Application Error":[null,"Erro no Sistema"],"Report Bug":[null,"Relatar erro"],"Processing...":[null,"Processando..."],"Create...":[null,"Criar..."],"Download":[null,"Baixar"],"...":[null,"..."],"Attachments (%1)":[null,"Anexo (%1)"],"Notes (%1)":[null,"Notas (%1)"],"Search %1":[null,"Buscar %1"],"Revision":[null,"Revisão"],"All Fields":[null,"Todos os Campos"],"Clear":[null,"Limpar"],"Fields Selected":[null,"Campos Selecionados"],"CSV Parameters":[null,"Parâmetros CSV"],"Delimiter:":[null,"Separador:"],"Quote Char:":[null,"Caractere de Citação:"],"Encoding:":[null,"Codificação:"],"Import from CSV":[null,"Importar de CSV"],"Auto-Detect":[null,"Auto-Detectar"],"File to Import":[null,"Arquivo a importar"],"Lines to Skip:":[null,"Linhas a Ignorar:"],"You must select an import file first":[null,"Primeiro você deve selecionar um arquivo para importar."],"Error occured in loading the file":[null,"Ocorreu um erro ao carregar o arquivo"],"Error processing the file at field %1.":[null,"Erro ao processar o arquivo no campo %1."],"Error":[null,"Erro"],"Export to CSV":[null,"Exportar para CSV"],"Predefined Exports":[null,"Exportações Pre-definidas"],"Save Export":[null,"Gravar Exportação"],"Delete Export":[null,"Apagar Exportação"],"Add Field Names":[null,"Adicionar Campos"],"%1 (string)":[null,"%1 (texto)"],"What is the name of this export?":[null,"Qual é o nome desta Exportação?"],"Override %1 definition?":[null,"Sobrescrever definição %1?"],"Wizard":[null,"Assistente"]}
\ No newline at end of file
diff --git a/locale/pt_BR.po b/locale/pt_BR.po
index be1e894..ffd4204 100644
--- a/locale/pt_BR.po
+++ b/locale/pt_BR.po
@@ -2,9 +2,10 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 15 2017 01:03:29 GMT+0200 (CEST)
 msgid "Manage favorites"
-msgstr ""
+msgstr "Gerenciar favoritos"
 
 # Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
 # Generated by grunt-xgettext on Fri Oct 16 2015 17:37:32 GMT+0200 (CEST)
@@ -12,16 +13,19 @@ msgid "Logout"
 msgstr "Sair"
 
 msgid "Favorites"
-msgstr ""
+msgstr "Favoritos"
 
 msgid "Search..."
-msgstr "Pesquisar..."
+msgstr "Buscar..."
 
 msgid "Unable to reach the server"
-msgstr "Pesquisar..."
+msgstr "Não é possível se conectar ao servidor"
 
 msgid "Login"
-msgstr "Login"
+msgstr "Entrar"
+
+msgid "User name"
+msgstr "Usuário"
 
 msgid "Database"
 msgstr "Banco de dados"
@@ -29,11 +33,8 @@ msgstr "Banco de dados"
 msgid "Unable to reach the server."
 msgstr "Não foi possível se conectar ao servidor."
 
-msgid "Toggle navigation"
-msgstr "Exibir navegação"
-
-msgid "Menu"
-msgstr "Menu"
+msgid "Close"
+msgstr "Fechar"
 
 msgid ""
 "The following action requires to close all tabs.\n"
@@ -42,63 +43,54 @@ msgstr ""
 "A seguinte ação requer que todas as abas sejam fechadas.\n"
 "Você deseja continuar?"
 
-msgid "Close"
-msgstr "Fechar"
-
-msgid "New"
-msgstr "Novo"
-
 msgid "Create a new record"
 msgstr "Criar um novo registro"
 
-msgid "Save"
-msgstr "Gravar"
-
 msgid "Save this record"
 msgstr "Gravar este registro"
 
-msgid "Switch"
-msgstr "Trocar"
-
 msgid "Switch view"
-msgstr "Trocar a visão"
+msgstr "Alternar a visão"
 
 msgid "Reload"
 msgstr "Recarregar"
 
-msgid "Previous"
-msgstr "Anterior"
-
 msgid "Previous Record"
 msgstr "Registro anterior"
 
-msgid "Next"
-msgstr "Próximo"
-
 msgid "Next Record"
 msgstr "Próximo registro"
 
-msgid "Attachment"
-msgstr "Anexo"
-
 msgid "Add an attachment to the record"
 msgstr "Adicionar um anexo ao registro"
 
-msgid "Note"
-msgstr ""
-
 msgid "Add a note to the record"
-msgstr ""
+msgstr "Adicionar uma nota ao registro"
+
+msgid "New"
+msgstr "Novo"
+
+msgid "Save"
+msgstr "Gravar"
+
+msgid "Switch"
+msgstr "Alternar"
 
 msgid "Reload/Undo"
 msgstr "Recarregar/Desfazer"
 
 msgid "Duplicate"
-msgstr "Recarregar/Desfazer"
+msgstr "Duplicar"
 
 msgid "Delete"
 msgstr "Apagar"
 
+msgid "Previous"
+msgstr "Anterior"
+
+msgid "Next"
+msgstr "Próximo"
+
 msgid "Search"
 msgstr "Buscar"
 
@@ -111,6 +103,12 @@ msgstr "Mostrar revisões..."
 msgid "Close Tab"
 msgstr "Fechar aba"
 
+msgid "Attachment"
+msgstr "Anexo"
+
+msgid "Note"
+msgstr "Nota"
+
 msgid "Action"
 msgstr "Ação"
 
@@ -121,10 +119,10 @@ msgid "Print"
 msgstr "Imprimir"
 
 msgid "Export"
-msgstr ""
+msgstr "Exportar"
 
 msgid "Import"
-msgstr ""
+msgstr "Importar"
 
 msgid "Launch action"
 msgstr "Iniciar ação"
@@ -133,7 +131,7 @@ msgid "Open related records"
 msgstr "Abrir registros relacionados"
 
 msgid "Print report"
-msgstr "Abrir registros relacionados"
+msgstr "Imprimir relatório"
 
 msgid ""
 "This record has been modified\n"
@@ -146,7 +144,7 @@ msgid "Record saved."
 msgstr "Registro gravado."
 
 msgid "Working now on the duplicated record(s)."
-msgstr "Registro gravado."
+msgstr "Trabalhando agora no(s) registro(s) duplicado(s)"
 
 msgid "Are you sure to remove this record?"
 msgstr "Você tem certeza que deseja apagar este registro?"
@@ -158,7 +156,7 @@ msgid "Records removed."
 msgstr "Registros apagados."
 
 msgid "Records not removed."
-msgstr "Registros apagados."
+msgstr "Registros não apagados."
 
 msgid "You have to select one record."
 msgstr "Você precisa selecionar um registro."
@@ -179,13 +177,7 @@ msgid "Latest Modification Date:"
 msgstr "Data da última modificação:"
 
 msgid "Model: "
-msgstr "ID:"
-
-msgid "Attachment(%1)"
-msgstr "Anexo(%1)"
-
-msgid "Note(%1)"
-msgstr ""
+msgstr "Modelo: "
 
 msgid "Filters"
 msgstr "Filtros"
@@ -194,7 +186,7 @@ msgid "Bookmarks"
 msgstr "Favoritos"
 
 msgid "Remove this bookmark"
-msgstr "Remover favorito"
+msgstr "Remover este favorito"
 
 msgid "Bookmark this filter"
 msgstr "Adicionar este filtro aos favoritos"
@@ -239,7 +231,7 @@ msgid "Pre-validation"
 msgstr "Pré-validação"
 
 msgid "Translate"
-msgstr ""
+msgstr "Traduzir"
 
 msgid "Cancel"
 msgstr "Cancelar"
@@ -248,16 +240,22 @@ msgid "OK"
 msgstr "OK"
 
 msgid "Edit"
-msgstr ""
+msgstr "Editar"
 
 msgid "Fuzzy"
-msgstr ""
+msgstr "Vago"
 
 msgid "You need to save the record before adding translations."
-msgstr ""
+msgstr "Você precisa gravar o registro antes de adicionar traduções."
 
 msgid "No other language available."
-msgstr ""
+msgstr "Não há outro idioma disponível."
+
+msgid "Show"
+msgstr "Mostrar"
+
+msgid "Hide"
+msgstr "Ocultar"
 
 msgid "Font"
 msgstr "Fonte"
@@ -266,7 +264,7 @@ msgid "Size"
 msgstr "Tamanho"
 
 msgid "Add"
-msgstr "Tamanho"
+msgstr "Adicionar"
 
 msgid "Remove"
 msgstr "Remover"
@@ -289,23 +287,23 @@ msgstr ":"
 msgid "More"
 msgstr "Mais"
 
-#, fuzzy
+msgid ": "
+msgstr ": "
+
 msgid ", "
 msgstr ", "
 
-#, fuzzy
 msgid ",…"
 msgstr ",…"
 
 msgid "%1 (%2)"
-msgstr ""
+msgstr "%1 (%2)"
 
 msgid "Select your action"
 msgstr "Selecione sua ação"
 
-#, fuzzy
 msgid "No action defined."
-msgstr "Nenhuma ação definida!"
+msgstr "Nenhuma ação definida."
 
 msgid "Your selection:"
 msgstr "Sua seleção:"
@@ -320,7 +318,7 @@ msgid "w"
 msgstr "s"
 
 msgid "d"
-msgstr "s"
+msgstr "d"
 
 msgid "h"
 msgstr "h"
@@ -332,7 +330,7 @@ msgid "s"
 msgstr "s"
 
 msgid "By: "
-msgstr ""
+msgstr "Por: "
 
 msgid "y"
 msgstr "a"
@@ -341,10 +339,10 @@ msgid "Yes"
 msgstr "Sim"
 
 msgid "t"
-msgstr "t"
+msgstr "v"
 
 msgid "Message: "
-msgstr "t"
+msgstr "Mensagem: "
 
 msgid "Warning: "
 msgstr "Alerta: "
@@ -359,13 +357,13 @@ msgid "No"
 msgstr "Não"
 
 msgid "Confirmation: "
-msgstr "Confirmação:"
+msgstr "Confirmação: "
 
 msgid "Concurrency Exception"
 msgstr "Exceção de concorrência"
 
 msgid "Write Concurrency Warning: "
-msgstr "Alerta de edição concorrente:"
+msgstr "Alerta de edição concorrente: "
 
 msgid "This record has been modified while you were editing it."
 msgstr "Este registro foi modificado enquanto você o editava."
@@ -380,7 +378,7 @@ msgid "\"Compare\" to see the modified version;"
 msgstr "\"Comparar\" para ver a versão modificada;"
 
 msgid "\"Write Anyway\" to save your current version."
-msgstr "\"Forçar Escrita\" para salvar sua versão atual."
+msgstr "\"Forçar Escrita\" para gravar sua versão atual."
 
 msgid "Compare"
 msgstr "\"Escrever mesmo assim\" para gravar sua versão atual."
@@ -389,96 +387,103 @@ msgid "Write Anyway"
 msgstr "Forçar Escrita"
 
 msgid "Application Error"
-msgstr "Forçar Escrita"
+msgstr "Erro no Sistema"
 
 msgid "Report Bug"
 msgstr "Relatar erro"
 
-#, fuzzy
+msgid "Processing..."
+msgstr "Processando..."
+
 msgid "Create..."
 msgstr "Criar..."
 
-#, fuzzy
+msgid "Download"
+msgstr "Baixar"
+
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
-msgstr "Anexo(%1)"
+msgstr "Anexo (%1)"
 
 msgid "Notes (%1)"
-msgstr ""
+msgstr "Notas (%1)"
 
 msgid "Search %1"
-msgstr ""
+msgstr "Buscar %1"
 
 msgid "Revision"
 msgstr "Revisão"
 
 msgid "All Fields"
-msgstr ""
+msgstr "Todos os Campos"
 
 msgid "Clear"
-msgstr ""
+msgstr "Limpar"
 
 msgid "Fields Selected"
-msgstr ""
+msgstr "Campos Selecionados"
 
 msgid "CSV Parameters"
-msgstr ""
+msgstr "Parâmetros CSV"
 
 msgid "Delimiter:"
-msgstr ""
+msgstr "Separador:"
 
 msgid "Quote Char:"
-msgstr ""
+msgstr "Caractere de Citação:"
 
 msgid "Encoding:"
-msgstr ""
+msgstr "Codificação:"
 
 msgid "Import from CSV"
-msgstr ""
+msgstr "Importar de CSV"
 
 msgid "Auto-Detect"
-msgstr ""
+msgstr "Auto-Detectar"
 
 msgid "File to Import"
-msgstr ""
+msgstr "Arquivo a importar"
 
 msgid "Lines to Skip:"
-msgstr ""
+msgstr "Linhas a Ignorar:"
 
 msgid "You must select an import file first"
-msgstr ""
+msgstr "Primeiro você deve selecionar um arquivo para importar."
 
 msgid "Error occured in loading the file"
-msgstr ""
+msgstr "Ocorreu um erro ao carregar o arquivo"
 
 msgid "Error processing the file at field %1."
-msgstr ""
+msgstr "Erro ao processar o arquivo no campo %1."
 
 msgid "Error"
-msgstr ""
+msgstr "Erro"
 
 msgid "Export to CSV"
-msgstr ""
+msgstr "Exportar para CSV"
 
 msgid "Predefined Exports"
-msgstr ""
+msgstr "Exportações Pre-definidas"
 
 msgid "Save Export"
-msgstr ""
+msgstr "Gravar Exportação"
 
 msgid "Delete Export"
-msgstr ""
+msgstr "Apagar Exportação"
 
 msgid "Add Field Names"
-msgstr ""
+msgstr "Adicionar Campos"
 
 msgid "%1 (string)"
-msgstr ""
+msgstr "%1 (texto)"
 
 msgid "What is the name of this export?"
-msgstr ""
+msgstr "Qual é o nome desta Exportação?"
 
 msgid "Override %1 definition?"
-msgstr ""
+msgstr "Sobrescrever definição %1?"
 
 msgid "Wizard"
 msgstr "Assistente"
diff --git a/locale/ru.json b/locale/ru.json
index c4bdbb4..207155f 100644
--- a/locale/ru.json
+++ b/locale/ru.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,""],"Favorites":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Login":[null,""],"User name":[null,""],"Database":[null,""],"Unable to reach the server.":[null,""],"Close":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Create a new record":[null,""],"Save this record":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous Record":[null,""],"Next Record":[null,""],"Add an attachment to the record":[null,""],"Add a note to the record":[null,""],"New":[null,""],"Save":[null,""],"Switch":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Previous":[null,""],"Next":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Attachment":[null,""],"Note":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Export":[null,""],"Import":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Translate":[null,""],"Cancel":[null,""],"OK":[null,""],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"%1 (%2)":[null,""],"Select your action":[null,""],"No action defined.":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"By: ":[null,""],"y":[null,""],"Yes":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Processing...":[null,""],"Create...":[null,""],"Download":[null,""],"Attachments (%1)":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,""],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/ru.po b/locale/ru.po
index 3766150..6c93eb0 100644
--- a/locale/ru.po
+++ b/locale/ru.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -21,16 +21,16 @@ msgstr ""
 msgid "Login"
 msgstr ""
 
-msgid "Database"
+msgid "User name"
 msgstr ""
 
-msgid "Unable to reach the server."
+msgid "Database"
 msgstr ""
 
-msgid "Toggle navigation"
+msgid "Unable to reach the server."
 msgstr ""
 
-msgid "Menu"
+msgid "Close"
 msgstr ""
 
 msgid ""
@@ -38,52 +38,37 @@ msgid ""
 "Do you want to continue?"
 msgstr ""
 
-msgid "Close"
-msgstr ""
-
-msgid "New"
-msgstr ""
-
 msgid "Create a new record"
 msgstr ""
 
-msgid "Save"
-msgstr ""
-
 msgid "Save this record"
 msgstr ""
 
-msgid "Switch"
-msgstr ""
-
 msgid "Switch view"
 msgstr ""
 
 msgid "Reload"
 msgstr ""
 
-msgid "Previous"
-msgstr ""
-
 msgid "Previous Record"
 msgstr ""
 
-msgid "Next"
+msgid "Next Record"
 msgstr ""
 
-msgid "Next Record"
+msgid "Add an attachment to the record"
 msgstr ""
 
-msgid "Attachment"
+msgid "Add a note to the record"
 msgstr ""
 
-msgid "Add an attachment to the record"
+msgid "New"
 msgstr ""
 
-msgid "Note"
+msgid "Save"
 msgstr ""
 
-msgid "Add a note to the record"
+msgid "Switch"
 msgstr ""
 
 msgid "Reload/Undo"
@@ -95,6 +80,12 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
 msgid "Search"
 msgstr ""
 
@@ -107,6 +98,12 @@ msgstr ""
 msgid "Close Tab"
 msgstr ""
 
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr ""
 
@@ -175,12 +172,6 @@ msgstr ""
 msgid "Model: "
 msgstr ""
 
-msgid "Attachment(%1)"
-msgstr ""
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr ""
 
@@ -253,6 +244,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr ""
 
@@ -284,6 +281,10 @@ msgid "More"
 msgstr ""
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -387,9 +388,19 @@ msgstr ""
 msgid "Report Bug"
 msgstr ""
 
+msgid "Processing..."
+msgstr ""
+
 msgid "Create..."
 msgstr ""
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr ""
 
diff --git a/locale/ru_RU.json b/locale/ru_RU.json
new file mode 100644
index 0000000..9fb066f
--- /dev/null
+++ b/locale/ru_RU.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,""],"Search...":[null,""],"Unable to reach the server":[null,""],"Unable to reach the server.":[null,""],"Login":[null,""],"Password":[null,""],"Database":[null,""],"OK":[null,""],"Toggle navigation":[null,""],"Menu":[null,""],"The following action requires to close all tabs.\nDo you want to continue?":[null,""],"Close":[null,""],"New":[null,""],"Create a new record":[null,""],"Save":[null,""],"Save this record":[null,""],"Switch":[null,""],"Switch view":[null,""],"Reload":[null,""],"Previous":[null,""],"Previous Record":[null,""],"Next":[null,""],"Next Record":[null,""],"Attachment":[null,""],"Add an attachment to the record":[null,""],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,""],"Duplicate":[null,""],"Delete":[null,""],"Search":[null,""],"View Logs...":[null,""],"Show revisions...":[null,""],"Close Tab":[null,""],"Action":[null,""],"Relate":[null,""],"Print":[null,""],"Launch action":[null,""],"Open related records":[null,""],"Print report":[null,""],"This record has been modified\ndo you want to save it?":[null,""],"Record saved.":[null,""],"Working now on the duplicated record(s).":[null,""],"Are you sure to remove this record?":[null,""],"Are you sure to remove those records?":[null,""],"Records removed.":[null,""],"Records not removed.":[null,""],"You have to select one record.":[null,""],"ID:":[null,""],"Creation User:":[null,""],"Creation Date:":[null,""],"Latest Modification by:":[null,""],"Latest Modification Date:":[null,""],"Model: ":[null,""],"Attachment(%1)":[null,""],"Note(%1)":[null,""],"Filters":[null,""],"Bookmarks":[null,""],"Remove this bookmark":[null,""],"Bookmark this filter":[null,""],"Bookmark Name:":[null,""],"True":[null,""],"False":[null,""],"Find":[null,""],"ID":[null,""],"Creation User":[null,""],"Creation Date":[null,""],"Modification User":[null,""],"Modification Date":[null,""],"\"%1\" is required":[null,""],"\"%1\" is not valid according to its domain":[null,""],"The values of \"%1\" are not valid":[null,""],"Pre-validation":[null,""],"Font":[null,""],"Size":[null,""],"Add":[null,""],"Remove":[null,""],"Open":[null,""],"Undelete":[null,""],"Select":[null,""],"Cancel":[null,""],"%1%":[null,""],":":[null,""],"More":[null,""],"Calendar view not yet implemented":[null,""],"Warning":[null,""],"Select your action":[null,""],"No action defined!":[null,""],"Your selection:":[null,""],"Y":[null,""],"M":[null,""],"w":[null,""],"d":[null,""],"h":[null,""],"m":[null,""],"s":[null,""],"y":[null,""],"yes":[null,""],"true":[null,""],"t":[null,""],"Message: ":[null,""],"Warning: ":[null,""],"Always ignore this warning.":[null,""],"Do you want to proceed?":[null,""],"No":[null,""],"Yes":[null,""],"Confirmation: ":[null,""],"Concurrency Exception":[null,""],"Write Concurrency Warning: ":[null,""],"This record has been modified while you were editing it.":[null,""],"Choose:":[null,""],"\"Cancel\" to cancel saving;":[null,""],"\"Compare\" to see the modified version;":[null,""],"\"Write Anyway\" to save your current version.":[null,""],"Compare":[null,""],"Write Anyway":[null,""],"Application Error":[null,""],"Report Bug":[null,""],"Create...":[null,""],"Revision":[null,""],"Wizard":[null,""]}
\ No newline at end of file
diff --git a/locale/sl.json b/locale/sl.json
index 14f4c1d..72ff7ee 100644
--- a/locale/sl.json
+++ b/locale/sl.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Upravljaj zaznamke"],"Logout":[null,"Odjava"],"Favorites":[null,"Zaznamki"],"Search...":[null,"Išči ..."],"Unable to reach the server":[null,"Ni se mogoče povezati s strežnikom"],"Login":[null,"Prijava"],"Database":[null,"Podatkovna baza"],"Unable to reach the server.":[null,"Ni se mogoče povezati s strežnikom."],"Toggle navigation":[null,"Vklop/izklop krmarjenja"],"Menu":[null,"Meni"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"Za slednji ukrep se bodo zaprli vsi zavihki.\nAli želiš nadaljevati?"],"Close":[null,"Zapri"],"New":[null,"Novo"],"Create a new record":[null,"Ustvari nov zapis"],"Save":[null,"Shrani"],"Save this record":[null,"Shrani ta zapis"],"Switch":[null,"Preklopi"],"Switch view":[null,"Preklopi pogled"],"Reload":[null,"Ponovno naloži"],"Previous":[null,"Prejšnji"],"Previous Record":[null,"Prejšnji zapis"],"Next":[null,"Naslednji"],"Next Record":[null,"Naslednji zapis"],"Attachment":[null,"Priponka"],"Add an attachment to the record":[null,"Dodaj priponko zapisu"],"Note":[null,"Zabeležka"],"Add a note to the record":[null,"Dodaj zapisu zabeležko"],"Reload/Undo":[null,"Ponovno naloži"],"Duplicate":[null,"Podvoji"],"Delete":[null,"Zbriši"],"Search":[null,"Išči"],"View Logs...":[null,"Prikaži dnevnik ..."],"Show revisions...":[null,"Prikaži revizije ..."],"Close Tab":[null,"Zapri zavihek"],"Action":[null,"Ukrep"],"Relate":[null,"Veza"],"Print":[null,"Tisk"],"Export":[null,"Izvoz"],"Import":[null,"Uvoz"],"Launch action":[null,"Zaženi ukrep"],"Open related records":[null,"Odpri povezane zapise"],"Print report":[null,"Izpis poročila"],"This record has been modified\ndo you want to save it?":[null,"Ta zapis je bil spremenjen,\nga želiš shraniti?"],"Record saved.":[null,"Zapis shranjen."],"Working now on the duplicated record(s).":[null,"Trenutno se dela na podvojenem zapisu."],"Are you sure to remove this record?":[null,"Ali res želiš zbrisati ta zapis?"],"Are you sure to remove those records?":[null,"Ali res želiš zbrisati te zapise?"],"Records removed.":[null,"Zapisi zbrisani."],"Records not removed.":[null,"Zapisi niso bili zbrisani."],"You have to select one record.":[null,"En zapis mora biti izbran."],"ID:":[null,"ID:"],"Creation User:":[null,"Ustvaril:"],"Creation Date:":[null,"Ustvarjeno:"],"Latest Modification by:":[null,"Nazadnje popravil:"],"Latest Modification Date:":[null,"Nazadnje popravljeno:"],"Model: ":[null,"Model: "],"Attachment(%1)":[null,"Priponka(%1)"],"Note(%1)":[null,"Zabeležka(%1)"],"Filters":[null,"Filtri"],"Bookmarks":[null,"Zaznamki"],"Remove this bookmark":[null,"Zbriši ta zaznamek"],"Bookmark this filter":[null,"Shrani ta filter"],"Bookmark Name:":[null,"Ime zaznamka:"],"True":[null,"Da"],"False":[null,"Ne"],"Find":[null,"Najdi"],"ID":[null,"ID"],"Creation User":[null,"Ustvaril"],"Creation Date":[null,"Ustvarjeno"],"Modification User":[null,"Popravil"],"Modification Date":[null,"Popravljeno"],"\"%1\" is required":[null,"Polje \"%1\" je obvezno"],"\"%1\" is not valid according to its domain":[null,"Polje \"%1\" ni veljavno glede na svojo domeno"],"The values of \"%1\" are not valid":[null,"Vrednosti polja \"%1\" niso veljavne"],"Pre-validation":[null,"Predpreverjanje"],"Translate":[null,"Prevod"],"Cancel":[null,"Prekliči"],"OK":[null,"V redu"],"Edit":[null,"Uredi"],"Fuzzy":[null,"Nejasno"],"You need to save the record before adding translations.":[null,"Pred prevajanjem mora biti zapis shranjen."],"No other language available.":[null,"Drugega jezika ni na voljo."],"Font":[null,"Pisava"],"Size":[null,"Velikost"],"Add":[null,"Dodaj"],"Remove":[null,"Odstrani"],"Open":[null,"Odpri"],"Undelete":[null,"Povrni"],"Select":[null,"Izberi"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Več"],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Izberi ukrep"],"No action defined.":[null,"Nobenega ukrepa še ni določenega."],"Your selection:":[null,"Vaša izbira:"],"Y":[null,"l"],"M":[null,"M"],"w":[null,"t"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Od: "],"y":[null,"d"],"Yes":[null,"Da"],"t":[null,"d"],"Message: ":[null,"Sporočilo:"],"Warning: ":[null,"Opozorilo: "],"Always ignore this warning.":[null,"Vedno prezri to opozorilo."],"Do you want to proceed?":[null,"Ali želiš nadaljevati?"],"No":[null,"Ne"],"Confirmation: ":[null,"Potrditev: "],"Concurrency Exception":[null,"Napaka sočasnega izvajanja"],"Write Concurrency Warning: ":[null,"Opozorilo sočasnega zapisovanja: "],"This record has been modified while you were editing it.":[null,"Ta zapis je bil spremenjen v času vašega popravljanja."],"Choose:":[null,"Izberi:"],"\"Cancel\" to cancel saving;":[null,"\"Prekliči\" - prekliči spremembe;"],"\"Compare\" to see the modified version;":[null,"\"Primerjaj\" - primerjaj z drugo različico;"],"\"Write Anyway\" to save your current version.":[null,"\"Vseeno shrani\" - shrani trenutno različico."],"Compare":[null,"Primerjaj"],"Write Anyway":[null,"Vseeno shrani"],"Application Error":[null,"Programska napaka"],"Report Bug":[null,"Prijavi programsko napako"],"Create...":[null,"Izdelaj ..."],"Attachments (%1)":[null,"Priponke (%1)"],"Notes (%1)":[null,"Zabeležke (%1)"],"Search %1":[null,"Išči %1"],"Revision":[null,"Različica"],"All Fields":[null,"Vsa polja"],"Clear":[null,"Počisti"],"Fields Selected":[null,"Izbrana polja"],"CSV Parameters":[null,"CSV parametri"],"Delimiter:":[null,"Ločilo:"],"Quote Char:":[null,"Narekovaj:"],"Encoding:":[null,"Kodiranje:"],"Import from CSV":[null,"Uvozi iz CSV"],"Auto-Detect":[null,"Samozaznava"],"File to Import":[null,"Datoteka za uvoz"],"Lines to Skip:":[null,"Izpuščene vrstice:"],"You must select an import file first":[null,"Najprej je potrebno izbrati datoteko za uvoz"],"Error occured in loading the file":[null,"Pri nalaganju datoteke je prišlo do napake"],"Error processing the file at field %1.":[null,"Napaka pri obdelavi datoteke pri polju %1."],"Error":[null,"Napaka"],"Export to CSV":[null,"Izvozi v CSV"],"Predefined Exports":[null,"Prednastavljeni izvozi"],"Save Export":[null,"Shrani izvoz"],"Delete Export":[null,"Zbriši izvoz"],"Add Field Names":[null,"Dodaj imena polj"],"%1 (string)":[null,"%1 (niz)"],"What is the name of this export?":[null,"Ime izvoza?"],"Override %1 definition?":[null,"Prepis definicije %1?"],"Wizard":[null,"Čarovnik"]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,"Upravljaj zaznamke"],"Logout":[null,"Odjava"],"Favorites":[null,"Zaznamki"],"Search...":[null,"Išči ..."],"Unable to reach the server":[null,"Ni se mogoče povezati s strežnikom"],"Login":[null,"Prijava"],"User name":[null,"Uporabniško ime"],"Database":[null,"Podatkovna baza"],"Unable to reach the server.":[null,"Ni se mogoče povezati s strežnikom."],"Close":[null,"Zapri"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"Za slednji ukrep se bodo zaprli vsi zavihki.\nAli želiš nadaljevati?"],"Create a new record":[null,"Ustvari nov zapis"],"Save this record":[null,"Shrani ta zapis"],"Switch view":[null,"Preklopi pogled"],"Reload":[null,"Ponovno naloži"],"Previous Record":[null,"Prejšnji zapis"],"Next Record":[null,"Naslednji zapis"],"Add an attachment to the record":[null,"Dodaj priponko zapisu"],"Add a note to the record":[null,"Dodaj zapisu zabeležko"],"New":[null,"Novo"],"Save":[null,"Shrani"],"Switch":[null,"Preklopi"],"Reload/Undo":[null,"Ponovno naloži"],"Duplicate":[null,"Podvoji"],"Delete":[null,"Zbriši"],"Previous":[null,"Prejšnji"],"Next":[null,"Naslednji"],"Search":[null,"Išči"],"View Logs...":[null,"Prikaži dnevnik ..."],"Show revisions...":[null,"Prikaži revizije ..."],"Close Tab":[null,"Zapri zavihek"],"Attachment":[null,"Priponka"],"Note":[null,"Zabeležka"],"Action":[null,"Ukrep"],"Relate":[null,"Veza"],"Print":[null,"Tisk"],"Export":[null,"Izvoz"],"Import":[null,"Uvoz"],"Launch action":[null,"Zaženi ukrep"],"Open related records":[null,"Odpri povezane zapise"],"Print report":[null,"Izpis poročila"],"This record has been modified\ndo you want to save it?":[null,"Ta zapis je bil spremenjen,\nga želiš shraniti?"],"Record saved.":[null,"Zapis shranjen."],"Working now on the duplicated record(s).":[null,"Trenutno se dela na podvojenem zapisu."],"Are you sure to remove this record?":[null,"Ali res želiš zbrisati ta zapis?"],"Are you sure to remove those records?":[null,"Ali res želiš zbrisati te zapise?"],"Records removed.":[null,"Zapisi zbrisani."],"Records not removed.":[null,"Zapisi niso bili zbrisani."],"You have to select one record.":[null,"En zapis mora biti izbran."],"ID:":[null,"ID:"],"Creation User:":[null,"Ustvaril:"],"Creation Date:":[null,"Ustvarjeno:"],"Latest Modification by:":[null,"Nazadnje popravil:"],"Latest Modification Date:":[null,"Nazadnje popravljeno:"],"Model: ":[null,"Model: "],"Filters":[null,"Filtri"],"Bookmarks":[null,"Zaznamki"],"Remove this bookmark":[null,"Zbriši ta zaznamek"],"Bookmark this filter":[null,"Shrani ta filter"],"Bookmark Name:":[null,"Ime zaznamka:"],"True":[null,"Da"],"False":[null,"Ne"],"Find":[null,"Najdi"],"ID":[null,"ID"],"Creation User":[null,"Ustvaril"],"Creation Date":[null,"Ustvarjeno"],"Modification User":[null,"Popravil"],"Modification Date":[null,"Popravljeno"],"\"%1\" is required":[null,"Polje \"%1\" je obvezno"],"\"%1\" is not valid according to its domain":[null,"Polje \"%1\" ni veljavno glede na svojo domeno"],"The values of \"%1\" are not valid":[null,"Vrednosti polja \"%1\" niso veljavne"],"Pre-validation":[null,"Predpreverjanje"],"Translate":[null,"Prevod"],"Cancel":[null,"Prekliči"],"OK":[null,"V redu"],"Edit":[null,"Uredi"],"Fuzzy":[null,"Nejasno"],"You need to save the record before adding translations.":[null,"Pred prevajanjem mora biti zapis shranjen."],"No other language available.":[null,"Drugega jezika ni na voljo."],"Show":[null,"Pokaži"],"Hide":[null,"Skrij"],"Font":[null,"Pisava"],"Size":[null,"Velikost"],"Add":[null,"Dodaj"],"Remove":[null,"Odstrani"],"Open":[null,"Odpri"],"Undelete":[null,"Povrni"],"Select":[null,"Izberi"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Več"],": ":[null,": "],", ":[null,", "],",…":[null,",…"],"%1 (%2)":[null,"%1 (%2)"],"Select your action":[null,"Izberi ukrep"],"No action defined.":[null,"Nobenega ukrepa še ni določenega."],"Your selection:":[null,"Vaša izbira:"],"Y":[null,"l"],"M":[null,"M"],"w":[null,"t"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"By: ":[null,"Od: "],"y":[null,"d"],"Yes":[null,"Da"],"t":[null,"d"],"Message: ":[null,"Sporočilo:"],"Warning: ":[null,"Opozorilo: "],"Always ignore this warning.":[null,"Vedno prezri to opozorilo."],"Do you want to proceed?":[null,"Ali želiš nadaljevati?"],"No":[null,"Ne"],"Confirmation: ":[null,"Potrditev: "],"Concurrency Exception":[null,"Napaka sočasnega izvajanja"],"Write Concurrency Warning: ":[null,"Opozorilo sočasnega zapisovanja: "],"This record has been modified while you were editing it.":[null,"Ta zapis je bil spremenjen v času vašega popravljanja."],"Choose:":[null,"Izberi:"],"\"Cancel\" to cancel saving;":[null,"\"Prekliči\" - prekliči spremembe;"],"\"Compare\" to see the modified version;":[null,"\"Primerjaj\" - primerjaj z drugo različico;"],"\"Write Anyway\" to save your current version.":[null,"\"Vseeno shrani\" - shrani trenutno različico."],"Compare":[null,"Primerjaj"],"Write Anyway":[null,"Vseeno shrani"],"Application Error":[null,"Programska napaka"],"Report Bug":[null,"Prijavi programsko napako"],"Processing...":[null,"Obdelava ..."],"Create...":[null,"Izdelaj ..."],"Download":[null,"Prenesi"],"...":[null,"..."],"Attachments (%1)":[null,"Priponke (%1)"],"Notes (%1)":[null,"Zabeležke (%1)"],"Search %1":[null,"Išči %1"],"Revision":[null,"Različica"],"All Fields":[null,"Vsa polja"],"Clear":[null,"Počisti"],"Fields Selected":[null,"Izbrana polja"],"CSV Parameters":[null,"CSV parametri"],"Delimiter:":[null,"Ločilo:"],"Quote Char:":[null,"Narekovaj:"],"Encoding:":[null,"Kodiranje:"],"Import from CSV":[null,"Uvozi iz CSV"],"Auto-Detect":[null,"Samozaznava"],"File to Import":[null,"Datoteka za uvoz"],"Lines to Skip:":[null,"Izpuščene vrstice:"],"You must select an import file first":[null,"Najprej je potrebno izbrati datoteko za uvoz"],"Error occured in loading the file":[null,"Pri nalaganju datoteke je prišlo do napake"],"Error processing the file at field %1.":[null,"Napaka pri obdelavi datoteke pri polju %1."],"Error":[null,"Napaka"],"Export to CSV":[null,"Izvozi v CSV"],"Predefined Exports":[null,"Prednastavljeni izvozi"],"Save Export":[null,"Shrani izvoz"],"Delete Export":[null,"Zbriši izvoz"],"Add Field Names":[null,"Dodaj imena polj"],"%1 (string)":[null,"%1 (niz)"],"What is the name of this export?":[null,"Ime izvoza?"],"Override %1 definition?":[null,"Prepis definicije %1?"],"Wizard":[null,"Čarovnik"]}
\ No newline at end of file
diff --git a/locale/sl.po b/locale/sl.po
index 9b31fd7..321bc96 100644
--- a/locale/sl.po
+++ b/locale/sl.po
@@ -2,6 +2,9 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 15 2017 01:03:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Apr 04 2017 10:44:30 GMT+0200 (CEST)
 # Generated by grunt-xgettext on Tue Nov 01 2016 15:18:23 GMT+0100 (CET)
 msgid "Manage favorites"
 msgstr "Upravljaj zaznamke"
@@ -23,17 +26,17 @@ msgstr "Ni se mogoče povezati s strežnikom"
 msgid "Login"
 msgstr "Prijava"
 
+msgid "User name"
+msgstr "Uporabniško ime"
+
 msgid "Database"
 msgstr "Podatkovna baza"
 
 msgid "Unable to reach the server."
 msgstr "Ni se mogoče povezati s strežnikom."
 
-msgid "Toggle navigation"
-msgstr "Vklop/izklop krmarjenja"
-
-msgid "Menu"
-msgstr "Meni"
+msgid "Close"
+msgstr "Zapri"
 
 msgid ""
 "The following action requires to close all tabs.\n"
@@ -42,54 +45,39 @@ msgstr ""
 "Za slednji ukrep se bodo zaprli vsi zavihki.\n"
 "Ali želiš nadaljevati?"
 
-msgid "Close"
-msgstr "Zapri"
-
-msgid "New"
-msgstr "Novo"
-
 msgid "Create a new record"
 msgstr "Ustvari nov zapis"
 
-msgid "Save"
-msgstr "Shrani"
-
 msgid "Save this record"
 msgstr "Shrani ta zapis"
 
-msgid "Switch"
-msgstr "Preklopi"
-
 msgid "Switch view"
 msgstr "Preklopi pogled"
 
 msgid "Reload"
 msgstr "Ponovno naloži"
 
-msgid "Previous"
-msgstr "Prejšnji"
-
 msgid "Previous Record"
 msgstr "Prejšnji zapis"
 
-msgid "Next"
-msgstr "Naslednji"
-
 msgid "Next Record"
 msgstr "Naslednji zapis"
 
-msgid "Attachment"
-msgstr "Priponka"
-
 msgid "Add an attachment to the record"
 msgstr "Dodaj priponko zapisu"
 
-msgid "Note"
-msgstr "Zabeležka"
-
 msgid "Add a note to the record"
 msgstr "Dodaj zapisu zabeležko"
 
+msgid "New"
+msgstr "Novo"
+
+msgid "Save"
+msgstr "Shrani"
+
+msgid "Switch"
+msgstr "Preklopi"
+
 msgid "Reload/Undo"
 msgstr "Ponovno naloži"
 
@@ -99,6 +87,12 @@ msgstr "Podvoji"
 msgid "Delete"
 msgstr "Zbriši"
 
+msgid "Previous"
+msgstr "Prejšnji"
+
+msgid "Next"
+msgstr "Naslednji"
+
 msgid "Search"
 msgstr "Išči"
 
@@ -111,6 +105,12 @@ msgstr "Prikaži revizije ..."
 msgid "Close Tab"
 msgstr "Zapri zavihek"
 
+msgid "Attachment"
+msgstr "Priponka"
+
+msgid "Note"
+msgstr "Zabeležka"
+
 msgid "Action"
 msgstr "Ukrep"
 
@@ -181,12 +181,6 @@ msgstr "Nazadnje popravljeno:"
 msgid "Model: "
 msgstr "Model: "
 
-msgid "Attachment(%1)"
-msgstr "Priponka(%1)"
-
-msgid "Note(%1)"
-msgstr "Zabeležka(%1)"
-
 msgid "Filters"
 msgstr "Filtri"
 
@@ -259,6 +253,12 @@ msgstr "Pred prevajanjem mora biti zapis shranjen."
 msgid "No other language available."
 msgstr "Drugega jezika ni na voljo."
 
+msgid "Show"
+msgstr "Pokaži"
+
+msgid "Hide"
+msgstr "Skrij"
+
 msgid "Font"
 msgstr "Pisava"
 
@@ -289,6 +289,9 @@ msgstr ":"
 msgid "More"
 msgstr "Več"
 
+msgid ": "
+msgstr ": "
+
 msgid ", "
 msgstr ", "
 
@@ -391,9 +394,18 @@ msgstr "Programska napaka"
 msgid "Report Bug"
 msgstr "Prijavi programsko napako"
 
+msgid "Processing..."
+msgstr "Obdelava ..."
+
 msgid "Create..."
 msgstr "Izdelaj ..."
 
+msgid "Download"
+msgstr "Prenesi"
+
+msgid "..."
+msgstr "..."
+
 msgid "Attachments (%1)"
 msgstr "Priponke (%1)"
 
diff --git a/locale/sl_SI.json b/locale/sl_SI.json
new file mode 100644
index 0000000..c4868dd
--- /dev/null
+++ b/locale/sl_SI.json
@@ -0,0 +1 @@
+{"":{"content-type":"text/plain; charset=utf-8"},"Logout":[null,"Odjava"],"Search...":[null,"Išči ..."],"Unable to reach the server":[null,"Ni se mogoče povezati s strežnikom"],"Unable to reach the server.":[null,"Ni se mogoče povezati s strežnikom."],"Login":[null,"Prijava"],"Password":[null,"Geslo"],"Database":[null,"Podatkovna baza"],"OK":[null,"V redu"],"Toggle navigation":[null,"Vklop/izklop krmarjenja"],"Menu":[null,"Meni"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"Za slednji ukrep se bodo zaprli vsi zavihki.\nAli želiš nadaljevati?"],"Close":[null,"Zapri"],"New":[null,"Novo"],"Create a new record":[null,"Ustvari nov zapis"],"Save":[null,"Shrani"],"Save this record":[null,"Shrani ta zapis"],"Switch":[null,"Preklopi"],"Switch view":[null,"Preklopi pogled"],"Reload":[null,"Ponovno naloži"],"Previous":[null,"Prejšnji"],"Previous Record":[null,"Prejšnji zapis"],"Next":[null,"Naslednji"],"Next Record":[null,"Naslednji zapis"],"Attachment":[null,"Priponka"],"Add an attachment to the record":[null,"Dodaj priponko zapisu"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"Ponovno naloži"],"Duplicate":[null,"Podvoji"],"Delete":[null,"Zbriši"],"Search":[null,"Išči"],"View Logs...":[null,"Prikaži dnevnik ..."],"Show revisions...":[null,"Prikaži revizije ..."],"Close Tab":[null,"Zapri zavihek"],"Action":[null,"Ukrep"],"Relate":[null,"Veza"],"Print":[null,"Tisk"],"Launch action":[null,"Zaženi ukrep"],"Open related records":[null,"Odpri povezane zapise"],"Print report":[null,"Izpis poročila"],"This record has been modified\ndo you want to save it?":[null,"Ta zapis je bil spremenjen,\nga želiš shraniti?"],"Record saved.":[null,"Zapis shranjen."],"Working now on the duplicated record(s).":[null,"Trenutno se dela na podvojenem zapisu."],"Are you sure to remove this record?":[null,"Ali res želiš zbrisati ta zapis?"],"Are you sure to remove those records?":[null,"Ali res želiš zbrisati te zapise?"],"Records removed.":[null,"Zapisi zbrisani."],"Records not removed.":[null,"Zapisi niso bili zbrisani."],"You have to select one record.":[null,"En zapis mora biti izbran."],"ID:":[null,"ID:"],"Creation User:":[null,"Ustvaril:"],"Creation Date:":[null,"Ustvarjeno:"],"Latest Modification by:":[null,"Nazadnje popravil:"],"Latest Modification Date:":[null,"Nazadnje popravljeno:"],"Model: ":[null,"Model: "],"Attachment(%1)":[null,"Priponka(%1)"],"Note(%1)":[null,""],"Filters":[null,"Filtri"],"Bookmarks":[null,"Zaznamki"],"Remove this bookmark":[null,"Zbriši ta zaznamek"],"Bookmark this filter":[null,"Shrani ta filter"],"Bookmark Name:":[null,"Ime zaznamka:"],"True":[null,"Da"],"False":[null,"Ne"],"Find":[null,"Najdi"],"ID":[null,"ID"],"Creation User":[null,"Ustvaril"],"Creation Date":[null,"Ustvarjeno"],"Modification User":[null,"Popravil"],"Modification Date":[null,"Popravljeno"],"\"%1\" is required":[null,"Polje \"%1\" je obvezno"],"\"%1\" is not valid according to its domain":[null,"Polje \"%1\" ni veljavno glede na svojo domeno"],"The values of \"%1\" are not valid":[null,"Vrednosti polja \"%1\" niso veljavne"],"Pre-validation":[null,"Predpreverjanje"],"Font":[null,"Pisava"],"Size":[null,"Velikost"],"Add":[null,"Dodaj"],"Remove":[null,"Odstrani"],"Open":[null,"Odpri"],"Undelete":[null,"Povrni"],"Select":[null,"Izberi"],"Cancel":[null,"Prekliči"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"Več"],"Calendar view not yet implemented":[null,"Koledarski pogled še ni implementiran"],"Warning":[null,"Opozorilo"],"Select your action":[null,"Izberi ukrep"],"No action defined!":[null,"Nobenega ukrepa še ni določenega"],"Your selection:":[null,"Vaša izbira:"],"Y":[null,"l"],"M":[null,"M"],"w":[null,"t"],"d":[null,"d"],"h":[null,"h"],"m":[null,"m"],"s":[null,"s"],"y":[null,"d"],"yes":[null,"da"],"true":[null,"da"],"t":[null,"d"],"Message: ":[null,"Sporočilo:"],"Warning: ":[null,"Opozorilo: "],"Always ignore this warning.":[null,"Vedno prezri to opozorilo."],"Do you want to proceed?":[null,"Ali želiš nadaljevati?"],"No":[null,"Ne"],"Yes":[null,"Da"],"Confirmation: ":[null,"Potrditev: "],"Concurrency Exception":[null,"Napaka sočasnega izvajanja"],"Write Concurrency Warning: ":[null,"Opozorilo sočasnega zapisovanja: "],"This record has been modified while you were editing it.":[null,"Ta zapis je bil spremenjen v času vašega popravljanja."],"Choose:":[null,"Izberi:"],"\"Cancel\" to cancel saving;":[null,"\"Prekliči\" - prekliči spremembe;"],"\"Compare\" to see the modified version;":[null,"\"Primerjaj\" - primerjaj z drugo različico;"],"\"Write Anyway\" to save your current version.":[null,"\"Vseeno shrani\" - shrani trenutno različico."],"Compare":[null,"Primerjaj"],"Write Anyway":[null,"Vseeno shrani"],"Application Error":[null,"Programska napaka"],"Report Bug":[null,"Prijavi programsko napako"],"Revision":[null,"Različica"],"Wizard":[null,"Čarovnik"]}
\ No newline at end of file
diff --git a/locale/zh_CN.json b/locale/zh_CN.json
index 3f0b3af..ec11ea3 100644
--- a/locale/zh_CN.json
+++ b/locale/zh_CN.json
@@ -1 +1 @@
-{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,"注销"],"Favorites":[null,""],"Search...":[null,"查找..."],"Unable to reach the server":[null,"无法连接到服务器"],"Login":[null,"登录"],"Database":[null,"服务标识:"],"Unable to reach the server.":[null,"无法连接到服务器."],"Toggle navigation":[null,"切换导航"],"Menu":[null,"菜单"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"该操作需要关闭打开的项目\n是否继续?"],"Close":[null,"关闭"],"New":[null,"新建"],"Create a new record":[null,"新建项目"],"Save":[null,"保存"],"Save this record":[null,"保存项目"],"Switch":[null,"切换视图"],"Switch view":[null,"切换视图"],"Reload":[null,"重载"],"Previous":[null,"向前"],"Previous Record":[null,"前一项"],"Next":[null,"向后"],"Next Record":[null,"后一项"],"Attachment":[null,"附件文档"],"Add an attachment to the record":[null,"给当前项添加附件"],"Note":[null,""],"Add a note to the record":[null,""],"Reload/Undo":[null,"重载/撤销"],"Duplicate":[null,"复制"],"Delete":[null,"删除"],"Search":[null,"查找"],"View Logs...":[null,"查看日志..."],"Show revisions...":[null,"显示版本..."],"Close Tab":[null,"关闭标签"],"Action":[null,"操作"],"Relate":[null,"关联"],"Print":[null,"打印"],"Export":[null,""],"Import":[null,""],"Launch action":[null,"执行操作"],"Open related records":[null,"打开关联项目"],"Print report":[null,"打印报表"],"This record has been modified\ndo you want to save it?":[null,"记录有改动, 是否保存?"],"Record saved.":[null,"保存成功."],"Working now on the duplicated record(s).":[null,"当前处理的是项目的副本."],"Are you sure to remove this record?":[null,"确定要删除此项吗?"],"Are you sure to remove those records?":[null,"确定要删除这些项目?"],"Records removed.":[null,"项目已成功删除"],"Records not removed.":[null,"项目未删除"],"You have to select one record.":[null,"选择需要操作的项目"],"ID:":[null,"标识:"],"Creation User:":[null,"创建者:"],"Creation Date:":[null,"创建日期:"],"Latest Modification by:":[null,"最近更改:"],"Latest Modification Date:":[null,"最近更改日期:"],"Model: ":[null,"模型:"],"Attachment(%1)":[null,"附件(%1)"],"Note(%1)":[null,""],"Filters":[null,"筛选"],"Bookmarks":[null,"书签"],"Remove this bookmark":[null,"移除书签"],"Bookmark this filter":[null,"收藏筛选器"],"Bookmark Name:":[null,"书签名称:"],"True":[null,"True"],"False":[null,"False"],"Find":[null,"查找"],"ID":[null,"标识"],"Creation User":[null,"创建者"],"Creation Date":[null,"创建日期"],"Modification User":[null,"修改者"],"Modification Date":[null,"修改日期"],"\"%1\" is required":[null,"\"%1\" 是必填项"],"\"%1\" is not valid according to its domain":[null,"根据域设置,\"%1\" 不可用"],"The values of \"%1\" are not valid":[null,"无法获得\"%1\" 的值"],"Pre-validation":[null,"预校验"],"Translate":[null,""],"Cancel":[null,"取消"],"OK":[null,"确定"],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Font":[null,"字体"],"Size":[null,"大小"],"Add":[null,"添加"],"Remove":[null,"删除"],"Open":[null,"打开"],"Undelete":[null,"回滚"],"Select":[null,"选择"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"更多"],"%1 (%2)":[null,""],"Select your action":[null,"选择一项操作"],"Your selection:":[null,"已选择:"],"Y":[null,"年"],"M":[null,"月"],"w":[null,"星期"],"d":[null,"日"],"h":[null,"时"],"m":[null,"分"],"s":[null,"秒"],"By: ":[null,""],"y":[null,"y"],"Yes":[null,"是"],"t":[null,"t"],"Message: ":[null,"信息:"],"Warning: ":[null,"警告:"],"Always ignore this warning.":[null,"下次不再提示."],"Do you want to proceed?":[null,"继续此项操作 ?"],"No":[null,"否"],"Confirmation: ":[null,"确认:"],"Concurrency Exception":[null,"并行操作异常"],"Write Concurrency Warning: ":[null,"同步操作警告:"],"This record has been modified while you were editing it.":[null,"当前数据已经被其他操作更改."],"Choose:":[null,"选择:"],"\"Cancel\" to cancel saving;":[null,"\"取消\" 不保存;"],"\"Compare\" to see the modified version;":[null," \"对比\" 查看变更的数据;"],"\"Write Anyway\" to save your current version.":[null," \"覆写\" 保存当前数据."],"Compare":[null,"对比"],"Write Anyway":[null,"覆写"],"Application Error":[null,"程序错误"],"Report Bug":[null,"报告Bug"],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,"版本"],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,"向导"]}
\ No newline at end of file
+{"":{"content-type":"text/plain; charset=utf-8"},"Manage favorites":[null,""],"Logout":[null,"注销"],"Favorites":[null,""],"Search...":[null,"查找..."],"Unable to reach the server":[null,"无法连接到服务器"],"Login":[null,"登录"],"User name":[null,""],"Database":[null,"服务标识:"],"Unable to reach the server.":[null,"无法连接到服务器."],"Close":[null,"关闭"],"The following action requires to close all tabs.\nDo you want to continue?":[null,"该操作需要关闭打开的项目\n是否继续?"],"Create a new record":[null,"新建项目"],"Save this record":[null,"保存项目"],"Switch view":[null,"切换视图"],"Reload":[null,"重载"],"Previous Record":[null,"前一项"],"Next Record":[null,"后一项"],"Add an attachment to the record":[null,"给当前项添加附件"],"Add a note to the record":[null,""],"New":[null,"新建"],"Save":[null,"保存"],"Switch":[null,"切换视图"],"Reload/Undo":[null,"重载/撤销"],"Duplicate":[null,"复制"],"Delete":[null,"删除"],"Previous":[null,"向前"],"Next":[null,"向后"],"Search":[null,"查找"],"View Logs...":[null,"查看日志..."],"Show revisions...":[null,"显示版本..."],"Close Tab":[null,"关闭标签"],"Attachment":[null,"附件文档"],"Note":[null,""],"Action":[null,"操作"],"Relate":[null,"关联"],"Print":[null,"打印"],"Export":[null,""],"Import":[null,""],"Launch action":[null,"执行操作"],"Open related records":[null,"打开关联项目"],"Print report":[null,"打印报表"],"This record has been modified\ndo you want to save it?":[null,"记录有改动, 是否保存?"],"Record saved.":[null,"保存成功."],"Working now on the duplicated record(s).":[null,"当前处理的是项目的副本."],"Are you sure to remove this record?":[null,"确定要删除此项吗?"],"Are you sure to remove those records?":[null,"确定要删除这些项目?"],"Records removed.":[null,"项目已成功删除"],"Records not removed.":[null,"项目未删除"],"You have to select one record.":[null,"选择需要操作的项目"],"ID:":[null,"标识:"],"Creation User:":[null,"创建者:"],"Creation Date:":[null,"创建日期:"],"Latest Modification by:":[null,"最近更改:"],"Latest Modification Date:":[null,"最近更改日期:"],"Model: ":[null,"模型:"],"Filters":[null,"筛选"],"Bookmarks":[null,"书签"],"Remove this bookmark":[null,"移除书签"],"Bookmark this filter":[null,"收藏筛选器"],"Bookmark Name:":[null,"书签名称:"],"True":[null,"True"],"False":[null,"False"],"Find":[null,"查找"],"ID":[null,"标识"],"Creation User":[null,"创建者"],"Creation Date":[null,"创建日期"],"Modification User":[null,"修改者"],"Modification Date":[null,"修改日期"],"\"%1\" is required":[null,"\"%1\" 是必填项"],"\"%1\" is not valid according to its domain":[null,"根据域设置,\"%1\" 不可用"],"The values of \"%1\" are not valid":[null,"无法获得\"%1\" 的值"],"Pre-validation":[null,"预校验"],"Translate":[null,""],"Cancel":[null,"取消"],"OK":[null,"确定"],"Edit":[null,""],"Fuzzy":[null,""],"You need to save the record before adding translations.":[null,""],"No other language available.":[null,""],"Show":[null,""],"Hide":[null,""],"Font":[null,"字体"],"Size":[null,"大小"],"Add":[null,"添加"],"Remove":[null,"删除"],"Open":[null,"打开"],"Undelete":[null,"回滚"],"Select":[null,"选择"],"%1%":[null,"%1%"],":":[null,":"],"More":[null,"更多"],"%1 (%2)":[null,""],"Select your action":[null,"选择一项操作"],"Your selection:":[null,"已选择:"],"Y":[null,"年"],"M":[null,"月"],"w":[null,"星期"],"d":[null,"日"],"h":[null,"时"],"m":[null,"分"],"s":[null,"秒"],"By: ":[null,""],"y":[null,"y"],"Yes":[null,"是"],"t":[null,"t"],"Message: ":[null,"信息:"],"Warning: ":[null,"警告:"],"Always ignore this warning.":[null,"下次不再提示."],"Do you want to proceed?":[null,"继续此项操作 ?"],"No":[null,"否"],"Confirmation: ":[null,"确认:"],"Concurrency Exception":[null,"并行操作异常"],"Write Concurrency Warning: ":[null,"同步操作警告:"],"This record has been modified while you were editing it.":[null,"当前数据已经被其他操作更改."],"Choose:":[null,"选择:"],"\"Cancel\" to cancel saving;":[null,"\"取消\" 不保存;"],"\"Compare\" to see the modified version;":[null," \"对比\" 查看变更的数据;"],"\"Write Anyway\" to save your current version.":[null," \"覆写\" 保存当前数据."],"Compare":[null,"对比"],"Write Anyway":[null,"覆写"],"Application Error":[null,"程序错误"],"Report Bug":[null,"报告Bug"],"Processing...":[null,""],"Download":[null,""],"Notes (%1)":[null,""],"Search %1":[null,""],"Revision":[null,"版本"],"All Fields":[null,""],"Clear":[null,""],"Fields Selected":[null,""],"CSV Parameters":[null,""],"Delimiter:":[null,""],"Quote Char:":[null,""],"Encoding:":[null,""],"Import from CSV":[null,""],"Auto-Detect":[null,""],"File to Import":[null,""],"Lines to Skip:":[null,""],"You must select an import file first":[null,""],"Error occured in loading the file":[null,""],"Error processing the file at field %1.":[null,""],"Error":[null,""],"Export to CSV":[null,""],"Predefined Exports":[null,""],"Save Export":[null,""],"Delete Export":[null,""],"Add Field Names":[null,""],"%1 (string)":[null,""],"What is the name of this export?":[null,""],"Override %1 definition?":[null,""],"Wizard":[null,"向导"]}
\ No newline at end of file
diff --git a/locale/zh_CN.po b/locale/zh_CN.po
index 34f3e4a..54c7132 100644
--- a/locale/zh_CN.po
+++ b/locale/zh_CN.po
@@ -2,7 +2,7 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=utf-8\n"
 
-# Generated by grunt-xgettext on Sat Nov 12 2016 00:09:11 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sun Apr 23 2017 17:34:31 GMT+0200 (CEST)
 msgid "Manage favorites"
 msgstr ""
 
@@ -23,17 +23,17 @@ msgstr "无法连接到服务器"
 msgid "Login"
 msgstr "登录"
 
+msgid "User name"
+msgstr ""
+
 msgid "Database"
 msgstr "服务标识:"
 
 msgid "Unable to reach the server."
 msgstr "无法连接到服务器."
 
-msgid "Toggle navigation"
-msgstr "切换导航"
-
-msgid "Menu"
-msgstr "菜单"
+msgid "Close"
+msgstr "关闭"
 
 msgid ""
 "The following action requires to close all tabs.\n"
@@ -42,54 +42,39 @@ msgstr ""
 "该操作需要关闭打开的项目\n"
 "是否继续?"
 
-msgid "Close"
-msgstr "关闭"
-
-msgid "New"
-msgstr "新建"
-
 msgid "Create a new record"
 msgstr "新建项目"
 
-msgid "Save"
-msgstr "保存"
-
 msgid "Save this record"
 msgstr "保存项目"
 
-msgid "Switch"
-msgstr "切换视图"
-
 msgid "Switch view"
 msgstr "切换视图"
 
 msgid "Reload"
 msgstr "重载"
 
-msgid "Previous"
-msgstr "向前"
-
 msgid "Previous Record"
 msgstr "前一项"
 
-msgid "Next"
-msgstr "向后"
-
 msgid "Next Record"
 msgstr "后一项"
 
-msgid "Attachment"
-msgstr "附件文档"
-
 msgid "Add an attachment to the record"
 msgstr "给当前项添加附件"
 
-msgid "Note"
-msgstr ""
-
 msgid "Add a note to the record"
 msgstr ""
 
+msgid "New"
+msgstr "新建"
+
+msgid "Save"
+msgstr "保存"
+
+msgid "Switch"
+msgstr "切换视图"
+
 msgid "Reload/Undo"
 msgstr "重载/撤销"
 
@@ -99,6 +84,12 @@ msgstr "复制"
 msgid "Delete"
 msgstr "删除"
 
+msgid "Previous"
+msgstr "向前"
+
+msgid "Next"
+msgstr "向后"
+
 msgid "Search"
 msgstr "查找"
 
@@ -111,6 +102,12 @@ msgstr "显示版本..."
 msgid "Close Tab"
 msgstr "关闭标签"
 
+msgid "Attachment"
+msgstr "附件文档"
+
+msgid "Note"
+msgstr ""
+
 msgid "Action"
 msgstr "操作"
 
@@ -179,12 +176,6 @@ msgstr "最近更改日期:"
 msgid "Model: "
 msgstr "模型:"
 
-msgid "Attachment(%1)"
-msgstr "附件(%1)"
-
-msgid "Note(%1)"
-msgstr ""
-
 msgid "Filters"
 msgstr "筛选"
 
@@ -257,6 +248,12 @@ msgstr ""
 msgid "No other language available."
 msgstr ""
 
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
 msgid "Font"
 msgstr "字体"
 
@@ -288,6 +285,10 @@ msgid "More"
 msgstr "更多"
 
 #, fuzzy
+msgid ": "
+msgstr ": "
+
+#, fuzzy
 msgid ", "
 msgstr ", "
 
@@ -392,10 +393,20 @@ msgstr "程序错误"
 msgid "Report Bug"
 msgstr "报告Bug"
 
+msgid "Processing..."
+msgstr ""
+
 #, fuzzy
 msgid "Create..."
 msgstr "新建..."
 
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
 #, fuzzy
 msgid "Attachments (%1)"
 msgstr "附件(%1)"
diff --git a/package.json b/package.json
index 47650bd..c0af292 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "tryton-sao",
   "title": "sao",
   "description": "Tryton webclient",
-  "version": "4.2.3",
+  "version": "4.4.0",
   "homepage": "http://www.tryton.org/",
   "author": {
     "name": "Tryton"
@@ -33,19 +33,12 @@
   ],
   "scripts": {
     "test": "./node_modules/.bin/grunt test",
-    "postinstall": "./node_modules/.bin/bower install --allow-root"
+    "postinstall": "./node_modules/.bin/bower install"
   },
   "devDependencies": {
-    "grunt": "^0.4",
-    "grunt-cli": "^0.1",
-    "grunt-contrib-concat": "^0.5",
-    "grunt-contrib-jshint": "^0.11",
-    "grunt-contrib-less": "^1.2",
     "grunt-contrib-nodeunit": "^0.4",
     "grunt-contrib-qunit": "^1.2",
-    "grunt-contrib-uglify": "^0.9",
     "grunt-contrib-watch": "^0.6",
-    "grunt-po2json": "^0.3",
     "grunt-shell": "^1.2",
     "grunt-xgettext": "^0.3"
   },
@@ -53,6 +46,13 @@
     "tryton"
   ],
   "dependencies": {
+    "grunt": "^0.4",
+    "grunt-cli": "^0.1",
+    "grunt-contrib-concat": "^0.5",
+    "grunt-contrib-jshint": "^0.11",
+    "grunt-contrib-uglify": "^0.9",
+    "grunt-contrib-less": "^1.2",
+    "grunt-po2json": "^0.3",
     "bower": "^1.7"
   }
 }
diff --git a/src/action.js b/src/action.js
index 4ffaa08..6eb1433 100644
--- a/src/action.js
+++ b/src/action.js
@@ -96,6 +96,7 @@
                 params.model = action.res_model || data.res_model;
                 params.res_id = action.res_id || data.res_id;
                 params.context_model = action.context_model;
+                params.context_domain = action.context_domain;
                 params.limit = action.limit;
                 params.icon = action['icon.rec_name'] || '';
 
@@ -197,31 +198,36 @@
             var name = result[3];
 
             // TODO direct print
-            var blob = new Blob([data],
-                {type: Sao.common.guess_mimetype(report_type)});
-            var blob_url = window.URL.createObjectURL(blob);
-            if (Sao.Action.report_blob_url) {
-                window.URL.revokeObjectURL(Sao.Action.report_blob_url);
-            }
-            Sao.Action.report_blob_url = blob_url;
-            window.open(blob_url);
+            var file_name = name + '.' + report_type;
+            Sao.common.download_file(data, file_name);
         });
     };
 
-    Sao.Action.execute = function(id, data, type, context) {
+    Sao.Action.execute = function(id, data, type, context, keyword) {
         if (!type) {
             Sao.rpc({
                 'method': 'model.ir.action.read',
                 'params': [[id], ['type'], context]
             }, Sao.Session.current_session).done(function(result) {
-                Sao.Action.execute(id, data, result[0].type, context);
+                Sao.Action.execute(id, data, result[0].type, context, keyword);
             });
         } else {
             Sao.rpc({
                 'method': 'model.' + type + '.search_read',
                 'params': [[['action', '=', id]], 0, 1, null, null, context]
             }, Sao.Session.current_session).done(function(result) {
-                Sao.Action.exec_action(result[0], data, context);
+                var action = result[0];
+                if (keyword) {
+                    var keywords = {
+                        'ir.action.report': 'form_report',
+                        'ir.action.wizard': 'form_action',
+                        'ir.action.act_window': 'form_relate'
+                    };
+                    if (!action.keyword) {
+                        action.keyword = keywords[type];
+                    }
+                }
+                Sao.Action.exec_action(action, data, context);
             });
         }
     };
diff --git a/src/board.js b/src/board.js
index c7613a8..b1322b5 100644
--- a/src/board.js
+++ b/src/board.js
@@ -175,11 +175,14 @@
 
     Sao.View.Board.Action = Sao.class_(Object, {
         init: function(attributes, context) {
+            if (context === undefined) {
+                context = {};
+            }
             var model, action_prm, act_window;
             var decoder, search_context, search_value;
 
             this.name = attributes.name;
-            this.context = context || {};
+            this.context = jQuery.extend({}, context);
 
             act_window = new Sao.Model('ir.action.act_window');
             this.action_prm = act_window.execute('get', [this.name],
diff --git a/src/common.js b/src/common.js
index 4bfebf1..9608c2b 100644
--- a/src/common.js
+++ b/src/common.js
@@ -2678,8 +2678,7 @@
         build_dialog: function(message, title, prm) {
             var dialog = Sao.common.WarningDialog._super.build_dialog.call(
                 this);
-            dialog.add_title(title);
-            dialog.body.append(jQuery('<div/>', {
+            var content = jQuery('<div/>', {
                 'class': 'alert alert-warning',
                 role: 'alert'
             }).append(jQuery('<span/>', {
@@ -2688,9 +2687,15 @@
             })).append(jQuery('<span/>', {
                 'class': 'sr-only'
             }).append(Sao.i18n.gettext('Warning: '))
-            ).append(jQuery('<span/>')
-                .append(message)
-                .css('white-space', 'pre-wrap')));
+            ).append(jQuery('<h4/>')
+                .append(title)
+                .css('white-space', 'pre-wrap'));
+            if (message) {
+                content.append(jQuery('<span/>')
+                    .append(message)
+                    .css('white-space', 'pre-wrap'));
+            }
+            dialog.body.append(content);
             jQuery('<button/>', {
                 'class': 'btn btn-primary',
                 'type': 'button'
@@ -2972,7 +2977,7 @@
             });
             this.el.append(jQuery('<span/>', {
                 'class': 'label label-info',
-                'text': 'Processing...'
+                'text': Sao.i18n.gettext('Processing...')
             }));
             this.el.hide();
             jQuery(function() {
@@ -3280,4 +3285,49 @@
             label.removeClass('editable required');
         }
     };
+
+    Sao.common.download_file = function(data, name) {
+        var type = Sao.common.guess_mimetype(
+            name ? name.split('.').pop() : undefined);
+        var blob = new Blob([data], {type: type});
+        var blob_url = window.URL.createObjectURL(blob);
+
+        var dialog = new Sao.Dialog(Sao.i18n.gettext('Download'));
+        var close = function() {
+            dialog.modal.modal('hide');
+        };
+        var a = jQuery('<a/>', {
+                'href': blob_url,
+                'download': name,
+                'text': name,
+                'target': '_blank'
+                }).appendTo(dialog.body)
+                .append(jQuery('<span/>', {
+                    'class': 'glyphicon glyphicon-download-alt'}))
+                .click(close);
+        var button = jQuery('<button/>', {
+            'class': 'btn btn-default',
+            'type': 'button'
+        }).append(Sao.i18n.gettext('Close')).click(close)
+            .appendTo(dialog.footer);
+        dialog.modal.on('shown.bs.modal', function() {
+            // Force the click trigger
+            a[0].click();
+        });
+        dialog.modal.modal('show');
+
+        dialog.modal.on('hidden.bs.modal', function() {
+            jQuery(this).remove();
+            window.URL.revokeObjectURL(this.blob_url);
+        });
+
+    };
+
+    Sao.common.ellipsize = function(string, length) {
+        if (string.length <= length) {
+            return string;
+        }
+        var ellipsis = Sao.i18n.gettext('...');
+        return string.slice(0, length - ellipsis.length) + ellipsis;
+    };
 }());
diff --git a/src/model.js b/src/model.js
index b4c0287..c71ad75 100644
--- a/src/model.js
+++ b/src/model.js
@@ -239,7 +239,7 @@
             if (modified) {
                 record._changed.id = true;
             }
-            if (!(record.group.parent) || (record.id < 0) || force_remove) {
+            if ((record.id < 0) || force_remove) {
                 this._remove(record);
             }
             record.group.changed();
@@ -294,7 +294,11 @@
                 deferreds.push(record.save());
             });
             if (!jQuery.isEmptyObject(this.record_deleted)) {
+                this.record_deleted.forEach(function(record) {
+                    this._remove(record);
+                }.bind(this));
                 deferreds.push(this.model.delete_(this.record_deleted));
+                this.record_deleted.splice(0, this.record_deleted.length);
             }
             return jQuery.when.apply(jQuery, deferreds);
         };
@@ -727,7 +731,6 @@
             var name, value;
             var rec_named_fields = ['many2one', 'one2one', 'reference'];
             var later = {};
-            var promises = [];
             var fieldnames = [];
             for (name in values) {
                 if (!values.hasOwnProperty(name)) {
@@ -769,17 +772,10 @@
                 this.model.fields[name].set(this, value);
                 this._loaded[name] = true;
             }
-            for (var fname in this.model.fields) {
-                var field = this.model.fields[fname];
-                if (field.description.autocomplete &&
-                        field.description.autocomplete.length > 0) {
-                    promises.push(this.do_autocomplete(fname));
-                }
-            }
             if (validate) {
-                promises.push(this.validate(fieldnames, true));
+                return this.validate(fieldnames, true);
             }
-            return jQuery.when.apply(jQuery, promises);
+            return jQuery.when();
         },
         get: function() {
             var value = {};
@@ -788,7 +784,8 @@
                     continue;
                 }
                 var field = this.model.fields[name];
-                if (field.description.readonly) {
+                if (field.description.readonly &&
+                        !(field instanceof Sao.field.One2Many)) {
                     continue;
                 }
                 if ((this._changed[name] === undefined) && this.id >= 0) {
@@ -825,16 +822,6 @@
             this.model.fields[name].set_client(this, value, force_change);
         },
         default_get: function(rec_name) {
-            var dfd = jQuery.Deferred();
-            var promises = [];
-            // Ensure promisses is filled before default_get is resolved
-            for (var fname in this.model.fields) {
-                var field = this.model.fields[fname];
-                if (field.description.autocomplete &&
-                        field.description.autocomplete.length > 0) {
-                    promises.push(this.do_autocomplete(fname));
-                }
-            }
             if (!jQuery.isEmptyObject(this.model.fields)) {
                 var context = this.get_context();
                 if (context.default_rec_name === undefined) {
@@ -842,7 +829,7 @@
                 }
                 var prm = this.model.execute('default_get',
                         [Object.keys(this.model.fields)], context);
-                prm.then(function(values) {
+                return prm.then(function(values) {
                     if (this.group.parent &&
                             this.group.parent_name in this.group.model.fields) {
                         var parent_field =
@@ -857,15 +844,10 @@
                                 this.group.parent.id;
                         }
                     }
-                    promises.push(this.set_default(values));
-                    jQuery.when.apply(jQuery, promises).then(function() {
-                        dfd.resolve(values);
-                    });
+                    return this.set_default(values);
                 }.bind(this));
-            } else {
-                dfd.resolve();
             }
-            return dfd;
+            return jQuery.when();
         },
         set_default: function(values, validate) {
             if (validate === undefined) {
@@ -1140,7 +1122,7 @@
                     if (fields && !~fields.indexOf(fname)) {
                         continue;
                     }
-                    if (field.get_state_attrs(this).readonly) {
+                    if (field.description.readonly) {
                         continue;
                     }
                     if (~exclude_fields.indexOf(fname)) {
diff --git a/src/rpc.js b/src/rpc.js
index 69a2e0e..b7bb019 100644
--- a/src/rpc.js
+++ b/src/rpc.js
@@ -63,7 +63,7 @@
                 } else if (data.error[0] == 'UserError') {
                     msg = data.error[1][0];
                     description = data.error[1][1];
-                    Sao.common.warning.run(msg, description)
+                    Sao.common.warning.run(description, msg)
                         .always(dfd.reject);
                     return;
                 } else if (data.error[0] == 'ConcurrencyException') {
diff --git a/src/sao.js b/src/sao.js
index b457fd0..c0cfacf 100644
--- a/src/sao.js
+++ b/src/sao.js
@@ -398,7 +398,8 @@ var Sao = {};
             'view_ids': view_ids,
             'domain': domain,
             'context': action_ctx,
-            'selection_mode': Sao.common.SELECTION_NONE
+            'selection_mode': Sao.common.SELECTION_NONE,
+            'limit': null
         });
         Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(form), 1);
         form.view_prm.done(function() {
diff --git a/src/sao.less b/src/sao.less
index faa83cc..6c283d9 100644
--- a/src/sao.less
+++ b/src/sao.less
@@ -1,15 +1,17 @@
 @import "variables";
+ at import "mixins";
 
-.navbar {
-    z-index: @zindex-navbar;
+#tablist > li > a > span {
+    display: inline-block;
+    max-width: 9em;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
 }
 
 .tab-form, .tab-board {
     & nav.toolbar {
         margin-bottom: 1px;
-        & ul.nav > li > a {
-            padding-right: 0px;
-        }
     }
     & nav.toolbar.affix {
         top: @navbar-height + 1px;
@@ -17,14 +19,9 @@
     }
 }
 
-.nav-tabs > li .close {
-    margin: -2px 0 0 10px;
-    font-size: 18px;
-}
-
 @media screen and (max-width: @screen-xs-max) {
     .tab-form, .tab-board {
-        .navbar-nav > li {
+        .navbar-header > ul > li {
             float: left;
             width: 50%;
         }
@@ -68,6 +65,7 @@ button {
             overflow: hidden;
             text-overflow: ellipsis;
             min-width: 30px;
+            text-align: center;
         }
         & > tbody > tr > td {
             cursor: pointer;
@@ -117,9 +115,9 @@ button {
 
 .form {
     width: 100%;
-    & > .form-container {
+    & > table.form-container {
         width: 100%;
-        & td {
+        & > tbody > tr > td {
             padding: 1px;
         }
     }
@@ -205,6 +203,9 @@ button {
 .column-integer, .column-float, .column-timedelta {
     text-align: right;
 }
+input.column-boolean, input.selection {
+    .center-block();
+}
 
 .form-boolean, .editabletree-boolean {
     & input[type=checkbox] {
@@ -225,6 +226,12 @@ button {
     margin-bottom: 0px;
 }
 
+.window-form {
+    & .window-form-toolbar {
+        text-align: right;
+    }
+}
+
 .csv {
     & .modal-dialog {
         & .column-fields {
@@ -248,10 +255,10 @@ button {
     table.responsive,
     table.responsive > thead,
     table.responsive > thead > tr,
-    table.responsive > thead > tr > th,
+    table.responsive > thead > tr > th:not(.invisible),
     table.responsive > tbody,
     table.responsive > tbody > tr,
-    table.responsive > tbody > tr > td {
+    table.responsive > tbody > tr > td:not(.invisible) {
         display: block !important;
     }
     table.responsive {
@@ -284,22 +291,27 @@ button {
             border: none;
             border-bottom: 1px solid #eee;
             position: relative;
-            padding-left: 30%;
         }
-        & > tbody > tr > td:before {
-            /* Now like a table header */
-            position: absolute;
-            /* Top/left values mimic padding */
-            top: 6px;
-            left: 6px;
-            width: 30%;
-            padding-right: 10px;
-            text-align: left;
-            font-weight: bold;
-            overflow: hidden;
-            text-overflow: ellipsis;
-            /* Label */
-            content: attr(data-title);
+        & > tbody > tr {
+            & > td:before {
+                /* Now like a table header */
+                position: absolute;
+                /* Top/left values mimic padding */
+                top: 6px;
+                left: 6px;
+                padding-right: 10px;
+                text-align: left;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                /* Label */
+                content: attr(data-title);
+            }
+            & > td.required:before {
+                font-weight: bold;
+            }
+            & > td.editable:before {
+                font-style: italic;
+            }
         }
     }
 }
diff --git a/src/screen.js b/src/screen.js
index 8b423c1..9e4642d 100644
--- a/src/screen.js
+++ b/src/screen.js
@@ -489,7 +489,7 @@
                     jQuery('<div/>', {
                         'class': 'col-sm-8'
                     }).append(input).appendTo(form_group);
-                    this.search_form.fields.push([field.string, entry]);
+                    this.search_form.fields.push([field.string, entry, input]);
                 }
 
                 jQuery('<button/>', {
@@ -515,7 +515,7 @@
                             fentry.val('');
                     }
                 }
-                this.search_form.fields[0][1].focus();
+                this.search_form.fields[0][2].focus();
             }
         }
     });
@@ -622,7 +622,6 @@
             this.model_name = model_name;
             this.model = new Sao.Model(model_name, attributes);
             this.attributes = jQuery.extend({}, attributes);
-            this.attributes.limit = this.attributes.limit || Sao.config.limit;
             this.view_ids = jQuery.extend([], attributes.view_ids);
             this.view_to_load = jQuery.extend([],
                 attributes.mode || ['tree', 'form']);
@@ -634,8 +633,13 @@
             this.current_view = null;
             this.current_record = null;
             this.domain = attributes.domain || [];
+            this.context_domain = attributes.context_domain;
             this.size_limit = null;
-            this.limit = attributes.limit || Sao.config.limit;
+            if (this.attributes.limit === undefined) {
+                this.limit = Sao.config.limit;
+            } else {
+                this.limit = attributes.limit;
+            }
             this.offset = 0;
             this.order = this.default_order = attributes.order;
             var access = Sao.common.MODELACCESS.get(model_name);
@@ -809,6 +813,10 @@
             }
 
             var domain = this.search_domain(search_string, true);
+            if (this.context_domain) {
+                var decoder = new Sao.PYSON.Decoder(this.context);
+                domain = ['AND', domain, decoder.decode(this.context_domain)];
+            }
             var tab_domain = this.screen_container.get_tab_domain();
             if (!jQuery.isEmptyObject(tab_domain)) {
                 domain = ['AND', domain, tab_domain];
@@ -828,7 +836,8 @@
             grp_prm.done(this.display.bind(this));
             jQuery.when(grp_prm, count_prm).done(function(group, count) {
                 this.screen_container.but_next.prop('disabled',
-                        !(group.length == this.limit &&
+                        !(this.limit !== undefined &&
+                            group.length == this.limit &&
                             count > this.limit + this.offset));
             }.bind(this));
             this.screen_container.but_prev.prop('disabled', this.offset <= 0);
@@ -912,10 +921,10 @@
             this.tree_states_done = [];
             this.group = group;
             this.model = group.model;
-            if (jQuery.isEmptyObject(group)) {
-                this.set_current_record(null);
-            } else {
+            if (group && group.length) {
                 this.set_current_record(group[0]);
+            } else {
+                this.set_current_record(null);
             }
             this.group.add_fields(fields);
         },
@@ -947,7 +956,7 @@
             var deferreds = [];
             if (this.current_record &&
                     ~this.current_record.group.indexOf(this.current_record)) {
-            } else if (!jQuery.isEmptyObject(this.group) &&
+            } else if (this.group && this.group.length &&
                     (this.current_view.view_type != 'calendar')) {
                 this.current_record = this.group[0];
             } else {
@@ -1124,7 +1133,7 @@
             var current_record = this.current_record;
             if (!current_record) {
                 if ((this.current_view.view_type == 'tree') &&
-                        (!jQuery.isEmptyObject(this.group))) {
+                        this.group && this.group.length) {
                     this.set_current_record(this.group[0]);
                 } else {
                     return jQuery.when();
@@ -1135,12 +1144,15 @@
             var path = current_record.get_path(this.group);
             var prm = jQuery.Deferred();
             if (this.current_view.view_type == 'tree') {
-                prm = this.group.save();
+                prm = this.group.save().then(function() {
+                    return this.current_record;
+                }.bind(this));
             } else {
                 current_record.validate(fields).then(function(validate) {
                     if (validate) {
-                        current_record.save().then(
-                            prm.resolve, prm.reject);
+                        current_record.save().then(function() {
+                            prm.resolve(current_record);
+                        }, prm.reject);
                     } else {
                         this.current_view.display().done(
                                 this.set_cursor.bind(this));
@@ -1149,16 +1161,15 @@
                 }.bind(this));
             }
             var dfd = jQuery.Deferred();
-            prm = prm.then(function() {
-                if (path && current_record.id) {
+            prm.then(function(current_record) {
+                if (path && current_record && current_record.id) {
                     path.splice(-1, 1,
                             [path[path.length - 1][0], current_record.id]);
                 }
                 return this.group.get_by_path(path).then(function(record) {
                     this.set_current_record(record);
                 }.bind(this));
-            }.bind(this));
-            prm.then(function() {
+            }.bind(this)).then(function() {
                 this.display().always(dfd.resolve);
             }.bind(this), function() {
                 this.display().always(dfd.reject);
@@ -1386,11 +1397,15 @@
             });
         },
         search_prev: function(search_string) {
-            this.offset -= this.limit;
+            if (this.limit) {
+                this.offset -= this.limit;
+            }
             this.search_filter(search_string);
         },
         search_next: function(search_string) {
-            this.offset += this.limit;
+            if (this.limit) {
+                this.offset += this.limit;
+            }
             this.search_filter(search_string);
         },
         invalid_message: function(record) {
@@ -1493,7 +1508,7 @@
                         model: this.model_name,
                         id: this.current_record.id,
                         ids: ids
-                    }, null, this.context);
+                    }, null, this.context, true);
                 }
             };
 
diff --git a/src/session.js b/src/session.js
index 054d657..be7e0b2 100644
--- a/src/session.js
+++ b/src/session.js
@@ -93,7 +93,7 @@
         dialog.login_input = jQuery('<input/>', {
             'class': 'form-control',
             'id': 'login-login',
-            'placeholder': Sao.i18n.gettext('Login')
+            'placeholder': Sao.i18n.gettext('User name')
         });
         dialog.body.append(jQuery('<div/>', {
             'class': 'form-group'
@@ -108,7 +108,7 @@
         }).append(jQuery('<label/>', {
             'class': 'control-label',
             'for': 'login-login'
-        }).append(Sao.i18n.gettext('Login')))
+        }).append(Sao.i18n.gettext('User name')))
         .append(dialog.login_input)
         );
         dialog.button = jQuery('<button/>', {
diff --git a/src/tab.js b/src/tab.js
index 2c7e347..17418b7 100644
--- a/src/tab.js
+++ b/src/tab.js
@@ -8,6 +8,7 @@
             Sao.Tab.tabs.push(this);
             this.buttons = {};
             this.id = 'tab-' + Sao.Tab.counter++;
+            this.name = '';
             this.name_el = jQuery('<span/>');
         },
         create_tabcontent: function() {
@@ -16,7 +17,7 @@
             });
 
             var toolbar = this.create_toolbar().appendTo(this.el);
-            this.title = toolbar.find('a.navbar-brand');
+            this.title = toolbar.find('.title');
 
             this.content = jQuery('<div/>').appendTo(this.el);
 
@@ -50,84 +51,90 @@
             }.bind(this));
         },
         create_toolbar: function() {
-            var toolbar = jQuery(
-                    '<nav class="navbar-default toolbar" role="navigation">' +
-                    '<div class="container-fluid">' +
-                    '<div class="navbar-header">' +
-                    '<a class="navbar-brand" href="#"></a>' +
-                    '<button type="button" class="navbar-toggle collapsed" ' +
-                    'data-toggle="collapse" ' +
-                    'data-target="#navbar-' + this.id + '">' +
-                    '<span class="sr-only">' +
-                    Sao.i18n.gettext('Toggle navigation') +
-                    '</span>' +
-                    '<span class="icon-bar"></span>' +
-                    '<span class="icon-bar"></span>' +
-                    '<span class="icon-bar"></span>' +
-                    '</div>' +
-                    '<div class="collapse navbar-collapse" ' +
-                    'id="navbar-' + this.id + '">' +
-                    '<ul class="nav navbar-nav">' +
-                    '<li class="dropdown">' +
-                    '<a href="#" class="dropdown-toggle" ' +
-                    'data-toggle="dropdown" role="button" ' +
-                    'aria-expanded="false">' +
-                    '<span class="glyphicon glyphicon-wrench" ' +
-                    'aria-hidden="true"></span>' +
-                    '<span class="visible-xs">' +
-                    Sao.i18n.gettext('Menu') +
-                    '</span>' +
-                    '<span class="caret"></span>' +
-                    '</a>' +
-                    '<ul class="dropdown-menu" role="menu">' +
-                    '</ul>' +
-                    '</li>' +
-                    '</ul>' +
-                    '</div>' +
-                    '</div>' +
-                    '</nav>'
-                    );
+            var toolbar = jQuery('<nav/>', {
+                'class': 'toolbar navbar navbar-default',
+                'role': 'toolbar'
+            }).append(jQuery('<div/>', {
+                'class': 'container-fluid'
+            }).append(jQuery('<div/>', {
+                'class': 'dropdown navbar-header navbar-left'
+            }).append(jQuery('<a/>', {
+                'href': "#",
+                'class': "navbar-brand dropdown-toggle",
+                'data-toggle': 'dropdown',
+                'role': 'button',
+                'aria-expanded': false,
+                'aria-haspopup': true
+            }).append(jQuery('<span/>', {
+                'class': 'title'
+            })).append(jQuery('<span/>', {
+                'class': 'caret'
+            }))).append(jQuery('<ul/>', {
+                'class': 'dropdown-menu',
+                'role': 'menu'
+            })).append(jQuery('<button/>', {
+                'type': 'button',
+                'class': 'close visible-xs visible-sm',
+                'aria-label': Sao.i18n.gettext('Close')
+            }).append(jQuery('<span/>', {
+                'aria-hidden': true
+            }).append('×')).click(function() {
+                this.close();
+            }.bind(this)))).append(jQuery('<div/>', {
+                'class': 'btn-toolbar navbar-right',
+                'role': 'toolbar'
+            })));
             var wrapper = jQuery('<div/>', {
-                'class': 'nav-wrapper'
+                'class': 'toolbar-wrapper'
             }).append(toolbar);
             this.set_menu(toolbar.find('ul[role*="menu"]'));
 
+            var group;
             var add_button = function(tool) {
-                var item = jQuery('<li/>', {
-                    'role': 'presentation'
-                }).appendTo(toolbar.find('.navbar-collapse > ul'));
-                this.buttons[tool[0]] = jQuery('<a/>', {
-                    'role': 'menuitem',
-                    'href': '#',
+                if (!tool) {
+                    group = null;
+                    return;
+                }
+                if (!group) {
+                    group = jQuery('<div/>', {
+                        'class': 'btn-group',
+                        'role': 'group'
+                    }).appendTo(toolbar.find('.btn-toolbar'));
+                }
+                this.buttons[tool[0]] = jQuery('<button/>', {
+                    'type': 'button',
+                    'class': 'btn btn-default navbar-btn',
+                    'title': tool[2],
                     'id': tool[0]
                 })
                 .append(jQuery('<span/>', {
                     'class': 'glyphicon ' + tool[1],
                     'aria-hidden': 'true'
                 }))
-                .append(jQuery('<span/>', {
-                    'class': 'hidden-sm'
-                }).append(' ' + tool[2]))
-                .appendTo(item);
-                if (tool[4]) {
-                    this.buttons[tool[0]].click(this[tool[4]].bind(this));
+                .appendTo(group)
+                .data('toggle', 'tooltip')
+                .data('placement', 'bottom')
+                .tooltip();
+                if (tool[3]) {
+                    this.buttons[tool[0]].click(this[tool[3]].bind(this));
                 } else {
                     item.addClass('disabled');
                 }
-                // TODO tooltip
             };
             this.toolbar_def().forEach(add_button.bind(this));
+            toolbar.find('.btn-toolbar > .btn-group').last().addClass(
+                    'hidden-xs');
             var tabs = jQuery('#tabs');
             toolbar.affix({
                 'target': tabs.parent(),
                 'offset': {
                     'top': function() {
-                        return tabs.find('.nav-tabs').height();
+                        return jQuery('#main_navbar').height();
                     }
                 }
             });
             toolbar.on('affix.bs.affix', function() {
-                wrapper.height(toolbar.height());
+                wrapper.height(jQuery('#main_navbar').height());
             });
             toolbar.on('affix-top.bs.affix affix-bottom.bs.affix',
                     function() {
@@ -144,15 +151,16 @@
         },
         close: function() {
             var tabs = jQuery('#tabs');
-            var tab = tabs.find('#nav-' + this.id);
+            var tablist = jQuery('#tablist');
+            var tab = tablist.find('#nav-' + this.id);
             var content = tabs.find('#' + this.id);
-            tabs.find('a[href="#' + this.id + '"]').tab('show');
+            tablist.find('a[href="#' + this.id + '"]').tab('show');
             return this._close_allowed().then(function() {
-                var next = tab.next();
+                var next = tab.nextAll('li').first();
                 if (!next.length) {
-                    next = tab.prev();
+                    next = tab.prevAll('li').first();
                 }
-                tab.remove();
+                tab.tooltip('destroy').remove();
                 content.remove();
                 Sao.Tab.tabs.splice(Sao.Tab.tabs.indexOf(this), 1);
                 if (next) {
@@ -165,7 +173,9 @@
             return jQuery.when();
         },
         set_name: function(name) {
-            this.name_el.text(name);
+            this.name = name;
+            this.name_el.text(Sao.common.ellipsize(name, 20));
+            this.name_el.parents('li').first().attr('title', name).tooltip();
         }
     });
 
@@ -217,7 +227,7 @@
         return jQuery.when();
     };
     Sao.Tab.tabs.get_current = function() {
-        var tabs = jQuery('#tabs > ul');
+        var tabs = jQuery('#tablist');
         var i = tabs.find('li').index(tabs.find('li.active'));
         return Sao.Tab.tabs[i];
     };
@@ -241,6 +251,8 @@
 
     Sao.Tab.add = function(tab) {
         var tabs = jQuery('#tabs');
+        var tablist = jQuery('#tablist');
+        var tabcontent = jQuery('#tabcontent');
         var tab_link = jQuery('<a/>', {
             'aria-controls': tab.id,
             'role': 'tab',
@@ -259,15 +271,17 @@
         .append(tab.name_el);
         jQuery('<li/>', {
             'role': 'presentation',
+            'data-toggle': 'tooltip',
+            'data-placement': 'bottom',
             id: 'nav-' + tab.id
         }).append(tab_link)
-        .appendTo(tabs.find('> .nav-tabs'));
+        .appendTo(tablist);
         jQuery('<div/>', {
             role: 'tabpanel',
             'class': 'tab-pane',
             id: tab.id
         }).html(tab.el)
-        .appendTo(tabs.find('> .tab-content'));
+        .appendTo(tabcontent);
         tab_link.on('shown.bs.tab', function() {
             Sao.View.resize(tab.el);
         });
@@ -315,28 +329,22 @@
         toolbar_def: function() {
             return [
                 ['new', 'glyphicon-edit',
-                Sao.i18n.gettext('New'),
                 Sao.i18n.gettext('Create a new record'), 'new_'],
                 ['save', 'glyphicon-save',
-                Sao.i18n.gettext('Save'),
                 Sao.i18n.gettext('Save this record'), 'save'],
                 ['switch', 'glyphicon-list-alt',
-                Sao.i18n.gettext('Switch'),
                 Sao.i18n.gettext('Switch view'), 'switch_'],
                 ['reload', 'glyphicon-refresh',
-                Sao.i18n.gettext('Reload'),
                 Sao.i18n.gettext('Reload'), 'reload'],
+                null,
                 ['previous', 'glyphicon-chevron-left',
-                Sao.i18n.gettext('Previous'),
                 Sao.i18n.gettext('Previous Record'), 'previous'],
                 ['next', 'glyphicon-chevron-right',
-                Sao.i18n.gettext('Next'),
                 Sao.i18n.gettext('Next Record'), 'next'],
+                null,
                 ['attach', 'glyphicon-paperclip',
-                Sao.i18n.gettext('Attachment'),
                 Sao.i18n.gettext('Add an attachment to the record'), 'attach'],
                 ['note', 'glyphicon-comment',
-                Sao.i18n.gettext('Note'),
                 Sao.i18n.gettext('Add a note to the record'), 'note']
             ];
         },
@@ -377,46 +385,54 @@
             prm.done(function(toolbars) {
                 [
                 ['action', 'glyphicon-cog',
-                    Sao.i18n.gettext('Action'),
                     Sao.i18n.gettext('Launch action')],
                 ['relate', 'glyphicon-share-alt',
-                     Sao.i18n.gettext('Relate'),
                      Sao.i18n.gettext('Open related records')],
                 ['print', 'glyphicon-print',
-                     Sao.i18n.gettext('Print'),
                      Sao.i18n.gettext('Print report')]
                 ].forEach(function(menu_action) {
-                    var button = jQuery('<li/>', {
-                        'class': 'dropdown'
+                    var button = jQuery('<div/>', {
+                        'class': 'btn-group',
+                        'role': 'group'
                     })
-                    .append(jQuery('<a/>', {
-                        href: '#',
-                        id: menu_action[0],
-                        'class': 'dropdown-toggle',
+                    .append(jQuery('<button/>', {
+                        'type': 'button',
+                        'class': 'btn btn-default navbar-btn dropdown-toggle',
                         'data-toggle': 'dropdown',
-                        role: 'button',
-                        'aria-expanded': 'false'
+                        'aria-expanded': false,
+                        'aria-haspopup': true,
+                        'title': menu_action[2],
+                        'id': menu_action[0],
+                        'disabled': !toolbars[menu_action[0]].length
                     })
                         .append(jQuery('<span/>', {
                             'class': 'glyphicon ' + menu_action[1],
                             'aria-hidden': 'true'
                         }))
                         .append(jQuery('<span/>', {
-                            'class': 'hidden-sm'
-                        }).append(' ' + menu_action[2] + ' '))
-                        .append(jQuery('<span/>', {
                             'class': 'caret'
-                        })))
+                        }))
+                        .data('toggle', 'tooltip')
+                        .data('placement', 'bottom')
+                        .tooltip())
                     .append(jQuery('<ul/>', {
                         'class': 'dropdown-menu',
-                        role: 'menu',
+                        'role': 'menu',
                         'aria-labelledby': menu_action[0]
                     }))
-                    .appendTo(toolbar.find('.navbar-collapse > ul'));
+                    .appendTo(toolbar.find('.btn-toolbar > .btn-group').last());
                     buttons[menu_action[0]] = button;
+                    var dropdown = button
+                        .on('show.bs.dropdown', function() {
+                            jQuery(this).parents('.btn-group').removeClass(
+                                    'hidden-xs');
+                        }).on('hide.bs.dropdown', function() {
+                            jQuery(this).parents('.btn-group').addClass(
+                                    'hidden-xs');
+                        });
                     var menu = button.find('ul[role*="menu"]');
                     if (menu_action[0] == 'action') {
-                        button.find('a').click(function() {
+                        button.click(function() {
                             menu.find('.action_button').remove();
                             var buttons = screen.get_buttons();
                             buttons.forEach(function(button) {
@@ -710,9 +726,9 @@
                 var time_format = '%H:%M:%S.%f';
                 revision = Sao.common.format_datetime(date_format, time_format,
                         revision);
-                label = this.name_el.text() + ' @ '+ revision;
+                label = this.name + ' @ '+ revision;
             } else {
-                label = this.name_el.text();
+                label = this.name;
             }
             this.title.html(label);
             this.set_buttons_sensitive(revision);
@@ -756,8 +772,13 @@
             }
         },
         attachment_count: function(count) {
-            var label = Sao.i18n.gettext('Attachment(%1)', count);
-            this.buttons.attach.text(label);
+            var badge = this.buttons.attach.find('.badge');
+            if (!badge.length) {
+                badge = jQuery('<span/>', {
+                    'class': 'badge'
+                }).appendTo(this.buttons.attach);
+            }
+            badge.text(count);
             var record_id = this.screen.get_id();
             this.buttons.attach.prop('disabled',
                 record_id < 0 || record_id === null);
@@ -781,8 +802,13 @@
             }
         },
         _unread_note: function(unread) {
-            var label = Sao.i18n.gettext('Note(%1)', unread);
-            this.buttons.note.text(label);
+            var badge = this.buttons.note.find('.badge');
+            if (!badge.length) {
+                badge = jQuery('<span/>', {
+                    'class': 'badge'
+                }).appendTo(this.buttons.note);
+            }
+            badge.text(unread);
             var record_id = this.screen.get_id();
             this.buttons.note.prop('disabled',
                     record_id < 0 || record_id === null);
@@ -792,20 +818,17 @@
         },
         action: function() {
             window.setTimeout(function() {
-                this.buttons.action.find('ul.dropdown-menu')
-                    .dropdown('toggle');
+                this.buttons.action.find('button').click();
             }.bind(this));
         },
         relate: function() {
             window.setTimeout(function() {
-                this.buttons.relate.find('ul.dropdown-menu')
-                    .dropdown('toggle');
+                this.buttons.relate.find('button').click();
             }.bind(this));
         },
         print: function() {
             window.setTimeout(function() {
-                this.buttons.print.find('ul.dropdown-menu')
-                    .dropdown('toggle');
+                this.buttons.print.find('button').click();
             }.bind(this));
         },
         export: function(){
@@ -813,7 +836,8 @@
                 this.screen.current_view.selected_records().map(function(r) {
                     return r.id;
                 }),
-                this.screen.current_view.get_fields());
+                this.screen.current_view.get_fields(),
+                this.screen.context);
         },
         import: function(){
             new Sao.Window.Import(this.screen);
@@ -855,7 +879,6 @@
         toolbar_def: function() {
             return [
                 ['reload', 'glyphicon-refresh',
-                Sao.i18n.gettext('Reload'),
                 Sao.i18n.gettext('Reload'), 'reload']
             ];
         },
diff --git a/src/view/form.js b/src/view/form.js
index 81298dd..b94425d 100644
--- a/src/view/form.js
+++ b/src/view/form.js
@@ -458,6 +458,7 @@ function eval_pyson(value){
     Sao.View.Form.Container = Sao.class_(Object, {
         init: function(col) {
             if (col === undefined) col = 4;
+            if (col < 0) col = 0;
             this.col = col;
             this.el = jQuery('<table/>', {
                 'class': 'form-container responsive responsive-noheader'
@@ -480,14 +481,16 @@ function eval_pyson(value){
             if (xfill === undefined) xfill = 1;
             var xexpand = attributes.xexpand;
             if (xexpand === undefined) xexpand = 1;
-            var len = 0;
             var row = this.row();
-            row.children().map(function(i, e) {
-                len += Number(jQuery(e).attr('colspan') || 1);
-            });
-            if (len + colspan > this.col) {
-                this.add_row();
-                row = this.row();
+            if (this.col > 0) {
+                var len = 0;
+                row.children().map(function(i, e) {
+                    len += Number(jQuery(e).attr('colspan') || 1);
+                });
+                if (len + colspan > this.col) {
+                    this.add_row();
+                    row = this.row();
+                }
             }
             var el;
             if (widget) {
@@ -1191,7 +1194,7 @@ function eval_pyson(value){
                 'type': 'text',
                 'class': 'form-control input-sm'
             }).appendTo(this.group);
-            if (attributes.autocomplete) {
+            if (!jQuery.isEmptyObject(attributes.autocomplete)) {
                 this.datalist = jQuery('<datalist/>').appendTo(this.el);
                 this.datalist.uniqueId();
                 this.input.attr('list', this.datalist.attr('id'));
@@ -1225,15 +1228,22 @@ function eval_pyson(value){
             Sao.View.Form.Char._super.display.call(this, record, field);
             if (this.datalist) {
                 this.datalist.children().remove();
-                var selection = [];
-                if (record) {
-                    selection = record.autocompletion[this.field_name] || [];
+                var set_autocompletion = function() {
+                    var selection = [];
+                    if (record) {
+                        selection = record.autocompletion[this.field_name] || [];
+                    }
+                    selection.forEach(function(e) {
+                        jQuery('<option/>', {
+                            'value': e
+                        }).appendTo(this.datalist);
+                    }.bind(this));
+                }.bind(this);
+                if (record && !(this.field_name in record.autocompletion)) {
+                    record.do_autocomplete(this.field_name).done(set_autocompletion);
+                } else {
+                    set_autocompletion();
                 }
-                selection.forEach(function(e) {
-                    jQuery('<option/>', {
-                        'value': e
-                    }).appendTo(this.datalist);
-                }.bind(this));
             }
 
             // Set size
@@ -1273,6 +1283,32 @@ function eval_pyson(value){
             Sao.View.Form.Password._super.init.call(this, field_name, model,
                 attributes);
             this.input.prop('type', 'password');
+            this.button = jQuery('<button/>', {
+                'class': 'btn btn-default btn-sm form-control',
+                'type': 'button'
+            }).appendTo(jQuery('<span/>', {
+                'class': 'input-group-btn'
+            }).appendTo(this.group));
+            this._set_password_label();
+            this.button.click(this.toggle_visibility.bind(this));
+
+        },
+        toggle_visibility: function() {
+            if (this.input.prop('type') == 'password') {
+                this.input.prop('type', 'text');
+                this.input.attr('autocomplete', 'off');
+            } else {
+                this.input.prop('type', 'password');
+                this.input.removeAttr('autocomplete');
+            }
+            this._set_password_label();
+        },
+        _set_password_label: function() {
+            if (this.input.prop('type') == 'password') {
+                this.button.text(Sao.i18n.gettext('Show'));
+            } else {
+                this.button.text(Sao.i18n.gettext('Hide'));
+            }
         }
     });
 
@@ -2487,6 +2523,7 @@ function eval_pyson(value){
                 views_preload: attributes.views || {},
                 row_activate: this.activate.bind(this),
                 exclude_field: attributes.relation_field || null,
+                limit: null,
                 pre_validate: attributes.pre_validate
             });
             this.screen.pre_validate = attributes.pre_validate == 1;
@@ -2594,7 +2631,6 @@ function eval_pyson(value){
                     this.screen.domain = domain;
                 }
                 this.screen.size_limit = size_limit;
-                this.screen.attributes.readonly = this._readonly;
                 this.screen.display();
             }.bind(this));
         },
@@ -2910,7 +2946,8 @@ function eval_pyson(value){
                 mode: ['tree'],
                 view_ids: (attributes.view_ids || '').split(','),
                 views_preload: attributes.views || {},
-                row_activate: this.activate.bind(this)
+                row_activate: this.activate.bind(this),
+                limit: null
             });
             this.prm = this.screen.switch_view('tree').done(function() {
                 this.content.append(this.screen.screen_container.el);
@@ -2930,9 +2967,15 @@ function eval_pyson(value){
                     this._required);
         },
         _set_button_sensitive: function() {
-            var size_limit = false;
-            if (this.record() && this.field()) {
-                // TODO
+            var size_limit = false,
+                record = this.record(),
+                field = this.field();
+            if (record && field) {
+                var field_size = record.expr_eval(this.attributes.size);
+                var m2m_size = field.get_eval(record).length;
+                size_limit = (((field_size !== undefined) &&
+                            (field_size !== null)) &&
+                        (m2m_size >= field_size >= 0));
             }
 
             this.entry.prop('disabled', this._readonly);
@@ -3209,13 +3252,12 @@ function eval_pyson(value){
                 prm = jQuery.when(field.get(record));
             }
             prm.done(function(data) {
-                var blob = new Blob([data], {type: mimetype});
-                var blob_url = window.URL.createObjectURL(blob);
-                if (this.blob_url) {
-                    window.URL.revokeObjectURL(this.blob_url);
+                var name;
+                var field = this.filename_field();
+                if (field) {
+                    name = field.get(this.record());
                 }
-                this.blob_url = blob_url;
-                window.open(blob_url);
+                Sao.common.download_file(data, name);
             }.bind(this));
         },
         clear: function() {
@@ -3986,7 +4028,7 @@ function eval_pyson(value){
             return value;
         },
         set_value: function(value) {
-            this.date.data('DateTimePicker').date(value);
+            this.input.data('DateTimePicker').date(value);
         }
     });
 
diff --git a/src/view/graph.js b/src/view/graph.js
index 2888160..9546132 100644
--- a/src/view/graph.js
+++ b/src/view/graph.js
@@ -36,6 +36,7 @@
                         for (j=0, c_len=child.children.length; j < c_len; j++) {
                             xfield = get_attributes(child.children[j]);
                             field = this.screen.model.fields[xfield.name];
+                            xfield.type = field.description.type;
                             if (!(xfield.string || '')) {
                                 xfield.string = field.description.string;
                             }
@@ -109,6 +110,10 @@
                 return function () {
                     record = group[index];
                     var x = record.field_get_client(this.xfield.name);
+                    // c3 does not support moment
+                    if (x && (x.isDate || x.isDateTime)) {
+                        x = x.toDate();
+                    }
                     data.columns[0][index + 1] = x;
                     this._add_id(x, record.id);
 
@@ -165,13 +170,10 @@
             });
         },
         _add_id: function(key, id) {
-            // c3 do not use the moment instance but its date repr when calling
-            // onclick
-            var id_x = (key.isDate || key.isDateTime) ? key._d : key;
-            if (!(id_x in this.ids)) {
-                this.ids[id_x] = [];
+            if (!(key in this.ids)) {
+                this.ids[key] = [];
             }
-            this.ids[id_x].push(id);
+            this.ids[key].push(id);
         },
         display: function(group) {
             var update_prm = this.update_data(group);
@@ -189,22 +191,12 @@
             c3_config.data.x = 'labels';
             c3_config.data.onclick = this.action.bind(this);
 
-            var i, len;
-            var found, labels;
-            for (i = 0, len = data.columns.length; i < len; i++) {
-                labels = data.columns[i];
-                if (labels[0] == 'labels') {
-                    found = true;
-                    break;
-                }
-            }
-            if (found && (labels.length > 1) &&
-                    (labels[1] && (labels[1].isDateTime || labels[1].isDate)))
-            {
+            var type = this.xfield.type;
+            if ((type == 'date') || (type == 'datetime')) {
                 var format_func, date_format, time_format;
                 date_format = this.view.screen.context.date_format || '%x';
                 time_format = '%X';
-                if (labels[1].isDateTime) {
+                if (type == 'datetime') {
                     format_func = function(dt) {
                         return Sao.common.format_datetime(date_format,
                                 time_format, moment(dt));
@@ -222,14 +214,25 @@
                         }
                     }
                 };
-            }
-            else {
+            } else {
                 c3_config.axis = {
                     x: {
                         type: 'category',
                     }
                 };
             }
+            var colors = {};
+            for (var i = 0; i < this.yfields.length; i++) {
+                var field = this.yfields[i];
+                if (field.color) {
+                    colors[field.name] = field.color;
+                }
+            }
+            c3_config.data.color = function(color, column) {
+                // column is an object when called for legend
+                var name = column.id || column;
+                return colors[name] || color;
+            };
             return c3_config;
         },
         action: function(data, element) {
@@ -284,12 +287,12 @@
             // Pie chart do not support axis definition.
             delete config.axis;
             delete config.data.x;
-            var format_func, date_format, datetime_format;
-            if ((labels.length > 0) &&
-                    (labels[0].isDateTime || labels[0].isDate)) {
-                date_format = this.view.screen.context.date_format || '%x';
-                datetime_format = date_format + ' %X';
-                if (labels[1].isDateTime) {
+            var format_func;
+            var type = this.xfield.type;
+            if ((type == 'date') || (type == 'datetime')) {
+                var date_format = this.view.screen.context.date_format || '%x';
+                var datetime_format = date_format + ' %X';
+                if (type == 'datetime') {
                     format_func = function(dt) {
                         return Sao.common.format_datetime(datetime_format, dt);
                     };
@@ -314,20 +317,17 @@
             return config;
         },
         _add_id: function(key, id) {
-            var id_x = key;
-            if (key.isDateTime || key.isDate) {
+            var type = this.xfield.type;
+            if ((type == 'date') || (type == 'datetime')) {
                 var date_format = this.view.screen.context.date_format || '%x';
                 var datetime_format = date_format + ' %X';
-                if (key.isDateTime) {
-                    id_x = Sao.common.format_datetime(datetime_format, key);
+                if (type == 'datetime') {
+                    key = Sao.common.format_datetime(datetime_format, key);
                 } else {
-                    id_x = Sao.common.format_date(date_format, key);
+                    key = Sao.common.format_date(date_format, key);
                 }
             }
-            if (!(id_x in this.ids)) {
-                this.ids[id_x] = [];
-            }
-            this.ids[id_x].push(id);
+            Sao.View.Graph.Pie._super._add_id.call(this, key, id);
         },
         _action_key: function(data) {
             return data.id;
diff --git a/src/view/tree.js b/src/view/tree.js
index 503d03f..25ceb93 100644
--- a/src/view/tree.js
+++ b/src/view/tree.js
@@ -99,6 +99,11 @@
                         label.addClass('editable');
                     }
                 }
+                if (column.attributes.help) {
+                    label.data('toggle', 'tooltip');
+                    label.attr('title', column.attributes.help);
+                    label.tooltip();
+                }
                 if (column.sortable) {
                     var arrow = jQuery('<span/>');
                     label.append(arrow);
@@ -153,7 +158,7 @@
                         'add_remove', 'sort', 'context', 'filename',
                         'autocomplete', 'translate', 'create', 'delete',
                         'selection_change_with', 'schema_model', 'required',
-                        'readonly'];
+                        'readonly', 'help'];
                     for (i in attribute_names) {
                         var attr = attribute_names[i];
                         if ((attr in model.fields[name].description) &&
@@ -316,10 +321,10 @@
                 if (!name) {
                     return;
                 }
-                if (decoder.decode(column.attributes.tree_invisible || '0')) {
-                    column.header.hide();
-                } else if (name === this.screen.exclude_field) {
+                if ((decoder.decode(column.attributes.tree_invisible || '0')) ||
+                        (name === this.screen.exclude_field)) {
                     column.header.hide();
+                    column.header.addClass('invisible');
                 } else {
                     var inv_domain = inversion.domain_inversion(domain, name);
                     if (typeof inv_domain != 'boolean') {
@@ -328,8 +333,10 @@
                     var unique = inversion.unique_value(inv_domain)[0];
                     if (unique && jQuery.isEmptyObject(this.children_field)) {
                         column.header.hide();
+                        column.header.addClass('invisible');
                     } else {
                         column.header.show();
+                        column.header.removeClass('invisible');
                     }
                 }
             }.bind(this));
@@ -656,7 +663,8 @@
             for (var i = 0; i < this.tree.columns.length; i++) {
                 var column = this.tree.columns[i];
                 td = jQuery('<td/>', {
-                    'data-title': column.attributes.string
+                    // TODO RTL
+                    'data-title': column.attributes.string + Sao.i18n.gettext(': ')
                 }).append(jQuery('<div/>', { // For responsive min-height
                     'aria-hidden': true
                 }));
@@ -666,6 +674,13 @@
                             true));
                 if (!this.tree.editable) {
                     td.dblclick(this.switch_row.bind(this));
+                } else {
+                    if (column.attributes.required) {
+                        td.addClass('required');
+                    }
+                    if (!column.attributes.readonly) {
+                        td.addClass('editable');
+                    }
                 }
                 var widgets = this.build_widgets();
                 var table = widgets[0];
@@ -789,8 +804,10 @@
                 if ((column.header.is(':hidden') && thead_visible) ||
                         column.header.css('display') == 'none') {
                     td.hide();
+                    td.addClass('invisible');
                 } else {
                     td.show();
+                    td.removeClass('invisible');
                 }
             }
             var row_id_path = this.get_id_path();
diff --git a/src/window.js b/src/window.js
index 74f469b..d1e5ca5 100644
--- a/src/window.js
+++ b/src/window.js
@@ -72,7 +72,7 @@
                     }
                 }.bind(this));
             }.bind(this));
-            var dialog = new Sao.Dialog('', '', 'lg');
+            var dialog = new Sao.Dialog('', 'window-form', 'lg');
             this.el = dialog.modal;
 
             var readonly = (this.screen.attributes.readonly ||
@@ -115,7 +115,9 @@
             }.bind(this));
 
             if (view_type == 'tree') {
-                var menu = jQuery('<div/>').appendTo(dialog.body);
+                var menu = jQuery('<div/>', {
+                    'class': 'window-form-toolbar'
+                }).appendTo(dialog.body);
                 var group = jQuery('<div/>', {
                     'class': 'input-group input-group-sm'
                 }).appendTo(menu);
@@ -412,7 +414,7 @@
                 this.screen.group.forEach(function(record) {
                     resource.set_client(record, this.resource);
                 }.bind(this));
-                prm = this.screen.group.save();
+                prm = this.screen.save_current();
             }
             if (this.attachment_callback) {
                 prm.always(this.attachment_callback.bind(this));
@@ -453,7 +455,7 @@
                         }
                     }
                 }.bind(this));
-                prm = this.screen.group.save();
+                prm = this.screen.save_current();
             }
             if (this.note_callback) {
                 prm.always(this.note_callback.bind(this));
@@ -546,13 +548,9 @@
 
                 var callback = function(result) {
                     if (result) {
-                        screen.save_current().then(function() {
-                            var record = screen.current_record;
-                            this.callback([[record.id,
-                                record._values.rec_name || '']]);
-                        }.bind(this), function() {
-                            this.callback(null);
-                        }.bind(this));
+                        var record = screen.current_record;
+                        this.callback([[record.id,
+                            record._values.rec_name || '']]);
                     } else {
                         this.callback(null);
                     }
@@ -560,6 +558,7 @@
                 this.el.modal('hide');
                 new Sao.Window.Form(screen, callback.bind(this), {
                     new_: true,
+                    save_current: true,
                     title: this.title
                 });
                 return;
@@ -938,7 +937,6 @@
                 'size': '1',
                 'maxlength': '1',
                 'value': '\"',
-                'readonly': '' // Until PapaParse releases custom quote feature
             });
 
             jQuery('<div/>', {
@@ -1176,7 +1174,7 @@
             Papa.parse(this.file_input[0].files[0], {
                 config: {
                     delimiter: this.el_csv_delimiter.val(),
-                    // TODO quoteChar: this.el_csv_quotechar.val(),
+                    quoteChar: this.el_csv_quotechar.val(),
                     preview: 1,
                     encoding: this.el_csv_encoding.val()
                 },
@@ -1275,7 +1273,7 @@
             Papa.parse(this.file_input[0].files[0], {
                 config: {
                     delimiter: this.el_csv_delimiter.val(),
-                    // TODO quoteChar: this.el_csv_quotechar.val(),
+                    quoteChar: this.el_csv_quotechar.val(),
                     encoding: encoding
                 },
                 error: function(err, file, inputElem, reason) {
@@ -1315,10 +1313,11 @@
     });
 
     Sao.Window.Export = Sao.class_(Sao.Window.CSV, {
-        init: function(screen, ids, names) {
+        init: function(screen, ids, names, context) {
             this.ids = ids;
             this.screen = screen;
             this.session = Sao.Session.current_session;
+            this.context = context;
             Sao.Window.Export._super.init.call(this,
                 Sao.i18n.gettext('Export to CSV')).then(function() {
                     names.forEach(function(name) {
@@ -1678,7 +1677,7 @@
                 Sao.rpc({
                     'method': 'model.' + this.screen.model_name +
                         '.export_data',
-                    'params': [this.ids, fields, {}]
+                    'params': [this.ids, fields, this.context]
                 }, this.session).then(function(data) {
                     this.export_csv(fields2, data).then(function() {
                         this.destroy();
@@ -1696,7 +1695,7 @@
                 unparse_obj.fields = fields;
             }
             var csv = Papa.unparse(unparse_obj, {
-                // TODO quoteChar: this.el_csv_quotechar.val(),
+                quoteChar: this.el_csv_quotechar.val(),
                 delimiter: this.el_csv_delimiter.val()
             });
             var blob = new Blob([csv], {type: 'text/csv;charset=' + encoding});
-- 
tryton-sao



More information about the tryton-debian-vcs mailing list