Vn.App = new Class ({ Extends: Vn.Object ,initialize: function () { window.onerror = this._onWindowError.bind (this); window.onunload = this._onWindowUnload.bind (this); Vn.Hash.initialize (); this._isGuest = new Vn.HashParam ({ type: Boolean, key: 'guest' }); this._isGuest.on ('changed', this._onGuestChange, this); var conn = new Db.Conn (); this.link ({_conn: conn}, {'error': this._onConnError}); } ,run: function () { var guest = Vn.Cookie.check ('hedera_guest'); if (guest) Vn.Cookie.unset ('hedera_guest'); if (Vn.Cookie.check ('vn_pass')) { this._conn.open (null, null, null, this._onAutoLogin.bind (this)); } else if (this._isGuest.value || guest) { this._guestLogin (); } else { var login = this._login = new Vn.Login ({conn: this._conn}); login.on ('login', this._onLogin, this); login.show (); } } ,_onGuestChange: function () { if (this._isGuest.value) this._guestLogin (); } ,_guestLogin: function () { this._conn.open ( null, null, null, this._onGuestLogin.bind (this), true ); } ,_onGuestLogin: function (conn, success) { this._isGuest.value = undefined; if (success) { Vn.Cookie.set ('hedera_guest', true); this._onLogin (); } else this.run (); } ,_onAutoLogin: function (success) { if (!success) { Vn.Cookie.unset ('vn_pass'); this.run (); } else this._onLogin (); } ,_onLogin: function () { this._freeLogin (); var gui = this._gui = new Vn.Gui ({conn: this._conn}); gui.on ('logout', this._onLogout, this); gui.show (); } ,_onLogout: function (gui) { this._freeGui (); Vn.Cookie.unset ('hedera_guest'); Vn.Cookie.unset ('vn_pass'); this.run (); } ,_onWindowError: function (message, file, line) { var error = new Error (message); error.fileName = file; error.lineNumber = line; Htk.Toast.showError (_('There was an internal error')); this._notifyError (error); } ,_onWindowUnload: function () { this.unref (); } ,_onConnError: function (conn, error) { if (error instanceof Vn.Error) switch (error.domain) { case 'Auth': Htk.Toast.showError (_('You\'ve been too idle')); if (this._gui) this._gui.logout (); break; case 'Version': this._newVersion (error); break; case 'User': Htk.Toast.showError (error.message); break; default: console.error (error.message); Htk.Toast.showError (_('There was an internal error')); } else { console.error (error); Htk.Toast.showError (_('There was an internal error')); this._notifyError (error); } } ,_newVersion: function (error) { if (this.newVersionBlock || this.skipVersion) return; this.newVersionBlock = true; var reload; var message = _('New version available') +"\n\n"+ error.message; if (error.code == 'criticalVersion') { alert (message) reload = true; } else { reload = confirm (message); this.skipVersion = true; } if (reload) location.reload (); this.newVersionBlock = false; } ,_notifyError: function (error) { if (error instanceof Error) { var httpRequest = new Vn.HttpRequest () httpRequest.add ({ 'file': error.fileName ,'line': error.lineNumber ,'message': error.message ,'stack': error.stack }); httpRequest.send ('log.php'); } } ,_freeLogin: function () { if (this._login) { this._login.disconnectByInstance (this); this._login.hide (); this._login.unref (); this._login = null; } } ,_freeGui: function () { if (this._gui) { this._gui.disconnectByInstance (this); this._gui.hide (); this._gui.unref (); this._gui = null; } } ,_destroy: function () { this._freeLogin (); this._freeGui (); this._conn.unref (); } });