(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else {
		var a = factory();
		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
	}
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// install a JSONP callback for chunk loading
/******/ 	var parentJsonpFunction = window["webpackJsonp"];
/******/ 	window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
/******/ 		// add "moreModules" to the modules object,
/******/ 		// then flag all "chunkIds" as loaded and fire callback
/******/ 		var moduleId, chunkId, i = 0, resolves = [], result;
/******/ 		for(;i < chunkIds.length; i++) {
/******/ 			chunkId = chunkIds[i];
/******/ 			if(installedChunks[chunkId]) {
/******/ 				resolves.push(installedChunks[chunkId][0]);
/******/ 			}
/******/ 			installedChunks[chunkId] = 0;
/******/ 		}
/******/ 		for(moduleId in moreModules) {
/******/ 			if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
/******/ 				modules[moduleId] = moreModules[moduleId];
/******/ 			}
/******/ 		}
/******/ 		if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);
/******/ 		while(resolves.length) {
/******/ 			resolves.shift()();
/******/ 		}
/******/
/******/ 	};
/******/
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// objects to store loaded and loading chunks
/******/ 	var installedChunks = {
/******/ 		10: 0
/******/ 	};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/ 	// This file contains only the entry chunk.
/******/ 	// The chunk loading function for additional chunks
/******/ 	__webpack_require__.e = function requireEnsure(chunkId) {
/******/ 		var installedChunkData = installedChunks[chunkId];
/******/ 		if(installedChunkData === 0) {
/******/ 			return new Promise(function(resolve) { resolve(); });
/******/ 		}
/******/
/******/ 		// a Promise means "currently loading".
/******/ 		if(installedChunkData) {
/******/ 			return installedChunkData[2];
/******/ 		}
/******/
/******/ 		// setup Promise in chunk cache
/******/ 		var promise = new Promise(function(resolve, reject) {
/******/ 			installedChunkData = installedChunks[chunkId] = [resolve, reject];
/******/ 		});
/******/ 		installedChunkData[2] = promise;
/******/
/******/ 		// start chunk loading
/******/ 		var head = document.getElementsByTagName('head')[0];
/******/ 		var script = document.createElement('script');
/******/ 		script.type = 'text/javascript';
/******/ 		script.charset = 'utf-8';
/******/ 		script.async = true;
/******/ 		script.timeout = 120000;
/******/
/******/ 		if (__webpack_require__.nc) {
/******/ 			script.setAttribute("nonce", __webpack_require__.nc);
/******/ 		}
/******/ 		script.src = __webpack_require__.p + "" + ({"2":"Tinebase/js/cytoscape"}[chunkId]||chunkId) + "-" + {"2":"96d3bbdf22caecc2e76b"}[chunkId] + "-FAT.js";
/******/ 		var timeout = setTimeout(onScriptComplete, 120000);
/******/ 		script.onerror = script.onload = onScriptComplete;
/******/ 		function onScriptComplete() {
/******/ 			// avoid mem leaks in IE.
/******/ 			script.onerror = script.onload = null;
/******/ 			clearTimeout(timeout);
/******/ 			var chunk = installedChunks[chunkId];
/******/ 			if(chunk !== 0) {
/******/ 				if(chunk) {
/******/ 					chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
/******/ 				}
/******/ 				installedChunks[chunkId] = undefined;
/******/ 			}
/******/ 		};
/******/ 		head.appendChild(script);
/******/
/******/ 		return promise;
/******/ 	};
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// on error function for async loading
/******/ 	__webpack_require__.oe = function(err) { console.error(err); throw err; };
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 247);
/******/ })
/************************************************************************/
/******/ ({

/***/ 0:
/***/ (function(module, exports) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function(useSourceMap) {
	var list = [];

	// return the list of modules as css string
	list.toString = function toString() {
		return this.map(function (item) {
			var content = cssWithMappingToString(item, useSourceMap);
			if(item[2]) {
				return "@media " + item[2] + "{" + content + "}";
			} else {
				return content;
			}
		}).join("");
	};

	// import a list of modules into the list
	list.i = function(modules, mediaQuery) {
		if(typeof modules === "string")
			modules = [[null, modules, ""]];
		var alreadyImportedModules = {};
		for(var i = 0; i < this.length; i++) {
			var id = this[i][0];
			if(typeof id === "number")
				alreadyImportedModules[id] = true;
		}
		for(i = 0; i < modules.length; i++) {
			var item = modules[i];
			// skip already imported module
			// this implementation is not 100% perfect for weird media query combinations
			//  when a module is imported multiple times with different media queries.
			//  I hope this will never occur (Hey this way we have smaller bundles)
			if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
				if(mediaQuery && !item[2]) {
					item[2] = mediaQuery;
				} else if(mediaQuery) {
					item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
				}
				list.push(item);
			}
		}
	};
	return list;
};

function cssWithMappingToString(item, useSourceMap) {
	var content = item[1] || '';
	var cssMapping = item[3];
	if (!cssMapping) {
		return content;
	}

	if (useSourceMap && typeof btoa === 'function') {
		var sourceMapping = toComment(cssMapping);
		var sourceURLs = cssMapping.sources.map(function (source) {
			return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'
		});

		return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
	}

	return [content].join('\n');
}

// Adapted from convert-source-map (MIT)
function toComment(sourceMap) {
	// eslint-disable-next-line no-undef
	var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
	var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;

	return '/*# ' + data + ' */';
}


/***/ }),

/***/ 1:
/***/ (function(module, exports, __webpack_require__) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

var stylesInDom = {};

var	memoize = function (fn) {
	var memo;

	return function () {
		if (typeof memo === "undefined") memo = fn.apply(this, arguments);
		return memo;
	};
};

var isOldIE = memoize(function () {
	// Test for IE <= 9 as proposed by Browserhacks
	// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
	// Tests for existence of standard globals is to allow style-loader
	// to operate correctly into non-standard environments
	// @see https://github.com/webpack-contrib/style-loader/issues/177
	return window && document && document.all && !window.atob;
});

var getElement = (function (fn) {
	var memo = {};

	return function(selector) {
		if (typeof memo[selector] === "undefined") {
			var styleTarget = fn.call(this, selector);
			// Special case to return head of iframe instead of iframe itself
			if (styleTarget instanceof window.HTMLIFrameElement) {
				try {
					// This will throw an exception if access to iframe is blocked
					// due to cross-origin restrictions
					styleTarget = styleTarget.contentDocument.head;
				} catch(e) {
					styleTarget = null;
				}
			}
			memo[selector] = styleTarget;
		}
		return memo[selector]
	};
})(function (target) {
	return document.querySelector(target)
});

var singleton = null;
var	singletonCounter = 0;
var	stylesInsertedAtTop = [];

var	fixUrls = __webpack_require__(2);

module.exports = function(list, options) {
	if (typeof DEBUG !== "undefined" && DEBUG) {
		if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
	}

	options = options || {};

	options.attrs = typeof options.attrs === "object" ? options.attrs : {};

	// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
	// tags it will allow on a page
	if (!options.singleton) options.singleton = isOldIE();

	// By default, add <style> tags to the <head> element
	if (!options.insertInto) options.insertInto = "head";

	// By default, add <style> tags to the bottom of the target
	if (!options.insertAt) options.insertAt = "bottom";

	var styles = listToStyles(list, options);

	addStylesToDom(styles, options);

	return function update (newList) {
		var mayRemove = [];

		for (var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];

			domStyle.refs--;
			mayRemove.push(domStyle);
		}

		if(newList) {
			var newStyles = listToStyles(newList, options);
			addStylesToDom(newStyles, options);
		}

		for (var i = 0; i < mayRemove.length; i++) {
			var domStyle = mayRemove[i];

			if(domStyle.refs === 0) {
				for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();

				delete stylesInDom[domStyle.id];
			}
		}
	};
};

function addStylesToDom (styles, options) {
	for (var i = 0; i < styles.length; i++) {
		var item = styles[i];
		var domStyle = stylesInDom[item.id];

		if(domStyle) {
			domStyle.refs++;

			for(var j = 0; j < domStyle.parts.length; j++) {
				domStyle.parts[j](item.parts[j]);
			}

			for(; j < item.parts.length; j++) {
				domStyle.parts.push(addStyle(item.parts[j], options));
			}
		} else {
			var parts = [];

			for(var j = 0; j < item.parts.length; j++) {
				parts.push(addStyle(item.parts[j], options));
			}

			stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
		}
	}
}

function listToStyles (list, options) {
	var styles = [];
	var newStyles = {};

	for (var i = 0; i < list.length; i++) {
		var item = list[i];
		var id = options.base ? item[0] + options.base : item[0];
		var css = item[1];
		var media = item[2];
		var sourceMap = item[3];
		var part = {css: css, media: media, sourceMap: sourceMap};

		if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});
		else newStyles[id].parts.push(part);
	}

	return styles;
}

function insertStyleElement (options, style) {
	var target = getElement(options.insertInto)

	if (!target) {
		throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");
	}

	var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];

	if (options.insertAt === "top") {
		if (!lastStyleElementInsertedAtTop) {
			target.insertBefore(style, target.firstChild);
		} else if (lastStyleElementInsertedAtTop.nextSibling) {
			target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);
		} else {
			target.appendChild(style);
		}
		stylesInsertedAtTop.push(style);
	} else if (options.insertAt === "bottom") {
		target.appendChild(style);
	} else if (typeof options.insertAt === "object" && options.insertAt.before) {
		var nextSibling = getElement(options.insertInto + " " + options.insertAt.before);
		target.insertBefore(style, nextSibling);
	} else {
		throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");
	}
}

function removeStyleElement (style) {
	if (style.parentNode === null) return false;
	style.parentNode.removeChild(style);

	var idx = stylesInsertedAtTop.indexOf(style);
	if(idx >= 0) {
		stylesInsertedAtTop.splice(idx, 1);
	}
}

function createStyleElement (options) {
	var style = document.createElement("style");

	options.attrs.type = "text/css";

	addAttrs(style, options.attrs);
	insertStyleElement(options, style);

	return style;
}

function createLinkElement (options) {
	var link = document.createElement("link");

	options.attrs.type = "text/css";
	options.attrs.rel = "stylesheet";

	addAttrs(link, options.attrs);
	insertStyleElement(options, link);

	return link;
}

function addAttrs (el, attrs) {
	Object.keys(attrs).forEach(function (key) {
		el.setAttribute(key, attrs[key]);
	});
}

function addStyle (obj, options) {
	var style, update, remove, result;

	// If a transform function was defined, run it on the css
	if (options.transform && obj.css) {
	    result = options.transform(obj.css);

	    if (result) {
	    	// If transform returns a value, use that instead of the original css.
	    	// This allows running runtime transformations on the css.
	    	obj.css = result;
	    } else {
	    	// If the transform function returns a falsy value, don't add this css.
	    	// This allows conditional loading of css
	    	return function() {
	    		// noop
	    	};
	    }
	}

	if (options.singleton) {
		var styleIndex = singletonCounter++;

		style = singleton || (singleton = createStyleElement(options));

		update = applyToSingletonTag.bind(null, style, styleIndex, false);
		remove = applyToSingletonTag.bind(null, style, styleIndex, true);

	} else if (
		obj.sourceMap &&
		typeof URL === "function" &&
		typeof URL.createObjectURL === "function" &&
		typeof URL.revokeObjectURL === "function" &&
		typeof Blob === "function" &&
		typeof btoa === "function"
	) {
		style = createLinkElement(options);
		update = updateLink.bind(null, style, options);
		remove = function () {
			removeStyleElement(style);

			if(style.href) URL.revokeObjectURL(style.href);
		};
	} else {
		style = createStyleElement(options);
		update = applyToTag.bind(null, style);
		remove = function () {
			removeStyleElement(style);
		};
	}

	update(obj);

	return function updateStyle (newObj) {
		if (newObj) {
			if (
				newObj.css === obj.css &&
				newObj.media === obj.media &&
				newObj.sourceMap === obj.sourceMap
			) {
				return;
			}

			update(obj = newObj);
		} else {
			remove();
		}
	};
}

var replaceText = (function () {
	var textStore = [];

	return function (index, replacement) {
		textStore[index] = replacement;

		return textStore.filter(Boolean).join('\n');
	};
})();

function applyToSingletonTag (style, index, remove, obj) {
	var css = remove ? "" : obj.css;

	if (style.styleSheet) {
		style.styleSheet.cssText = replaceText(index, css);
	} else {
		var cssNode = document.createTextNode(css);
		var childNodes = style.childNodes;

		if (childNodes[index]) style.removeChild(childNodes[index]);

		if (childNodes.length) {
			style.insertBefore(cssNode, childNodes[index]);
		} else {
			style.appendChild(cssNode);
		}
	}
}

function applyToTag (style, obj) {
	var css = obj.css;
	var media = obj.media;

	if(media) {
		style.setAttribute("media", media)
	}

	if(style.styleSheet) {
		style.styleSheet.cssText = css;
	} else {
		while(style.firstChild) {
			style.removeChild(style.firstChild);
		}

		style.appendChild(document.createTextNode(css));
	}
}

function updateLink (link, options, obj) {
	var css = obj.css;
	var sourceMap = obj.sourceMap;

	/*
		If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled
		and there is no publicPath defined then lets turn convertToAbsoluteUrls
		on by default.  Otherwise default to the convertToAbsoluteUrls option
		directly
	*/
	var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;

	if (options.convertToAbsoluteUrls || autoFixUrls) {
		css = fixUrls(css);
	}

	if (sourceMap) {
		// http://stackoverflow.com/a/26603875
		css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
	}

	var blob = new Blob([css], { type: "text/css" });

	var oldSrc = link.href;

	link.href = URL.createObjectURL(blob);

	if(oldSrc) URL.revokeObjectURL(oldSrc);
}


/***/ }),

/***/ 2:
/***/ (function(module, exports) {


/**
 * When source maps are enabled, `style-loader` uses a link element with a data-uri to
 * embed the css on the page. This breaks all relative urls because now they are relative to a
 * bundle instead of the current page.
 *
 * One solution is to only use full urls, but that may be impossible.
 *
 * Instead, this function "fixes" the relative urls to be absolute according to the current page location.
 *
 * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.
 *
 */

module.exports = function (css) {
  // get current location
  var location = typeof window !== "undefined" && window.location;

  if (!location) {
    throw new Error("fixUrls requires window.location");
  }

	// blank or null?
	if (!css || typeof css !== "string") {
	  return css;
  }

  var baseUrl = location.protocol + "//" + location.host;
  var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/");

	// convert each url(...)
	/*
	This regular expression is just a way to recursively match brackets within
	a string.

	 /url\s*\(  = Match on the word "url" with any whitespace after it and then a parens
	   (  = Start a capturing group
	     (?:  = Start a non-capturing group
	         [^)(]  = Match anything that isn't a parentheses
	         |  = OR
	         \(  = Match a start parentheses
	             (?:  = Start another non-capturing groups
	                 [^)(]+  = Match anything that isn't a parentheses
	                 |  = OR
	                 \(  = Match a start parentheses
	                     [^)(]*  = Match anything that isn't a parentheses
	                 \)  = Match a end parentheses
	             )  = End Group
              *\) = Match anything and then a close parens
          )  = Close non-capturing group
          *  = Match anything
       )  = Close capturing group
	 \)  = Match a close parens

	 /gi  = Get all matches, not the first.  Be case insensitive.
	 */
	var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) {
		// strip quotes (if they exist)
		var unquotedOrigUrl = origUrl
			.trim()
			.replace(/^"(.*)"$/, function(o, $1){ return $1; })
			.replace(/^'(.*)'$/, function(o, $1){ return $1; });

		// already a full url? no change
		if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/)/i.test(unquotedOrigUrl)) {
		  return fullMatch;
		}

		// convert the url to a full url
		var newUrl;

		if (unquotedOrigUrl.indexOf("//") === 0) {
		  	//TODO: should we add protocol?
			newUrl = unquotedOrigUrl;
		} else if (unquotedOrigUrl.indexOf("/") === 0) {
			// path should be relative to the base url
			newUrl = baseUrl + unquotedOrigUrl; // already starts with '/'
		} else {
			// path should be relative to current directory
			newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './'
		}

		// send back the fixed url(...)
		return "url(" + JSON.stringify(newUrl) + ")";
	});

	// send back the fixed css
	return fixedCss;
};


/***/ }),

/***/ 247:
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(248);
__webpack_require__(249);
__webpack_require__(250);
__webpack_require__(251);
__webpack_require__(252);
__webpack_require__(253);
__webpack_require__(254);
__webpack_require__(256);
__webpack_require__(257);
__webpack_require__(258);
__webpack_require__(259);
__webpack_require__(260);
__webpack_require__(261);
__webpack_require__(82);
__webpack_require__(262);
__webpack_require__(263);
__webpack_require__(264);
__webpack_require__(265);
__webpack_require__(266);
__webpack_require__(267);
__webpack_require__(268);
__webpack_require__(269);
__webpack_require__(270);
__webpack_require__(271);
__webpack_require__(83);
__webpack_require__(272);
__webpack_require__(273);
__webpack_require__(274);
__webpack_require__(275);
__webpack_require__(276);
__webpack_require__(277);
__webpack_require__(278);
__webpack_require__(288);
__webpack_require__(293);
__webpack_require__(296);
__webpack_require__(298);


/***/ }),

/***/ 248:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2010-2017 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * TODO         add 'one of / in' operator?
 */
Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListMemberFilterModel
 * @extends     Tine.widgets.grid.FilterModel
 * 
 * @author      Philipp Schüle <p.schuele@metaways.de>
 */
Tine.Addressbook.ListMemberFilterModel = Ext.extend(Tine.widgets.grid.FilterModel, {
    /**
     * @property Tine.Tinebase.Application app
     */
    app: null,
    
    field: 'list',
    defaultOperator: 'equals',

    /**
     * @private
     */
    initComponent: function() {
        Tine.Addressbook.ListMemberFilterModel.superclass.initComponent.call(this);
        
        this.app = Tine.Tinebase.appMgr.get('Addressbook');
        
        this.operators = ['equals'];
        this.label = this.app.i18n._('Member of List');
    },
    
    /**
     * value renderer
     * 
     * @param {Ext.data.Record} filter line
     * @param {Ext.Element} element to render to 
     */
    valueRenderer: function(filter, el) {
        var value = new Tine.Tinebase.widgets.form.RecordPickerComboBox({
            blurOnSelect: true,
            recordClass: this.field == 'list' ? Tine.Addressbook.Model.List : Tine.Addressbook.Model.Contact,
            filter: filter,
            width: this.filterValueWidth,
            id: 'tw-ftb-frow-valuefield-' + filter.id,
            value: filter.data.value ? filter.data.value : this.defaultValue,
            renderTo: el
        });
        value.on('select', this.onFiltertrigger, this);
        return value;
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['addressbook.listMember'] = Tine.Addressbook.ListMemberFilterModel;


/***/ }),

/***/ 249:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * TODO         add 'one of / in' operator?
 */
Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListRoleMemberFilterModel
 * @extends     Tine.widgets.grid.FilterModel
 * 
 * @author      Philipp Schüle <p.schuele@metaways.de>
 */
Tine.Addressbook.ListRoleMemberFilterModel = Ext.extend(Tine.widgets.grid.FilterModel, {
    /**
     * @property Tine.Tinebase.Application app
     */
    app: null,
    
    field: 'list_role_id',
    defaultOperator: 'equals',
    
    /**
     * @private
     */
    initComponent: function() {
        Tine.Addressbook.ListRoleMemberFilterModel.superclass.initComponent.call(this);
        
        this.app = Tine.Tinebase.appMgr.get('Addressbook');
        
        this.operators = ['equals'];
        this.label = this.app.i18n._('List Function');
    },
    
    /**
     * value renderer
     * 
     * @param {Ext.data.Record} filter line
     * @param {Ext.Element} element to render to 
     */
    valueRenderer: function(filter, el) {
        var value = new Tine.Tinebase.widgets.form.RecordPickerComboBox({
            blurOnSelect: true,
            recordClass: Tine.Addressbook.Model.ListRole,
            filter: filter,
            width: this.filterValueWidth,
            id: 'tw-ftb-frow-valuefield-' + filter.id,
            value: filter.data.value ? filter.data.value : this.defaultValue,
            renderTo: el
        });
        value.on('select', this.onFiltertrigger, this);
        return value;
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['addressbook.listRoleMember'] = Tine.Addressbook.ListRoleMemberFilterModel;


/***/ }),

/***/ 250:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2007-2011 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
/*global Ext, Tine*/
 
Ext.ns('Tine.Addressbook.Model');

// TODO: move this into model definition and replace uscases (?) with getter fn
Tine.Addressbook.Model.ContactArray = Tine.Tinebase.Model.genericFields.concat([
    {name: 'id', omitDuplicateResolving: true},
    {name: 'tid', omitDuplicateResolving: true},
    {name: 'private', omitDuplicateResolving: true},
    {name: 'cat_id', omitDuplicateResolving: true},
    {name: 'n_family', label: 'Last Name', group: 'Name' },//_('Last Name') _('Name')
    {name: 'n_given', label: 'First Name', group: 'Name' }, //_('First Name')
    {name: 'n_middle', label: 'Middle Name', group: 'Name' }, //_('Middle Name')
    {name: 'n_prefix', label: 'Title', group: 'Name' }, //_('Title')
    {name: 'n_suffix', label: 'Suffix', group: 'Name'}, //_('Suffix')
    {name: 'n_fn', label: 'Display Name', group: 'Name', omitDuplicateResolving: true }, //_('Display Name')
    {name: 'n_fileas', group: 'Name', omitDuplicateResolving: true },
    {name: 'bday', label: 'Birthday', type: 'date', dateFormat: Date.patterns.ISO8601Long }, //_('Birthday')
    {name: 'org_name', label: 'Company', group: 'Company' }, //_('Company')
    {name: 'org_unit', label: 'Unit', group: 'Company' }, //_('Unit')
    {name: 'salutation', label: 'Salutation', group: 'Name' }, //_('Salutation')
    {name: 'title', label: 'Job Title', group: 'Company' }, //_('Job Title')
    {name: 'role', label: 'Job Role', group: 'Company' }, //_('Job Role')
    {name: 'assistent', group: 'Company', omitDuplicateResolving: true},
    {name: 'room', label: 'Room', group: 'Company' }, //_('Room')
    {name: 'adr_one_street', label: 'Street (Company Address)', group: 'Company Address' }, //_('Street (Company Address)')  _('Company Address')
    {name: 'adr_one_street2', label: 'Street 2 (Company Address)', group: 'Company Address' }, //_('Street 2 (Company Address)')
    {name: 'adr_one_locality', label: 'City (Company Address)', group: 'Company Address' }, //_('City (Company Address)')
    {name: 'adr_one_region', label: 'Region (Company Address)', group: 'Company Address' }, //_('Region (Company Address)')
    {name: 'adr_one_postalcode', label: 'Postal Code (Company Address)', group: 'Company Address' }, //_('Postal Code (Company Address)')
    {name: 'adr_one_countryname', label: 'Country (Company Address)', group: 'Company Address' }, //_('Country (Company Address)')
    {name: 'adr_one_lon', label: 'Longitude (Company Address)', group: 'Company Address', omitDuplicateResolving: true }, //_('Longitude (Company Address)')
    {name: 'adr_one_lat', label: 'Latitude (Company Address)', group: 'Company Address', omitDuplicateResolving: true }, //_('Latitude (Company Address)')
    {name: 'label', omitDuplicateResolving: true},
    {name: 'adr_two_street', label: 'Street (Private Address)', group: 'Private Address' }, //_('Street (Private Address)')  _('Private Address')
    {name: 'adr_two_street2', label: 'Street 2 (Private Address)', group: 'Private Address' }, //_('Street 2 (Private Address)')
    {name: 'adr_two_locality', label: 'City (Private Address)', group: 'Private Address' }, //_('City (Private Address)')
    {name: 'adr_two_region', label: 'Region (Private Address)', group: 'Private Address' }, //_('Region (Private Address)')
    {name: 'adr_two_postalcode', label: 'Postal Code (Private Address)', group: 'Private Address' }, //_('Postal Code (Private Address)')
    {name: 'adr_two_countryname', label: 'Country (Private Address)', group: 'Private Address' }, //_('Country (Private Address)')
    {name: 'adr_two_lon', group: 'Private Address', omitDuplicateResolving: true},
    {name: 'adr_two_lat', group: 'Private Address', omitDuplicateResolving: true},
    {name: 'preferred_address', group: 'Preferred Address', omitDuplicateResolving: true}, //_('Preferred Address')
    {name: 'tel_work', label: 'Phone', group: 'Company Communication' }, //_('Phone') _('Company Communication')
    {name: 'tel_cell', label: 'Mobile', group: 'Company Communication' }, //_('Mobile')
    {name: 'tel_fax', label: 'Fax', group: 'Company Communication' }, //_('Fax')
    {name: 'tel_assistent', group: 'contact_infos', omitDuplicateResolving: true },
    {name: 'tel_car', group: 'contact_infos', omitDuplicateResolving: true },
    {name: 'tel_pager', group: 'contact_infos', omitDuplicateResolving: true },
    {name: 'tel_home', label: 'Phone (private)', group: 'Private Communication' }, //_('Phone (private)') _('Private Communication')
    {name: 'tel_fax_home', label: 'Fax (private)', group: 'Private Communication' }, //_('Fax (private)')
    {name: 'tel_cell_private', label: 'Mobile (private)', group: 'Private Communication' }, //_('Mobile (private)')
    {name: 'tel_other', group: 'contact_infos', omitDuplicateResolving: true },
    {name: 'tel_prefer', group: 'contact_infos', omitDuplicateResolving: true},
    {name: 'email', label: 'E-Mail', group: 'Company Communication' }, //_('E-Mail')
    {name: 'email_home', label: 'E-Mail (private)', group: 'Private Communication' }, //_('E-Mail (private)')
    {name: 'url', label: 'Web', group: 'Company Communication' }, //_('Web')
    {name: 'url_home', label: 'Web (private)', group: 'Private Communication' }, //_('Web (private)')
    {name: 'freebusy_uri', omitDuplicateResolving: true},
    {name: 'calendar_uri', omitDuplicateResolving: true},
    {name: 'note', label: 'Description' }, //_('Description')
    {name: 'tz', omitDuplicateResolving: true},
    {name: 'pubkey', omitDuplicateResolving: true},
    {name: 'jpegphoto', omitDuplicateResolving: true},
    {name: 'account_id', omitDuplicateResolving: true},
    {name: 'tags'},
    {name: 'notes', omitDuplicateResolving: true},
    {name: 'relations', omitDuplicateResolving: true},
    {name: 'customfields', omitDuplicateResolving: true},
    {name: 'attachments', omitDuplicateResolving: true},
    {name: 'paths', omitDuplicateResolving: true},
    {name: 'type', omitDuplicateResolving: true},
    {name: 'memberroles', omitDuplicateResolving: true},
    {name: 'industry', omitDuplicateResolving: true},
    {name: 'groups', label: 'Groups'} //_('Groups')
]);

/**
 * @namespace   Tine.Addressbook.Model
 * @class       Tine.Addressbook.Model.Contact
 * @extends     Tine.Tinebase.data.Record
 * @constructor
 * Model of a contact<br>
 * 
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 */
Tine.Addressbook.Model.Contact = Tine.Tinebase.data.Record.create(Tine.Addressbook.Model.ContactArray, {
    appName: 'Addressbook',
    modelName: 'Contact',
    idProperty: 'id',
    titleProperty: 'n_fn',
    // ngettext('Contact', 'Contacts', n); gettext('Contacts');
    recordName: 'Contact',
    recordsName: 'Contacts',
    containerProperty: 'container_id',
    // ngettext('Addressbook', 'Addressbooks', n); gettext('Addressbooks');
    containerName: 'Addressbook',
    containersName: 'Addressbooks',
    copyOmitFields: ['account_id', 'type'],
    
    /**
     * returns true if record has an email address
     * @return {Boolean}
     */
    hasEmail: function() {
        return this.get('email') || this.get('email_home');
    },
    
    /**
     * returns true preferred email if available
     * @return {String}
     */
    getPreferredEmail: function(preferred) {
        var preferred = preferred || 'email',
            other = preferred == 'email' ? 'email_home' : 'email';
            
        return (this.get(preferred) || this.get(other));
    },

    getTitle: function() {
        var result = this.get('n_fn');

        var tinebaseApp = new Tine.Tinebase.Application({
            appName: 'Tinebase'
        });
        if (tinebaseApp.featureEnabled('featureShowAccountEmail')) {
            var email = this.getPreferredEmail();
            if (email) {
                result += ' (' + email + ')';
            }
        }

        return result;
    }
});

/**
 * get filtermodel of contact model
 * 
 * @namespace Tine.Addressbook.Model
 * @static
 * @return {Array} filterModel definition
 */ 
Tine.Addressbook.Model.Contact.getFilterModel = function() {
    var app = Tine.Tinebase.appMgr.get('Addressbook');
    
    var typeStore = [['contact', app.i18n._('Contact')], ['user', app.i18n._('User Account')]];
    
    var filters = [
        {label: i18n._('Quick Search'),                                                      field: 'query',              operators: ['contains']},
        {filtertype: 'tine.widget.container.filtermodel', app: app, recordClass: Tine.Addressbook.Model.Contact},
        {filtertype: 'addressbook.listMember', app: app},
        {filtertype: 'addressbook.listRoleMember', app: app},
        {label: app.i18n._('Title'),                                                    field: 'n_prefix' },
        {label: app.i18n._('First Name'),                                               field: 'n_given' },
        {label: app.i18n._('Last Name'),                                                field: 'n_family'},
        {label: app.i18n._('Middle Name'),                                              field: 'n_middle'},
        {label: app.i18n._('Company'),                                                  field: 'org_name'},
        {label: app.i18n._('Unit'),                                                     field: 'org_unit'},
        {label: app.i18n._('Phone'),                                                    field: 'telephone',          operators: ['contains']},
        {label: app.i18n._('Job Title'),                                                field: 'title'},
        {label: app.i18n._('Description'),                                              field: 'note', valueType: 'fulltext'},
        {label: app.i18n._('E-Mail'),                                                   field: 'email_query',        operators: ['contains']},
        {filtertype: 'tinebase.tag', app: app},
//        {label: app.i18n._('Job Role'),                                                 field: 'role'},
//        {label: app.i18n._('Birthday'),    field: 'bday', valueType: 'date'},
        {label: app.i18n._('Street') + ' (' + app.i18n._('Company Address') + ')',      field: 'adr_one_street',     defaultOperator: 'equals'},
        {label: app.i18n._('Region') + ' (' + app.i18n._('Company Address') + ')',      field: 'adr_one_region',     defaultOperator: 'equals'},
        {label: app.i18n._('Postal Code') + ' (' + app.i18n._('Company Address') + ')', field: 'adr_one_postalcode', defaultOperator: 'equals'},
        {label: app.i18n._('City') + '  (' + app.i18n._('Company Address') + ')',       field: 'adr_one_locality'},
        {label: app.i18n._('Country') + '  (' + app.i18n._('Company Address') + ')',    field: 'adr_one_countryname', valueType: 'country'},
        {label: app.i18n._('Street') + ' (' + app.i18n._('Private Address') + ')',      field: 'adr_two_street',     defaultOperator: 'equals'},
        {label: app.i18n._('Region') + ' (' + app.i18n._('Private Address') + ')',      field: 'adr_two_region',     defaultOperator: 'equals'},
        {label: app.i18n._('Postal Code') + ' (' + app.i18n._('Private Address') + ')', field: 'adr_two_postalcode', defaultOperator: 'equals'},
        {label: app.i18n._('City') + ' (' + app.i18n._('Private Address') + ')',        field: 'adr_two_locality'},
        {label: app.i18n._('Country') + '  (' + app.i18n._('Private Address') + ')',    field: 'adr_two_countryname', valueType: 'country'},
        {label: app.i18n._('Type'), defaultValue: 'contact', valueType: 'combo',        field: 'type',               store: typeStore},
        {label: i18n._('Last Modified Time'),                                                field: 'last_modified_time', valueType: 'date'},
        {label: i18n._('Last Modified By'),                                                  field: 'last_modified_by',   valueType: 'user'},
        {label: i18n._('Creation Time'),                                                     field: 'creation_time',      valueType: 'date'},
        {label: i18n._('Created By'),                                                        field: 'created_by',         valueType: 'user'},
        {
            label: app.i18n._('Salutation'),
            field: 'salutation',
            filtertype: 'tine.widget.keyfield.filter',
            app: app,
            keyfieldName: 'contactSalutation',
            defaultOperator: 'in'
        }
    ];
    
    if (Tine.Tinebase.appMgr.get('Addressbook').featureEnabled('featureIndustry')) {
        filters.push({filtertype: 'foreignrecord', 
            app: app,
            foreignRecordClass: Tine.Addressbook.Model.Industry,
            ownField: 'industry'
        });
    }
    return filters;
};

/**
 * default timesheets backend
 */
Tine.Addressbook.contactBackend = new Tine.Tinebase.data.RecordProxy({
    appName: 'Addressbook',
    modelName: 'Contact',
    recordClass: Tine.Addressbook.Model.Contact
});

/**
 * list model
 */
Tine.Addressbook.Model.List = Tine.Tinebase.data.Record.create([
    {name: 'id'},
    {name: 'container_id'},
    {name: 'created_by'},
    {name: 'creation_time'},
    {name: 'seq'},
    {name: 'last_modified_by'},
    {name: 'last_modified_time'},
    {name: 'is_deleted'},
    {name: 'deleted_time'},
    {name: 'deleted_by'},
    {name: 'name'},
    {name: 'description'},
    {name: 'members'},
    {name: 'memberroles'},
    {name: 'email'},
    {name: 'type'},
    {name: 'list_type'},
    {name: 'group_id'},
    {name: 'emails'},
    {name: 'notes', omitDuplicateResolving: true},
    {name: 'paths', omitDuplicateResolving: true},
    {name: 'relations', omitDuplicateResolving: true},
    {name: 'customfields', omitDuplicateResolving: true},
    {name: 'tags'}
], {
    appName: 'Addressbook',
    modelName: 'List',
    idProperty: 'id',
    titleProperty: 'name',
    // ngettext('List', 'Lists', n); gettext('Lists');
    recordName: 'List',
    recordsName: 'Lists',
    containerProperty: 'container_id',
    // ngettext('Addressbook', 'Addressbooks', n); gettext('Addressbooks');
    containerName: 'Addressbook',
    containersName: 'Addressbooks',
    copyOmitFields: ['group_id']
});

Tine.Addressbook.Model.List.getFilterModel = function() {
    
    var app = Tine.Tinebase.appMgr.get('Addressbook');
    
    var typeStore = [['list', app.i18n._('List')], ['user', app.i18n._('User Account')]];
    
    return [
        {label: i18n._('Quick Search'),                                                      field: 'query',              operators: ['contains']},
        {filtertype: 'tine.widget.container.filtermodel', app: app, recordClass: Tine.Addressbook.Model.Contact},
        {filtertype: 'addressbook.listMember', app: app, field: 'contact'},
        {label: app.i18n._('Name'),                                               field: 'name' },
        {label: app.i18n._('Description'),                                                field: 'description',           valueType: 'fulltext'},
        {label: i18n._('Last Modified Time'),                                                field: 'last_modified_time', valueType: 'date'},
        {label: i18n._('Last Modified By'),                                                  field: 'last_modified_by',   valueType: 'user'},
        {label: i18n._('Creation Time'),                                                     field: 'creation_time',      valueType: 'date'},
        {label: i18n._('Created By'),                                                        field: 'created_by',         valueType: 'user'},
        {filtertype: 'tinebase.tag', app: app}
    ];
};

/**
 * default list backend
 */
Tine.Addressbook.listBackend = new Tine.Tinebase.data.RecordProxy({
    appName: 'Addressbook',
    modelName: 'List',
    recordClass: Tine.Addressbook.Model.List
});

/**
 * email address model
 */
Tine.Addressbook.Model.EmailAddress = Tine.Tinebase.data.Record.create([
   {name: 'n_fileas'},
   {name: 'emails'},
   {name: 'email'},
   {name: 'email_home'}
], {
    appName: 'Addressbook',
    modelName: 'EmailAddress',
    titleProperty: 'name',
    // ngettext('Email Address', 'Email Addresses', n); gettext('Email Addresses');
    recordName: 'Email Address',
    recordsName: 'Email Addresses',
    containerProperty: 'container_id',
    // ngettext('Addressbook', 'Addressbooks', n); gettext('Addressbooks');
    containerName: 'Addressbook',
    containersName: 'Addressbooks',
    copyOmitFields: ['group_id'],

    getPreferredEmail: function(preferred) {
        var emails = this.get("emails");
        if (! this.get("email") && ! this.get("email_home")) {
            return this.get("emails");
        } else {
            var preferred = preferred || 'email',
            other = preferred == 'email' ? 'email_home' : 'email';
            return (this.get(preferred) || this.get(other));
        }
    }
});


/**
 * get filtermodel of emailaddress model
 * 
 * @namespace Tine.Addressbook.Model
 * @static
 * @return {Array} filterModel definition
 */ 
Tine.Addressbook.Model.EmailAddress.getFilterModel = function() {
    return [
        {label: i18n._('Quick search'),       field: 'query',              operators: ['contains']}
    ];
};

/**
 * ListRole model
 */
Tine.Addressbook.Model.ListRole = Tine.Tinebase.data.Record.create([
    {name: 'id'},
    {name: 'name'},
    {name: 'members'},
    {name: 'description'}
], {
    appName: 'Addressbook',
    modelName: 'ListRole',
    titleProperty: 'name',
    // ngettext('List Function', 'List Functions', n); gettext('List Functions');
    recordName: 'List Function',
    recordsName: 'List Functions'
});

/**
 * get filtermodel of ListRole model
 *
 * @namespace Tine.Addressbook.Model
 * @static
 * @return {Array} filterModel definition
 */
Tine.Addressbook.Model.ListRole.getFilterModel = function() {
    return [
        {label: i18n._('Quick search'),       field: 'query',              operators: ['contains']}
    ];
};

/**

/**
 * Industry model
 */
Tine.Addressbook.Model.Industry = Tine.Tinebase.data.Record.create([
    {name: 'id'},
    {name: 'name'},
    {name: 'description'}
], {
    appName: 'Addressbook',
    modelName: 'Industry',
    titleProperty: 'name',
    // ngettext('Industry', 'Industries', n); gettext('Industries');
    recordName: 'Industry',
    recordsName: 'Industries'
});

/**
 * get filtermodel of Industry model
 *
 * @namespace Tine.Addressbook.Model
 * @static
 * @return {Array} filterModel definition
 */
Tine.Addressbook.Model.Industry.getFilterModel = function() {
    return [
        {label: i18n._('Quick search'),       field: 'query',              operators: ['contains']}
    ];
};

/**
 * Structure (fake) model
 */
Tine.Addressbook.Model.Structure = Tine.Tinebase.data.Record.create([
    {name: 'id'},
    {name: 'name'},
    {name: 'description'}
], {
    appName: 'Addressbook',
    modelName: 'Structure',
    titleProperty: 'name',
    // ngettext('Structure', 'Structures', n); gettext('Structures');
    recordName: 'Structure',
    recordsName: 'Structures'
});


/***/ }),

/***/ 251:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 *
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Stefanie Stamer <s.stamer@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 */

/*global Ext, Tine*/

Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListRoleEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * Addressbook Edit Dialog <br>
 *
 * @author      Philipp Schüle <p.schuele@metaways.de>
 */
Tine.Addressbook.IndustryEditDialog = Ext.extend(Tine.widgets.dialog.SimpleRecordEditDialog, {
    windowNamePrefix: 'IndustryEditWindow_',
    appName: 'Addressbook',
    recordClass: Tine.Addressbook.Model.Industry
});

/**
 * Opens a new contact edit dialog window
 *
 * @return {Ext.ux.Window}
 */
Tine.Addressbook.IndustryEditDialog.openWindow = function (config) {
    var id = (config.record && config.record.id) ? config.record.id : 0;
    var window = Tine.WindowFactory.getWindow({
        width: 400,
        height: 300,
        name: Tine.Addressbook.IndustryEditDialog.prototype.windowNamePrefix + id,
        contentPanelConstructor: 'Tine.Addressbook.IndustryEditDialog',
        contentPanelConstructorConfig: config
    });
    return window;
};


/***/ }),

/***/ 252:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * Addressbook industry combo box
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Addressbook');

/**
 * Contract selection combo box
 * 
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.IndustrySearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>log
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Addressbook.IndustrySearchCombo
 */
Tine.Addressbook.IndustrySearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    initComponent: function(){
        this.recordClass = Tine.Addressbook.Model.Industry;

        Tine.Addressbook.IndustrySearchCombo.superclass.initComponent.call(this);

        this.displayField = 'name';
        this.sortBy = 'name';
    }
});

Tine.widgets.form.RecordPickerManager.register('Addressbook', 'Industry', Tine.Addressbook.IndustrySearchCombo);

/***/ }),

/***/ 253:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.GenericContactGridPanelHook
 * 
 * Hook prototype for other applications to hook into the addressbook contact grid context menu<br>
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */

Tine.Addressbook.GenericContactGridPanelHook = function(config) {
    Tine.log.info('initialising addressbook hook');
    Ext.apply(this, config);
    
    this.recordClass = Tine[this.app.name].Model[this.modelName];
    var text = this.recordClass.getMeta('recordName');
    
    this.addRecordAction = new Ext.Action({
        actionType: 'add',
        requiredGrant: 'readGrant',
        text: text,
        iconCls: this.app.getIconCls(),
        scope: this,
        handler: this.onUpdateRecord,
        allowMultiple: true,
        listeners: {
            scope: this,
            render: this.onRender
        }
    });
    
    this.newRecordAction = new Ext.Action({
        actionType: 'new',
        requiredGrant: 'readGrant',
        text: text,
        iconCls: this.app.getIconCls(),
        scope: this,
        handler: this.onAddRecord,
        allowMultiple: true,
        listeners: {
            scope: this,
            render: this.onRender
        }
    });
    
    Ext.ux.ItemRegistry.registerItem('Addressbook-Contact-GridPanel-ContextMenu-Add', this.addRecordAction, 100);
    Ext.ux.ItemRegistry.registerItem('Addressbook-Contact-GridPanel-ContextMenu-New', this.newRecordAction, 100);
};

Ext.apply(Tine.Addressbook.GenericContactGridPanelHook.prototype, {
    
    /**
     * The hooking application
     * 
     * @type Tine.Tinebase.Application
     */
    app: null,
    
    /**
     * The hooking model name of the
     * 
     * @type 
     */
    modelName: null,
    
    /**
     * The Addressbook Contact Grid to hook into
     * 
     * @type {Tine.Addressbook.ContactGridPanel}
     */
    contactGridPanel: null,
        
    /**
     * get addressbook contact grid panel
     */
    getContactGridPanel: function() {
        if (! this.contactGridPanel) {
            this.contactGridPanel = Tine.Tinebase.appMgr.get('Addressbook').getMainScreen().getCenterPanel();
        }
        return this.contactGridPanel;
    },

    /**
     * add selected contacts to a new record
     * 
     * @param {Button} btn 
     */
    onAddRecord: function(btn) {
        var ms = this.app.getMainScreen(),
            cp = ms.getCenterPanel(),
            filter = this.getFilter(ms);
        
        if (!filter) {
            var addRelations = this.getSelectionsAsArray();
        } else {
            var addRelations = true;
        }

        cp.onEditInNewWindow.call(cp, 'add', null, [{
            ptype: 'addrelations_edit_dialog', selectionFilter: filter, addRelations: addRelations, callingApp: 'Addressbook', callingModel: 'Contact'
        }]);
    },
    
    /**
     * adds selected contacts to an existing record
     */
    onUpdateRecord: function() {
        var ms = this.app.getMainScreen(),
            cp = ms.getCenterPanel(),
            filter = this.getFilter(ms),
            sm = this.getContactGridPanel().selectionModel;
            
        if (! filter) {
            var addRelations = this.getSelectionsAsArray(),
                count = this.getSelectionsAsArray().length;
        } else {
            var addRelations = true,
                count = sm.store.totalLength;
        }
        var cn = 'AddTo' + this.modelName + 'Panel';
        
        Tine[this.app.name][cn].openWindow({
            count: count, selectionFilter: filter, addRelations: addRelations, callingApp: 'Addressbook', callingModel: 'Contact'
        });
    },
    
    /**
     * returns the current filter if is filter selection
     * @param {Tine.widgets.MainScreen}
     * @return {Object}
     */
    getFilter: function(ms) {
        var sm = this.getContactGridPanel().selectionModel,
            filter = null;
        
        if (sm.isFilterSelect) {
            var filter = sm.getSelectionFilter();
        }
        return filter;
    },
    
    /**
     * returns selected contacts
     * @returns {Array}
     */
    getSelectionsAsArray: function() {
        var contacts = this.getContactGridPanel().grid.getSelectionModel().getSelections(),
            cont = [];
        
        Ext.each(contacts, function(contact) {
           if (contact.data) cont.push(contact.data);
        });
        
        return cont;
    },
    
    /**
     * add to action updater the first time we render
     */
    onRender: function() {
        var actionUpdater = this.getContactGridPanel().actionUpdater,
            registeredActions = actionUpdater.actions;

        if (registeredActions.indexOf(this.addRecordAction) < 0) {
            actionUpdater.addActions([this.addRecordAction]);
        }

        if (registeredActions.indexOf(this.newRecordAction) < 0) {
            actionUpdater.addActions([this.newRecordAction]);
        }
    }
});

/***/ }),

/***/ 254:
/***/ (function(module, exports, __webpack_require__) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2007-2017 Metaways Infosystems GmbH (http://www.metaways.de)
 */

Ext.ns('Tine.Addressbook');

__webpack_require__(255);

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.Application
 * @extends     Tine.Tinebase.Application
 * Addressbook Application Object <br>
 * 
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 */
Tine.Addressbook.Application = Ext.extend(Tine.Tinebase.Application, {
    
    /**
     * auto hook text i18n._('New Contact')
     */
    addButtonText: 'New Contact',
    
    /**
     * Get translated application title of the calendar application
     * 
     * @return {String}
     */
    getTitle: function() {
        return this.i18n.ngettext('Addressbook', 'Addressbooks', 1);
    },

    /** 
     * Overide get main screen to allow for feature gating
     *
     **/
    getMainScreen: function() {
        var mainscreen = Tine.Addressbook.Application.superclass.getMainScreen.call(this);

        if (!Tine.Tinebase.appMgr.get('Addressbook').featureEnabled('featureListView')
            && !Tine.Tinebase.appMgr.get('Addressbook').featureEnabled('featureResources')) {
            mainscreen.useModuleTreePanel = false;
        }

        return mainscreen;
    },

    registerCoreData: function() {
        Tine.CoreData.Manager.registerGrid('adb_lists', Tine.Addressbook.ListGridPanel, {
            app: this,
            initialLoadAfterRender: false
        });

        Tine.CoreData.Manager.registerGrid(
            'adb_list_roles',
            Tine.widgets.grid.GridPanel,
            {
                recordClass: Tine.Addressbook.Model.ListRole,
                app: this,
                initialLoadAfterRender: false,
                // TODO move this to a generic place
                gridConfig: {
                    autoExpandColumn: 'name',
                    columns: [{
                        id: 'id',
                        header: this.i18n._("ID"),
                        width: 150,
                        sortable: true,
                        dataIndex: 'id',
                        hidden: true
                    }, {
                        id: 'name',
                        header: this.i18n._("Name"),
                        width: 300,
                        sortable: true,
                        dataIndex: 'name'
                    }, {
                        id: 'description',
                        header: this.i18n._("Description"),
                        width: 300,
                        sortable: true,
                        dataIndex: 'description',
                        hidden: true
                    }]
                }
            }
        );
        
        Tine.CoreData.Manager.registerGrid(
            'adb_industries',
            Tine.widgets.grid.GridPanel,
            {
                recordClass: Tine.Addressbook.Model.Industry,
                app: this,
                initialLoadAfterRender: false,
                // TODO move this to a generic place
                gridConfig: {
                    autoExpandColumn: 'name',
                    columns: [{
                        id: 'id',
                        header: this.i18n._("ID"),
                        width: 150,
                        sortable: true,
                        dataIndex: 'id',
                        hidden: true
                    }, {
                        id: 'name',
                        header: this.i18n._("Name"),
                        width: 300,
                        sortable: true,
                        dataIndex: 'name'
                    }, {
                        id: 'description',
                        header: this.i18n._("Description"),
                        width: 300,
                        sortable: true,
                        dataIndex: 'description',
                        hidden: true
                    }]
                }
            }
        );
    }
});

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.MainScreen
 * @extends     Tine.widgets.MainScreen
 * MainScreen of the Addressbook Application <br>
 * 
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 */
Tine.Addressbook.MainScreen = Ext.extend(Tine.widgets.MainScreen, {
    activeContentType: 'Contact',
    contentTypes: [
        {model: 'Contact', requiredRight: null, singularContainerMode: false}
    ],

    initComponent: function() {
        var app = Tine.Tinebase.appMgr.get('Addressbook');

        if (app.featureEnabled('featureListView')) {
            this.contentTypes.push({model: 'List', requiredRight: null, singularContainerMode: false});
        }

        if (app.featureEnabled('featureStructurePanel')) {
            this.contentTypes.push({
                contentType: 'structure',
                app: app,
                text: app.i18n._('Structure'), // _('Structure')
                iconCls: 'AddressbookStructure',
                xtype: 'addressbook.structurepanel'
            });
        }

        // only show if calendar is available and user has manage_resources right
        if (app.featureEnabled('featureResources')
            && Tine.Tinebase.common.hasRight('run', 'Calendar')
            && Tine.Tinebase.common.hasRight('manage', 'Calendar', 'resources')
        ) {
            var cal = Tine.Tinebase.appMgr.get('Calendar');
            this.contentTypes.push({
                contentType: 'resource',
                app: cal,
                text: cal.i18n._('Resources'),
                iconCls: 'CalendarResource',
                xtype: 'calendar.resourcegridpanel',
                ownActionToolbar: false,
                singularContainerMode: true
            });
        }

        Tine.Addressbook.MainScreen.superclass.initComponent.call(this);
    }
});

Tine.Addressbook.ContactTreePanel = function(config) {
    Ext.apply(this, config);
    
    this.id = 'Addressbook_Contact_Tree';
    this.filterMode = 'filterToolbar';
    this.recordClass = Tine.Addressbook.Model.Contact;
    Tine.Addressbook.ContactTreePanel.superclass.constructor.call(this);
};
Ext.extend(Tine.Addressbook.ContactTreePanel , Tine.widgets.container.TreePanel);

Tine.Addressbook.ListTreePanel = function(config) {
    Ext.apply(this, config);
    
    this.id = 'Addressbook_List_Tree';
    this.filterMode = 'filterToolbar';
    this.recordClass = Tine.Addressbook.Model.List;
    Tine.Addressbook.ListTreePanel.superclass.constructor.call(this);
};
Ext.extend(Tine.Addressbook.ListTreePanel , Tine.widgets.container.TreePanel);


Tine.Addressbook.handleRequestException = Tine.Tinebase.ExceptionHandler.handleRequestException;

Tine.Addressbook.ContactFilterPanel = function(config) {
    Ext.apply(this, config);
    Tine.Addressbook.ContactFilterPanel.superclass.constructor.call(this);
};

Ext.extend(Tine.Addressbook.ContactFilterPanel, Tine.widgets.persistentfilter.PickerPanel, {
    filter: [{field: 'model', operator: 'equals', value: 'Addressbook_Model_ContactFilter'}]
});

Tine.Addressbook.ListFilterPanel = function(config) {
    Ext.apply(this, config);
    Tine.Addressbook.ListFilterPanel.superclass.constructor.call(this);
};

Ext.extend(Tine.Addressbook.ListFilterPanel, Tine.widgets.persistentfilter.PickerPanel, {
    filter: [{field: 'model', operator: 'equals', value: 'Addressbook_Model_ListFilter'}]
});


/***/ }),

/***/ 255:
/***/ (function(module, exports, __webpack_require__) {

/*
 * Tine 2.0
 *
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiß <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
 */

Ext.ns('Tine.Addressbook');

// @TODO: implement selection model
// @TODO: enable edit&delete btns // have action updater
// @TODO: show relation type - resove all relation types e.g. SITE -> Standort
Tine.Addressbook.StructurePanel = Ext.extend(Tine.widgets.grid.GridPanel, {

    /**
     * @property {cytoscape} cy
     */
    cy: null,

    // private
    recordClass: Tine.Tinebase.Model.Path,
    border: false,
    layout: 'border',
    usePagingToolbar: false,
    autoRefreshInterval: null,
    listenMessageBus: false,

    initComponent: function() {
        var me = this;

        this.app = Tine.Tinebase.appMgr.get('Addressbook');

        this.recordProxy = new Tine.Tinebase.data.RecordProxy({
            recordClass: this.recordClass
        });

        this.detailsPanel = new Ext.Container({
            layout: 'card',
            activeItem: 0,
            border: false,
            items: [new Ext.ux.display.DisplayPanel ({
                id: 'none',
                border: false,
                layout: 'hbox',
                defaults:{margins:'0 5 0 0'},
                layoutConfig: {
                    padding:'5',
                    align:'stretch'
                },
                items: [{
                    cls : 'x-ux-display',
                    layout: 'ux.display',
                    flex: 1,
                    layoutConfig: {
                        background: 'solid',
                        declaration: this.app.i18n._('Select record to see its details')
                    }
                }, {
                    flex: 1,
                    border: false,
                    layout: 'ux.display',
                    layoutConfig: {
                        background: 'border'
                    },
                    html: [
                        '<p>', this.app.i18n._('This module visualises hierarchically depended relations between records of different types.'), '</p>',
                        '<p>', this.app.i18n._('Hierarchically depended relations are created automatically for some data types like users and groups, but can also be created manually via the corresponding relation types.'), '</p>'
                    ].join('')
                }]
            })],
            doBind: function() {}
        });
        Tine.Addressbook.StructurePanel.superclass.initComponent.call(this);
    },

    initGrid: function() {
        var me = this,
            view = {};

        this.cyPanel = new Ext.Panel({
            // ref: '../cyPanel',
            tbar: [this.refresh = new Ext.Toolbar.Button({
                tooltip: Ext.PagingToolbar.prototype.refreshText,
                overflowText: Ext.PagingToolbar.prototype.refreshText,
                iconCls: 'x-tbar-loading',
                handler: this.doRefresh,
                scope: this
            }), '-'],
            layout: 'fit',
            border: false,
            getStore: function() {
                return me.store;
            },
            getView: function() {
                return view;
            },
            getSelectionModel: function() {
                return {
                    getSelections: function() {
                        return this.selectedNode;
                    }
                };
            }
        });

        // abstract code needs this name
        this.grid = this.cyPanel;
    },

    initActions: function() {
        Tine.Addressbook.StructurePanel.superclass.initActions.apply(this, arguments);
        this.action_addInNewWindow.hide();
        this.action_editInNewWindow.hide();
        this.action_deleteRecord.hide();
        this.actions_print.hide();
    },

    // NOTE: not yet, reloading(relayout) resets viewport
    initMessageBus: function() {
        postal.subscribe({
            channel: "recordchange",
            topic: '*.*.update',
            callback: this.onRecordChanges.createDelegate(this)
        });
    },

    /**
     * bus notified about record changes
     */
    onRecordChanges: function(data, e) {
        var me = this,
            _ = window.lodash,
            appName = e.topic.split('.')[0],
            modelName = e.topic.split('.')[1],
            model = [appName, 'Model', modelName].join('_'),
            id = data.id;

        if (me.cy) {
            var eles = me.cy.filter('[id="' + id+'"]').filter('[model="' + model + '"]');
            if (eles.length) {
                me.doRefresh()
            }
        }
    },

    doRefresh: function() {
        this.store.reload();
    },

    onRender: function() {
        var me = this;

        me.isReady = Promise.all([
            me.cyPanel.afterIsRendered(),
            new Promise(function (resolve, reject) {
                __webpack_require__.e/* require.ensure */(2).then((function () {
                    resolve(__webpack_require__(230));
                }).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
            })])
            .then(function(values) {
                me.renderCy(values[1]);
            });

        Tine.Addressbook.StructurePanel.superclass.onRender.apply(this, arguments);
    },

    renderCy: function(cytoscape) {
        // init cy
        var me = this,
            _ = window.lodash;//,
            // elements = values[0];

        me.cy = cytoscape({
            container: me.cyPanel.body.dom,
            elements: [],
            boxSelectionEnabled: false,
            autounselectify: true,
            style: [
                {
                    selector: 'node',
                    css: {
                        'shape': 'rectangle',
                        'height': 20,
                        'width': function (ele) {
                            return 20 + _.get(ele.data('recordData'), 'tags', []).length * 18;
                        },
                        'background-position-x': 0,
                        'background-position-y': 0,
                        'border-color': '#ffffff',
                        'background-opacity': 0,
                        'border-width': 3,
                        'border-opacity': 0,
                        'background-color': '#ffffff',
                        'label': 'data(name)',
                        'background-image': me.createImage,
                        'background-fit': 'contain',
                        'overlay-padding': '20'

                    }
                },
                {
                    selector: 'node:selected',
                    css: {
                        'overlay-color': 'blue',
                        'overlay-opacity': '0.2',
                        'overlay-padding': '20'
                    }
                },
                {
                    selector: 'edge',
                    css: {
                        // 'label': 'data(type)',
                        'curve-style': 'bezier',
                        'target-arrow-shape': 'triangle',
                        'width': 4,
                        'line-color': '#ddd',
                        'target-arrow-color': '#ddd'
                    }
                }
            ]
        });

        me.cy.on('tap', _.bind(me.onTap, me));
    },

    /**
     * called before store queries for data
     */
    onStoreBeforeload: function(store, options) {
        Tine.Addressbook.StructurePanel.superclass.onStoreBeforeload.apply(this, arguments);

        // filter = [{field: 'shadow_path', operator: 'contains', value: '{SITE}'}]

        var me = this;
        me.refresh.disable();
        me.showLoadMask();
    },

    /**
     * called after a new set of Records has been loaded
     *
     * @param  {Ext.data.Store} this.store
     * @param  {Array}          loaded records
     * @param  {Array}          load options
     * @return {Void}
     */
    onStoreLoad: function(store, records, options) {
        Tine.Addressbook.StructurePanel.superclass.onStoreLoad.apply(this, arguments);

        var me = this,
            _ = window.lodash,
            elements = me.computeElements(records);

        me.resolveRecords(elements)
            .then(me.isReady)
            .then(function() {
                var cy = me.cy;

                cy.startBatch();
                cy.remove('*');
                cy.add(elements);
                cy.endBatch();
                cy.layout(me.getLayoutOpts()).run();
                me.refresh.enable();
                me.hideLoadMask();
            });

    },

    getLayoutOpts: function() {
        return {
            name: 'breadthfirst',
            directed: true,
            padding: 10
        };
    },

    onTap: function(evt){
        var evtTarget = evt.target;

        // for some reason cy internal selection model does not work :-(
        // -> might have to do with autounselectify opton :-)
        if (this.selectedNode) {
            this.selectedNode.style({
                'overlay-opacity': '0'
            });
        }

        if (evtTarget === this.cy) {
            this.detailsPanel.layout.setActiveItem(0);
            return;
        }

        if (evtTarget.isNode()) {
            var node = evtTarget,
                model = node.data('model'),
                id = node.data('id');

            this.selectedNode = node;
            this.selectedNode.style({
                'overlay-opacity': '0.2'
            });

            // update detailsPanel
            var recordClass = Tine.Tinebase.data.RecordMgr.get(model),
                recordData = node.data('recordData'),
                record = new recordClass(recordData, node.data('id'));

            this.updateDetails(record);
            // @TODO later: update actions

            if (recordData && Ext.isDate(this.onTapLastTime) && this.onTapLastTime.getElapsed() < 500) {
                this.editRecord(record);
            }
            this.onTapLastTime = new Date();
        }
    },

    /**
     * NOTE: this is bullshit! The logic for opening a EditDialog is contained in the center panel
     *       but we don't want to fetch the centerpanel - we don't even know where to find it in some cases!
     *       -> let openWindow method deal with records!
     *       -> we have the same problem in the relations genericPickerGridPanel!
     * @param record
     */
    editRecord: function(record) {
        var _ = window.lodash,
            appName = record.appName,
            modelName = record.modelName,
            openMethod = _.get(Tine, appName + '.' + modelName + 'EditDialog.openWindow');

        if (openMethod) {
            openMethod({
                record: record,
                listeners: {
                    scope: this,
                    'update': this.doRefresh
                }
            });
        }
    },

    updateDetails: function(record) {
        var key = record.appName + '.' + record.modelName,
            detailsPanel = this.detailsPanel.get(key);

        if (! detailsPanel) {
            switch (key) {
                case 'Addressbook.Contact':
                    var dp = new Tine.Addressbook.ContactGridDetailsPanel({
                            i18n: Tine.Tinebase.appMgr.get('Addressbook').i18n
                        }),
                        detailsPanel = dp.getSingleRecordPanel();
                    break;
                default:
                    detailsPanel = new Ext.Panel({
                        id: key,
                        loadRecord: Ext.emptyFn,
                        border: false,
                        layout: 'fit',
                        padding: 5,
                        items: [{
                            cls : 'x-ux-display',
                            layout: 'ux.display',
                            layoutConfig: {
                                background: 'solid'
                            }
                        }]
                    });
                    break;
            }

            this.detailsPanel.items.add(key, detailsPanel);
        }

        this.detailsPanel.layout.setActiveItem(key);
        detailsPanel.loadRecord(record);
    },

    resolveRecords: function(elements) {
        var _ = window.lodash,
            me = this,
            promises = [];

        _.each(_.groupBy(elements.nodes, 'data.model'), function(data, modelName) {
            var ids = _.map(data, 'data.id'),
                method = _.get(Tine, modelName.replace(/_.*$/, '') + '.search' + modelName.replace(/^.*_/, '') + 's');

            promises.push(method([{field: 'id', operator: 'in', value: ids}], {})
                .then(function(response) {
                    _.each(response.results, function(recordData) {
                        _.set(_.find(data, function(o) {
                            return _.get(o, 'data.id') == recordData.id;
                        }), 'data.recordData', recordData);
                    })
                })
                .catch(function(error) {})
            );
        });

        return Promise.all(promises);
    },

    // els & edges
    computeElements: function(paths) {
        var _ = window.lodash,
            me = this,
            elements = {nodes: [], edges: []},
            processed = [];

        _.each(paths, function(path) {
            var pathData = path.data,
                names = String(pathData.path).replace(/^\//, '').split('/'),
                ids = String(pathData.shadow_path).replace(/^\//, '').split('/'),
                lastId = false,
                type = '';

            _.each(names, function(name) {
                var parts = ids.shift().match(/\{(.+)\}([^{]+)(?:\{(.*)\})?/),
                    model = parts[1],
                    id = parts[2],
                    elId;

                // @TODO: map list-role to edgetype?
                if (model == 'Addressbook_Model_ListRole') return;

                name = name.replace(/{.*}$/, '');

                if (lastId) {
                    // edge
                    elId = lastId + id + type;
                    if (processed.indexOf(elId) < 0) {
                        elements.edges.push({data: {id: elId, source: lastId, target: id, type: type}});
                        processed.push(elId);
                    }
                }
                // node
                elId = model + id;
                if (processed.indexOf(elId) < 0) {
                    elements.nodes.push({data: {id: id, name: name, model: model}});
                    processed.push(elId);
                }

                lastId = id;
                type = parts[3];
            });
        });

        return elements;
    },

    createImage: function(ele) {
        var _ = window.lodash,
            tags = _.get(ele.data('recordData'), 'tags', []),
            recordImage = _.get(ele.data('recordData'), 'jpegphoto'),
            iconCls = '.' + ele.data('model').replace('_Model_', ''),
            url = function(data) {return data},
            cssRule = Ext.util.CSS.getRule(iconCls) || Ext.util.CSS.getRule('.ApplicationIconCls'),
            iconData = cssRule.style.backgroundImage,
            iconImage = new Image(),
            canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d');

        canvas.width = 20 + tags.length * 18;
        canvas.height = 18;

        iconImage.src = eval(iconData);
        ctx.drawImage(iconImage, 0, 0, 18, 18);

        ctx.strokeStyle = "#000000";
        _.each(tags, function(tag, idx) {
            ctx.fillStyle = tag.color;
            ctx.beginPath();
            ctx.arc(20 + 9 + idx*18, 8, 7, 0, Math.PI*2, true);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();
        });

        return 'url("' + canvas.toDataURL() + '")';
    },

    showLoadMask: function() {
        var me = this;
        return me.afterIsRendered()
            .then(function() {
                if (! me.loadMask) {
                    me.loadMask = new Ext.LoadMask(me.getEl(), {msg: me.app.i18n._("Loading Structure data...")});
                }
                me.loadMask.show.defer(100, me.loadMask);
            });
    },

    hideLoadMask: function() {
        this.loadMask.hide.defer(100, this.loadMask);
        return Promise.resolve();
    }
});

Ext.reg('addressbook.structurepanel', Tine.Addressbook.StructurePanel);


Tine.Addressbook.StructureWestPanel = Ext.extend(Tine.widgets.mainscreen.WestPanel, {
    recordClass: Tine.Tinebase.Model.Path,
    hasContainerTreePanel: false,
    hasFavoritesPanel: true
});

/***/ }),

/***/ 256:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 *
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Addressbook');

/**
 * Render given addresss
 *
 * You need to pass the record and a config to use this renderer.
 * The config contains a mapping, which fields from the record should have which place in the template.
 * Undefined fields won't be rendered, this keeps it well reusable for all address like purposes.
 *
 * @namespace   Tine.Addressbook
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @singleton
 */
Tine.Addressbook.addressRenderer = function (v, metadata, record, store, a, b, config) {
    var template = new Ext.XTemplate(
        '<tpl for="." class="address">' +
        '<tpl if="street">{street} <br /></tpl>' +
        '<tpl if="street2">{street2} <br /></tpl>' +
        '<tpl if="postalcode">{postalcode}</tpl> <tpl if="locality">{locality}</tpl><br />' +
        '<tpl if="region">{region} <br /></tpl>' +
        '<tpl if="country">{country}</tpl>' +
        '</tpl>');
    template.compile();
    
    if (!record) {
        return template.applyTemplate({
            street: '',
            street2: '',
            postalcode: '',
            locality: '',
            region: '',
            country: ''
        });
    }

    var local = Ext.apply({}, config);
    var keys = Object.keys(local);

    // According to config, resolve the given fields from record
    keys.forEach(function (key) {
        var value = null;

        if (!record.data) {
            value = window.lodash.get(record, local[key]);
        } else {
            value = window.lodash.get(record.data, local[key]);
        }

        local[key] = Tine.Tinebase.EncodingHelper.encode(value);

        // Country code to country name
        // @todo: Wouldn't it be cool, if this could be managed by the modelconfig as well?
        if (key === 'country') {
            var countryRenderer = Tine.widgets.grid.RendererManager.get("Addressbook", "Addressbook_Model_Contact", "country", "displayPanel");
            local[key] = countryRenderer(local[key]);
        }
    });

    return template.applyTemplate(local);
};

Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'addressblock', Tine.Addressbook.addressRenderer, 'displayPanel');

/***/ }),

/***/ 257:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 *
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Addressbook');

/**
 * Render country name by it's iso code
 *
 * @namespace   Tine.Addressbook
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @singleton
 */
Tine.Addressbook.countryRenderer = function (v) {
    return Locale.getTranslationData('CountryList', v);
};

Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'country', Tine.Addressbook.countryRenderer, 'displayPanel');

/***/ }),

/***/ 258:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 *
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Addressbook');

/**
 * Render given MailAddresss
 *
 * @namespace   Tine.Addressbook
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @singleton
 */
Tine.Addressbook.mailAddressRenderer = function (email) {
    if (!email) {
        return '';
    }

    email = Tine.Tinebase.EncodingHelper.encode(email);
    var link = (this.felamimail === true) ? '#' : 'mailto:' + email;
    var id = Ext.id() + ':' + email;

    return '<a href="' + link + '" class="tinebase-email-link" id="' + id + '">'
        + Ext.util.Format.ellipsis(email, 18) + '</a>';
};

Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'email', Tine.Addressbook.mailAddressRenderer, 'displayPanel');



/***/ }),

/***/ 259:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 *
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Addressbook');

/**
 * Render given image
 *
 * @namespace   Tine.Addressbook
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @singleton
 */
Tine.Addressbook.imageRenderer = function (jpegphoto, metadata, record) {
    function getImageUrl(url, width, height, contact) {
        var _ = window.lodash,
            mtime = (_.get(contact, 'data.last_modified_time') || _.get(contact, 'data.creation_time')) || null;
        if (url.match(/&/)) {
            url = Ext.ux.util.ImageURL.prototype.parseURL(url);
            url.width = width;
            url.height = height;
            url.ratiomode = 0;
            url.mtime = Ext.isDate(mtime) ? mtime.getTime() : new Date().getTime();
        }
        return url;
    }
    
    var url = getImageUrl(jpegphoto, 90, 113, record);

    return '<img src="' + url + '" />';
};

Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'image', Tine.Addressbook.imageRenderer, 'displayPanel');

/***/ }),

/***/ 260:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 *
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Addressbook');

/**
 * Render given URL as html
 *
 * @namespace   Tine.Addressbook
 * @author      Michael Spahn <m.spahn@metaways.de>
 * @singleton
 */
Tine.Addressbook.urlRenderer = function (url) {
    return '<a href=' + Tine.Tinebase.EncodingHelper.encode(url, 'href') + ' target="_blank">' + Tine.Tinebase.EncodingHelper.encode(url, 'shorttext') + '</a>';
};

Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'url', Tine.Addressbook.urlRenderer, 'displayPanel');

/***/ }),

/***/ 261:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 *
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2017 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 * TODO         add preference for sending mails with felamimail or mailto?
 */

Ext.ns('Tine.Addressbook');

/**
 * the details panel (shows contact details)
 *
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ContactGridDetailsPanel
 * @extends     Tine.widgets.grid.DetailsPanel
 */
Tine.Addressbook.ContactGridDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsPanel, {

    il8n: null,
    felamimail: false,

    recordClass: Tine.Addressbook.Model.Contact,

    getSingleRecordPanel: function() {
        var me = this;
        if (! this.singleRecordPanel) {
            this.singleRecordPanel = new Tine.widgets.display.RecordDisplayPanel({
                recordClass: this.recordClass,
                getBodyItems: function() {
                    return [{
                        layout: 'hbox',
                        flex: 1,
                        border: false,
                        layoutConfig: {
                            padding: '0',
                            align: 'stretch'
                        },
                        defaults: {
                            margins: '0 5 0 0'
                        },
                        items: [{
                            width: 90,
                            layout: 'ux.display',
                            layoutConfig: {
                                background: 'solid'
                            },
                            items: [{
                                xtype: 'ux.displayfield',
                                name: 'jpegphoto',
                                cls: 'preview-panel-image',
                                anchor:'100% 100%',
                                hideLabel: true,
                                htmlEncode: false,
                                renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'image', 'displayPanel').createDelegate(me)
                            }]
                        }, {
                            flex: 1,
                            layout: 'ux.display',
                            labelWidth: 60,
                            layoutConfig: {
                                background: 'solid'
                            },
                            items: [{
                                layout: 'hbox',
                                border: false,
                                anchor: '100% 100%',
                                layoutConfig: {
                                    align: 'stretch'
                                },
                                items: [{
                                    layout: 'ux.display',
                                    layoutConfig: {
                                        background: 'inner',
                                        labelLWidth: 100,
                                        declaration: this.app.i18n._('Business')
                                    },
                                    labelAlign: 'top',
                                    border: false,
                                    flex: 1,
                                    items: [{
                                        xtype: 'ux.displayfield',
                                        name: 'org_name',
                                        hideLabel: true,
                                        htmlEncode: false,
                                        renderer: function(value) {
                                            return '<b>' +  Tine.Tinebase.EncodingHelper.encode(value) + '</b>';
                                        }
                                    }, {
                                        xtype: 'ux.displayfield',
                                        name: 'dtstart',
                                        hideLabel: true,
                                        htmlEncode: false,
                                        renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'addressblock', 'displayPanel').createDelegate(me, {
                                            'street': 'adr_one_street',
                                            'street2': 'adr_one_street2',
                                            'postalcode': 'adr_one_postalcode',
                                            'locality': 'adr_one_locality',
                                            'region': 'adr_one_region',
                                            'country': 'adr_one_countryname'
                                        }, true)
                                    }]
                                }, {
                                    layout: 'ux.display',
                                    layoutConfig: {
                                        background: 'inner'
                                    },
                                    labelWidth: 50,
                                    flex: 1,
                                    border: false,
                                    items: [{
                                        xtype: 'ux.displayfield',
                                        name: 'tel_work',
                                        fieldLabel: this.app.i18n._('Phone')
                                    }, {
                                        xtype: 'ux.displayfield',
                                        name: 'tel_cell',
                                        fieldLabel: this.app.i18n._('Mobile')
                                    }, {
                                        xtype: 'ux.displayfield',
                                        name: 'tel_fax',
                                        fieldLabel: this.app.i18n._('Fax')
                                    }, {
                                        xtype: 'ux.displayfield',
                                        name: 'email',
                                        fieldLabel: this.app.i18n._('E-Mail'),
                                        htmlEncode: false,
                                        renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'email', 'displayPanel').createDelegate(me)
                                    }, {
                                        xtype: 'ux.displayfield',
                                        name: 'url',
                                        fieldLabel: this.app.i18n._('Web'),
                                        htmlEncode: false,
                                        renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'url', 'displayPanel').createDelegate(me)
                                    }]
                                }]
                            }]
                        }, {
                            flex: 1,
                            layout: 'ux.display',
                            labelAlign: 'top',
                            autoScroll: true,
                            layoutConfig: {
                                background: 'solid',
                                declaration: this.app.i18n._('Private')
                            },

                            // @todo: this field doesn't actually require a certain field, there should be two methods for RenderManager:
                            //  + get()
                            //  + getBlock() // block actually doesn't specify a certain field and only an record, the field declaration should come from the modelconfig later
                            items: [{
                                xtype: 'ux.displayfield',
                                name: 'attendee',
                                hideLabel: true,
                                htmlEncode: false,
                                renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'addressblock', 'displayPanel').createDelegate(me, {
                                    'street': 'adr_two_street',
                                    'street2': 'adr_two_street2',
                                    'postalcode': 'adr_two_postalcode',
                                    'locality': 'adr_two_locality',
                                    'region': 'adr_two_region',
                                    'country': 'adr_two_countryname'
                                }, true)
                            }]
                        }, {
                            flex: 1,
                            layout: 'fit',

                            border: false,
                            items: [{
                                cls: 'x-ux-display-background-border',
                                xtype: 'ux.displaytextarea',
                                name: 'note'
                            }]
                        }]
                    }];
                }
            });
        }

        return this.singleRecordPanel;
    },

    /**
     * add on click event after render
     */
    afterRender: function() {
        Tine.Addressbook.ContactGridDetailsPanel.superclass.afterRender.apply(this, arguments);

        if (this.felamimail === true) {
            this.body.on('click', this.onClick, this);
        }
    },

    /**
     * on click for compose mail
     *
     * @param {} e
     *
     * TODO check if account is configured?
     * TODO generalize that
     */
    onClick: function(e) {
        var target = e.getTarget('a[class=tinebase-email-link]');
        if (target) {
            var email = target.id.split(':')[1];
            var defaults = Tine.Felamimail.Model.Message.getDefaultData();
            defaults.to = [email];
            defaults.body = Tine.Felamimail.getSignature();

            var record = new Tine.Felamimail.Model.Message(defaults, 0);

            Tine.Felamimail.MessageEditDialog.openWindow({
                record: record
            });
        }
    }
});


/***/ }),

/***/ 262:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2010 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Calendar');

/**
 * @namespace   Tine.Calendar
 * @class       Tine.Addressbook.ContactFilterModel
 * @extends     Tine.widgets.grid.FilterModel
 * 
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 */
Tine.Addressbook.ContactFilterModel = Ext.extend(Tine.widgets.grid.FilterModel, {
    /**
     * @property Tine.Tinebase.Application app
     */
    app: null,
    
    field: 'contact_id',
    defaultOperator: 'equals',
    
    /**
     * @private
     */
    initComponent: function() {
        Tine.Addressbook.ContactFilterModel.superclass.initComponent.call(this);
        
        this.app = Tine.Tinebase.appMgr.get('Addressbook');
        
        this.operators = ['equals'/*, 'notin'*/];
        this.label = this.label || this.app.i18n._('Contact');
    },
    
    /**
     * value renderer
     * 
     * @param {Ext.data.Record} filter line
     * @param {Ext.Element} element to render to 
     */
    valueRenderer: function(filter, el) {
        var value = new Tine.Addressbook.SearchCombo({
            app: this.app,
            filter: filter,
            width: this.filterValueWidth,
            listWidth: 400,
            listAlign : 'tr-br?',
            id: 'tw-ftb-frow-valuefield-' + filter.id,
            value: filter.data.value ? filter.data.value : this.defaultValue,
            renderTo: el,
            getValue: function() {
                return this.selectedRecord.id;
            },
            onSelect: function(record) {
                this.setValue(record);
                this.collapse();
        
                this.fireEvent('select', this, record);
                if (this.blurOnSelect) {
                    this.fireEvent('blur', this);
                }
            },
            setValue: function(value) {
                this.selectedRecord = value;
                var displayValue = Tine.Calendar.AttendeeGridPanel.prototype.renderAttenderUserName.call(this, value);
                Tine.Addressbook.SearchCombo.superclass.setValue.call(this, displayValue);
            }
        });
        value.on('select', this.onFiltertrigger, this);
        return value;
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['addressbook.contact'] = Tine.Addressbook.ContactFilterModel;



/***/ }),

/***/ 263:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 *
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2009-2012 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

/*global Ext, Tine*/

Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ContactEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * Addressbook Edit Dialog <br>
 *
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 */
Tine.Addressbook.ContactEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {

    /**
     * parse address button
     * @type Ext.Button
     */
    parseAddressButton: null,

    windowNamePrefix: 'ContactEditWindow_',
    appName: 'Addressbook',
    recordClass: Tine.Addressbook.Model.Contact,
    showContainerSelector: true,
    multipleEdit: true,
    displayNotes: true,

    preferredAddressBusinessCheckbox: null,
    preferredAddressPrivateCheckbox: null,

    getFormItems: function () {
        if (Tine.Tinebase.configManager.get('mapPanel') && Tine.widgets.MapPanel) {
            this.mapPanel = new Tine.Addressbook.MapPanel({
                pos: 30,
                layout: 'fit',
                title: this.app.i18n._('Map'),
                disabled: (Ext.isEmpty(this.record.get('adr_one_lon')) || Ext.isEmpty(this.record.get('adr_one_lat'))) && (Ext.isEmpty(this.record.get('adr_two_lon')) || Ext.isEmpty(this.record.get('adr_two_lat')))
            });

            Tine.widgets.dialog.MultipleEditDialogPlugin.prototype.registerSkipItem(this.mapPanel);

        } else {
            this.mapPanel = new Ext.Panel({
                layout: 'fit',
                title: this.app.i18n._('Map'),
                disabled: true,
                html: ''
            });
        }

        this.preferredAddressBusinessCheckbox = new Ext.form.Checkbox({
            checked: this.record.get('preferred_address') === "0",
            hideLabel: false,
            fieldLabel: this.app.i18n._('Preferred Address'),
            listeners: {
                'check': function(checkbox, value) {
                    if (value) {
                        this.preferredAddressPrivateCheckbox.setValue(false);
                        this.record.set('preferred_address', 0);
                    }
                },
                scope: this
            }
        });

        this.preferredAddressPrivateCheckbox = new Ext.form.Checkbox({
            checked: this.record.get('preferred_address') === "1",
            hideLabel: false,
            fieldLabel: this.app.i18n._('Preferred Address'),
            listeners: {
                'check': function(checkbox, value) {
                    if (value) {
                        this.preferredAddressBusinessCheckbox.setValue(false);
                        this.record.set('preferred_address', 1);
                    }
                },
                scope: this
            }
        });

        if (Tine.Tinebase.common.hasRight('run', 'Calendar', null) && Tine.Tinebase.appMgr.get('Addressbook').featureEnabled('featureContactEventList')) {
            this.contactEventPanel = new Tine.Calendar.ContactEventsGridPanel({
                editDialog: this,
                hasFavoritesPanel: false
            });
        } else {
            this.contactEventPanel = null;
        }

        var tabs = [{
            title: this.app.i18n.n_('Contact', 'Contacts', 1),
            border: false,
            frame: true,
            layout: 'border',
            items: [{
                region: 'center',
                layout: 'border',
                items: [{
                    xtype: 'fieldset',
                    region: 'north',
                    autoHeight: true,
                    title: this.app.i18n._('Personal Information'),
                    items: [{
                        xtype: 'panel',
                        layout: 'hbox',
                        align: 'stretch',
                        plugins: [{
                            ptype: 'ux.itemregistry',
                            key:   'Tine.Addressbook.editDialog.northPanel'
                        }],
                        items: [{
                            flex: 1,
                            xtype: 'columnform',
                            autoHeight: true,
                            style:'padding-right: 5px;',
                            items: [[
                                new Tine.Tinebase.widgets.keyfield.ComboBox({
                                    fieldLabel: this.app.i18n._('Salutation'),
                                    name: 'salutation',
                                    app: 'Addressbook',
                                    keyFieldName: 'contactSalutation',
                                    value: '',
                                    columnWidth: 0.35,
                                    listeners: {
                                        scope: this,
                                        'select': function (combo, record, index) {
                                            var jpegphoto = this.getForm().findField('jpegphoto');
                                            // set new empty photo depending on chosen salutation only if user doesn't have own image
                                            jpegphoto.setDefaultImage(record.json.image || 'images/icon-set/icon_undefined_contact.svg');
                                        }
                                    }
                                }), {
                                    columnWidth: 0.65,
                                    fieldLabel: this.app.i18n._('Title'),
                                    name: 'n_prefix',
                                    maxLength: 64
                                }], [{
                                columnWidth: 0.35,
                                fieldLabel: this.app.i18n._('First Name'),
                                name: 'n_given',
                                maxLength: 64
                            }, {
                                columnWidth: 0.30,
                                fieldLabel: this.app.i18n._('Middle Name'),
                                name: 'n_middle',
                                maxLength: 64
                            }, {
                                columnWidth: 0.35,
                                fieldLabel: this.app.i18n._('Last Name'),
                                name: 'n_family',
                                maxLength: 255
                            }], [{
                                columnWidth: 0.65,
                                xtype: 'mirrortextfield',
                                fieldLabel: this.app.i18n._('Company'),
                                name: 'org_name',
                                maxLength: 255
                            }, {
                                columnWidth: 0.35,
                                fieldLabel: this.app.i18n._('Unit'),
                                name: 'org_unit',
                                maxLength: 64
                            }
                            ]/* move to seperate tab, [{
                                    columnWidth: .4,
                                    fieldLabel: this.app.i18n._('Suffix'),
                                    name:'n_suffix'
                                }, {
                                    columnWidth: .4,
                                    fieldLabel: this.app.i18n._('Job Role'),
                                    name:'role'
                                }, {
                                    columnWidth: .2,
                                    fieldLabel: this.app.i18n._('Room'),
                                    name:'room'
                                }]*/
                            ]},
                            new Ext.ux.form.ImageField({
                                name: 'jpegphoto',
                                width: 90,
                                height: 120
                            })
                        ]
                    }, {
                        xtype: 'columnform',
                        items: [[
                            !Tine.Tinebase.appMgr.get('Addressbook').featureEnabled('featureIndustry') ?
                                {
                                    columnWidth: 0.64,
                                    xtype: 'combo',
                                    fieldLabel: this.app.i18n._('Display Name'),
                                    name: 'n_fn',
                                    disabled: true
                                } :
                                (
                                    new Tine.Addressbook.IndustrySearchCombo({
                                        fieldLabel: this.app.i18n._('Industry'),
                                        columnWidth: 0.64,
                                        name: 'industry'
                                    })
                                ), {
                                     columnWidth: 0.36,
                                     fieldLabel: this.app.i18n._('Job Title'),
                                     name: 'title',
                                     maxLength: 64
                                }, {
                                     width: 110,
                                     xtype: 'extuxclearabledatefield',
                                     fieldLabel: this.app.i18n._('Birthday'),
                                     name: 'bday'
                                }
                            ]]
                        }]
                    }, {
                        xtype: 'fieldset',
                        region: 'center',
                        title: this.app.i18n._('Contact Information'),
                        autoScroll: true,
                        plugins: [{
                            ptype: 'ux.itemregistry',
                            key:   'Tine.Addressbook.editDialog.centerPanel'
                        }],
                        items: [{
                            xtype: 'columnform',
                            items: [[{
                                fieldLabel: this.app.i18n._('Phone'),
                                labelIcon: 'images/icon-set/icon_phone.svg',
                                name: 'tel_work',
                                maxLength: 40
                            }, {
                                fieldLabel: this.app.i18n._('Mobile'),
                                labelIcon: 'images/icon-set/icon_mobile.svg',
                                name: 'tel_cell',
                                maxLength: 40
                            }, {
                                fieldLabel: this.app.i18n._('Fax'),
                                labelIcon: 'images/icon-set/icon_print.svg',
                                name: 'tel_fax',
                                maxLength: 40
                            }], [{
                                fieldLabel: this.app.i18n._('Phone (private)'),
                                labelIcon: 'images/icon-set/icon_phone.svg',
                                name: 'tel_home',
                                maxLength: 40
                            }, {
                                fieldLabel: this.app.i18n._('Mobile (private)'),
                                labelIcon: 'images/icon-set/icon_mobile.svg',
                                name: 'tel_cell_private',
                                maxLength: 40
                            }, {
                                fieldLabel: this.app.i18n._('Fax (private)'),
                                labelIcon: 'images/icon-set/icon_print.svg',
                                name: 'tel_fax_home',
                                maxLength: 40
                            }], [{
                                fieldLabel: this.app.i18n._('E-Mail'),
                                labelIcon: 'images/icon-set/icon_email.svg',
                                name: 'email',
                                vtype: 'email',
                                maxLength: 64
                            }, {
                                fieldLabel: this.app.i18n._('E-Mail (private)'),
                                labelIcon: 'images/icon-set/icon_email.svg',
                                name: 'email_home',
                                vtype: 'email',
                                maxLength: 64
                            }, {
                                xtype: 'mirrortextfield',
                                fieldLabel: this.app.i18n._('Web'),
                                labelIcon: 'images/icon-set/icon_globe.svg',
                                name: 'url',
                                maxLength: 128,
                                listeners: {
                                    scope: this,
                                    focus: function (field) {
                                        if (! field.getValue()) {
                                            field.setValue('http://www.');
                                            field.selectText.defer(100, field, [7, 11]);
                                        }
                                    },
                                    blur: function (field) {
                                        if (field.getValue() === 'http://www.') {
                                            field.setValue(null);
                                            field.validate();
                                        }
                                        if (field.getValue().indexOf('http://http://') == 0 || field.getValue().indexOf('http://https://') == 0) {
                                            field.setValue(field.getValue().substr(7));
                                            field.validate();
                                        }
                                        if (field.getValue().indexOf('http://www.http://') == 0 || field.getValue().indexOf('http://www.https://') == 0) {
                                            field.setValue(field.getValue().substr(11));
                                            field.validate();
                                        }
                                    }
                                }
                            }]]
                        }]
                    }, {
                        xtype: 'tabpanel',
                        region: 'south',
                        border: false,
                        deferredRender: false,
                        height: 160,
                        split: true,
                        activeTab: 0,
                        defaults: {
                            frame: true
                        },
                        plugins: [{
                            ptype: 'ux.itemregistry',
                            key:   'Tine.Addressbook.editDialog.southPanel'
                        }],
                        items: [{
                            title: this.app.i18n._('Company Address'),
                            xtype: 'columnform',
                            items: [[{
                                fieldLabel: this.app.i18n._('Street'),
                                name: 'adr_one_street',
                                maxLength: 64
                            }, {
                                fieldLabel: this.app.i18n._('Street 2'),
                                name: 'adr_one_street2',
                                maxLength: 64
                            }, {
                                fieldLabel: this.app.i18n._('Region'),
                                name: 'adr_one_region',
                                maxLength: 64
                            }], [{
                                fieldLabel: this.app.i18n._('Postal Code'),
                                name: 'adr_one_postalcode',
                                maxLength: 64
                            }, {
                                fieldLabel: this.app.i18n._('City'),
                                name: 'adr_one_locality',
                                maxLength: 64
                            }, {
                                xtype: 'widget-countrycombo',
                                fieldLabel: this.app.i18n._('Country'),
                                name: 'adr_one_countryname',
                                maxLength: 64
                            }], [this.preferredAddressBusinessCheckbox]]
                        }, {
                            title: this.app.i18n._('Private Address'),
                            xtype: 'columnform',
                            items: [[{
                                fieldLabel: this.app.i18n._('Street'),
                                name: 'adr_two_street',
                                maxLength: 64
                            }, {
                                fieldLabel: this.app.i18n._('Street 2'),
                                name: 'adr_two_street2',
                                maxLength: 64
                            }, {
                                fieldLabel: this.app.i18n._('Region'),
                                name: 'adr_two_region',
                                maxLength: 64
                            }], [{
                                fieldLabel: this.app.i18n._('Postal Code'),
                                name: 'adr_two_postalcode',
                                maxLength: 64
                            }, {
                                fieldLabel: this.app.i18n._('City'),
                                name: 'adr_two_locality',
                                maxLength: 64
                            }, {
                                xtype: 'widget-countrycombo',
                                fieldLabel: this.app.i18n._('Country'),
                                name: 'adr_two_countryname',
                                maxLength: 64
                            }], [this.preferredAddressPrivateCheckbox]]
                        }]
                    }]
                }, {
                    // activities and tags
                    region: 'east',
                    layout: 'ux.multiaccordion',
                    animate: true,
                    width: 210,
                    split: true,
                    collapsible: true,
                    collapseMode: 'mini',
                    header: false,
                    margins: '0 5 0 5',
                    border: true,
                    plugins: [{
                        ptype: 'ux.itemregistry',
                        key:   'Tine.Addressbook.editDialog.eastPanel'
                    }],
                    items: [
                        new Ext.Panel({
                            // @todo generalise!
                            title: this.app.i18n._('Description'),
                            iconCls: 'descriptionIcon',
                            layout: 'form',
                            labelAlign: 'top',
                            border: false,
                            items: [{
                                style: 'margin-top: -4px; border 0px;',
                                labelSeparator: '',
                                xtype: 'textarea',
                                name: 'note',
                                hideLabel: true,
                                grow: false,
                                preventScrollbars: false,
                                anchor: '100% 100%',
                                emptyText: this.app.i18n._('Enter description'),
                                requiredGrant: 'editGrant'
                            }]
                        }), new Ext.Panel({
                            title: this.app.i18n._('Groups'),
                            iconCls: 'tinebase-accounttype-group',
                            layout: 'fit',
                            border: false,
                            bodyStyle: 'border:1px solid #B5B8C8;',
                            items: [
                                this.groupsPanel
                            ]
                        }), new Tine.widgets.tags.TagPanel({
                            app: 'Addressbook',
                            border: false,
                            bodyStyle: 'border:1px solid #B5B8C8;'
                        })
                    ]
                }]
            }, this.mapPanel,
            new Tine.widgets.activities.ActivitiesTabPanel({
                app: this.appName,
                record_id: (this.record && ! this.copyRecord) ? this.record.id : '',
                record_model: this.appName + '_Model_' + this.recordClass.getMeta('modelName')
            }),
        ];

        if (this.contactEventPanel) {
            tabs.push(this.contactEventPanel);
        }

        return {
            xtype: 'tabpanel',
            border: false,
            plain: true,
            activeTab: 0,
            plugins: [{
                ptype : 'ux.tabpanelkeyplugin'
            }],
            defaults: {
                hideMode: 'offsets'
            },
            items: tabs
        };
    },

    /**
     * init component
     */
    initComponent: function () {
        this.initToolbar();
        this.groupsPanel = new Tine.Addressbook.contactListsGridPanel({
            initialLoadAfterRender: false,
            frame: false
        });
        Tine.Addressbook.ContactEditDialog.superclass.initComponent.apply(this, arguments);
    },

    /**
     * initToolbar
     */
    initToolbar: function() {
        this.parseAddressButton = new Ext.Action({
            text: Tine.Tinebase.appMgr.get('Addressbook').i18n._('Parse address'),
            handler: this.onParseAddress,
            iconCls: 'action_parseAddress',
            disabled: false,
            scope: this,
            enableToggle: true
        });
        this.printButton = new Ext.Action({
            text: Tine.Tinebase.appMgr.get('Addressbook').i18n._('Print contact'),
            handler: this.onPrint,
            iconCls:'action_print',
            disabled: false,
            scope: this
        });

        this.tbarItems = this.tbarItems || [];
        this.tbarItems = this.tbarItems.concat([this.parseAddressButton, this.printButton]);
    },

    onPrint: function(printMode) {
        this.onRecordUpdate();
        var renderer = new Tine.Addressbook.Printer.ContactRenderer();
        renderer.print(this);
    },

    /**
     * parse address handler
     *
     * opens message box where user can paste address
     *
     * @param {Ext.Button} button
     */
    onParseAddress: function (button) {
        if (button.pressed) {
            Ext.Msg.prompt(this.app.i18n._('Paste address'), this.app.i18n._('Please paste an address or a URI to a vcard that should be parsed:'), function(btn, text) {
                if (btn == 'ok'){
                    this.parseAddress(text);
                } else if (btn == 'cancel') {
                    button.toggle();
                }
            }, this, 100);
        } else {
            button.setText(this.app.i18n._('Parse address'));
            this.tokenModePlugin.endTokenMode();
        }
    },

    /**
     * send address to server + fills record/form with parsed data + adds unrecognizedTokens to description box
     *
     * @param {String} address
     */
    parseAddress: function(address) {
        Tine.log.debug('parsing address ... ');

        Tine.Addressbook.parseAddressData(address, function(result, response) {
            Tine.log.debug('parsed address:');
            Tine.log.debug(result);

            if (result.hasOwnProperty('exceptions')) {
                Ext.Msg.alert(this.app.i18n._('Failed to parse address!'), this.app.i18n._('The address could not be read.'));
            } else {
                // only set the fields that could be detected
                Ext.iterate(result.contact, function(key, value) {
                    if (value && ! this.record.get(key)) {
                        this.record.set(key, value);
                    }
                }, this);

                var oldNote = (this.record.get('note')) ? this.record.get('note') : '';

                if (result.hasOwnProperty('unrecognizedTokens')) {
                    this.record.set('note', result.unrecognizedTokens.join(' ') + oldNote);
                }

                this.onRecordLoad();

                this.parseAddressButton.setText(this.app.i18n._('End token mode'));
                this.tokenModePlugin.startTokenMode();
            }
        }, this);
    },

    /**
     * onRecordLoad
     */
    onRecordLoad: function () {
        // NOTE: it comes again and again till
        if (this.rendered) {
            var container = this.record.get('container_id');

            // handle default container
            // TODO should be generalized
            if (! this.record.id && ! Ext.isObject(container)) {
                container = this.app.getMainScreen().getWestPanel().getContainerTreePanel().getSelectedContainer('addGrant', Tine.Addressbook.registry.get('defaultAddressbook'));
                this.record.set('container_id', container);
            }

            if (this.mapPanel instanceof Tine.Addressbook.MapPanel) {
                this.mapPanel.onRecordLoad(this.record);
            }
        }
        if (this.record.id) {
            this.groupsPanel.store.loadData(this.record.get('groups'));
        }
        this.supr().onRecordLoad.apply(this, arguments);
    }
});

/**
 * Opens a new contact edit dialog window
 *
 * @return {Ext.ux.Window}
 */
Tine.Addressbook.ContactEditDialog.openWindow = function (config) {
    var id = (config.record && config.record.id) ? config.record.id : 0;
    var window = Tine.WindowFactory.getWindow({
        width: 800,
        height: 610,
        name: Tine.Addressbook.ContactEditDialog.prototype.windowNamePrefix + id,
        contentPanelConstructor: 'Tine.Addressbook.ContactEditDialog',
        contentPanelConstructorConfig: config
    });
    return window;
};


/***/ }),

/***/ 264:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 *
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 */

/*global Ext, Tine*/

Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListRoleEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * Addressbook Edit Dialog <br>
 *
 * @author      Philipp Schüle <p.schuele@metaways.de>
 */
Tine.Addressbook.ListRoleEditDialog = Ext.extend(Tine.widgets.dialog.SimpleRecordEditDialog, {
    windowNamePrefix: 'ListRoleEditWindow_',
    appName: 'Addressbook',
    recordClass: Tine.Addressbook.Model.ListRole,
});

/**
 * Opens a new contact edit dialog window
 *
 * @return {Ext.ux.Window}
 */
Tine.Addressbook.ListRoleEditDialog.openWindow = function (config) {
    var id = (config.record && config.record.id) ? config.record.id : 0;
    var window = Tine.WindowFactory.getWindow({
        width: 400,
        height: 300,
        name: Tine.Addressbook.ListRoleEditDialog.prototype.windowNamePrefix + id,
        contentPanelConstructor: 'Tine.Addressbook.ListRoleEditDialog',
        contentPanelConstructorConfig: config
    });
    return window;
};


/***/ }),

/***/ 265:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Frederic Heihoff <heihoff@sh-systems.eu>
 * @copyright   Copyright (c) 2007-2011 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.ns('Tine.Addressbook');

/**
 * List grid panel
 * 
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>List Grid Panel</p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Frederic Heihoff <heihoff@sh-systems.eu>
 * @copyright   Copyright (c) 2007-2011 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Addressbook.ListGridPanel
 */
Tine.Addressbook.ListGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    /**
     * record class
     * @cfg {Tine.Addressbook.Model.List} recordClass
     */
    recordClass: Tine.Addressbook.Model.List,
    
    /**
     * grid specific
     * @private
     */ 
    defaultSortInfo: {field: 'name', direction: 'ASC'},
    copyEditAction: true,
    felamimail: false,
    multipleEdit: false,
    duplicateResolvable: false,
    
    /**
     * @cfg {Bool} hasDetailsPanel 
     */
    hasDetailsPanel: false,
    
    /**
     * inits this cmp
     * @private
     */
    initComponent: function() {
        this.recordProxy = Tine.Addressbook.listBackend;
        
        // check if felamimail is installed and user has run right and wants to use felamimail in adb
        if (Tine.Felamimail && Tine.Tinebase.common.hasRight('run', 'Felamimail') && Tine.Felamimail.registry.get('preferences').get('useInAdb')) {
            this.felamimail = (Tine.Felamimail.registry.get('preferences').get('useInAdb') == 1);
        }
        this.gridConfig.cm = this.getColumnModel();
        this.filterToolbar = this.filterToolbar || this.getFilterToolbar();

        if (this.hasDetailsPanel) {
            this.detailsPanel = this.getDetailsPanel();
        }

        this.plugins = this.plugins || [];
        this.plugins.push(this.filterToolbar);
        
        Tine.Addressbook.ListGridPanel.superclass.initComponent.call(this);
    },
    
    /**
     * returns column model
     * 
     * @return Ext.grid.ColumnModel
     * @private
     */
    getColumnModel: function() {
        return new Ext.grid.ColumnModel({
            defaults: {
                sortable: true,
                hidden: true,
                resizable: true
            },
            columns: this.getColumns()
        });
    },
    
    /**
     * returns array with columns
     * 
     * @return {Array}
     */
    getColumns: function() {
        return [
            { id: 'type', header: this.app.i18n._('Type'), dataIndex: 'type', width: 30, renderer: Tine.Addressbook.ListGridPanel.listTypeRenderer, hidden: false },
            { id: 'tags', header: this.app.i18n._('Tags'), dataIndex: 'tags', width: 50, renderer: Tine.Tinebase.common.tagsRenderer, sortable: false, hidden: false },
            { id: 'name', header: this.app.i18n._('Name'), dataIndex: 'name', width: 30, hidden: false },
            { id: 'list_type', header: this.app.i18n._('List type'), dataIndex: 'list_type', width: 30, renderer: Tine.Tinebase.widgets.keyfield.Renderer.get('Addressbook', 'listType'), hidden: false },
            { id: 'emails', header: this.app.i18n._('Emails'), dataIndex: 'emails', hidden: false, renderer: function(value) {
                if (! value) {
                    return '';
                }
                // TODO should be fixed on server side
                // remove leading comma
                return value.replace(/^,/, '');
            }},
        ].concat(this.getModlogColumns().concat(this.getCustomfieldColumns()));
    },
    
    /**
     * @private
     */
    initActions: function() {        
        Tine.Addressbook.ListGridPanel.superclass.initActions.call(this);
    },

    /**
     * returns details panel
     * 
     * @private
     * @return {Tine.Addressbook.ListGridDetailsPanel}
     */
    getDetailsPanel: function() {
        return new Tine.Addressbook.ListGridDetailsPanel({
            gridpanel: this,
            il8n: this.app.i18n
        });
    }
});

/**
 * list type renderer
 *
 * @private
 * @return {String} HTML
 */
Tine.Addressbook.ListGridPanel.listTypeRenderer = function(data, cell, record) {
    var i18n = Tine.Tinebase.appMgr.get('Addressbook').i18n,
        type = ((record.get && record.get('type')) || record.type),
        cssClass = type == 'group' ? 'renderer_typeGroupIcon' : 'renderer_typeListIcon',
        qtipText = Tine.Tinebase.common.doubleEncode(type == 'group' ? i18n._('System Group') : i18n._('Group'));

    return '<div ext:qtip="' + qtipText + '" style="background-position:0px;" class="' + cssClass + '">&#160</div>';
};


/***/ }),

/***/ 266:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListRoleGridPanel
 * @extends     Ext.grid.EditorGridPanel
 * @author      Philipp Schüle <p.schuele@metaways.de>
 */
Tine.Addressbook.contactListsGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {

    recordClass: Tine.Addressbook.Model.List,
    usePagingToolbar: false,

    gridConfig: {
        autoExpandColumn: 'name'
    },

    // the list record
    record: null,

    // deactivate some fns
    initActions: Ext.emptyFn,
    initFilterPanel: Ext.emptyFn,

    /**
     * init component
     */
    initComponent: function() {
        this.app = this.app ? this.app : Tine.Tinebase.appMgr.get('Addressbook');
        this.store = new Ext.data.JsonStore({
            fields: Tine.Addressbook.Model.List
        });

        this.gridConfig.cm = new Ext.grid.ColumnModel({
            defaults: {
                resizable: true
            },
            columns: this.getColumns()
        });

        Tine.Addressbook.contactListsGridPanel.superclass.initComponent.call(this);
    },

    getColumns: function() {
        return [
            {id: 'type', header: this.app.i18n._('Type'), dataIndex: 'type', width: 20, renderer: Tine.Addressbook.ListGridPanel.listTypeRenderer, hidden: false },
            {id: 'name', header: this.app.i18n._('Name'), width: 100, sortable: true, dataIndex: 'name'
        }];
    }
});


/***/ }),

/***/ 267:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Frederic Heihoff <heihoff@sh-systems.eu>
 * @copyright   Copyright (c) 2007-2009 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.ns('Tine.Addressbook');

/**
 * the details panel (shows List details)
 * 
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListGridDetailsPanel
 * @extends     Tine.widgets.grid.DetailsPanel
 */
Tine.Addressbook.ListGridDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsPanel, {
    
    il8n: null,
    felamimail: false,
    
    /**
     * init
     */
    initComponent: function() {

        // init templates
        this.initTemplate();
        this.initDefaultTemplate();
        
        Tine.Addressbook.ListGridDetailsPanel.superclass.initComponent.call(this);
    },

    /**
     * add on click event after render
     */
    afterRender: function() {
        Tine.Addressbook.ListGridDetailsPanel.superclass.afterRender.apply(this, arguments);
    },
    
    /**
     * init default template
     */
    initDefaultTemplate: function() {
        
        this.defaultTpl = new Ext.XTemplate(
            '<div class="preview-panel-list-nobreak">',    
                '<!-- Preview contacts -->',
                '<div class="preview-panel preview-panel-list-left">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.il8n._('Lists') + '</div>',
                    '<div class="preview-panel-list-leftside preview-panel-left">',
                        '<span class="preview-panel-bold">',
                            this.il8n._('Select list') + '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                '</div>',
            '</div>'        
        );
    },
    
    /**
     * init single List template (this.tpl)
     */
    initTemplate: function() {
        this.tpl = new Ext.XTemplate(
            '<div class="preview-panel-list-nobreak">',    
                '<!-- Preview contacts -->',
                '<div class="preview-panel preview-panel-list-left">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.il8n._('Lists') + '</div>',
                    '<div class="preview-panel-list-leftside preview-panel-left" style="width: 100%">',
                        '<span class="preview-panel-bold">',
                            this.il8n._('List') + '<br/>',
                        '</span>',
                        '<div style="word-wrap:break-word;">{[values.emails]}</div>',
                    '</div>',
                '</div>',
            '</div>'
        );
    }
});


/***/ }),

/***/ 268:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 *
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
Ext.ns('Tine.Addressbook');

/**
 * config grid panel
 *
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListMemberRoleLayerCombo
 * @extends     Tine.widgets.grid.LayerCombo
 */
Tine.Addressbook.ListMemberRoleLayerCombo = Ext.extend(Tine.widgets.grid.PickerGridLayerCombo, {

    /**
     * @cfg contact record
     */
    record: null,

    /**
     * @cfg grid record class
     */
    gridRecordClass: Tine.Addressbook.Model.ListRole,

    /**
     * sets values to innerForm (grid)
     */
    setFormValue: function (value) {
        var listRoles = [];
        if (Ext.isArray(value)) {
            Ext.each(value, function (role) {
                listRoles.push(role.list_role_id);
            });
        }

        this.setStoreFromArray(listRoles);
    },

    /**
     * retrieves values from grid
     *
     * @returns {*|Array}
     */
    getFormValue: function () {
        var listRoles = this.getFromStoreAsArray(),
            result = [];

        Ext.each(listRoles, function(role) {
            result.push({
                list_role_id: role,
                contact_id: this.record,
            })
        }, this);

        return result;
    },
});


/***/ }),

/***/ 269:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListMemberRoleGridPanel
 * @extends     Ext.grid.EditorGridPanel
 * @author      Philipp Schüle <p.schuele@metaways.de>
 */
Tine.Addressbook.ListMemberRoleGridPanel = Ext.extend(Tine.widgets.grid.PickerGridPanel, {

    recordClass: Tine.Addressbook.Model.Contact,
    clicksToEdit: 1,
    enableHdMenu: false,
    autoExpandColumn: 'n_fileas',
    memberroles: null,
    memberRolesPanel: null,

    // the list record
    record: null,

    /**
     * init component
     */
    initComponent: function() {
        this.app = this.app ? this.app : Tine.Tinebase.appMgr.get('Addressbook');

        this.title = this.hasOwnProperty('title') ? this.title : this.app.i18n._('Members');
        this.plugins = this.plugins || [];
        this.plugins.push(new Ext.ux.grid.GridViewMenuPlugin({}));

        this.sm = new Ext.grid.RowSelectionModel({singleSelect:true});

        this.initColumns();
        this.store = new Ext.data.Store({
            autoSave: false,
            fields:  Tine.Addressbook.Model.Contact,
            proxy: Tine.Addressbook.contactBackend,
            reader: Tine.Addressbook.contactBackend.getReader(),
            listeners: {
                load: this.onLoad,
                beforeload: this.onBeforeLoad,
                scope: this
            }
        });

        this.addListener("beforeedit", this.onBeforeEdit, this);
        this.addListener("afteredit", this.onAfterEdit, this);

        Tine.Addressbook.ListMemberRoleGridPanel.superclass.initComponent.call(this);
    },

    /**
     * before cell edit
     *
     * @param o
     */
    onBeforeEdit: function(o) {
        var ed = this.colModel.getCellEditor(o.column, o.row);
        ed.record = o.record
    },

    /**
     * before cell edit
     *
     * @param o
     */
    onAfterEdit: function(o) {
        o.record.commit();

        // update this.memberroles + memberRolesPanel
        this.memberRolesPanel.setListRolesOfContact(o.record);
    },

    /**
     * initialises grid with an array of member uids
     */
    setMembers: function(cb, scope) {
        var options = {
            loadCb: cb || Ext.emptyFn,
            scope: scope
        };

        this.memberroles = this.record.get("memberroles");
        this.store.load(options)
    },

    onBeforeLoad: function (store, options) {
        var members = this.record.get("members") || [];

        options.params = options.params || {};
        options.params.paging = {"sort":"n_fileas","dir":"ASC"};
        options.params.filter = [
            {"field": "id", "operator": "in", "value": members}
        ];
    },

    onLoad: function(store, records, options) {
        this.store.sort("n_fileas", "ASC");
        
        if (this.memberroles) {
            this.store.each(function(contact) {
                var contactRoles = [];
                Tine.log.debug(contact);
                // TODO improve detection of matching contact (filter?)
                Ext.each(this.memberroles, function(memberrole) {
                    if (memberrole.contact_id.id == contact.get('id')
                        && memberrole.list_id == this.record.get('id')
                        && memberrole.list_role_id.id
                    )
                    {
                        contactRoles.push(memberrole);
                    }
                }, this);
                if (contactRoles.length > 0) {
                    contact.set('memberroles', contactRoles);
                    contact.commit();
                }
            }, this);

            this.memberRolesPanel.setListRoles(this.memberroles);
        }

        if (Ext.isFunction(options.loadCb)) {
            options.loadCb.call(options.scope || window);
        }
    },

    /**
     * returns current array of member uids
     *
     * @return []
     */
    getMembers: function() {
        var result = [],
            roles = null;
        this.memberroles = [];

        this.store.each(function(contact) {
            if (contact.get('id')) {
                result.push(contact.get('id'));
                if (contact.get('memberroles').length > 0) {
                    roles = contact.get('memberroles');
                    Ext.each(roles, function (role) {
                        role.contact_id = contact.get('id');
                        role.list_id = this.record.get('id');
                        this.memberroles.push(role);
                    }, this);
                }
            }
        }, this);

        return result;
    },

    /**
     * returns current array of member roles
     *
     * @return []
     */
    getMemberRoles: function() {
        return this.memberroles;
    },

    /**
     * init columns
     */
    initColumns: function() {
        this.columns = this.getColumns();
        this.editors = [];
        var visibleColumns = ["n_fileas", "email", "memberroles"];
        Ext.each(this.columns, function(value, idx) {
            if (visibleColumns.indexOf(this.columns[idx].id) === -1) {
                this.columns[idx].hidden = true;
            } else {
                this.columns[idx].width = 150;
            }
            if (this.columns[idx].id === "memberroles") {
                this.editors[idx] = new Tine.Addressbook.ListMemberRoleLayerCombo({});
                this.columns[idx].editor = this.editors[idx];
            }
        }, this);
    },

    /**
     * returns array with columns
     * 
     * @return {Array}
     */
    getColumns: function() {
        return Tine.Addressbook.ContactGridPanel.getBaseColumns(this.app.i18n).concat([
            { id: 'memberroles', header: this.app.i18n._('List Roles'), dataIndex: 'memberroles', renderer: this.listMemberRoleRenderer }
        ]);
    },

    // NOTE: Ext doc seems to be wrong on arguments here
    onContextMenu: function(e, target) {
        e.stopEvent();
        var row = this.getView().findRowIndex(target);
        var contact = this.store.getAt(row);
        if (contact) {
            // don't delete 'add' row
            if (! contact.get('id')) {
                return;
            }

            // select row
            this.getSelectionModel().selectRow(row);

            Tine.log.debug('onContextMenu - contact:');
            Tine.log.debug(contact);

            var items = [{
                text: this.app.i18n._('Remove Member'),
                iconCls: 'action_delete',
                scope: this,
                //disabled: ! this.record.get('editGrant'),
                handler: function() {
                    this.store.removeAt(row);
                }
            }, '-'];

            this.ctxMenu = new Ext.menu.Menu({
                items: items,
                plugins: [{
                    ptype: 'ux.itemregistry',
                    key:   'Tinebase-MainContextMenu'
                }],
                listeners: {
                    scope: this,
                    hide: function() {
                        this.getSelectionModel().clearSelections();
                    }
                }
            });
            this.ctxMenu.showAt(e.getXY());
        }
    },

    /**
     *list member role render
     *
     * @param value
     * @returns {string}
     * @constructor
     */
    listMemberRoleRenderer: function(value) {
        if (Ext.isArray(value)) {
            var result = [];
            Ext.each(value, function(memberrole) {
                if (memberrole.list_role_id.name) {
                    result.push(memberrole.list_role_id.name);
                }
            });
            return result.toString();
        }

        return '';
    }
});


/***/ }),

/***/ 270:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListRoleGridPanel
 * @extends     Ext.grid.EditorGridPanel
 * @author      Philipp Schüle <p.schuele@metaways.de>
 *
 * NOTE: this is currently only used in ListEditDialog. If we need a separate ListRole grid panel with toolbars, filters,
 * ... this needs to be splitted/renamed.
 */
Tine.Addressbook.ListRoleGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {

    recordClass: Tine.Addressbook.Model.ListRole,
    usePagingToolbar: false,

    autoExpandColumn: 'name',
    memberroles: null,

    // the list record
    record: null,

    // deactivate some fns
    initActions: Ext.emptyFn,
    initFilterPanel: Ext.emptyFn,

    /**
     * init component
     */
    initComponent: function() {
        this.app = this.app ? this.app : Tine.Tinebase.appMgr.get('Addressbook');

        this.gridConfig.cm = new Ext.grid.ColumnModel({
            defaults: {
                resizable: true
            },
            columns: this.getColumns()
        });

        this.title = this.app.i18n._('List Functions')

        Tine.Addressbook.ListRoleGridPanel.superclass.initComponent.call(this);
    },

    getColumns: function() {
        return [{
            id: 'id',
            header: this.app.i18n._("ID"),
            width: 50,
            sortable: true,
            dataIndex: 'id',
            hidden: true
        }, {
            id: 'name',
            header: this.app.i18n._("Name"),
            width: 100,
            sortable: true,
            dataIndex: 'name'
        }, {
            id: 'members',
            header: this.app.i18n._("Members"),
            width: 150,
            sortable: true,
            dataIndex: 'members',
            renderer: this.memberRenderer
        }];
    },

    /**
     * fill store with list roles and the members
     *
     * @param [] memberroles
     */
    setListRoles: function(memberroles) {
        Ext.each(memberroles, function(memberrole) {
            this.updateListRole(memberrole);
        }, this);
    },

    updateListRole: function(memberrole) {
        // check if already in store
        var listRoleId = memberrole.list_role_id.id;

        if (listRoleId) {
            var listRole = this.getStore().getById(listRoleId),
                insertNew = false,
                members = [],
                newMember = true;

            if (! listRole) {
                listRole = new this.recordClass(memberrole.list_role_id);
                insertNew = true;
                members = [memberrole.contact_id];
            } else {
                members = listRole.get('members');

                Ext.each(members, function(member) {
                    if (member.id == memberrole.contact_id.id) {
                        // already id
                        newMember = false;
                    }
                });

                if (! newMember) {
                    return;
                }

                members.push(memberrole.contact_id)
            }

            listRole.set('members', members);
            listRole.commit();

            if (insertNew) {
                this.getStore().insert(0, listRole);
            }
        }
    },

    /**
     * TODO implement removal of a memberrole OR reset role members after each update
     *
     * @param contact
     */
    setListRolesOfContact: function(contact) {
        Ext.each(contact.get('memberroles'), function(memberrole) {
            memberrole.contact_id = Ext.copyTo({}, contact.data, 'id,n_fn');
            this.updateListRole(memberrole);
        }, this);
    },

    memberRenderer: function(value) {
        if (Ext.isArray(value)) {
            var result = [];
            Ext.each(value, function(contact) {
                if (contact) {
                    result.push(contact.n_fn);
                }
            });
            return result.toString();
        }

        return '';
    }
});


/***/ }),

/***/ 271:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Frederic Heihoff <heihoff@sh-systems.eu>
 * @copyright   Copyright (c) 2009-2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

/*global Ext, Tine*/

Ext.ns('Tine.Addressbook');

/**
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ListEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * Addressbook Edit Dialog <br>
 * 
 * @author      Frederic Heihoff <heihoff@sh-systems.eu>
 */
Tine.Addressbook.ListEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {

    windowNamePrefix: 'ListEditWindow_',
    appName: 'Addressbook',
    recordClass: Tine.Addressbook.Model.List,
    showContainerSelector: true,
    multipleEdit: true,
    displayNotes: true,
    enablePrinting: true,

    /**
     * init component
     */
    initComponent: function () {
        this.on('load', this.resolveMemberData, this);
        this.printer = Tine.Addressbook.Printer.ListRenderer;

        this.memberGridPanel = new Tine.Addressbook.ListMemberRoleGridPanel({
            region: "center",
            frame: true,
            margins: '6 0 0 0'
        });
        this.memberRolesPanel = new Tine.Addressbook.ListRoleGridPanel({
            region: "south",
            frame: true,
            margins: '6 0 0 0',
            height: 150
        });
        this.supr().initComponent.apply(this, arguments);
    },

    getFormItems: function () {
        return {
            xtype: 'tabpanel',
            border: false,
            plain: true,
            activeTab: 0,
            plugins: [{
                ptype : 'ux.tabpanelkeyplugin'
            }],
            items: [{
                title: this.app.i18n.n_('List', 'Lists', 1),
                border: false,
                frame: true,
                layout: 'border',
                items: [{
                    region: 'center',
                    layout: 'border',
                    items: [{
                        xtype: 'fieldset',
                        region: 'north',
                        autoHeight: true,
                        title: this.app.i18n._('List Information'),
                        items: [{
                            xtype: 'panel',
                            layout: 'hbox',
                            align: 'stretch',
                            items: [{
                                flex: 1,
                                xtype: 'columnform',
                                autoHeight: true,
                                style:'padding-right: 5px;',
                                items: [[{
                                    columnWidth: 1,
                                    fieldLabel: this.app.i18n._('Name'),
                                    name: 'name',
                                    maxLength: 64
                                }],
                                [new Tine.Tinebase.widgets.keyfield.ComboBox({
                                        columnWidth: 1,
                                        fieldLabel: this.app.i18n._('List type'),
                                        name: 'list_type',
                                        app: 'Addressbook',
                                        keyFieldName: 'listType',
                                        value: ''
                                    })
                                ]]
                            }]
                        }]
                    },
                        // TODO allow user to switch between those two grid panels (card layout?)
                        this.memberGridPanel,
                        this.memberRolesPanel
                    ]
                }, {
                    // activities and tags
                    region: 'east',
                    layout: 'ux.multiaccordion',
                    animate: true,
                    width: 210,
                    split: true,
                    collapsible: true,
                    collapseMode: 'mini',
                    header: false,
                    margins: '0 5 0 5',
                    border: true,
                    items: [
                        new Ext.Panel({
                            // @todo generalise!
                            title: this.app.i18n._('Description'),
                            iconCls: 'descriptionIcon',
                            layout: 'form',
                            labelAlign: 'top',
                            border: false,
                            items: [{
                                style: 'margin-top: -4px; border 0px;',
                                labelSeparator: '',
                                xtype: 'textarea',
                                name: 'description',
                                hideLabel: true,
                                grow: false,
                                preventScrollbars: false,
                                anchor: '100% 100%',
                                emptyText: this.app.i18n._('Enter description'),
                                requiredGrant: 'editGrant'
                            }]
                        }),
                        new Tine.widgets.tags.TagPanel({
                            app: 'Addressbook',
                            border: false,
                            bodyStyle: 'border:1px solid #B5B8C8;'
                        })
                    ]
                }]
            },
            new Tine.widgets.activities.ActivitiesTabPanel({
                app: this.appName,
                record_id: (this.record && ! this.copyRecord) ? this.record.id : '',
                record_model: this.appName + '_Model_' + this.recordClass.getMeta('modelName')
            })
            ]
        };
    },
    
    /**
     * checks if form data is valid
     * 
     * @return {Boolean}
     */
    isValid: function () {
        var form = this.getForm();
        var isValid = true;
        
        // you need to fill in one of: n_given n_family org_name
        // @todo required fields should depend on salutation ('company' -> org_name, etc.)
        //       and not required fields should be disabled (n_given, n_family, etc.)
        if (form.findField('name').getValue() === '') {
            var invalidString = String.format(this.app.i18n._('{0} must be given'), this.app.i18n._('Name'));
            
            form.findField('name').markInvalid(invalidString);
            
            isValid = false;
        }
        
        return isValid && Tine.Addressbook.ListEditDialog.superclass.isValid.apply(this, arguments);
    },
    
    /**
     * onRecordLoad
     */
    resolveMemberData: function (editDialog, record, ticketFn) {
        this.memberGridPanel.record = this.record;
        if (this.record.id) {
            var ticket = ticketFn();
            this.memberGridPanel.setMembers(ticket);
            this.memberGridPanel.memberRolesPanel = this.memberRolesPanel;
        }
    },

    /**
     * onRecordUpdate
     */
    onRecordUpdate: function() {
        Tine.Addressbook.ListEditDialog.superclass.onRecordUpdate.apply(this, arguments);
        this.record.set("members", this.memberGridPanel.getMembers());
        this.record.set("memberroles", this.memberGridPanel.getMemberRoles());
    }
});

/**
 * Opens a new List edit dialog window
 * 
 * @return {Ext.ux.Window}
 */
Tine.Addressbook.ListEditDialog.openWindow = function (config) {
    
    // if a container is selected in the tree, take this as default container
    var treeNode = Ext.getCmp('Addressbook_Tree') ? Ext.getCmp('Addressbook_Tree').getSelectionModel().getSelectedNode() : null;
    if (treeNode && treeNode.attributes && treeNode.attributes.container.type) {
        config.forceContainer = treeNode.attributes.container;
    } else {
        config.forceContainer = null;
    }
    
    var id = (config.record && config.record.id) ? config.record.id : 0;
    var window = Tine.WindowFactory.getWindow({
        width: 800,
        height: 610,
        name: Tine.Addressbook.ListEditDialog.prototype.windowNamePrefix + id,
        contentPanelConstructor: 'Tine.Addressbook.ListEditDialog',
        contentPanelConstructorConfig: config
    });
    return window;
};


/***/ }),

/***/ 272:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * contacts combo box and store
 *
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiß <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 */

Ext.ns('Tine.Addressbook');

Tine.Addressbook.ListSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {

    /**
     * @cfg {Boolean} groupOnly
     */
    groupOnly: false,
    departmentOnly: false,

    //private
    initComponent: function(){
        this.app = Tine.Tinebase.appMgr.get('Addressbook');
        this.recordClass = Tine.Addressbook.Model.List;

        this.emptyText = this.emptyText || (this.groupOnly ?
            this.app.i18n._('Search for system groups ...') :
            this.app.i18n._('Search for groups ...')
        );

        this.supr().initComponent.call(this);
    },

    /**
     * use beforequery to set query filter
     *
     * @param {Event} qevent
     */
    onBeforeQuery: function(qevent){
        Tine.Addressbook.SearchCombo.superclass.onBeforeQuery.apply(this, arguments);

        var contactFilter = {condition: 'AND', filters: this.store.baseParams.filter},
            pathFilter = { field: 'path', operator: 'contains', value: qevent.query };

        this.store.baseParams.filter = [{condition: "OR", filters: [
            contactFilter,
            pathFilter
        ] }];

        if (this.groupOnly) {
            this.store.baseParams.filter.push({field: 'type', operator: 'equals', value: 'group'});
        }
        
        if (this.departmentOnly) {
            this.store.baseParams.filter.push({field: 'list_type', operator: 'equals', value: 'department'});
        }
    },

    /**
     * init template
     * @private
     */
    initTemplate: function() {
        if (! this.tpl) {
            this.tpl = new Ext.XTemplate('<tpl for=".">',
                    '<div class="x-combo-list-item">',
                        '<table>',
                            '<tr>',
                                '<td style="min-width: 20px;">{[Tine.Addressbook.ListGridPanel.listTypeRenderer(null, null, values)]}</td>',
                                '<td width="100%">{[Tine.Tinebase.EncodingHelper.encode(values.name)]}</td>',
                            '</tr>',
                        '</table>',
                        '{[Tine.widgets.path.pathsRenderer(values.paths, this.getLastQuery())]}',
                    '</div>',
                '</tpl>', {
                    getLastQuery: this.getLastQuery.createDelegate(this)
                }
            );
        }
    }
});

Tine.widgets.form.RecordPickerManager.register('Addressbook', 'List', Tine.Addressbook.ListSearchCombo);


/***/ }),

/***/ 273:
/***/ (function(module, exports) {

/* 
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2007-2008 Metaways Infosystems GmbH (http://www.metaways.de)
 */

/*global Ext, Tine*/

Ext.ns('Tine.Addressbook');

Tine.Addressbook.MapPanel = Ext.extend(Ext.Panel, {
    
    /**
     * @property
     */    
    activeMapCard: null,
    
    record: null,
    
    layout: 'fit',
    frame: true,
    
    /**
     * Company address map panel
     * @type {Tine.widgets.MapPanel}
     */
    companyMap: null,
    
    /**
     * Private address map panel
     * @type {Tine.widgets.MapPanel}
     */
    privateMap: null,
    
    initComponent: function () {
        this.app = Tine.Tinebase.appMgr.get('Addressbook');
        
        this.title = this.app.i18n._('Map');

        this.defaults = {
            border: false
        };
        
        this.mapCards = new Ext.Panel({
            layout: 'card',
            activeItem: 0,
            items: []
        });

        this.idPrefix = Ext.id();
        
        this.tbar = [{
            id: this.idPrefix + 'tglbtn' + 'companyMap',
            enableToggle: true,
            allowDepress: false,
            text: this.app.i18n._('Company address'),
            handler: this.onMapChange.createDelegate(this, ['companyMap']),
            toggleGroup: this.idPrefix + 'maptglgroup'
        }, ' ', {
            id: this.idPrefix + 'tglbtn' + 'privateMap',
            enableToggle: true,
            allowDepress: false,
            text: this.app.i18n._('Private address'),
            handler: this.onMapChange.createDelegate(this, ['privateMap']),
            toggleGroup: this.idPrefix + 'maptglgroup'
        }];
        
        this.items = this.mapCards;
        
        Tine.Addressbook.MapPanel.superclass.initComponent.call(this);
    },
    
    /**
     * Change active map card
     * 
     * @param {String} map
     */
    onMapChange: function (map) {
        this.mapCards.layout.setActiveItem(this[map]);
        this.mapCards.layout.layout();
        this.activeMapCard = this[map];
    },
    
    /**
     * Called after contact record is loaded to fill map panels
     * 
     * @param {Tine.Addressbook.Model.Contact} record
     */
    onRecordLoad: function (record) {
        this.record = record;
        
        var adrOne = ! Ext.isEmpty(this.record.get('adr_one_lon')) && ! Ext.isEmpty(this.record.get('adr_one_lat')),
            adrTwo = ! Ext.isEmpty(this.record.get('adr_two_lon')) && ! Ext.isEmpty(this.record.get('adr_two_lat')),
            
            btnOne = Ext.getCmp(this.idPrefix + 'tglbtn' + 'companyMap'),
            btnTwo = Ext.getCmp(this.idPrefix + 'tglbtn' + 'privateMap');
        
           // if we have coordinates for company address add map panel
        if (adrOne && ! this.companyMap) {
            Tine.log.debug('Add company address map');
            this.companyMap = new Tine.widgets.MapPanel({
                map: 'companyMap',
                layout: 'fit',
                zoom: 15,
                listeners: {
                    scope: this,
                    'mapAdded': function (p) {
                        if (! p.center) {
                            Tine.log.debug('Loading company address map coordinates: ' + this.record.get('adr_one_lon') + ', ' + this.record.get('adr_one_lat'));
                            p.setCenter(this.record.get('adr_one_lon'), this.record.get('adr_one_lat'));
                        }
                    }
                }
            });
            this.mapCards.add(this.companyMap);
            this.mapCards.doLayout();
        }
        
        // if we have coordinates for private address add map panel
        if (adrTwo && ! this.privateMap) {
            Tine.log.debug('Add private address map');
            this.privateMap = new Tine.widgets.MapPanel({
                map: 'privateMap',
                layout: 'fit',
                zoom: 15,
                listeners: {
                    scope: this,
                    'mapAdded': function (p) {
                        if (! p.center) {
                            Tine.log.debug('Loading private address map coordinates: ' + this.record.get('adr_two_lon') + ', ' + this.record.get('adr_two_lat'));
                            p.setCenter(this.record.get('adr_two_lon'), this.record.get('adr_two_lat'));
                        }
                    }
                }
            });
            this.mapCards.add(this.privateMap);
            this.mapCards.doLayout();
        }
            
        btnOne.toggle(adrOne);
        btnOne.setDisabled(! adrOne);
        
        btnTwo.toggle(! adrOne && adrTwo);
        btnTwo.setDisabled(! adrTwo);
    },
    
    onRecordUpdate: function (record) {
    }
});


/***/ }),

/***/ 274:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2011 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Addressbook');

/**
 * render the CardDAV Url into property panel of contianers
 * 
 * @class   Tine.Addressbook.CardDAVContainerPropertiesHookField
 * @extends Ext.form.TextField
 */
Tine.Addressbook.CardDAVContainerPropertiesHookField = Ext.extend(Ext.form.TextField, {

    anchor: '100%',
    readOnly: true,
    
    /**
     * @private
     */
    initComponent: function() {
        this.on('added', this.onContainerAdded, this);

        Tine.Addressbook.CardDAVContainerPropertiesHookField.superclass.initComponent.call(this);
    },
    
    /**
     * @private
     */
    onContainerAdded: function() {
        this.app = Tine.Tinebase.appMgr.get('Addressbook');
        this.fieldLabel = this.app.i18n._('CardDAV URL');
        
        this.propertiesDialog = this.findParentBy(function(p) {return !! p.grantContainer});
        this.grantContainer = this.propertiesDialog.grantContainer;
        
        if (this.grantContainer.application_id && this.grantContainer.application_id.name) {
            this.isAddressbook = (this.grantContainer.application_id.name == 'Addressbook');
        } else {
            this.isAddressbook = this.grantContainer.application_id === this.app.id;
        }
        
        this.hidden = ! this.isAddressbook;
        // cardDAV URL
        this.value = [
            Tine.Tinebase.common.getUrl('full').replace(/\/$/, ''), // might have an trailing /, we can safely remove it!
            '/addressbooks/',
            Tine.Tinebase.registry.get('currentAccount').contact_id,
            '/',
            this.grantContainer.id
        ].join('');
    }
    
});

Ext.ux.ItemRegistry.registerItem('Tine.widgets.container.PropertiesDialog.FormItems.Properties', Tine.Addressbook.CardDAVContainerPropertiesHookField, 100);

/***/ }),

/***/ 275:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Stefanie Stamer <s.stamer@metaways.de>
 * @copyright   Copyright (c) 2009 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.namespace('Tine.Addressbook');

/**
 * admin settings panel
 * 
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.AdminPanel
 * @extends     Ext.TabPanel
 * 
 * <p>Addressbook Admin Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Stefanie Stamer <s.stamer@metaways.de>
 * @copyright   Copyright (c) 2009 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Addressbook.AdminPanel
 */
Tine.Addressbook.AdminPanel = Ext.extend(Ext.TabPanel, {

    border: false,
    activeTab: 0,

    /**
     * @private
     */
    initComponent: function() {
        
        this.app = Tine.Tinebase.appMgr.get('Addressbook');
        
        this.items = [
            new Tine.Admin.config.GridPanel({
                configApp: this.app
            })
        ];
        
        Tine.Addressbook.AdminPanel.superclass.initComponent.call(this);
    }
});
    
/**
 * Addressbook Admin Panel Popup
 * 
 * @param   {Object} config
 * @return  {Ext.ux.Window}
 */
Tine.Addressbook.AdminPanel.openWindow = function (config) {
    var window = Tine.WindowFactory.getWindow({
        width: 600,
        height: 470,
        name: 'addressbook-admin-panel',
        contentPanelConstructor: 'Tine.Addressbook.AdminPanel',
        contentPanelConstructorConfig: config
    });
};


/***/ }),

/***/ 276:
/***/ (function(module, exports) {

Ext.ns('Tine.Addressbook.Printer');

Tine.Addressbook.Printer.ContactRenderer = Ext.extend(Ext.ux.Printer.EditDialogRenderer, {
    stylesheetPath: 'Tinebase/css/widgets/print.css',

    generateBody: function(component, data) {
        var i18n = Tine.Tinebase.appMgr.get('Addressbook').i18n;

        return new Promise(function (fulfill, reject) {
            var bodyTpl = new Ext.XTemplate(
                '<div class="rp-print-single">',
                '{[Tine.widgets.printer.headerRenderer()]}',
                '<table><tr><td>',
                '<div class="rp-print-single-image">',
                '<img src="{jpegphoto}">',
                '</div>',
                '</td><td>',
                '<div class="rp-print-single-block">',
                '<div class="rp-print-single-details-row">',
                '<span class="rp-print-single-value">{salutation} {n_prefix}</span>',
                '</div>',
                '<div class="rp-print-single-summary">',
                '<span class="adb-print-single-value">{n_fn}</span>',
                '</div>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.org_name, "Company")]}',
                '</div>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.org_unit, "Unit")]}',
                '</div>',
                '<tpl if="this.featureIndustry()">',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.industry, "Industry")]}',
                '</div>',
                '</tpl>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.title, "Job Title")]}',
                '</div>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.bday, "Birthday")]}',
                '</div>',
                '</div>',
                '</td></tr></table></br>',
                new Ext.ux.Printer.TagsRenderer().generateBody(component.getForm().findField('tags').tagsPanel),
                '<div class="cal-print-single-block-heading">', i18n._('Description'), '</div>',
                '<div class="rp-print-single-block">',
                '{[this.encode(values.note)]}',
                '</div>',
                '</br>',
                '<div class="cal-print-single-block-heading">', i18n._('Contact Information'), '</div>',
                '<div class="rp-print-single-block">',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.tel_work, "Phone")]}',
                '</div>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.tel_cell, "Mobile")]}',
                '</div>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.tel_home, "Phone (private)")]}',
                '</div>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.tel_cell_private, "Mobile (private)")]}',
                '</div>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.email, "E-Mail")]}',
                '</div>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.email_home, "E-Mail (private)")]}',
                '</div>',
                '<div class="rp-print-single-details-row">',
                '{[this.fieldRenderer(values.url, "Web")]}',
                '</div>',
                '</div>',
                '</br>',
                '<div class="cal-print-single-block-heading">', i18n._('Company Address'), '{[values.preferred_address == "0" ? (" (" + Tine.Tinebase.appMgr.get("Addressbook").i18n._("Preferred Address") + ")") : ""]}</div>',
                '<div class="rp-print-single-block">',
                "{[this.addressRenderer({'street': 'adr_one_street', 'street2': 'adr_one_street2', 'postalcode': 'adr_one_postalcode', 'locality': 'adr_one_locality', 'region': 'adr_one_region','country': 'adr_one_countryname'})]}",
                '</div>',
                '</br>',
                '<div class="cal-print-single-block-heading">', i18n._('Private Address'), '{[values.preferred_address == "1" ? (" (" + Tine.Tinebase.appMgr.get("Addressbook").i18n._("Preferred Address") + ")") : ""]}</div>',
                '<div class="rp-print-single-block">',
                "{[this.addressRenderer({'street': 'adr_two_street', 'street2': 'adr_two_street2', 'postalcode': 'adr_two_postalcode', 'locality': 'adr_two_locality', 'region': 'adr_two_region','country': 'adr_two_countryname'})]}",
                '</div>',
                '</br>',
                '{[this.customFieldRenderer(values.customfields)]}',
                '</br>',
                '<div class="cal-print-single-block-heading">', i18n._('Related to'), '</div>',
                '<div class="rp-print-single-block">',
                '{[this.relationRenderer(values.relations)]}',
                '</div>',
                '</div>',

                {
                    customFieldRenderer: function (values) {
                        return Tine.widgets.customfields.Renderer.renderAll('Addressbook', Tine.Addressbook.Model.Contact, values);
                    },
                    fieldRenderer: function (fieldValue, label) {
                        return Tine.widgets.printer.fieldRenderer('Addressbook', Tine.Addressbook.Model.Contact, fieldValue, label);
                    },
                    addressRenderer: function (config) {
                        var renderer = Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'addressblock', 'displayPanel');
                        return renderer(null, null, data, null, null, null, config);
                    },
                    relationRenderer: function (values) {
                        return Tine.widgets.relation.Renderer.renderAll(values);

                    },
                    featureIndustry: function() {
                        return Tine.Tinebase.appMgr.get('Addressbook').featureEnabled('featureIndustry');
                    }

                });
            fulfill(bodyTpl.apply(data));
        })
    }
});


/***/ }),

/***/ 277:
/***/ (function(module, exports) {

Ext.ns('Tine.Addressbook.Printer');

Tine.Addressbook.Printer.ListRenderer = Ext.extend(Ext.ux.Printer.EditDialogRenderer, {

    stylesheetPath: 'Tinebase/css/widgets/print.css',

    generateMemberBody: function(component) {
        var renderer = new Ext.ux.Printer.GridPanelRenderer();

        return new Promise(function (fulfill, reject) {
            var data = renderer.extractData(component, component.store.data.items);
            renderer.generateBody(component).then(function(bodyHtml) {
                fulfill(new Ext.XTemplate(
                    bodyHtml
                ).apply(data));
            });
        });
    },

    generateBody: function(component, data) {
        var i18n = Tine.Tinebase.appMgr.get('Addressbook').i18n;
        var me = this;

        return new Promise(function (fulfill, reject) {
            me.generateMemberBody(component.memberGridPanel).then(function(memberHtml) {
                fulfill(new Ext.XTemplate(
                    '<div class="rp-print-single">',
                    '{[Tine.widgets.printer.headerRenderer()]}',
                    '<div class="rp-print-single-summary">',
                    '<span class="adb-print-single-value">{name}</span>',
                    '</div>',
                    '<div class="rp-print-single-details-row">',
                    '{[this.fieldRenderer("", "List type")]}',
                    '{[this.keyFieldRenderer("listType", values.list_type)]}',
                    '</div>',
                    '<div class="rp-print-single-details-row">',
                    '{[this.fieldRenderer(values.description, "Description")]}',
                    '</div>',
                    '</br>',
                    memberHtml,
                    '</br>',
                    '{[this.customFieldRenderer(values.customfields)]}',
                    '{[this.relationRenderer(values.relations)]}',
                    '</div>',

                    {
                        keyFieldRenderer: function (keyField, values) {
                            return Tine.Tinebase.widgets.keyfield.Renderer.render('Addressbook', keyField, values);
                        },
                        customFieldRenderer: function (values) {
                            var customFields = '';

                            customFields = Tine.widgets.customfields.Renderer.renderAll('Addressbook', Tine.Addressbook.Model.List, values);
                            if(customFields) {
                                return '<div class="rp-print-single-block-heading">' + i18n._('Customfields') + '</div>' + customFields + '</br>';
                            }
                        },
                        fieldRenderer: function (fieldValue, label) {
                            return Tine.widgets.printer.fieldRenderer('Addressbook', Tine.Addressbook.Model.list, fieldValue, label);
                        },
                        relationRenderer: function (values) {
                            var relations = '';

                            relations = Tine.widgets.relation.Renderer.renderAll(values);
                            if (relations) {
                                return '<div class="rp-print-single-block-heading">' + i18n._('Related to') + '</div>' + relations  + '</br>';
                            }
                        }
                    }).apply(data));
            });
        });
    }
});

/***/ }),

/***/ 278:
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(279);
if(typeof content === 'string') content = [[module.i, content, '']];
// Prepare cssTransformation
var transform;

var options = {"hmr":true}
options.transform = transform
// add the styles to the DOM
var update = __webpack_require__(1)(content, options);
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../Tinebase/js/node_modules/css-loader/index.js!./Addressbook.css", function() {
			var newContent = require("!!../../Tinebase/js/node_modules/css-loader/index.js!./Addressbook.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),

/***/ 279:
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(0)(undefined);
// imports


// module
exports.push([module.i, ".action_addList {\n    background-image:url(" + __webpack_require__(280) + ") !important;\n}\n.x-btn-medium .action_addList {\n    background-image:url(" + __webpack_require__(281) + ") !important;\n}\n.x-btn-large .action_addList {\n    background-image:url(" + __webpack_require__(282) + ") !important;\n}\n\n.AddressbookIconCls, .AddressbookContact {\n    background-image:url(" + __webpack_require__(283) + ") !important;\n}\n\n.action_parseAddress {\n    background-image:url(" + __webpack_require__(36) + ") !important;\n}\n\n.x-form-item-float-left {\n    float: left;\n    margin-right: 5px;\n}\n\n.renderer_typeAccountIcon {\n    background-image:url(" + __webpack_require__(30) + ") !important;\n    background-repeat: no-repeat;\n    background-position: 2px 2px;\n    height: 16px;\n}\n\n.renderer_typeContactIcon {\n    background-image:url(" + __webpack_require__(284) + ") !important;\n    background-repeat: no-repeat;\n    background-position: 2px 2px;\n    height: 16px;\n}\n\n.renderer_typeGroupIcon, .AddressbookList{\n    background-image:url(" + __webpack_require__(285) + ") !important;\n    background-repeat: no-repeat;\n    /*background-position: 2px 2px;*/\n    /*height: 16px;*/\n}\n\n.renderer_typeListIcon {\n    background-image:url(" + __webpack_require__(286) + ") !important;\n    background-repeat: no-repeat;\n    /*background-position: 2px 2px;*/\n    /*height: 16px;*/\n}\n\n.x-grid3-cell-inner .renderer_typeAccountIcon,\n.x-grid3-cell-inner .renderer_typeContactIcon {\n    margin-bottom: -2px;\n    margin-top: -2px;\n}\n\n.renderer_displayNameRenderer_noName {\n    font-style: italic;\n    /*color: #808080;*/\n}\n\n.addressbook-search-combo table {\n    width: 100%;\n    font-size: 11px;\n    border: none;\n}\n\n.addressbook-search-combo td {\n    vertical-align: top;\n    padding-top: 4px;\n}\n\n.AddressbookStructure {\n    background-image:url(" + __webpack_require__(287) + ") !important;\n    background-repeat: no-repeat;\n}", ""]);

// exports


/***/ }),

/***/ 280:
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAADdcAAA3XAHLx6S5AAAACXZwQWcAAAAQAAAAEABcxq3DAAAGDklEQVRIx+1U709U6Rl93vf+mssMHX4sM9cR8bLICMzU7aRWE1CcNrGpwrrDGj9IWJyqS6tGrbaVrqkk4q+VGF3TajaN2aU1kXZpazBVBxJJXesgSieCAS2ShYAEFzCAM3PvzHvvfd9+EP+Gfun5cr495+R5znkA/o//MVD+ofxD+YcA+Av8Bf4CZNAiWkSLQEsH08F0EG0pOFdwruAc5qQqqUqqgn/j6/g6vs4+cAw7hh3D9HfyEfmIfARE9bH6WH0MxPAaXsMLBVJQCkpB+NSV48px5cAeS7VUS4UFo9woN8oBcU1cE9cEjH9R8qLkRQkgaIM2aAMNLLDAgkLUiTpRJ3t3Wp1Wp1XrM7bAFtgCALjBDW7owy24BbdA2EVd1EWhNVYQK4gVwBN8FB/FR/GHvrO+s76ztDayNLI0shRvkz2yR/bQH6MpNIWm4GPqp37qBxEpRCEKAUB+5Ed+ZI874864kyVpNa2m1QXfW62sVlYrv4w5qZM66ZJabUgb0oa+/CGO4iiO3v4ZEpGIRBTu6unq6ephP7mXupe6l0LNM80zzTPNtrqaUzWnak7pnUW9Rb1FvWjMG/aGvWFGJugEnaAwhRhjjDGAbWQb2UZQP+igg87ei1XGKmOVN72OHY4djh2b/7OwdmHtwlr4AzvIDrKD2r44F+finK/KbDabzeaxDpOYxCS2HnWnulPd2bIyO5IdyY7U7+ZH+VF+tLV1RBlRRpRf3dXqtXqt3ny/OFwcLg7DR2gxCx8scsdbQ+qIOqKODDSTWTJLZr97zCgxSowScluOyBE5Im5KjCZGE6Pl43aP3WP39CwXbgg3hBt/JNwsN8vN1gt6r96r9xp/Nw4YB4wDwofOJc4lziUnL5iiKZriscPsBDvBTuCXeFF4YP30+un105AsnyifKJ8AmI/OR+ej2lekhbSQFgBbra3WVsu7xAFxQBwA0Ffpq/RV859LNskm2aRLjDLK6GZ72p/2p/0AieOJ44nj+GPUjbpRN4AVskJWaMcay2E5LEdGEvWjftRPFd69373fvR9GhyqGKoYqcJoSSiih8Galgx3cU+4p93QtcCEuxIXw99PD6eH08Leh1JnUmdSZMf5NW5TfQju0Q/t3ppPPks+SzwBAAAEE3CXdl+5L9wHM3eZuc7ejzNRN3dTlv1j7rH3WPg1wsiPZkexAR/VN+iZ9ExdMXk5eTl4GIE/IE/LktgHVUA3VAGaD2WA2AKTcKXfK/a/x4j3Fe4r36H8TD4uHxcOze9OZ6cx05jecscXYYmwB4G/yN/mbFlhRK2pFAaxSq9QqjfyUxEmcxF/ttF5aL62XuPTtP5hcvL1SuL1we+H23J+LTGQi+2Ig607Wnaw7jOVN5k3mTTKmjCvjyviwt2xv2d6yvT/4zdsBzipnlbNq5SmH7JAd8rd1ufZce66dMc8lzyXPpa+jvtO+077TXM8a9xr3GjdAxt2Muxl38Y/A3mZvs7d5/Vkki2SRv7JMLVPL1JIrHcRBHIQx16Rr0jXJ3lPqlDqljv3CU+Gp8FSw3uW3lt9afot9ssy2zLbM9nCpK8+V58q76s68lnkt81rqm2whW8gWGMu/kn8l/8r8Vz7RJ/rE33/uDXgD3kDFF+sa1zWua0Q5iFd5lVcHA9wcN8fNlcX4MX6MH2NdckJOyAkUkSRJkiQ4j/twH+4DMC3TMi14//Wr169ev4J3hD6hT+iDL8V2sV1sB4MLckEuCIKwVdgqbAWgV+lVehUSbzIAZ81Ss9QshROpk6mTqZN//udiDWfiQkAICIGMDXK33C13o1xpSpqSpjARREEURLiMc3AOzkFfE4EIRECj+gP9gf4AGu0he8geoin5ofxQfgjviCvEFeIK4Rl+hB/hR6ifBmiABtg/yByZI3MmaBe1i9pFnKe1aq1a62uKUAiFUKjwU7FSrBQr5U94iZd4SfwI1+AaXCPx6Dl6jp5LMdbJOlmn+C5tok20ScB0kA7SQS7MNrANbAOs5nfxu/hd0MWf58/z5yFfaBAahAarDnOYw1z6GGyEjbCR/JrO0Bk6k/yT1Wg1Wo3jm/8LAbvjPikRY2AAAAAielRYdFNvZnR3YXJlAAB42isvL9fLzMsuTk4sSNXLL0oHADbYBlgQU8pcAAAAAElFTkSuQmCC"

/***/ }),

/***/ 281:
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWEAYAAACUJLB4AAAABmJLR0T///////8JWPfcAAAACXBIWXMAADdcAAA3XAHLx6S5AAAACXZwQWcAAAAWAAAAFgDcxelYAAAJ3UlEQVRIx+1Wa0xUZxp+vnOZGebGxTkzzDilctGBBQfQeoslUOrqNipYWwmgy+J6jTZY2airWJPtllp2TYkKLRYFTRB1rRSrNRRUisG1jjYa0fVStlQHBGuFIghzZs75vv3B6I/9vdlfff88503ePOfJm+d73xf4NX6NX+P/GuT5B7eYW8wtBmgDbaANIIwxxtiLOhZfG18bX8ttjemL6YvpIxfMheZCcyE7o4QqoUooie492nu096j6O2GnsFPYiXpNqaZUUwpBpSpVKZTWvNa81rz/oeDI/Mj8yHxA6Bf6hX6IhBFGGAKDWwa3DG4hFjvssINF0ipaRatws8vYZewyQlBqlBqlBoozz5nnzCPW7iPdR7qPMJ6kkBSSgt607rTutG5oNXc1dzV3Ife93fd239vcb7Xfa7/Xfo+/xa6JXRO7hvyBFJEiUkR1hvuG+4b7zKMeVg+rhxGCDnSgA6NNHzZ92PQhIDwX/Mj6yPrICrB6Vs/qgQ1tG9o2tOGkWCaWiWUsu1HXqGvUzWl3veV6y/VWfum0jdM2TttomCfXyXVyXXPacPlw+XD5oa2ph1IPpR5S6sO8Yd4wLzIbzjacbTiLh46XHC85XuIWmlvMLeYW+p1CFapQpP7Q+UPnD50AjuAIjkCW0+V0OZ2kCXbBLtiZB5/hM3yGENsD2wPbA4y+6HCEFCFFSAC3lFvKLeWOKxlKhpJBlygLlAXKgiUVUQ1RDVEN/1hvSDOkGdLADc0bmjc0jxaw+Ww+m88d5A5zh7nDu/ZJvMRL/Ka1dA/dQ/dwhXKn3Cl3os5gNVgNVqoMyAPygDw3Znzh+MLxhUUwp5pTzal3C/UJ+gR9wt81lgJLgaWg78+dxzqPdR4j7qcLny58upDd6Fnds7pnNfgX3kj1pHpSPUCykqwkK3xkyqmUUymnAEe2I9uRfXCau9fd6+5lLGpO1JyoOfI2qUwqk8oCcdbT1tPW04xZFlkWWRZ1VATpNta+Vvta7Wtonx41PWp6FBB9Lvpc9LnNiRPnTpw7cW4g2aV1aV1atj7hm4RvEr5hzJ3hznBndMYn6ZJ0Sbqo/OR7yfeS7wHuTHemO5MkTXZNdk12AdyLDg9EDEQMAMIJ4YRwgu0XjaJRNAK4iIu4qP90oGOgY6ADGFk6snRkqXAaxShGMV+qv6C/oL8AGJINyYZknXeMTbut+EDxgeIDeLUvpy+nLyfzLDlPzpPzZTfpPrqP7uMm+Tw+j8+jrn6Y+jD1YWpgvrfEW+Itib0d0Af0Af1u7sn1J9efXAceHX90/NFxZIZz4Vw4h9AXHr71ya1Pbn0CUFBQkHfQgx70ACN9I30jfcOtunBduC4cU2GAAQZ2nnfwDt5B3tHEaGI0McgZaRlpGWkZ+esYmzJFW62t1lYDSEISkrJ2sPVsPVuP11WDalAN9NBQ/VD9UL0QgmpUo5pfHZIYkhiSiDLFo3gUz3yqcWgcGkd8ie4r3Ve6r+6U9lT0VPRUkHsvBA/mDeYN5gFcApfAJSAPPvjgw051mbpMXfbvVeomdZO6CeAb+Ua+EXfEk+JJ8SSLp0ZqpEYCf6u/1d/qdc12zHbMdqhdXnjhBUAjaSSNjO8joSSUhALP3M/cz9zctsD4wPjAeJRrw7Rh2jBka6o0VZoqGquYFJNiErdQgQpUiO0gHOEId6cU/ehHPxfPCblCrpAL+Gf4Z/hnALIoi7LIbvo+933u+xwIyAE5ILeVKC7FpbgATuIkTuKPwQ477CzD7/Q7/U5gdO3o2tG159bdyryVeSsTiCiNKI0oBdj77H32vvCu/4D/gP8AIMfKsXIs2lCAAhQAol20i3YMqzbVptrw0dhjBWgOzaE5P9VTH/VRH0C7aBftYm8IGq/Gq/EC+AW/4Be8MeZJMpS1IGtB1gKyoCa9Jr0m/Sqjm+lmuvmBlp1hZ9iZKJkup8vpcu5D9bZ6W72N9KFzQ+eGzp29AzPMMAOPIx5HPI4A6Cw6i85qFvzb/dv9218Hzaf5NB8awSN4BA9ArpAr5Ar9Ts1QM9QMro5cI9fItebe/uL+4v7iKx+xClbBKrDC5rV5bV7axSlJSpKSRD4gbaSNtJGwn1t/bv25lQ6PCWWnsQM7sGNCCKtklawy7FvGM57xQGBqYGpgKlvCbrPb7DYgZUvZUnb8CkuWJcuSBfTf7L/Zf5N8EFYeVh5W/nGx72Xfy76XP5aYm7mZm/uWOImTOBnPWlgLa+HSA86AM+D8omT0vdH3Rt9bon1TelN6UyI2a5Q1yhrFfWQxWUwWE84/t7BRf19/X39f+Kuj0dHoaHzdJO2R9kh7Kr/UZeoydZmPs0wFpgJTAWOWq5arlqtsmTROGieNY1/YLtsu2y4zNiFkQsiEEN8rifsT9yfuP/GB64zrjOtM/rLg1CiKuR5zPeZ6BjXVmepMdepMs2JWzAo1WsOsYdYwxlzXXNdc1/Z6/msRmzcs37B8w3LMEC2iRbQQFfxKfiW/MroyVB+qD9W3W8zbzNvM2xgz5BhyDDkszdhsbDY2s5XSJGmSNInttJfZy+xljNmZndkZY/Zn9mf2Z8xjt9ltdhv7jSPaEe2IZnedOqfOqWPMZrQZbcafOIvWorVo5d8bcg25hlzGwqvDq8Or2WWrwWqwGtg2Z5WzylnFWHxnfGd8ZzdcdpfdZa+ujTkVcyrm1PSm6L3Re6P3AsLYHDv4pW+Wb5Zv1uzHLI/lsbxAiXa3drd2N56JTGQi4wqFicJEYSKJF7YIW4Qt+Be60Y1uRKIBDWggi3w/+n70/cj2DQ8ODw4P0tn8Rf4ifxHvikQkIpGG+Jn8TH4mLTM1mhpNjbRJiBfihXhykvua+5r7Gt5AZCAyEEnLn5x4cuLJifGvsCbWxJpWFtJYGktj/zhZlmRJlrZ/GlzN/eHERmzEFt6vuaG5obmBtdo12jXaNagSd4m7xF2AOCqOiqOAMEWYIkwBcAmXcAlAF7rQBTxtf9r+tB1Qi9QitQgwphhTjCmAdpV2lXYVoOnUdGo6AX4Jv4RfAhCBCEQAmId5mAdQ09V0NR0IxAXiAnGAXClXypVo99X6an21eFXeKm+Vt/qtwTl89hKXw+VwOeMkPo6P4+MQTtaRdWQd/ypZQVaQFdxfWDNrZs38JjqPzqPzuNVoRzvauTfoYrqYLuajxQaxQWwgvVwsF8vFcjuDwvXKBGWCMgHnuXaunWsXHo5tTu4qr+f1vJ6sIvfIPXKP5nK5XC6XS/cKJUKJUEK/ZSITmRg4yAIswAIj81kNq2E1/zz8/Ph5flSoQUwcA2HWGGp6x1DcH8yXBvNbwbrxQZq44HXdF+SZHDynjwYx2CAqBjfi9jEMBP/vzwnmRWMou4N1fwry6f8Ds1FpNKpmNjMAAAAielRYdFNvZnR3YXJlAAB42isvL9fLzMsuTk4sSNXLL0oHADbYBlgQU8pcAAAAAElFTkSuQmCC"

/***/ }),

/***/ 282:
/***/ (function(module, exports) {

module.exports = "data:image/png;base64, "

/***/ }),

/***/ 283:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M20.9,25.5c0,0.8-0.2,1.4-0.7,2s-1,0.8-1.7,0.8H9.1c-0.7,0-1.2-0.3-1.7-0.8s-0.7-1.2-0.7-2c0-0.8,0.1-1.5,0.2-2.2 s0.3-1.3,0.5-1.9c0.3-0.6,0.6-1.1,1.1-1.4c0.5-0.4,1.1-0.5,1.8-0.5c0.1,0,0.3,0.2,0.6,0.3s0.5,0.3,0.7,0.4c0.2,0.1,0.4,0.2,0.7,0.3 c0.3,0.1,0.5,0.2,0.8,0.3c0.3,0.1,0.5,0.1,0.8,0.1c0.3,0,0.5,0,0.8-0.1c0.3-0.1,0.5-0.1,0.8-0.3c0.3-0.1,0.5-0.2,0.7-0.3 c0.2-0.1,0.4-0.2,0.7-0.4c0.3-0.2,0.5-0.3,0.6-0.3c0.7,0,1.3,0.2,1.8,0.5c0.5,0.4,0.9,0.8,1.1,1.4c0.3,0.6,0.4,1.2,0.5,1.9 C20.8,24,20.9,24.7,20.9,25.5z M18,15.9c0,1.2-0.4,2.1-1.2,3c-0.8,0.8-1.8,1.2-3,1.2s-2.1-0.4-3-1.2s-1.2-1.8-1.2-3s0.4-2.1,1.2-3 c0.8-0.8,1.8-1.2,3-1.2s2.1,0.4,3,1.2C17.6,13.8,18,14.8,18,15.9z M35.1,24.1v1.2c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2 H23.9c-0.2,0-0.3-0.1-0.4-0.2c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h10.6 c0.2,0,0.3,0.1,0.4,0.2C35,23.8,35.1,24,35.1,24.1z M35.1,19.5v1c0,0.2-0.1,0.3-0.2,0.5c-0.1,0.1-0.3,0.2-0.5,0.2H23.9 c-0.2,0-0.3-0.1-0.5-0.2s-0.2-0.3-0.2-0.5v-1c0-0.2,0.1-0.3,0.2-0.5s0.3-0.2,0.5-0.2h10.5c0.2,0,0.3,0.1,0.5,0.2 C35,19.1,35.1,19.3,35.1,19.5z M35.1,14.7v1.2c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2H23.9c-0.2,0-0.3-0.1-0.4-0.2 c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h10.6c0.2,0,0.3,0.1,0.4,0.2S35.1,14.5,35.1,14.7z M37.4,32.4V10c0-0.2-0.1-0.3-0.2-0.4c-0.1-0.1-0.3-0.2-0.4-0.2H5c-0.2,0-0.3,0.1-0.4,0.2C4.4,9.7,4.4,9.8,4.4,10v22.4 c0,0.2,0.1,0.3,0.2,0.4C4.7,32.9,4.8,33,5,33h6.5v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2 c0.1,0.1,0.2,0.3,0.2,0.4V33H28v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2 c0.1,0.1,0.2,0.3,0.2,0.4V33h6.5c0.2,0,0.3-0.1,0.4-0.2C37.4,32.7,37.4,32.6,37.4,32.4z M39.8,10v22.4c0,0.8-0.3,1.5-0.9,2.1 c-0.6,0.6-1.3,0.9-2.1,0.9H5c-0.8,0-1.5-0.3-2.1-0.9C2.3,33.9,2,33.2,2,32.4V10c0-0.8,0.3-1.5,0.9-2.1S4.1,7,5,7h31.9 c0.8,0,1.5,0.3,2.1,0.9C39.5,8.4,39.8,9.1,39.8,10z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 284:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M29.8,18.9c0.6,0.2,1.2,0.4,1.7,0.7c0.5,0.3,1.1,0.8,1.7,1.4s1.1,1.3,1.5,2.2s0.8,1.9,1,3.3c0.3,1.3,0.4,2.8,0.4,4.5 c0,1.9-0.6,3.6-1.9,5c-1.3,1.4-2.8,2.1-4.6,2.1H13.5c-1.8,0-3.3-0.7-4.6-2.1c-1.3-1.4-1.9-3-1.9-5c0-1.7,0.1-3.1,0.4-4.5 c0.3-1.3,0.6-2.4,1-3.3S9.4,21.6,10,21c0.6-0.6,1.1-1.1,1.7-1.4c0.5-0.3,1.1-0.5,1.7-0.7c-1-1.6-1.5-3.3-1.5-5.2 c0-1.3,0.3-2.6,0.8-3.8s1.2-2.2,2.1-3.1c0.9-0.9,1.9-1.6,3.1-2.1S20.2,4,21.5,4s2.6,0.3,3.8,0.8c1.2,0.5,2.2,1.2,3.1,2.1 c0.9,0.9,1.6,1.9,2.1,3.1c0.5,1.2,0.8,2.4,0.8,3.8C31.2,15.6,30.7,17.3,29.8,18.9z M21.5,6.4c-2,0-3.7,0.7-5.1,2.1 c-1.4,1.4-2.1,3.1-2.1,5.1s0.7,3.7,2.1,5.1c1.4,1.4,3.1,2.1,5.1,2.1s3.7-0.7,5.1-2.1c1.4-1.4,2.1-3.1,2.1-5.1s-0.7-3.7-2.1-5.1 C25.3,7.1,23.6,6.4,21.5,6.4z M29.6,35.5c1.1,0,2.1-0.5,2.9-1.4c0.8-0.9,1.2-2,1.2-3.3c0-3-0.5-5.4-1.5-7.1c-1-1.7-2.4-2.7-4.3-2.7 c-1.8,1.6-4,2.4-6.4,2.4S17,22.6,15.2,21c-1.9,0.1-3.3,1-4.3,2.7c-1,1.7-1.5,4.1-1.5,7.1c0,1.3,0.4,2.4,1.2,3.3 c0.8,0.9,1.7,1.4,2.9,1.4H29.6z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 285:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M34.3,24.1v1.2c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2h-5.8c-0.2,0-0.3-0.1-0.4-0.2s-0.2-0.3-0.2-0.4v-1.2 c0-0.2,0.1-0.3,0.2-0.4s0.3-0.2,0.4-0.2h5.8c0.2,0,0.3,0.1,0.4,0.2C34.2,23.8,34.3,24,34.3,24.1z M34.3,19.5v1 c0,0.2-0.1,0.3-0.2,0.5s-0.3,0.2-0.5,0.2H28c-0.2,0-0.3-0.1-0.5-0.2s-0.2-0.3-0.2-0.5v-1c0-0.2,0.1-0.3,0.2-0.5s0.3-0.2,0.5-0.2h5.6 c0.2,0,0.3,0.1,0.5,0.2S34.3,19.3,34.3,19.5z M34.3,14.7v1.2c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2h-5.8 c-0.2,0-0.3-0.1-0.4-0.2s-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h5.8c0.2,0,0.3,0.1,0.4,0.2 S34.3,14.5,34.3,14.7z M37.4,32.4V10c0-0.2-0.1-0.3-0.2-0.4c-0.1-0.1-0.3-0.2-0.4-0.2H5c-0.2,0-0.3,0.1-0.4,0.2 C4.4,9.7,4.4,9.8,4.4,10v22.4c0,0.2,0.1,0.3,0.2,0.4C4.7,32.9,4.8,33,5,33h6.5v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2 h1.2c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4V33H28v-1.8c0-0.2,0.1-0.3,0.2-0.4s0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2 s0.2,0.3,0.2,0.4V33h6.5c0.2,0,0.3-0.1,0.4-0.2C37.4,32.7,37.4,32.6,37.4,32.4z M39.8,10v22.4c0,0.8-0.3,1.5-0.9,2.1 c-0.6,0.6-1.3,0.9-2.1,0.9H5c-0.8,0-1.5-0.3-2.1-0.9C2.3,33.9,2,33.2,2,32.4V10c0-0.8,0.3-1.5,0.9-2.1S4.1,7,5,7h31.9 c0.8,0,1.5,0.3,2.1,0.9C39.5,8.4,39.8,9.1,39.8,10z M12,20.3c-1.1,0.1-1.9,0.5-2.6,1.3H8c-0.5,0-1-0.2-1.4-0.4 C6.3,21,6.1,20.6,6.1,20c0-2.3,0.4-3.5,1.2-3.5c0.1,0,0.2,0.1,0.4,0.2C8,16.9,8.3,17,8.6,17.1c0.4,0.2,0.8,0.2,1.2,0.2 c0.4,0,0.9-0.1,1.3-0.2c-0.1,0.3-0.1,0.5-0.1,0.6C11.2,18.7,11.4,19.6,12,20.3z M22.7,26.8c0,0.8-0.3,1.4-0.7,1.9 c-0.5,0.5-1.1,0.7-1.9,0.7h-8.6c-0.8,0-1.4-0.2-1.9-0.7c-0.5-0.5-0.7-1.1-0.7-1.9c0-0.4,0-0.7,0.1-1.1C8.9,25.3,8.9,25,9,24.6 c0.1-0.4,0.2-0.7,0.3-1.1c0.1-0.3,0.3-0.6,0.4-0.9c0.2-0.3,0.4-0.6,0.6-0.8c0.2-0.2,0.5-0.4,0.8-0.5c0.3-0.1,0.7-0.2,1.1-0.2 c0.1,0,0.2,0.1,0.4,0.2c0.2,0.2,0.5,0.3,0.7,0.5c0.3,0.2,0.6,0.3,1.1,0.5s0.9,0.2,1.3,0.2c0.4,0,0.9-0.1,1.3-0.2s0.8-0.3,1.1-0.5 c0.3-0.2,0.5-0.3,0.7-0.5c0.2-0.2,0.4-0.2,0.4-0.2c0.4,0,0.8,0.1,1.1,0.2c0.3,0.2,0.6,0.3,0.8,0.5c0.2,0.2,0.4,0.5,0.6,0.8 c0.2,0.3,0.3,0.6,0.4,0.9c0.1,0.3,0.2,0.7,0.3,1.1c0.1,0.4,0.1,0.7,0.2,1.1C22.7,26.1,22.7,26.4,22.7,26.8z M12.4,14 c0,0.7-0.3,1.3-0.7,1.8s-1.1,0.7-1.8,0.7s-1.3-0.3-1.8-0.7S7.4,14.7,7.4,14s0.3-1.3,0.7-1.8c0.5-0.5,1.1-0.7,1.7-0.7 s1.3,0.3,1.8,0.7C12.1,12.7,12.4,13.3,12.4,14z M19.1,17.8c0,0.9-0.3,1.7-1,2.4c-0.7,0.7-1.5,1-2.4,1c-0.9,0-1.7-0.3-2.4-1 c-0.7-0.7-1-1.5-1-2.4s0.3-1.7,1-2.4c0.7-0.6,1.5-1,2.4-1c0.9,0,1.7,0.3,2.4,1C18.8,16.1,19.1,16.9,19.1,17.8z M25.4,20 c0,0.5-0.2,0.9-0.6,1.2c-0.4,0.3-0.8,0.4-1.4,0.4h-1.3c-0.7-0.8-1.6-1.3-2.6-1.3c0.5-0.8,0.8-1.6,0.8-2.5c0-0.2,0-0.4-0.1-0.6 c0.4,0.2,0.9,0.2,1.3,0.2c0.4,0,0.8-0.1,1.2-0.2c0.4-0.2,0.7-0.3,0.9-0.4c0.3-0.2,0.4-0.2,0.4-0.2C25,16.6,25.4,17.7,25.4,20z M24.2,14c0,0.7-0.3,1.3-0.7,1.8s-1.1,0.7-1.8,0.7c-0.7,0-1.3-0.3-1.8-0.7c-0.5-0.5-0.7-1.1-0.7-1.8s0.3-1.3,0.7-1.8 c0.5-0.5,1.1-0.7,1.8-0.7c0.7,0,1.3,0.3,1.8,0.7C23.9,12.7,24.2,13.3,24.2,14z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 286:
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAlwSFlzAAABsQAAAbEBYZgoDgAAActpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+d3d3Lmlua3NjYXBlLm9yZzwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KGMtVWAAAAhtJREFUOBHt0TtsUlEYB/DvwC2PwoV7URoplCpIU5aaaomDE47WxYG1tXFxNZ3sxKSbMXHQmEYTTUx0V+OiRhMTTRxc0FSFKqEW+rw87uPcx+c5CEhinFw9w7lfznf+v3NyD8D/8c9/gAwLL+4WJUTPAhD4cnpp5clw72/1AHh24/K0is6bYECUY5Np1Klxf+7M+UUeZLCPwScJgXp+aeXTMPYbuF1cncpmL1CXHyQ5AtXymlFeezoeFI66dbQfisFQPpZMNXVqLs/NL672EVe/mDgcj0ykUpDKzsBYMg2JI2khHjgkE593fvb4iXxyegai8WQI0L706FrB388J/UKSpVeUGucEjwHguEAMiTU6daA2aSbCHEZ/FASPFxBtiW4mOKDx7OAG47nC9Y6y2xCsJuj7P6CxWbuTzxd1WQ5/MKmhoc1hE4Ki+NpIh5v9gwcAXzBJYL1e34L1SgWabe0tX4vlCi/byt7zHozb9do9Blu8x0cXKFWrmY26cnM0fmzW8hyE0WgGMrmzt3TdvoiIAiX+Ug82lJb29Ve0N3/8vHFle7dNTQuRmg52VAM13WQ5RNOysdUx9vZ3dsrV0jv8VnrvqG31gaqap1i7ezipfN/CsagEboKADOXvyr98EPbwIyMCaBplNbuuywU+rwCW7ViUWo91rb1AKtWG5fd53REp1N3kOCzON7OEbTugtDpdMSz6/oCVZufqT1aC+bhMP8YTAAAAAElFTkSuQmCC"

/***/ }),

/***/ 287:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M20.4,15.8h1v8.3h-1V15.8z M32.2,19.6H9.5v4.5h1v-3.8h20.7v3.8h1V19.6z M6.6,28.9h6.9v-4.8H6.6V28.9z M28.2,28.9h6.9v-4.8 h-6.9C28.2,24.1,28.2,28.9,28.2,28.9z M17.4,28.9h6.9v-4.8h-6.9V28.9z M17.4,15.8h6.9V11h-6.9V15.8z M37.4,32.4V10 c0-0.2-0.1-0.3-0.2-0.4c-0.1-0.1-0.3-0.2-0.4-0.2H5c-0.2,0-0.3,0.1-0.4,0.2C4.4,9.7,4.4,9.8,4.4,10v22.4c0,0.2,0.1,0.3,0.2,0.4 C4.7,32.9,4.8,33,5,33h6.5v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4 V33H28v-1.8c0-0.2,0.1-0.3,0.2-0.4s0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2s0.2,0.3,0.2,0.4V33h6.5c0.2,0,0.3-0.1,0.4-0.2 C37.4,32.7,37.4,32.6,37.4,32.4z M39.8,10v22.4c0,0.8-0.3,1.5-0.9,2.1c-0.6,0.6-1.3,0.9-2.1,0.9H5c-0.8,0-1.5-0.3-2.1-0.9 C2.3,33.9,2,33.2,2,32.4V10c0-0.8,0.3-1.5,0.9-2.1S4.1,7,5,7h31.9c0.8,0,1.5,0.3,2.1,0.9C39.5,8.4,39.8,9.1,39.8,10z M21.4,19.6h-1 v0.7h1V19.6z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 288:
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(289);
if(typeof content === 'string') content = [[module.i, content, '']];
// Prepare cssTransformation
var transform;

var options = {"hmr":true}
options.transform = transform
// add the styles to the DOM
var update = __webpack_require__(1)(content, options);
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../Tinebase/js/node_modules/css-loader/index.js!./Contact.css", function() {
			var newContent = require("!!../../Tinebase/js/node_modules/css-loader/index.js!./Contact.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),

/***/ 289:
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(0)(undefined);
// imports


// module
exports.push([module.i, "/*\n * Tine 2.0\n *\n * @license      http://www.gnu.org/licenses/agpl.html AGPL Version 3\n * @author       Michael Spahn <m.spahn@metaways.de>\n * @copyright    Copyright (c) 2018 Metaways Infosystems GmbH (http://www.metaways.de)\n *\n */\n\n.t-contenttype-contact .action_add {\n    background-image:url(" + __webpack_require__(36) + ") !important;\n}\n\n.t-contenttype-contact .action_edit {\n    background-image:url(" + __webpack_require__(290) + ") !important;\n}\n\n.t-contenttype-contact .action_delete {\n    background-image:url(" + __webpack_require__(84) + ") !important;\n}\n\n.t-contenttype-contact .action_export {\n    background-image:url(" + __webpack_require__(291) + ") !important;\n}\n\n.t-contenttype-contact .action_import {\n    background-image:url(" + __webpack_require__(292) + ") !important;\n}", ""]);

// exports


/***/ }),

/***/ 290:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M35.4,25h2.4v7.4c0,0.8-0.3,1.5-0.9,2.1s-1.3,0.9-2.1,0.9H3c-0.8,0-1.5-0.3-2.1-0.9S0,33.2,0,32.4V10c0-0.8,0.3-1.5,0.9-2.1 S2.1,7,3,7h31.9c0.8,0,1.5,0.3,2.1,0.9s0.9,1.3,0.9,2.1v0.7h-2.4V10c0-0.2-0.1-0.3-0.2-0.4S35,9.4,34.8,9.4H3 c-0.2,0-0.3,0.1-0.4,0.2S2.4,9.8,2.4,10v22.4c0,0.2,0.1,0.3,0.2,0.4S2.8,33,3,33h6.5v-1.8c0-0.2,0.1-0.3,0.2-0.4 c0.1-0.1,0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4V33H26v-1.8c0-0.2,0.1-0.3,0.2-0.4s0.3-0.2,0.4-0.2h1.2 c0.2,0,0.3,0.1,0.4,0.2s0.2,0.3,0.2,0.4V33h6.5c0.2,0,0.3-0.1,0.4-0.2s0.2-0.3,0.2-0.4V25H35.4z M35,14.2l4.1,5.2L27,28.9l-4.6-0.6 l0.6-4.6L35,14.2z M41.8,17.2l-1.7,1.3L36,13.3l1.7-1.3c0.3-0.3,0.7-0.4,1.1-0.3s0.8,0.2,1,0.6l2.1,2.7c0.3,0.3,0.4,0.7,0.3,1.1 C42.4,16.6,42.2,16.9,41.8,17.2z M26.4,27.2l2.1-1.6l-2.1-2.7l-2.1,1.6l-0.1,0.9l1.5,0.2l-0.2,1.5L26.4,27.2z M34.9,16.5 c-0.2-0.2-0.3-0.2-0.5,0l-6.3,4.9c-0.2,0.2-0.2,0.3-0.1,0.5c0.2,0.2,0.3,0.2,0.5,0l6.3-4.9C35.1,16.9,35.1,16.7,34.9,16.5z M18.9,25.5c0,0.8-0.2,1.4-0.7,2s-1,0.8-1.7,0.8H7.1c-0.7,0-1.2-0.3-1.7-0.8s-0.7-1.2-0.7-2c0-0.8,0.1-1.5,0.2-2.2s0.3-1.3,0.5-1.9 c0.3-0.6,0.6-1.1,1.1-1.4c0.5-0.4,1.1-0.5,1.8-0.5c0.1,0,0.3,0.2,0.6,0.3s0.5,0.3,0.7,0.4c0.2,0.1,0.4,0.2,0.7,0.3 c0.3,0.1,0.5,0.2,0.8,0.3c0.3,0.1,0.5,0.1,0.8,0.1c0.3,0,0.5,0,0.8-0.1c0.3-0.1,0.5-0.1,0.8-0.3c0.3-0.1,0.5-0.2,0.7-0.3 c0.2-0.1,0.4-0.2,0.7-0.4c0.3-0.2,0.5-0.3,0.6-0.3c0.7,0,1.3,0.2,1.8,0.5c0.5,0.4,0.9,0.8,1.1,1.4c0.3,0.6,0.4,1.2,0.5,1.9 C18.8,24,18.9,24.7,18.9,25.5z M16,15.9c0,1.2-0.4,2.1-1.2,3c-0.8,0.8-1.8,1.2-3,1.2s-2.1-0.4-3-1.2s-1.2-1.8-1.2-3s0.4-2.1,1.2-3 c0.8-0.8,1.8-1.2,3-1.2s2.1,0.4,3,1.2C15.6,13.8,16,14.8,16,15.9z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 291:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M35.4,32.4c0,0.2-0.1,0.3-0.2,0.4S35,33,34.8,33h-6.5v-1.8c0-0.2-0.1-0.3-0.2-0.4s-0.3-0.2-0.4-0.2h-1.2 c-0.2,0-0.3,0.1-0.4,0.2C26,30.9,26,31,26,31.2V33H11.8v-1.8c0-0.2-0.1-0.3-0.2-0.4c-0.1-0.1-0.3-0.2-0.4-0.2H10 c-0.2,0-0.3,0.1-0.4,0.2c-0.1,0.1-0.2,0.3-0.2,0.4V33H3c-0.2,0-0.3-0.1-0.4-0.2s-0.2-0.3-0.2-0.4V10c0-0.2,0.1-0.3,0.2-0.4 S2.8,9.4,3,9.4h31.9c0.2,0,0.3,0.1,0.4,0.2s0.2,0.3,0.2,0.4v3.1h2.4V10c0-0.8-0.3-1.5-0.9-2.1S35.7,7,34.8,7H3 C2.1,7,1.4,7.3,0.9,7.9S0,9.1,0,10v22.4c0,0.8,0.3,1.5,0.9,2.1s1.3,0.9,2.1,0.9h31.9c0.8,0,1.5-0.3,2.1-0.9s0.9-1.3,0.9-2.1v-3.1 h-2.4L35.4,32.4L35.4,32.4z M42.5,21.2c0,0.3-0.1,0.5-0.3,0.7L37,27.1c-0.2,0.2-0.4,0.3-0.7,0.3s-0.5-0.1-0.7-0.3L35,26.5 c-0.2-0.2-0.3-0.4-0.3-0.7s0.1-0.5,0.3-0.7l2.3-2.3H22.2c-0.3,0-0.5-0.1-0.7-0.3c-0.2-0.2-0.3-0.4-0.3-0.7v-1c0-0.3,0.1-0.5,0.3-0.7 c0.2-0.2,0.4-0.3,0.7-0.3h15.2L35,17.3c-0.2-0.2-0.3-0.4-0.3-0.7s0.1-0.5,0.3-0.7l0.6-0.6c0.2-0.2,0.4-0.3,0.7-0.3s0.5,0.1,0.7,0.3 l5.2,5.2C42.4,20.6,42.5,20.9,42.5,21.2z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 292:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M32.2,24.1 M37.4,32.4V10c0-0.2-0.1-0.3-0.2-0.4c-0.1-0.1-0.3-0.2-0.4-0.2H5c-0.2,0-0.3,0.1-0.4,0.2C4.4,9.7,4.4,9.8,4.4,10 v22.4c0,0.2,0.1,0.3,0.2,0.4C4.7,32.9,4.8,33,5,33h6.5v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h1.2 c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4V33H28v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h1.2 c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4V33h6.5c0.2,0,0.3-0.1,0.4-0.2C37.4,32.7,37.4,32.6,37.4,32.4z M39.8,10v22.4 c0,0.8-0.3,1.5-0.9,2.1c-0.6,0.6-1.3,0.9-2.1,0.9H5c-0.8,0-1.5-0.3-2.1-0.9C2.3,33.9,2,33.2,2,32.4V10c0-0.8,0.3-1.5,0.9-2.1 S4.1,7,5,7h31.9c0.8,0,1.5,0.3,2.1,0.9C39.5,8.4,39.8,9.1,39.8,10z M23.3,21.2c0,0.3-0.1,0.5-0.3,0.7l-5.2,5.2 c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3l-0.6-0.6c-0.2-0.2-0.3-0.4-0.3-0.7s0.1-0.5,0.3-0.7l2.3-2.3H2.9 c-0.3,0-0.5-0.1-0.7-0.3C2.1,22.2,2,22,2,21.7v-1c0-0.3,0.1-0.5,0.3-0.7c0.2-0.2,0.4-0.3,0.7-0.3h15.2l-2.3-2.3 c-0.2-0.2-0.3-0.4-0.3-0.7s0.1-0.5,0.3-0.7l0.6-0.6c0.2-0.2,0.4-0.3,0.7-0.3c0.3,0,0.5,0.1,0.7,0.3l5.2,5.2 C23.2,20.6,23.3,20.9,23.3,21.2z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 293:
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(294);
if(typeof content === 'string') content = [[module.i, content, '']];
// Prepare cssTransformation
var transform;

var options = {"hmr":true}
options.transform = transform
// add the styles to the DOM
var update = __webpack_require__(1)(content, options);
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../Tinebase/js/node_modules/css-loader/index.js!./List.css", function() {
			var newContent = require("!!../../Tinebase/js/node_modules/css-loader/index.js!./List.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),

/***/ 294:
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(0)(undefined);
// imports


// module
exports.push([module.i, "/*\n * Tine 2.0\n *\n * @license      http://www.gnu.org/licenses/agpl.html AGPL Version 3\n * @author       Michael Spahn <m.spahn@metaways.de>\n * @copyright    Copyright (c) 2018 Metaways Infosystems GmbH (http://www.metaways.de)\n *\n */\n\n\n.t-contenttype-list .action_add {\n    background-image:url(" + __webpack_require__(36) + ") !important;\n}\n\n.t-contenttype-list .action_edit {\n    background-image:url(" + __webpack_require__(295) + ") !important;\n}", ""]);

// exports


/***/ }),

/***/ 295:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M35.5,25h2.4v7.4c0,0.8-0.3,1.5-0.9,2.1s-1.3,0.9-2.1,0.9H3c-0.8,0-1.5-0.3-2.1-0.9S0,33.2,0,32.4V10c0-0.8,0.3-1.5,0.9-2.1 S2.2,7,3,7h31.9c0.8,0,1.5,0.3,2.1,0.9s0.9,1.3,0.9,2.1v0.7h-2.4V10c0-0.2-0.1-0.3-0.2-0.4S35,9.4,34.9,9.4H3 c-0.2,0-0.3,0.1-0.4,0.2S2.4,9.8,2.4,10v22.4c0,0.2,0.1,0.3,0.2,0.4S2.8,33,3,33h6.5v-1.8c0-0.2,0.1-0.3,0.2-0.4 c0.1-0.1,0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4V33H26v-1.8c0-0.2,0.1-0.3,0.2-0.4s0.3-0.2,0.4-0.2h1.2 c0.2,0,0.3,0.1,0.4,0.2s0.2,0.3,0.2,0.4V33h6.5c0.2,0,0.3-0.1,0.4-0.2s0.2-0.3,0.2-0.4C35.5,32.4,35.5,25,35.5,25z M35,14.2l4.1,5.2 L27,28.9l-4.6-0.6l0.6-4.6L35,14.2z M41.9,17.2l-1.7,1.3l-4.1-5.2l1.7-1.3c0.3-0.3,0.7-0.4,1.1-0.3c0.4,0.1,0.8,0.2,1,0.6L42,15 c0.3,0.3,0.4,0.7,0.3,1.1C42.2,16.5,42.2,16.9,41.9,17.2z M26.5,27.2l2.1-1.6l-2.1-2.7l-2.1,1.6l-0.1,0.9l1.5,0.2l-0.2,1.5 L26.5,27.2z M35,16.5c-0.2-0.2-0.3-0.2-0.5,0l-6.3,4.9c-0.2,0.2-0.2,0.3-0.1,0.5c0.2,0.2,0.3,0.2,0.5,0l6.3-4.9 C35.1,16.9,35.1,16.7,35,16.5z M10,20.3c-1.1,0.1-1.9,0.5-2.6,1.3H6.1c-0.5,0-1-0.2-1.4-0.4C4.3,21,4.1,20.6,4.1,20 c0-2.3,0.4-3.5,1.2-3.5c0.1,0,0.2,0.1,0.4,0.2C6,16.9,6.3,17,6.7,17.1c0.4,0.2,0.8,0.2,1.2,0.2c0.4,0,0.9-0.1,1.3-0.2 c-0.1,0.3-0.1,0.5-0.1,0.6C9.2,18.7,9.5,19.6,10,20.3z M20.8,26.8c0,0.8-0.3,1.4-0.7,1.9s-1.1,0.7-1.9,0.7H9.5 c-0.8,0-1.4-0.2-1.9-0.7c-0.5-0.5-0.7-1.1-0.7-1.9c0-0.4,0-0.7,0.1-1.1C6.9,25.3,6.9,25,7,24.6c0.1-0.4,0.2-0.7,0.3-1.1 c0.1-0.3,0.3-0.6,0.4-0.9s0.4-0.6,0.6-0.8c0.2-0.2,0.5-0.4,0.8-0.5c0.3-0.1,0.7-0.2,1.1-0.2c0.1,0,0.2,0.1,0.4,0.2 c0.2,0.2,0.5,0.3,0.7,0.5c0.3,0.2,0.6,0.3,1.1,0.5c0.4,0.2,0.9,0.2,1.3,0.2c0.4,0,0.9-0.1,1.3-0.2c0.4-0.2,0.8-0.3,1.1-0.5 c0.3-0.2,0.5-0.3,0.7-0.5c0.2-0.2,0.4-0.2,0.4-0.2c0.4,0,0.8,0.1,1.1,0.2s0.6,0.3,0.8,0.5c0.2,0.2,0.4,0.5,0.6,0.8 c0.2,0.3,0.3,0.6,0.4,0.9c0.1,0.3,0.2,0.7,0.3,1.1c0.1,0.4,0.1,0.7,0.2,1.1C20.8,26.1,20.8,26.4,20.8,26.8z M10.5,14 c0,0.7-0.3,1.3-0.7,1.8c-0.5,0.5-1.1,0.7-1.8,0.7c-0.7,0-1.3-0.3-1.8-0.7c-0.5-0.5-0.7-1.1-0.7-1.8s0.3-1.3,0.7-1.8s1.1-0.7,1.7-0.7 s1.3,0.3,1.8,0.7S10.5,13.3,10.5,14z M17.2,17.8c0,0.9-0.3,1.7-1,2.4c-0.7,0.7-1.5,1-2.4,1c-0.9,0-1.7-0.3-2.4-1 c-0.7-0.7-1-1.5-1-2.4s0.3-1.7,1-2.4s1.5-1,2.4-1c0.9,0,1.7,0.3,2.4,1C16.9,16.1,17.2,16.9,17.2,17.8z M23.5,20 c0,0.5-0.2,0.9-0.6,1.2s-0.8,0.4-1.4,0.4h-1.3c-0.7-0.8-1.6-1.3-2.6-1.3c0.5-0.8,0.8-1.6,0.8-2.5c0-0.2,0-0.4-0.1-0.6 c0.4,0.2,0.9,0.2,1.3,0.2c0.4,0,0.8-0.1,1.2-0.2c0.4-0.2,0.7-0.3,0.9-0.4c0.3-0.2,0.4-0.2,0.4-0.2C23.1,16.6,23.5,17.7,23.5,20z M22.2,14c0,0.7-0.3,1.3-0.7,1.8c-0.5,0.5-1.1,0.7-1.8,0.7c-0.7,0-1.3-0.3-1.8-0.7c-0.5-0.5-0.7-1.1-0.7-1.8s0.3-1.3,0.7-1.8 c0.5-0.5,1.1-0.7,1.8-0.7c0.7,0,1.3,0.3,1.8,0.7C22,12.7,22.2,13.3,22.2,14z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 296:
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(297);
if(typeof content === 'string') content = [[module.i, content, '']];
// Prepare cssTransformation
var transform;

var options = {"hmr":true}
options.transform = transform
// add the styles to the DOM
var update = __webpack_require__(1)(content, options);
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../Tinebase/js/node_modules/css-loader/index.js!./Structure.css", function() {
			var newContent = require("!!../../Tinebase/js/node_modules/css-loader/index.js!./Structure.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),

/***/ 297:
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(0)(undefined);
// imports


// module
exports.push([module.i, "/*\n * Tine 2.0\n *\n * @license      http://www.gnu.org/licenses/agpl.html AGPL Version 3\n * @author       Michael Spahn <m.spahn@metaways.de>\n * @copyright    Copyright (c) 2018 Metaways Infosystems GmbH (http://www.metaways.de)\n *\n */\n\n\n.t-contenttype-structure .action_add {\n    background-image:url(" + __webpack_require__(54) + ") !important;\n}", ""]);

// exports


/***/ }),

/***/ 298:
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(299);
if(typeof content === 'string') content = [[module.i, content, '']];
// Prepare cssTransformation
var transform;

var options = {"hmr":true}
options.transform = transform
// add the styles to the DOM
var update = __webpack_require__(1)(content, options);
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../Tinebase/js/node_modules/css-loader/index.js!./Resource.css", function() {
			var newContent = require("!!../../Tinebase/js/node_modules/css-loader/index.js!./Resource.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),

/***/ 299:
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(0)(undefined);
// imports


// module
exports.push([module.i, "/*\n * Tine 2.0\n *\n * @license      http://www.gnu.org/licenses/agpl.html AGPL Version 3\n * @author       Michael Spahn <m.spahn@metaways.de>\n * @copyright    Copyright (c) 2018 Metaways Infosystems GmbH (http://www.metaways.de)\n *\n */\n\n.t-contenttype-resource .action_add {\n    background-image:url(" + __webpack_require__(54) + ") !important;\n}\n\n.t-contenttype-resource .action_edit {\n}", ""]);

// exports


/***/ }),

/***/ 30:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M21.2,4c-2.3,0-4.3,0.8-6,2.5s-2.5,3.7-2.5,6s0.8,4.3,2.5,6s3.7,2.5,6,2.5s4.3-0.8,6-2.5s2.5-3.7,2.5-6s-0.8-4.3-2.5-6 S23.5,4,21.2,4z M30.6,38c1.3,0,2.4-0.5,3.3-1.6s1.4-2.3,1.4-3.8c0-3.5-0.6-6.3-1.7-8.3s-2.8-3.1-5-3.2c-2.1,1.9-4.6,2.8-7.4,2.8 s-5.3-0.9-7.4-2.8c-2.2,0.1-3.8,1.2-5,3.2S7,29,7,32.5c0,1.5,0.5,2.8,1.4,3.8s2,1.6,3.3,1.6H30.6z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 36:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M20.9,25.5c0,0.8-0.2,1.4-0.7,2s-1,0.8-1.7,0.8H9.1c-0.7,0-1.2-0.3-1.7-0.8s-0.7-1.2-0.7-2s0.1-1.5,0.2-2.2s0.3-1.3,0.5-1.9 C7.7,20.8,8,20.3,8.5,20c0.5-0.4,1.1-0.5,1.8-0.5c0.1,0,0.3,0.2,0.6,0.3s0.5,0.3,0.7,0.4s0.4,0.2,0.7,0.3c0.3,0.1,0.5,0.2,0.8,0.3 c0.3,0.1,0.5,0.1,0.8,0.1s0.5,0,0.8-0.1s0.5-0.1,0.8-0.3c0.3-0.1,0.5-0.2,0.7-0.3c0.2-0.1,0.4-0.2,0.7-0.4c0.3-0.2,0.5-0.3,0.6-0.3 c0.7,0,1.3,0.2,1.8,0.5c0.5,0.4,0.9,0.8,1.1,1.4c0.3,0.6,0.4,1.2,0.5,1.9C20.8,24,20.9,24.7,20.9,25.5z M18,15.9 c0,1.2-0.4,2.1-1.2,3c-0.8,0.8-1.8,1.2-3,1.2s-2.1-0.4-3-1.2s-1.2-1.8-1.2-3s0.4-2.1,1.2-3c0.8-0.8,1.8-1.2,3-1.2s2.1,0.4,3,1.2 C17.6,13.8,18,14.8,18,15.9z M37.4,32.4V10c0-0.2-0.1-0.3-0.2-0.4c-0.1-0.1-0.3-0.2-0.4-0.2H5c-0.2,0-0.3,0.1-0.4,0.2 C4.4,9.7,4.4,9.8,4.4,10v22.4c0,0.2,0.1,0.3,0.2,0.4C4.7,32.9,4.8,33,5,33h6.5v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2 h1.2c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4V33H28v-1.8c0-0.2,0.1-0.3,0.2-0.4s0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2 s0.2,0.3,0.2,0.4V33h6.5c0.2,0,0.3-0.1,0.4-0.2C37.4,32.7,37.4,32.6,37.4,32.4z M39.8,10v22.4c0,0.8-0.3,1.5-0.9,2.1 c-0.6,0.6-1.3,0.9-2.1,0.9H5c-0.8,0-1.5-0.3-2.1-0.9C2.3,33.9,2,33.2,2,32.4V10c0-0.8,0.3-1.5,0.9-2.1S4.1,7,5,7h31.9 c0.8,0,1.5,0.3,2.1,0.9C39.5,8.4,39.8,9.1,39.8,10z M23.4,21.1c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4 s0.3-0.2,0.4-0.2h4.3v-4.3c0-0.2,0.1-0.3,0.2-0.4s0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2s0.2,0.3,0.2,0.4v4.3h4.3 c0.2,0,0.3,0.1,0.4,0.2s0.2,0.3,0.2,0.4v1.2c0,0.2-0.1,0.3-0.2,0.4s-0.3,0.2-0.4,0.2h-4.3v4.3c0,0.2-0.1,0.3-0.2,0.4 s-0.3,0.2-0.4,0.2h-1.2c-0.2,0-0.3-0.1-0.4-0.2s-0.2-0.3-0.2-0.4v-4.3h-4.3C23.7,21.2,23.5,21.2,23.4,21.1z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 54:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M28.3,9.8C27.8,6.5,24.7,4,21,4c-4.1,0-7.4,3-7.4,6.8c0,1,0.9,1.9,2,1.9c1.1,0,2-0.8,2-1.9c0-1.7,1.5-3.1,3.4-3.1 c1.9,0,3.4,1.4,3.4,3.1c0,2.6-7,3.6-7,3.6l0,0c-2,0.3-3.5,2-3.5,3.9V34c0,2.2,1.9,4,4.3,4h6c2.2,0,4-1.6,4.2-3.5l0,0v-0.1 c0-0.1,0-0.2,0-0.4V18.3c0-0.1,0-0.2,0-0.4v-6.8c0-0.1,0-0.2,0-0.4c0-0.2,0-0.5,0-0.7L28.3,9.8C28.4,9.8,28.4,9.8,28.3,9.8L28.3,9.8 z M27.7,27.5'/%3E %3C/svg%3E\""

/***/ }),

/***/ 82:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2007-2013 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.ns('Tine.Addressbook');

/**
 * Contact grid panel
 * 
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.ContactGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>Contact Grid Panel</p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2007-2011 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Addressbook.ContactGridPanel
 */
Tine.Addressbook.ContactGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    /**
     * record class
     * @cfg {Tine.Addressbook.Model.Contact} recordClass
     */
    recordClass: Tine.Addressbook.Model.Contact,
    
    /**
     * grid specific
     * @private
     */ 
    defaultSortInfo: {field: 'n_fileas', direction: 'ASC'},
    gridConfig: {
        autoExpandColumn: 'n_fileas',
        enableDragDrop: true,
        ddGroup: 'containerDDGroup'
    },
    copyEditAction: true,
    felamimail: false,
    multipleEdit: true,
    duplicateResolvable: true,
    
    /**
     * @cfg {Bool} hasDetailsPanel 
     */
    hasDetailsPanel: true,
    
    /**
     * inits this cmp
     * @private
     */
    initComponent: function() {
        this.recordProxy = Tine.Addressbook.contactBackend;
        
        // check if felamimail is installed and user has run right and wants to use felamimail in adb
        if (Tine.Felamimail && Tine.Tinebase.common.hasRight('run', 'Felamimail') && Tine.Felamimail.registry.get('preferences').get('useInAdb')) {
            this.felamimail = (Tine.Felamimail.registry.get('preferences').get('useInAdb') == 1);
        }
        this.gridConfig.cm = this.getColumnModel();

        if (this.hasDetailsPanel) {
            this.detailsPanel = this.getDetailsPanel();
        }

        Tine.Addressbook.ContactGridPanel.superclass.initComponent.call(this);
    },
    
    /**
     * returns column model
     * 
     * @return Ext.grid.ColumnModel
     * @private
     */
    getColumnModel: function() {
        return new Ext.grid.ColumnModel({
            defaults: {
                sortable: true,
                hidden: true,
                resizable: true
            },
            columns: this.getColumns()
        });
    },
    
    /**
     * returns array with columns
     * 
     * @return {Array}
     */
    getColumns: function() {
        return Tine.Addressbook.ContactGridPanel.getBaseColumns(this.app.i18n)
            .concat(this.getModlogColumns().concat(this.getCustomfieldColumns()));
    },
    
    /**
     * @private
     */
    initActions: function() {
        this.actions_import = new Ext.Action({
            //requiredGrant: 'addGrant',
            text: this.app.i18n._('Import contacts'),
            disabled: false,
            handler: this.onImport,
            iconCls: 'action_import',
            scope: this,
            allowMultiple: true
        });
        
        // register actions in updater
        this.actionUpdater.addActions([
            this.actions_import
        ]);
        
        Tine.Addressbook.ContactGridPanel.superclass.initActions.call(this);
    },

    /**
     * get default / selected addressbook container
     *
     * @returns {Object|Tine.Tinebase.Model.Container}
     */
    getDefaultContainer: function() {
        return this.app.getMainScreen().getWestPanel().getContainerTreePanel().getDefaultContainer('defaultAddressbook');
    },
    
    /**
     * returns details panel
     * 
     * @private
     * @return {Tine.Addressbook.ContactGridDetailsPanel}
     */
    getDetailsPanel: function() {
        return new Tine.Addressbook.ContactGridDetailsPanel({
            gridpanel: this,
            il8n: this.app.i18n,
            felamimail: this.felamimail
        });
    }
});

// Static Methods

/**
 * tid renderer
 * 
 * @private
 * @return {String} HTML
 */
Tine.Addressbook.ContactGridPanel.contactTypeRenderer = function(data, cell, record) {
    var i18n = Tine.Tinebase.appMgr.get('Addressbook').i18n,
        hasAccount = ((record.get && record.get('account_id')) || record.account_id),
        cssClass = hasAccount ? 'renderer_typeAccountIcon' : 'renderer_typeContactIcon',
        qtipText = Tine.Tinebase.common.doubleEncode(hasAccount ? i18n._('Contact of a user account') : i18n._('Contact'));
    
    return '<div ext:qtip="' + qtipText + '" style="background-position:0px;" class="' + cssClass + '">&#160</div>';
};

Tine.Addressbook.ContactGridPanel.displayNameRenderer = function(data) {
    var i18n = Tine.Tinebase.appMgr.get('Addressbook').i18n;
    return data ?  Tine.Tinebase.EncodingHelper.encode(data) : ('<div class="renderer_displayNameRenderer_noName">' + i18n._('No name') + '</div>');
};

Tine.Addressbook.ContactGridPanel.countryRenderer = function(data) {
    data = Locale.getTranslationData('CountryList', data);
    return Ext.util.Format.htmlEncode(data);
};

/**
 * Column renderer adb preferred_address field
 * @param value
 * @return {*}
 */
Tine.Addressbook.ContactGridPanel.preferredAddressRenderer = function(value) {
    var i18n = Tine.Tinebase.appMgr.get('Addressbook').i18n;

    switch (value) {
        case '0':
            return i18n._('Business');
        case '1':
            return i18n._('Private');
        default:
            return i18n._('Not set');
    }
};

/**
 * Statically constructs the columns used to represent a contact. Reused by ListMemberGridPanel + ListMemberRoleGridPanel
 */
Tine.Addressbook.ContactGridPanel.getBaseColumns = function(i18n) {
    var columns = [
        { id: 'type', header: i18n._('Type'), dataIndex: 'type', width: 30, renderer: Tine.Addressbook.ContactGridPanel.contactTypeRenderer.createDelegate(this), hidden: false },
        { id: 'tags', header: i18n._('Tags'), dataIndex: 'tags', width: 50, renderer: Tine.Tinebase.common.tagsRenderer, sortable: false, hidden: false  },
        { id: 'salutation', header: i18n._('Salutation'), dataIndex: 'salutation', renderer: Tine.Tinebase.widgets.keyfield.Renderer.get('Addressbook', 'contactSalutation') },
        {
            id: 'container_id',
            dataIndex: 'container_id',
            header: Tine.Addressbook.Model.Contact.getContainerName(),
            width: 150,
            renderer: Tine.Tinebase.common.containerRenderer
        },
        { id: 'n_prefix', header: i18n._('Title'), dataIndex: 'n_prefix', width: 80 },
        { id: 'n_middle', header: i18n._('Middle Name'), dataIndex: 'n_middle', width: 80 },
        { id: 'n_family', header: i18n._('Last Name'), dataIndex: 'n_family' },
        { id: 'n_given', header: i18n._('First Name'), dataIndex: 'n_given', width: 80 },
        { id: 'n_fn', header: i18n._('Full Name'), dataIndex: 'n_fn', renderer: Tine.Addressbook.ContactGridPanel.displayNameRenderer },
        { id: 'n_fileas', header: i18n._('Display Name'), dataIndex: 'n_fileas', hidden: false, renderer: Tine.Addressbook.ContactGridPanel.displayNameRenderer},
        { id: 'org_name', header: i18n._('Company'), dataIndex: 'org_name', width: 120, hidden: false },
        { id: 'org_unit', header: i18n._('Unit'), dataIndex: 'org_unit'  },
        { id: 'title', header: i18n._('Job Title'), dataIndex: 'title' },
//            { id: 'role', header: i18n._('Job Role'), dataIndex: 'role' },
//            { id: 'room', header: i18n._('Room'), dataIndex: 'room' },
        { id: 'adr_one_street', header: i18n._('Street'), dataIndex: 'adr_one_street' },
        { id: 'adr_one_locality', header: i18n._('City'), dataIndex: 'adr_one_locality', width: 150, hidden: false },
        { id: 'adr_one_region', header: i18n._('Region'), dataIndex: 'adr_one_region' },
        { id: 'adr_one_postalcode', header: i18n._('Postalcode'), dataIndex: 'adr_one_postalcode' },
        { id: 'adr_one_countryname', header: i18n._('Country'), dataIndex: 'adr_one_countryname', renderer: Tine.Addressbook.ContactGridPanel.countryRenderer },
        { id: 'adr_two_street', header: i18n._('Street (private)'), dataIndex: 'adr_two_street' },
        { id: 'adr_two_locality', header: i18n._('City (private)'), dataIndex: 'adr_two_locality' },
        { id: 'adr_two_region', header: i18n._('Region (private)'), dataIndex: 'adr_two_region' },
        { id: 'adr_two_postalcode', header: i18n._('Postalcode (private)'), dataIndex: 'adr_two_postalcode' },
        { id: 'adr_two_countryname', header: i18n._('Country (private)'), dataIndex: 'adr_two_countryname', renderer: Tine.Addressbook.ContactGridPanel.countryRenderer },
        { id: 'preferred_address', header: i18n._('Preferred Address'), dataIndex: 'preferred_address', renderer: Tine.Addressbook.ContactGridPanel.preferredAddressRenderer },
        { id: 'email', header: i18n._('Email'), dataIndex: 'email', width: 150, hidden: false },
        { id: 'tel_work', header: i18n._('Phone'), dataIndex: 'tel_work', hidden: false },
        { id: 'tel_cell', header: i18n._('Mobile'), dataIndex: 'tel_cell', hidden: false },
        { id: 'tel_fax', header: i18n._('Fax'), dataIndex: 'tel_fax' },
        { id: 'tel_car', header: i18n._('Car phone'), dataIndex: 'tel_car' },
        { id: 'tel_pager', header: i18n._('Pager'), dataIndex: 'tel_pager' },
        { id: 'tel_home', header: i18n._('Phone (private)'), dataIndex: 'tel_home' },
        { id: 'tel_fax_home', header: i18n._('Fax (private)'), dataIndex: 'tel_fax_home' },
        { id: 'tel_cell_private', header: i18n._('Mobile (private)'), dataIndex: 'tel_cell_private' },
        { id: 'email_home', header: i18n._('Email (private)'), dataIndex: 'email_home' },
        { id: 'url', header: i18n._('Web'), dataIndex: 'url' },
        { id: 'url_home', header: i18n._('URL (private)'), dataIndex: 'url_home' },
        { id: 'note', header: i18n._('Note'), dataIndex: 'note' },
        { id: 'tz', header: i18n._('Timezone'), dataIndex: 'tz' },
        { id: 'geo', header: i18n._('Geo'), dataIndex: 'geo' },
        { id: 'bday', header: i18n._('Birthday'), dataIndex: 'bday', renderer: Tine.Tinebase.common.dateRenderer },
        { id: 'memberroles', header: i18n._('List Roles'), dataIndex: 'memberroles', renderer: Tine.Addressbook.ListMemberRoleRenderer }
    ];

    if (Tine.Tinebase.appMgr.get('Addressbook').featureEnabled('featureIndustry')) {
        columns.push({ id: 'industry', header: i18n._('Industry'), dataIndex: 'industry', renderer: Tine.Tinebase.common.foreignRecordRenderer});
    }
    
    return columns;
};


/***/ }),

/***/ 83:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * contacts combo box and store
 * 
 * @package     Addressbook
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Addressbook');

/**
 * contact selection combo box
 * 
 * @namespace   Tine.Addressbook
 * @class       Tine.Addressbook.SearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * <p>Contact Search Combobox</p>
 * <p><pre>
 * TODO         make this a twin trigger field with 'clear' button?
 * TODO         add switch to filter for expired/enabled/disabled user accounts
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2011 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Addressbook.SearchCombo
 * 
 * TODO         add     forceSelection: true ?
 */
Tine.Addressbook.ContactSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    /**
     * @cfg {Boolean} userOnly
     */
    userOnly: false,

    /**
     * @cfg {Boolean} addPathFilter
     */
    addPathFilter: true,

    /**
     * use account objects/records in get/setValue
     * 
     * @cfg {Boolean} legacy
     * @legacy
     * 
     * TODO remove this later
     */
    useAccountRecord: false,
    allowBlank: false,
    
    itemSelector: 'div.search-item',
    minListWidth: 350,
    
    //private
    initComponent: function(){
        this.app = Tine.Tinebase.appMgr.get('Addressbook');

        if (this.recordClass === null) {
            this.recordClass = Tine.Addressbook.Model.Contact;
            this.recordProxy = Tine.Addressbook.contactBackend;
        }

        this.emptyText = this.emptyText || (this.readOnly || this.disabled ? '' : (this.userOnly ?
            this.app.i18n._('Search for users ...') :
            this.app.i18n._('Search for Contacts ...')
        ));

        this.initTemplate();
        Tine.Addressbook.SearchCombo.superclass.initComponent.call(this);
    },
    
    /**
     * is called in accountMode to reset the value
     * @param value
     */
    processValue: function(value) {
        if (this.useAccountRecord) {
            if (value == '') {
                this.accountId = null;
                this.selectedRecord = null;
            }
        }
        return Tine.Addressbook.SearchCombo.superclass.processValue.call(this, value);
    },

    /**
     * use beforequery to set query filter
     * 
     * @param {Event} qevent
     */
    onBeforeQuery: function(qevent){
        Tine.Addressbook.SearchCombo.superclass.onBeforeQuery.apply(this, arguments);

        var contactFilter = {condition: 'AND', filters: this.store.baseParams.filter};

        if (this.addPathFilter) {
            var pathFilter = {field: 'path', operator: 'contains', value: qevent.query};

            this.store.baseParams.filter = [{
                condition: "OR", filters: [
                    contactFilter,
                    pathFilter
                ]
            }];
        } else {
            this.store.baseParams.filter = [contactFilter];
        }

        if (this.userOnly) {
            this.store.baseParams.filter.push({field: 'type', operator: 'equals', value: 'user'});
        }
    },
    
    /**
     * init template
     * @private
     */
    initTemplate: function() {
        // Custom rendering Template
        if (! this.tpl) {
            this.tpl = new Ext.XTemplate(
                '<tpl for="."><div class="search-item addressbook-search-combo x-combo-list-item">',
                    '<table>',
                        '<tr>',
                            '<td style="min-width: 20px;">{[Tine.Addressbook.ContactGridPanel.contactTypeRenderer(null, null, values)]}</td>',
                            '<td width="30%"><b>{[Tine.Addressbook.ContactGridPanel.displayNameRenderer(values.n_fileas)]}</b><br/>,' +
                                '{[Tine.Tinebase.EncodingHelper.encode(values.org_name)]}</td>',
                            '<td width="25%">{[Tine.Tinebase.EncodingHelper.encode(values.adr_one_street)]}<br/>',
                                '{[Tine.Tinebase.EncodingHelper.encode(values.adr_one_postalcode)]} {[this.encode(values.adr_one_locality)]}</td>',
                            '<td width="25%">{[Tine.Tinebase.EncodingHelper.encode(values.tel_work)]}<br/>{[Tine.Tinebase.EncodingHelper.encode(values.tel_cell)]}</td>',
                            '<td width="50px">',
                                '<img width="45px" height="39px" src="{jpegphoto}" />',
                            '</td>',
                        '</tr>',
                    '</table>',
                    '{[Tine.widgets.path.pathsRenderer(values.paths, this.getLastQuery())]}',
                '</div></tpl>', {
                    getLastQuery: this.getLastQuery.createDelegate(this)
                }
            );
        }
    },
    
    getValue: function() {
        if (this.useAccountRecord) {
            if (this.selectedRecord) {
                return this.selectedRecord.get('account_id');
            } else {
                return this.accountId;
            }
        } else {
            return Tine.Addressbook.SearchCombo.superclass.getValue.call(this);
        }
    },

    setValue: function (value) {
        if (this.useAccountRecord) {
            if (value) {
                if(value.accountId) {
                    // account object
                    this.accountId = value.accountId;
                    value = value.accountDisplayName;
                } else if (typeof(value.get) == 'function') {
                    // account record
                    this.accountId = value.get('id');
                    value = value.get('name');
                }
            } else {
                this.accountId = null;
                this.selectedRecord = null;
            }
        }
        return Tine.Addressbook.SearchCombo.superclass.setValue.call(this, value);
    }

});

// legacy
Tine.Addressbook.SearchCombo = Tine.Addressbook.ContactSearchCombo;

Ext.reg('addressbookcontactpicker', Tine.Addressbook.ContactSearchCombo);
Tine.widgets.form.RecordPickerManager.register('Addressbook', 'Contact', Tine.Addressbook.ContactSearchCombo);


/***/ }),

/***/ 84:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M32.2,24.1 M37.4,32.4V10c0-0.2-0.1-0.3-0.2-0.4c-0.1-0.1-0.3-0.2-0.4-0.2H5c-0.2,0-0.3,0.1-0.4,0.2C4.4,9.7,4.4,9.8,4.4,10 v22.4c0,0.2,0.1,0.3,0.2,0.4C4.7,32.9,4.8,33,5,33h6.5v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h1.2 c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4V33H28v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h1.2 c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4V33h6.5c0.2,0,0.3-0.1,0.4-0.2C37.4,32.7,37.4,32.6,37.4,32.4z M39.8,10v22.4 c0,0.8-0.3,1.5-0.9,2.1c-0.6,0.6-1.3,0.9-2.1,0.9H5c-0.8,0-1.5-0.3-2.1-0.9C2.3,33.9,2,33.2,2,32.4V10c0-0.8,0.3-1.5,0.9-2.1 S4.1,7,5,7h31.9c0.8,0,1.5,0.3,2.1,0.9C39.5,8.4,39.8,9.1,39.8,10z M28.3,26.8L27.1,28c-0.2,0.2-0.4,0.2-0.6,0.2s-0.4-0.1-0.6-0.2 l-5-5l-5,5c-0.2,0.2-0.4,0.2-0.6,0.2s-0.4-0.1-0.6-0.2l-1.2-1.2c-0.2-0.2-0.2-0.4-0.2-0.6c0-0.2,0.1-0.4,0.2-0.6l5-5l-5-5 c-0.2-0.2-0.2-0.4-0.2-0.6s0.1-0.4,0.2-0.6l1.2-1.2c0.2-0.2,0.4-0.2,0.6-0.2s0.4,0.1,0.6,0.2l5,5l5-5c0.2-0.2,0.4-0.2,0.6-0.2 s0.4,0.1,0.6,0.2l1.2,1.2c0.2,0.2,0.2,0.4,0.2,0.6s-0.1,0.4-0.2,0.6l-5,5l5,5c0.2,0.2,0.2,0.4,0.2,0.6 C28.6,26.4,28.5,26.6,28.3,26.8z'/%3E %3C/svg%3E\""

/***/ })

/******/ });
});