PageSourceSearch

https://wowit.stadtwerke-essen.de/chat/widget.nx01/widget-injector.js

js stadtwerke-essen.de collected 2026-10-05 06:42:54 UTC 27,651 bytes, 827 lines download raw bytes

1var imcs_externalurl = "https://wowit.stadtwerke-essen.de";
2var imcs_context = "/chat";
3var imcs_id = "widget.nx01";
4var imcs_baseurl = "https://wowit.stadtwerke-essen.de/chat/widget.nx01";
5
6( function( $ ) {
7	$( function() {
8		var Base64 = { _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", encode: function( e ) { var t = ""; var n, r, i, s, o, u, a; var f = 0; e = Base64._utf8_encode( e ); while ( f < e.length ) { n = e.charCodeAt( f++ ); r = e.charCodeAt( f++ ); i = e.charCodeAt( f++ ); s = n >> 2; o = ( n & 3 ) << 4 | r >> 4; u = ( r & 15 ) << 2 | i >> 6; a = i & 63; if ( isNaN( r ) ) { u = a = 64; } else if ( isNaN( i ) ) { a = 64; } t = t + this._keyStr.charAt( s ) + this._keyStr.charAt( o ) + this._keyStr.charAt( u ) + this._keyStr.charAt( a ); } return t; }, decode: function( e ) { var t = ""; var n, r, i; var s, o, u, a; var f = 0; e = e.replace( /[^A-Za-z0-9\+\/\=]/g, "" ); while ( f < e.length ) { s = this._keyStr.indexOf( e.charAt( f++ ) ); o = this._keyStr.indexOf( e.charAt( f++ ) ); u = this._keyStr.indexOf( e.charAt( f++ ) ); a = this._keyStr.indexOf( e.charAt( f++ ) ); n = s << 2 | o >> 4; r = ( o & 15 ) << 4 | u >> 2; i = ( u & 3 ) << 6 | a; t = t + String.fromCharCode( n ); if ( u != 64 ) { t = t + String.fromCharCode( r ); } if ( a != 64 ) { t = t + String.fromCharCode( i ); } } t = Base64._utf8_decode( t ); return t; }, _utf8_encode: function( e ) { e = e.replace( /\r\n/g, "\n" ); var t = ""; for ( var n = 0; n < e.length; n++ ) { var r = e.charCodeAt( n ); if ( r < 128 ) { t += String.fromCharCode( r ); } else if ( r > 127 && r < 2048 ) { t += String.fromCharCode( r >> 6 | 192 ); t += String.fromCharCode( r & 63 | 128 ); } else { t += String.fromCharCode( r >> 12 | 224 ); t += String.fromCharCode( r >> 6 & 63 | 128 ); t += String.fromCharCode( r & 63 | 128 ); } } return t; }, _utf8_decode: function( e ) { var t = ""; var n = 0; var r = c1 = c2 = 0; while ( n < e.length ) { r = e.charCodeAt( n ); if ( r < 128 ) { t += String.fromCharCode( r ); n++; } else if ( r > 191 && r < 224 ) { c2 = e.charCodeAt( n + 1 ); t += String.fromCharCode( ( r & 31 ) << 6 | c2 & 63 ); n += 2; } else { c2 = e.charCodeAt( n + 1 ); c3 = e.charCodeAt( n + 2 ); t += String.fromCharCode( ( r & 15 ) << 12 | ( c2 & 63 ) << 6 | c3 & 63 ); n += 3; } } return t; } };
9
10		// drag plugin
11		jQuery.fn.draggable = function( opt ) {
12			var options = typeof opt === 'object' ? opt : {};
13			var element = this;
14			var nop = function() { };
15			var handle = typeof options.handle === 'string' ? $( options.handle ) : element;
16			var oncreate = typeof options.create === 'function' ? options.create : nop;
17			var onstart = typeof options.start === 'function' ? options.start : nop;
18			var ondrag = typeof options.drag === 'function' ? options.drag : nop;
19			var onstop = typeof options.stop === 'function' ? options.stop : nop;
20			var targetw = element.width();
21			var targeth = element.height();
22			var ismousedown = false;
23			var hasmoved = false;
24			var fixedmode,
25				relX, relY,
26				adjX, adjY,
27				docw, doch;
28
29			switch ( element.css( 'position' ) ) {
30				case 'absolute':
31					fixedmode = false;
32					break;
33				case 'fixed':
34					fixedmode = true;
35					break;
36				default:
37					if ( options.fixedmode ) {
38						console.log( 'forcing incompatible position mode "' + element.css( 'position' ) + '" to "fixed"' );
39						element.css( 'position', 'fixed' );
40						fixedmode = true;
41					}
42					else {
43						console.log( 'forcing incompatible position mode "' + element.css( 'position' ) + '" to "absolute"' );
44						element.css( 'position', 'absolute' );
45						fixedmode = false;
46					}
47			}
48			handle.css( 'cursor', 'move' );
49
50			handle.on( 'mousedown', function( e ) {
51				if ( e.button != 0 ) {
52					return;
53				}
54				var pos = element.offset();
55				var srcX = pos.left;
56				var srcY = pos.top;
57
58				if ( fixedmode ) {
59					adjX = $( window ).scrollLeft();
60					adjY = $( window ).scrollTop();
61					docw = window.innerWidth || window.clientWidth;
62					doch = window.innerHeight || window.clientHeight;
63				}
64				else {
65					adjX = 0;
66					adjY = 0;
67					docw = $( 'body' ).width();
68					doch = $( 'body' ).height();
69				}
70
71				relX = e.pageX - srcX;
72				relY = e.pageY - srcY;
73
74				ismousedown = true;
75				hasmoved = false;
76				onstart( e, element, handle );
77			} );
78
79			$( document ).on( 'mousemove', function( e ) {
80				if ( ismousedown ) {
81					targetw = element.width();
82					targeth = element.height();
83
84					var maxX = docw - targetw;
85					var maxY = doch - targeth;
86
87					var posX = Math.min( Math.max( e.pageX - relX - adjX, 0 ), maxX );
88					var posY = Math.min( Math.max( e.pageY - relY - adjY, 0 ), maxY );
89
90					element.css( 'top', ( posY ) + 'px' );
91					element.css( 'left', ( posX ) + 'px' );
92
93					hasmoved = true;
94					ondrag( e, element, handle );
95				}
96			} );
97
98			$( window ).on( 'mouseup', function( e ) {
99				if ( ismousedown ) {
100					ismousedown = false;
101					onstop( e, element, handle, hasmoved );
102					hasmoved = false;
103				}
104			} );
105
106			oncreate( element, handle );
107			return this;
108		};
109
110		// Default Configuration
111		var config = {
112			stylesheet: "",
113			canclose: true,
114			canmove: true,
115			rechecktime: 300,
116			z_index: 2147483640,
117			display: {
118				minheight: 0,
119				minwidth: 0,
120			},
121			invite: {
122				label: "Fragen? Jetzt zum Chat",
123				mobilelabel: "Chat",
124				icon: imcs_baseurl + "/img/icon-chat.png",
125				always: false,
126				right: false,
127			},
128			restore: {
129				label: "Zurück zum Chat",
130				icon: imcs_baseurl + "/img/icon-chat.png",
131			},
132			form: {
133				caption: "Formular ausfüllen und los geht's",
134				subcaption: "",
135				header: "",
136				text: "",
137				submit: "Zum Chat",
138				mandatory: "(Pflichtfeld)",
139				width: "500px",
140				height: "500px",
141			},
142			chat: {
143				right: false,
144				caption: "Willkommen im Chat",
145				subcaption: "",
146				width: "500px",
147				height: "500px",
148				allow: undefined,
149			},
150			unavailable: {
151				caption: "Chat nicht verfügbar",
152				subcaption: "",
153				header: "Es tut uns leid!",
154				text: "Wir sind gerade nicht erreichbar. Bitte versuchen Sie es später noc
154h einmal. Vielen Dank!",
155			},
156			colors: {
157				main: {
158					text: '#20263A',
159					link: '#4f546b',
160					background: 'white'
161				},
162				primary: {
163					text: 'white',
164					link: '#a9a9a9',
165					background: '#20263A'
166				},
167				secondary: {
168					text: 'white',
169					link: '#a9a9a9',
170					background: '#19B8FC'
171				},
172				tertiary: {
173					text: '#888888',
174					link: '#ddddee',
175					background: '#e8e8e8'
176				}
177			},
178			fields: {
179				name: {
180					label: "Ihr Name",
181					value: "",
182					required: true,
183					placeholder: "Geben Sie bitte Ihren Namen ein",
184				},
185				email: {
186					label: "Ihre E-Mail-Adresse",
187					value: "",
188					required: true,
189					placeholder: "Geben Sie bitte Ihre E-Mail Adresse ein",
190				}
191			},
192			extrafields: [],
193			autoappend: {},
194			userdata: {},
195			privacy: false,
196		};
197
198		// Browser and OS detection
199		// originally from https://medium.com/creative-technology-concepts-code/detect-device-browser-and-version-using-javascript-8b511906745
200		var browserDetect = function() {
201			'use strict';
202
203			var module = {
204				options: [],
205				header: [ navigator.platform, navigator.userAgent, navigator.appVersion, navigator.vendor, window.opera ],
206				dataos: [
207					{ name: 'Windows Phone', value: 'Windows Phone', version: 'OS' },
208					{ name: 'Windows', value: 'Win', version: 'NT' },
209					{ name: 'iPhone', value: 'iPhone', version: 'OS' },
210					{ name: 'iPad', value: 'iPad', version: 'OS' },
211					{ name: 'Kindle', value: 'Silk', version: 'Silk' },
212					{ name: 'Android', value: 'Android', version: 'Android' },
213					{ name: 'PlayBook', value: 'PlayBook', version: 'OS' },
214					{ name: 'BlackBerry', value: 'BlackBerry', version: '/' },
215					{ name: 'Macintosh', value: 'Mac', version: 'OS X' },
216					{ name: 'Linux', value: 'Linux', version: 'rv' },
217					{ name: 'Palm', value: 'Palm', version: 'PalmOS' }
218				],
219				databrowser: [
220					{ name: 'Chrome', value: 'Chrome', version: 'Chrome' },
221					{ name: 'Firefox', value: 'Firefox', version: 'Firefox' },
222					{ name: 'Safari', value: 'Safari', version: 'Version' },
223					{ name: 'Internet Explorer', value: 'MSIE', version: 'MSIE' },
224					{ name: 'Opera', value: 'Opera', version: 'Opera' },
225					{ name: 'BlackBerry', value: 'CLDC', version: 'CLDC' },
226					{ name: 'Mozilla', value: 'Mozilla', version: 'Mozilla' }
227				],
228				init: function() {
229					var agent = this.header.join( ' ' ),
230						os = this.matchItem( agent, this.dataos ),
231						browser = this.matchItem( agent, this.databrowser );
232
233					return { os: os, browser: browser };
234				},
235				matchItem: function( string, data ) {
236					var i = 0,
237						j = 0,
238						html = '',
239						regex,
240						regexv,
241						match,
242						matches,
243						version;
244
245					for ( i = 0; i < data.length; i += 1 ) {
246						regex = new RegExp( data[ i ].value, 'i' );
247						match = regex.test( string );
248						if ( match ) {
249							regexv = new RegExp( data[ i ].version + '[- /:;]([\\d._]+)', 'i' );
250							matches = string.match( regexv );
251							version = '';
252							if ( matches ) { if ( matches[ 1 ] ) { matches = matches[ 1 ]; } }
253							if ( matches ) {
254								matches = matches.split( /[._]+/ );
255								for ( j = 0; j < matches.length; j += 1 ) {
256									if ( j === 0 ) {
257										version += matches[ j ] + '.';
258									} else {
259										version += matches[ j ];
260									}
261								}
262							} else {
263								version = '0';
264							}
265							return {
266								name: data[ i ].name,
267								version: parseFloat( version )
268							};
269						}
270					}
271					return { name: 'unknown', version: 0 };
272				}
273			};
274
275			return module.init();
276		};
277
278		function digicomAddAutoAppendData( cfg ) {
279			// Is there anything to do at all?
280			if ( Object.keys( cfg.autoappend ).length == 0 ) {
281				return;
282			}
283			// Check for known keys
284			var environment = null;
285			if ( cfg.autoappend.os ) {
286				environment = browserDetect();
287				cfg.userdata[ cfg.autoappend.os ] = ( environment.os.name + ", Version "
288					+ environment.os.version );
289			}
290			if ( cfg.autoappend.browser ) {
291				environment = environment ? environment : browserDetect();
292				cfg.userdata[ cfg.autoappend.browser ] = ( environment.browser.name
293					+ ", Version " + environment.browser.version );
294			}
295			if ( cfg.autoappend.resolution ) {
296				cfg.userdata[ cfg.autoappend.resolution ] = ( window.innerWidth + " x "
297					+ window.innerHeight );
298			}
299			if ( cfg.autoappend.url ) {
300				cfg.userdata[ cfg.autoappend.url ] = window.location.href;
301			}
302		}
303
304		var formSubmitted = false;
305
306		function digicomEncodeForURL( object ) {
307			// See https://tools.ietf.org/html/rfc4648#section-5
308			return encodeURIComponent( Base64.encode( JSON.stringify( object ) ).replace( /\+/g, '-' ).replace( /\//g, '_' ).replace( /\=+$/, '' ) );
309		}
310
311		function digicomEncodeForJSB( object ) {
312			return 'jsb:' + Base64.encode( JSON.stringify( object ) ) + ':jsb';
313		}
314
315		function digicomMergeConfiguration( destConfig, srcConfig ) {
316			if ( ( typeof destConfig === 'object' ) && ( typeof srcConfig === 'object' ) ) {
317				Object.keys( srcConfig ).forEach( function( key ) {
318					switch ( key ) {
319						case 'name':
320						case 'email':
321							if ( typeof srcConfig[ key ] === 'boolean' && srcConfig[ key ] === false ) {
322								destConfig[ key ] = srcConfig[ key ];
323								break;
324							}
325						case 'invite':
326						case 'restore':
327						case 'form':
328						case 'chat':
329						case 'unavailable':
330						case 'colors':
331						case 'main':
332						case 'primary':
333						case 'secondary':
334						case 'tertiary':
335						case 'fields':
336						case 'userdata':
337							destConfig[ key ] = digicomMergeConfiguration( destConfig[ key ], srcConfig[ key ] );
338							break;
339						default:
340							destConfig[ key ] = srcConfig[ key ];
341							break;
342					}
343				} );
344			}
345			return destConfig;
346		}
347
348		function digicomChatInjectCss( url ) {
349			if ( url ) {
350				$( 'head' ).append( $( '<link>' ).attr( 'rel', 'stylesheet prefetch' ).attr( 'href', url ) );
351			}
352		}
353
354		function digicomShowUnavailable() {
355			config.specific = {
356				stylesheet: imcs_baseurl + '/widgetstyle.css',
357				externalurl: imcs_externalurl,
358				context: imcs_context,
359				id: imcs_id,
360				headtext: config.unavailable.header,
361				statustext: config.unavailable.text
362			};
363			digicomShowMain( imcs_baseurl + '/widgetstatus/' + digicomEncodeForURL( config ), config.unavailable.caption, config.unavailable.subcaption );
364			delete config.specific;
365		}
366
367		function digicomCheckForm() {
368			if ( $( '#digicom-main' ).is( ':visible' ) ) {
369				if ( $( '#digicom-iframe' ).attr( 'src' ).search( '/widgetform/' ) != -1 ) {
370					if ( digicomCanChat() ) {
371						setTimeout( digicomCheckForm, 5000 );
372					} else {
373						digicomShowUnavailable();
374					}
375				}
376			}
377		}
378
379		var digicomClickInvitation = function( e ) {
380			digicomHideInvitation();
381			var ufn = digicomNewUFN();
382			if ( ufn && digicomCanChat() ) {
383				// gehe zum Formular
384				config.specific = {
385					stylesheet: imcs_baseurl + '/widgetstyle.css',
386					externalurl: imcs_externalurl,
387					context: imcs_context,
388					id: imcs_id,
389					ufn: ufn,
390					tab: digicomIsSmallScreen()
391				};
392				if ( config.userdata ) {
393					config.specific.userdata = digicomEncodeForJSB( config.userdata );
394				}
395				if ( config.chat.stylesheet ) {
396					config.specific.chatstyle = config.chat.stylesheet;
397				}
398				digicomShowMain( imcs_baseurl + '/widgetform/' + digicomEncodeForURL( config ), config.form.caption, config.form.subcaption );
399				delete config.specific;
400				digicomCheckForm();
401			}
402			else {
403				// Zeige "Sorry"
404				digicomShowUnavailable();
405			}
406		};
407
408		var digicomClickRestore = function( e ) {
409			localStorage.removeItem( 'digicom-chat-view' );
410			digicomHideRestore();
411			digicomReenter( true );
412		};
413
414		var digicomClickClose = function( e ) {
415			digicomHideMain();
416			digicomClearPosition();
417			var path = digicomInChat();
418			if ( typeof path === 'string' ) {
419				// chat is still running - forget it and close it
420				digicomClearChat();
421				$( '#digicom-iframe' )[ 0 ].contentWindow.postMessage( { type: 'closesession' }, '*' );
422			}
423			digicomReenter();
424		};
425
426		var digicomClickMinimize = function( e ) {
427			digicomHideMain();
428
429			var path = digicomInChat();
430			if ( typeof path === 'string' ) {
431				// chat is still running
432				localStorage.setItem( 'digicom-chat-view', 'minimized' );
433				digicomShowRestore();
434				digicomMinimizeChecker();
435			}
436			else {
437				// no valid chat running
438				digicomReenter();
439			}
440		};
441
442		function digicomEventHandler() {
443			$( window ).on( 'message', function( e ) {
444				var msg = typeof e.originalEvent === 'object' && typeof e.originalEvent.data === 'object' ? e.originalEvent.data : { type: 'none' };
445				switch ( msg.type ) {
446					case 'submit':
447						localStorage.setItem( 'digicom-chat-ufn', msg.ufn );
448						if ( msg.tab ) localStorage.setItem( 'digicom-chat-view', msg.tab );
449						$( '#digicom-caption' ).text( config.chat.caption );
450						$( '#digicom-caption-subtext' ).text( config.chat.subcaption );
451						$( '#digicom-main' ).removeClass( config.chat.right ? 'digicom-form-float-right' : 'digicom-form-float-left' );
452						$( '#digicom-main' ).addClass( config.chat.right ? 'digicom-chat-float-right' : 'digicom-chat-float-left' );
453						formSubmitted = true;
454						break;
455					case 'agentmessage':
456						if ( digicomGetView() == 'minimized' ) {
457							$( '#digicom-restore' ).addClass( 'digicom-attention' );
458							$( '#digicom-restore-text' ).addClass( 'digicom-attention' );
459						}
460						break;
461					default:
462						break;
463				}
464			} );
465			$( window ).on( 'resize', function( e ) {
466				if ( $( '#digicom-main' ).is( ':visible' ) ) {
467					var pos = digicomReadPosition();
468					if ( pos ) {
469						if ( parseInt( pos.top ) >= $( window ).height() || parseInt( pos.left ) >= $( window ).width() ) {
470							digicomClearPosition();
471							$( '#digicom-main' ).removeAttr( 'style' );
472						}
473					}
474				}
475			} );
476		}
477
478		function digicomGetView() {
479			switch ( localStorage.getItem( 'digicom-chat-view' ) ) {
480				case 'minimized':
481					return 'minimized';
482				case 'maximized':
483					return 'maximized';
484				default:
485					return 'normal';
486			}
487		}
488
489		function digicomChatInjectWidget() {
490			if ( $( '#digicomChatWidget' ).length ) {
491				console.warn( 'digicomChatInjectWidget: widget already injected' );
492			}
493			else {
494				let widget = $(
495					'<div id="digicomChatWidget" class="digicom">' +
496					'<div id="digicom">' +
497					// iframe container
498					'<div id="digicom-main" class="digicom-main">' +
499					'<div id="digicom-titlebar" class="digicom-titlebar">' +
500					'<div id="digicom-titlebar-first" class="digicom-titlebar-first">' +
501					'<div id="digicom-titlebar-caption" class="digicom-titlebar-caption">' +
502					'<span id="digicom-caption" class="digicom-caption"></span>' +
503					'</div>' +
504					'<div id="digicom-titlebar-buttons" class="digicom-titlebar-buttons"><button id="digicom-minimize" tabindex="0"></button><button id="digicom-close" tabindex="0"></button></div>' +
505					'</div>' +
506					'<div id="digicom-titlebar-second" class="digicom-titlebar-second">' +
507					'<span id="digicom-caption-subtext" class="digicom-caption-subtext"></span>' +
508					'</div>' +
509					'</div>' +
510					'<iframe id="digicom-iframe" class="digicom-iframe"' + ( config.chat.allow ? ' allow="' + config.chat.allow + '"' : '' ) + '>' +
511					'</iframe>' +
512					'</div>' +
513					// restore
514					'<button id="digicom-restore" tabindex="0">' +
515					'<img id="digicom-restore-image" class="digicom-restore-image" src="' + config.restore.icon + '" alt="" />' +
516					'<span id="digicom-restore-text" class="digicom-restore-text">' + config.restore.label + '</span>' +
517					'</button>' +
518					// invitation
519					'<button id="digicom-invite" tabindex="0">' +
520					'<img id="digicom-invite-image" class="digicom-invite-image" src="' + config.invite.icon + '" alt="" />' +
521					'<span id="digicom-invite-text" class="digicom-invite-text">' + config.invite.label + '</span>' +
522					'<span id="digicom-invite-text-mobile" class="digicom-invite-text-mobile">' + config.invite.mobilelabel + '</span>' +
523					'</button>' +
524					'</div>' +
525					'</div>'
526				);
527				$( 'body' ).append( widget );
528				// initialize invitation object
529				$( '#digicom-invite' ).hide();
530				$( '#digicom-invite' ).addClass( config.invite.right ? 'digicom-right' : 'digicom-left' );
531				$( '#digicom-invite' ).on( 'click', digicomClickInvitation );
532				// initialize restore object
533				$( '#digicom-restore' ).hide();
534				$( '#digicom-restore' ).addClass( config.invite.right ? 'digicom-right' : 'digicom-left' );
535				$( '#digicom-restore' ).on( 'click', digicomClickRestore );
536				// initialize iframe container
537				$( '#digicom-main' ).hide();
538				$( '#digicom-close' ).on( 'click', digicomClickClose );
539				$( '#digicom-minimize' ).on( 'click', digicomClickMinimize );
540				// configuration
541				if ( config.canclose ) $( '#digicom-close' ).show(); else $( '#digicom-close' ).hide();
542				if ( config.canmove ) $( '#digicom-main' ).draggable( {
543					handle: '#digicom-titlebar',
544					fixedmode: true,
545					stop: function( e, element, handle, hasmoved ) {
546						if ( hasmoved ) {
547							digicomSavePosition( element.css( 'left' ), element.css( 'top' ) );
548						}
549					}
550				} );
551			}
552		}
553
554		function digicomClearChat() {
555			localStorage.removeItem( 'digicom-chat-ufn' );
556		}
557
558		function digicomSavePosition( x, y ) {
559			localStorage.setItem( 'digicom-chat-top', y );
560			localStorage.setItem( 'digicom-chat-left', x );
561			localStorage.setItem( 'digicom-chat-position-update', ( new Date ).getTime() );
562			console.log( "Position saved" );
563		}
564
565		function digicomReadPosition( maxage ) {
566			var position = {
567				left: localStorage.getItem( 'digicom-chat-left' ),
568				top: localStorage.getItem( 'digicom-chat-top' ),
569				updated: localStorage.getItem( 'digicom-chat-position-update' )
570			};
571			if ( position.top && position.left && position.updated ) {
572				if ( maxage ) {
573					return ( ( new Date ).getTime() - position.updated ) < maxage ? position : undefined;
574				}
575				return position;
576			}
577		}
578
579		function digicomClearPosition() {
580			localStorage.removeItem( 'digicom-chat-top' );
581			localStorage.removeItem( 'digicom-chat-left' );
582			localStorage.removeItem( 'digicom-chat-position-update' );
583			console.log( "Position removed" );
584		}
585
586		function digicomInChat() {
587			var retval = false;
588			var ufn = localStorage.getItem( 'digicom-chat-ufn' );
589			if ( ufn ) {
590				$.ajax( {
591					url: imcs_baseurl + '/api/checkufn/' + ufn,
592					method: 'GET',
593					async: false,
594					cache: false,
595					timeout: 2000,
596					success: function( data ) {
597						if ( typeof data.causecode === 'number' ) {
598							if ( data.causecode > 0 ) {
599								// valid but closed session closed
600								digicomClearChat();
601								digicomClearPosition();
602								retval = false;
603							}
604							else {
605								// reopen window
606								retval = '/caller/' + ufn + '/resume/resume%40example%2Ecom';
607							}
608						}
609						else {
610							// invalid
611							digicomClearChat();
612						}
613					}
614				} );
615			}
616			return retval;
617		}
618
619		function digicomCallerConnected() {
620			var retval = false;
621			var ufn = localStorage.getItem( 'digicom-chat-ufn' );
622			if ( ufn ) {
623				$.ajax( {
624					url: imcs_baseurl + '/api/callerconnected/' + ufn,
625					method: 'GET',
626					async: false,
627					cache: false,
628					timeout: 2000,
629					success: function( data ) {
630						retval = data.callerConnected ? data.callerConnected : false;
631					}
632				} );
633			}
634			return retval;
635		}
636
637		function digicomCanChat() {
638			var retval = false;
639			$.ajax( {
640				url: imcs_baseurl + '/api/acceptingnewchats',
641				method: 'POST',
642				data: config.userdata,
643				async: false,
644				cache: false,
645				timeout: 2000,
646				success: function( data ) {
647					retval = data.accepts ? data.accepts : false;
648				}
649			} );
650			return retval;
651		}
652
653		function digicomCanDisplay() {
654			if ( typeof config.display === 'object' ) {
655				return ( ( window.innerHeight >= config.display.minheight ) && ( window.innerWidth >= config.display.minwidth ) );
656			}
657			return true;
658		}
659
660		function digicomNewUFN() {
661			var retval = '';
662			$.ajax( {
663				url: imcs_baseurl + '/api/ufn',
664				method: 'GET',
665				async: false,
666				cache: false,
667				timeout: 2000,
668				success: function( data ) {
669					retval = data.ufn;
670				}
671			} );
672			return retval;
673		}
674
675		function digicomShowMain( url, caption, subcaption ) {
676			$( '#digicom-restore' ).removeClass( 'digicom-attention' );
677			$( '#digicom-restore-text' ).removeClass( 'digicom-attention' );
678
679			if ( digicomIsSmallScreen() ) {
680				open( url );
681				setTimeout( digicomReenter, 15000 );
682			} else {
683				var pos = config.canmove ? digicomReadPosition( 1800000 ) : undefined;
684				if ( pos && parseInt( pos.top ) < $( window ).height() && parseInt( pos.left ) < $( window ).width() ) {
685					$( '#digicom-main' ).css( 'top', pos.top ).css( 'left', pos.left );
686				}
687				else {
688					digicomClearPosition();
689					$( '#digicom-main' ).removeAttr( 'style' );
690				}
691
692				$( '#digicom-main' ).show();
693				$( '#digicom-main' ).addClass( config.chat.right ? 'digicom-chat-float-right' : 'digicom-chat-float-left' );
694				$( '#digicom-caption' ).text( caption );
695				$( '#digicom-caption-subtext' ).text( subcaption );
696				if ( !formSubmitted && $( '#digicom-iframe' ).attr( 'src' ) != url ) {
697					$( '#digicom-iframe' ).attr( 'src', url );
698				}
699			}
700		}
701
702		function digicomHideMain() {
703			$( '#digicom-main' ).hide();
704			$( '#digicom-main' ).removeClass( config.chat.right ? 'digicom-chat-float-right' : 'digicom-chat-float-left' );
705		}
706
707		function digicomShowInvitation() {
708			$( '#digicom-invite' ).show();
709			$( '#digicom-invite' ).addClass( 'digicom-slideup' );
710			$( '#digicom-main' ).removeClass( config.chat.right ? 'digicom-chat-float-right' : 'digicom-chat-float-left' );
711			$( '#digicom-main' ).addClass( config.chat.right ? 'digicom-form-float-right' : 'digicom-form-float-left' );
712			formSubmitted = false;
713		}
714
715		function digicomHideInvitation() {
716			$( '#digicom-invite' ).hide();
717			$( '#digicom-invite' ).removeClass( 'digicom-slideup' );
718		}
719
720		function digicomShowRestore() {
721			$( '#digicom-restore' ).show();
722			$( '#digicom-restore' ).addClass( 'digicom-slideup' );
723		}
724
725		function digicomHideRestore() {
726			$( '#digicom-restore' ).hide();
727			$( '#digicom-restore' ).removeClass( 'digicom-slideup' );
728		}
729
730		function digicomMinimizeChecker() {
731			if ( digicomGetView() == 'minimized' ) {
732				var path = digicomInChat();
733				if ( path ) {
734					if ( Date.now() - digicomTimeStamp < ( 1000 * config.rechecktime ) ) {
735						setTimeout( digicomMinimizeChecker, 15000 );
736					}
737				}
738				else {
739					localStorage.removeItem( 'digicom-chat-view' );
740					digicomHideRestore();
741					digicomReenter();
742				}
743			}
744		}
745
746		function digicomReenter( restore ) {
747			// decide which element to show AND how to show it
748			var path = digicomInChat();
749			if ( path ) {
750				if ( !restore && digicomCallerConnected() ) {
751					// do nothing - there is another window with the active chat still open but maybe it may change....
752					console.debug( 'Other Page: Rechecking for chat in 5 seconds' );
753					if ( digicomIsSmallScreen() ) {
754						// always check on small screens or the user may be locked out of chatting after some time
755						digicomHideInvitation();
756						digicomHideRestore();
757						setTimeout( digicomReenter, 15000 );
758					} else if ( Date.now() - digicomTimeStamp < ( 1000 * config.rechecktime ) ) {
759						setTimeout( digicomReenter, 15000 );
760					} else {
761						console.debug( 'Other Page: Will not check anymore, recheck time expired.' );
762					}
763				}
764				else {
765					switch ( digicomGetView() ) {
766						case 'minimized':
767							digicomHideInvitation();
768							digicomShowRestore();
769							digicomMinimizeChecker();
770							break;
771						default:
772							// normal
773							if ( !restore && digicomIsSmallScreen() ) {
774								// show "restore" on small devices instead of re-opening tab
775								digicomShowRestore();
776							} else {
777								digicomShowMain( imcs_externalurl + imcs_context + path, config.chat.caption, config.chat.subcaption );
778							}
779					}
780				}
781			}
782			else if ( digicomCanDisplay() && ( config.invite.always || digicomCanChat() ) ) {
783				// no chat running
784				digicomShowInvitation();
785				// keep checking on small screens, a chat may start in another tab
786				if ( digicomIsSmallScreen() ) setTimeout( digicomReenter, 15000 );
787			}
788			else {
789				// no chat agents available
790				console.debug( 'No ACD: Rechecking for chat in 5 seconds' );
791				if ( Date.now() - digicomTimeStamp < ( 1000 * config.rechecktime ) ) {
792					setTimeout( digicomReenter, 15000 );
793				} else {
794					console.debug( 'No ACD: Will not check anymore, recheck time expired.' );
795				}
796			}
797		}
798
799		function digicomIsSmallScreen() {
800			return innerHeight <= 576 || innerWidth <= 576;
801		}
802
803		// merge supplied user configuration with internal configuration store
804		digicomMergeConfiguration( config, customWidgetConfig );
805		// force chat.width to be at least 500px - IMCS-531
806		config.chat.width = config.chat.width.split( 'px' )[ 0 ] >= 500 ? config.chat.width : '500px';
807		console.debug( "digicomChat: resulting configuration", config );
808
809		// add autoappend data (if configured)
810		digicomAddAutoAppendData( config );
811
812		// add stylesheetss to web page
813		digicomChatInjectCss( imcs_baseurl + '/css/widgetstyle.css' );
814		digicomChatInjectCss( imcs_baseurl + '/widgetstyle.css?data=' + digicomEncodeForURL( config ) );
815		digicomChatInjectCss( config.stylesheet );
816
817		// inject the widget into the page
818		digicomChatInjectWidget();
819
820		// attach event handler
821		digicomEventHandler();
822
823		// standard handling
824		var digicomTimeStamp = Date.now();
825		digicomReenter();
826	} );
827} )( jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.