PageSourceSearch

https://datenschutz-generator.de/wp-content/plugins/ts-dsg/js/dsg-tour.js

js datenschutz-generator.de collected 2026-10-01 08:42:13 UTC 100,361 bytes, 2,719 lines download raw bytes

1
2
3
4
5/*===================================================================================    
6*
7*
8* dsg-tour.js - Funktionen zur Darstellung von Hilfehinweisen für Nutzer
9*
10*
11*
12* css_de im Modul mit folgenden Klassen kennzeichnen (jeweils Anbieter, Modul und Option in dem Modul):
13
14dsg-tour-step-provider  -> Gruppe der ersten Modulreihe mit Anagben zum Unternehmen
15dsg-tour-step-regmodule -> Modul mit einer Ja/Nein-Frage und Option
16dsg-tour-step-regoption -> Option in dem obigen Modul.
17
18*
19*
20====================================================================================*/
21jQuery(document).ready(function($) {
22	
23    // console.log('dsg-tour.js');
24
25    // Set up click handler for .button-close
26	// $('.button-close, .button-cookie-copy').click(function() {  
27
28    // Event delegation to the body for later added element
29    $('body').on('click', '#dsg-project-help-button, .dsg-tour-start-button', function() {
30        // console.log('tour ON0');
31        if (!$('.dsg-tour-wrap').length) {
32
33            // console.log('tour ON1');
34            dsg_tour_init();
35			
36			
37		} else {
38				dsg_tour_end();
39		}
40    });
41	 
42	//start per Tastatureingabe
43	let dsg_tour_typingUserInput = "";
44	let dsg_tour_typingTimer;
45	document.addEventListener('keydown', function(event) {
46		// Clear the previous timer
47		clearTimeout(dsg_tour_typingTimer);
48
49		// Add the typed character to the string
50		dsg_tour_typingUserInput += event.key;
51
52		// Set the timer to reset input if typing interval exceeds 0.5 seconds
53		dsg_tour_typingTimer = setTimeout(function() {
54			dsg_tour_typingUserInput = ""; // Reset input
55		}, 3000);
56
57		// Check if the input contains 'gotour'
58		if (dsg_tour_typingUserInput.includes("go")) {
59			// console.log("go");
60			// dsg_tour_init(); // Call the tour initialization function
61			dsg_helper_button_start();
62			dsg_tour_typingUserInput = ""; // Reset after successful match
63		}
64	});
65	
66	
67	//Tourbutton erstellen
68    
69    window.dsg_helper_button_start = function () {
70
71		
72		setTimeout(function() {
73				
74				if ( !$('.dsg-tour-start-button-textwrp').length &&  $('body').hasClass('dsg-generator-running') ) { 
75				
76				   const title_generator = 'Wünschen Sie eine Tour?';
77				   
78					// Add the help button to the menu
79					// $('#primary-menu').prepend('<li id="dsg-project-help-button"><div class="dsg-tour-start-button help-button dsg-ttip" title="' + title + '"></div></li>');
80					startbutton_text ='<div class="dsg-tour-start-button-textwrp"><span class="dsg-tour-start-button" title="Tour starten">'+title_generator+'</span></div>';
81					
82					if (!url_parameter.dsgp) {
83						$('.entry-title').after( startbutton_text );
84					} else {
85						$('.projektname').after(startbutton_text);
86					}
87
88					
89					dsg_tooltip_activate($('.dsg-tour-start-button'), '');
90		
91				}			
92			}, 0);
93
94    }
95	
96	window.dsg_helper_button_start();
97	
98	if (typeof window.dsg_helper_button_start === 'function') {
99		window.dsg_helper_button_start();
100	}	
101
102
103	$('body').on('click', '#dsg-drpld .button', function() {
104		 dsg_helper_button_start(); 
105	});
106
107	
108		
109	window.dsg_helper_button_start_mydocs = function () {
110		
111		if ( !$('.dsg-tour-start-button-textwrp').length && window.location.href.includes("/mein-konto/dokumente")) {
112			
113			const title_mydocs = 'Wünschen Sie eine Tour?';	
114			setTimeout(function() {
115        
116			startbutton_text ='<div class="dsg-tour-start-button-textwrp"><a class="dsg-tour-start-button light-up-loop" title="Tour starten">'+title_mydocs+'</a></div>';
117			$('.entry-title').after(startbutton_text);
118			
119			}, 100);
120			
121			setTimeout(function() {
122				$('.light-up-loop').removeClass('light-up-loop');
123			}, 5000);		
124
125			$(document).on('mouseover', '.dsg-tour-start-button', function(event) {
126
127				$(this).removeClass('light-up-loop');
128			});
129		
130		
131			dsg_tooltip_activate($('.dsg-tour-start-button'), '');
132		
133		}
134	}
135	
136
137	if ( $(".dsg-project-divselect").length )  {
138			dsg_helper_button_start_mydocs();
139	}	
140		
141//===================================================================================    
142//
143// tour Inititalisieren
144//
145//====================================================================================
146
147    
148    function dsg_tour_init() {
149         // console.log('tour ON2');
150        dsg_tour_start();
151    }
152//===================================================================================    
153//
154// tour schaltet funktionen des DSG ab
155//
156//====================================================================================
157
158
159// Function to create a transparent overlay over the entire screen with z-index 90.
160function dsg_tour_overlay_create() {
161    $('<div id="dsg-tour-overlay"></div>').css({
162        'position': 'fixed',
163        'top': '0',
164        'left': '0',
165        'height': '100%',
166        'width': '100%',
167        'z-index': '90',
168        'background-color': 'transparent', // You can adjust the color and transparency as needed.
169    }).appendTo('body');
170}
171
172// Function to end the creation of the overlay.
173function dsg_tour_overlay_end() {
174    $('#dsg-tour-overlay').remove();
175}
176
177
178// Function for user click on the overlay.
179$(document).on('click', '#dsg-tour-overlay', function(event) {
180    dsg_tour_overlay_click(event);
181});
182
183
184function dsg_tour_overlay_click(event) {
185    // Remove any existing message element
186    let message_element = $('#dsg-tour-no-click-message');
187    message_element.remove();
188
189    // Create an invisible div at the click position
190    var x = event.pageX;
191    var y = event.pageY;
192    var message = 'Während der Tour kann der Generator nicht benutzt werden. Bitte beenden Sie hierzu erst die Tour';
193
194    var jquery_this = $('<div id="dsg-tour-no-click-message" class="dsg-ttip" title="'+message+'"></div>').css({
195        'position': 'absolute',
196        'top': y + 'px',
197        'left': x + 'px',
198        'width': '10px',
199        'height': '10px',
200        'overflow': 'hidden',
201        'opacity': '0',
202        'z-index': '91',
203        'background-color': 'transparent'
204    }).attr('title', message).appendTo('body');
205
206    // Run jQuery UI tooltip
207    jquery_this.tooltip({ 
208        content: message, 
209        items: '#dsg-tour-no-click-message', 
210        show: { delay: 0 },
211        position: { my: "left top", at: "left bottom", of: event }
212    });
213}
214
215	
216	//Def Globals
217	var tour_elements_obj = {};
218	var step_current = 0;
219	var tour_keys = "";
220
221
222//===================================================================================    
223//
224// tour Start
225//
226//====================================================================================
227		
228
229		
230    function dsg_tour_start() {
231
232		//H3 Titel in Gruppentiteln wrappen, um sie besser andockbar ohne Überdeckung zu machen
233		dsg_tour_grup_title_wrap();
234	
235
236		tour_elements_obj = dsg_tour_tour_object("", "");
237		step_current = parseInt(Object.keys(tour_elements_obj)[0]);
238		tour_keys = Object.keys(tour_elements_obj).map(Number);
239
240			// console.dir(tour_keys);		
241		//Erstes Element darstellen
242		// step_current = "";// man kann auch ein bestimmtes vorgeben
243        display_tour_element(step_current);
244		
245		//Oberlay erstellen, damit die elemente der Website während der Tour unzugänglich werden
246		dsg_tour_overlay_create();
247    }
248	
249
250
251//===================================================================================    
252//
253// tour Start - Gruppentitel Wraps
254//
255//====================================================================================
256
257    function dsg_tour_grup_title_wrap () {
258		
259		$(".dsg-group .group-title").each(function() {
260		  // Get the current text of the element
261		  var currentText = $(this).text();
262
263		  // Wrap the text in a <span> with a class
264		  var wrappedText = '<span class="text">' + currentText + '</span>';
265
266		  // Set the HTML of the element to the wrapped text
267		  $(this).html(wrappedText);
268		});
269
270    }
271	
272	
273//===================================================================================    
274//
275// tour Element anzeigen - Vorscrollen des Dockimg-Elements
276//
277//====================================================================================
278function display_tour_element(step) {
279	
280  if ( !step ) step = 100;
281	
282  let tour_element = tour_elements_obj[step];
283  let tour_dock_selector = tour_element.dock_selector;
284  let tour_dock = $(tour_dock_selector);
285
286  if (tour_dock.length ) { 
287    let elementRect = tour_dock[0].getBoundingClientRect();
288    let isVisible = (
289      elementRect.top >= 0 &&
290      elementRect.bottom <= (window.innerHeight || document.documentElement.clientHeight)
291    );
292
293    if (!isVisible) {
294      let scrollToY = window.scrollY + elementRect.top - window.innerHeight / 2 + elementRect.height / 2;
295      // console.log("scrolleeeeeeee " + tour_dock_selector + " to: " + scrollToY);
296
297      window.scrollTo({
298        top: scrollToY,
299        behavior: 'smooth'
300      }); 
301
302      // Use a setTimeout or requestAnimationFrame to check when scrolling is likely finished
303      let scrollTimeout;
304      const onScroll = () => {
305        // Clear the timeout to ensure the action only happens after scrolling stops
306        clearTimeout(scrollTimeout);
307        // Setup a new timeout
308        scrollTimeout = setTimeout(() => {
309          window.removeEventListener('scroll', onScroll);
310          display_tour_element_go(step); // Call after scrolling has settled
311
312        }, 100); // Adjust this timeout as needed
313      };
314
315      window.addEventListener('scroll', onScroll);
316
317    } else {
318      display_tour_element_go(step);
319    }
320  } else {
321    display_tour_element_go(step);
322  }
323}
324
325
326	
327//===================================================================================    
328//
329// tour Element anzeigen
330//
331//====================================================================================
332
333    function display_tour_element_go(step) {
334	
335  let tour_element = tour_elements_obj[step];
336  let tour_dock_selector = tour_element.dock_selector;
337  let tour_dock = $(tour_dock_selector);
338
339  if (tour_dock.length) {
340    let elementRect = tour_dock[0].getBoundingClientRect();
341    let isVisible = (
342      elementRect.top >= 0 &&
343      elementRect.bottom <= (window.innerHeight || document.documentElement.clientHeight)
344    );
345
346    if (!isVisible) {
347      let scrollToY = window.scrollY + elementRect.top - window.innerHeight / 2 + elementRect.height / 2;
348      // console.log("scrolleeeeeeee " + tour_dock_selector + " to: " + scrollToY);
349
350      window.scrollTo({
351        top: scrollToY,
352        behavior: 'smooth'
353      });
354
355      // Use a setTimeout or requestAnimationFrame to check when scrolling is likely finished
356      let scrollTimeout;
357      const onScroll = () => {
358        // Clear the timeout to ensure the action only happens after scrolling stops
359        clearTimeout(scrollTimeout);
360        // Setup a new timeout
361        scrollTimeout = setTimeout(() => {
362          window.removeEventListener('scroll', onScroll);
363		  // console.log("--------------------1");
364          display_tour_element_go(step); // Call after scrolling has settled
365
366        }, 100); // Adjust this timeout as needed
367      };
368
369      window.addEventListener('scroll', onScroll);
370
371    } else {
372      display_tour_element_go(step);		  
373	   
374    }
375  } else {
376    display_tour_element_go(step);		  
377
378  }
379  
380
381}
382
383
384	
385//===================================================================================    
386//
387// tour Element anzeigen
388//
389//====================================================================================
390
391    function display_tour_element_go(step) {
392
393				// console.log("GOOOOOOOOOOOOOO step:"+step);
394		//if ( step === step_all ) step = 1;
395		
396		 // console.log('display_tour_element_go');
397		 // console.dir(tour_elements_obj);
398		
399        let tour_element = tour_elements_obj[step];
400        let tour_title = tour_element.title;
401        let tour_text = tour_element.text;
402        let tour_css_class = tour_element.css_class;
403        let tour_dock_selector = tour_element.dock_selector;
404		
405        let tour_dock_distance_x = tour_element.dist_to_dock_x;
406        let tour_dock_distance_y = tour_element.dist_to_dock_y;
407        let tour_dock_diffuse_selectors = tour_element.diffuse;
408        let tour_dock_lightup_selectors = tour_element.lightup;
409        let tour_dock_functions_before = tour_element.functions_before;
410        let tour_dock_functions_on = tour_element.functions_on;
411        let tour_dock_functions_off = tour_element.functions_off;
412				
413
414		
415		//Dock ID
416        let tour_dock = $(tour_element.dock_selector);
417		let tour_dock_id = $(tour_element.dock_selector).attr('id');
418		
419		//wenn ein dockselector angegeben, aber nicht gefunden wurden, dann überspringen
420		if ( tour_element.dock_selector && tour_element.dock_selector.search('dsg-usmo-edit') === -1 && !tour_dock.length ) {
421			return;
422		}
423
424		if (!tour_dock_id) {
425		  tour_dock_id = 'dock_' + Math.random().toString(36).substr(2, 9);
426		  $(tour_element.dock_selector).attr('id', tour_dock_id);
427		}
428		
429				// console.log("step2:"+step);
430		//Steps
431		let step_current_counter = tour_keys.indexOf(step) + 1;
432		let step_all = tour_keys.length;
433		
434		if (step_current_counter === 1) {
435			
436			tour_buttons_first  = '';
437			
438		} else {
439			
440			tour_buttons_first  = '<div class="button-tour button-tour-previous dsg-ttip dsg-ttip-activate" title="Zum vorhergigen Schritt der Tour">Zur&uuml;ck</div>';
441			
442		}
443
444		if (step_current_counter == step_all ) {
445			
446			tour_buttons_last  = '<div class="button-tour button-tour-close dsg-ttip dsg-ttip-activate" title="Tour schließen">Schlie&szlig;en</div>';
447			
448		} else {
449			
450			tour_buttons_last  = '<div class="button-tour button-tour-next dsg-ttip dsg-ttip-activate" title="Zum nächsten Schritt der Tour">Vor</div>';
451			
452		}		
453
454		
455        let tour_buttons = `
456		    <div class="tour-steps dsg-ttip dsg-ttip-activate" title="Ihr Tour-Fortschritt">Schritt ${step_current_counter}/${step_all}</div>
457			<div class="tour-buttons">
458				${tour_buttons_first}
459				${tour_buttons_last}
460			</div>
461			<div class="button-tour-stop dsg-ttip dsg-ttip-activate" title="Klicken Sie bitte hier, um die Tour abzubrechen"><span class="text">Abbrechen</span></div>
462			<div class="button-tour-noblink dsg-ttip dsg-ttip-activate" title="Mit dieser Einstellung können Sie das Blinken der bei der Tour angesteuerten Elemente abschalten. Die Einstellung wird in Ihrem Browser gespeichert, bis sie per Klick abgewählt wird."><span class="text">Blinken aus</span></div>
463            `;
464
465		let element_id = `dsg-tour-wrap-${step}`;
466		
467        let tour_dom_element = `
468            <div id="${element_id}" class="dsg-tour-wrap ${tour_css_class}" data-tour_id="${element_id}" data-step="${step}" data-lightup_selectors = "${tour_dock_lightup_selectors}">
469				<div class="dsg-tour-element-card">
470					<div class="dsg-tour-element-inner">
471						<div class="tour-content-wrap">
472							<div class="tour-title">${tour_title}</div>
473							<div class="tour-text">${tour_text}</div>
474							<div class="tour-infobut">${tour_buttons}</div>
475						</div>
476					</div>
477				</div>
478            </div>`;
479
480		//Funktion vor Start
481		if ( tour_dock_functions_before ) {
482		
483		// console.log("funk: " + tour_dock_functions_before);
484			
485			dsg_tour_functions_before ( element_id, tour_dock_functions_before );	
486			
487			wait_to_execute_ms = 20;
488			
489		} else {
490		
491			wait_to_execute_ms = 20;
492		
493		}
494		
495		setTimeout(function() {
496			
497			$(".dsg-tour-wrap").remove();
498			$("body").append(tour_dom_element);
499			
500			setTimeout(function() {
501				dsg_tooltip_activate( $('.dsg-tour-wrap'), ''); 
502			}, 10);	
503			
504
505			//Funktion bei Start
506			if ( tour_dock_functions_on ) dsg_tour_functions_on ( element_id, tour_dock_functions_on );	
507			
508			//Funktion wenn Element geschlossen wird
509			if ( tour_dock_functions_off ) dsg_tour_functions_off ( element_id, tour_dock_functions_off );
510			
511			//Tour Element entsprechend dem Dockingselektor platzieren
512			dsg_tour_docking( element_id, tour_element, false );
513			
514			//Elemente ausblenden
515			if ( tour_dock_diffuse_selectors ) dsg_tour_diffuse ( element_id, tour_dock_diffuse_selectors );
516
517			
518			//Elemente flashen
519			if ( tour_dock_lightup_selectors ) dsg_tour_lightup ( element_id, tour_dock_lightup_selectors );
520			// dsg_tour_noblink("icon"); //Blinken ggf ausschlaten und richtig icon anzeigen 
521
522			// Store the keys (properties) in an array
523			const tour_keys = Object.keys(tour_elements_obj).map(Number);
524
525
526			// Button Events
527			$(".button-tour-previous").on("click", function () {
528			  const currentIndex = getCurrentIndex();
529			  if (currentIndex > 0) {
530				step_current = tour_keys[currentIndex - 1];
531				display_tour_element(step_current);
532			  }
533			});
534
535			$(".button-tour-next").on("click", function () {
536				
537			  const currentIndex = getCurrentIndex();
538			  if (currentIndex < tour_keys.length - 1) {
539				step_current = tour_keys[currentIndex + 1];
540				display_tour_element(step_current);
541			  }
542			});
543			
544			$(".button-tour-restart").on("click", function () {
545				
546				dsg_tour_end();
547			
548				setTimeout(() => {
549				  dsg_tour_start();
550				}, 20);
551			});		
552			
553			$(".button-tour-end-button, .button-tour-close, .button-tour-stop").on("click", function () {
554				dsg_tour_end();
555			});
556
557			
558		}, wait_to_execute_ms);
559
560    }
561
562		
563//===================================================================================    
564//
565// Tour - Keypress events
566//
567//====================================================================================
568// Keypress events
569$(document).on("keydown", function (event) {
570  // Check if .dsg-tour-wrap element is visible
571  if (!$(".dsg-tour-wrap").is(":visible")) {
572    return;
573  }
574
575  const key = event.key;
576  const currentIndex = getCurrentIndex();
577  
578  event.preventDefault(); // Prevent default  key behavior
579
580  if (key === "ArrowRight" || key === "PageUp" || key === "Enter") {
581    if (currentIndex < tour_keys.length - 1) {
582      step_current = tour_keys[currentIndex + 1];
583      display_tour_element(step_current);
584    }
585  } else if (key === "ArrowLeft" || key === "PageDown") {
586    if (currentIndex > 0) {
587      step_current = tour_keys[currentIndex - 1];
588      display_tour_element(step_current);
589    }
590  } else if (key === " ") { // Space key as 'next'
591    if (currentIndex < tour_keys.length - 1) {
592      step_current = tour_keys[currentIndex + 1];
593      display_tour_element(step_current);
594    }
595  } else if (key === "Backspace") { // Backspace key as 'previous'
596    if (currentIndex > 0) {
597      step_current = tour_keys[currentIndex - 1];
598      display_tour_element(step_current);
599    }
600  } else if (key === "Escape") {
601    dsg_tour_end();
602  }
603});
604
605	
606//===================================================================================    
607//
608// Bliken beenden (Epilepsie)
609// steps: click = einstellung ändern
610// icon: nur icon richtig anzeigen
611  // Initial check on page load
612
613  // Bind click event handler to the button, removing any previous handlers first
614  $('body').on('click', '.button-tour-noblink', function() {
615    // console.log('Noblink button clicked');
616    dsg_tour_noblink('click');
617  });
618
619  // Initial state check
620  updateDsgTourState();
621
622
623function updateDsgTourState() {
624  var isDsgTourNoBlink = localStorage.getItem('dsg_tour_noblink') === 'true';
625  // console.log("isDsgTourNoBlink on start: ", isDsgTourNoBlink);
626
627  if (isDsgTourNoBlink) {
628    $('body').addClass('button-tour-noblink');
629  } else {
630    $('body').removeClass('button-tour-noblink');
631  }
632}
633
634function dsg_tour_noblink(type) {
635  var isDsgTourNoBlink = localStorage.getItem('dsg_tour_noblink') === 'true';
636  // console.log("isDsgTourNoBlink before toggle: ", isDsgTourNoBlink);
637  // console.log("Event type: ", type);
638
639  if (type === "click") {
640    if (isDsgTourNoBlink) {
641      // console.log("Toggling off...");
642      localStorage.removeItem('dsg_tour_noblink');
643      $('body').removeClass('button-tour-noblink');
644    } else {
645      // console.log("Toggling on...");
646      localStorage.setItem('dsg_tour_noblink', 'true');
647      $('body').addClass('button-tour-noblink');
648    }
649    // Trigger light-up logic if necessary
650    triggerLightup();
651  }
652}
653
654function triggerLightup() {
655  var tour_wrap_el = $(".dsg-tour-wrap");
656  var tour_id = tour_wrap_el.data("tour_id");
657  var tour_lightup = tour_wrap_el.data("lightup_selectors");
658
659  // console.log("Tour ID: ", tour_id, ", Lightup Selectors: ", tour_lightup);
660
661  dsg_tour_lightup(tour_id, tour_lightup);
662}
663
664
665//
666//====================================================================================
667	
668//===================================================================================    
669//
670// Get Index of object
671//
672//====================================================================================
673
674	// Function to find the index of the current step
675	function getCurrentIndex() {
676	  const index = tour_keys.indexOf(step_current);
677	  return index >= 0 ? index : 0;
678	}
679
680
681
682//===================================================================================    
683//
684// Tour - Stop Tour
685//
686//====================================================================================
687
688
689// Modify the dsg_tour_end function
690function dsg_tour_end() {
691	
692	
693/* 	25.2.25 Close per hand in dsg_tour_functions_css_dsg_tour_all_off()
694
695    const tour_elements_obj = dsg_tour_tour_object( "", "" );
696    
697	step_current = parseInt(Object.keys(tour_elements_obj)[0]);
698	
699	console.dir(step_current);
700	
701	const functions_close = extract_functions_close(tour_elements_obj);
702	    
703    functions_close.forEach(fn => {
704		
705		// console.log('fn 0:'+ fn);
706		
707        if (typeof window[fn] === 'function') {
708			console.log('fn 1:'+ fn);
709            window[fn]();
710        }
711    }); */
712    
713    $(".dsg-tour-wrap").remove();
714	$('.light-up-loop').removeClass('light-up-loop');
715	
716	dsg_tour_functions_css_dsg_tour_all_off();
717	
718	
719	dsg_tour_overlay_end();
720}
721	
722	
723//===================================================================================    
724//
725// Tour - Stop Tour - Extract all "_off" functions from object
726//
727//====================================================================================
728
729// Add this helper function to extract the functions with "_off" at the end
730/* 25.2.25 Close per hand in dsg_tour_functions_css_dsg_tour_all_off()
731function extract_functions_close(tour_elements_obj) {
732	
733    const functions_close = [];
734for (const key in tour_elements_obj) {
735    const element = tour_elements_obj[key];
736    if (element.functions_off) {
737        // console.log('element.functions_off 0: ' + element.functions_off);
738        const functions = element.functions_off.split(',').map(fn => fn.trim());
739        functions_close.push(...functions);
740    }
741
742    if (element.functions_exit) {
743        // console.log('element.functions_exit 0: ' + element.functions_exit);
744        const functions = element.functions_exit.split(',').map(fn => fn.trim());
745        functions_close.push(...functions);
746    }
747}
748
749	
750	// console.dir(functions_close);
751	
752    return functions_close;
753}
754 */
755
756	
757//===================================================================================
758// Tour - Element andocken - Am Ende prüfen, ob sichtbar, sonst nachscrollen
759//====================================================================================
760
761function ensureElementFullyVisible(element) {
762    var rect = element[0].getBoundingClientRect();
763    var margin = 50; // Minimum margin in pixels
764    var viewportHeight = window.innerHeight || document.documentElement.clientHeight;
765    
766    if (rect.top < margin) {
767        // Scroll up to ensure the element is fully visible
768        var scrollUpTo = window.scrollY + rect.top - margin;
769        window.scrollTo({ top: scrollUpTo, behavior: 'smooth' });
770    } else if (rect.bottom > viewportHeight - margin) {
771        // Scroll down to ensure the element is fully visible
772        var scrollDownTo = window.scrollY + (rect.bottom - viewportHeight) + margin;
773        window.scrollTo({ top: scrollDownTo, behavior: 'smooth' });
774    }
775}
776	
777//===================================================================================
778// Tour - Element andocken
779//====================================================================================
780
781
782function dsg_tour_docking(element_id, tour_element, isRetry) {
783    let dock_selector = tour_element.dock_selector;
784    let distance_x = tour_element.dist_to_dock_x;
785    let distance_y = tour_element.dist_to_dock_y;
786    let given_position = tour_element.position;
787    var element = $('#' + element_id);
788
789    // Initially hide the element
790    element.css({ display: 'none' });
791
792    // Check if a valid dock selector is provided
793    if (!dock_selector) {
794        dsg_tour_docking_center(element);
795        return;
796    }
797
798    var dock = $(dock_selector);
799
800    if (!dock.length) {
801        dsg_tour_docking_center(element);
802        return;
803    }
804
805    scrollDockIfNeeded(element, dock).then(function(dockScrolled) {
806        var dockOffset = dock.offset();
807        var dockWidth = dock.outerWidth();
808        var dockHeight = dock.outerHeight();
809        var elementWidth = element.outerWidth();
810        var elementHeight = element.outerHeight();
811        
812        var positions = dsg_tour_docking_get_positions(
813            dock, dockOffset, dockWidth, dockHeight, elementWidth, elementHeight, distance_x, distance_y
814        );
815        
816        var bestPosition = dsg_tour_docking_find_best_position(
817            given_position, positions, elementWidth, elementHeight, dockOffset, dockWidth, dockHeight
818        );
819        
820        dsg_tour_docking_set_position(element, bestPosition);
821        
822        // Show the element after positioning
823        element.css({ display: 'block' });
824        
825        ensureElementFullyVisible(element); // Ensure it's fully visible after positioning
826        
827        if (dockScrolled && !isRetry) {
828            dsg_tour_docking(element_id, tour_element, true);
829        } else if (dock_selector) {
830            dsg_tour_triangle(element_id, dock_selector, tour_element);
831        }
832    });
833}
834
835
836
837
838function dsg_tour_docking_center(element) {
839  var windowWidth = $(window).width();
840  var windowHeight = $(window).height();
841  var elementWidth = element.outerWidth();
842  var elementHeight = element.outerHeight();
843
844  element.css({
845    position: 'fixed', // Use 'fixed' for centering
846    left: (windowWidth - elementWidth) / 2,
847    top: (windowHeight - elementHeight) / 2,
848    display: 'block' // Ensure it is visible here
849  });
850}
851
852function dsg_tour_docking_get_positions(dock, dockOffset, dockWidth, dockHeight, elementWidth, elementHeight, distance_x, distance_y) {
853    return [
854        { x: dockOffset.left - elementWidth - distance_x, y: dockOffset.top + (dockHeight / 2) - (elementHeight / 2) }, // left
855        { x: dockOffset.left + dockWidth + distance_x, y: dockOffset.top + (dockHeight / 2) - (elementHeight / 2) }, // right
856        { x: dockOffset.left + (dockWidth / 2) - (elementWidth / 2), y: dockOffset.top - elementHeight - distance_y }, // above
857        { x: dockOffset.left + (dockWidth / 2) - (elementWidth / 2), y: dockOffset.top + dockHeight + distance_y }, // below
858    ];
859}
860
861
862
863function dsg_tour_docking_find_best_position(given_position, positions, elementWidth, elementHeight, dockOffset, dockWidth, dockHeight) {
864    var bestPosition;
865    var windowWidth = $(window).width();
866    var windowHeight = $(window).height();
867    var margin = 30; // Safety margin
868
869    // Try to place the element above first
870    var abovePosition = positions[2]; // The "above" position is at index 2 in the array
871
872    if (abovePosition && abovePosition.y > margin) {
873        return abovePosition; // Choose above if it fits
874    }
875
876    // If above is not possible, try below
877    var belowPosition = positions[3]; // The "below" position is at index 3
878
879    if (belowPosition && belowPosition.y + elementHeight < windowHeight - margin) {
880        return belowPosition; // Choose below if it fits
881    }
882
883    // If above/below do not work, fall back to side positions
884    positions.forEach((position, index) => {
885        var score = 0;
886
887        // Left or right placement should not occlude the dock
888        if (index < 2) {
889            const isWithinDockHeight = (
890                position.y < dockOffset.top + dockHeight &&
891                position.y + elementHeight > dockOffset.top
892            );
893            if (!isWithinDockHeight) {
894                score -= 1000; // Prioritize this option
895            }
896        }
897
898        // Penalize positions that are too close to the viewport edges
899        if (position.x < margin) {
900            score += margin - position.x;
901        } else if (position.x + elementWidth > windowWidth - margin) {
902            score += (position.x + elementWidth) - (windowWidth - margin);
903        }
904
905        if (position.y < margin) {
906            score += margin - position.y;
907        } else if (position.y + elementHeight > windowHeight - margin) {
908            score += (position.y + elementHeight) - (windowHeight - margin);
909        }
910
911        if (!bestPosition || score < bestPosition.score) {
912            bestPosition = { ...position, score: score };
913        }
914    });
915
916    return bestPosition;
917}
918
919
920
921function dsg_tour_docking_set_position(element, bestPosition) {
922    // Get document dimensions
923    var documentWidth = $(document).width();
924    var documentHeight = $(document).height();
925    var elementWidth = element.outerWidth();
926    var elementHeight = element.outerHeight();
927    var margin = 30; // Safety margin
928
929    // Allow positioning relative to the entire document width and height
930    bestPosition.x = Math.max(margin, Math.min(bestPosition.x, documentWidth - elementWidth - margin));
931    bestPosition.y = Math.max(margin, Math.min(bestPosition.y, documentHeight - elementHeight - margin));
932
933    // Set the element's position
934    element.css({
935        position: 'absolute',
936        left: bestPosition.x,
937        top: bestPosition.y,
938    });
939}
940
941
942function scrollDockIfNeeded(element, dock) {
943    var dockOffset = dock.offset();
944    var dockWidth = dock.outerWidth();
945    var dockHeight = dock.outerHeight();
946    var viewportTop = $(window).scrollTop();
947    var viewportBottom = viewportTop + $(window).height();
948    var viewportHeight = $(window).height();
949    var viewportLeft = $(window).scrollLeft();
950    var viewportRight = viewportLeft + $(window).width();
951
952    // Determine if the dock's position requires scrolling
953    var isDockLowestPartInUpperThird = (dockOffset.top + dockHeight) <= (viewportTop + viewportHeight / 3);
954    var isDockHighestPartInLowerThird = dockOffset.top >= (viewportTop + (2 * viewportHeight / 3));
955
956    // console.log("Checking dock position:");
957    // console.log("Viewport top:", viewportTop);
958    // console.log("Viewport bottom:", viewportBottom);
959    // console.log("Dock top:", dockOffset.top);
960    // console.log("Dock bottom:", dockOffset.top + dockHeight);
961
962    return new Promise((resolve) => {
963        let scrollTop = viewportTop;
964
965        // Adjust vertical scroll position
966        if (isDockLowestPartInUpperThird) {
967            // console.log("Dock's lower edge is in the upper third of the screen or above. Scrolling down to center.");
968            scrollTop = dockOffset.top + (dockHeight ) - (viewportHeight / 2);
969        } else if (isDockHighestPartInLowerThird) {
970            // console.log("Dock's upper edge is in the lower third of the screen or below. Scrolling up to center.");
971            scrollTop = dockOffset.top + (dockHeight ) - (viewportHeight / 2);
972        } else {
973            // console.log("Dock is already centered or does not require scrolling.");
974        }
975
976        // Calculate duration based on distance
977        const distanceY = Math.abs(scrollTop - viewportTop);
978        const speedLimit = 2; // Pixels per millisecond
979        const minDuration = 150; // Minimum duration in milliseconds for a smooth scroll
980        const scrollDuration = Math.max(distanceY / speedLimit, minDuration);
981
982        // Perform scrolling animation
983        $('html, body').animate({ scrollTop: scrollTop }, {
984            duration: scrollDuration,
985            easing: 'swing', // Default jQuery easing function
986            complete: function() {
987                resolve(isDockLowestPartInUpperThird || isDockHighestPartInLowerThird);
988            }
989        });
990    });
991}
992
993
994
995
996/*===================================================================================    
997//
998// Tour - Element Dreieck erstellen (vor der Platzierung wegen der Größenmessung)
999//
1000//====================================================================================*/
1001
1002
1003function dsg_tour_triangle(element_id, dock_selector, tour_element) {
1004    var element = $('#' + element_id);
1005    var dock = $(dock_selector);
1006
1007    if (!element.length || !dock.length) {
1008        console.warn(`Element or dock not found. element_id: ${element_id}, dock_selector: ${dock_selector}`);
1009        return;
1010    }
1011
1012    var elemPos = element.offset();
1013    var dockPos = dock.offset();
1014    var elemBottom = elemPos.top + element.outerHeight();
1015    var dockBottom = dockPos.top + dock.outerHeight();
1016    var closestSide;
1017
1018    // console.log("Element position:", elemPos);
1019    // console.log("Dock position:", dockPos);
1020    // console.log("Element bottom:", elemBottom, "Dock bottom:", dockBottom);
1021
1022    // Determine if the dock is above or below the element
1023    if (elemPos.top > dockBottom) {
1024        closestSide = 'top'; // Element is below, triangle should be on top
1025        // console.log("Dock is above the element. Closest side: top");
1026    } else if (elemBottom < dockPos.top) {
1027        closestSide = 'bottom'; // Element is above, triangle should be on bottom
1028        // console.log("Dock is below the element. Closest side: bottom");
1029    } else if (elemPos.left > dockPos.left + dock.outerWidth()) {
1030        closestSide = 'left'; // Dock is to the left of the element
1031        // console.log("Dock is to the left of the element. Closest side: left");
1032    } else if (elemPos.left + element.outerWidth() < dockPos.left) {
1033        closestSide = 'right'; // Dock is to the right of the element
1034        // console.log("Dock is to the right of the element. Closest side: right");
1035    } else {
1036        closestSide = 'bottom'; // Default to bottom if no clear side is determined
1037        // console.log("Default closest side: bottom");
1038    }
1039
1040    // Add classes to the element for styling
1041    element.removeClass('top bottom left right').addClass(closestSide);
1042
1043    // Create and position the triangle
1044    var triangle = $('<div>').addClass('tour-triangle').addClass(closestSide);
1045    var trianglePosition = dockPos.left + dock.outerWidth() / 2 - elemPos.left - triangle.outerWidth() / 2;
1046
1047    // console.log("Calculated triangle position:", trianglePosition);
1048
1049    if (closestSide === 'bottom') {
1050        triangle.css({
1051            'left': Math.min(Math.max(trianglePosition, 30), element.outerWidth() - triangle.outerWidth() - 30),
1052            'top': element.outerHeight() // Align at the bottom of the element
1053        });
1054    } else if (closestSide === 'top') {
1055        triangle.css({
1056            'left': Math.min(Math.max(trianglePosition, 30), element.outerWidth() - triangle.outerWidth() - 30),
1057            'bottom': element.outerHeight() // Align at the top of the element
1058        });
1059    } else if (closestSide === 'left') {
1060        var topPosition = dockPos.top + dock.outerHeight() / 2 - elemPos.top - triangle.outerHeight() / 2;
1061        triangle.css({
1062            'top': Math.min(Math.max(topPosition, 30), element.outerHeight() - triangle.outerHeight() - 30),
1063            'right': element.outerWidth() // Align at the left of the element
1064        });
1065    } else if (closestSide === 'right') {
1066        var topPosition = dockPos.top + dock.outerHeight() / 2 - elemPos.top - triangle.outerHeight() / 2;
1067        triangle.css({
1068            'top': Math.min(Math.max(topPosition, 30), element.outerHeight() - triangle.outerHeight() - 30),
1069            'left': element.outerWidth() // Align at the right of the element
1070        });
1071    }
1072
1073    element.append(triangle);
1074
1075    // console.log("Triangle placed:", closestSide);
1076}
1077
1078
1079
1080
1081/*===================================================================================    
1082//
1083// Tour - Funktionen, die vor dem Start des Tourelements auszuführen sind
1084//
1085//====================================================================================*/
1086function dsg_tour_functions_before(element_id, functions_before) {
1087
1088  if (functions_before) {
1089	   
1090    var functionArray = functions_before.split(',');
1091    
1092    functionArray.forEach(function(function_before) {
1093		
1094      var trimmedFunction = function_before.trim().replace(/\s+$/, '');
1095
1096	
1097	
1098      // Check if the function exists before calling it
1099      if (typeof window[trimmedFunction] === 'function') {
1100
1101        window[trimmedFunction]();
1102      }
1103      
1104      // Add a unique class name to the element
1105      $(element_id).addClass(trimmedFunction);
1106    });
1107  } 
1108
1109}
1110
1111/*===================================================================================    
1112//
1113// Tour - Funktionen, die mit dem Start des Tourelements auszuführen sind - müssen in windows registriert werden
1114//
1115//====================================================================================*/
1116function dsg_tour_functions_on(element_id, functions_on) {
1117
1118	//console.log("TESTING1.---------function_on: "+ functions_on);
1119	
1120  if (functions_on) {
1121    var functionArray = functions_on.split(',');
1122    
1123    functionArray.forEach(function(function_on) {
1124		
1125      var trimmedFunction = function_on.trim().replace(/\s+$/, '');
1126
1127	//console.log("TESTING2.---------function_on: "+ trimmedFunction);
1128	
1129      // Check if the function exists before calling it
1130      if (typeof window[trimmedFunction] === 'function') {
1131
1132	//console.log("TESTING3.---------function_on: "+ trimmedFunction);
1133	
1134        window[trimmedFunction]();
1135      }
1136      
1137      // Add a unique class name to the element
1138      $(element_id).addClass(trimmedFunction);
1139    });
1140  } 
1141
1142}
1143
1144/*===================================================================================    
1145//
1146// Tour - Funktionen, die mit dem Schließen des Tourelements auszuführen sind
1147//
1148//====================================================================================*/
1149var dsg_tour_functions_off_intervalMap = {}; // Object to store and manage intervals
1150
1151function dsg_tour_functions_off(element_id, functions_off) {
1152  if (functions_off) {
1153    var functionArray = functions_off.split(',');
1154
1155    functionArray.forEach(function (function_off) {
1156      var trimmedFunction = function_off.trim().replace(/\s+$/, '');
1157
1158      if (typeof window[trimmedFunction] === 'function') {
1159        // Create a unique identifier based on element_id and function name
1160        var intervalId = element_id + "_" + trimmedFunction;
1161
1162        // Clear any existing interval with the same id
1163        if (dsg_tour_functions_off_intervalMap[intervalId]) {
1164          clearInterval(dsg_tour_functions_off_intervalMap[intervalId]);
1165        }
1166
1167        dsg_tour_functions_off_intervalMap[intervalId] = setInterval(function () {
1168          var element = $('#' + element_id);
1169
1170          // Check if the element is not in the DOM or not visible
1171          if (element.length === 0 || !element.is(':visible')) {
1172            // Execute the function (aber etw später, damit das element das überwacht wird, überhaupt geöffnet wird)
1173			// console.log("TESTING.---------functions_off ("+ dsg_tour_functions_off_intervalMap[intervalId]+"): " + functions_off);
1174            setTimeout(function() {
1175              
1176              window[trimmedFunction]();
1177            }, 30);
1178
1179            // Clear the interval to stop checking
1180            clearInterval(dsg_tour_functions_off_intervalMap[intervalId]);
1181            // Remove the interval from the dsg_tour_functions_off_intervalMap object
1182            delete dsg_tour_functions_off_intervalMap[intervalId];
1183          }
1184        }, 100); // Check every 100ms
1185      }
1186    });
1187  }
1188}
1189
1190
1191
1192/*===================================================================================    
1193//
1194// Tour - Elemente in den Hintergrund treten lassen
1195//
1196//====================================================================================*/
1197// Create an object to store intervals
1198var intervals = {};
1199
1200function dsg_tour_lightup(element_id, selectors) {
1201
1202    var isDsgTourNoBlink = localStorage.getItem('dsg_tour_noblink') === 'true';
1203	
1204	// console.log("dsg_tour_noblink 4="+isDsgTourNoBlink);
1205
1206   
1207		
1208	if (isDsgTourNoBlink) {
1209		
1210		$('.light-up-loop').removeClass('light-up-loop');		
1211		
1212	} else if (element_id && selectors) {
1213	  
1214		$('.light-up-loop').removeClass('light-up-loop');
1215		var selectorArray = selectors.split(',');
1216		selectorArray.forEach(function (selector) {
1217		  var trimmedSelector = selector.trim();
1218		  $(trimmedSelector).addClass('light-up-loop');
1219
1220		  // If an interval already exists for this element_id, clear it
1221		  if (intervals[element_id]) {
1222			clearInterval(intervals[element_id]);
1223		  }
1224
1225		  // Create a new interval for this element_id
1226		  intervals[element_id] = setInterval(function() {
1227			var element = $('#'+element_id);
1228			
1229			 // console.log("CHECKING:  " + element_id);
1230			
1231			  if(!element.length) {
1232				// console.log("REMOOOOOOOVING ");
1233				$(trimmedSelector).removeClass('light-up-loop');
1234				clearInterval(intervals[element_id]); // Clear the interval
1235			  }
1236		  }, 100);
1237		});
1238	  } 
1239  
1240}
1241
1242
1243
1244/*===================================================================================    
1245//
1246// Tour - Elemente in den Hintergrund treten lassen
1247//
1248//====================================================================================*/
1249function dsg_tour_diffuse(element_id, selectors) {
1250	
1251  var element = $('#' + element_id);
1252  var uniqueClassName = "opacity-set-" + element_id + "-" + Date.now();
1253
1254  // Create a style element and add the opacity style for the uniqueClassName
1255  var style = document.createElement('style');
1256  style.setAttribute('data-id', uniqueClassName);
1257  style.innerHTML = '.' + uniqueClassName + ' { opacity: 0.3 !important; }';
1258  document.head.appendChild(style);
1259
1260  if (selectors) {
1261    var selectorArray = selectors.split(',');
1262    selectorArray.forEach(function (selector) {
1263      var trimmedSelector = selector.trim();
1264      $(trimmedSelector).addClass(uniqueClassName);
1265    });
1266  } else {
1267    element.addClass(uniqueClassName);
1268  }
1269
1270  // Listen for visibility changes of the element
1271  var observer = new MutationObserver(function (mutations) {
1272    mutations.forEach(function (mutation) {
1273      if (mutation.type === 'childList' && !document.contains(element[0])) {
1274        // Remove the unique class from elements and delete the style
1275        if (selectors) {
1276          selectorArray.forEach(function (selector) {
1277            var trimmedSelector = selector.trim();
1278            $(trimmedSelector).removeClass(uniqueClassName);
1279          });
1280        } else {
1281          element.removeClass(uniqueClassName);
1282        }
1283        // Remove the style element from the DOM
1284        //document.head.removeChild(style);
1285        $('style[data-id="'+uniqueClassName+'"]').remove();
1286        observer.disconnect();
1287      }
1288    });
1289  });
1290
1291  // Configure the observer and start observing
1292  var config = { childList: true, subtree: true };
1293  observer.observe(document.body, config);
1294}
1295
1296
1297
1298//===================================================================================    
1299//
1300// Generate Tour  Anzeige mini-DSG
1301//
1302// positions: above, below,right,left
1303//====================================================================================
1304function dsg_tour_tour_minidsg(col_number) {
1305    let col1 = "";
1306    let col2 = "";
1307    let col3 = "";
1308
1309    if (col_number === 1) col1 = "active";
1310    if (col_number === 2) col2 = "active";
1311    if (col_number === 3) col3 = "active";
1312
1313    const minidsg = `
1314        <div class="dsg-tour-mini-column-wrap">
1315            <div class="dsg-tour-mini-column-container">
1316                <div class="mini-col ${col1}"></div>
1317                <div class="mini-col ${col2}"></div>
1318                <div class="mini-col ${col3}"></div>
1319            </div>
1320        </div>
1321    `;
1322    
1323    return minidsg;
1324}
1325
1326//===================================================================================    
1327//
1328// Generate Tour
1329//
1330// positions: above, below,right,left
1331//
1332// category = Kann Nr oder Alpha sein, muss bei If abgebildet sein. // Leer lassen, um automatisch auszulesen
1333// status = free/premium // Leer lassen, um automatisch auszulesen
1334//
1335//====================================================================================
1336function dsg_tour_tour_object(category, status) {
1337	
1338	// tour_elements_obj_stored = JSON.parse( localStorage.getItem('tour_elements_obj') );
1339	
1340	 // if (tour_elements_obj_stored) {
1341		 // console.log("TOUR OBJ IN CACHE");
1342		 // console.dir(tour_elements_obj_stored);
1343		 // return tour_elements_obj_stored;
1344	// }
1345
1346	 
1347	//Category auto einfügen
1348    if (!category || category === "") {
1349		
1350		if (window.location.href.includes("/mein-konto/dokumente")) {
1351        
1352			category = "meinedokumente"; // Update current category
1353		
1354		} else if (!category_current || category_current === "") {
1355            category = category_current; // Default category if nothing is set
1356        } else {
1357             category = $('#dsg-category-current').val(); // Default category if nothing is set
1358        }
1359    } 
1360	
1361	//Status autoeinfügen
1362	if (!status || status === "") {
1363	 let status = $('body').hasClass('dsg-premium-free') ? "free" : "premium";
1364	}
1365
1366		
1367	// console.log("category: "+category);
1368	
1369    // Start of the tour
1370    var tour_elements_obj_start = {
1371        30: {
1372            title: 'Willkommen zur Tour',
1373            status: "premium,free,premiumtest",
1374            css_class: 'dsg-tour-element dsg-tour-navigation',
1375            text: '<p>Während der Tour erfahren Sie, wie unser Generator funktioniert.</p><p>Sie können die Tour auch mit den Pfeil-Tasten Ihrer Tastatur steuern und sie mit der "Esc"-Taste jederzeit beenden.</p>',
1376            dock_selector: '',
1377            dist_to_dock_x: 0,
1378            dist_to_dock_y: 0,
1379            diffuse: '#header, #main, #dsg-out-generate-do-wrap, #colophon',
1380            functions_on: 'dsg_tour_functions_document_scroll_top, dsg_tour_functions_13_premium_off',
1381        }
1382    };
1383	
1384    // Start of the tour
1385    var tour_elements_obj_save = {
1386        40: {
1387            title: 'Speicherung Ihrer Eingaben',
1388            status: "free,premiumtest",
1389            css_class: 'dsg-tour-element dsg-tour-navigation',
1390            text: '<p>Hinweis vorab: Ihre Eingaben werden automatisch gespeichert (rotierendes Speichern-Symbol).</p>',
1391            dock_selector: '#dsg-cookie-header-wrap-li',
1392            dist_to_dock_x: 0,
1393            dist_to_dock_y: 30,
1394            diffuse: '#header .logo-item, #header #primary-menu li:not(#dsg-cookie-header-wrap-li) , #main, #dsg-out-generate-do-wrap, #colophon',
1395            functions_on: 'dsg_tour_functions_save_on_autooff',
1396        }
1397    };
1398
1399    // Languages and Seals 
1400    var tour_elements_obj_languages = {
1401
1402            50: {
1403                title: 'Sprachauswahl und Siegelvorschau' ,
1404				status: "premiumtest",
1405                css_class: 'dsg-tour-element dsg-tour-navigation',
1406                text: 'Hier können Sie die Sprache auswählen und sich die Vorschau unseres Siegels anzeigen lassen.',
1407				dock_selector: '#dsg-group-premium .group-title',
1408				dist_to_dock_x: 40,
1409				dist_to_dock_y: 40,
1410				diffuse: '#header,  #dsg-projects-loading-lp, .dsg-group:not(#dsg-group-urlscan), #individualarea, #dsg-group-urlscan, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon, .divider-heading',
1411				lightup: '#dsg-group-premium',
1412				functions_before: '',
1413				functions_on: 'dsg_tour_functions_13_scan_off, dsg_tour_functions_13_premium_on',
1414				functions_off: '',
1415            },
1416	}; 
1417	
1418    // Languages and Seals 
1419    var tour_elements_obj_languages = {
1420
1421            60: {
1422                title: 'Sprachauswahl und Siegelvorschau' ,
1423				status: "premiumtest",
1424                css_class: 'dsg-tour-element dsg-tour-navigation',
1425                text: 'Hier können Sie die Sprache auswählen und sich die Vorschau unseres Siegels anzeigen lassen.',
1426				dock_selector: '#dsg-group-premium .group-title',
1427				dist_to_dock_x: 40,
1428				dist_to_dock_y: 40,
1429				diffuse: '#header,  #dsg-projects-loading-lp, .dsg-group:not(#dsg-group-urlscan), #individualarea, #dsg-group-urlscan, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon, .divider-heading',
1430				lightup: '#dsg-group-premium',
1431				functions_before: '',
1432				functions_on: 'dsg_tour_functions_13_scan_off, dsg_tour_functions_13_premium_on',
1433				functions_off: '',
1434            },
1435	};    
1436	
1437	// Schnellauswahl 
1438    var tour_elements_obj_schnellauswahl = {
1439      
1440			75: {
1441                title: 'Schnellauswahl',
1442				status: "premium,free,premiumtest",
1443                css_class: 'dsg-tour-element dsg-tour-modules',
1444                text: '<p>Mit Hilfe der Schnellauswahl können Sie die wichtigsten Bestandteile Ihres Dokuments auswählen.',
1445				dock_selector: '#dsg-out-group-presets',
1446				dist_to_dock_x: 50,
1447				dist_to_dock_y: 30,
1448				lightup: '#dsg-out-group-presets',
1449				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(#dsg-out-group-presets), #dsg-group-premium, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1450				functions_before: '',
1451				functions_off: '',				
1452            },    
1453	
1454	};
1455
1456    // Generate 
1457    var tour_elements_obj_generate = {
1458
1459		5000: {
1460				title: 'Dokument erstellen' ,
1461				status: "premium,free,premiumtest",
1462				css_class: 'dsg-tour-element dsg-tour-modules',
1463				text: '<p>Wenn Sie alle Module ausgewählt haben, können Sie diese Schalfläche anklicken, um Ihr Dokument fertigzustellen.</p>',
1464				dock_selector: '#dsg-out-generate-do-button-wrap',
1465				dist_to_dock_x: 40,
1466				dist_to_dock_y: 30,
1467				lightup: '#dsg-out-generate-do-button-wrap',
1468				diffuse: '#header,#dsg-projects-loading-lp, .dsg-group, #dsg-out-group-search, #colophon, #dsg-out-generate-check-terms, .dsg-generate-domain-entry',
1469				functions_before: 'dsg_tour_functions_generation_wrap_on',
1470				functions_off: '',				
1471		},
1472	};
1473
1474	
1475    // End of the tour
1476    var tour_elements_obj_end = {
1477        10000: {
1478            title: 'Tour erfolgreich beendet',
1479            status: "premium,free,premiumtest",
1480            css_class: 'dsg-tour-element dsg-tour-document-saving',
1481            text: '<p>Herzlichen Glückwunsch! Sie kennen jetzt die Funktionen des Generators.</p><p>P.S. Sie können die Tour jederzeit wieder starten und falls Sie noch Fragen haben, <a href="https://datenschutz-generator.de/kontakt-faq/" target="_blank">nutzen Sie unsere FAQ</a>.</p>',
1482            dock_selector: '',
1483            diffuse: '#header, #main, #colophon, #dsg-out-generate-do-wrap, #colophon',
1484            dist_to_dock_x: 0,
1485            dist_to_dock_y: 0,
1486            functions_before: 'dsg_tour_functions_generation_wrap_off, dsg_tour_functions_document_scroll_top,dsg_tour_functions_css_dsg_tour_anbieter_off, dsg_tour_functions_css_dsg_tour_regmodule_off, dsg_tour_functions_css_dsg_tour_regoption_off',
1487            functions_off: '',
1488            functions_exit: '',
1489        }
1490    };
1491
1492    // Core tour elements (Category-specific)
1493    let tour_elements_obj_category  = {};
1494    let tour_elements_obj_core = {};
1495	
1496	
1497
1498	
1499	//*KATEGORIE: MEINE DOKUMENTE *//
1500	
1501
1502
1503    if ( category === "meinedokumente") {
1504		
1505        tour_elements_obj_category = {
1506			100: {
1507				title: 'Willkommen zur Tour',
1508				status: "premium,free,premiumtest",
1509				css_class: 'dsg-tour-element dsg-tour-navigation',
1510				text: '<p>
1510Während der Tour erfahren Sie, wie Ihre Dokumentenübersicht aufgebaut ist und Sie Ihre Dokumente effektiv bearbeiten und verwalten können.</p><p>Sie können die Tour auch mit den Pfeil-Tasten Ihrer Tastatur steuern und sie mit der "Esc"-Taste jederzeit beenden.</p>',
1511				dock_selector: '',
1512				dist_to_dock_x: 0,
1513				dist_to_dock_y: 0,
1514				diffuse: '#header, #main, #colophon, .entry-header, .woocommerce-MyAccount-navigation, .select-items, .my_account_subscriptions',
1515				functions_on: 'dsg_tour_functions_document_scroll_top',
1516			},			
1517            200: {
1518                title: 'Liste Ihrer Dokumente' ,
1519				status: "",
1520                css_class: 'dsg-tour-element dsg-tour-navigation',
1521                text: '<p>In der Liste erhalten Sie eine Übersicht Ihrer Dokumente und können diese sortieren, indem Sie die Dokumente per Mausklick greifen und bewegen. Änderungen werden automatisch gespeichert.',
1522				dock_selector: '.select-selected',
1523				dist_to_dock_x: 40,
1524				dist_to_dock_y: 40,
1525				diffuse: '#header, #colophon, .entry-header, .woocommerce-MyAccount-navigation, .my_account_subscriptions',
1526				lightup: '.select-selected',
1527				functions_before: '',
1528				functions_on: 'dsg_tour_functions_mydocs_list_on',
1529				functions_off: '',
1530            },
1531            300: {
1532                title: 'Lizenznummer' ,
1533				status: "",
1534                css_class: 'dsg-tour-element dsg-tour-navigation',
1535                text: 'Dies hier ist die zu dem Dokument gehörende Lizenznummer. Sollten Sie Schwierigkeiten mit einer Lizenz haben, teilen Sie uns bitte deren Nummer mit.',
1536				dock_selector: '.select-items .single-item:first-child .inner-cell-0',
1537				dist_to_dock_x: 40,
1538				dist_to_dock_y: 40,
1539				diffuse: '#header, #colophon, .select-selected, .select-items .single-item:not(:first-child), .entry-header, .woocommerce-MyAccount-navigation, .my_account_subscriptions',
1540				lightup: '.select-items .single-item:first-child .inner-cell-0',
1541				functions_before: '',
1542				functions_on: '',
1543				functions_off: '',
1544            },
1545            400: {
1546                title: 'Name und Art des Dokuments' ,
1547				status: "",
1548                css_class: 'dsg-tour-element dsg-tour-navigation',
1549                text: 'Unten links steht der Name sowie rechts die Art Ihres Dokuments. Wie Sie Dokumente benennen, erfahren Sie gleich im Laufe der Tour.',
1550				dock_selector: '.select-items .single-item:first-child .inner-cell-2',
1551				dist_to_dock_x: 40,
1552				dist_to_dock_y: 40,
1553				diffuse: '#header, #colophon, .select-selected, .select-items .single-item:not(:first-child), .entry-header, .woocommerce-MyAccount-navigation, .my_account_subscriptions',
1554				lightup: '.select-items .single-item:first-child .inner-cell-2',
1555				functions_before: '',
1556				functions_on: '',
1557				functions_off: '',
1558            },
1559            500: {
1560                title: 'Datum der letzten Bearbeitung' ,
1561				status: "",
1562                css_class: 'dsg-tour-element dsg-tour-navigation',
1563                text: 'Wenn Sie Ihr Dokument bearbeitet haben, sehen Sie an dieser Stelle das Datum der letzten Bearbeitung.',
1564				dock_selector: '.select-items .single-item:first-child .inner-cell-3',
1565				dist_to_dock_x: 40,
1566				dist_to_dock_y: 40,
1567				diffuse: '#header, #colophon, .select-selected, .select-items .single-item:not(:first-child), .entry-header, .woocommerce-MyAccount-navigation, .my_account_subscriptions',
1568				lightup: '.select-items .single-item:first-child .inner-cell-3',
1569				functions_before: '',
1570				functions_on: '',
1571				functions_off: '',
1572            },
1573            600: {
1574                title: 'Dokument bearbeiten' ,
1575				status: "",
1576                css_class: 'dsg-tour-element dsg-tour-navigation',
1577                text: 'Wenn Sie das "Bearbeiten"-Icon anklicken, wird das Dokument im neuen Browser-Tab geöffnet und kann dort bearbeitet werden.',
1578				dock_selector: '.select-items .single-item:first-child .inner-cell-4',
1579				dist_to_dock_x: 40,
1580				dist_to_dock_y: 40,
1581				diffuse: '#header, #colophon, .select-selected, .select-items .single-item:not(:first-child), .entry-header, .woocommerce-MyAccount-navigation, .my_account_subscriptions',
1582				lightup: '.select-items .single-item:first-child .inner-cell-4',
1583				functions_before: '',
1584				functions_on: '',
1585				functions_off: '',
1586            },
1587            700: {
1588                title: 'Detailinformationen zum Dokument und Lizenz' ,
1589				status: "",
1590                css_class: 'dsg-tour-element dsg-tour-navigation',
1591                text: 'Wenn Sie auf das "Info"-Icon klicken, wird unter der Dokumenteliste eine Detailansicht des Dokuments geladen. In dieser finden Sie die Lizenzinformationen und können den Namen des Dokuments ändern.',
1592				dock_selector: '.select-items .single-item:first-child .inner-cell-5',
1593				dist_to_dock_x: 40,
1594				dist_to_dock_y: 40,
1595				diffuse: '#header, #colophon, .select-selected, .select-items .single-item:not(:first-child), .entry-header, .woocommerce-MyAccount-navigation, .my_account_subscriptions',
1596				lightup: '.select-items .single-item:first-child .inner-cell-5',
1597				functions_before: '',
1598				functions_on: '',
1599				functions_off: '',
1600            },
1601            800: {
1602                title: 'Farbliche Kennzeichnung' ,
1603				status: "",
1604                css_class: 'dsg-tour-element dsg-tour-navigation',
1605                text: 'Per Klick auf das "Farbpaletten"-Icon können Sie Ihre Dokumente farblich kennzeichnen (z.B. um sich unbearbeitete Dokumente vorzumerken oder zusammengehörende Dokumente zu gruppieren).',
1606				dock_selector: '.select-items .single-item:first-child .inner-cell-6',
1607				dist_to_dock_x: 40,
1608				dist_to_dock_y: 40,
1609				diffuse: '#header, #colophon, .select-selected, .select-items .single-item:not(:first-child), .entry-header, .woocommerce-MyAccount-navigation, .my_account_subscriptions',
1610				lightup: '.select-items .single-item:first-child .inner-cell-6',
1611				functions_before: 'dsg_tour_functions_mydocs_list_on',
1612				functions_on: '',
1613				functions_off: '',
1614            },
1615			/*
1616            900: {
1617                title: 'Dokumente Favorisieren' ,
1618				status: "",
1619                css_class: 'dsg-tour-element dsg-tour-navigation',
1620                text: 'Wenn Sie das Dokument favorisieren, dann bleibt es in der Liste immer oben, auch wenn neue Dokumente dazukommen.',
1621				dock_selector: '.select-items .single-item:first-child .inner-cell-7',
1622				dist_to_dock_x: 40,
1623				dist_to_dock_y: 40,
1624				diffuse: '#header, #colophon, .select-selected, .select-items .single-item:not(:first-child), .entry-header, .woocommerce-MyAccount-navigation',
1625				lightup: '.select-items .single-item:first-child .inner-cell-7',
1626				functions_before: 'dsg_tour_functions_mydocs_list_on',
1627				functions_on: '',
1628				functions_off: '',
1629            },*/ 
1630            1000: {
1631                title: 'Details zum Dokument und zur Lizenz' ,
1632				status: "",
1633                css_class: 'dsg-tour-element dsg-tour-navigation',
1634                text: 'In der Detailübersicht des Dokuments können Sie insbesondere dessen Namen anpassen und zuletzt erstellte Dokumente herunterladen.',
1635				dock_selector: '.my_account_subscriptions tbody tr:first-child .subscription-project',
1636				dist_to_dock_x: 40,
1637				dist_to_dock_y: 40,
1638				diffuse: '#header, #colophon, .select-selected, .select-items, .my_account_subscriptions tbody tr:not(:first-child), .entry-header, .woocommerce-MyAccount-navigation',
1639				lightup: '.my_account_subscriptions tbody tr:first-child',
1640				functions_before: '',
1641				functions_on: '',
1642				functions_off: '',
1643            },
1644			1100: {
1645                title: 'Bearbeiten und Lizenzdetails' ,
1646				status: "",
1647                css_class: 'dsg-tour-element dsg-tour-navigation',
1648                text: 'Sie können hier ebenfalls das Dokument zur Bearbeitung aufrufen sowie die Details zur Lizenz einsehen.',
1649				dock_selector: '.my_account_subscriptions tbody tr:first-child .subscription-edit',
1650				dist_to_dock_x: 40,
1651				dist_to_dock_y: 40,
1652				diffuse: '#header, #colophon, .select-selected, .select-items, .my_account_subscriptions tbody tr:not(:first-child), .entry-header, .woocommerce-MyAccount-navigation',
1653				lightup: '.my_account_subscriptions tbody tr:first-child .subscription-edit, .my_account_subscriptions tbody tr:first-child .subscription-status',
1654				functions_before: '',
1655				functions_on: '',
1656				functions_off: '',
1657            },
1658			10000: {
1659				title: 'Tour erfolgreich beendet',
1660				status: "premium,free,premiumtest",
1661				css_class: 'dsg-tour-element dsg-tour-document-saving',
1662				text: '<p>Herzlichen Glückwunsch! Sie kennen nun den Aufbau Ihrer Dokumenteverwaltung.</p><p>P.S. Sie können die Tour jederzeit wieder starten und falls Sie noch Fragen haben, <a href="https://datenschutz-generator.de/kontakt-faq/" target="_blank">nutzen Sie unsere FAQ</a>.</p>',
1663				dock_selector: '',
1664				diffuse: '#header, #main, #colophon, #dsg-out-generate-do-wrap, #colophon, .entry-header, .woocommerce-MyAccount-navigation',
1665				dist_to_dock_x: 0,
1666				dist_to_dock_y: 0,
1667				functions_before: 'dsg_tour_functions_mydocs_list_off, dsg_tour_functions_document_scroll_top',
1668				functions_off: '',
1669				functions_exit: '',
1670        }			
1671
1672		}			
1673		
1674		
1675    } else if ( Number(category) === 13) {
1676		
1677	
1678	
1679	//*KATEGORIE: DSE */
1680	
1681		
1682        tour_elements_obj_category = {
1683
1684			300: {
1685                title: 'Datenschutz-Analyse' ,
1686				status: "premium,premiumtest",
1687                css_class: 'dsg-tour-element dsg-tour-navigation',
1688                text: 'Starten Sie mit dem Website-Scan. Sie erhalten passende Modul-Vorschläge, um damit Ihre Datenschutzerklärung den Anforderungen Ihrer Website anzupassen.',
1689				dock_selector: '#dsg-group-urlscan .group-title .text',
1690				dist_to_dock_x: 40,
1691				dist_to_dock_y: 40,
1692				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(#dsg-group-urlscan), #individualarea, #dsg-group-premium, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1693				lightup: '#dsg-group-urlscan',
1694				functions_before: '',
1695				functions_on: 'dsg_tour_functions_13_scan_on, dsg_tour_functions_13_premium_off',
1696				functions_off: '',
1697            },
1698            400: {
1699                title: 'Suchfunktion',
1700				status: "premium,premiumtest",
1701                css_class: 'dsg-tour-element dsg-tour-modules',
1702                text: 'Sie können nach den von ihnen eingesetzten Tools und Anbietern in unserer Datenbank suchen (wie z. B. "Google Analytics"), um sie in Ihre Datenschutzerklärung aufzunehmen.',
1703				dock_selector: '#dsg-out-group-search #dsg-search-submit-main',
1704				dist_to_dock_x: 50,
1705				dist_to_dock_y: 30,
1706				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(#dsg-out-group-search), #dsg-group-premium, #individualarea, #dsg-out-generate-do-wrap, #colophon',
1707				lightup: '#dsg-out-group-search #dsg-search-submit-main',
1708				functions_before: '',
1709				functions_off: '',				
1710            },       
1711			500: {
1712                title: 'Schnellauswahl',
1713				status: "free",
1714                css_class: 'dsg-tour-element dsg-tour-modules',
1715                text: '<p>Mit Hilfe der Schnellauswahl können Sie die wichtigsten Bestandteile Ihrer Datenschutzerklärung auswählen.',
1716				dock_selector: '#dsg-out-group-presets',
1717				dist_to_dock_x: 50,
1718				dist_to_dock_y: 30,
1719				lightup: '#dsg-out-group-presets',
1720				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(#dsg-out-group-presets), #dsg-group-premium, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1721				functions_before: '',
1722				functions_off: '',				
1723            },       
1724			600: {
1725                title: 'Individuelle Einstellungen',
1726				status: "premium,free,premiumtest",
1727                css_class: 'dsg-tour-element dsg-tour-modules',
1728                text: '<p>Nach der Vorauswahl können Sie die Inhalte Ihrer Datenschutzerklärung individuell anpassen, wie in diesem Beispiel die Angaben zum Verantwortlichen.',
1729				dock_selector: '#individualarea',
1730				dist_to_dock_x: 50,
1731				dist_to_dock_y: 30,
1732				lightup: '.dsg-tour-step-provider .group-title .text, #individualarea',
1733				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-provider), #dsg-group-premium, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1734				functions_before: 'dsg_tour_functions_css_dsg_tour_anbieter_on, dsg_tour_functions_css_dsg_tour_regmodule_on',
1735				functions_off: '',				
1736            },
1737			700: {
1738                title: 'Auswahl von Modulen' ,
1739				status: "premium,free,premiumtest",
1740                css_class: 'dsg-tour-element dsg-tour-modules',
1741                text: '<p>Beantworten Sie die "Ja/Nein" Fragen, um die Module in Ihre Datenschutzerklärung aufzunehmen ("wie in diesem Beispiel zum Cookie-Einsatz").</p><p>Unsere Empfehlungen sind vorausgewählt.</p>',
1742				dock_selector: '.dsg-tour-step-regmodule h4',
1743				dist_to_dock_x: 40,
1744				dist_to_dock_y: 30,
1745				lightup: '.dsg-tour-step-regmodule h4, .dsg-tour-step-regmodule .module-yesno-button',
1746				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-regmodule),  .dsg-element-option, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1747				functions_before: '',
1748				functions_off: '',				
1749            },
1750			800: {
1751                title: 'Erläuterungen' ,
1752				status: "premium,free,premiumtest",
1753                css_class: 'dsg-tour-element dsg-tour-modules',
1754                text: '<p>Wenn Sie weitere Fragen zu dem Modul haben, dann klicken Sie auf den Link "Erläuterungen anzeigen".</p>',
1755				dock_selector: '.dsg-tour-step-regmodule .module-info-show',
1756				dist_to_dock_x: 40,
1757				dist_to_dock_y: 30,
1758				lightup: '#dsg-module-151 .module-info-show',
1759				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-regmodule),  .dsg-element-option, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1760				functions_before: '',
1761				functions_off: '',				
1762            },
1763			900: {
1764                title: 'Auswahl von Verfahren und Anbietern' ,
1765				status: "premium,free,premiumtest",
1766                css_class: 'dsg-tour-element dsg-tour-modules',
1767                text: '<p>Innerhalb der Module können Sie ferner weitere Verfahrensarten oder Anbieter auswählen, wie z.B. das Einwilligungsverfahren bei Cookies.</p>',
1768				dock_selector: '.dsg-tour-step-regoption',
1769				dist_to_dock_x: 40,
1770				dist_to_dock_y: 30,
1771				lightup: '.dsg-tour-step-regoption',
1772				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-regmodule),  .dsg-element-option:not(.dsg-tour-step-regoption), #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1773				functions_before: 'dsg_tour_functions_css_dsg_tour_regoption_on',
1774				functions_off: '',				
1775            },
1776			1000: {
1777                title: 'Module, Verfahren oder Anbieter ergänzen' ,
1778				status: "premium,free,premiumtest",
1779                css_class: 'dsg-tour-element dsg-tour-modules',
1780                text: '<p>Sie können weitere Module, Verfahren oder Anbieter aus unserer Datenbank auswählen oder individuell ergänzen (Nur für Premium-Kunden).</p>',
1781				dock_selector: '.dsg-tour-step-regmodule .dsg-search-input',
1782				dist_to_dock_x: 40,
1783				dist_to_dock_y: 30,
1784				lightup: '.dsg-tour-step-regmodule .dsgusmo-wrap',
1785				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-regmodule), .dsg-element-option, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1786				functions_before: '',
1787				functions_off: '',				
1788            },
1789			1100: {
1790                title: 'Vorschau' ,
1791				status: "premium,free,premiumtest",
1792                css_class: 'dsg-tour-element dsg-tour-modules',
1793                text: '<p>Wenn Sie auf die Schaltfläche "Vorschau" klicken, wird eine Vorschau des Modduls angezeigt.</p>',
1794				dock_selector: '.dsg-tour-step-regmodule .module-infopreview-buttons .preview-button',
1795				dist_to_dock_x: 40,
1796				dist_to_dock_y: 30,
1797				lightup: '.dsg-tour-step-regmodule .module-infopreview-buttons',
1798				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(#dsg-group-110), .dsg-element-option, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1799				functions_before: 'dsg_tour_functions_generation_wrap_off',
1800				functions_off: 'dsg_tour_functions_css_dsg_tour_anbieter_on, dsg_tour_functions_css_dsg_tour_regmodule_on, dsg_tour_functions_css_dsg_tour_regoption_on, dsg_tour_functions_generation_wrap_off',				
1801            }
1802        };
1803		
1804			
1805    } else  {
1806		
1807				
1808	
1809	
1810	//*KATEGORIE: ANDERE */
1811		
1812        tour_elements_obj_category = {
1813			200: {
1814                title: 'Verknüpfung mit Ihrer Datenschutzerklärung' ,
1815				status: "premium,premiumtest",
1816                css_class: 'dsg-tour-element dsg-tour-navigation',
1817                text: 'Vermeiden Sie Doppelarbeit: Datenschutzerklärung und Verarbeitungsverzeichnis überschneiden sich oft. Bei uns können Sie beide Dokumente verknüpfen, sodass Änderungen automatisch übernommen werden.',
1818				dock_selector: '#dsg-group-dsevvbrdg',
1819				dist_to_dock_x: 40,
1820				dist_to_dock_y: 40,
1821				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(#dsg-group-dsevvbrdg), #individualarea, #dsg-group-premium, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1822				lightup: '#dsg-group-dsevvbrdg',
1823				functions_before: '',
1824				functions_on: 'dsg_tour_functions_13_scan_on, dsg_tour_functions_13_premium_off',
1825				functions_off: 'dsg_tour_functions_css_dsg_tour_anbieter_on, dsg_tour_functions_css_dsg_tour_regmodule_on',
1826            },	
1827			300: {
1828                title: 'Datenschutz-Analyse' ,
1829				status: "premium,premiumtest",
1830                css_class: 'dsg-tour-element dsg-tour-navigation',
1831                text: 'Starten Sie mit dem Website-Scan. Sie erhalten passende Modul-Vorschläge, um damit Ihre Datenschutzerklärung den Anforderungen Ihrer Website anzupassen.',
1832				dock_selector: '#dsg-group-urlscan .group-title .text',
1833				dist_to_dock_x: 40,
1834				dist_to_dock_y: 40,
1835				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(#dsg-group-urlscan), #individualarea, #dsg-group-premium, #dsg-out-group-search, #dsg-out-generate-do-wrap, #colophon',
1836				lightup: '#dsg-group-urlscan',
1837				functions_before: '',
1838				functions_on: 'dsg_tour_functions_13_scan_on, dsg_tour_functions_13_premium_off',
1839				functions_off: 'dsg_tour_functions_css_dsg_tour_anbieter_on, dsg_tour_functions_css_dsg_tour_regmodule_on',
1840            },
1841            400: {
1842                title: 'Suchfunktion',
1843				status: "premium,premiumtest",
1844                css_class: 'dsg-tour-element dsg-tour-modules',
1845                text: 'Sie können nach den von ihnen eingesetzten Tools und Anbietern in unserer Datenbank suchen (wie z. B. "Google Analytics"), um sie in Ihr Dokument aufzunehmen.',
1846				dock_selector: '#dsg-out-group-search #dsg-search-submit-main',
1847				dist_to_dock_x: 50,
1848				dist_to_dock_y: 30,
1849				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(#dsg-out-group-search), #dsg-group-premium, #individualarea, #dsg-out-generate-do-wrap, #colophon',
1850				lightup: '#dsg-out-group-search #dsg-search-submit-main',
1851				functions_before: '',
1852				functions_off: '',				
1853            }, 			
1854			600: {
1855                title: 'Individuelle Einstellungen',
1856				status: "premium,free,premiumtest",
1857                css_class: 'dsg-tour-element dsg-tour-modules',
1858                text: '<p>Nach der Vorauswahl können Sie die Inhalte Ihres Dokuments individuell anpassen, und z.B. Angaben zu Verantwortlichen, Anbietern oder Vertragsparteien Eingeben.',
1859				dock_selector: '.dsg-tour-step-provider',
1860				dist_to_dock_x: 50,
1861				dist_to_dock_y: 30,
1862				lightup: '.dsg-tour-step-provider',
1863				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-provider), #dsg-group-premium, , #dsg-out-generate-do-wrap, #colophon',
1864				functions_before: 'dsg_tour_functions_css_dsg_tour_anbieter_on, dsg_tour_functions_css_dsg_tour_regmodule_on',
1865				functions_off: '',				
1866            },
1867			700: {
1868                title: 'Auswahl von Modulen' ,
1869				status: "premium,free,premiumtest",
1870                css_class: 'dsg-tour-element dsg-tour-modules',
1871                text: '<p>Beantworten Sie die "Ja/Nein" Fragen, um die jeweiligen Module in Ihr Dokument aufzunehmen.</p><p>Unsere Empfehlungen sind vorausgewählt.</p>',
1872				dock_selector: '.dsg-tour-step-regmodule h4',
1873				dist_to_dock_x: 40,
1874				dist_to_dock_y: 30,
1875				lightup: '.dsg-tour-step-regmodule h4',
1876				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-regmodule),  .dsg-element-option, #dsg-out-generate-do-wrap, #colophon',
1877				functions_before: '',
1878				functions_off: '',				
1879            },
1880			800: {
1881                title: 'Erläuterungen' ,
1882				status: "premium,free,premiumtest",
1883                css_class: 'dsg-tour-element dsg-tour-modules',
1884                text: '<p>Wenn Sie weitere Fragen zu dem Modul haben, dann klicken Sie auf den Link "Erläuterungen anzeigen".</p>',
1885				dock_selector: '.dsg-tour-step-regmodule .module-info-show',
1886				dist_to_dock_x: 40,
1887				dist_to_dock_y: 30,
1888				lightup: '#dsg-module-151 .module-info-show',
1889				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-regmodule),  #dsg-out-group-search, .dsg-element-option, #dsg-out-generate-do-wrap, #colophon',
1890				functions_before: '',
1891				functions_off: '',				
1892            },
1893			900: {
1894                title: 'Auswahl von Optionen' ,
1895				status: "premium,free,premiumtest",
1896                css_class: 'dsg-tour-element dsg-tour-modules',
1897                text: '<p>Innerhalb mancher Module können Sie zudem weitere Optionen auswählen.</p>',
1898				dock_selector: '.dsg-tour-step-regoption',
1899				dist_to_dock_x: 40,
1900				dist_to_dock_y: 30,
1901				lightup: '.dsg-tour-step-regoption',
1902				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-regmodule),  .dsg-element-option:not(.dsg-tour-step-regoption), #dsg-out-generate-do-wrap, #colophon',
1903				functions_before: 'dsg_tour_functions_css_dsg_tour_regoption_on',
1904				functions_off: '',				
1905            },
1906			1000: {
1907                title: 'Module, Verfahren oder Anbieter ergänzen' ,
1908				status: "premium,premiumtest",
1909                css_class: 'dsg-tour-element dsg-tour-modules',
1910                text: '<p>Sie können weitere Module, z.B. mit weiteren Klauslen individuell ergänzen (Nur für Premium-Kunden).</p>',
1911				dock_selector: '.dsg-tour-step-regmodule .dsgusmo-button-openform',
1912				dist_to_dock_x: 40,
1913				dist_to_dock_y: 30,
1914				lightup: '.dsg-tour-step-regmodule .dsgusmo-button-openform',
1915				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-regmodule),  .dsg-element-option, .dsg-element-option, #dsg-out-generate-do-wrap, #colophon',
1916				functions_before: '',
1917				functions_off: '',				
1918            },
1919			1100: {
1920                title: 'Vorschau' ,
1921				status: "premium,free,premiumtest",
1922                css_class: 'dsg-tour-element dsg-tour-modules',
1923                text: '<p>Wenn Sie auf die Schaltfläche "Vorschau" klicken, wird eine Vorschau des Moduls angezeigt.</p>',
1924				dock_selector: '.dsg-tour-step-regmodule .module-infopreview-buttons .preview-button:not([hidden])',
1925				dist_to_dock_x: 40,
1926				dist_to_dock_y: 30,
1927				lightup: '.dsg-tour-step-regmodule .module-infopreview-buttons',
1928				diffuse: '#header, #dsg-projects-loading-lp, .dsg-group:not(.dsg-tour-step-regmodule), .dsg-element-option,  #dsg-out-generate-do-wrap, #colophon',
1929				functions_before: 'dsg_tour_functions_css_dsg_tour_anbieter_on, dsg_tour_functions_css_dsg_tour_regmodule_on, dsg_tour_functions_css_dsg_tour_regoption_on, dsg_tour_functions_generation_wrap_off',
1930				functions_off: '',				
1931            }
1932        };
1933
1934    }
1935	
1936	// console.dir(tour_elements_obj_category);
1937	
1938
1939    // Merge `tour_elements_obj_generate` only if category is a valid number
1940    if (typeof category === "number" || (typeof category === "string" && /^\d+$/.test(category))) {
1941		
1942		tour_elements_obj_core_1 = {};
1943		tour_elements_obj_core_2 = {};
1944		
1945		 // console.warn("Category is a number. merging.");
1946		 
1947        tour_elements_obj_core_1= {
1948            ...tour_elements_obj_category,
1949            ...tour_elements_obj_generate
1950        };
1951
1952		
1953		if ( Number(category) === 273) {
1954			
1955			tour_elements_obj_core_2 = {
1956				...tour_elements_obj_languages,
1957				...tour_elements_obj_core_1,
1958				...tour_elements_obj_save,
1959			};
1960		
1961		} else if ( Number(category) === 13) {
1962			
1963			tour_elements_obj_core_2 = {
1964				...tour_elements_obj_languages,
1965				...tour_elements_obj_core_1,
1966				...tour_elements_obj_save,
1967			};
1968
1969		}  else  {
1970			
1971			tour_elements_obj_core_2 = {
1972				...tour_elements_obj_languages,
1973				...tour_elements_obj_schnellauswahl,				
1974				...tour_elements_obj_core_1,
1975				...tour_elements_obj_save,
1976			};
1977
1978		}
1979			
1980					// console.dir(tour_elements_obj_core_2);		
1981			
1982        tour_elements_obj_core = {
1983            ...tour_elements_obj_core_2
1984        };
1985		
1986		// tour_elements_obj_start_out = tour_elements_obj_start;
1987		// tour_elements_obj_end_out = tour_elements_obj_end;			
1988
1989		
1990    } else {
1991        console.warn("Category is not a valid number. Skipping merge.");
1992		tour_elements_obj_core = tour_elements_obj_category;
1993		
1994		
1995		tour_elements_obj_start = {};
1996		tour_elements_obj_end = {};		
1997    }
1998		
1999
2000		
2001	//Überflüssige elemente entfernen
2002	// console.dir(tour_elements_obj_core);
2003	
2004	var tour_elements_obj_core_purged = dsg_tour_obj_purged ( tour_elements_obj_core );
2005	// console.dir(tour_elements_obj_core_purged);	
2006	
2007    // Merge all parts into one object
2008    const tour_elements_obj = {
2009        ...tour_elements_obj_start,
2010        ...tour_elements_obj_core_purged,
2011        ...tour_elements_obj_end
2012    };
2013
2014	// console.dir(tour_elements_obj);	
2015	
2016	// localStorage.setItem('tour_elements_obj', JSON.stringify(tour_elements_obj));
2017
2018
2019    return tour_elements_obj;
2020}
2021
2022
2023
2024//===================================================================================    
2025//
2026// tour Objekt von überflüssigen Imhalten bereinigen (wichtig: erst nach dsg_tour_grup_title_wrap() )
2027//
2028//====================================================================================
2029
2030
2031function dsg_tour_obj_purged( tour_elements_obj ) {
2032	
2033	if ( !tour_elements_obj ) { return false };
2034
2035    // const tour_elements_obj = dsg_tour_tour_object( "", "" );
2036    const result = {};
2037
2038    for (const key in tour_elements_obj) {
2039        const element = tour_elements_obj[key];
2040        let removed = false;
2041
2042        // Check for 'status' property and filter accordingly
2043        if (element.hasOwnProperty('status')) {
2044			
2045			// console.log("test status--------");
2046			
2047            const statusArray = element.status.split(',');
2048
2049            if (!url_parameter.dsgp) {
2050                if (
2051                    document.body.classList.contains('dsg-premium-free') &&
2052                    !statusArray.includes('free')
2053                ) {
2054                    // console.log(`Removed element ${key} due to status mismatch: free`);
2055                    removed = true;
2056                    continue;
2057                }
2058
2059                if (
2060                    document.body.classList.contains('dsg-premium-premium') &&
2061                    !statusArray.includes('premiumtest')
2062                ) {
2063                    // console.log(`Removed element ${key} due to status mismatch: premiumtest`);
2064                    removed = true;
2065                    continue;
2066                }
2067            } else if (!statusArray.includes('premium')) {
2068                // console.log(`Removed element ${key} due to status mismatch: premium`);
2069                removed = true;
2070                continue;
2071            }
2072        }
2073
2074        // Check for dock_selector and remove if not present in DOM
2075        if (element.dock_selector && !$(element.dock_selector).length) {
2076            // console.log(`Removed element ${key} due to missing dock_selector in DOM: ${element.dock_selector}`);
2077            removed = true;
2078            continue;
2079        }
2080
2081        if (!removed) {
2082            result[key] = element;
2083        }
2084    }
2085	
2086	// console.log ("ELEMENTS");
2087	// console.dir(result);
2088    
2089	return result;
2090}
2091
2092   
2093    //dsg_tour_start();
2094
2095    
2096
2097
2098
2099/*===================================================================================    
2100// Tour - Funktionen on, off - Beisspielsmodul anzeigen
2101//====================================================================================*/
2102window.dsg_tour_functions_css_dsg_tour_all_off = function () {
2103  dsg_tour_functions_css_dsg_tour_regmodule_off();
2104  dsg_tour_functions_css_dsg_tour_regoption_off();
2105  dsg_tour_functions_css_dsg_tour_anbieter_off();
2106  dsg_tour_functions_generation_wrap_off();
2107  dsg_tour_functions_mydocs_list_off();
2108};
2109
2110window.dsg_tour_functions_css_dsg_tour_regoption_on = function () {
2111  setTimeout(function() {
2112    let regoption = $('.dsg-tour-step-regoption');
2113    let regoption_mid = regoption.data("mid");
2114    
2115    if (!regoption.hasClass('active')) {
2116      regoption.addClass('activated-by-tour');
2117      dsg_simulate_optionclick(regoption_mid);
2118    }
2119  }, 0);
2120};
2121
2122window.dsg_tour_functions_css_dsg_tour_regoption_off = function () {
2123  let regoption = $('.dsg-tour-step-regoption');
2124  let regoption_mid = regoption.data("mid");
2125  
2126  if (regoption.hasClass('activated-by-tour')) {
2127    dsg_simulate_optionclick(regoption_mid);
2128    regoption.removeClass('activated-by-tour');
2129  }
2130};
2131
2132window.dsg_tour_functions_css_dsg_tour_regmodule_on = function () {
2133  setTimeout(function() {
2134    setTimeout(function() {
2135      let regmodule = $('.dsg-tour-step-regmodule');
2136      let regmodule_yesno = $('.module-yesno-button', regmodule);
2137      let group_mid = regmodule.data("group_mid");
2138      
2139      $('.group-modules-wrap[data-slider-id="' + group_mid + '"]').slideDown();
2140      
2141      if (!regmodule_yesno.hasClass('active')) {
2142        dsg_module_yesno_button_activate(regmodule_yesno.data("mid"));
2143        regmodule_yesno.addClass('activated-by-tour');
2144      }
2145    }, 0);
2146  }, 10);
2147};
2148
2149window.dsg_tour_functions_css_dsg_tour_regmodule_off = function () {
2150  let regmodule = $('.dsg-tour-step-regmodule');
2151  let regmodule_options = $('.module-options', regmodule);
2152  let regmodule_yesno = $('.module-yesno-button', regmodule);
2153  let group_mid = regmodule.data("group_mid");
2154  
2155  setTimeout(function() {
2156    $('.group-modules-wrap[data-slider-id="' + group_mid + '"]').slideUp();
2157    
2158    if (regmodule_yesno.hasClass('activated-by-tour')) {
2159      dsg_module_yesno_button_deactivate(regmodule_yesno.data("mid"));
2160      regmodule_yesno.removeClass('activated-by-tour');
2161      regmodule_options.slideUp();
2162    }
2163  }, 10);
2164};
2165
2166window.dsg_tour_functions_css_dsg_tour_anbieter_on = function () {
2167  setTimeout(function() {
2168    if (!$('.dsg-tour-step-provider').hasClass('active')) {
2169      $('.dsg-tour-step-provider').trigger('click').addClass('activated-by-tour');
2170    }
2171  }, 0);
2172};
2173
2174window.dsg_tour_functions_css_dsg_tour_anbieter_off = function () {
2175  setTimeout(function() {
2176    if ($('.dsg-tour-step-provider').hasClass('activated-by-tour')) {
2177      $('.dsg-tour-step-provider').trigger('click').removeClass('activated-by-tour');
2178    }
2179  }, 0);
2180};
2181
2182window.dsg_tour_functions_mydocs_list_on = function () {
2183  setTimeout(function() {
2184    $('.select-items').scrollTop(0);
2185  }, 20);
2186  
2187  if ($('.select-items').hasClass('select-hide')) {
2188    setTimeout(function() {
2189      $('.select-selected').trigger('click').addClass('activated-by-tour');
2190    }, 0);
2191  }
2192};
2193
2194window.dsg_tour_functions_mydocs_list_off = function () {
2195  if (!$('.select-items').hasClass('select-hide')) {
2196    setTimeout(function() {
2197      if ($('.select-items.ui-sortable').is(':visible')) {
2198        $('.select-selected').trigger('click').removeClass('activated-by-tour');
2199      }
2200    }, 100);
2201  }
2202};
2203
2204
2205window.dsg_tour_functions_13_premium_on =  function () {
2206
2207        // setTimeout(function() {
2208            // $('.group-wrap.dsg-slider.dsg-group-premium').slideDown(150).addClass("active");
2209        // }, 10);
2210		
2211
2212}
2213window.dsg_tour_functions_13_scan_on =  function () {
2214
2215        // setTimeout(function() {
2216            // $('#group-modules-wrap-urlscan').slideDown(150).addClass("active");
2217        // }, 10);
2218		
2219
2220}
2221
2222window.dsg_tour_functions_13_scan_off =  function () {
2223
2224	// $('#group-modules-wrap-urlscan').slideUp(0).removeClass("active");
2225}
2226
2227window.dsg_tour_functions_13_premium_on =  function () {
2228
2229        // setTimeout(function() {
2230            // $('.group-wrap.dsg-slider.dsg-group-premium').slideDown(150).addClass("active");
2231        // }, 10);
2232		
2233
2234}
2235
2236window.dsg_tour_functions_13_premium_off =  function () {
2237
2238	// $('.group-wrap.dsg-slider.dsg-group-premium').slideUp(0).removeClass("active");
2239}
2240
2241
2242
2243
2244window.dsg_tour_functions_generation_wrap_on =  function () {
2245
2246        setTimeout(function() {
2247            $('#dsg-out-generate-output-wrap').slideDown(0).addClass("active");
2248            // $('#dsg-module-334 .dsg-sort-options').slideDown(0).addClass("active");
2249        }, 0);
2250		
2251
2252}
2253
2254window.dsg_tour_functions_generation_wrap_off =  function () {
2255
2256            $('#dsg-out-generate-output-wrap').slideUp(0).removeClass("active");
2257            // $('#dsg-module-334 .dsg-sort-options').slideUp("300").removeClass("active");
2258}
2259
2260
2261
2262/*===================================================================================    
2263// Tour - Funktionen on, off - Beisspielsmodul anzeigen
2264//====================================================================================*/
2265window.dsg_tour_functions_example_navi_on =  function () {
2266	
2267	// console.log("dsg_tour_functions_example_navi_on IS ON!!!!!!!!!!!!!!!!!!");	
2268
2269	$("#dsg-nav-element-example").removeClass("hidden").addClass("active");
2270	
2271	  const activeElement = $('.dsg-app-out-nav');
2272
2273	  if (activeElement.length) {
2274		activeElement.animate({
2275		  scrollTop: activeElement.offset().top - 170
2276		}, 0); // Adjust the duration (in milliseconds) as needed
2277	  }
2278
2279}
2280	
2281
2282/*===================================================================================    
2283// Tour - Funktionen on, off - Beisspielsmodul ausblenden
2284//====================================================================================*/
2285window.dsg_tour_functions_example_navi_off =  function () {
2286	
2287	// console.log("dsg_tour_functions_example_navi_off IS OFFF");	
2288	
2289	$("#dsg-nav-element-example").addClass("hidden");
2290	
2291}
2292
2293
2294
2295/*===================================================================================    
2296// Tour - Funktionen on, off - Beisspielsmodul anzeigen
2297//====================================================================================*/
2298window.dsg_tour_functions_example_navi_done_on =  function () {
2299	
2300	// console.log("dsg_tour_functions_example_module_on IS ON!!!!!!!!!!!!!!!!!!");	
2301
2302	$("#dsg-nav-element-example").addClass('light-up-loop').attr('data-status', 'done');
2303	dsg_app_nav_status_create("example");
2304	
2305	
2306
2307}
2308	
2309
2310/*===================================================================================    
2311// Tour - Funktionen on, off - Beisspielsmodul ausblenden
2312//====================================================================================*/
2313window.dsg_tour_functions_example_navi_done_off =  function () {
2314	
2315	$("#dsg-nav-element-example").removeClass('light-up-loop').removeAttr('data-status');
2316	
2317}
2318
2319	
2320
2321/*===================================================================================    
2322// Tour - Funktionen on, off - Saveicon rotieren
2323//====================================================================================*/
2324window.dsg_tour_functions_save_on_autooff = function() {
2325    // Function to perform the timeout operation
2326    function toggleIndicateSave() {
2327        $('.save-indicator-icon').addClass("indicate-save");
2328        $('#dsg-cookie-header-icon').addClass("indicate-save");
2329
2330        setTimeout(function() {
2331            $('.save-indicator-icon').removeClass("indicate-save");
2332            $('#dsg-cookie-header-icon').removeClass("indicate-save");
2333        }, 800);
2334    }
2335
2336    // Loop to repeat the timeout operation three times with a 1.5-second waiting period between each iteration
2337	toggleIndicateSave();
2338    for (let i = 0; i < 2; i++) {
2339        setTimeout(function() {
2340            toggleIndicateSave();
2341        }, i * 1500);
2342    }
2343}
2344
2345
2346/*===================================================================================    
2347// Tour - Funktionen on, off - Beisspielsmodul anzeigen
2348//====================================================================================*/
2349
2350window.dsg_tour_functions_example_module_on = function () {
2351  // Store the data-mid value of the .dsg-nav-element.active element
2352  const activeDataMid = $('.dsg-nav-element.active').attr('data-mid');
2353
2354  // Save the data-mid value to the .dsg-module-example element
2355  if ( !$('#dsg-module-example').attr('data-tour-start-saved-mid') ) {
2356	  
2357	$('#dsg-module-example').attr('data-tour-start-saved-mid', activeDataMid);
2358	
2359  }
2360
2361	//29.12.2024 Appteil
2362	//dsg_usmo_sort_init("example");
2363	
2364  //29.12.2024 Appteil
2365  //dsg_app_nav_click("example", false, false);
2366};
2367
2368/*===================================================================================    
2369// Tour - Funktionen on, off - Beisspielsmodul ausblenden
2370//====================================================================================*/
2371window.dsg_tour_functions_example_module_off = function () {
2372  // Get the saved data-tour-start-saved-mid value and remove the attribute
2373  const save_mid = $('#dsg-module-example').attr('data-tour-start-saved-mid') || 'starter';
2374  $('#dsg-module-example').removeAttr('data-tour-start-saved-mid');
2375
2376  //dsg_nav_element_click("example");
2377    //29.12.2024 Appteil
2378  // dsg_app_nav_click(save_mid, false, false);
2379};
2380
2381
2382/*===================================================================================    
2383// Tour - Funktionen on, off - Generatemodul anzeigen
2384//====================================================================================*/
2385window.dsg_tour_functions_generate_on = function () {
2386
2387    //console.log("generate----------------***************");
2388
2389    dsg_prev_errors_handling_init();
2390  
2391    //29.12.2024 Appteil
2392    //dsg_app_nav_click("generate", false, false);
2393	
2394    //dsg_app_module_scrollto("generate", "generate", false);
2395	$('#dsg-nav-element-generate').addClass('light-up-loop');
2396 
2397    // get the element with class .dsg-app-out-modules
2398    const outerElement = document.querySelector('.dsg-app-out-modules');
2399
2400    // get the element with ID group-modules-wrap-generate inside the outer element
2401    const targetElement = outerElement.querySelector('#group-modules-wrap-generate');
2402
2403    // scroll to the top of the page
2404    window.scrollTo({ top: 0, behavior: 'auto' });
2405
2406    // scroll the outer element to the top
2407    outerElement.scrollTo({ top: 0, behavior: 'auto' });
2408
2409    // If you still want to scroll to the targetElement afterwards, uncomment the following lines:
2410    /*
2411    const relativeOffset = getRelativeOffset(targetElement, outerElement);
2412    outerElement.scrollTo({
2413        top: relativeOffset,
2414        behavior: 'auto',
2415    });
2416    */
2417};
2418
2419// A helper function to calculate the relative offset
2420function getRelativeOffset(element, container) {
2421    let offset = 0;
2422    let currentElement = element;
2423
2424    while(currentElement && currentElement !== container) {
2425        offset += currentElement.offsetTop;
2426        currentElement = currentElement.offsetParent;
2427    }
2428
2429    return offset;
2430}
2431
2432
2433/*===================================================================================    
2434// Tour - Funktionen on, off - Generatemodul Lightup ende
2435//====================================================================================*/
2436window.dsg_tour_functions_generate_off = function () {
2437
2438	$('#dsg-nav-element-generate').removeClass('light-up-loop');
2439	
2440}
2441
2442// Tour - Funktionen on, off - Progress
2443//==============================================================================
2444window.dsg_tour_functions_progress_on = function () {
2445
2446  example_width = "66%";
2447  progress_inner = $(".dsg-progress-bar-inner");
2448  progress_inner.attr("data-saved-width", progress_inner.width());
2449  progress_inner.width(example_width);
2450  
2451  percentage_element = $('.dsg-progress-percentage');
2452  percentage_amount = percentage_element.text();
2453  percentage_element.attr("data-saved-percentage", percentage_amount );
2454  percentage_element.text(example_width);
2455  
2456};
2457
2458// Tour - Funktionen on, off - Progress
2459//==============================================================================
2460window.dsg_tour_functions_progress_off = function () {
2461  progress_inner = $(".dsg-progress-bar-inner");
2462  progress_inner.width(progress_inner.attr("data-saved-width"));
2463  progress_inner.removeAttr("data-saved-width");
2464  
2465  percentage_element = $('.dsg-progress-percentage');
2466  percentage_amount = percentage_element.attr("data-saved-percentage");
2467  percentage_element.text(percentage_amount);
2468  progress_inner.removeAttr("data-saved-percentage");
2469  
2470};
2471
2472/*===================================================================================    
2473// Tour - Funktionen on, off - Document Scroll top
2474//====================================================================================*/
2475
2476window.dsg_tour_functions_document_scroll_top = function () {
2477	
2478 
2479window.scrollTo({
2480    top: 0,
2481    behavior: 'smooth'  // For smooth scrolling
2482});
2483
2484
2485}
2486
2487/*===================================================================================    
2488// Tour - Funktionen on, off - Document Steuerung
2489//====================================================================================*/
2490
2491window.dsg_tour_functions_document_controls_on = function () {
2492	
2493	$('.dsg-app-doc-scroll-up').css({display: 'flex', opacity: 1}).fadeIn();
2494	$('.dsg-app-doc-navi').css("padding-top","90px");
2495
2496
2497};
2498
2499/*===================================================================================    
2500// Tour - Funktionen on, off - Beispielsmodul SteuerungSteuerung
2501//====================================================================================*/
2502window.dsg_tour_functions_document_controls_off = function () {
2503
2504
2505	$('.dsg-app-doc-scroll-up').fadeOut().css("opacity",0);
2506	$('.dsg-app-doc-navi').css("padding-top","0");
2507	
2508};
2509
2510
2511/*===================================================================================    
2512// Tour - Funktionen on, off - Errors & Lizenzhinweis ausblenden
2513//====================================================================================*/
2514
2515window.dsg_tour_functions_hide_errors_license_on = function () {
2516	
2517	$('#dsg-module-app-errors').addClass("hidden-important");
2518	$('#group-modules-wrap-generate .dsg-out-generate-error-messages-shoplink').addClass("hidden-important");
2519
2520
2521};
2522
2523/*===================================================================================    
2524// Tour - Funktionen on, off - Beisspielsmodul SteuerungSteuerung
2525//====================================================================================*/
2526window.dsg_tour_functions_hide_errors_license_off = function () {
2527
2528
2529	$('#dsg-module-app-errors').removeClass("hidden-important");
2530	$('#group-modules-wrap-generate .dsg-out-generate-error-messages-shoplink').removeClass("hidden-important");
2531
2532	
2533};
2534
2535
2536		
2537/*===================================================================================    
2538// Tour - Funktionen on, off - Beisspielsmodul SteuerungSteuerung
2539//====================================================================================*/
2540window.dsg_tour_functions_document_edit_on = function () {
2541
2542    // Recursive function to get the mid of the first non-empty .dsg-preview-option element
2543    function getMid(elements) {
2544        if (elements.length === 0) {
2545            return null;
2546        }
2547
2548        var first = elements.first();
2549        var mid = first.data("mid");
2550        var html = first.html();
2551
2552        if (mid && html && html.trim() !== "") {
2553            return mid;
2554        } else {
2555            return getMid(elements.slice(1));
2556        }
2557    }
2558
2559    var mid = getMid($('.dsg-preview-option:not(.is_index):visible'));
2560    var language = $('.dsg-app-out-document-inner:visible').data("language");
2561
2562    var preview_element = $('.dsg-titletext-preview[data-mid="' + mid + '"][data-language="' + language + '"]');
2563
2564    // console.log("preview_mid: " + mid + " - language: " + language);
2565    // console.log("preview_element: " + '.dsg-titletext-preview[data-mid="' + mid + '"][data-language="' + language + '"]' );
2566		
2567	if (!$('.dsg-usmo-options', preview_element).length) preview_element.append(dsg_usmo_options_get(preview_element, mid, 'usmo-text'));
2568
2569	$('.dsg-usmo-options', preview_element).addClass('not-hiden').attr("id", 'dsg-usmo-options-example').fadeIn();
2570
2571	// console.log(" html: " + $('.dsg-titletext-preview[data-mid="' + mid + '"] .dsg-usmo-options').html());
2572
2573	dsg_usmo_options_get(preview_element, mid, "textedit");
2574
2575};
2576
2577
2578
2579/*===================================================================================    
2580// Tour - Funktionen on, off - Beisspielsmodul SteuerungSteuerung
2581//====================================================================================*/
2582window.dsg_tour_functions_document_edit_off = function () {
2583
2584	$('.dsg-usmo-options').removeClass('not-hiden');
2585	
2586};
2587	
2588	
2589	/*===================================================================================    
2590// Tour - Funktionen on, off - Beisspielsmodul SteuerungSteuerung
2591//====================================================================================*/
2592
2593
2594// Create image array
2595var dsg_images_seenadeln = [
2596  'https://reefs.com/blog/wp-content/uploads/2016/06/Corythoichthys-instinalis-Scribbled-Pipefish-2-Aaron-Down.jpg',
2597  'https://cdn.notroublesjustbubbles.com/images/marine-life/Cheeked-Pipefish.jpg',
2598  'https://3.bp.blogspot.com/-vdSUtDV70zQ/VJQBPBkTiVI/AAAAAAAAKjM/HaXtqF49IfY/s1600/Banded%2BPipefish%2Br800.jpg',
2599  'https://img.peapix.com/1e7b407ed5dc492888023d285286e2d6.jpg?attachment&modal',
2600  'https://2.bp.blogspot.com/-42Q9ZSheasw/UeIqsK-NKKI/AAAAAAAAJTE/F4rYnblN7p0/w1200-h630-p-k-no-nu/pipefish.jpg',
2601  'https://www.aquariadise.com/wp-content/uploads/2021/07/Pipefish.jpg',
2602  'https://seaunseen.com/wp-content/uploads/2020/07/003A9374.jpg',
2603  'https://i.pinimg.com/originals/d2/1b/3a/d21b3ad46c451329c5a774d8eef6576a.jpg',
2604  'https://upload.wikimedia.org/wikipedia/commons/b/be/Ornate_Ghost_Pipef
2604ish.jpg'
2605];
2606
2607//dsg_tour_functions_seenadeln_preload();
2608
2609window.dsg_tour_functions_seenadeln_preload = function () {
2610  
2611	if (typeof window.dsg_preloaded_seenadeln_images === 'undefined') {
2612		
2613	  var imageUrls = dsg_images_seenadeln;
2614
2615	  var loadedImages = 0;
2616	  var totalImages = imageUrls.length;
2617	  var images = [];
2618	  
2619	  //console.log('Starting loading images');
2620
2621	  for (var i = 0; i < totalImages; i++) {
2622		images[i] = new Image();
2623		images[i].src = imageUrls[i];
2624		images[i].onload = function() {
2625		  loadedImages++;
2626		  if (loadedImages === totalImages) {
2627			//console.log('All images have been loaded');
2628			window.dsg_preloaded_seenadeln_images = images;
2629		  }
2630		};
2631		images[i].onerror = function() {
2632		  loadedImages++;
2633		  if (loadedImages === totalImages) {
2634			//console.log('All images have been loaded');
2635			window.dsg_preloaded_seenadeln_images = images;
2636		  }
2637		};
2638	  }
2639	  
2640	}
2641}
2642
2643window.dsg_tour_functions_seenadeln_on = function() {
2644  // Wait for the images to be preloaded
2645  	  		
2646  var waitForImages = function(callback) {
2647    if (typeof window.dsg_preloaded_seenadeln_images !== 'undefined') {
2648
2649      callback();
2650    } else {
2651
2652      setTimeout(function() {
2653		  dsg_tour_functions_seenadeln_preload();
2654        waitForImages(callback);
2655      }, 100);
2656    }
2657  };
2658
2659  waitForImages(function() {
2660
2661    // Create container
2662// Create container
2663var container = document.createElement('div');
2664container.id = 'dsg-tour-seenadeln';
2665container.style.position = 'fixed';
2666container.style.top = '0'; // Changed to 0
2667container.style.bottom = '0';
2668container.style.right = '0'; // Changed to 0
2669container.style.left = '0'; // Changed to 0
2670container.style.width = '100%'; // Changed to 100%
2671container.style.height = '100%'; // Changed to 100%
2672container.style.overflow = 'hidden';
2673container.style.display = 'none';
2674document.body.appendChild(container);
2675
2676    // Set up image rotation
2677    var index = 0;
2678    var interval = setInterval(function() {
2679      // Use preloaded image
2680      var img = window.dsg_preloaded_seenadeln_images[index];
2681      img.style.position = 'absolute';
2682      img.style.top = '0';
2683      img.style.left = '0';
2684      img.style.width = '100%';
2685      img.style.height = '100%';
2686      img.style.objectFit = 'cover'; // Add this line to make the image cover the container
2687      container.innerHTML = '';
2688      container.appendChild(img);
2689
2690      // Update index
2691      index++;
2692      if (index >= dsg_images_seenadeln.length) {
2693        index = 0;
2694      }
2695    }, 2000);
2696
2697    // Make container visible
2698    container.style.display = 'block';
2699	
2700
2701  });
2702};
2703
2704
2705
2706/*===================================================================================    
2707// Tour - Funktionen on, off - Beisspielsmodul SteuerungSteuerung
2708//====================================================================================*/
2709window.dsg_tour_functions_seenadeln_off = function () {
2710
2711	$('#dsg-tour-seenadeln').remove();
2712	
2713};
2714		
2715	
2716/*-------------------------*/
2717
2718
2719});

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.