text: /*!
   * SAP UI development toolkit for HTML5 (SAPUI5/OpenUI5)
   * (c) Copyright 2009-2015 SAP SE or an SAP affiliate company.
   * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
   */
  
  // Provides class sap.ui.core.util.LibraryInfo
  sap.ui.define(['jquery.sap.global', 'sap/ui/base/Object', 'jquery.sap.script'],
  	function(jQuery, BaseObject/* , jQuerySap */) {
  	"use strict";
  
  
  	/**
  	 * Provides library information.
  	 * @class Provides library information.
  	 *
  	 * @extends sap.ui.base.Object
  	 * @author SAP SE
  	 * @version 1.28.5
  	 * @constructor
  	 * @private
  	 * @alias sap.ui.core.util.LibraryInfo
  	 */
  	var LibraryInfo = BaseObject.extend("sap.ui.core.util.LibraryInfo", {
  		constructor : function() {
  			BaseObject.apply(this);
  			this._oLibInfos = {};
  		},
  		
  		destroy : function() {
  			BaseObject.prototype.destroy.apply(this, arguments);
  			this._oLibInfos = {};
  		},
  		
  		getInterface : function() {
  			return this;
  		}
  	});
  	
  	
  	LibraryInfo.prototype._loadLibraryMetadata = function(sLibraryName, fnCallback) {
  		sLibraryName = sLibraryName.replace(/\//g, ".");
  		
  		if (this._oLibInfos[sLibraryName]) {
  			jQuery.sap.delayedCall(0, window, fnCallback, [this._oLibInfos[sLibraryName]]);
  			return;
  		}
  		
  		var that = this, 
  		    sUrl, 
  		    sLibraryType,
  		    aParts = /themelib_(.*)/i.exec(sLibraryName);
  		if (!aParts) {
  			// UI library
  			sLibraryType = ".library";
  			sUrl = jQuery.sap.getModulePath(sLibraryName, '/');
  		} else {
  			// theme library
  			sLibraryType = ".theme";
  			sUrl = jQuery.sap.getModulePath("sap.ui.core", '/themes/' + aParts[1] + "/");	
  		}
  		
  		jQuery.ajax({
  			url : sUrl + sLibraryType,
  			dataType : "xml",
  			error : function(xhr, status, e) {
  				jQuery.sap.log.error("failed to load library details from '" + sUrl + sLibraryType + ": " + status + ", " + e);
  				that._oLibInfos[sLibraryName] = {name: sLibraryName, data: null, url: sUrl};
  				fnCallback(that._oLibInfos[sLibraryName]);
  			},
  			success : function(oData, sStatus, oXHR) {
  				that._oLibInfos[sLibraryName] = {name: sLibraryName, data: oData, url: sUrl};
  				fnCallback(that._oLibInfos[sLibraryName]);
  			}
  		});
  	};
  	
  	
  	LibraryInfo.prototype._getLibraryInfo = function(sLibraryName, fnCallback) {
  		this._loadLibraryMetadata(sLibraryName, function(oData){
  			var result = {libs: [], library: oData.name, libraryUrl: oData.url};
  	
  			if (oData.data) {
  				var $data = jQuery(oData.data);
  				result.vendor = $data.find("vendor").text();
  				result.copyright = $data.find("copyright").text();
  				result.version = $data.find("version").text();
  				result.documentation = $data.find("documentation").text();
  				result.releasenotes = $data.find("releasenotes").attr("url"); // in the appdata section
  				result.componentInfo = LibraryInfo.prototype._getLibraryComponentInfo($data);
  			}
  			
  			fnCallback(result);
  		});
  	};
  	
  	
  	LibraryInfo.prototype._getThirdPartyInfo = function(sLibraryName, fnCallback) {
  		this._loadLibraryMetadata(sLibraryName, function(oData){
  			var result = {libs: [], library: oData.name, libraryUrl: oData.url};
  	
  			if (oData.data) {
  				var $Libs = jQuery(oData.data).find("appData").find("thirdparty").children();
  				$Libs.each(function(i, o){
  					if (o.nodeName === "lib") {
  						var $Lib = jQuery(o);
  						var $license = $Lib.children("license");
  						result.libs.push({
  							displayName: $Lib.attr("displayName"),
  							homepage: $Lib.attr("homepage"),
  							license: {
  								url: $license.attr("url"),
  								type: $license.attr("type"),
  								file: oData.url + $license.attr("file")
  							}
  						});
  					}
  				});
  			}
  			
  			fnCallback(result);
  		});
  	};
  	
  	
  	LibraryInfo.prototype._getDocuIndex = function(sLibraryName, fnCallback) {
  		this._loadLibraryMetadata(sLibraryName, function(oData){
  			var lib = oData.name,
  				libUrl = oData.url,
  				result = {"docu": {}, library: lib, libraryUrl: libUrl};
  	
  			if (!oData.data) {
  				fnCallback(result);
  				return;
  			}
  				
  			var $Doc = jQuery(oData.data).find("appData").find("documentation");
  			var sUrl = $Doc.attr("indexUrl");
  			
  			if (!sUrl) {
  				fnCallback(result);
  				return;
  			}
  				
  			if ($Doc.attr("resolve") == "lib") {
  				sUrl = oData.url + sUrl;
  			}
  			
  			jQuery.ajax({
  				url : sUrl,
  				dataType : "json",
  				error : function(xhr, status, e) {
  					jQuery.sap.log.error("failed to load library docu from '" + sUrl + "': " + status + ", " + e);
  					fnCallback(result);
  				},
  				success : function(oData, sStatus, oXHR) {
  					oData.library = lib;
  					oData.libraryUrl = libUrl;
  					fnCallback(oData);
  				}
  			});
  		});
  	};
  	
  	LibraryInfo.prototype._getReleaseNotes = function(sLibraryName, sVersion, fnCallback) {
  		this._loadLibraryMetadata(sLibraryName, function(oData){
  	
  			if (!oData.data) {
  				fnCallback({});
  				return;
  			}
  			
  			var oVersion = jQuery.sap.Version(sVersion);
  			
  			var iMajor = oVersion.getMajor();
  			var iMinor = oVersion.getMinor();
  			var iPatch = oVersion.getPatch();
  			
  			var $Doc = jQuery(oData.data).find("appData").find("releasenotes");
  			var sUrl = $Doc.attr("url");
  			
  			if (!sUrl) {
  				jQuery.sap.log.warning("failed to load release notes for library " + sLibraryName );
  				fnCallback({});
  				return;
  			}
  			
  			// for SNAPSHOT versions we fallback to the next minor version, e.g.:
  			// 1.27.1-SNAPSHOT => 1.28.0
  			if (oVersion.getSuffix() === "-SNAPSHOT") {
  				if (iMinor % 2 != 0) {
  					iMinor = (iMinor + 1);
  					iPatch = 0;
  				}
  				sVersion = iMajor + "." + iMinor + "." + iPatch;
  			}
  			
  			// replace the placeholders for major, minor and patch
  			sUrl = sUrl.replace("{major}", iMajor);
  			sUrl = sUrl.replace("{minor}", iMinor);
  			sUrl = sUrl.replace("{patch}", iPatch);
  			
  			// if the URL should be resolved against the library the URL
  			// is relative to the library root path
  			if ($Doc.attr("resolve") == "lib") {
  				sUrl = oData.url + sUrl;
  			}
  			
  			// load the changelog/releasenotes
  			jQuery.ajax({
  				url : sUrl,
  				dataType : "json",
  				error : function(xhr, status, e) {
  					if (status === "parsererror") {
  						jQuery.sap.log.error("failed to parse release notes for library '" + sLibraryName + ", " + e);
  					} else {
  						jQuery.sap.log.warning("failed to load release notes for library '" + sLibraryName + ", " + e);
  					}
  					fnCallback({});
  				},
  				success : function(oData, sStatus, oXHR) {
  					// in case of a version is specified we return only the content
  					// of the specific version instead of the full data of the release notes file.
  					fnCallback(oData, sVersion);
  				}
  			});
  			
  		});
  	};
  
  	/**
  	*Collect components from .library file
  	*@param {object} oData xml formatted object of .library file
  	*@return {array.<Object>} library component info or empty string
  	*/
  
  	LibraryInfo.prototype._getLibraryComponentInfo = function(oData) {
  		var oAllLibComponents = {};
  		var aComponentModules = [];
  		var sDefaultComponent = "";
  
  		oData.find("ownership > component").each(function(index, oCurrentComponent) {
  			if (oCurrentComponent.childElementCount === 0) {
  				sDefaultComponent = oCurrentComponent.textContent;
  			} else {
  				var vCurrentComponentName = oCurrentComponent.getElementsByTagName("name");
  				if (vCurrentComponentName && vCurrentComponentName.length > 0) {
  					vCurrentComponentName = vCurrentComponentName[0].textContent;
  					var vCurrentModules = oCurrentComponent.getElementsByTagName("module");
  					if (vCurrentComponentName && vCurrentModules && vCurrentModules.length > 0) {
  						var sConcatenatedModules = "";
  						for (var i = 0; i < vCurrentModules.length; i++) {
  							var sModule = vCurrentModules[i].textContent.replace(/\//g, ".");
  							if (sModule) {
  								sConcatenatedModules = sConcatenatedModules + "," + sModule;
  							}
  						}
  
  						if (sConcatenatedModules) {
  							sConcatenatedModules = sConcatenatedModules.replace(/^,/, ''); // remove first comma
  							var oTemp = { "component" : vCurrentComponentName, "modules" : sConcatenatedModules };
  							aComponentModules.push(oTemp);
  						}
  					}
  				}
  			}
  		});
  
  		oAllLibComponents["defaultComponent"] = sDefaultComponent;
  		if (aComponentModules && aComponentModules.length > 0) {
  			oAllLibComponents["specialCases"] = aComponentModules;
  		}
  
  		return oAllLibComponents;
  	};
  
  	/**
  	*Return the control's component for Ownership app (TeamApp) & Explored app (Demokit)
  	*@param {array.<Object>} oComponentInfos object for each library with the default component and special cases
  	*@param {string} sModuleName control name, e.g. sap.m.Button
  	*@return {string} component
  	*/
  
  	LibraryInfo.prototype._getActualComponent = function(oComponentInfos, sModuleName) {
  		if (sModuleName) {
  			for (var key in oComponentInfos) {
  				if (key && sModuleName.indexOf(key) === 0) {
  					//check for special modules
  					var bSpecialModule = false;
  					var oSpecCases = oComponentInfos[key].specialCases;
  					var sSpecComponent = "";
  					var aSpecModules = [];
  
  					if (oSpecCases) {
  						for (var i = 0; i < oSpecCases.length; i++) {
  							aSpecModules = oSpecCases[i].modules.split(",");
  
  							for (var j = 0; j < aSpecModules.length; j++) {
  								if (sModuleName === aSpecModules[j]) {
  									sSpecComponent = oSpecCases[i].component;
  									bSpecialModule = true;
  									break;
  								}
  							}
  						}
  					}
  
  					if (bSpecialModule) {
  						return sSpecComponent;
  					} else {
  						return oComponentInfos[key].defaultComponent;
  					}
  				}
  			}
  		}
  	};
  
  	/**
  	*Return the default library's component for Version Info (Demokit)
  	*@param {array.<Object>} oLibraryInfo array with all library information, e.g componentInfo, releasenotes and etc
  	*@return {string} component
  	*/
  
  	LibraryInfo.prototype._getDefaultComponent = function(oLibraryInfo) {
  		return oLibraryInfo && oLibraryInfo.componentInfo && oLibraryInfo.componentInfo.defaultComponent;
  	};
  
  	return LibraryInfo;
  
  }, /* bExport= */ true);
  