PageSourceSearch

https://magdeburg360.de/virtueller-stadtrundgangdata/graphics/KolorBootstrap.js

js magdeburg360.de collected 2026-10-02 22:15:56 UTC 53,848 bytes, 1,382 lines download raw bytes

1//krpano instance
2var krpano = null;
3//trace
4var debug = false;
5//is krpano loaded
6var krpanoLoaded = false;
7//methods to call when plugin is loaded
8var pluginLoaded = new ktools.Map();
9//is tour started
10var isTourStarted = false;
11//fullscreen object
12var kolorFullscreen = null;
13//browser detection
14var kolorBrowserDetect = null;
15//start z-index value
16var kolorStartIndex = 4000;
17//target url for cross domains application
18var crossDomainTargetUrl = '';
19var tourLanguage;
20
21if ( debug ) {
22	if ( typeof(console) == 'undefined' ) {
23		console = {log : function (text) {} };
24	}
25}
26
27/* ======== FULLSCREEN STUFF ========================================== */
28
29/**
30 * @description Register Fullscreen on DOM ready.
31 */
32jQuery(document).ready(function() {
33	//add browser detection
34	kolorBrowserDetect = new ktools.BrowserDetect();
35	kolorBrowserDetect.init();
36	//kolorBrowserDetect.browser : Browser string
37	//kolorBrowserDetect.version : Browser version
38	//kolorBrowserDetect.OS : Platform OS
39	
40	//add fullscreen
41	kolorFullscreen = new ktools.Fullscreen(document.getElementById("tourDIV"));
42	kolorFullscreen.supportsFullscreen();
43	//activate krpano fallback and update methods
44	kolorFullscreen.setExternal({
45		'enter': krPanoFullscreenEnter,
46		'exit': krPanoFullscreenExit,
47		'change': krpanoFullscreenChange,
48		'resize': krPanoFullscreenResize
49	});
50});
51
52/**
53 * @function
54 * @description Enter fullscreen fallback method for krpano.
55 * @return {void}
56 */
57function krPanoFullscreenEnter() {
58	var ki = getKrPanoInstance();
59	if(ki !== null){
60		getKrPanoInstance().call("enterFullScreenFallback");
61	}
62}
63
64/**
65 * @function
66 * @description Exit fullscreen fallback method for krpano.
67 * @return {void}
68 */
69function krPanoFullscreenExit() {
70	var ki = getKrPanoInstance();
71	if(ki !== null){
72		ki.call("exitFullScreenFallback");
73	}
74}
75
76/**
77 * @function
78 * @description Launch method for krpano on fullscreen change event.
79 * @param {Boolean} state If true enter fullscreen event, else exit fullscreen event.
80 * @return {void}
81 */
82function krpanoFullscreenChange(state) {
83	var ki = getKrPanoInstance();
84	if(ki !== null){
85		if(state){
86			getKrPanoInstance().call("enterFullScreenChangeEvent");
87		}else{
88			getKrPanoInstance().call("exitFullScreenChangeEvent");
89		}
90	}
91}
92
93/**
94 * @function
95 * @description Launch resize method for krpano correct resize.
96 * @return {void}
97 */
98function krPanoFullscreenResize() {
99	var ki = getKrPanoInstance();
100	if(ki !== null){
101		getKrPanoInstance().call("resizeFullScreenEvent");
102	}
103}
104
105/**
106 * @function
107 * @description Set fullscreen mode.
108 * @param {String|Boolean} value The fullscreen status: 'true' for open or 'false' for close.
109 * @return {void}
110 */
111function setFullscreen(value) {
112	var state;
113	if(typeof value == "string")
114		state = (value.toLowerCase() == "true");
115	else
116		state = Boolean(value);
117
118	if (kolorFullscreen) {
119		if(state){
120			kolorFullscreen.request();
121		}else{
122			kolorFullscreen.exit();
123		}
124	}
125}
126
127/* ========== DIALOG BETWEEN KRPANO/JS STUFF ================================= */
128
129/**
130 * @function
131 * @description Get krpano instance.
132 * @return {Object} krpano instance.
133 */
134function getKrPanoInstance() {
135	if ( krpano == null ) {
136		krpano = document.getElementById('krpanoSWFObject');
137	}
138	return krpano;
139}
140
141/**
142 * @function
143 * @description Call krpano function.
144 * @param {String} fnName The krpano action name.
145 * @param {*} Following parameters are passed to the krPano function
146 * @return {void}
147 */
148function invokeKrFunction(fnName) {
149	var args = [].slice.call(arguments, 1);
150	var callString = fnName+'(';
151	for(var i=0, ii=args.length; i<ii; i++)
152	{
153		callString += args[i];
154		if(i != ii-1) { callString += ', '; }
155	}
156	callString += ');';
157	if(getKrPanoInstance() !== null)
158	{
159		getKrPanoInstance().call(callString);
160	}
161}
162
163/**
164 * @function
165 * @description Get krpano identifier value.
166 * @param {String} identifier The qualifier.
167 * @param {String} type The converting type. Can be: 'int', 'float', 'string', 'boolean', 'object'.
168 * @return {Object}
169 */
170function getKrValue(identifier, type) {
171	if ( typeof identifier == "undefined" ){
172		return identifier;
173	}
174	
175	if(getKrPanoInstance() !== null)
176	{
177		if(getKrPanoInstance().get(identifier) == null) {
178			return null;
179		}
180
181		switch ( type ) {
182			case "int":
183				return parseInt(getKrPanoInstance().get(identifier));
184			case "float":
185				return parseFloat(getKrPanoInstance().get(identifier));
186			case "string":
187				return String(getKrPanoInstance().get(identifier));
188			case "bool":
189				return Boolean(getKrPanoInstance().get(identifier) === 'true' || parseInt(getKrPanoInstance().get(identifier)) === 1 || getKrPanoInstance().get(identifier) === 'yes' || getKrPanoInstance().get(identifier) === 'on');
190			default:
191				return getKrPanoInstance().get(identifier);
192		}
193	}
194	else
195	{
196		return null;
197	}
198}
199
200/**
201 * @function
202 * @description Invoke a function of a plugin engine.
203 * @param {String} pluginName The name/id of the plugin.
204 * @param {String} functionName The name of the function to invoke.
205 * @param {Object[]} arguments Additional arguments will be passed to the invoked function as an array.
206 * @return {Object}
207 */
208function invokePluginFunction(pluginName, functionName) {
209	if ( debug ) {
210		console.log("invokePluginFunction("+pluginName+", "+functionName+")");
211	}
212	
213	var plugin = ktools.KolorPluginList.getInstance().getPlugin(pluginName);
214	if (plugin == null) {
215		if ( debug ) { console.log("invokePluginFunction: plugin instance doesn't exist"); }
216		if(pluginLoaded && pluginLoaded.item(pluginName)){
217			pluginLoaded.update(pluginName, arguments);
218		}else{
219			pluginLoaded.add(pluginName, arguments);
220		}
221		return false;
222	}
223	var engine = plugin.getRegistered();
224	if (engine == null) {
225		if ( debug ) { console.log("invokePluginFunction: plugin isn't registered"); }
226		if(pluginLoaded && pluginLoaded.item(pluginName)){
227			pluginLoaded.update(pluginName, arguments);
228		}else{
229			pluginLoaded.add(pluginName, arguments);
230		}
231		return false;
232	}
233	var restArgs = [].slice.call(arguments, 2);
234	return engine[functionName](restArgs);
235}
236
237/**
238 * @function
239 * @description This function is called when krpano is ready.
240 * The ready state of krpano is told by its event onready (in fact it's not fully ready, included XML are not necessarily loaded) 
241 * @return {void}
242 */
243function eventKrpanoLoaded (isWebVr) {
244	if ( debug ) {
245		console.log('krpano is loaded');
246	}
247	
248	if (krpanoLoaded) { return false; }
249	
250	tourLanguage = getKrValue("tour_language","string")
251	if(typeof tourLanguage == "undefined"){
252		tourLanguage = 'de';
253	}
254	ktools.I18N.getInstance().initLanguage(tourLanguage, crossDomainTargetUrl+'virtueller-stadtrundgangdata/virtueller-stadtrundgang_messages_','.xml');
255	krpanoLoaded = true;
256	
257	if(isWebVr){
258	
259	addKolorAnalytics('analytics');
260
261	}else{
262	
263	addKolorArea('SuperText1');
264
265
266addKolorArea('panotourmapsArea');
267addKolorBox('webVideoViewer');
268addKolorBox('websiteViewer');
269addKolorAnalytics('analytics');
270
271	}
272}
273
274/**
275 * @function
276 * @description This function is called when plugins must be unloaded.
277 * @return {void}
278 */
279function eventUnloadPlugins () {
280	resetValuesForPlugins();
281
282	deleteKolorAnalytics('analytics');
283deleteKolorBox('websiteViewer');
284deleteKolorBox('webVideoViewer');
285
286
287deleteKolorMap('panotourmaps');
288deleteKolorArea('panotourmapsArea');
289
290deleteKolorArea('SuperText1');
291
292}
293
294/**
295 * @function
296 * @description Reset the default values for the player and plugins loaders.
297 * @return {void}
298 */
299function resetValuesForPlugins () {
300	krpano = null;
301	krpanoLoaded = false;
302	isTourStarted = false;
303	pluginLoaded = new ktools.Map();
304	kolorStartIndex = 4000;
305}
306
307/**
308 * @function
309 * @description This function is called when tour is started.
310 * @return {void}
311 */
312function eventTourStarted () {
313	if ( debug ) {
314		console.log('tour is started');
315	}
316	
317	isTourStarted = true;
318}
319
320/**
321 * @function
322 * @description This function is called when tour language is updated.
323 * @return {void}
324 */
325function eventTourChangeLanguage (pLang) {
326	if ( debug ) {
327		console.log('change tour language : '+pLang);
328	}
329	
330	ktools.I18N.getInstance().initLanguage(pLang, crossDomainTargetUrl+'virtueller-stadtrundgangdata/virtueller-stadtrundgang_messages_','.xml');
331}
332
333
334/* ========= KOLOR PLUGINS SCRIPTS ============================== */
335
336
337/**
338 * @function
339 * @description Add an instance of KolorAnalytics JS Engine, loads JS and CSS files then init and populate related plugin that's based on it.
340 * @param {String} pPlugID The name of the plugin you want to give to the kolorAnalytics instance.
341 * @return {void}
342 */
343function addKolorAnalytics(pPlugID)
344{
345	if(typeof ktools.KolorPluginList.getInstance().getPlugin(pPlugID) == "undefined")
346	{
347		var kolorAnalyticsJS = new ktools.Script("KolorAnalyticsJS", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorAnalytics/KolorAnalytics.min.js", [], true);
348		var kolorAnalyticsPlugin = new ktools.KolorPlugin(pPlugID);
349		kolorAnalyticsPlugin.addScript(kolorAnalyticsJS);
350		ktools.KolorPluginList.getInstance().addPlugin(kolorAnalyticsPlugin.getPluginName(), 
350kolorAnalyticsPlugin, true);
351
352		//generate it
353		if(!ktools.KolorPluginList.getInstance().getPlugin(pPlugID).getRegistered() || !ktools.KolorPluginList.getInstance().getPlugin(pPlugID).isInitialized() || typeof KolorAnalytics == "undefined"){
354			createKolorAnalytics(pPlugID);
355		}
356	}
357}
358
359/**
360 * @function
361 * @description Init, populate and show the KolorAnalytics.
362 * @param {String} pPlugID The name of the plugin you want to init and show.
363 * @return {void}
364 */
365function createKolorAnalytics(pPlugID)
366{
367	if(debug) { console.log("createKolorAnalytics "+pPlugID); }
368
369	//Check if the KolorAnalytics is loaded
370	if(!ktools.KolorPluginList.getInstance().getPlugin(pPlugID).isInitialized()  || typeof KolorAnalytics == "undefined")
371	{
372		err = "KolorAnalytics JS or XML is not loaded !";
373		if(debug){ console.log(err); }
374		//If not loaded, retry in 100 ms
375		setTimeout(function() { createKolorAnalytics(pPlugID); }, 100);
376		return;
377	}
378
379	//Check if the KolorAnalytics is instantiate and registered with the ktools.Plugin Object
380	//If not, instantiate the KolorAnalytics and register it.
381	if(ktools.KolorPluginList.getInstance().getPlugin(pPlugID).getRegistered() == null)
382	{
383		ktools.KolorPluginList.getInstance().getPlugin(pPlugID).register(new KolorAnalytics(pPlugID, "panoDIV"));
384	}
385
386	//Get the registered instance of KolorAnalytics
387	var kolorAnalytics = ktools.KolorPluginList.getInstance().getPlugin(pPlugID).getRegistered();
388
389	//If KolorAnalytics is not ready, populate datas
390	if(!kolorAnalytics.isReady())
391	{
392		var kolorAnalyticsOptions = [];
393
394		//Build the Options data for the KolorAnalytics
395		var optionLength = parseInt(getKrPanoInstance().get("ptplugin["+pPlugID+"].settings.option.count"));
396
397		for(var i = 0; i < optionLength; i++)
398		{
399			kolorAnalyticsOptions[getKrValue("ptplugin["+pPlugID+"].settings.option["+i+"].name","string")] = getKrValue("ptplugin["+pPlugID+"].settings.option["+i+"].value", getKrValue("ptplugin["+pPlugID+"].settings.option["+i+"].type", "string"));
400		}
401
402		kolorAnalytics.setKolorAnalyticsOptions(kolorAnalyticsOptions);
403
404		//KolorAnalytics is now ready
405		kolorAnalytics.setReady(true);
406
407		//call ready statement for krpano script
408		invokeKrFunction("kolorAnalyticsJsReady_"+pPlugID);
409
410		//Display the KolorAnalytics
411		kolorAnalytics.generateKolorAnalytics();
412	}
413}
414
415/**
416 * @function
417 * @description Update and populate KolorAnalytics.
418 * @param {String} pPlugID The name of the plugin you want to update.
419 * @param {String} pLang The language used by the plugin.
420 * @return {void}
421 */
422function updateKolorAnalytics(pPlugID,pLang)
423{
424	if(debug) { console.log("updateKolorAnalytics "+pPlugID); }
425
426	//Check if the KolorAnalytics is loaded
427	// if(ktools.KolorPluginList.getInstance().getPlugin(pPlugID).isInitialized() && typeof KolorAnalytics != "undefined" && ktools.KolorPluginList.getInstance().getPlugin(pPlugID).getRegistered() != null)
428	// {
429	// }
430}
431
432/**
433 * @function
434 * @description Delete KolorAnalytics.
435 * @param {String} pPlugID The name of the plugin you want to delete.
436 * @return {void}
437 */
438function deleteKolorAnalytics(pPlugID)
439{
440	if(ktools.KolorPluginList.getInstance().getPlugin(pPlugID)){
441		ktools.KolorPluginList.getInstance().removePlugin(pPlugID);
442	}
443}
444
445
446/**
447 * @function
448 * @description Add an instance of kolorBox JS Engine, loads JS and CSS files then init and populate related plugin that's based on it.
449 * @param {String} pPlugID The name of the plugin you want to give to the kolorBox instance. 
450 * @return {void}
451 */
452function addKolorBox(pPlugID)
453{
454	if(typeof ktools.KolorPluginList.getInstance().getPlugin(pPlugID) == "undefined")
455	{
456		var kolorBoxCSS = new ktools.CssStyle("KolorBoxCSS", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorBox/kolorBox.css");
457		var kolorBoxJS = new ktools.Script("KolorBoxJS", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorBox/KolorBox.min.js", [], true);
458		var kolorBoxPlugin = new ktools.KolorPlugin(pPlugID);
459		kolorBoxPlugin.addScript(kolorBoxJS);
460		kolorBoxPlugin.addCss(kolorBoxCSS);
461		ktools.KolorPluginList.getInstance().addPlugin(kolorBoxPlugin.getPluginName(), 
461kolorBoxPlugin, true);
462		showKolorBox(pPlugID, 0, true);
463	}
464}
465
466/**
467 * @function
468 * @description Init, populate and show the kolorBox. You can init only.
469 * @param {String} pPlugID The name of the plugin you want to init and/or show.
470 * @param {Number} pIndex The index you want to open, supposing your kolorBox is populated by a list of items (gallery case).
471 * @param {Boolean} pInitOnly If this param is true, just populate the kolorBox engine with the XML data without opening it.
472 * @return {void}
473 */
474function showKolorBox(pPlugID, pIndex, pInitOnly)
475{
476	if(debug) { console.log("showKolorBox " + pPlugID); }
477
478	//Check if the KolorBox is loaded
479	if(!ktools.KolorPluginList.getInstance().getPlugin(pPlugID).isInitialized() || typeof KolorBox === "undefined")
480	{
481		err = "KolorBox JS or XML is not loaded !";
482		if(debug){ console.log(err); }
483		//If not loaded, retry in 100 ms
484		setTimeout(function() { showKolorBox(pPlugID, pIndex, pInitOnly); }, 100);
485		return;
486	}
487
488	//Check if the KolorBox is instantiate and registered with the ktools.Plugin Object
489	//If not, instantiate the KolorBox and register it.
490	if(ktools.KolorPluginList.getInstance().getPlugin(pPlugID).getRegistered() === null)
491	{
492		ktools.KolorPluginList.getInstance().getPlugin(pPlugID).register(new KolorBox(pPlugID, "panoDIV"));
493	}
494
495	//Get the registered instance of KolorBox
496	var kolorBox = ktools.KolorPluginList.getInstance().getPlugin(pPlugID).getRegistered();
497
498	//If kolorBox is not ready, populate datas
499	if(!kolorBox.isReady())
500	{
501		var kolorBoxOptions = [];
502		var optionName = '';
503		var optionValue = '';
504
505		//Build the Options data for the KolorBox
506		var optionLength = parseInt(getKrPanoInstance().get("ptplugin["+pPlugID+"].settings.option.count"));
507
508		for(var j = 0; j < optionLength; j++)
509		{
510			optionName = getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].name","string");
511			if (optionName == 'zorder') {
512				optionValue = kolorStartIndex + getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].value", getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].type", "string"));
513			} else {
514				optionValue = getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].value", getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].type", "string"));
515			}
516			kolorBoxOptions[optionName] = optionValue;
517		}
518		//add the device check
519		kolorBoxOptions['device'] = getKrValue('vrtourdevice','string');
520		//kolorBoxOptions['scale'] = getKrValue('vrtourdevicescale','float');
521		kolorBox.setKolorBoxOptions(kolorBoxOptions);
522
523		if(kolorBoxOptions['starts_opened']) {
524			pInitOnly = false;
525		}
526
527		//Build the Items data for the KolorBox
528		var kbItem = null;
529		var itemLength = parseInt(getKrPanoInstance().get("ptplugin["+pPlugID+"].internaldata.item.count"));
530		for(var k = 0; k < itemLength; k++)
531		{
532			//Build a new item
533			kbItem = new KolorBoxObject();
534			kbItem.setName(getKrValue("ptplugin["+pPlugID+"].internaldata.item["+k+"].name","string"));
535			kbItem.setTitle(getKrValue("ptplugin["+pPlugID+"].internaldata.item["+k+"].title","string"));
536			kbItem.setCaption(getKrValue("ptplugin["+pPlugID+"].internaldata.item["+k+"].caption","string"));
537			kbItem.setValue(getKrValue("ptplugin["+pPlugID+"].internaldata.item["+k+"].value","string"));
538
539			//If external data get n' set
540			if(kbItem.getValue() === "externalData")
541				kbItem.setData(getKrValue('data['+getKrValue("ptplugin["+pPlugID+"].internaldata.item["+k+"].dataName","string")+'].content', 'string'));
542
543			//Add the item
544			kolorBox.addKolorBoxItem(kbItem);
545
546			kbItem.init();
547		}
548
549		//Kolorbox is now ready !
550		kolorBox.setReady(true);
551		//call ready statement for krpano script
552		invokeKrFunction("kolorBoxJsReady_"+pPlugID);
553	}
554
555	//If id is defined, show this kolorBox
556	if(typeof pPlugID !== "undefined" && (typeof pInitOnly === "undefined" || pInitOnly === false))
557	{
558		//If no index specified, set 0 as default index
559		if(typeof pIndex === "undefined") { pIndex = 0; }
560		kolorBox.openKolorBox(pIndex);
561	}
562
563	//If a plugin method has been called before registration the method is called now
564	if(pluginLoaded && pluginLoaded.item(pPlugID)){
565		invokePluginFunction.apply(null, pluginLoaded.item(pPlugID));
566		pluginLoaded.remove(pPlugID);
567	}
568}
569
570/**
571 * @function
572 * @description Delete kolorBox.
573 * @param {String} pPlugID The name of the plugin you want to delete.
574 * @return {void}
575 */
576function deleteKolorBox(pPlugID)
577{
578	if(ktools.KolorPluginList.getInstance().getPlugin(pPlugID)){
579		ktools.KolorPluginList.getInstance().removePlugin(pPlugID);
580	}
581	var parent = document.getElementById("panoDIV");
582	var child = document.getElementById(pPlugID);
583	if(parent && child){
584		parent.removeChild(child);
585	}
586}
587
588
589
590
591
592
593/** ---------------------- Start Plugin Map ----------------------- **/
594
595//KolorMap api providers
596var KolorMapApiProviders  = new Object();
597KolorMapApiProviders.Type = { googlev3: "googlev3", openlayersv2: "openlayersv2", microsoftv7: "microsoftv7", yandexv2: "yandexv2" };
598KolorMapApiProviders.Url  = { googlev3: "//maps.googleapis.com/maps/api/js?callback=handleApiReady",
599        openlayersv2: "//cdnjs.cloudflare.com/ajax/libs/openlayers/2.12/OpenLayers.js",
600        microsoftv7: "//www.bing.com/api/maps/mapcontrol/?callback=handleApiReady",
601        yandexv2: "//api-maps.yandex.ru/2.0-stable/?load=package.full&lang=ru-RU&onload=handleApiReady"
602    };
603KolorMapApiProviders.Key = { googlev3: "&key=", openlayersv2: "", microsoftv7: "", yandexv2: "&key=" };
604KolorMapApiProviders.Script = { googlev3: "mxn.googlev3.core.js", openlayersv2: "mxn.openlayersv2.core.js", microsoftv7: "mxn.microsoftv7.core.js", yandexv2: "mxn.yandexv2.core.js" };
605
606//store map loaded state
607var mapLoaded = new ktools.Map();
608var mapLoadedCounter = new ktools.Map();
609var mapPluginApiReadyCheck = new Array();
610//store the default marker ID to activate it once registered
611var mapMarkerDefault = new ktools.Map();
612//validate if the map has been instantiated
613var mapInstance = new ktools.Map();
614var mapInitCounter = new ktools.Map();
615
616//Add timestamp to mapstraction library to force IE to reload scripts
617var refreshIE = "";
618if (navigator.appName == "Microsoft Internet Explorer") {
619    var timestamp = new Date().getTime();
620    refreshIE = "?v="+timestamp;
621}
622
623//API provider keys
624var microsoftv7_key = "";
625
626/**
627 * @desc Check if a map API is loaded.
628 * @function
629 * @return {void}
630 */
631function handleApiReady() {
632    //get first plugName
633    var pluginName = mapPluginApiReadyCheck[0];
634
635    if( debug ){
636        console.log('Proprietary map API is loaded for '+pluginName);
637    }
638
639    if( pluginName != null ){
640        var counter = mapLoadedCounter.item(pluginName) - 1;
641        mapLoadedCounter.update(pluginName, counter);
642
643        if(counter <= 0){
644            mapLoaded.update(pluginName, true);
645        }
646
647        //remove first plugName
648        mapPluginApiReadyCheck.shift();
649    }
650}
651
652/** START PLUGIN MAP */
653
654/**
655 * @desc Add KolorMap plugin instance when krpano is loaded.
656 * @function
657 * @param {String} pluginName The name of the plugin instance.
658 * @param {Object[]} mapsApiArray Array of maps API names and keys couple.
659 * @param {String} mapAreaDiv The map area DOM div name, if exists.
660 * @return {void}
661 */
662function addKolorMap(pluginName, mapsApiArray, mapAreaDiv){
663
664    var mapsApiLength = mapsApiArray.length;
665    if(mapsApiLength > 0){
666        // add map for maps API
667
668        var mapApiOrder = new Array();
669        var useGoogleLabelsClass = false;
670        var hasOpenlayersMap = false;
671        //loop for maps API and maps API keys construction
672        for(var i=0; i < mapsApiLength; i++){
673
674            mapPluginApiReadyCheck.push(pluginName);
675
676            switch(mapsApiArray[i][0]){
677                case "microsoft" :
678                case "microsoft7" :
679                case "microsoftv7" :
680                case "microsoftv8" :
681                    //update the microsoft key
682                    microsoftv7_key = mapsApiArray[i][1];
683                    mapApiOrder[i] = [KolorMapApiProviders.Type.microsoftv7, KolorMapApiProviders.Url.microsoftv7, KolorMapApiProviders.Key.microsoftv7, KolorMapApiProviders.Script.microsoftv7];
684                    break;
685                case "google" :
686                case "googlev3" :
687                    //add key
688                    KolorMapApiProviders.Key.googlev3 += mapsApiArray[i][1];
689                    mapApiOrder[i] = [KolorMapApiProviders.Type.googlev3, KolorMapApiProviders.Url.googlev3, KolorMapApiProviders.Key.googlev3, KolorMapApiProviders.Script.googlev3];
690                    useGoogleLabelsClass = true;
691                    break;
692                case "yandex" :
693                case "yandexv2" :
694                    //add key
695                    KolorMapApiProviders.Key.yandexv2 += mapsApiArray[i][1];
696                    mapApiOrder[i] = [KolorMapApiProviders.Type.yandexv2, KolorMapApiProviders.Url.yandexv2, KolorMapApiProviders.Key.yandexv2, KolorMapApiProviders.Script.yandexv2];
697                    break;
698                case "openlayers" :
699                case "openlayersv2" :
700                    hasOpenlayersMap = true;
701                    mapApiOrder[i] = [KolorMapApiProviders.Type.openlayersv2, KolorMapApiProviders.Url.openlayersv2, KolorMapApiProviders.Key.openlayersv2, KolorMapApiProviders.Script.openlayersv2];
702                    break;
703            }
704        }
705
706        //init values for this plugin
707        mapLoaded.add(pluginName, false);
708        mapMarkerDefault.add(pluginName, {done: false});
709        mapInstance.add(pluginName, false);
710        //number of maps API to load
711        mapLoadedCounter.add(pluginName, mapsApiLength);
712        mapInitCounter.add(pluginName, 300); //try to load map only during 30 seconds max.
713
714        var mapPlugin = new ktools.KolorPlugin(pluginName);
715
716        // Libraries Dynamic loading
717        var mapApiScript = new ktools.Script(mapApiOrder[0][0], mapApiOrder[0][1]+mapApiOrder[0][2], [], false);
718
719        if (mapsApiLength > 1 && mapApiOrder[1]) {
720            //add second map layer
721            var mapApiScript2 = new ktools.Script(mapApiOrder[1][0], mapApiOrder[1][1]+mapApiOrder[1][2], [mapApiScript], false);
722            if (mapsApiLength > 2 && mapApiOrder[2]) {
723                //add third map layer
724                var mapApiScript3 = new ktools.Script(mapApiOrder[2][0], mapApiOrder[2][1]+mapApiOrder[2][2], [mapApiScript2], false);
725                var mapstractionScript = new ktools.Script("maps_mapstraction", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.js"+refreshIE, [mapApiScript3], false);
726                var mapstractionScriptBase = new ktools.Script("maps_mapstraction_base", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.basemap.js", [mapstractionScript], false);
727                var mapstractionScriptCore = new ktools.Script("maps_mapstraction_core", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.core.js"+refreshIE, [mapstractionScriptBase], false);
728                var mapstractionScriptCoreLayer3 = new ktools.Script("maps_mapstraction_core_layer3", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/"+mapApiOrder[2][3]+refreshIE, [mapstractionScriptCore], false);
729                var mapstractionScriptCoreLayer2 = new ktools.Script("maps_mapstraction_core_layer2", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/"+mapApiOrder[1][3]+refreshIE, [mapstractionScriptCoreLayer3], false);
730                var mapstractionScriptCoreLayer1 = new ktools.Script("maps_mapstraction_core_layer1", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/"+mapApiOrder[0][3]+refreshIE, [mapstractionScriptCoreLayer2], false);
731            } else {
732                if(mapsApiLength > 2){
733                    var tmp_counter = mapLoadedCounter.item(pluginName) - 1;
734                    mapLoadedCounter.update(pluginName, tmp_counter);
735                }
736                var mapstractionScript = new ktools.Script("maps_mapstraction", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.js"+refreshIE, [mapApiScript2], false);
737                var mapstractionScriptBase = new ktools.Script("maps_mapstraction_base", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.basemap.js", [mapstractionScript], false);
738                var mapstractionScriptCore = new ktools.Script("maps_mapstraction_core", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.core.js"+refreshIE, [mapstractionScriptBase], false);
739                var mapstractionScriptCoreLayer2 = new ktools.Script("maps_mapstraction_core_layer2", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/"+mapApiOrder[1][3]+refreshIE, [mapstractionScriptCore], false);
740                var mapstractionScriptCoreLayer1 = new ktools.Script("maps_mapstraction_core_layer1", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/"+mapApiOrder[0][3]+refreshIE, [mapstractionScriptCoreLayer2], false);
741            }
742        } else {
743            if(mapsApiLength > 1){
744                var tmp_counter = mapLoadedCounter.item(pluginName) - 1;
745                mapLoadedCounter.update(pluginName, tmp_counter);
746            }
747            var mapstractionScript = new ktools.Script("maps_mapstraction", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.js"+refreshIE, [mapApiScript], false);
748            var mapstractionScriptBase = new ktools.Script("maps_mapstraction_base", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.basemap.js", [mapstractionScript], false);
749            var mapstractionScriptCore = new ktools.Script("maps_mapstraction_core", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.core.js"+refreshIE, [mapstractionScriptBase], false);
750            var mapstractionScriptCoreLayer1 = new ktools.Script("maps_mapstraction_core_layer1", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/"+mapApiOrder[0][3]+refreshIE, [mapstractionScriptCore], false);
751        }
752
753        var kolorMapScript = null;
754        if (useGoogleLabelsClass) {
755            var googleLabelsScript = new ktools.Script("maps_google_labels", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/lib/mxn.googlev3.core.labels.js", [mapstractionScriptCoreLayer1], false);
756            kolorMapScript = new ktools.Script("kolormap", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/js/KolorMap.min.js", [googleLabelsScript], true);
757        } else {
758            kolorMapScript = new ktools.Script("kolormap", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/js/KolorMap.min.js", [mapstractionScriptCoreLayer1], true);
759        }
760        mapPlugin.addScript(kolorMapScript);
761
762        var kolorMapCSS = new ktools.CssStyle("kolormapCSS", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorMap/js/kolorMap.css");
763        mapPlugin.addCss(kolorMapCSS);
764
765        ktools.KolorPluginList.getInstance().addPlugin(mapPlugin.getPluginName(), mapPlugin, true);
766
767        if(hasOpenlayersMap){
768            //delay for 1000ms for OpenLayers only
769            setTimeout(function() { handleApiReady(); }, 1000);
770        }
771
772        //display
773        initKolorMapOnReady(pluginName, mapApiScript.getName(), mapAreaDiv);
774    }
775}
776
777/**
778 * @desc Init the KolorMap script to generate the map.
779 * @function
780 * @param {String} pluginName The name of the plugin instance.
781 * @param {String} defaultMapLayer the default map layer name.
782 * @param {String} mapAreaDiv The map area DOM div name, if exists.
783 * @return {void}
784 */
785function initKolorMapOnReady(pluginName, defaultMapLayer, mapAreaDiv) {
786    var err = "";
787    var reload = false;
788
789    if ( !krpanoLoaded ) {
790        err = "throw: krpano is not loaded";
791        reload = true;
792    }
793
794    if ( !isTourStarted ) {
795        err = "throw: tour is not started";
796        reload = true;
797    }
798
799    if ( !mapLoaded.item(pluginName) ) {
800        err = "throw: plugin Map is not loaded";
801        reload = true;
802    }
803
804    //map generation
805    if  ( typeof KolorMap == "undefined" || !ktools.KolorPluginList.getInstance().getPlugin(pluginName).isInitialized() ) {
806        err = "throw: KolorMap library not ready";
807        reload = true;
808    }
809
810    //verify map instance
811    if(mapInstance.item(pluginName) && ktools.KolorPluginList.getInstance().getPlugin(pluginName).getRegistered()){
812        err = "throw: KolorMap already loaded";
813        reload = true;
814    }else{
815        mapInstance.update(pluginName, true);
816    }
817
818    // verify if vr XML plugin is loaded
819    if (getKrValue('ptplugin['+pluginName+'].engine', 'string') == null){
820        err = "throw: KolorMap can't reach XML yet";
821        reload = true;
822    }
823
824    // reload init if KolorMap is not ready
825    if(reload){
826        if ( debug ) {
827            console.log(err);
828        }
829
830        if(mapInitCounter.item(pluginName) > 0){
831            // start counter only when tour is started
832            if (isTourStarted) {
833                mapInitCounter.update(pluginName, (mapInitCounter.item(pluginName) - 1));
834            }
835            // if not loaded, retry in 100 ms
836            setTimeout(function() { initKolorMapOnReady(pluginName, defaultMapLayer, mapAreaDiv); }, 100);
837            return;
838        }else{
839            // FIXME : i18n change text value
840            alert("Connection timeout while making map API call. Try to reload the page.");
841            return;
842        }
843    }
844
845    // prepare multimap swap selector
846    var selectorArray = new Array();
847
848    //set the default map
849    if (getKrValue('ptplugin['+pluginName+'].multimap', 'bool')) {
850
851        //default map is the first element
852        var defaultMap = new Object();
853        defaultMap['element'] = getKrValue('ptplugin['+pluginName+'].multiplemaps.map.element', 'string'); //sample: 'mapdiv'
854        defaultMap['provider'] = getKrValue('ptplugin['+pluginName+'].multiplemaps.map.provider', 'string'); //sample: mapApiScript.getName()
855        defaultMap['name'] = ktools.I18N.getInstance().getMessage(getKrValue('ptplugin['+pluginName+'].multiplemaps.map.name', 'string'));
856        selectorArray[0] = defaultMap;
857
858        kolorMap = new KolorMap(defaultMap.element, defaultMap.provider);
859    }else{
860        if (mapAreaDiv) {
861            kolorMap = new KolorMap(mapAreaDiv, defaultMapLayer);
862        } else {
863            kolorMap = new KolorMap('mapDIV', defaultMapLayer);
864        }
865    }
866
867    if ( debug ) {
868        console.log("instance: " + kolorMap);
869    }
870
871    //add map default DOM div elements
872    if (mapAreaDiv) {
873        kolorMap.setMapLayer(mapAreaDiv);
874    } else {
875        kolorMap.setMapLayer('mapDIV');
876        kolorMap.setMapContainer('mapcontainer');
877        kolorMap.setPanoContainer('panoDIV');
878        kolorMap.setTourContainer('tourDIV');
879    }
880
881    //map div position
882    kolorMap.setMapPosition(getKrValue('ptplugin['+pluginName+'].position', 'string'));
883
884    //set zOrder
885    kolorMap.setMapZorder(kolorStartIndex + getKrValue("ptplugin["+pluginName+"].zorder","int"));
886
887    //set url for maps images
888    kolorMap.setGraphicsUrl(crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/"+pluginName.toLowerCase()+"/");
889
890    //set color and resizable option
891    kolorMap.setMapResizable(getKrValue('ptplugin['+pluginName+'].resizable', 'bool'));
892    kolorMap.setBgColor(getKrValue('ptplugin['+pluginName+'].bgcolor', 'string'));
893
894    //add the device check
895    kolorMap.setDeviceUsed(getKrValue('vrtourdevice','string'));
896    //kolorMap.setDeviceScale(getKrValue('vrtourdevicescale','float'));
897
898    // set if map must be displayed or hidden
899    var displayOnStart = getKrValue('ptplugin['+pluginName+'].openatstart', 'bool');
900
901    //init map size into DOM (needed for openlayers API);
902    if (mapAreaDiv) {
903        kolorMap.initMapLayer();
904    } else {
905        kolorMap.setMapSize(getKrValue('ptplugin['+pluginName+'].size', 'int'));
906        if(displayOnStart){
907            kolorMap.initMapSize();
908            kolorMap.initMapLayer();
909        }
910    }
911
912    //add swap selector
913    if (getKrValue('ptplugin['+pluginName+'].multimap', 'bool')) {
914
915        //second map
916        var secondMap = new Object();
917        secondMap['element'] = getKrValue('ptplugin['+pluginName+'].multiplemaps.map[1].element', 'string');
918        secondMap['provider'] = getKrValue('ptplugin['+pluginName+'].multiplemaps.map[1].provider', 'string');
919        secondMap['name'] = ktools.I18N.getInstance().getMessage(getKrValue('ptplugin['+pluginName+'].multiplemaps.map[1].name', 'string'));
920        selectorArray[1] = secondMap;
921        //add in DOM
922        jQuery('#mapcontainer').append('<div id="'+secondMap['element']+'"></div>');
923
924        //third map
925        if (getKrValue('ptplugin['+pluginName+'].multiplemaps.map[2]')) {
926            var thirdMap = new Object();
927            thirdMap['element'] = getKrValue('ptplugin['+pluginName+'].multiplemaps.map[2].element', 'string');
928            thirdMap['provider'] = getKrValue('ptplugin['+pluginName+'].multiplemaps.map[2].provider', 'string');
929            thirdMap['name'] = ktools.I18N.getInstance().getMessage(getKrValue('ptplugin['+pluginName+'].multiplemaps.map[2].name', 'string'));
930            selectorArray[2] = thirdMap;
931            //add in DOM
932            jQuery('#mapcontainer').append('<div id="'+thirdMap['element']+'"></div>');
933        }
934
935        kolorMap.addSwapSelector(pluginName, selectorArray, ktools.I18N.getInstance().getMessage(getKrValue('ptplugin['+pluginName+'].multiplemaps.label', 'string')));
936    }
937
938    // initialize map position
939    var startPointLat = getKrValue('ptplugin['+pluginName+'].lat', 'float');
940    var startPointLng = getKrValue('ptplugin['+pluginName+'].lng', 'float');
941    var startPointZoom = getKrValue('ptplugin['+pluginName+'].zoom','int');
942    var startPoint = new mxn.LatLonPoint(startPointLat, startPointLng);
943    kolorMap.setStartPoint(startPoint, startPointZoom);
944    kolorMap.getMxnMap().setCenterAndZoom(startPoint, startPointZoom);
945
946    // set map type
947    switch(getKrValue('ptplugin['+pluginName+'].maptypelayer','string')){
948        case 'satellite':
949            kolorMap.getMxnMap().setMapType(mxn.Mapstraction.SATELLITE);
950            break;
951        case 'hybrid':
952            kolorMap.getMxnMap().setMapType(mxn.Mapstraction.HYBRID);
953            break;
954        case 'physical':
955            kolorMap.getMxnMap().setMapType(mxn.Mapstraction.PHYSICAL);
956            break;
957        default:
958            //'road'
959            kolorMap.getMxnMap().setMapType(mxn.Mapstraction.ROAD);
960    }
961
962    // add controls
963    var useZoom = getKrValue('ptplugin['+pluginName+'].controls.zoom', 'bool');
964    var usePan = getKrValue('ptplugin['+pluginName+'].controls.pan', 'bool');
965    var useMapType = getKrValue('ptplugin['+pluginName+'].controls.maptype', 'bool');
966    var useOverview = getKrValue('ptplugin['+pluginName+'].controls.overview', 'bool');
967    var useScale = getKrValue('ptplugin['+pluginName+'].controls.scale', 'bool');
968    var useSpecific = new Object();
969    if(getKrValue('ptplugin['+pluginName+'].controls.specific')){
970        if(getKrValue('ptplugin['+pluginName+'].controls.specific.streetview', 'bool')){
971            useSpecific.streetview = getKrValue('ptplugin['+pluginName+'].controls.specific.streetview', 'bool');
972        }
973        if(getKrValue('ptplugin['+pluginName+'].controls.specific.view45degree', 'bool')){
974            useSpecific.view45degree = getKrValue('ptplugin['+pluginName+'].controls.specific.view45degree', 'bool');
975        }
976    }
977    kolorMap.addControls(useZoom,usePan,useScale,useMapType,useOverview,useSpecific);
978
979    // add ui controls
980    var useDragging = false;
981    var useScroll = false;
982    var useDblClick = false;
983    if(getKrValue('ptplugin['+pluginName+'].controls.ui')){
984        useDragging = getKrValue('ptplugin['+pluginName+'].controls.ui.draggable', 'bool');
985        useScroll = getKrValue('ptplugin['+pluginName+'].controls.ui.scrollable', 'bool');
986        useDblClick = getKrValue('ptplugin['+pluginName+'].controls.ui.dblclick', 'bool');
987    }
988    kolorMap.getMxnMap().setOption('enableDragging', useDragging);
989    kolorMap.getMxnMap().setOption('enableScrollWheelZoom', useScroll);
990    kolorMap.getMxnMap().setOption('disableDoubleClickZoom', !useDblClick);
991
992    // generate radar(s)
993    var useRadars = false;
994    var radarOptions = {};
995    if(getKrValue('ptplugin['+pluginName+'].radar.visible','string') == "true"){
996        useRadars = true;
997        radarOptions = {
998            radius: getKrValue('ptplugin['+pluginName+'].radar.radius','int'),
999            linkToZoom: getKrValue('ptplugin['+pluginName+'].radar.linktozoom','bool'),
1000            quality: getKrValue('ptplugin['+pluginName+'].radar.quality','int'),
1001            color: getKrValue('ptplugin['+pluginName+'].radar.linecolor','string'),
1002            opacity: getKrValue('ptplugin['+pluginName+'].radar.lineopacity','float'),
1003            width: getKrValue('ptplugin['+pluginName+'].radar.linewidth','int'),
1004            fillColor: getKrValue('ptplugin['+pluginName+'].radar.fillcolor','string'),
1005            fillOpacity: getKrValue('ptplugin['+pluginName+'].radar.fillopacity','float'),
1006            enginePreset: 0
1007        };
1008    }
1009
1010    // markers animation
1011    var useAnimation = false;
1012    if(getKrValue('ptplugin['+pluginName+'].markers.animation','string') == "bounce"){
1013        useAnimation = true;
1014    }
1015
1016    // add markers
1017    var markersLength = parseInt(getKrPanoInstance().get('ptplugin['+pluginName+'].marker.count'));
1018    if(markersLength > 0){
1019        for( var i=0; i < markersLength; i++ ){
1020            var markerId = getKrValue('ptplugin['+pluginName+'].marker[' + i + '].name', 'string');
1021            var markerPointLat = getKrValue('ptplugin['+pluginName+'].marker[' + i + '].lat', 'float');
1022            var markerPointLng = getKrValue('ptplugin['+pluginName+'].marker[' + i + '].lng', 'float');
1023            var markerLatLon = new mxn.LatLonPoint(markerPointLat, markerPointLng);
1024
1025            // actions
1026            var isDraggable = getKrValue('ptplugin['+pluginName+'].marker[' + i + '].draggable', 'bool');
1027            var infoOnHover = getKrValue('ptplugin['+pluginName+'].marker[' + i + '].onhover', 'bool');
1028            var isAnimated = getKrValue('ptplugin['+pluginName+'].marker[' + i + '].animated', 'bool');
1029
1030            // icon
1031            var iconUrl = "";
1032            var iconSize = null;
1033            var iconAnchor = null;
1034            var markerIcon = getKrValue('ptplugin['+pluginName+'].marker[' + i + '].markericon','object');
1035            if ( markerIcon != null ) {
1036                iconUrl = markerIcon.url;
1037                iconSize = new Array();
1038                iconSize[0] = parseInt(markerIcon.iconwidth);
1039                iconSize[1] = parseInt(markerIcon.iconheight);
1040                iconAnchor = new Array();
1041                switch ( markerIcon.iconanchor.toLowerCase() ) {
1042                    case "topleft":
1043                        iconAnchor[0] = 0;
1044                        iconAnchor[1] = 0;
1045                        iconAnchor[2] = "topleft";
1046                        break;
1047                    case "top"://topcenter
1048                        iconAnchor[0] = parseInt(iconSize[0]/2);
1049                        iconAnchor[1] = 0;
1050                        iconAnchor[2] = "top";
1051                        break;
1052                    case "topright":
1053                        iconAnchor[0] = iconSize[0];
1054                        iconAnchor[1] = 0;
1055                        iconAnchor[2] = "topright";
1056                        break;
1057                    case "left"://middleleft
1058                        iconAnchor[0] = 0;
1059                        iconAnchor[1] = parseInt(iconSize[1]/2);
1060                        iconAnchor[2] = "left";
1061                        break;
1062                    case "center"://middlecenter
1063                        iconAnchor[0] = parseInt(iconSize[1]/2);
1064                        iconAnchor[1] = parseInt(iconSize[1]/2);
1065                        iconAnchor[2] = "center";
1066                        break;
1067                    case "right"://middleright
1068                        iconAnchor[0] = iconSize[0];
1069                        iconAnchor[1] = parseInt(iconSize[1]/2);
1070                        iconAnchor[2] = "right";
1071                        break;
1072                    case "bottomleft":
1073                        iconAnchor[0] = 0;
1074                        iconAnchor[1] = iconSize[1];
1075                        iconAnchor[2] = "bottomleft";
1076                        break;
1077                    case "bottomright":
1078                        iconAnchor[0] = iconSize[0];
1079                        iconAnchor[1] = iconSize[1];
1080                        iconAnchor[2] = "bottomright";
1081                        break;
1082                    default:
1083                        //"bottom" : bottomcenter
1084                        iconAnchor[0] = parseInt(iconSize[0]/2);
1085                        iconAnchor[1] = iconSize[1];
1086                        iconAnchor[2] = "bottom";
1087                }
1088            }
1089
1090            // add radar only for scene marker
1091            if(useRadars && getKrValue('ptplugin['+pluginName+'].marker[' + i + '].isscene', 'bool') && getKrValue('ptplugin['+pluginName+'].marker[' + i + '].hasradar', 'bool')){
1092
1093                // change radar heading
1094                var markerPointHeading = getKrValue('ptplugin['+pluginName+'].marker[' + i + '].heading', 'float');
1095                radarOptions.heading = markerPointHeading;
1096
1097                var aMarkerRadar = kolorMap.addRadar(markerId, markerLatLon, radarOptions);
1098            }
1099
1100            kolorMap.activateMarkersAnimation(useAnimation);
1101
1102            //add marker (always after radar for openlayers layers z-index)
1103            var aMarker = kolorMap.addMarker(markerId, pluginName, markerLatLon, iconUrl, iconSize, iconAnchor, jQuery.trim(ktools.I18N.getInstance().getMessage(getKrValue('ptplugin['+pluginName+'].marker[' + i + '].desc', 'string'))), getKrValue('ptplugin['+pluginName+'].marker[' + i + '].desctype', 'string'), infoOnHover, isDraggable, isAnimated);
1104
1105            // set the marker's event
1106            kolorMap.getMxnMap().addEventListener('click', mapMarkerEvent, aMarker);
1107        }
1108    }
1109
1110    //register plugin
1111    ktools.KolorPluginList.getInstance().getPlugin(pluginName).register(kolorMap);
1112
1113    var kolorMapRegistred = ktools.KolorPluginList.getInstance().getPlugin(pluginName).getRegistered();
1114
1115    //if the marker ID to activate have been initialized while the map wasn't registered, activate it now
1116    if ( kolorMapRegistred ) {
1117
1118        if (mapMarkerDefault.item(pluginName).done == false) {
1119            var applySelection = true;
1120            if (getKrValue('ptplugin['+pluginName+'].markerSelected.name','string') != "") {
1121                setMapDefaultMarker(pluginName, getKrValue('ptplugin['+pluginName+'].markerSelected.name','string'), getKrValue('ptplugin['+pluginName+'].markerSelected.heading','float'), getKrValue('ptplugin['+pluginName+'].markerSelected.fov','float'));
1122            } else if (mapMarkerDefault.item(pluginName).id != undefined) {
1123                mapMarkerDefaultArray = [mapMarkerDefault.item(pluginName).id, mapMarkerDefault.item(pluginName).heading, mapMarkerDefault.item(pluginName).fov];
1124            } else {
1125                applySelection = false;
1126            }
1127
1128            if (applySelection) {
1129                if ( debug ) {
1130                    console.log("activate the stored marker after init");
1131                }
1132                var mapMarkerDefaultArray = [mapMarkerDefault.item(pluginName).id, mapMarkerDefault.item(pluginName).heading, mapMarkerDefault.item(pluginName).fov, getKrValue('ptplugin['+pluginName+'].centeronspots','bool')];
1133                kolorMapRegistred.changeCurrentMarker(mapMarkerDefaultArray);
1134            }
1135            mapMarkerDefault.update(pluginName, {done: true});
1136        }
1137    }else{
1138        if ( debug ) {
1139            console.log("KolorMap isn't really loaded");
1140        }
1141        mapInstance.update(pluginName, false);
1142        //if not loaded, retry in 100 ms
1143        setTimeout(function() { initKolorMapOnReady(pluginName, defaultMapLayer, mapAreaDiv); }, 100);
1144        return;
1145    }
1146
1147    if (mapAreaDiv) {
1148        //force refresh for openlayers
1149        kolorMapRegistred.forceResizeMapLayer([mapAreaDiv]);
1150    } else {
1151        //hide map if needed
1152        if(displayOnStart){
1153            kolorMapRegistred.initResizableMap();
1154        }else{
1155            if ( kolorMapRegistred ) {
1156                kolorMapRegistred.openCloseMap(["close"]);
1157            }
1158        }
1159    }
1160
1161    //call ready statement for krpano script
1162    invokeKrFunction("kolorMapJsReady_"+pluginName);
1163
1164    //If a plugin method has been called before registration the method is called now
1165    if(pluginLoaded && pluginLoaded.item(pluginName)){
1166        invokePluginFunction.apply(null, pluginLoaded.item(pluginName).funcArgs);
1167        pluginLoaded.remove(pluginName);
1168    }
1169}
1170
1171/**
1172 * @desc Store the map default marker with datas.
1173 * @function
1174 * @param {String} pluginName The plugin name.
1175 * @param {String} markerId The marker ID.
1176 * @param {String} krHeading The heading value from krpano.
1177 * @param {String} krFov The fov value from krpano.
1178 */
1179function setMapDefaultMarker(pluginName, markerId, krHeading, krFov){
1180    var mapMarkerDefaultObject = { id: markerId, heading: krHeading, fov: krFov, done: false };
1181    mapMarkerDefault.update(pluginName, mapMarkerDefaultObject);
1182}
1183
1184/**
1185 * @desc Event on a map marker.
1186 * @function
1187 * @param {String} eventType The type of the event: 'click'.
1188 * @param {mxn.Marker} objectSource The marker object.
1189 * @param {Object} objdata Structured object additional informations.
1190 * @return {void}
1191 */
1192function mapMarkerEvent(eventType, objectSource, objdata) {
1193    if (debug) {
1194        console.log('Map marker event "' + eventType + '" for marker "' + objectSource.getAttribute("id") + '" on plugin "' + objectSource.getAttribute("plugName") + '"');
1195    }
1196
1197    // if current marker is different select and activate the new marker
1198    if ( kolorMap.getActiveMarker() != objectSource ) {
1199        var jsMapMarkerAction = objectSource.getAttribute("plugName")+"GoMarker('" + objectSource.getAttribute("id") + "')";
1200        getKrPanoInstance().call(jsMapMarkerAction);
1201    }
1202
1203    // call the marker 'jsclick' action
1204    var krMapMarkerAction = getKrValue('ptplugin['+objectSource.getAttribute("plugName")+'].marker[' + objectSource.getAttribute("id") + '].jsclick');
1205    getKrPanoInstance().call(krMapMarkerAction);
1206}
1207
1208/**
1209 * @desc Change api provider on the fly for the map.
1210 * @function
1211 * @param {String} pluginName The plugin name.
1212 * @param {String} element The DOM element containing the map layer.
1213 * @param {String} api The provider API selected for the map layer element.
1214 * @return {void}
1215 */
1216function swapProvider(pluginName, element, api){
1217    if ( ktools.KolorPluginList.getInstance().getPlugin(pluginName).getRegistered() != null ) {
1218        var kolorMapRegistered = ktools.KolorPluginList.getInstance().getPlugin(pluginName).getRegistered();
1219        kolorMapRegistered.swapProvider([element, api]);
1220    }
1221}
1222
1223/**
1224 * @function
1225 * @description Delete kolorMap.
1226 * @param {String} pPlugID The name of the plugin you want to delete.
1227 * @return {void}
1228 */
1229function deleteKolorMap(pPlugID)
1230{
1231    if(ktools.KolorPluginList.getInstance().getPlugin(pPlugID)){
1232        ktools.KolorPluginList.getInstance().removePlugin(pPlugID);
1233    }
1234}
1235
1236var kolorMapContainerDOM;
1237
1238/**
1239 * @function
1240 * @description Delete kolorMap and the restore the DOM.
1241 * @param {String} pPlugID The name of the plugin you want to delete.
1242 * @return {void}
1243 */
1244function deleteKolorMapDOM(pPlugID)
1245{
1246    if(ktools.KolorPluginList.getInstance().getPlugin(pPlugID)){
1247        var kolorMapRegistered = ktools.KolorPluginList.getInstance().getPlugin(pPlugID).getRegistered();
1248        if(kolorMapRegistered)
1249        {
1250            //delete resizable part
1251            kolorMapRegistered.deleteResizableMap();
1252            //restore map container DOM
1253            kolorMapRegistered.restoreMapContainerDOM(kolorMapContainerDOM);
1254            //resize player div
1255            kolorMapRegistered.restorePanoContainerDOM();
1256        }
1257        //delete plugin instance
1258        deleteKolorMap('panotourmaps');
1259    }
1260}
1261
1262/**
1263 * @function
1264 * @description Save the kolorMap container initial DOM.
1265 * @return {void}
1266 */
1267function saveKolorMapContainer()
1268{
1269    kolorMapContainerDOM = jQuery('#mapcontainer').clone();
1270}
1271
1272/** ---------------------- End Plugin Map ----------------------- **/
1273
1274
1275/**
1276 * @function
1277 * @description Add an instance of kolorArea JS Engine, loads JS and CSS files then init and populate related plugin that's based on it.
1278 * @param {String} pPlugID The name of the plugin you want to give to the kolorArea instance.
1279 * @return {void}
1280 */
1281function addKolorArea(pPlugID)
1282{
1283	if(typeof ktools.KolorPluginList.getInstance().getPlugin(pPlugID) == "undefined")
1284	{
1285		var kolorAreaCSS = new ktools.CssStyle("KolorAreaCSS", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorArea/kolorArea.css");
1286		var kolorAreaJS = new ktools.Script("KolorAreaJS", crossDomainTargetUrl+"virtueller-stadtrundgangdata/graphics/KolorArea/KolorArea.min.js", [], true);
1287		var kolorAreaPlugin = new ktools.KolorPlugin(pPlugID);
1288		kolorAreaPlugin.addScript(kolorAreaJS);
1289		kolorAreaPlugin.addCss(kolorAreaCSS);
1290		ktools.KolorPluginList.getInstance().addPlugin(kolorAreaPlugin.getPluginName(), 
1290kolorAreaPlugin, true);
1291	}
1292}
1293
1294/**
1295 * @function
1296 * @description Init, populate and show the kolorArea.
1297 * @param {String} pPlugID The name of the plugin you want to init and show.
1298 * @param {String} pContent The content you want to inject into the kolorArea. I could be HTML string or any other string.
1299 * @return {void}
1300 */
1301function showKolorArea(pPlugID, pContent)
1302{
1303	if(debug) { console.log("showKolorArea " + pPlugID); }
1304
1305	//Check if the KolorArea is loaded
1306	if(!ktools.KolorPluginList.getInstance().getPlugin(pPlugID).isInitialized() || typeof KolorArea == "undefined")
1307	{
1308		err = "KolorArea JS is not loaded !";
1309		if(debug){ console.log(err); }
1310		//If not loaded, retry in 100 ms
1311		setTimeout(function() { showKolorArea(pPlugID, pContent); }, 100);
1312		return;
1313	}
1314
1315	//Check if the KolorArea is instantiate and registered with the ktools.Plugin Object
1316	//If not, instantiate the KolorArea and register it.
1317	if(ktools.KolorPluginList.getInstance().getPlugin(pPlugID).getRegistered() == null)
1318	{
1319		ktools.KolorPluginList.getInstance().getPlugin(pPlugID).register(new KolorArea(pPlugID, "panoDIV"));
1320	}
1321
1322	//Get the registered instance of KolorArea
1323	var kolorArea = ktools.KolorPluginList.getInstance().getPlugin(pPlugID).getRegistered();
1324
1325	//If kolorArea is not ready, populate datas
1326	if(!kolorArea.isReady())
1327	{
1328		var kolorAreaOptions = [];
1329		var optionName = '';
1330		var optionValue = '';
1331
1332		//Build the Options data for the KolorArea
1333		var optionLength = parseInt(getKrPanoInstance().get("ptplugin["+pPlugID+"].settings.option.count"));
1334
1335		for(var j = 0; j < optionLength; j++)
1336		{
1337			optionName = getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].name","string");
1338			if (optionName == 'zorder') {
1339				optionValue = kolorStartIndex + getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].value", getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].type", "string"));
1340			} else {
1341				optionValue = getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].value", getKrValue("ptplugin["+pPlugID+"].settings.option["+j+"].type", "string"));
1342			}
1343			kolorAreaOptions[optionName] = optionValue;
1344		}
1345		//add the device check
1346		kolorAreaOptions['device'] = getKrValue('vrtourdevice','string');
1347		//kolorAreaOptions['scale'] = getKrValue('vrtourdevicescale','float');
1348		kolorArea.setKolorAreaOptions(kolorAreaOptions);
1349
1350		//KolorArea is now ready !
1351		kolorArea.setReady(true);
1352		//call ready statement for krpano script
1353		invokeKrFunction("kolorAreaJsReady_"+pPlugID);
1354	}
1355
1356	kolorArea.setKolorAreaContent(pContent);
1357	kolorArea.openKolorArea();
1358
1359	//If a plugin method has been called before registration the method is called now
1360	if(pluginLoaded && pluginLoaded.item(pPlugID)){
1361		invokePluginFunction.apply(null, pluginLoaded.item(pPlugID).funcArgs);
1362		pluginLoaded.remove(pPlugID);
1363	}
1364}
1365
1366/**
1367 * @function
1368 * @description Delete kolorArea.
1369 * @param {String} pPlugID The name of the plugin you want to delete.
1370 * @return {void}
1371 */
1372function deleteKolorArea(pPlugID)
1373{
1374	if(ktools.KolorPluginList.getInstance().getPlugin(pPlugID)){
1375		ktools.KolorPluginList.getInstance().removePlugin(pPlugID);
1376	}
1377	var parent = document.getElementById("panoDIV");
1378	var child = document.getElementById(pPlugID);
1379	if(parent && child){
1380		parent.removeChild(child);
1381	}
1382}

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.