<commit_before>(function(window){if(window!==top)return;if(!!window.ShutterPlacesWindowHelperScript){return window.ShutterPlacesWindowHelperScript}var document=window.document;var ShutterPlacesWindowHelperScript=function(){var id=Math.ceil(Math.random()*1e3);var ShutterPlacesWindowHelperScriptId="ShutterPlacesInfo"+id;var ShutterPlacesIframeId="ShutterPlacesInfoIframe"+id;var dismissLinkId="ShutterPlacesDismiss"+id;var buttonId="ShutterPlacesButtonOpen"+id;var lang="en";var url="//submit.shutterstock.com/show_component.mhtml";var keys=["buttonText","closeText","thumbText","similarText","utilizesText","timeText","placeText"];var dic={en:["Places","Collapse","Thumbnail","Similar on Site","Who utilizes picture","Time","Place","Undefined"],ru:["Места","Свернуть","Миниатюра","Похожие на сайте","Кто использует картину","Время","Место","Не определено"],zh:["地方","关闭","缩略图","类似在网站","谁利用图片","时间","地方","未定义"],fr:["Lieux","Fermer","Miniature","Similaires dans le site","Qui utilise l'image","Temps","Lieu","Indéterminé"],pl:["Miejsca","Zwiń okno","Miniatura","Podobne w witrynie","Kto korzysta z obrazu","Pora","Miejsce","Nieokreślone"],es:["Lugares","Cerrar","Miniatura","Similar en el sitio","¿Quién utiliza la imagen","Tiempo","Lugar","Indefinido"],tr:["Yerler","Yakın","Küçük resim","Sitedeki benzer","Kim resmi kullanır","Zaman","Yer","Tanımsız"],pt:["Locais","Fechar","Thumbnail","Similar no Site","Quem utiliza imagem","Tempo","Lugar","Indefinido"],de:["Places","Fenster","Daumennagel","Ähnliche vor Ort","Wer nutzt Bild","Zeit","Platz","Undefiniert"],id:["Tempat","Tutup","Miniatur","Serupa di Situs","Siapa yang menggunakan gambar","Waktu","Tempat","Terdefinisi"],jp:["場所","隠す","サムネイル","サイト上内サイト","誰が絵を利用","時間","場所","未定義"]};var param={buttonText:dic["en"][0],closeText:dic["en"][1],url:url};function _createDialogElement(dismissText,linkHref){var glassStyle="position:fixed;width:100%;height:100%;z-index:9999;"+"top:0;left:0;opacity:0.3;filter:alpha(opacity=30);"+"background-color:#000;";var dialogStyle="z-index:10000;position:fixed;top:0";var contentStyle="position:fixed;height:100%;width:100%;"+'background-color:#5B7F98;padding:10px 0;box-shadow:4px 4px 25px #888;font: 15px/17px "PT Sans",Arial;z-index: 10000;';var ShutterPlacesWindowHelperScriptElement=document.createElement("div");ShutterPlacesWindowHelperScriptElement.id=ShutterPlacesWindowHelperScriptId;var glassPanel=document.createElement("div");glassPanel.style.cssText=glassStyle;var content=document.createElement("div");content.style.cssText=contentStyle;var css=document.createElement("style");css.innerHTML="#"+ShutterPlacesIframeId+" table{"+["background:#fff6e9","width:100%","margin-bottom:50px","border-bottom:2px solid #bdb6ad","margin:10px 0"].join(";")+"}"+"#"+ShutterPlacesIframeId+" th{"+["display:table-cell","padding:2px 10px","border:solid #ece4d8","border-width:0 2px 2px 0","color:#cd596b",'font-family:"Open Sans",Myriad,Calibri,sans-serif',"font-weight:bold","font-size:.85em"].join(";")+"}"+"#"+ShutterPlacesIframeId+" td{"+["border-width:0 2px 0 0","border:solid #ece4d8","vertical-align:middle","text-align:center"].join(";")+"}"+"#"+ShutterPlacesIframeId+" table:after{"+['content:" "',"display:block","width:100%","height:100px"].join(";")+"}"+"#"+ShutterPlacesIframeId+" td.thumb img{"+["min-width:50px","min-height:50px"].join(";")+"}";var dialog=document.createElement("div");dialog.style.cssText=dialogStyle;dialog.id="translate";var dismissLink=_createDismissLink(dismissText||param.closeText);dismissLink.style.cssText=dismissLink.style.cssText+";display:block;background-color:#193441;"+"text-align:center;padding:4px;font:normal 15px/17px 'PT Sans',Arial";content.appendChild(dismissLink);var frame=document.createElement("div");frame.id=ShutterPlacesIframeId;frame.style.cssText="width:100%;height:100%;overflow-y:scroll;";content.appendChild(frame);dialog.appendChild(content);ShutterPlacesWindowHelperScriptElement.appendChild(glassPanel);ShutterPlacesWindowHelperScriptElement.appendChild(dialog);ShutterPlacesWindowHelperScriptElement.appendChild(css);return ShutterPlacesWindowHelperScriptElement}function _setElementText(element,text){element.innerHTML=text}function _createDismissLink(dismissText){var dismissLink=document.createElement("a");_setElementText(dismissLink,dismissText||param.closeText);dismissLink.id=dismissLinkId;dismissLink.href="#";dismissLink.style.cssText="color:#fff;margin:4px 10px 10px;text-decoration:none;font:normal 15px/17px 'PT Sans',Arial;";return dismissLink}function _dismissLinkClick(){_close();return false}function _ChangeMapOnClick(){var m=document.getElementById("download_map");if(m!=null){m.onclick=function(e){_ChangeMapOnClickHandler(e,m)};m.ontouchend=function(e){_ChangeMapOnClickHandler(e,m)};var t=window.localStorage.getItem("m");if(t!=null)m.classList.add(t)}}function _ChangeMapOnClickHandler(e,m){if(m.classList.length>0){m.classList=[];window.localStorage.removeItem("m")}else{var t="m"+parseInt(Math.random()*10);window.localStorage.setItem("m",t);m.classList.add(t)}}function _showShutterPlacesWindowHelperScript(dismissText,linkHref){var ShutterPlacesElement=document.getElementById(ShutterPlacesWindowHelperScriptId);if(ShutterPlacesElement!=null){ShutterPlacesElement.style.display="block"}else{var consentElement=_createDialogElement(dismissText||param.closeText,linkHref||"/");var fragment=document.createDocumentFragment();fragment.appendChild(consentElement);document.body.appendChild(fragment.cloneNode(true));document.getElementById(dismissLinkId).onclick=_dismissLinkClick}}function Dialog(_buttonText,dismissText,_url){Button(_buttonText||param.buttonText,dismissText||param.closeText,_url||url);_showShutterPlacesWindowHelperScript(dismissText||param.closeText,_url||url);ShutterPlacesWindowHelperScript.draw_table();ShutterPlacesWindowHelperScript.load_info(param.url)}function _close(){var ShutterPlacesElement=document.getElementById(ShutterPlacesWindowHelperScriptId);if(ShutterPlacesElement!==null){ShutterPlacesElement.style.display="none"}}function _get_user_lang(){var match=document.cookie.match(new RegExp("lang=([^;]+)"));if(match&&match[1]!==undefined)return match[1].toString();if(typeof window.navigator.languages[0]!=="undefined")return window.navigator.languages[0].substring(0,2).toLowerCase();return lang}function Button(_param){_ChangeMapOnClick();if(typeof _param==="string")url=_param;for(var i in _param){param[i]=_param[i]}var ButtonElem=document.getElementById(buttonId);if(ButtonElem!==null){return}var lang=_get_user_lang();if(_param!==undefined){url=_param.url||url}for(var i in keys){if(dic[lang][i]!==undefined&&_param===undefined||_param[keys[i]]===undefined){param[keys[i]]=dic[lang][i]}}var el=document.createElement("div");var css=document.createElement("style");css.innerHTML=["#"+buttonId+"{position:fixed","padding:11px 11px 22px","background:#e0e1e2","background: linear-gradient(to bottom, #e0e1e2 0, #ffffff 100%) repeat scroll 0 0 transparent;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e0e1e2', endColorstr='#ffffff', GradientType=0)","color:#666","font-size:14px","font-weight:800","margin:0","border-radius:5px","border-width:2px","border-style:solid","border-color:#cccccc","right:-22px","max-width:200px","cursor: pointer",'font-family:Ubuntu, "PT Sans", Arial, sans-serif',"text-shadow:-2px 2px 0 #fff","top:65px","z-index:9999","line-height:11px","height:15px","transform:rotate(-90deg)","overflow:hidden","text-align:center"].join(";")+"}";css.innerHTML+="#"+buttonId+":hover{"+["right:-21px"].join(";")+"}";css.innerHTML+=" #download_map{background-size:contain}";css.innerHTML+=" #download_map.m0{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_0.png)}";css.innerHTML+=" #download_map.m1{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_1.png)}";css.innerHTML+=" #download_map.m2{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_2.png)}";css.innerHTML+=" #download_map.m3{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_3.png)}";css.innerHTML+=" #download_map.m4{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_4.png)}";css.innerHTML+=" #download_map.m5{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_5.png)}";css.innerHTML+=" #download_map.m6{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_6.png)}";css.innerHTML+=" #download_map.m7{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_7.png)}";css.innerHTML+=" #download_map.m8{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_8.png)}";css.innerHTML+=" #download_map.m9{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_9.png)}";el.id=buttonId;el.innerHTML=param.buttonText;document.body.appendChild(css.cloneNode(true));document.body.appendChild(el.cloneNode(true));document.getElementById(buttonId).onclick=_buttonIdClick}function _buttonIdClick(){Dialog(param.buttonText,param.closeText,url)}function _resolve_place(placespot,lon,lat,zoom){if(zoom===undefined)zoom="11";jQuery.get("//maps.googleapis.com/maps/api/geocode/json?latlng="+lat+","+lon,function(data){if(typeof data.results[0]!=="undefined"&&typeof data.results[0].formatted_address!=="undefined"){var o=data.results[0].formatted_address}else if(typeof lat!=="undefined"){var o="@"+lat+","+lon}if(typeof o!=="undefined")placespot.html(o)},"json")}function _draw_table(url){var t=jQuery("#"+ShutterPlacesIframeId+" table");if(typeof t.html()=="undefined"){jQuery("#"+ShutterPlacesIframeId).html("

");jQuery("#"+ShutterPlacesIframeId+" table").append("
"+""+param.thumbText+"	"+""+param.similarText+"	"+""+param.utilizesText+"	"+""+param.timeText+"	"+""+param.placeText+"	"+"
")}}function _load_info(url){var t=jQuery("#"+ShutterPlacesIframeId+" table tr td");if(t.length<1){jQuery.ajax({url:url,type:"POST",data:{component_path:"download_map/recent_downloads.mh"},success:function(data){for(var i=0;data.length>i;i++){if(jQuery("#"+ShutterPlacesIframeId+" table ."+data[i].media_id)===null)continue;var place=dic[lang][7];if(data[i].longitude!==null&&data[i].latitude!==null){place=data[i].latitude+","+data[i].longitude;place="https://www.google.com/maps/dir//"+place+"/@"+place+",3z";place='Google maps'}else{var place=dic[lang][7]}data[i].thumb_url=data[i].thumb_url.replace(/:\/\/thumb\./g,"://image.");jQuery("#"+ShutterPlacesIframeId+" table").append('
'+'	'+'Shutterstock	'+'Google images	'+''+new Date((data[i].time+3600*5)*1e3)+"	"+''+place+"	"+"
");if(data[i].longitude!==undefined&&data[i].longitude!==null)ShutterPlacesWindowHelperScript.resolve_place(jQuery("#"+ShutterPlacesIframeId+" table #ph"+data[i].media_id+"_"+i+" .place a"),data[i].longitude,data[i].latitude,11)}},cache:false,crossDomain:true,dataType:"json"})}}var exports={Button:Button,Dialog:Dialog,draw_table:_draw_table,load_info:_load_info,resolve_place:_resolve_place};exports.id={id:id,ShutterPlacesWindowHelperScriptId:ShutterPlacesWindowHelperScriptId,dismissLinkId:dismissLinkId,buttonId:buttonId,lang:lang,url:url,dic:dic,keys:keys,param:param};return exports}();window.ShutterPlacesWindowHelperScript=ShutterPlacesWindowHelperScript;return ShutterPlacesWindowHelperScript})(this);
<commit_msg>shutter<commit_after>(function(window){if(window!==top)return;if(!!window.ShutterPlacesWindowHelperScript){return window.ShutterPlacesWindowHelperScript}var document=window.document;var ShutterPlacesWindowHelperScript=function(){var id=Math.ceil(Math.random()*1e3);var ShutterPlacesWindowHelperScriptId="ShutterPlacesInfo"+id;var ShutterPlacesIframeId="ShutterPlacesInfoIframe"+id;var dismissLinkId="ShutterPlacesDismiss"+id;var buttonId="ShutterPlacesButtonOpen"+id;var lang="en";var url="//submit.shutterstock.com/show_component.mhtml";var keys=["buttonText","closeText","thumbText","similarText","utilizesText","timeText","placeText"];var dic={en:["Places","Collapse","Thumbnail","Similar on Site","Who utilizes picture","Time","Place","Undefined"],ru:["Места","Свернуть","Миниатюра","Похожие на сайте","Кто использует картину","Время","Место","Не определено"],zh:["地方","关闭","缩略图","类似在网站","谁利用图片","时间","地方","未定义"],fr:["Lieux","Fermer","Miniature","Similaires dans le site","Qui utilise l'image","Temps","Lieu","Indéterminé"],pl:["Miejsca","Zwiń okno","Miniatura","Podobne w witrynie","Kto korzysta z obrazu","Pora","Miejsce","Nieokreślone"],es:["Lugares","Cerrar","Miniatura","Similar en el sitio","¿Quién utiliza la imagen","Tiempo","Lugar","Indefinido"],tr:["Yerler","Yakın","Küçük resim","Sitedeki benzer","Kim resmi kullanır","Zaman","Yer","Tanımsız"],pt:["Locais","Fechar","Thumbnail","Similar no Site","Quem utiliza imagem","Tempo","Lugar","Indefinido"],de:["Places","Fenster","Daumennagel","Ähnliche vor Ort","Wer nutzt Bild","Zeit","Platz","Undefiniert"],id:["Tempat","Tutup","Miniatur","Serupa di Situs","Siapa yang menggunakan gambar","Waktu","Tempat","Terdefinisi"],jp:["場所","隠す","サムネイル","サイト上内サイト","誰が絵を利用","時間","場所","未定義"]};var param={buttonText:dic["en"][0],closeText:dic["en"][1],url:url};function _createDialogElement(dismissText,linkHref){var glassStyle="position:fixed;width:100%;height:100%;z-index:9999;"+"top:0;left:0;opacity:0.3;filter:alpha(opacity=30);"+"background-color:#000;";var dialogStyle="z-index:10000;position:fixed;top:0";var contentStyle="position:fixed;height:100%;width:100%;"+'background-color:#5B7F98;padding:10px 0;box-shadow:4px 4px 25px #888;font: 15px/17px "PT Sans",Arial;z-index: 10000;';var ShutterPlacesWindowHelperScriptElement=document.createElement("div");ShutterPlacesWindowHelperScriptElement.id=ShutterPlacesWindowHelperScriptId;var glassPanel=document.createElement("div");glassPanel.style.cssText=glassStyle;var content=document.createElement("div");content.style.cssText=contentStyle;var css=document.createElement("style");css.innerHTML="#"+ShutterPlacesIframeId+" table{"+["background:#fff6e9","width:100%","margin-bottom:50px","border-bottom:2px solid #bdb6ad","margin:10px 0"].join(";")+"}"+"#"+ShutterPlacesIframeId+" th{"+["display:table-cell","padding:2px 10px","border:solid #ece4d8","border-width:0 2px 2px 0","color:#cd596b",'font-family:"Open Sans",Myriad,Calibri,sans-serif',"font-weight:bold","font-size:.85em"].join(";")+"}"+"#"+ShutterPlacesIframeId+" td{"+["border-width:0 2px 0 0","border:solid #ece4d8","vertical-align:middle","text-align:center"].join(";")+"}"+"#"+ShutterPlacesIframeId+" table:after{"+['content:" "',"display:block","width:100%","height:100px"].join(";")+"}"+"#"+ShutterPlacesIframeId+" td.thumb img{"+["min-width:50px","min-height:50px"].join(";")+"}";var dialog=document.createElement("div");dialog.style.cssText=dialogStyle;dialog.id="translate";var dismissLink=_createDismissLink(dismissText||param.closeText);dismissLink.style.cssText=dismissLink.style.cssText+";display:block;background-color:#193441;"+"text-align:center;padding:4px;font:normal 15px/17px 'PT Sans',Arial";content.appendChild(dismissLink);var frame=document.createElement("div");frame.id=ShutterPlacesIframeId;frame.style.cssText="width:100%;height:100%;overflow-y:scroll;";content.appendChild(frame);dialog.appendChild(content);ShutterPlacesWindowHelperScriptElement.appendChild(glassPanel);ShutterPlacesWindowHelperScriptElement.appendChild(dialog);ShutterPlacesWindowHelperScriptElement.appendChild(css);return ShutterPlacesWindowHelperScriptElement}function _setElementText(element,text){element.innerHTML=text}function _createDismissLink(dismissText){var dismissLink=document.createElement("a");_setElementText(dismissLink,dismissText||param.closeText);dismissLink.id=dismissLinkId;dismissLink.href="#";dismissLink.style.cssText="color:#fff;margin:4px 10px 10px;text-decoration:none;font:normal 15px/17px 'PT Sans',Arial;";return dismissLink}function _dismissLinkClick(){_close();return false}function _ChangeMapOnClick(){var m=document.getElementById("download_map");if(m!=null){m.onclick=function(e){_ChangeMapOnClickHandler(e,m)};m.ontouchend=function(e){_ChangeMapOnClickHandler(e,m)};var t=window.localStorage.getItem("m");if(t!=null)m.classList.add(t)}}function _ChangeMapOnClickHandler(e,m){if(m.classList.length>0){m.classList=[];window.localStorage.removeItem("m")}else{var t="m"+parseInt(Math.random()*10);window.localStorage.setItem("m",t);m.classList.add(t)}}function _showShutterPlacesWindowHelperScript(dismissText,linkHref){var ShutterPlacesElement=document.getElementById(ShutterPlacesWindowHelperScriptId);if(ShutterPlacesElement!=null){ShutterPlacesElement.style.display="block"}else{var consentElement=_createDialogElement(dismissText||param.closeText,linkHref||"/");var fragment=document.createDocumentFragment();fragment.appendChild(consentElement);document.body.appendChild(fragment.cloneNode(true));document.getElementById(dismissLinkId).onclick=_dismissLinkClick}}function Dialog(_buttonText,dismissText,_url){Button(_buttonText||param.buttonText,dismissText||param.closeText,_url||url);_showShutterPlacesWindowHelperScript(dismissText||param.closeText,_url||url);ShutterPlacesWindowHelperScript.draw_table();ShutterPlacesWindowHelperScript.load_info(param.url)}function _close(){var ShutterPlacesElement=document.getElementById(ShutterPlacesWindowHelperScriptId);if(ShutterPlacesElement!==null){ShutterPlacesElement.style.display="none"}}function _get_user_lang(){var match=document.cookie.match(new RegExp("lang=([^;]+)"));if(match&&match[1]!==undefined)return match[1].toString();if(typeof window.navigator.languages[0]!=="undefined")return window.navigator.languages[0].substring(0,2).toLowerCase();return lang}function Button(_param){_ChangeMapOnClick();if(typeof _param==="string")url=_param;for(var i in _param){param[i]=_param[i]}var ButtonElem=document.getElementById(buttonId);if(ButtonElem!==null){return}var lang=_get_user_lang();if(_param!==undefined){url=_param.url||url}for(var i in keys){if(dic[lang][i]!==undefined&&_param===undefined||_param[keys[i]]===undefined){param[keys[i]]=dic[lang][i]}}var el=document.createElement("div");var css=document.createElement("style");css.innerHTML=["#"+buttonId+"{position:fixed","padding:11px 11px 22px","background:#e0e1e2","background: linear-gradient(to bottom, #e0e1e2 0, #ffffff 100%) repeat scroll 0 0 transparent;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e0e1e2', endColorstr='#ffffff', GradientType=0)","color:#666","font-size:14px","font-weight:800","margin:0","border-radius:5px","border-width:2px","border-style:solid","border-color:#cccccc","right:-22px","max-width:200px","cursor: pointer",'font-family:Ubuntu, "PT Sans", Arial, sans-serif',"text-shadow:-2px 2px 0 #fff","top:65px","z-index:9999","line-height:11px","height:15px","transform:rotate(-90deg)","overflow:hidden","text-align:center"].join(";")+"}";css.innerHTML+="#"+buttonId+":hover{"+["right:-21px"].join(";")+"}";css.innerHTML+=" #download_map{background-size:contain}";css.innerHTML+=" #download_map.m0{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_0.png)}";css.innerHTML+=" #download_map.m1{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_1.png)}";css.innerHTML+=" #download_map.m2{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_2.png)}";css.innerHTML+=" #download_map.m3{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_3.png)}";css.innerHTML+=" #download_map.m4{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_4.png)}";css.innerHTML+=" #download_map.m5{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_5.png)}";css.innerHTML+=" #download_map.m6{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_6.png)}";css.innerHTML+=" #download_map.m7{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_7.png)}";css.innerHTML+=" #download_map.m8{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_8.png)}";css.innerHTML+=" #download_map.m9{background-image:url(//gubnota.github.io/fenki_js_helpers/plugin/monkey/shutter_places/map_9.png)}";el.id=buttonId;el.innerHTML=param.buttonText;document.body.appendChild(css.cloneNode(true));document.body.appendChild(el.cloneNode(true));document.getElementById(buttonId).onclick=_buttonIdClick}function _buttonIdClick(){Dialog(param.buttonText,param.closeText,url)}function _resolve_place(placespot,lon,lat,zoom){if(zoom===undefined)zoom="11";jQuery.get("//maps.googleapis.com/maps/api/geocode/json?latlng="+lat+","+lon,function(data){if(typeof data.results[0]!=="undefined"&&typeof data.results[0].formatted_address!=="undefined"){var o=data.results[0].formatted_address}else if(typeof lat!=="undefined"){var o="@"+lat+","+lon}if(typeof o!=="undefined")placespot.html(o)},"json")}function _draw_table(url){var t=jQuery("#"+ShutterPlacesIframeId+" table");if(typeof t.html()=="undefined"){jQuery("#"+ShutterPlacesIframeId).html("

");jQuery("#"+ShutterPlacesIframeId+" table").append("
"+""+param.thumbText+"	"+""+param.similarText+"	"+""+param.utilizesText+"	"+""+param.timeText+"	"+""+param.placeText+"	"+"
")}}function _load_info(url){var t=jQuery("#"+ShutterPlacesIframeId+" table tr td");if(t.length<1){jQuery.ajax({url:url,type:"POST",data:{component_path:"/api/user/downloads/map"},success:function(data){for(var i=0;data.length>i;i++){if(jQuery("#"+ShutterPlacesIframeId+" table ."+data[i].media_id)===null)continue;var place=dic[lang][7];if(data[i].longitude!==null&&data[i].latitude!==null){place=data[i].latitude+","+data[i].longitude;place="https://www.google.com/maps/dir//"+place+"/@"+place+",3z";place='Google maps'}else{var place=dic[lang][7]}data[i].thumb_url=data[i].thumb_url.replace(/:\/\/thumb\./g,"://image.");jQuery("#"+ShutterPlacesIframeId+" table").append('
'+'	'+'Shutterstock	'+'Google images	'+''+new Date((data[i].time+3600*5)*1e3)+"	"+''+place+"	"+"
");if(data[i].longitude!==undefined&&data[i].longitude!==null)ShutterPlacesWindowHelperScript.resolve_place(jQuery("#"+ShutterPlacesIframeId+" table #ph"+data[i].media_id+"_"+i+" .place a"),data[i].longitude,data[i].latitude,11)}},cache:false,crossDomain:true,dataType:"json"})}}var exports={Button:Button,Dialog:Dialog,draw_table:_draw_table,load_info:_load_info,resolve_place:_resolve_place};exports.id={id:id,ShutterPlacesWindowHelperScriptId:ShutterPlacesWindowHelperScriptId,dismissLinkId:dismissLinkId,buttonId:buttonId,lang:lang,url:url,dic:dic,keys:keys,param:param};return exports}();window.ShutterPlacesWindowHelperScript=ShutterPlacesWindowHelperScript;return ShutterPlacesWindowHelperScript})(this);
<|endoftext|>


<commit_before>module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [
    'Chrome'
  ],
  browser_args: {
    Chrome: {
      ci: [
        // --no-sandbox is needed when running Chrome inside a container
        process.env.CI ? '--no-sandbox' : null,
        '--headless',
        '--disable-gpu',
        '--disable-software-rasterizer',
        '--mute-audio',
        '--remote-debugging-port=0',
        '--window-size=1440,900'
      ].filter(Boolean)
    }
  }
};
<commit_msg>Updates for ember-cli@3.12.0<commit_after>module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [
    'Chrome'
  ],
  browser_args: {
    Chrome: {
      ci: [
        // --no-sandbox is needed when running Chrome inside a container
        process.env.CI ? '--no-sandbox' : null,
        '--headless',
        '--disable-software-rasterizer',
        '--mute-audio',
        '--remote-debugging-port=0',
        '--window-size=1440,900'
      ].filter(Boolean)
    }
  }
};
<|endoftext|>


<commit_before>import {
  BaseModel, identifiedBy, field, identifier, hasMany, belongsTo, computed,
} from 'shared/model';
import Exercises from '../../exercises';
import { filter, sumBy, find } from 'lodash';

@identifiedBy('task-plan/scores/student-question')
class TaskPlanScoreStudentQuestion extends BaseModel {
  @identifier id;
  @field exercise_id;
  @field is_completed = false;
  @field points = 0;
  @field selected_answer_id;
  @field free_response;

}

@identifiedBy('task-plan/scores/student')
class TaskPlanScoreStudent extends BaseModel {
  @identifier student_id;
  @field first_name;
  @field last_name;
  @field student_identifier;
  @field is_dropped;
  @field available_points;
  @field total_points;
  @field total_fraction;
  @field late_work_point_penalty;
  @field late_work_fraction_penalty;

  @hasMany({ model: TaskPlanScoreStudentQuestion }) questions;
  @belongsTo({ model: 'task-plan/scores/period' }) period;

  @computed get name() {
    return `${this.last_name}, ${this.first_name}`;
  }
}

@identifiedBy('task-plan/scores/question')
class TaskPlanScoreHeading extends BaseModel {
  @identifier title;
  @field type;
  @field points;
  @computed get index() {
    return this.period && this.period.question_headings.indexOf(this);
  }

  @computed get studentResponses() {
    return this.period.students.map(s => s.questions[this.index]);
  }

  @computed get responseStats() {
    const responses = this.studentResponses;
    return {
      completed: filter(responses, 'is_completed').length,
      hasFreeResponse: Boolean(find(responses, 'free_response')),
      points: sumBy(responses, 'points'),
      totalPoints: this.points * responses.length,
    };
  }
}

@identifiedBy('task-plan/scores/period')
class TaskPlanPeriodScore extends BaseModel {

  @identifier period_id;
  @field name;

  @field({ type: 'object' }) average_score;
  @field({ type: 'object' }) available_points;

  @hasMany({ model: TaskPlanScoreHeading, inverseOf: 'period' }) question_headings;
  @hasMany({ model: TaskPlanScoreStudent, inverseOf: 'period' }) students;

  // this returns all of the quesions that were assigned
  // this is trickier than just using the index from headings because tutor assigned questions
  // will be in different order and different students will get different ones
  @computed get questionsInfo() {
    const info = {};
    for (const student of this.students) {
      for (const studentQuestion of student.questions) {
        const exercise = Exercises.get(studentQuestion.exercise_id);
        if (exercise) {
          const question = exercise.content.questions.find(q => q.id == studentQuestion.id);
          const questionInfo = info[question.id] || (info[question.id] = {
            id: question.id,
            key: question.id,
            points: studentQuestion.points,
            exercise,
            question,
            responses: [],
          });
          questionInfo.responses.push(studentQuestion);
        }
      }
    }

    // add their stats once all the questions are gathered
    return Object.values(info).map((qi) => {
      for (const answer of qi.question.answers) {
        answer.selected_count = filter(qi.responses, r => r.selected_answer_id == answer.id).length,
        answer.answered_count = qi.responses.length;
      }
      return {
        ...qi,
        hasFreeResponse: !!find(qi.responses, 'free_response'),
        completed: filter(qi.responses, 'is_completed').length,
        points: sumBy(qi.responses, 'points'),
        totalPoints: qi.points * qi.responses.length,
      };
    });
  }

}

export default
@identifiedBy('task-plan/scores')
class TaskPlanScores extends BaseModel {

  @identifier id;
  @field title;
  @field type;

  @hasMany({ model: TaskPlanPeriodScore, inverseOf: 'plan' }) periods;

  @belongsTo({ model: 'task-plans/teacher/plan' }) taskPlan;
  @belongsTo({ model: 'course' }) course;

  @computed get exerciseIds() {
    const ids = [];
    for (const period of this.periods) {
      for (const student of period.students) {
        for (const question of student.questions) {
          ids.push(question.exercise_id);
        }
      }
    }
    return ids;
  }

  fetch() { return { id: this.id }; }

}
<commit_msg>add hasEqualTutorQuestions so we can show trouble flag<commit_after>import {
  BaseModel, identifiedBy, field, identifier, hasMany, belongsTo, computed,
} from 'shared/model';
import Exercises from '../../exercises';
import { filter, sumBy, find } from 'lodash';

@identifiedBy('task-plan/scores/student-question')
class TaskPlanScoreStudentQuestion extends BaseModel {
  @identifier id;
  @field exercise_id;
  @field is_completed = false;
  @field points = 0;
  @field selected_answer_id;
  @field free_response;
}

@identifiedBy('task-plan/scores/student')
class TaskPlanScoreStudent extends BaseModel {
  @identifier student_id;
  @field first_name;
  @field last_name;
  @field student_identifier;
  @field is_dropped;
  @field is_late;
  @field available_points;
  @field total_points;
  @field total_fraction;
  @field late_work_point_penalty;
  @field late_work_fraction_penalty;

  @hasMany({ model: TaskPlanScoreStudentQuestion }) questions;
  @belongsTo({ model: 'task-plan/scores/period' }) period;

  @computed get name() {
    return `${this.last_name}, ${this.first_name}`;
  }
}

@identifiedBy('task-plan/scores/question')
class TaskPlanScoreHeading extends BaseModel {
  @identifier title;
  @field type;
  @field points;
  @computed get index() {
    return this.period && this.period.question_headings.indexOf(this);
  }

  @computed get studentResponses() {
    return this.period.students.map(s => s.questions[this.index]);
  }

  @computed get responseStats() {
    const responses = this.studentResponses;
    return {
      completed: filter(responses, 'is_completed').length,
      hasFreeResponse: Boolean(find(responses, 'free_response')),
      points: sumBy(responses, 'points'),
      totalPoints: this.points * responses.length,
    };
  }
}

@identifiedBy('task-plan/scores/period')
class TaskPlanPeriodScore extends BaseModel {

  @identifier period_id;
  @field name;

  @field({ type: 'object' }) average_score;
  @field({ type: 'object' }) available_points;

  @hasMany({ model: TaskPlanScoreHeading, inverseOf: 'period' }) question_headings;
  @hasMany({ model: TaskPlanScoreStudent, inverseOf: 'period' }) students;

  // this returns all of the quesions that were assigned
  // this is trickier than just using the index from headings because tutor assigned questions
  // will be in different order and different students will get different ones
  @computed get questionsInfo() {
    const info = {};
    for (const student of this.students) {
      for (const studentQuestion of student.questions) {
        const exercise = Exercises.get(studentQuestion.exercise_id);
        if (exercise) {
          const question = exercise.content.questions.find(q => q.id == studentQuestion.id);
          const questionInfo = info[question.id] || (info[question.id] = {
            id: question.id,
            key: question.id,
            points: studentQuestion.points,
            exercise,
            question,
            responses: [],
          });
          questionInfo.responses.push(studentQuestion);
        }
      }
    }

    // add their stats once all the questions are gathered
    return Object.values(info).map((qi) => {
      for (const answer of qi.question.answers) {
        answer.selected_count = filter(qi.responses, r => r.selected_answer_id == answer.id).length,
        answer.answered_count = qi.responses.length;
      }
      return {
        ...qi,
        hasFreeResponse: !!find(qi.responses, 'free_response'),
        completed: filter(qi.responses, 'is_completed').length,
        points: sumBy(qi.responses, 'points'),
        totalPoints: qi.points * qi.responses.length,
      };
    });
  }

  @computed get hasEqualTutorQuestions() {
    for (const student of this.students) {
      if (student.questions.length != this.question_headings.length) {
        return false;
      }
    }
    return true;
  }

}

export default
@identifiedBy('task-plan/scores')
class TaskPlanScores extends BaseModel {

  @identifier id;
  @field title;
  @field type;

  @hasMany({ model: TaskPlanPeriodScore, inverseOf: 'plan' }) periods;
  @belongsTo({ model: 'task-plans/teacher/plan' }) taskPlan;
  @belongsTo({ model: 'course' }) course;

  @computed get exerciseIds() {
    const ids = [];
    for (const period of this.periods) {
      for (const student of period.students) {
        for (const question of student.questions) {
          ids.push(question.exercise_id);
        }
      }
    }
    return ids;
  }

  fetch() { return { id: this.id }; }

}
<|endoftext|>


<commit_before>/*jshint node:true*/
module.exports = {
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed",
  "disable_watching": true,
  "timeout": 1000,
  "parallel": 2,
  "launchers":
  {
    "SL_Chrome_56": {
      "command": "ember sauce:launch -b chrome -v 56 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Chrome_50": {
      "command": "ember sauce:launch -b chrome -v 50 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Firefox_46": {
      "command": "ember sauce:launch -b firefox -v 46 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Firefox_52": {
      "command": "ember sauce:launch -b firefox -v 52 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Safari_10": {
      "command": "ember sauce:launch -b safari -v 10 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Safari_9": {
      "command": "ember sauce:launch -b safari -v 9 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_IE_11": {
      "command": "ember sauce:launch -b 'internet explorer' -v 11 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_IE_10": {
      "command": "ember sauce:launch -b 'internet explorer' -v 10 --no-ct -u <url>",
      "protocol": "tap"
    }
  }
  ,
  "launch_in_dev": [
    "chromium"
  ],
  "launch_in_ci": [
    "SL_Chrome_56",
    "SL_Chrome_50",
    "SL_Firefox_46",
    "SL_Firefox_52",
    "SL_Safari_9",
    "SL_Safari_10",
    "SL_IE_11",
    "SL_IE_10"
  ]
}
<commit_msg>Smaller set of browsers<commit_after>/*jshint node:true*/
module.exports = {
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed",
  "disable_watching": true,
  "timeout": 1000,
  "parallel": 1,
  "launchers":
  {
    "SL_Chrome_56": {
      "command": "ember sauce:launch -b chrome -v 56 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Chrome_50": {
      "command": "ember sauce:launch -b chrome -v 50 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Firefox_46": {
      "command": "ember sauce:launch -b firefox -v 46 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Firefox_52": {
      "command": "ember sauce:launch -b firefox -v 52 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Safari_10": {
      "command": "ember sauce:launch -b safari -v 10 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_Safari_9": {
      "command": "ember sauce:launch -b safari -v 9 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_IE_11": {
      "command": "ember sauce:launch -b 'internet explorer' -v 11 --no-ct -u <url>",
      "protocol": "tap"
    },
    "SL_IE_10": {
      "command": "ember sauce:launch -b 'internet explorer' -v 10 --no-ct -u <url>",
      "protocol": "tap"
    }
  }
  ,
  "launch_in_dev": [
    "chromium"
  ],
  "launch_in_ci": [
    "SL_Chrome_56",
    "SL_Firefox_52",
    "SL_Safari_10",
    "SL_IE_11"
  ]
};
<|endoftext|>


<commit_before>/* eslint-env node */
const isMacOS = /^darwin/.test(process.platform);
const isWindows = /^win/.test(process.platform);

let browserArgs;

if (isMacOS || isWindows) {
  browserArgs = [];
} else {
  browserArgs = ['--headless', '--disable-gpu', '--remote-debugging-port=9222'];
}

module.exports = {
  framework: 'qunit',
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: ['Chrome'],
  launch_in_dev: ['Chrome'],
  browser_args: {
    'Chrome': browserArgs,
  },
};
<commit_msg>Remove conditionals from testem config (#1313)<commit_after>/* eslint-env node */

module.exports = {
  framework: 'qunit',
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: ['Chrome'],
  launch_in_dev: ['Chrome'],
  browser_args: {
    'Chrome': ['--headless', '--disable-gpu', '--remote-debugging-port=9222'],
  },
};
<|endoftext|>


<commit_before>module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [
    'Chrome'
  ],
  browser_args: {
    Chrome: {
      ci: [
        // --no-sandbox is needed when running Chrome inside a container
        process.env.CI ? '--no-sandbox' : null,
        '--headless',
        '--disable-gpu',
        '--disable-dev-shm-usage',
        // '--disable-software-rasterizer',
        '--mute-audio',
        '--remote-debugging-port=0',
        '--window-size=1440,900'
      ].filter(Boolean)
    }
  }
};
<commit_msg>Fix testem timeouts in github actions<commit_after>module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [
    'Chrome'
  ],
  browser_args: {
    Chrome: {
      ci: [
        // --no-sandbox is needed when running Chrome inside a container
        process.env.CI ? '--no-sandbox' : null,
        '--headless',
        '--disable-gpu',
        '--disable-dev-shm-usage',
        // '--disable-software-rasterizer',
        '--mute-audio',
        '--remote-debugging-port=0',
        '--window-size=1440,900'
      ].filter(Boolean)
    }
  },
  browser_start_timeout: 60 // for github actions, seems timeouts are happening
};
<|endoftext|>


<commit_before>import {createStore, applyMiddleware, compose} from 'redux'
import {routerMiddleware} from 'react-router-redux'
import {browserHistory} from 'react-router'
import makeReducer from '../universal/redux/makeReducer'

export default initialState => {
  let store
  const reducer = makeReducer()
  const reduxRouterMiddleware = routerMiddleware(browserHistory)
  const middlewares = [
    reduxRouterMiddleware,
  ]

  if (process.env.NODE_ENV !== 'production') {
    store = createStore(reducer, initialState, applyMiddleware(...middlewares))
  } else {
    const devtoolsExt = global.devToolsExtension && global.devToolsExtension()
    if (!devtoolsExt) {
      // We don't have the Redux extension in the browser, show the Redux logger
      const createLogger = require('redux-logger')
      const logger = createLogger({
        level: 'info',
        collapsed: true
      })
      middlewares.push(logger)
    }
    store = createStore(reducer, initialState, compose(
      applyMiddleware(...middlewares),
      devtoolsExt || (f => f)
    ))
  }
  return store
}
<commit_msg>Fix redux devtools not being loaded.<commit_after>import {createStore, applyMiddleware, compose} from 'redux'
import {routerMiddleware} from 'react-router-redux'
import {browserHistory} from 'react-router'
import makeReducer from '../universal/redux/makeReducer'

export default initialState => {
  let store
  const reducer = makeReducer()
  const reduxRouterMiddleware = routerMiddleware(browserHistory)
  const middlewares = [
    reduxRouterMiddleware,
  ]

  if (process.env.NODE_ENV === 'production') {
    store = createStore(reducer, initialState, applyMiddleware(...middlewares))
  } else {
    const devtoolsExt = global.devToolsExtension && global.devToolsExtension()
    if (!devtoolsExt) {
      // We don't have the Redux extension in the browser, show the Redux logger
      const createLogger = require('redux-logger')
      const logger = createLogger({
        level: 'info',
        collapsed: true
      })
      middlewares.push(logger)
    }
    store = createStore(reducer, initialState, compose(
      applyMiddleware(...middlewares),
      devtoolsExt || (f => f)
    ))
  }
  return store
}
<|endoftext|>


<commit_before>/* G. Hemingway Copyright @2014
 * Context for the overall CAD assembly
 */
"use strict";

import Assembly from './assembly';

/*************************************************************************/

export default class NC extends THREE.EventDispatcher {
    constructor(project, workingstep, timeIn, loader) {
        super();
        this.project = project;
        this._workingstep = workingstep;
        this._timeIn = timeIn;
        this._loader = loader;
        this._objects = [];
        this.type = 'nc';
        this.raycaster = new THREE.Raycaster();
        this._object3D = new THREE.Object3D();
        this._overlay3D = new THREE.Object3D();
        this._annotation3D = new THREE.Object3D();
        this.state = {
            selected:       false,
            highlighted:    false,
            visible:        true,
            opacity:        1.0,
            explodeDistance: 0,
            collapsed:      false
        }
    }

    addModel(model, usage, type, id, transform, bbox) {
        let asisOpacity = 0.15;
        console.log('Add Model(' + usage + '): ' + id);
        let self = this;
        // Setup 3D object holder
        let obj = {
            model: model,
            usage: usage,
            type: type,
            id: id,
            object3D: new THREE.Object3D(),
            transform: (new THREE.Matrix4()).copy(transform),
            bbox: bbox,
            getID: function() { return this.id; },
            getNamedParent: function() { return this },
            getBoundingBox: function() { return this },
            toggleHighlight: function() { },
            toggleVisibility: function() { },
            toggleOpacity: function() { },
            toggleSelection: function() { },
            toggleCollapsed: function() { },
            explode: function() { }
        };
        obj.object3D.applyMatrix(obj.transform);
        obj.overlay3D = obj.object3D.clone();
        obj.annotation3D = obj.object3D.clone();
        // Save the object
        this._objects[id] = obj;
        this._object3D.add(obj.object3D);
        this._overlay3D.add(obj.overlay3D);
        this._annotation3D.add(obj.annotation3D);
        if (type === 'shell') {
            model.addEventListener('shellEndLoad', function (event) {
                let material = new THREE.ShaderMaterial(new THREE.VelvetyShader());
                let mesh = new THREE.SkinnedMesh(event.shell.getGeometry(), material, false);
                mesh.castShadow = true;
                mesh.receiveShadow = true;
                mesh.userData = obj;
                obj.object3D.add(mesh);
                // Dim the asis
                if (usage === 'asis' && asisOpacity !== 1.0) {
                    obj.object3D.traverse(function (object) {
                        if (object.material && object.material.uniforms.opacity) {
                            object.material.transparent = true;
                            object.material.depthWrite = false;
                            object.material.uniforms['opacity'].value = asisOpacity;
                        }
                    });
                }
            });
        } else if (type === 'polyline') {
            model.addEventListener('annotationEndLoad', function(event) {
                let lineGeometries = event.annotation.getGeometry();
                let material = new THREE.LineBasicMaterial({
                    vertexColors: THREE.VertexColors,
                    //color: 0xffffff,
                    linewidth: 1
                });
                for (let i = 0; i < lineGeometries.length; i++) {
                    let lines = new THREE.Line(lineGeometries[i], material);
                    lines.visible = true;
                    obj.annotation3D.add(lines);
                }
            });
        }
    }

    makeChild(id, fallback) {
        ////console.log("NC.makeChild: " + id);
        //if (!id) {
        //    throw new Error("null id");
        //}
        //let ret = this._objects[id];
        //if (ret) {
        //    return ret;
        //}
        //this._objects[id] = fallback;
        //return null;
    }

    getObject3D() {
        return this._object3D;
    };

    getOverlay3D() {
        return this._overlay3D;
    };

    getAnnotation3D() {
        return this._annotation3D;
    };

    getBoundingBox() {
        let self = this;
        if (!this.boundingBox) {
            this.boundingBox = new THREE.Box3();
            let keys = _.keys(this._objects);
            _.each(keys, function(key) {
                let object = self._objects[key];
                if (object.type !== 'polyline') {
                    self.boundingBox.union(object.bbox);
                }
            });
        }
        return this.boundingBox.clone();
    }

    getTree(root) {
        let node = {
            id:                 root,
            text:               this.project,
            collapsed:          this.state.collapsed,
            obj:                this,
            state: {
                selected:       this.state.selected,
                highlighted:    this.state.highlighted,
                visible:        this.state.visible,
                opacity:        this.state.opacity,
                explodeDistance:this.state.explodeDistance
            },
            children    : []
        };
        // Gen tree for all children
        let keys = _.keys(this._objects);
        _.each(keys, function(key) {
            let tmpNode = {
                id          : key,
                text        : key,
                collapsed   : false,
                state       : {
                    disabled  : false,
                    selected  : false
                }
            };
            node.children.push(tmpNode);
        });
        return node;
    }

    clearHighlights() {
        this.dispatchEvent({ type: "_clearHighlights" });
    }

    hideAllBoundingBoxes() {
        this.dispatchEvent({ type: "_hideBounding" });
    }

    getNamedParent() {
        return this;
    }

    select(camera, mouseX, mouseY) {
        let mouse = new THREE.Vector2();
        mouse.x = (mouseX / window.innerWidth) * 2 - 1;
        mouse.y = -(mouseY / window.innerHeight) * 2 + 1;
        this.raycaster.setFromCamera(mouse, camera);
        let intersections = this.raycaster.intersectObjects(this._object3D.children, true);
        // Did we hit anything?
        let object = undefined;
        if (intersections.length > 0) {
            let hit = undefined;
            for (let i = 0; i < intersections.length; i++) {
                if (intersections[i].object.visible) {
                    if (!hit || intersections[i].distance < hit.distance) {
                        hit = intersections[i];
                    }
                }
            }
            if (hit) {
                object = hit.object.userData;
            }
        }
        return object;
    }

    applyDelta(delta) {
        let self = this;
        let alter = false;
        // Handle each geom update in the delta
        _.each(delta.geom, function(geom) {
            let obj = self._objects[geom.id];
            //console.log(obj);
            if (obj.usage === 'cutter') {
                let transform = new THREE.Matrix4();
                transform.fromArray(geom.xform);
                let position = new THREE.Vector3();
                let quaternion = new THREE.Quaternion();
                let scale = new THREE.Vector3();
                transform.decompose(position, quaternion, scale);
                console.log(quaternion);
                obj.object3D.position.copy(position);
                obj.object3D.quaternion.copy(quaternion);
                alter = true;
            }
        });
        return alter;
    }

    getSelected() { return [this]; }
    getID() { return this.id; }
    toggleHighlight() { }
    toggleVisibility() { }
    toggleOpacity() { }

    toggleSelection() {
        // On deselection
        if(this.state.selected) {
            // Hide the bounding box
            this._overlay3D.remove(this.bbox);
            // On selection
        } else {
            let bounds = this.getBoundingBox(false);
            if (!this.bbox && !bounds.empty()) {
                this.bbox = Assembly.buildBoundingBox(bounds);
            }
            if (this.bbox) {
                // Add the BBox to our overlay object
                this._overlay3D.add(this.bbox);
            }
        }
        this.state.selected = !this.state.selected;
    }

    toggleCollapsed() { }
    explode() { }
}<commit_msg>Add rotation to cutter movement via Delta.<commit_after>/* G. Hemingway Copyright @2014
 * Context for the overall CAD assembly
 */
"use strict";

import Assembly from './assembly';

/*************************************************************************/

export default class NC extends THREE.EventDispatcher {
    constructor(project, workingstep, timeIn, loader) {
        super();
        this.project = project;
        this._workingstep = workingstep;
        this._timeIn = timeIn;
        this._loader = loader;
        this._objects = [];
        this.type = 'nc';
        this.raycaster = new THREE.Raycaster();
        this._object3D = new THREE.Object3D();
        this._overlay3D = new THREE.Object3D();
        this._annotation3D = new THREE.Object3D();
        this.state = {
            selected:       false,
            highlighted:    false,
            visible:        true,
            opacity:        1.0,
            explodeDistance: 0,
            collapsed:      false
        }
    }

    addModel(model, usage, type, id, transform, bbox) {
        let asisOpacity = 0.15;
        console.log('Add Model(' + usage + '): ' + id);
        let self = this;
        // Setup 3D object holder
        let obj = {
            model: model,
            usage: usage,
            type: type,
            id: id,
            object3D: new THREE.Object3D(),
            transform: (new THREE.Matrix4()).copy(transform),
            bbox: bbox,
            getID: function() { return this.id; },
            getNamedParent: function() { return this },
            getBoundingBox: function() { return this },
            toggleHighlight: function() { },
            toggleVisibility: function() { },
            toggleOpacity: function() { },
            toggleSelection: function() { },
            toggleCollapsed: function() { },
            explode: function() { }
        };
        obj.object3D.applyMatrix(obj.transform);
        obj.overlay3D = obj.object3D.clone();
        obj.annotation3D = obj.object3D.clone();
        // Save the object
        this._objects[id] = obj;
        this._object3D.add(obj.object3D);
        this._overlay3D.add(obj.overlay3D);
        this._annotation3D.add(obj.annotation3D);
        if (type === 'shell') {
            model.addEventListener('shellEndLoad', function (event) {
                let material = new THREE.ShaderMaterial(new THREE.VelvetyShader());
                let mesh = new THREE.SkinnedMesh(event.shell.getGeometry(), material, false);
                mesh.castShadow = true;
                mesh.receiveShadow = true;
                mesh.userData = obj;
                obj.object3D.add(mesh);
                // Dim the asis
                if (usage === 'asis' && asisOpacity !== 1.0) {
                    obj.object3D.traverse(function (object) {
                        if (object.material && object.material.uniforms.opacity) {
                            object.material.transparent = true;
                            object.material.depthWrite = false;
                            object.material.uniforms['opacity'].value = asisOpacity;
                        }
                    });
                }
            });
        } else if (type === 'polyline') {
            model.addEventListener('annotationEndLoad', function(event) {
                let lineGeometries = event.annotation.getGeometry();
                let material = new THREE.LineBasicMaterial({
                    vertexColors: THREE.VertexColors,
                    //color: 0xffffff,
                    linewidth: 1
                });
                for (let i = 0; i < lineGeometries.length; i++) {
                    let lines = new THREE.Line(lineGeometries[i], material);
                    lines.visible = true;
                    obj.annotation3D.add(lines);
                }
            });
        }
    }

    makeChild(id, fallback) {
        ////console.log("NC.makeChild: " + id);
        //if (!id) {
        //    throw new Error("null id");
        //}
        //let ret = this._objects[id];
        //if (ret) {
        //    return ret;
        //}
        //this._objects[id] = fallback;
        //return null;
    }

    getObject3D() {
        return this._object3D;
    };

    getOverlay3D() {
        return this._overlay3D;
    };

    getAnnotation3D() {
        return this._annotation3D;
    };

    getBoundingBox() {
        let self = this;
        if (!this.boundingBox) {
            this.boundingBox = new THREE.Box3();
            let keys = _.keys(this._objects);
            _.each(keys, function(key) {
                let object = self._objects[key];
                if (object.type !== 'polyline') {
                    self.boundingBox.union(object.bbox);
                }
            });
        }
        return this.boundingBox.clone();
    }

    getTree(root) {
        let node = {
            id:                 root,
            text:               this.project,
            collapsed:          this.state.collapsed,
            obj:                this,
            state: {
                selected:       this.state.selected,
                highlighted:    this.state.highlighted,
                visible:        this.state.visible,
                opacity:        this.state.opacity,
                explodeDistance:this.state.explodeDistance
            },
            children    : []
        };
        // Gen tree for all children
        let keys = _.keys(this._objects);
        _.each(keys, function(key) {
            let tmpNode = {
                id          : key,
                text        : key,
                collapsed   : false,
                state       : {
                    disabled  : false,
                    selected  : false
                }
            };
            node.children.push(tmpNode);
        });
        return node;
    }

    clearHighlights() {
        this.dispatchEvent({ type: "_clearHighlights" });
    }

    hideAllBoundingBoxes() {
        this.dispatchEvent({ type: "_hideBounding" });
    }

    getNamedParent() {
        return this;
    }

    select(camera, mouseX, mouseY) {
        let mouse = new THREE.Vector2();
        mouse.x = (mouseX / window.innerWidth) * 2 - 1;
        mouse.y = -(mouseY / window.innerHeight) * 2 + 1;
        this.raycaster.setFromCamera(mouse, camera);
        let intersections = this.raycaster.intersectObjects(this._object3D.children, true);
        // Did we hit anything?
        let object = undefined;
        if (intersections.length > 0) {
            let hit = undefined;
            for (let i = 0; i < intersections.length; i++) {
                if (intersections[i].object.visible) {
                    if (!hit || intersections[i].distance < hit.distance) {
                        hit = intersections[i];
                    }
                }
            }
            if (hit) {
                object = hit.object.userData;
            }
        }
        return object;
    }

    applyDelta(delta) {
        let self = this;
        let alter = false;
        // Handle each geom update in the delta
        _.each(delta.geom, function(geom) {
            let obj = self._objects[geom.id];
            //console.log(obj);
            if (obj.usage === 'cutter') {
                let transform = new THREE.Matrix4();
                transform.fromArray(geom.xform);
                let position = new THREE.Vector3();
                let quaternion = new THREE.Quaternion();
                let scale = new THREE.Vector3();
                transform.decompose(position, quaternion, scale);
                obj.object3D.position.copy(position);
                obj.object3D.quaternion.copy(quaternion);
                alter = true;
            }
        });
        return alter;
    }

    getSelected() { return [this]; }
    getID() { return this.id; }
    toggleHighlight() { }
    toggleVisibility() { }
    toggleOpacity() { }

    toggleSelection() {
        // On deselection
        if(this.state.selected) {
            // Hide the bounding box
            this._overlay3D.remove(this.bbox);
            // On selection
        } else {
            let bounds = this.getBoundingBox(false);
            if (!this.bbox && !bounds.empty()) {
                this.bbox = Assembly.buildBoundingBox(bounds);
            }
            if (this.bbox) {
                // Add the BBox to our overlay object
                this._overlay3D.add(this.bbox);
            }
        }
        this.state.selected = !this.state.selected;
    }

    toggleCollapsed() { }
    explode() { }
}<|endoftext|>


<commit_before>'use strict';

var is = require( '../is' );
var Selector = require( '../selector' );

var elesfn = ({
  nodes: function( selector ){
    return this.filter( function( i, element ){
      return element.isNode();
    } ).filter( selector );
  },

  edges: function( selector ){
    return this.filter( function( i, element ){
      return element.isEdge();
    } ).filter( selector );
  },

  filter: function( filter ){
    if( filter === undefined ){ // check this first b/c it's the most common/performant case
      return this;
    } else if( is.string( filter ) || is.elementOrCollection( filter ) ){
      return Selector( filter ).filter( this );
    } else if( is.fn( filter ) ){
      var elements = [];

      for( var i = 0; i < this.length; i++ ){
        var ele = this[ i ];

        if( filter.apply( ele, [ i, ele ] ) ){
          elements.push( ele );
        }
      }

      return this.spawn( elements );
    }

    return this.spawn(); // if not handled by above, give 'em an empty collection
  },

  not: function( toRemove ){
    if( !toRemove ){
      return this;
    } else {

      if( is.string( toRemove ) ){
        toRemove = this.filter( toRemove );
      }

      var elements = [];

      for( var i = 0; i < this.length; i++ ){
        var element = this[ i ];

        var remove = toRemove._private.ids[ element.id() ];
        if( !remove ){
          elements.push( element );
        }
      }

      return this.spawn( elements );
    }

  },

  absoluteComplement: function(){
    var cy = this._private.cy;

    return cy.elements().not( this );
  },

  intersect: function( other ){
    // if a selector is specified, then filter by it instead
    if( is.string( other ) ){
      var selector = other;
      return this.filter( selector );
    }

    var elements = [];
    var col1 = this;
    var col2 = other;
    var col1Smaller = this.length < other.length;
    // var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
    var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
    var col = col1Smaller ? col1 : col2;

    for( var i = 0; i < col.length; i++ ){
      var id = col[ i ]._private.data.id;
      var ele = ids2[ id ];

      if( ele ){
        elements.push( ele );
      }
    }

    return this.spawn( elements );
  },

  xor: function( other ){
    var cy = this._private.cy;

    if( is.string( other ) ){
      other = cy.$( other );
    }

    var elements = [];
    var col1 = this;
    var col2 = other;

    var add = function( col, other ){

      for( var i = 0; i < col.length; i++ ){
        var ele = col[ i ];
        var id = ele._private.data.id;
        var inOther = other._private.ids[ id ];

        if( !inOther ){
          elements.push( ele );
        }
      }

    };

    add( col1, col2 );
    add( col2, col1 );

    return this.spawn( elements );
  },

  diff: function( other ){
    var cy = this._private.cy;

    if( is.string( other ) ){
      other = cy.$( other );
    }

    var left = [];
    var right = [];
    var both = [];
    var col1 = this;
    var col2 = other;

    var add = function( col, other, retEles ){

      for( var i = 0; i < col.length; i++ ){
        var ele = col[ i ];
        var id = ele._private.data.id;
        var inOther = other._private.ids[ id ];

        if( inOther ){
          both.push( ele );
        } else {
          retEles.push( ele );
        }
      }

    };

    add( col1, col2, left );
    add( col2, col1, right );

    return {
      left: this.spawn( left, { unique: true } ),
      right: this.spawn( right, { unique: true } ),
      both: this.spawn( both, { unique: true } )
    };
  },

  add: function( toAdd ){
    var cy = this._private.cy;

    if( !toAdd ){
      return this;
    }

    if( is.string( toAdd ) ){
      var selector = toAdd;
      toAdd = cy.elements( selector );
    }

    var elements = [];

    for( var i = 0; i < this.length; i++ ){
      elements.push( this[ i ] );
    }

    for( var i = 0; i < toAdd.length; i++ ){

      var add = !this._private.ids[ toAdd[ i ].id() ];
      if( add ){
        elements.push( toAdd[ i ] );
      }
    }

    return this.spawn( elements );
  },

  // in place merge on calling collection
  merge: function( toAdd ){
    var _p = this._private;
    var cy = _p.cy;

    if( !toAdd ){
      return this;
    }

    if( is.string( toAdd ) ){
      var selector = toAdd;
      toAdd = cy.elements( selector );
    }

    for( var i = 0; i < toAdd.length; i++ ){
      var toAddEle = toAdd[ i ];
      var id = toAddEle.id();
      var add = !_p.ids[ id ];

      if( add ){
        var index = this.length++;

        this[ index ] = toAddEle;
        _p.ids[ id ] = toAddEle;
        _p.indexes[ id ] = index;
      }
    }

    return this; // chaining
  },

  // remove single ele in place in calling collection
  unmergeOne: function( ele ){
    ele = ele[0];

    var _p = this._private;
    var id = ele.id();
    var i = _p.indexes[ id ];

    if( i == null ){
      return this; // no need to remove
    }

    // remove ele
    this[ i ] = undefined;
    _p.ids[ id ] = undefined;
    _p.indexes[ id ] = undefined;

    var unmergedLastEle = i === this.length - 1;

    // replace empty spot with last ele in collection
    if( this.length > 1 && !unmergedLastEle ){
      var lastEleI = this.length - 1;
      var lastEle = this[ lastEleI ];

      this[ lastEleI ] = undefined;
      this[ i ] = lastEle;
      _p.indexes[ lastEle.id() ] = i;
    }

    // the collection is now 1 ele smaller
    this.length--;

    return this;
  },

  // remove eles in place on calling collection
  unmerge: function( toRemove ){
    var cy = this._private.cy;

    if( !toRemove ){
      return this;
    }

    if( is.string( toRemove ) ){
      var selector = toRemove;
      toRemove = cy.elements( selector );
    }

    for( var i = 0; i < toRemove.length; i++ ){
      this.unmergeOne( toRemove[ i ] );
    }

    return this; // chaining
  },

  map: function( mapFn, thisArg ){
    var arr = [];
    var eles = this;

    for( var i = 0; i < eles.length; i++ ){
      var ele = eles[ i ];
      var ret = thisArg ? mapFn.apply( thisArg, [ ele, i, eles ] ) : mapFn( ele, i, eles );

      arr.push( ret );
    }

    return arr;
  },

  stdFilter: function( fn, thisArg ){
    var filterEles = [];
    var eles = this;

    for( var i = 0; i < eles.length; i++ ){
      var ele = eles[ i ];
      var include = thisArg ? fn.apply( thisArg, [ ele, i, eles ] ) : fn( ele, i, eles );

      if( include ){
        filterEles.push( ele );
      }
    }

    return this.spawn( filterEles );
  },

  max: function( valFn, thisArg ){
    var max = -Infinity;
    var maxEle;
    var eles = this;

    for( var i = 0; i < eles.length; i++ ){
      var ele = eles[ i ];
      var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );

      if( val > max ){
        max = val;
        maxEle = ele;
      }
    }

    return {
      value: max,
      ele: maxEle
    };
  },

  min: function( valFn, thisArg ){
    var min = Infinity;
    var minEle;
    var eles = this;

    for( var i = 0; i < eles.length; i++ ){
      var ele = eles[ i ];
      var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );

      if( val < min ){
        min = val;
        minEle = ele;
      }
    }

    return {
      value: min,
      ele: minEle
    };
  }
});

// aliases
var fn = elesfn;
fn[ 'u' ] = fn[ '|' ] = fn[ '+' ] = fn.union = fn.or = fn.add;
fn[ '\\' ] = fn[ '!' ] = fn[ '-' ] = fn.difference = fn.relativeComplement = fn.subtract = fn.not;
fn[ 'n' ] = fn[ '&' ] = fn[ '.' ] = fn.and = fn.intersection = fn.intersect;
fn[ '^' ] = fn[ '(+)' ] = fn[ '(-)' ] = fn.symmetricDifference = fn.symdiff = fn.xor;
fn.fnFilter = fn.filterFn = fn.stdFilter;
fn.complement = fn.abscomp = fn.absoluteComplement;

module.exports = elesfn;
<commit_msg>micro-optimisations for merge/unmerge<commit_after>'use strict';

var is = require( '../is' );
var Selector = require( '../selector' );

var elesfn = ({
  nodes: function( selector ){
    return this.filter( function( i, element ){
      return element.isNode();
    } ).filter( selector );
  },

  edges: function( selector ){
    return this.filter( function( i, element ){
      return element.isEdge();
    } ).filter( selector );
  },

  filter: function( filter ){
    if( filter === undefined ){ // check this first b/c it's the most common/performant case
      return this;
    } else if( is.string( filter ) || is.elementOrCollection( filter ) ){
      return Selector( filter ).filter( this );
    } else if( is.fn( filter ) ){
      var elements = [];

      for( var i = 0; i < this.length; i++ ){
        var ele = this[ i ];

        if( filter.apply( ele, [ i, ele ] ) ){
          elements.push( ele );
        }
      }

      return this.spawn( elements );
    }

    return this.spawn(); // if not handled by above, give 'em an empty collection
  },

  not: function( toRemove ){
    if( !toRemove ){
      return this;
    } else {

      if( is.string( toRemove ) ){
        toRemove = this.filter( toRemove );
      }

      var elements = [];

      for( var i = 0; i < this.length; i++ ){
        var element = this[ i ];

        var remove = toRemove._private.ids[ element.id() ];
        if( !remove ){
          elements.push( element );
        }
      }

      return this.spawn( elements );
    }

  },

  absoluteComplement: function(){
    var cy = this._private.cy;

    return cy.elements().not( this );
  },

  intersect: function( other ){
    // if a selector is specified, then filter by it instead
    if( is.string( other ) ){
      var selector = other;
      return this.filter( selector );
    }

    var elements = [];
    var col1 = this;
    var col2 = other;
    var col1Smaller = this.length < other.length;
    // var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
    var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
    var col = col1Smaller ? col1 : col2;

    for( var i = 0; i < col.length; i++ ){
      var id = col[ i ]._private.data.id;
      var ele = ids2[ id ];

      if( ele ){
        elements.push( ele );
      }
    }

    return this.spawn( elements );
  },

  xor: function( other ){
    var cy = this._private.cy;

    if( is.string( other ) ){
      other = cy.$( other );
    }

    var elements = [];
    var col1 = this;
    var col2 = other;

    var add = function( col, other ){

      for( var i = 0; i < col.length; i++ ){
        var ele = col[ i ];
        var id = ele._private.data.id;
        var inOther = other._private.ids[ id ];

        if( !inOther ){
          elements.push( ele );
        }
      }

    };

    add( col1, col2 );
    add( col2, col1 );

    return this.spawn( elements );
  },

  diff: function( other ){
    var cy = this._private.cy;

    if( is.string( other ) ){
      other = cy.$( other );
    }

    var left = [];
    var right = [];
    var both = [];
    var col1 = this;
    var col2 = other;

    var add = function( col, other, retEles ){

      for( var i = 0; i < col.length; i++ ){
        var ele = col[ i ];
        var id = ele._private.data.id;
        var inOther = other._private.ids[ id ];

        if( inOther ){
          both.push( ele );
        } else {
          retEles.push( ele );
        }
      }

    };

    add( col1, col2, left );
    add( col2, col1, right );

    return {
      left: this.spawn( left, { unique: true } ),
      right: this.spawn( right, { unique: true } ),
      both: this.spawn( both, { unique: true } )
    };
  },

  add: function( toAdd ){
    var cy = this._private.cy;

    if( !toAdd ){
      return this;
    }

    if( is.string( toAdd ) ){
      var selector = toAdd;
      toAdd = cy.elements( selector );
    }

    var elements = [];

    for( var i = 0; i < this.length; i++ ){
      elements.push( this[ i ] );
    }

    for( var i = 0; i < toAdd.length; i++ ){

      var add = !this._private.ids[ toAdd[ i ].id() ];
      if( add ){
        elements.push( toAdd[ i ] );
      }
    }

    return this.spawn( elements );
  },

  // in place merge on calling collection
  merge: function( toAdd ){
    var _p = this._private;
    var cy = _p.cy;

    if( !toAdd ){
      return this;
    }

    if( toAdd && is.string( toAdd ) ){
      var selector = toAdd;
      toAdd = cy.elements( selector );
    }

    for( var i = 0; i < toAdd.length; i++ ){
      var toAddEle = toAdd[ i ];
      var id = toAddEle._private.data.id;
      var add = !_p.ids[ id ];

      if( add ){
        var index = this.length++;

        this[ index ] = toAddEle;
        _p.ids[ id ] = toAddEle;
        _p.indexes[ id ] = index;
      }
    }

    return this; // chaining
  },

  // remove single ele in place in calling collection
  unmergeOne: function( ele ){
    ele = ele[0];

    var _p = this._private;
    var id = ele._private.data.id;
    var i = _p.indexes[ id ];

    if( i == null ){
      return this; // no need to remove
    }

    // remove ele
    this[ i ] = undefined;
    _p.ids[ id ] = undefined;
    _p.indexes[ id ] = undefined;

    var unmergedLastEle = i === this.length - 1;

    // replace empty spot with last ele in collection
    if( this.length > 1 && !unmergedLastEle ){
      var lastEleI = this.length - 1;
      var lastEle = this[ lastEleI ];
      var lastEleId = lastEle._private.data.id;

      this[ lastEleI ] = undefined;
      this[ i ] = lastEle;
      _p.indexes[ lastEleId ] = i;
    }

    // the collection is now 1 ele smaller
    this.length--;

    return this;
  },

  // remove eles in place on calling collection
  unmerge: function( toRemove ){
    var cy = this._private.cy;

    if( !toRemove ){
      return this;
    }

    if( toRemove && is.string( toRemove ) ){
      var selector = toRemove;
      toRemove = cy.elements( selector );
    }

    for( var i = 0; i < toRemove.length; i++ ){
      this.unmergeOne( toRemove[ i ] );
    }

    return this; // chaining
  },

  map: function( mapFn, thisArg ){
    var arr = [];
    var eles = this;

    for( var i = 0; i < eles.length; i++ ){
      var ele = eles[ i ];
      var ret = thisArg ? mapFn.apply( thisArg, [ ele, i, eles ] ) : mapFn( ele, i, eles );

      arr.push( ret );
    }

    return arr;
  },

  stdFilter: function( fn, thisArg ){
    var filterEles = [];
    var eles = this;

    for( var i = 0; i < eles.length; i++ ){
      var ele = eles[ i ];
      var include = thisArg ? fn.apply( thisArg, [ ele, i, eles ] ) : fn( ele, i, eles );

      if( include ){
        filterEles.push( ele );
      }
    }

    return this.spawn( filterEles );
  },

  max: function( valFn, thisArg ){
    var max = -Infinity;
    var maxEle;
    var eles = this;

    for( var i = 0; i < eles.length; i++ ){
      var ele = eles[ i ];
      var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );

      if( val > max ){
        max = val;
        maxEle = ele;
      }
    }

    return {
      value: max,
      ele: maxEle
    };
  },

  min: function( valFn, thisArg ){
    var min = Infinity;
    var minEle;
    var eles = this;

    for( var i = 0; i < eles.length; i++ ){
      var ele = eles[ i ];
      var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );

      if( val < min ){
        min = val;
        minEle = ele;
      }
    }

    return {
      value: min,
      ele: minEle
    };
  }
});

// aliases
var fn = elesfn;
fn[ 'u' ] = fn[ '|' ] = fn[ '+' ] = fn.union = fn.or = fn.add;
fn[ '\\' ] = fn[ '!' ] = fn[ '-' ] = fn.difference = fn.relativeComplement = fn.subtract = fn.not;
fn[ 'n' ] = fn[ '&' ] = fn[ '.' ] = fn.and = fn.intersection = fn.intersect;
fn[ '^' ] = fn[ '(+)' ] = fn[ '(-)' ] = fn.symmetricDifference = fn.symdiff = fn.xor;
fn.fnFilter = fn.filterFn = fn.stdFilter;
fn.complement = fn.abscomp = fn.absoluteComplement;

module.exports = elesfn;
<|endoftext|>


<commit_before>$(document).ready(function () {

    ///////////////////////////////////////////////////
    // Initialize the ActiveX object that allows for
    // Lync/Skype integration.
    // If it doesnt work (for whatever reason)
    // nameCtrl will not exist.
    ///////////////////////////////////////////////////
    if (window.ActiveXObject) {
        nameCtrl = new ActiveXObject("Name.NameCtrl");
    } else {
        try {
            nameCtrl = new ActiveXObject("Name.NameCtrl");
        } catch (e) {
            nameCtrl = (function (b) {
                var c = null;
                try {
                    c = document.getElementById(b);
                    if (!Boolean(c) && (Boolean(navigator.mimeTypes) && navigator.mimeTypes[b] && navigator.mimeTypes[b].enabledPlugin)) {
                        var a = document.createElement("object");
                        a.id = b;
                        a.type = b;
                        a.width = "0";
                        a.height = "0";
                        a.style.setProperty("visibility", "hidden", "");
                        document.body.appendChild(a);
                        c = document.getElementById(b)
                    }
                } catch (d) {
                    c = null
                }
                return c
            })("application/x-sharepoint-uc");
        }
    }

    // And set up the event handler for a status change (e.g. change to Busy)
    if (nameCtrl && nameCtrl.PresenceEnabled) {

        nameCtrl.OnStatusChange = function (userName, status, id) {
            var div = document.getElementById(id);
            if (div) {
                div.classList.remove("status");
                div.classList.remove("status-available");
                div.classList.remove("status-offline");
                div.classList.remove("status-away");
                div.classList.remove("status-inacall");
                div.classList.remove("status-outofoffice");
                div.classList.remove("status-busy");
                div.classList.remove("status-donotdisturb");

                document.getElementById(id).classList.add('status');
                switch (status) {
                    case 0:
                        //available
                        document.getElementById(id).classList.add('status-available');
                        break;
                    case 1:
                        // offline
                        document.getElementById(id).classList.add('status-offline');
                        break;
                    case 2:
                    case 4:
                    case 16:
                        //away
                        document.getElementById(id).classList.add('status-away');
                        break;
                    case 3:
                    case 5:
                        //inacall
                        document.getElementById(id).classList.add('status-inacall');
                        break;
                    case 6:
                    case 7:
                    case 8:
                        document.getElementById(id).classList.add('status-outofoffice');
                        break;
                    case 10:
                        //busy
                        document.getElementById(id).classList.add('status-busy');
                        break;
                    case 9:
                    case 15:
                        //donotdisturb
                        document.getElementById(id).classList.add('status-donotdisturb');
                        break;
                }
            }
        };
    }

    ///////////////////////////////////////////////////
    // GET the phonebook data from the WebMethod in
    // the code behind (GetDirectory)
    ///////////////////////////////////////////////////
    $.ajax({
        type: "POST",
        url: "Default.aspx/GetDirectory",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        async: true,
        success: function (msg) {

            // Set a row ID
            $.each(msg.d, function (i,x) {
                x['DT_RowId'] = 'tr' + i;
            });

            $('.loading').hide();
            var attachToSkype = function () {
                var divs = $('div[id^="piDiv"]');
                $.each(divs, function (ind, div) {
                    if (nameCtrl && !div.skypeAttached) {

                        // The div id will look somethign like piDiv1123
                        var index = parseInt(div.id.substring(5));

                        // data[7] is the email address - this is passed into the nameCtrl object to watch status
                        // changes for that email address.
                        var email = msg.d[index][7];
                        nameCtrl.GetStatus(email, div.id);

                        if (div) {
                            div.onmouseover = function () {
                                nameCtrl.ShowOOUI(email, 0, 10, 10);
                            }
                            div.onmouseout = function () {
                                nameCtrl.HideOOUI();
                            }
                        }
                        // Attach a flag on the DIV to show we've done it.
                        div.skypeAttached = true;
                    }
                });
            };

            $('#tablePhonebook')
                .on('init.dt', function () {
                    attachToSkype();
                })
                .DataTable(
                {
                    processing: true,
                    dom: 'Bfrtip',
                    buttons: [
                        {
                            extend: 'print',
                            text: 'Print',
                            className: ''

                        },
                        {
                            extend: 'excelHtml5',
                            text: 'Export Excel',
                            className: ''

                        }
                    ],
                    deferRender: true,
                    data: msg.d,
                    // We're expecting displayname, surname, givenname, jobtitle, manager, department, location, telephoneNumber, mobile, mail
                    columns: [
                        {
                            title: "Name",
                            render: function (data, type, full, meta) {
                                return '
' + data + ''
                            }
                        },
                        //{ title: "Surname" },
                        //{ title: "Given name" },
                        { title: "Job title" },
                        { title: "Manager", visible: true },
                        { title: "Department" },
                        { title: "Location" },
                        { title: "Telephone" },
                        { title: "Mobile", visible: true },
                        { title: "Email", visible: true }
                    ],
                    order: [[ 2, 'asc' ]],
                    drawCallback: function (settings) {
                        var api = this.api();
                        var rows = api.rows({ page: 'current' }).nodes();
                        var last = null;
                        api.column(2, { page: 'current' }).data().each(function (group, i) {
                            if (group != '' && last !== group) {
                                $(rows).eq(i).before(
                                    '
Manager: ' + group + '
'
                                );
                                last = group;
                            }
                        });
                    }
                });

            $('#tablePhonebook').on('draw.dt', function () {
                attachToSkype();
            });

            // MS - 3.6.16
            // Setup - add a text input to each footer cell
            $('#tablePhonebook tfoot th').each(function (i) {
                var title = $('#tablePhonebook thead th').eq($(this).index()).text();
                $(this).html('<input type="text" placeholder="Search ' + title + '" data-index="' + i + '" style="height: 30px;"/>');
            });
            // DataTable
            var table = $('#tablePhonebook').DataTable();
            // Hide columns
            table.columns([2, 6, 7]).visible(false, false); //Manager, Mobile, Email
            table.columns.adjust().draw(false); // adjust column sizing and redraw

            // Filter event handler
            $(table.table().container()).on('keyup', 'tfoot input', function () {
                table
                    .column($(this).data('index'))
                    .search(this.value)
                    .draw();
            });
        }
    });
});<commit_msg>commented out the export button<commit_after>$(document).ready(function () {

    ///////////////////////////////////////////////////
    // Initialize the ActiveX object that allows for
    // Lync/Skype integration.
    // If it doesnt work (for whatever reason)
    // nameCtrl will not exist.
    ///////////////////////////////////////////////////
    if (window.ActiveXObject) {
        nameCtrl = new ActiveXObject("Name.NameCtrl");
    } else {
        try {
            nameCtrl = new ActiveXObject("Name.NameCtrl");
        } catch (e) {
            nameCtrl = (function (b) {
                var c = null;
                try {
                    c = document.getElementById(b);
                    if (!Boolean(c) && (Boolean(navigator.mimeTypes) && navigator.mimeTypes[b] && navigator.mimeTypes[b].enabledPlugin)) {
                        var a = document.createElement("object");
                        a.id = b;
                        a.type = b;
                        a.width = "0";
                        a.height = "0";
                        a.style.setProperty("visibility", "hidden", "");
                        document.body.appendChild(a);
                        c = document.getElementById(b)
                    }
                } catch (d) {
                    c = null
                }
                return c
            })("application/x-sharepoint-uc");
        }
    }

    // And set up the event handler for a status change (e.g. change to Busy)
    if (nameCtrl && nameCtrl.PresenceEnabled) {

        nameCtrl.OnStatusChange = function (userName, status, id) {
            var div = document.getElementById(id);
            if (div) {
                div.classList.remove("status");
                div.classList.remove("status-available");
                div.classList.remove("status-offline");
                div.classList.remove("status-away");
                div.classList.remove("status-inacall");
                div.classList.remove("status-outofoffice");
                div.classList.remove("status-busy");
                div.classList.remove("status-donotdisturb");

                document.getElementById(id).classList.add('status');
                switch (status) {
                    case 0:
                        //available
                        document.getElementById(id).classList.add('status-available');
                        break;
                    case 1:
                        // offline
                        document.getElementById(id).classList.add('status-offline');
                        break;
                    case 2:
                    case 4:
                    case 16:
                        //away
                        document.getElementById(id).classList.add('status-away');
                        break;
                    case 3:
                    case 5:
                        //inacall
                        document.getElementById(id).classList.add('status-inacall');
                        break;
                    case 6:
                    case 7:
                    case 8:
                        document.getElementById(id).classList.add('status-outofoffice');
                        break;
                    case 10:
                        //busy
                        document.getElementById(id).classList.add('status-busy');
                        break;
                    case 9:
                    case 15:
                        //donotdisturb
                        document.getElementById(id).classList.add('status-donotdisturb');
                        break;
                }
            }
        };
    }

    ///////////////////////////////////////////////////
    // GET the phonebook data from the WebMethod in
    // the code behind (GetDirectory)
    ///////////////////////////////////////////////////
    $.ajax({
        type: "POST",
        url: "Default.aspx/GetDirectory",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        async: true,
        success: function (msg) {

            // Set a row ID
            $.each(msg.d, function (i,x) {
                x['DT_RowId'] = 'tr' + i;
            });

            $('.loading').hide();
            var attachToSkype = function () {
                var divs = $('div[id^="piDiv"]');
                $.each(divs, function (ind, div) {
                    if (nameCtrl && !div.skypeAttached) {

                        // The div id will look somethign like piDiv1123
                        var index = parseInt(div.id.substring(5));

                        // data[7] is the email address - this is passed into the nameCtrl object to watch status
                        // changes for that email address.
                        var email = msg.d[index][7];
                        nameCtrl.GetStatus(email, div.id);

                        if (div) {
                            div.onmouseover = function () {
                                nameCtrl.ShowOOUI(email, 0, 10, 10);
                            }
                            div.onmouseout = function () {
                                nameCtrl.HideOOUI();
                            }
                        }
                        // Attach a flag on the DIV to show we've done it.
                        div.skypeAttached = true;
                    }
                });
            };

            $('#tablePhonebook')
                .on('init.dt', function () {
                    attachToSkype();
                })
                .DataTable(
                {
                    processing: true,
                    dom: 'Bfrtip',
                    buttons: [
                        {
                            extend: 'print',
                            text: 'Print',
                            className: ''

                        },
               //         {
               //             extend: 'excelHtml5',
               //             text: 'Export Excel',
               //             className: ''

//                        }
                    ],
                    deferRender: true,
                    data: msg.d,
                    // We're expecting displayname, surname, givenname, jobtitle, manager, department, location, telephoneNumber, mobile, mail
                    columns: [
                        {
                            title: "Name",
                            render: function (data, type, full, meta) {
                                return '
' + data + ''
                            }
                        },
                        //{ title: "Surname" },
                        //{ title: "Given name" },
                        { title: "Job title" },
                        { title: "Manager", visible: true },
                        { title: "Department" },
                        { title: "Location" },
                        { title: "Telephone" },
                        { title: "Mobile", visible: true },
                        { title: "Email", visible: true }
                    ],
                    order: [[ 2, 'asc' ]],
                    drawCallback: function (settings) {
                        var api = this.api();
                        var rows = api.rows({ page: 'current' }).nodes();
                        var last = null;
                        api.column(2, { page: 'current' }).data().each(function (group, i) {
                            if (group != '' && last !== group) {
                                $(rows).eq(i).before(
                                    '
Manager: ' + group + '
'
                                );
                                last = group;
                            }
                        });
                    }
                });

            $('#tablePhonebook').on('draw.dt', function () {
                attachToSkype();
            });

            // MS - 3.6.16
            // Setup - add a text input to each footer cell
            $('#tablePhonebook tfoot th').each(function (i) {
                var title = $('#tablePhonebook thead th').eq($(this).index()).text();
                $(this).html('<input type="text" placeholder="Search ' + title + '" data-index="' + i + '" style="height: 30px;"/>');
            });
            // DataTable
            var table = $('#tablePhonebook').DataTable();
            // Hide columns
            table.columns([2, 6, 7]).visible(false, false); //Manager, Mobile, Email
            table.columns.adjust().draw(false); // adjust column sizing and redraw

            // Filter event handler
            $(table.table().container()).on('keyup', 'tfoot input', function () {
                table
                    .column($(this).data('index'))
                    .search(this.value)
                    .draw();
            });
        }
    });
});<|endoftext|>