@mate-academy/sourcebuster 1.3.5 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -478,7 +478,13 @@ module.exports = function(prefs) {
478
478
 
479
479
  case terms.traffic.utm:
480
480
 
481
- __sbjs_type = terms.traffic.utm;
481
+ // Allow explicit type override via utm_type URL parameter
482
+ // This fixes mixed attribution when organic visits include UTM params in redirect URLs
483
+ if (typeof get_param.utm_type !== 'undefined') {
484
+ __sbjs_type = get_param.utm_type;
485
+ } else {
486
+ __sbjs_type = terms.traffic.utm;
487
+ }
482
488
 
483
489
  if (typeof get_param.utm_source !== 'undefined') {
484
490
  __sbjs_source = get_param.utm_source;
@@ -700,10 +706,10 @@ module.exports = function(prefs) {
700
706
  ) {
701
707
  __sbjs_source = y_host;
702
708
  return true;
703
- } else if (!!uri.parse(referer).host.match(g_host_regex)) {
709
+ } else if (uri.parse(referer).host.match(g_host_regex)) {
704
710
  __sbjs_source = g_host;
705
711
  return true;
706
- } else if (!!uri.parse(referer).query) {
712
+ } else if (uri.parse(referer).query) {
707
713
  for (var i = 0; i < p.organics.length; i++) {
708
714
  if (
709
715
  uri.parse(referer).host.match(new RegExp('^(?:.*\\.)?' + utils.escapeRegexp(p.organics[i].host) + '$', 'i')) &&
@@ -752,6 +758,7 @@ module.exports = function(prefs) {
752
758
  var gbraid = get_param.gbraid || '';
753
759
  var wbraid = get_param.wbraid || '';
754
760
  var fbclid = get_param.fbclid || '';
761
+ var ttclid = get_param.ttclid || '';
755
762
 
756
763
  // if utm_source = "sd" -> utm_term param is used
757
764
  var sdclid = get_param.utm_source === 'sd' ? get_param.utm_term || '' : '';
@@ -775,6 +782,11 @@ module.exports = function(prefs) {
775
782
  cookies.set('_mate-fbclid', fbclid, lifetime, domain, isolate);
776
783
  }
777
784
 
785
+ if (ttclid !== '') {
786
+ cookies.destroy('_mate-sdclid', domain, isolate);
787
+ cookies.set('_mate-ttclid', ttclid, lifetime, domain, isolate);
788
+ }
789
+
778
790
  if (sdclid !== '') {
779
791
  cookies.set('_mate-sdclid', sdclid, lifetime, domain, isolate);
780
792
  }
@@ -1,2 +1,2 @@
1
- /** @mate-academy/sourcebuster v1.3.5 **/
2
- !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.sbjs=e()}}(function(){return function e(t,r,n){function i(s,o){if(!r[s]){if(!t[s]){var c="function"==typeof require&&require;if(!o&&c)return c(s,!0);if(a)return a(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var d=r[s]={exports:{}};t[s][0].call(d.exports,function(e){var r=t[s][1][e];return i(r?r:e)},d,d.exports,e,t,r,n)}return r[s].exports}for(var a="function"==typeof require&&require,s=0;s<n.length;s++)i(n[s]);return i}({1:[function(e,t,r){"use strict";var n=e("./init"),i={init:function(e){this.get=n(e),e&&e.callback&&"function"==typeof e.callback&&e.callback(this.get)}};t.exports=i},{"./init":6}],2:[function(e,t,r){"use strict";var n=e("./terms"),i=e("./helpers/utils"),a={containers:{current:"sbjs_current",current_extra:"sbjs_current_add",first:"sbjs_first",first_extra:"sbjs_first_add",session:"sbjs_session",udata:"sbjs_udata",promocode:"sbjs_promo"},service:{migrations:"sbjs_migrations"},delimiter:"|||",aliases:{main:{type:"typ",source:"src",medium:"mdm",campaign:"cmp",content:"cnt",term:"trm",account_id:"ac_id",campaign_id:"cmp_id",ad_group_id:"adg_id",ad_id:"ad_id",term_id:"trm_id"},extra:{fire_date:"fd",entrance_point:"ep",referer:"rf"},session:{pages_seen:"pgs",current_page:"cpg",session_id:"sid"},udata:{visits:"vst",ip:"uip",agent:"uag"},promo:"code"},pack:{main:function(e){return a.aliases.main.type+"="+e.type+a.delimiter+a.aliases.main.source+"="+e.source+a.delimiter+a.aliases.main.medium+"="+e.medium+a.delimiter+a.aliases.main.campaign+"="+e.campaign+a.delimiter+a.aliases.main.content+"="+e.content+a.delimiter+a.aliases.main.term+"="+e.term+a.delimiter+a.aliases.main.account_id+"="+e.account_id+a.delimiter+a.aliases.main.campaign_id+"="+e.campaign_id+a.delimiter+a.aliases.main.ad_group_id+"="+e.ad_group_id+a.delimiter+a.aliases.main.ad_id+"="+e.ad_id+a.delimiter+a.aliases.main.term_id+"="+e.term_id},unpack:function(e){var t={},r=e.split("|||");return r.forEach(function(e){var r=e.split("="),n=r[0],i=r[1];t[n]=i}),t},extra:function(e){return a.aliases.extra.fire_date+"="+i.setDate(new Date,e)+a.delimiter+a.aliases.extra.entrance_point+"="+document.location.href+a.delimiter+a.aliases.extra.referer+"="+(document.referrer||n.none)},user:function(e,t){return a.aliases.udata.visits+"="+e+a.delimiter+a.aliases.udata.ip+"="+t+a.delimiter+a.aliases.udata.agent+"="+navigator.userAgent},session:function(e,t){var r=a.aliases.session.pages_seen+"="+e+a.delimiter+a.aliases.session.current_page+"="+document.location.href;return t?r+a.delimiter+a.aliases.session.session_id+"="+t:r},promo:function(e){return a.aliases.promo+"="+i.setLeadingZeroToInt(i.randomInt(e.min,e.max),e.max.toString().length)}}};t.exports=a},{"./helpers/utils":5,"./terms":9}],3:[function(e,t,r){"use strict";var n=e("../data").delimiter;t.exports={encodeData:function(e){return encodeURIComponent(e).replace(/\!/g,"%21").replace(/\~/g,"%7E").replace(/\*/g,"%2A").replace(/\'/g,"%27").replace(/\(/g,"%28").replace(/\)/g,"%29")},decodeData:function(e){try{return decodeURIComponent(e).replace(/\%21/g,"!").replace(/\%7E/g,"~").replace(/\%2A/g,"*").replace(/\%27/g,"'").replace(/\%28/g,"(").replace(/\%29/g,")")}catch(t){try{return unescape(e)}catch(r){return""}}},set:function(e,t,r,n,i){var a,s;if(r){var o=new Date;o.setTime(o.getTime()+60*r*1e3),a="; expires="+o.toGMTString()}else a="";s=n&&!i?";domain=."+n:"",document.cookie=this.encodeData(e)+"="+this.encodeData(t)+a+s+"; path=/"},get:function(e){for(var t=this.encodeData(e)+"=",r=document.cookie.split(";"),n=0;n<r.length;n++){for(var i=r[n];" "===i.charAt(0);)i=i.substring(1,i.length);if(0===i.indexOf(t))return this.decodeData(i.substring(t.length,i.length))}return null},destroy:function(e,t,r){this.set(e,"",-1,t,r)},parse:function(e){var t=[],r={};if("string"==typeof e)t.push(e);else for(var i in e)e.hasOwnProperty(i)&&t.push(e[i]);for(var a=0;a<t.length;a++){var s;r[this.unsbjs(t[a])]={},s=this.get(t[a])?this.get(t[a]).split(n):[];for(var o=0;o<s.length;o++){var c=s[o].split("="),u=c.splice(0,1);u.push(c.join("=")),r[this.unsbjs(t[a])][u[0]]=this.decodeData(u[1])}}return r},unsbjs:function(e){return e.replace("sbjs_","")}}},{"../data":2}],4:[function(e,t,r){"use strict";t.exports={parse:function(e){for(var t=this.parseOptions,r=t.parser[t.strictMode?"strict":"loose"].exec(e),n={},i=14;i--;)n[t.key[i]]=r[i]||"";return n[t.q.name]={},n[t.key[12]].replace(t.q.parser,function(e,r,i){r&&(n[t.q.name][r]=i)}),n},parseOptions:{strictMode:!1,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}},getParam:function(e){for(var t={},r=e?e:window.location.search.substring(1),n=r.split("&"),i=0;i<n.length;i++){var a=n[i].split("=");if("undefined"==typeof t[a[0]])t[a[0]]=a[1];else if("string"==typeof t[a[0]]){var s=[t[a[0]],a[1]];t[a[0]]=s}else t[a[0]].push(a[1])}return t},getHost:function(e){return this.parse(e).host.replace("www.","")}}},{}],5:[function(e,t,r){"use strict";t.exports={escapeRegexp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},setDate:function(e,t){var r=e.getTimezoneOffset()/60,n=e.getHours(),i=t||0===t?t:-r;e.setHours(n+r+i);var a=e.getFullYear(),s=this.setLeadingZeroToInt(e.getMonth()+1,2),o=this.setLeadingZeroToInt(e.getDate(),2),c=this.setLeadingZeroToInt(e.getHours(),2),u=this.setLeadingZeroToInt(e.getMinutes(),2),d=this.setLeadingZeroToInt(e.getSeconds(),2);return a+"-"+s+"-"+o+" "+c+":"+u+":"+d},setLeadingZeroToInt:function(e,t){for(var r=e+"";r.length<t;)r="0"+r;return r},randomInt:function(e,t){return Math.floor(Math.random()*(t-e+1))+e}}},{}],6:[function(e,t,r){"use strict";var n=e("./data"),i=e("./terms"),a=e("./helpers/cookies"),s=e("./helpers/uri"),o=e("./helpers/utils"),c=e("./params"),u=e("./migrations");t.exports=function(e){function t(){var e,t,s,o="undefined"!=typeof v.utm_source||"undefined"!=typeof v.utm_medium||"undefined"!=typeof v.utm_campaign||"undefined"!=typeof v.utm_content||"undefined"!=typeof v.utm_term||"undefined"!=typeof v.utm_ac_id||"undefined"!=typeof v.utm_id||"undefined"!=typeof v.utm_ad_group_id||"undefined"!=typeof v.utm_ad_id||"undefined"!=typeof v.utm_term_id||"undefined"!=typeof v.gclid||"undefined"!=typeof v.yclid||"undefined"!=typeof v[y.campaign_param]||"undefined"!=typeof v[y.term_param]||"undefined"!=typeof v[y.content_param],c=a.parse(n.containers),u=c[a.unsbjs(n.containers.current)],p=f(i.traffic.organic),m=!1;if(h(),o)_(),e=d(i.traffic.utm),t=u,s=n.pack.unpack(e),m=r(t,s);else if(p)_(),e=d(i.traffic.organic),t=u,s=n.pack.unpack(e),m=r(t,s);else if(!a.get(n.containers.session)&&f(i.traffic.referral))_(),e=d(i.traffic.referral),m=!0;else{if(a.get(n.containers.first)||a.get(n.containers.current))return{data:a.get(n.containers.current),is_utm_changed:m};_(),e=d(i.traffic.typein),m=!0}return{data:e,is_utm_changed:m}}function r(e,t){return e[n.aliases.main.type]!==t[n.aliases.main.type]||e[n.aliases.main.source]!==t[n.aliases.main.source]||e[n.aliases.main.medium]!==t[n.aliases.main.medium]||e[n.aliases.main.campaign]!==t[n.aliases.main.campaign]||e[n.aliases.main.content]!==t[n.aliases.main.content]||e[n.aliases.main.term]!==t[n.aliases.main.term]}function d(e){switch(e){case i.traffic.utm:w=i.traffic.utm,q="undefined"!=typeof v.utm_source?v.utm_source:"undefined"!=typeof v.gclid?"google":"undefined"!=typeof v.yclid?"yandex":i.none,I="undefined"!=typeof v.utm_medium?v.utm_medium:"undefined"!=typeof v.gclid?"cpc":"undefined"!=typeof v.yclid?"cpc":i.none,j="undefined"!=typeof v.utm_campaign?v.utm_campaign:"undefined"!=typeof v[y.campaign_param]?v[y.campaign_param]:"undefined"!=typeof v.gclid?"google_cpc":"undefined"!=typeof v.yclid?"yandex_cpc":i.none,R="undefined"!=typeof v.utm_content?v.utm_content:"undefined"!=typeof v[y.content_param]?v[y.content_param]:i.none,D="undefined"!=typeof v.utm_term?v.utm_term:"undefined"!=typeof v[y.term_param]?v[y.term_param]:p()||i.none,H="undefined"!=typeof v.utm_ac_id?v.utm_ac_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,T="undefined"!=typeof v.utm_id?v.utm_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,E="undefined"!=typeof v.utm_ad_group_id?v.utm_ad_group_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,O="undefined"!=typeof v.utm_ad_id?v.utm_ad_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,$="undefined"!=typeof v.utm_term_id?v.utm_term_id:"undefined"!=typeof v.gclid?"google_cpc":i.none;break;case i.traffic.organic:w=i.traffic.organic,q=q||s.getHost(document.referrer),I=i.referer.organic,j=i.none,R=i.none,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;case i.traffic.referral:w=i.traffic.referral,q=q||s.getHost(document.referrer),I=I||i.referer.referral,j=i.none,R=s.parse(document.referrer).path,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;case i.traffic.typein:w=i.traffic.typein,q=y.typein_attributes.source,I=y.typein_attributes.medium,j=i.none,R=i.none,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;default:w=i.oops,q=i.oops,I=i.oops,j=i.oops,R=i.oops,D=i.oops,H=i.oops,T=i.oops,E=i.oops,O=i.oops,$=i.oops}var t={type:w,source:q,medium:I,campaign:j,content:R,term:D,account_id:H,campaign_id:T,ad_group_id:E,ad_id:O,term_id:$};return n.pack.main(t)}function p(){var e=document.referrer;if(v.utm_term)return v.utm_term;if(!(e&&s.parse(e).host&&s.parse(e).host.match(/^(?:.*\.)?yandex\..{2,9}$/i)))return!1;try{return s.getParam(s.parse(document.referrer).query).text}catch(t){return!1}}function f(e){var t=document.referrer;switch(e){case i.traffic.organic:return!!t&&m(t)&&l(t);case i.traffic.referral:return!!t&&m(t)&&g(t);default:return!1}}function m(e){if(y.domain){if(x)return s.getHost(e)!==s.getHost(b);var t=new RegExp("^(?:.*\\.)?"+o.escapeRegexp(b)+"$","i");return!s.getHost(e).match(t)}return s.getHost(e)!==s.getHost(document.location.href)}function l(e){var t="yandex",r="text",n="google",i=new RegExp("^(?:.*\\.)?"+o.escapeRegexp(t)+"\\..{2,9}$"),a=new RegExp(".*"+o.escapeRegexp(r)+"=.*"),c=new RegExp("^(?:www\\.)?"+o.escapeRegexp(n)+"\\..{2,9}$");if(s.parse(e).query&&s.parse(e).host.match(i)&&s.parse(e).query.match(a))return q=t,!0;if(s.parse(e).host.match(c))return q=n,!0;if(!s.parse(e).query)return!1;for(var u=0;u<y.organics.length;u++){if(s.parse(e).host.match(new RegExp("^(?:.*\\.)?"+o.escapeRegexp(y.organics[u].host)+"$","i"))&&s.parse(e).query.match(new RegExp(".*"+o.escapeRegexp(y.organics[u].param)+"=.*","i")))return q=y.organics[u].display||y.organics[u].host,!0;if(u+1===y.organics.length)return!1}}function g(e){if(!(y.referrals.length>0))return q=s.getHost(e),!0;for(var t=0;t<y.referrals.length;t++){if(s.parse(e).host.match(new RegExp("^(?:.*\\.)?"+o.escapeRegexp(y.referrals[t].host)+"$","i")))return q=y.referrals[t].display||y.referrals[t].host,I=y.referrals[t].medium||i.referer.referral,!0;if(t+1===y.referrals.length)return q=s.getHost(e),!0}}function _(){a.set(n.containers.current_extra,n.pack.extra(y.timezone_offset),k,b,x),a.get(n.containers.first_extra)||a.set(n.containers.first_extra,n.pack.extra(y.timezone_offset),k,b,x)}function h(){var e=v.gclid||"",t=v.gbraid||"",r=v.wbraid||"",n=v.fbclid||"",i="sd"===v.utm_source?v.utm_term||"":"";""!==t&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-gbraid",t,k,b,x)),""!==r&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-wbraid",r,k,b,x)),""!==e&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-gclid",e,k,b,x)),""!==n&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-fbclid",n,k,b,x)),""!==i&&a.set("_mate-sdclid",i,k,b,x)}var y=c.fetch(e),v=s.getParam(),b=y.domain.host,x=y.domain.isolate,k=y.lifetime;u.go(k,b,x);var w,q,I,j,R,D,H,T,E,O,$;return function(){var e=t();a.set(n.containers.current,e.data,k,b,x),a.get(n.containers.first)||a.set(n.containers.first,a.get(n.containers.current),k,b,x);var r,i;a.get(n.containers.udata)?(r=parseInt(a.parse(n.containers.udata)[a.unsbjs(n.containers.udata)][n.aliases.udata.visits])||1,r=a.get(n.containers.session)?r:r+1,i=n.pack.user(r,y.user_ip)):(r=1,i=n.pack.user(r,y.user_ip)),a.set(n.containers.udata,i,k,b,x);var s,o;a.get(n.containers.session)?(s=parseInt(a.parse(n.containers.session)[a.unsbjs(n.containers.session)][n.aliases.session.pages_seen])||1,s+=1):s=1,a.get(n.containers.session)&&!e.is_utm_changed||(o=(new Date).getTime()),a.set(n.containers.session,n.pack.session(s,o),y.session_length,b,x),y.promocode&&!a.get(n.containers.promocode)&&a.set(n.containers.promocode,n.pack.promo(y.promocode),k,b,x)}(),a.parse(n.containers)}},{"./data":2,"./helpers/cookies":3,"./helpers/uri":4,"./helpers/utils":5,"./migrations":7,"./params":8,"./terms":9}],7:[function(e,t,r){"use strict";var n=e("./data"),i=e("./helpers/cookies");t.exports={go:function(e,t,r){var a,s=this.migrations,o={l:e,d:t,i:r};if(i.get(n.containers.first)||i.get(n.service.migrations)){if(!i.get(n.service.migrations))for(a=0;a<s.length;a++)s[a].go(s[a].id,o)}else{var c=[];for(a=0;a<s.length;a++)c.push(s[a].id);var u="";for(a=0;a<c.length;a++)u+=c[a]+"=1",a<c.length-1&&(u+=n.delimiter);i.set(n.service.migrations,u,o.l,o.d,o.i)}},migrations:[{id:"1418474375998",version:"1.0.0-beta",go:function(e,t){var r=e+"=1",a=e+"=0",s=function(e,t,r){return t||r?e:n.delimiter};try{var o=[];for(var c in n.containers)n.containers.hasOwnProperty(c)&&o.push(n.containers[c]);for(var u=0;u<o.length;u++)if(i.get(o[u])){var d=i.get(o[u]).replace(/(\|)?\|(\|)?/g,s);i.destroy(o[u],t.d,t.i),i.destroy(o[u],t.d,!t.i),i.set(o[u],d,t.l,t.d,t.i)}i.get(n.containers.session)&&i.set(n.containers.session,n.pack.session(0),t.l,t.d,t.i),i.set(n.service.migrations,r,t.l,t.d,t.i)}catch(p){i.set(n.service.migrations,a,t.l,t.d,t.i)}}}]}},{"./data":2,"./helpers/cookies":3}],8:[function(e,t,r){"use strict";var n=e("./terms"),i=e("./helpers/uri");t.exports={fetch:function(e){var t=e||{},r={};if(r.lifetime=this.validate.checkFloat(t.lifetime)||6,r.lifetime=parseInt(30*r.lifetime*24*60),r.session_length=this.validate.checkInt(t.session_length)||30,r.timezone_offset=this.validate.checkInt(t.timezone_offset),r.campaign_param=t.campaign_param||!1,r.term_param=t.term_param||!1,r.content_param=t.content_param||!1,r.user_ip=t.user_ip||n.none,t.promocode?(r.promocode={},r.promocode.min=parseInt(t.promocode.min)||1e5,r.promocode.max=parseInt(t.promocode.max)||999999):r.promocode=!1,t.typein_attributes&&t.typein_attributes.source&&t.typein_attributes.medium?(r.typein_attributes={},r.typein_attributes.source=t.typein_attributes.source,r.typein_attributes.medium=t.typein_attributes.medium):r.typein_attributes={source:"(direct)",medium:"(none)"},t.domain&&this.validate.isString(t.domain)?r.domain={host:t.domain,isolate:!1}:t.domain&&t.domain.host?r.domain=t.domain:r.domain={host:i.getHost(document.location.hostname),isolate:!1},r.referrals=[],t.referrals&&t.referrals.length>0)for(var a=0;a<t.referrals.length;a++)t.referrals[a].host&&r.referrals.push(t.referrals[a]);if(r.organics=[],t.organics&&t.organics.length>0)for(var s=0;s<t.organics.length;s++)t.organics[s].host&&t.organics[s].param&&r.organics.push(t.organics[s]);return r.organics.push({host:"bing.com",param:"q",display:"bing"}),r.organics.push({host:"yahoo.com",param:"p",display:"yahoo"}),r.organics.push({host:"about.com",param:"q",display:"about"}),r.organics.push({host:"aol.com",param:"q",display:"aol"}),r.organics.push({host:"ask.com",param:"q",display:"ask"}),r.organics.push({host:"globososo.com",param:"q",display:"globo"}),r.organics.push({host:"go.mail.ru",param:"q",display:"go.mail.ru"}),r.organics.push({host:"rambler.ru",param:"query",display:"rambler"}),r.organics.push({host:"tut.by",param:"query",display:"tut.by"}),r.referrals.push({host:"t.co",display:"twitter.com"}),r.referrals.push({host:"plus.url.google.com",display:"plus.google.com"}),r},validate:{checkFloat:function(e){return!(!e||!this.isNumeric(parseFloat(e)))&&parseFloat(e)},checkInt:function(e){return!(!e||!this.isNumeric(parseInt(e)))&&parseInt(e)},isNumeric:function(e){return!isNaN(e)},isString:function(e){return"[object String]"===Object.prototype.toString.call(e)}}}},{"./helpers/uri":4,"./terms":9}],9:[function(e,t,r){"use strict";t.exports={traffic:{utm:"utm",organic:"organic",referral:"referral",typein:"typein"},referer:{referral:"referral",organic:"organic",social:"social"},none:"(none)",oops:"(Houston, we have a problem)"}},{}]},{},[1])(1)});
1
+ /** @mate-academy/sourcebuster v1.4.0 **/
2
+ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.sbjs=e()}}(function(){return function e(t,r,n){function i(s,o){if(!r[s]){if(!t[s]){var c="function"==typeof require&&require;if(!o&&c)return c(s,!0);if(a)return a(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var d=r[s]={exports:{}};t[s][0].call(d.exports,function(e){var r=t[s][1][e];return i(r?r:e)},d,d.exports,e,t,r,n)}return r[s].exports}for(var a="function"==typeof require&&require,s=0;s<n.length;s++)i(n[s]);return i}({1:[function(e,t,r){"use strict";var n=e("./init"),i={init:function(e){this.get=n(e),e&&e.callback&&"function"==typeof e.callback&&e.callback(this.get)}};t.exports=i},{"./init":6}],2:[function(e,t,r){"use strict";var n=e("./terms"),i=e("./helpers/utils"),a={containers:{current:"sbjs_current",current_extra:"sbjs_current_add",first:"sbjs_first",first_extra:"sbjs_first_add",session:"sbjs_session",udata:"sbjs_udata",promocode:"sbjs_promo"},service:{migrations:"sbjs_migrations"},delimiter:"|||",aliases:{main:{type:"typ",source:"src",medium:"mdm",campaign:"cmp",content:"cnt",term:"trm",account_id:"ac_id",campaign_id:"cmp_id",ad_group_id:"adg_id",ad_id:"ad_id",term_id:"trm_id"},extra:{fire_date:"fd",entrance_point:"ep",referer:"rf"},session:{pages_seen:"pgs",current_page:"cpg",session_id:"sid"},udata:{visits:"vst",ip:"uip",agent:"uag"},promo:"code"},pack:{main:function(e){return a.aliases.main.type+"="+e.type+a.delimiter+a.aliases.main.source+"="+e.source+a.delimiter+a.aliases.main.medium+"="+e.medium+a.delimiter+a.aliases.main.campaign+"="+e.campaign+a.delimiter+a.aliases.main.content+"="+e.content+a.delimiter+a.aliases.main.term+"="+e.term+a.delimiter+a.aliases.main.account_id+"="+e.account_id+a.delimiter+a.aliases.main.campaign_id+"="+e.campaign_id+a.delimiter+a.aliases.main.ad_group_id+"="+e.ad_group_id+a.delimiter+a.aliases.main.ad_id+"="+e.ad_id+a.delimiter+a.aliases.main.term_id+"="+e.term_id},unpack:function(e){var t={},r=e.split("|||");return r.forEach(function(e){var r=e.split("="),n=r[0],i=r[1];t[n]=i}),t},extra:function(e){return a.aliases.extra.fire_date+"="+i.setDate(new Date,e)+a.delimiter+a.aliases.extra.entrance_point+"="+document.location.href+a.delimiter+a.aliases.extra.referer+"="+(document.referrer||n.none)},user:function(e,t){return a.aliases.udata.visits+"="+e+a.delimiter+a.aliases.udata.ip+"="+t+a.delimiter+a.aliases.udata.agent+"="+navigator.userAgent},session:function(e,t){var r=a.aliases.session.pages_seen+"="+e+a.delimiter+a.aliases.session.current_page+"="+document.location.href;return t?r+a.delimiter+a.aliases.session.session_id+"="+t:r},promo:function(e){return a.aliases.promo+"="+i.setLeadingZeroToInt(i.randomInt(e.min,e.max),e.max.toString().length)}}};t.exports=a},{"./helpers/utils":5,"./terms":9}],3:[function(e,t,r){"use strict";var n=e("../data").delimiter;t.exports={encodeData:function(e){return encodeURIComponent(e).replace(/\!/g,"%21").replace(/\~/g,"%7E").replace(/\*/g,"%2A").replace(/\'/g,"%27").replace(/\(/g,"%28").replace(/\)/g,"%29")},decodeData:function(e){try{return decodeURIComponent(e).replace(/\%21/g,"!").replace(/\%7E/g,"~").replace(/\%2A/g,"*").replace(/\%27/g,"'").replace(/\%28/g,"(").replace(/\%29/g,")")}catch(t){try{return unescape(e)}catch(r){return""}}},set:function(e,t,r,n,i){var a,s;if(r){var o=new Date;o.setTime(o.getTime()+60*r*1e3),a="; expires="+o.toGMTString()}else a="";s=n&&!i?";domain=."+n:"",document.cookie=this.encodeData(e)+"="+this.encodeData(t)+a+s+"; path=/"},get:function(e){for(var t=this.encodeData(e)+"=",r=document.cookie.split(";"),n=0;n<r.length;n++){for(var i=r[n];" "===i.charAt(0);)i=i.substring(1,i.length);if(0===i.indexOf(t))return this.decodeData(i.substring(t.length,i.length))}return null},destroy:function(e,t,r){this.set(e,"",-1,t,r)},parse:function(e){var t=[],r={};if("string"==typeof e)t.push(e);else for(var i in e)e.hasOwnProperty(i)&&t.push(e[i]);for(var a=0;a<t.length;a++){var s;r[this.unsbjs(t[a])]={},s=this.get(t[a])?this.get(t[a]).split(n):[];for(var o=0;o<s.length;o++){var c=s[o].split("="),u=c.splice(0,1);u.push(c.join("=")),r[this.unsbjs(t[a])][u[0]]=this.decodeData(u[1])}}return r},unsbjs:function(e){return e.replace("sbjs_","")}}},{"../data":2}],4:[function(e,t,r){"use strict";t.exports={parse:function(e){for(var t=this.parseOptions,r=t.parser[t.strictMode?"strict":"loose"].exec(e),n={},i=14;i--;)n[t.key[i]]=r[i]||"";return n[t.q.name]={},n[t.key[12]].replace(t.q.parser,function(e,r,i){r&&(n[t.q.name][r]=i)}),n},parseOptions:{strictMode:!1,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}},getParam:function(e){for(var t={},r=e?e:window.location.search.substring(1),n=r.split("&"),i=0;i<n.length;i++){var a=n[i].split("=");if("undefined"==typeof t[a[0]])t[a[0]]=a[1];else if("string"==typeof t[a[0]]){var s=[t[a[0]],a[1]];t[a[0]]=s}else t[a[0]].push(a[1])}return t},getHost:function(e){return this.parse(e).host.replace("www.","")}}},{}],5:[function(e,t,r){"use strict";t.exports={escapeRegexp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},setDate:function(e,t){var r=e.getTimezoneOffset()/60,n=e.getHours(),i=t||0===t?t:-r;e.setHours(n+r+i);var a=e.getFullYear(),s=this.setLeadingZeroToInt(e.getMonth()+1,2),o=this.setLeadingZeroToInt(e.getDate(),2),c=this.setLeadingZeroToInt(e.getHours(),2),u=this.setLeadingZeroToInt(e.getMinutes(),2),d=this.setLeadingZeroToInt(e.getSeconds(),2);return a+"-"+s+"-"+o+" "+c+":"+u+":"+d},setLeadingZeroToInt:function(e,t){for(var r=e+"";r.length<t;)r="0"+r;return r},randomInt:function(e,t){return Math.floor(Math.random()*(t-e+1))+e}}},{}],6:[function(e,t,r){"use strict";var n=e("./data"),i=e("./terms"),a=e("./helpers/cookies"),s=e("./helpers/uri"),o=e("./helpers/utils"),c=e("./params"),u=e("./migrations");t.exports=function(e){function t(){var e,t,s,o="undefined"!=typeof v.utm_source||"undefined"!=typeof v.utm_medium||"undefined"!=typeof v.utm_campaign||"undefined"!=typeof v.utm_content||"undefined"!=typeof v.utm_term||"undefined"!=typeof v.utm_ac_id||"undefined"!=typeof v.utm_id||"undefined"!=typeof v.utm_ad_group_id||"undefined"!=typeof v.utm_ad_id||"undefined"!=typeof v.utm_term_id||"undefined"!=typeof v.gclid||"undefined"!=typeof v.yclid||"undefined"!=typeof v[y.campaign_param]||"undefined"!=typeof v[y.term_param]||"undefined"!=typeof v[y.content_param],c=a.parse(n.containers),u=c[a.unsbjs(n.containers.current)],p=f(i.traffic.organic),m=!1;if(h(),o)_(),e=d(i.traffic.utm),t=u,s=n.pack.unpack(e),m=r(t,s);else if(p)_(),e=d(i.traffic.organic),t=u,s=n.pack.unpack(e),m=r(t,s);else if(!a.get(n.containers.session)&&f(i.traffic.referral))_(),e=d(i.traffic.referral),m=!0;else{if(a.get(n.containers.first)||a.get(n.containers.current))return{data:a.get(n.containers.current),is_utm_changed:m};_(),e=d(i.traffic.typein),m=!0}return{data:e,is_utm_changed:m}}function r(e,t){return e[n.aliases.main.type]!==t[n.aliases.main.type]||e[n.aliases.main.source]!==t[n.aliases.main.source]||e[n.aliases.main.medium]!==t[n.aliases.main.medium]||e[n.aliases.main.campaign]!==t[n.aliases.main.campaign]||e[n.aliases.main.content]!==t[n.aliases.main.content]||e[n.aliases.main.term]!==t[n.aliases.main.term]}function d(e){switch(e){case i.traffic.utm:w="undefined"!=typeof v.utm_type?v.utm_type:i.traffic.utm,q="undefined"!=typeof v.utm_source?v.utm_source:"undefined"!=typeof v.gclid?"google":"undefined"!=typeof v.yclid?"yandex":i.none,I="undefined"!=typeof v.utm_medium?v.utm_medium:"undefined"!=typeof v.gclid?"cpc":"undefined"!=typeof v.yclid?"cpc":i.none,j="undefined"!=typeof v.utm_campaign?v.utm_campaign:"undefined"!=typeof v[y.campaign_param]?v[y.campaign_param]:"undefined"!=typeof v.gclid?"google_cpc":"undefined"!=typeof v.yclid?"yandex_cpc":i.none,R="undefined"!=typeof v.utm_content?v.utm_content:"undefined"!=typeof v[y.content_param]?v[y.content_param]:i.none,D="undefined"!=typeof v.utm_term?v.utm_term:"undefined"!=typeof v[y.term_param]?v[y.term_param]:p()||i.none,H="undefined"!=typeof v.utm_ac_id?v.utm_ac_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,T="undefined"!=typeof v.utm_id?v.utm_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,E="undefined"!=typeof v.utm_ad_group_id?v.utm_ad_group_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,O="undefined"!=typeof v.utm_ad_id?v.utm_ad_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,$="undefined"!=typeof v.utm_term_id?v.utm_term_id:"undefined"!=typeof v.gclid?"google_cpc":i.none;break;case i.traffic.organic:w=i.traffic.organic,q=q||s.getHost(document.referrer),I=i.referer.organic,j=i.none,R=i.none,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;case i.traffic.referral:w=i.traffic.referral,q=q||s.getHost(document.referrer),I=I||i.referer.referral,j=i.none,R=s.parse(document.referrer).path,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;case i.traffic.typein:w=i.traffic.typein,q=y.typein_attributes.source,I=y.typein_attributes.medium,j=i.none,R=i.none,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;default:w=i.oops,q=i.oops,I=i.oops,j=i.oops,R=i.oops,D=i.oops,H=i.oops,T=i.oops,E=i.oops,O=i.oops,$=i.oops}var t={type:w,source:q,medium:I,campaign:j,content:R,term:D,account_id:H,campaign_id:T,ad_group_id:E,ad_id:O,term_id:$};return n.pack.main(t)}function p(){var e=document.referrer;if(v.utm_term)return v.utm_term;if(!(e&&s.parse(e).host&&s.parse(e).host.match(/^(?:.*\.)?yandex\..{2,9}$/i)))return!1;try{return s.getParam(s.parse(document.referrer).query).text}catch(t){return!1}}function f(e){var t=document.referrer;switch(e){case i.traffic.organic:return!!t&&m(t)&&l(t);case i.traffic.referral:return!!t&&m(t)&&g(t);default:return!1}}function m(e){if(y.domain){if(x)return s.getHost(e)!==s.getHost(b);var t=new RegExp("^(?:.*\\.)?"+o.escapeRegexp(b)+"$","i");return!s.getHost(e).match(t)}return s.getHost(e)!==s.getHost(document.location.href)}function l(e){var t="yandex",r="text",n="google",i=new RegExp("^(?:.*\\.)?"+o.escapeRegexp(t)+"\\..{2,9}$"),a=new RegExp(".*"+o.escapeRegexp(r)+"=.*"),c=new RegExp("^(?:www\\.)?"+o.escapeRegexp(n)+"\\..{2,9}$");if(s.parse(e).query&&s.parse(e).host.match(i)&&s.parse(e).query.match(a))return q=t,!0;if(s.parse(e).host.match(c))return q=n,!0;if(!s.parse(e).query)return!1;for(var u=0;u<y.organics.length;u++){if(s.parse(e).host.match(new RegExp("^(?:.*\\.)?"+o.escapeRegexp(y.organics[u].host)+"$","i"))&&s.parse(e).query.match(new RegExp(".*"+o.escapeRegexp(y.organics[u].param)+"=.*","i")))return q=y.organics[u].display||y.organics[u].host,!0;if(u+1===y.organics.length)return!1}}function g(e){if(!(y.referrals.length>0))return q=s.getHost(e),!0;for(var t=0;t<y.referrals.length;t++){if(s.parse(e).host.match(new RegExp("^(?:.*\\.)?"+o.escapeRegexp(y.referrals[t].host)+"$","i")))return q=y.referrals[t].display||y.referrals[t].host,I=y.referrals[t].medium||i.referer.referral,!0;if(t+1===y.referrals.length)return q=s.getHost(e),!0}}function _(){a.set(n.containers.current_extra,n.pack.extra(y.timezone_offset),k,b,x),a.get(n.containers.first_extra)||a.set(n.containers.first_extra,n.pack.extra(y.timezone_offset),k,b,x)}function h(){var e=v.gclid||"",t=v.gbraid||"",r=v.wbraid||"",n=v.fbclid||"",i=v.ttclid||"",s="sd"===v.utm_source?v.utm_term||"":"";""!==t&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-gbraid",t,k,b,x)),""!==r&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-wbraid",r,k,b,x)),""!==e&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-gclid",e,k,b,x)),""!==n&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-fbclid",n,k,b,x)),""!==i&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-ttclid",i,k,b,x)),""!==s&&a.set("_mate-sdclid",s,k,b,x)}var y=c.fetch(e),v=s.getParam(),b=y.domain.host,x=y.domain.isolate,k=y.lifetime;u.go(k,b,x);var w,q,I,j,R,D,H,T,E,O,$;return function(){var e=t();a.set(n.containers.current,e.data,k,b,x),a.get(n.containers.first)||a.set(n.containers.first,a.get(n.containers.current),k,b,x);var r,i;a.get(n.containers.udata)?(r=parseInt(a.parse(n.containers.udata)[a.unsbjs(n.containers.udata)][n.aliases.udata.visits])||1,r=a.get(n.containers.session)?r:r+1,i=n.pack.user(r,y.user_ip)):(r=1,i=n.pack.user(r,y.user_ip)),a.set(n.containers.udata,i,k,b,x);var s,o;a.get(n.containers.session)?(s=parseInt(a.parse(n.containers.session)[a.unsbjs(n.containers.session)][n.aliases.session.pages_seen])||1,s+=1):s=1,a.get(n.containers.session)&&!e.is_utm_changed||(o=(new Date).getTime()),a.set(n.containers.session,n.pack.session(s,o),y.session_length,b,x),y.promocode&&!a.get(n.containers.promocode)&&a.set(n.containers.promocode,n.pack.promo(y.promocode),k,b,x)}(),a.parse(n.containers)}},{"./data":2,"./helpers/cookies":3,"./helpers/uri":4,"./helpers/utils":5,"./migrations":7,"./params":8,"./terms":9}],7:[function(e,t,r){"use strict";var n=e("./data"),i=e("./helpers/cookies");t.exports={go:function(e,t,r){var a,s=this.migrations,o={l:e,d:t,i:r};if(i.get(n.containers.first)||i.get(n.service.migrations)){if(!i.get(n.service.migrations))for(a=0;a<s.length;a++)s[a].go(s[a].id,o)}else{var c=[];for(a=0;a<s.length;a++)c.push(s[a].id);var u="";for(a=0;a<c.length;a++)u+=c[a]+"=1",a<c.length-1&&(u+=n.delimiter);i.set(n.service.migrations,u,o.l,o.d,o.i)}},migrations:[{id:"1418474375998",version:"1.0.0-beta",go:function(e,t){var r=e+"=1",a=e+"=0",s=function(e,t,r){return t||r?e:n.delimiter};try{var o=[];for(var c in n.containers)n.containers.hasOwnProperty(c)&&o.push(n.containers[c]);for(var u=0;u<o.length;u++)if(i.get(o[u])){var d=i.get(o[u]).replace(/(\|)?\|(\|)?/g,s);i.destroy(o[u],t.d,t.i),i.destroy(o[u],t.d,!t.i),i.set(o[u],d,t.l,t.d,t.i)}i.get(n.containers.session)&&i.set(n.containers.session,n.pack.session(0),t.l,t.d,t.i),i.set(n.service.migrations,r,t.l,t.d,t.i)}catch(p){i.set(n.service.migrations,a,t.l,t.d,t.i)}}}]}},{"./data":2,"./helpers/cookies":3}],8:[function(e,t,r){"use strict";var n=e("./terms"),i=e("./helpers/uri");t.exports={fetch:function(e){var t=e||{},r={};if(r.lifetime=this.validate.checkFloat(t.lifetime)||6,r.lifetime=parseInt(30*r.lifetime*24*60),r.session_length=this.validate.checkInt(t.session_length)||30,r.timezone_offset=this.validate.checkInt(t.timezone_offset),r.campaign_param=t.campaign_param||!1,r.term_param=t.term_param||!1,r.content_param=t.content_param||!1,r.user_ip=t.user_ip||n.none,t.promocode?(r.promocode={},r.promocode.min=parseInt(t.promocode.min)||1e5,r.promocode.max=parseInt(t.promocode.max)||999999):r.promocode=!1,t.typein_attributes&&t.typein_attributes.source&&t.typein_attributes.medium?(r.typein_attributes={},r.typein_attributes.source=t.typein_attributes.source,r.typein_attributes.medium=t.typein_attributes.medium):r.typein_attributes={source:"(direct)",medium:"(none)"},t.domain&&this.validate.isString(t.domain)?r.domain={host:t.domain,isolate:!1}:t.domain&&t.domain.host?r.domain=t.domain:r.domain={host:i.getHost(document.location.hostname),isolate:!1},r.referrals=[],t.referrals&&t.referrals.length>0)for(var a=0;a<t.referrals.length;a++)t.referrals[a].host&&r.referrals.push(t.referrals[a]);if(r.organics=[],t.organics&&t.organics.length>0)for(var s=0;s<t.organics.length;s++)t.organics[s].host&&t.organics[s].param&&r.organics.push(t.organics[s]);return r.organics.push({host:"bing.com",param:"q",display:"bing"}),r.organics.push({host:"yahoo.com",param:"p",display:"yahoo"}),r.organics.push({host:"about.com",param:"q",display:"about"}),r.organics.push({host:"aol.com",param:"q",display:"aol"}),r.organics.push({host:"ask.com",param:"q",display:"ask"}),r.organics.push({host:"globososo.com",param:"q",display:"globo"}),r.organics.push({host:"go.mail.ru",param:"q",display:"go.mail.ru"}),r.organics.push({host:"rambler.ru",param:"query",display:"rambler"}),r.organics.push({host:"tut.by",param:"query",display:"tut.by"}),r.referrals.push({host:"t.co",display:"twitter.com"}),r.referrals.push({host:"plus.url.google.com",display:"plus.google.com"}),r},validate:{checkFloat:function(e){return!(!e||!this.isNumeric(parseFloat(e)))&&parseFloat(e)},checkInt:function(e){return!(!e||!this.isNumeric(parseInt(e)))&&parseInt(e)},isNumeric:function(e){return!isNaN(e)},isString:function(e){return"[object String]"===Object.prototype.toString.call(e)}}}},{"./helpers/uri":4,"./terms":9}],9:[function(e,t,r){"use strict";t.exports={traffic:{utm:"utm",organic:"organic",referral:"referral",typein:"typein"},referer:{referral:"referral",organic:"organic",social:"social"},none:"(none)",oops:"(Houston, we have a problem)"}},{}]},{},[1])(1)});
@@ -0,0 +1,225 @@
1
+ # Testing Guide for Sourcebuster.js
2
+
3
+ This document describes how to write and run tests for the sourcebuster-js package.
4
+
5
+ ## Overview
6
+
7
+ Sourcebuster.js is a browser JavaScript library that tracks visitor sources using cookies and URL parameters. The test infrastructure uses:
8
+ - **Jest**: Test runner with built-in assertions
9
+ - **jest-environment-jsdom**: Simulates browser environment (document, window, location)
10
+
11
+ ## Running Tests
12
+
13
+ ```bash
14
+ cd packages/sourcebuster-js
15
+
16
+ # Run all tests
17
+ npm test
18
+
19
+ # Run tests in watch mode
20
+ npm run test:watch
21
+
22
+ # Run with coverage report
23
+ npm run test:coverage
24
+
25
+ # Run specific test file
26
+ npm test -- src/js/init.test.js
27
+ ```
28
+
29
+ ## Test Structure
30
+
31
+ Tests are **colocated** with source files (no separate `__tests__` directory):
32
+
33
+ ```
34
+ src/js/
35
+ ├── init.js # Source file
36
+ ├── init.test.js # Tests for init.js (utm_type override)
37
+ ├── test.setup.js # Global test setup and browser mocks
38
+ ├── sourcebuster.js
39
+ └── ...
40
+ ```
41
+
42
+ ## Writing Tests
43
+
44
+ ### Test File Pattern
45
+
46
+ Use ES5 syntax to match the codebase style:
47
+
48
+ ```javascript
49
+ "use strict";
50
+
51
+ describe('feature name', function() {
52
+ describe('scenario group', function() {
53
+ it('should do something when condition', function() {
54
+ // Arrange
55
+ setLocation('https://example.com/?utm_source=test');
56
+
57
+ // Act
58
+ var sbjs = require('../sourcebuster');
59
+ sbjs.init();
60
+
61
+ // Assert
62
+ expect(sbjs.get.current.typ).toBe('utm');
63
+ });
64
+ });
65
+ });
66
+ ```
67
+
68
+ ### Key Points
69
+
70
+ 1. **Fresh module per test**: Use `require('../sourcebuster')` inside each test, not at file top. The setup file calls `jest.resetModules()` in `beforeEach` to ensure clean state.
71
+
72
+ 2. **Global helpers**: Available from setup.js:
73
+ - `setLocation(url)` - Set window.location
74
+ - `setReferrer(url)` - Set document.referrer
75
+ - `clearCookies()` - Clear all cookies
76
+ - `setCookie(name, value)` - Set a cookie directly
77
+ - `getCookie(name)` - Get a cookie value
78
+
79
+ 3. **Automatic cleanup**: `beforeEach` in setup.js automatically:
80
+ - Clears all cookies
81
+ - Resets location to `https://example.com/`
82
+ - Clears referrer
83
+ - Resets module cache
84
+
85
+ ### Example: Testing utm_type Override
86
+
87
+ ```javascript
88
+ "use strict";
89
+
90
+ describe('utm_type override', function() {
91
+ it('should set typ to organic when utm_type=organic', function() {
92
+ setLocation('https://example.com/?utm_type=organic&utm_source=google&utm_medium=organic');
93
+
94
+ var sbjs = require('../sourcebuster');
95
+ sbjs.init();
96
+
97
+ expect(sbjs.get.current.typ).toBe('organic');
98
+ expect(sbjs.get.current.src).toBe('google');
99
+ expect(sbjs.get.current.mdm).toBe('organic');
100
+ });
101
+
102
+ it('should default to typ=utm when no utm_type', function() {
103
+ setLocation('https://example.com/?utm_source=facebook&utm_medium=cpc');
104
+
105
+ var sbjs = require('../sourcebuster');
106
+ sbjs.init();
107
+
108
+ expect(sbjs.get.current.typ).toBe('utm');
109
+ });
110
+ });
111
+ ```
112
+
113
+ ### Example: Testing Cookie Behavior
114
+
115
+ ```javascript
116
+ "use strict";
117
+
118
+ describe('cookie persistence', function() {
119
+ it('should persist session data in cookie', function() {
120
+ setLocation('https://example.com/?utm_source=test');
121
+
122
+ var sbjs = require('../sourcebuster');
123
+ sbjs.init();
124
+
125
+ var cookie = getCookie('sbjs_current');
126
+ expect(cookie).toBeDefined();
127
+ expect(cookie).toContain('src=test');
128
+ });
129
+
130
+ it('should preserve existing cookie when no new params', function() {
131
+ setCookie('sbjs_current', 'typ=utm|||src=facebook|||mdm=cpc|||cmp=(none)|||cnt=(none)|||trm=(none)');
132
+ setLocation('https://example.com/');
133
+
134
+ var sbjs = require('../sourcebuster');
135
+ sbjs.init();
136
+
137
+ expect(sbjs.get.current.src).toBe('facebook');
138
+ });
139
+ });
140
+ ```
141
+
142
+ ## Best Practices
143
+
144
+ ### Test Isolation
145
+
146
+ Each test must be independent:
147
+ - Don't rely on state from previous tests
148
+ - The setup file handles cleanup automatically
149
+ - Always require the module fresh in each test
150
+
151
+ ### Test Naming
152
+
153
+ Use descriptive names:
154
+ - `describe` for grouping related tests
155
+ - `it` with format: "should [behavior] when [condition]"
156
+
157
+ ### Assertions
158
+
159
+ Use specific assertions:
160
+ ```javascript
161
+ // Good - specific
162
+ expect(sbjs.get.current.typ).toBe('organic');
163
+
164
+ // Avoid - too generic
165
+ expect(sbjs.get.current).toBeDefined();
166
+ ```
167
+
168
+ ## Configuration Files
169
+
170
+ ### jest.config.js
171
+
172
+ ```javascript
173
+ module.exports = {
174
+ testEnvironment: 'jsdom',
175
+ testMatch: ['**/src/js/**/*.test.js'],
176
+ setupFilesAfterEnv: ['<rootDir>/src/js/test.setup.js'],
177
+ moduleFileExtensions: ['js'],
178
+ verbose: true,
179
+ collectCoverageFrom: [
180
+ 'src/js/**/*.js',
181
+ '!src/js/**/*.test.js',
182
+ '!src/js/test.setup.js',
183
+ ],
184
+ };
185
+ ```
186
+
187
+ ### test.setup.js
188
+
189
+ The setup file provides:
190
+ - Cookie mocking via `Object.defineProperty(document, 'cookie', ...)`
191
+ - Location mocking via `Object.defineProperty(window, 'location', ...)`
192
+ - Referrer mocking via `Object.defineProperty(document, 'referrer', ...)`
193
+ - `beforeEach` hook that resets state and clears module cache
194
+
195
+ ## Troubleshooting
196
+
197
+ ### Tests affecting each other
198
+
199
+ Ensure you're requiring the module inside each test:
200
+ ```javascript
201
+ // Wrong - shared state
202
+ var sbjs = require('../sourcebuster');
203
+
204
+ describe('tests', function() {
205
+ it('test 1', function() {
206
+ sbjs.init(); // Uses cached module state
207
+ });
208
+ });
209
+
210
+ // Correct - fresh state per test
211
+ describe('tests', function() {
212
+ it('test 1', function() {
213
+ var sbjs = require('../sourcebuster');
214
+ sbjs.init();
215
+ });
216
+ });
217
+ ```
218
+
219
+ ### Cookie not being set
220
+
221
+ Check the setup.js cookie mock handles the cookie format correctly. The sourcebuster library uses `|||` as field separator.
222
+
223
+ ### Location not being read
224
+
225
+ Ensure `setLocation()` is called before requiring the module, as the module reads `window.location.search` during initialization.
@@ -0,0 +1,131 @@
1
+ # UTM Type Override Feature
2
+
3
+ ## Problem
4
+
5
+ Mixed attribution bug occurs when:
6
+ 1. User clicks paid ad (gclid) → `typ=utm, mdm=cpc`
7
+ 2. User returns organically → `typ=organic, mdm=organic`
8
+ 3. Backend redirect includes: `?utm_source=google&utm_medium=organic`
9
+ 4. Sourcebuster sees `utm_source` → sets `typ=utm` (ignoring actual organic attribution)
10
+ 5. Result: `typ=utm, mdm=organic` (MIXED - incorrect!)
11
+
12
+ ## Root Cause
13
+
14
+ Sourcebuster sets `typ='utm'` whenever ANY utm_* parameter exists in URL, regardless of the actual traffic type.
15
+
16
+ ## Solution
17
+
18
+ Add support for `utm_type` URL parameter to explicitly set the `typ` field.
19
+
20
+ ### Changes Required
21
+
22
+ #### 1. Sourcebuster.js (`packages/sourcebuster-js/src/js/init.js`)
23
+
24
+ **Location:** Line 123, inside `case terms.traffic.utm:`
25
+
26
+ **Before:**
27
+ ```javascript
28
+ __sbjs_type = terms.traffic.utm;
29
+ ```
30
+
31
+ **After:**
32
+ ```javascript
33
+ if (typeof get_param.utm_type !== 'undefined') {
34
+ __sbjs_type = get_param.utm_type;
35
+ } else {
36
+ __sbjs_type = terms.traffic.utm;
37
+ }
38
+ ```
39
+
40
+ #### 2. Backend (`api/src/modules/utmTags/UtmTags.helpers.ts`)
41
+
42
+ **Keep `lvType` in the whitelist** so `utm_type` is included in redirect URLs.
43
+
44
+ The whitelist should include:
45
+ - `lvType` → `utm_type`
46
+ - `lvSource` → `utm_source`
47
+ - `lvMedium` → `utm_medium`
48
+ - `lvCampaign` → `utm_campaign`
49
+ - `lvContent` → `utm_content`
50
+ - `lvTerm` → `utm_term`
51
+ - `lvAccountId` → `utm_ac_id`
52
+ - `lvCampaignId` → `utm_id`
53
+ - `lvAdGroupId` → `utm_ad_group_id`
54
+ - `lvAdId` → `utm_ad_id`
55
+ - `lvTermId` → `utm_term_id`
56
+
57
+ Click IDs (gclid, gbraid, fbclid, etc.) should NOT be in redirect URLs - they stay in cookies.
58
+
59
+ ## Expected Behavior After Fix
60
+
61
+ ### Scenario: Paid → Organic → Form Submit
62
+
63
+ 1. User clicks ad with `gclid=xxx`
64
+ - Sourcebuster: `typ=utm, src=google, mdm=cpc`
65
+ - Cookies: `_mate-gclid=xxx`
66
+
67
+ 2. User returns via Google organic search
68
+ - Sourcebuster updates: `typ=organic, src=google, mdm=organic`
69
+ - Cookie `_mate-gclid` persists (30-day lifetime)
70
+
71
+ 3. User submits form → Backend creates redirect:
72
+ ```
73
+ /success?utm_type=organic&utm_source=google&utm_medium=organic
74
+ ```
75
+ (No gclid in URL - stays in cookie)
76
+
77
+ 4. Success page loads:
78
+ - Sourcebuster reads `utm_type=organic` → sets `typ=organic`
79
+ - Result: `typ=organic, src=google, mdm=organic` ✅ CORRECT!
80
+
81
+ 5. Google Ads conversion tracking:
82
+ - gtag.js reads `_mate-gclid` from cookie
83
+ - Conversion attributed correctly ✅
84
+
85
+ ## Test Coverage
86
+
87
+ ### Unit Tests (Sourcebuster.js)
88
+
89
+ Location: `packages/sourcebuster-js/src/js/__tests__/`
90
+
91
+ 1. **utm_type override test**
92
+ - URL: `?utm_type=organic&utm_source=google&utm_medium=organic`
93
+ - Expected: `typ=organic, src=google, mdm=organic`
94
+
95
+ 2. **utm_type=utm test (explicit)**
96
+ - URL: `?utm_type=utm&utm_source=facebook&utm_medium=cpc`
97
+ - Expected: `typ=utm, src=facebook, mdm=cpc`
98
+
99
+ 3. **No utm_type (fallback to default)**
100
+ - URL: `?utm_source=facebook&utm_medium=cpc`
101
+ - Expected: `typ=utm, src=facebook, mdm=cpc`
102
+
103
+ 4. **gclid without utm_type (default behavior)**
104
+ - URL: `?gclid=xxx`
105
+ - Expected: `typ=utm, src=google, mdm=cpc`
106
+
107
+ ### E2E Tests
108
+
109
+ Location: `e2e/tests/playwright/e2e_analytics/UTM_Tags/Mixed_Attribution/`
110
+
111
+ 1. **paidToOrganicCookieBehavior.spec.ts** (existing, update expectations)
112
+ - Verify organic attribution preserved after redirect
113
+ - Verify click ID cookies persist
114
+ - Verify no mixed attribution
115
+
116
+ 2. **utmTypeOverride.spec.ts** (new)
117
+ - Test utm_type=organic overrides default utm type
118
+ - Test utm_type=utm explicitly sets utm type
119
+ - Test missing utm_type uses default behavior
120
+
121
+ ### Integration Tests (Backend)
122
+
123
+ Location: `api/src/modules/utmTags/__tests__/`
124
+
125
+ 1. **getUtmParamsForRedirect includes lvType**
126
+ - Input: `{ lvType: 'organic', lvSource: 'google', lvMedium: 'organic' }`
127
+ - Output: `{ utm_type: 'organic', utm_source: 'google', utm_medium: 'organic' }`
128
+
129
+ 2. **getUtmParamsForRedirect excludes click IDs**
130
+ - Input: `{ lvType: 'organic', gclid: 'xxx', gbraid: 'yyy' }`
131
+ - Output: `{ utm_type: 'organic' }` (no gclid/gbraid)
package/jest.config.js ADDED
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ testEnvironment: 'jsdom',
3
+ testMatch: ['**/src/js/**/*.test.js'],
4
+ setupFilesAfterEnv: ['<rootDir>/src/js/test.setup.js'],
5
+ moduleFileExtensions: ['js'],
6
+ verbose: true,
7
+ collectCoverageFrom: [
8
+ 'src/js/**/*.js',
9
+ '!src/js/**/*.test.js',
10
+ '!src/js/test.setup.js',
11
+ ],
12
+ };
package/package.json CHANGED
@@ -1,14 +1,17 @@
1
1
  {
2
2
  "name": "@mate-academy/sourcebuster",
3
- "version": "1.3.5",
3
+ "version": "1.4.0",
4
4
  "description": "Get sources of your site's visitors (utm / organic / referral / typein).",
5
5
  "license": "MIT",
6
6
  "main": "./dist/sourcebuster.js",
7
7
  "scripts": {
8
8
  "build": "NODE_ENV=production gulp build",
9
- "patch": "npm version patch && npm run build && npm publish",
10
- "minor": "npm version minor && npm run build && npm publish",
11
- "major": "npm version major && npm run build && npm publish",
9
+ "test": "jest",
10
+ "test:watch": "jest --watch",
11
+ "test:coverage": "jest --coverage",
12
+ "patch": "npm run test && npm version patch && npm run build && npm publish",
13
+ "minor": "npm run test && npm version minor && npm run build && npm publish",
14
+ "major": "npm run test && npm version major && npm run build && npm publish",
12
15
  "publish-webflow": "sh publish_current_version_to_webflow.sh"
13
16
  },
14
17
  "lintOptions": {
@@ -53,6 +56,8 @@
53
56
  "gulp-sourcemaps": "^1.2.8",
54
57
  "gulp-uglify": "^1.0.2",
55
58
  "gulp-util": "^3.0.1",
59
+ "jest": "^29.7.0",
60
+ "jest-environment-jsdom": "^29.7.0",
56
61
  "map-stream": "0.0.5",
57
62
  "node-notifier": "^4.0.3",
58
63
  "require-dir": "^0.3.2",
@@ -1,2 +1,2 @@
1
- /** @mate-academy/sourcebuster v1.3.5 **/
2
- !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.sbjs=e()}}(function(){return function e(t,r,n){function i(s,o){if(!r[s]){if(!t[s]){var c="function"==typeof require&&require;if(!o&&c)return c(s,!0);if(a)return a(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var d=r[s]={exports:{}};t[s][0].call(d.exports,function(e){var r=t[s][1][e];return i(r?r:e)},d,d.exports,e,t,r,n)}return r[s].exports}for(var a="function"==typeof require&&require,s=0;s<n.length;s++)i(n[s]);return i}({1:[function(e,t,r){"use strict";var n=e("./init"),i={init:function(e){this.get=n(e),e&&e.callback&&"function"==typeof e.callback&&e.callback(this.get)}};t.exports=i},{"./init":6}],2:[function(e,t,r){"use strict";var n=e("./terms"),i=e("./helpers/utils"),a={containers:{current:"sbjs_current",current_extra:"sbjs_current_add",first:"sbjs_first",first_extra:"sbjs_first_add",session:"sbjs_session",udata:"sbjs_udata",promocode:"sbjs_promo"},service:{migrations:"sbjs_migrations"},delimiter:"|||",aliases:{main:{type:"typ",source:"src",medium:"mdm",campaign:"cmp",content:"cnt",term:"trm",account_id:"ac_id",campaign_id:"cmp_id",ad_group_id:"adg_id",ad_id:"ad_id",term_id:"trm_id"},extra:{fire_date:"fd",entrance_point:"ep",referer:"rf"},session:{pages_seen:"pgs",current_page:"cpg",session_id:"sid"},udata:{visits:"vst",ip:"uip",agent:"uag"},promo:"code"},pack:{main:function(e){return a.aliases.main.type+"="+e.type+a.delimiter+a.aliases.main.source+"="+e.source+a.delimiter+a.aliases.main.medium+"="+e.medium+a.delimiter+a.aliases.main.campaign+"="+e.campaign+a.delimiter+a.aliases.main.content+"="+e.content+a.delimiter+a.aliases.main.term+"="+e.term+a.delimiter+a.aliases.main.account_id+"="+e.account_id+a.delimiter+a.aliases.main.campaign_id+"="+e.campaign_id+a.delimiter+a.aliases.main.ad_group_id+"="+e.ad_group_id+a.delimiter+a.aliases.main.ad_id+"="+e.ad_id+a.delimiter+a.aliases.main.term_id+"="+e.term_id},unpack:function(e){var t={},r=e.split("|||");return r.forEach(function(e){var r=e.split("="),n=r[0],i=r[1];t[n]=i}),t},extra:function(e){return a.aliases.extra.fire_date+"="+i.setDate(new Date,e)+a.delimiter+a.aliases.extra.entrance_point+"="+document.location.href+a.delimiter+a.aliases.extra.referer+"="+(document.referrer||n.none)},user:function(e,t){return a.aliases.udata.visits+"="+e+a.delimiter+a.aliases.udata.ip+"="+t+a.delimiter+a.aliases.udata.agent+"="+navigator.userAgent},session:function(e,t){var r=a.aliases.session.pages_seen+"="+e+a.delimiter+a.aliases.session.current_page+"="+document.location.href;return t?r+a.delimiter+a.aliases.session.session_id+"="+t:r},promo:function(e){return a.aliases.promo+"="+i.setLeadingZeroToInt(i.randomInt(e.min,e.max),e.max.toString().length)}}};t.exports=a},{"./helpers/utils":5,"./terms":9}],3:[function(e,t,r){"use strict";var n=e("../data").delimiter;t.exports={encodeData:function(e){return encodeURIComponent(e).replace(/\!/g,"%21").replace(/\~/g,"%7E").replace(/\*/g,"%2A").replace(/\'/g,"%27").replace(/\(/g,"%28").replace(/\)/g,"%29")},decodeData:function(e){try{return decodeURIComponent(e).replace(/\%21/g,"!").replace(/\%7E/g,"~").replace(/\%2A/g,"*").replace(/\%27/g,"'").replace(/\%28/g,"(").replace(/\%29/g,")")}catch(t){try{return unescape(e)}catch(r){return""}}},set:function(e,t,r,n,i){var a,s;if(r){var o=new Date;o.setTime(o.getTime()+60*r*1e3),a="; expires="+o.toGMTString()}else a="";s=n&&!i?";domain=."+n:"",document.cookie=this.encodeData(e)+"="+this.encodeData(t)+a+s+"; path=/"},get:function(e){for(var t=this.encodeData(e)+"=",r=document.cookie.split(";"),n=0;n<r.length;n++){for(var i=r[n];" "===i.charAt(0);)i=i.substring(1,i.length);if(0===i.indexOf(t))return this.decodeData(i.substring(t.length,i.length))}return null},destroy:function(e,t,r){this.set(e,"",-1,t,r)},parse:function(e){var t=[],r={};if("string"==typeof e)t.push(e);else for(var i in e)e.hasOwnProperty(i)&&t.push(e[i]);for(var a=0;a<t.length;a++){var s;r[this.unsbjs(t[a])]={},s=this.get(t[a])?this.get(t[a]).split(n):[];for(var o=0;o<s.length;o++){var c=s[o].split("="),u=c.splice(0,1);u.push(c.join("=")),r[this.unsbjs(t[a])][u[0]]=this.decodeData(u[1])}}return r},unsbjs:function(e){return e.replace("sbjs_","")}}},{"../data":2}],4:[function(e,t,r){"use strict";t.exports={parse:function(e){for(var t=this.parseOptions,r=t.parser[t.strictMode?"strict":"loose"].exec(e),n={},i=14;i--;)n[t.key[i]]=r[i]||"";return n[t.q.name]={},n[t.key[12]].replace(t.q.parser,function(e,r,i){r&&(n[t.q.name][r]=i)}),n},parseOptions:{strictMode:!1,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}},getParam:function(e){for(var t={},r=e?e:window.location.search.substring(1),n=r.split("&"),i=0;i<n.length;i++){var a=n[i].split("=");if("undefined"==typeof t[a[0]])t[a[0]]=a[1];else if("string"==typeof t[a[0]]){var s=[t[a[0]],a[1]];t[a[0]]=s}else t[a[0]].push(a[1])}return t},getHost:function(e){return this.parse(e).host.replace("www.","")}}},{}],5:[function(e,t,r){"use strict";t.exports={escapeRegexp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},setDate:function(e,t){var r=e.getTimezoneOffset()/60,n=e.getHours(),i=t||0===t?t:-r;e.setHours(n+r+i);var a=e.getFullYear(),s=this.setLeadingZeroToInt(e.getMonth()+1,2),o=this.setLeadingZeroToInt(e.getDate(),2),c=this.setLeadingZeroToInt(e.getHours(),2),u=this.setLeadingZeroToInt(e.getMinutes(),2),d=this.setLeadingZeroToInt(e.getSeconds(),2);return a+"-"+s+"-"+o+" "+c+":"+u+":"+d},setLeadingZeroToInt:function(e,t){for(var r=e+"";r.length<t;)r="0"+r;return r},randomInt:function(e,t){return Math.floor(Math.random()*(t-e+1))+e}}},{}],6:[function(e,t,r){"use strict";var n=e("./data"),i=e("./terms"),a=e("./helpers/cookies"),s=e("./helpers/uri"),o=e("./helpers/utils"),c=e("./params"),u=e("./migrations");t.exports=function(e){function t(){var e,t,s,o="undefined"!=typeof v.utm_source||"undefined"!=typeof v.utm_medium||"undefined"!=typeof v.utm_campaign||"undefined"!=typeof v.utm_content||"undefined"!=typeof v.utm_term||"undefined"!=typeof v.utm_ac_id||"undefined"!=typeof v.utm_id||"undefined"!=typeof v.utm_ad_group_id||"undefined"!=typeof v.utm_ad_id||"undefined"!=typeof v.utm_term_id||"undefined"!=typeof v.gclid||"undefined"!=typeof v.yclid||"undefined"!=typeof v[y.campaign_param]||"undefined"!=typeof v[y.term_param]||"undefined"!=typeof v[y.content_param],c=a.parse(n.containers),u=c[a.unsbjs(n.containers.current)],p=f(i.traffic.organic),m=!1;if(h(),o)_(),e=d(i.traffic.utm),t=u,s=n.pack.unpack(e),m=r(t,s);else if(p)_(),e=d(i.traffic.organic),t=u,s=n.pack.unpack(e),m=r(t,s);else if(!a.get(n.containers.session)&&f(i.traffic.referral))_(),e=d(i.traffic.referral),m=!0;else{if(a.get(n.containers.first)||a.get(n.containers.current))return{data:a.get(n.containers.current),is_utm_changed:m};_(),e=d(i.traffic.typein),m=!0}return{data:e,is_utm_changed:m}}function r(e,t){return e[n.aliases.main.type]!==t[n.aliases.main.type]||e[n.aliases.main.source]!==t[n.aliases.main.source]||e[n.aliases.main.medium]!==t[n.aliases.main.medium]||e[n.aliases.main.campaign]!==t[n.aliases.main.campaign]||e[n.aliases.main.content]!==t[n.aliases.main.content]||e[n.aliases.main.term]!==t[n.aliases.main.term]}function d(e){switch(e){case i.traffic.utm:w=i.traffic.utm,q="undefined"!=typeof v.utm_source?v.utm_source:"undefined"!=typeof v.gclid?"google":"undefined"!=typeof v.yclid?"yandex":i.none,I="undefined"!=typeof v.utm_medium?v.utm_medium:"undefined"!=typeof v.gclid?"cpc":"undefined"!=typeof v.yclid?"cpc":i.none,j="undefined"!=typeof v.utm_campaign?v.utm_campaign:"undefined"!=typeof v[y.campaign_param]?v[y.campaign_param]:"undefined"!=typeof v.gclid?"google_cpc":"undefined"!=typeof v.yclid?"yandex_cpc":i.none,R="undefined"!=typeof v.utm_content?v.utm_content:"undefined"!=typeof v[y.content_param]?v[y.content_param]:i.none,D="undefined"!=typeof v.utm_term?v.utm_term:"undefined"!=typeof v[y.term_param]?v[y.term_param]:p()||i.none,H="undefined"!=typeof v.utm_ac_id?v.utm_ac_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,T="undefined"!=typeof v.utm_id?v.utm_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,E="undefined"!=typeof v.utm_ad_group_id?v.utm_ad_group_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,O="undefined"!=typeof v.utm_ad_id?v.utm_ad_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,$="undefined"!=typeof v.utm_term_id?v.utm_term_id:"undefined"!=typeof v.gclid?"google_cpc":i.none;break;case i.traffic.organic:w=i.traffic.organic,q=q||s.getHost(document.referrer),I=i.referer.organic,j=i.none,R=i.none,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;case i.traffic.referral:w=i.traffic.referral,q=q||s.getHost(document.referrer),I=I||i.referer.referral,j=i.none,R=s.parse(document.referrer).path,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;case i.traffic.typein:w=i.traffic.typein,q=y.typein_attributes.source,I=y.typein_attributes.medium,j=i.none,R=i.none,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;default:w=i.oops,q=i.oops,I=i.oops,j=i.oops,R=i.oops,D=i.oops,H=i.oops,T=i.oops,E=i.oops,O=i.oops,$=i.oops}var t={type:w,source:q,medium:I,campaign:j,content:R,term:D,account_id:H,campaign_id:T,ad_group_id:E,ad_id:O,term_id:$};return n.pack.main(t)}function p(){var e=document.referrer;if(v.utm_term)return v.utm_term;if(!(e&&s.parse(e).host&&s.parse(e).host.match(/^(?:.*\.)?yandex\..{2,9}$/i)))return!1;try{return s.getParam(s.parse(document.referrer).query).text}catch(t){return!1}}function f(e){var t=document.referrer;switch(e){case i.traffic.organic:return!!t&&m(t)&&l(t);case i.traffic.referral:return!!t&&m(t)&&g(t);default:return!1}}function m(e){if(y.domain){if(x)return s.getHost(e)!==s.getHost(b);var t=new RegExp("^(?:.*\\.)?"+o.escapeRegexp(b)+"$","i");return!s.getHost(e).match(t)}return s.getHost(e)!==s.getHost(document.location.href)}function l(e){var t="yandex",r="text",n="google",i=new RegExp("^(?:.*\\.)?"+o.escapeRegexp(t)+"\\..{2,9}$"),a=new RegExp(".*"+o.escapeRegexp(r)+"=.*"),c=new RegExp("^(?:www\\.)?"+o.escapeRegexp(n)+"\\..{2,9}$");if(s.parse(e).query&&s.parse(e).host.match(i)&&s.parse(e).query.match(a))return q=t,!0;if(s.parse(e).host.match(c))return q=n,!0;if(!s.parse(e).query)return!1;for(var u=0;u<y.organics.length;u++){if(s.parse(e).host.match(new RegExp("^(?:.*\\.)?"+o.escapeRegexp(y.organics[u].host)+"$","i"))&&s.parse(e).query.match(new RegExp(".*"+o.escapeRegexp(y.organics[u].param)+"=.*","i")))return q=y.organics[u].display||y.organics[u].host,!0;if(u+1===y.organics.length)return!1}}function g(e){if(!(y.referrals.length>0))return q=s.getHost(e),!0;for(var t=0;t<y.referrals.length;t++){if(s.parse(e).host.match(new RegExp("^(?:.*\\.)?"+o.escapeRegexp(y.referrals[t].host)+"$","i")))return q=y.referrals[t].display||y.referrals[t].host,I=y.referrals[t].medium||i.referer.referral,!0;if(t+1===y.referrals.length)return q=s.getHost(e),!0}}function _(){a.set(n.containers.current_extra,n.pack.extra(y.timezone_offset),k,b,x),a.get(n.containers.first_extra)||a.set(n.containers.first_extra,n.pack.extra(y.timezone_offset),k,b,x)}function h(){var e=v.gclid||"",t=v.gbraid||"",r=v.wbraid||"",n=v.fbclid||"",i="sd"===v.utm_source?v.utm_term||"":"";""!==t&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-gbraid",t,k,b,x)),""!==r&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-wbraid",r,k,b,x)),""!==e&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-gclid",e,k,b,x)),""!==n&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-fbclid",n,k,b,x)),""!==i&&a.set("_mate-sdclid",i,k,b,x)}var y=c.fetch(e),v=s.getParam(),b=y.domain.host,x=y.domain.isolate,k=y.lifetime;u.go(k,b,x);var w,q,I,j,R,D,H,T,E,O,$;return function(){var e=t();a.set(n.containers.current,e.data,k,b,x),a.get(n.containers.first)||a.set(n.containers.first,a.get(n.containers.current),k,b,x);var r,i;a.get(n.containers.udata)?(r=parseInt(a.parse(n.containers.udata)[a.unsbjs(n.containers.udata)][n.aliases.udata.visits])||1,r=a.get(n.containers.session)?r:r+1,i=n.pack.user(r,y.user_ip)):(r=1,i=n.pack.user(r,y.user_ip)),a.set(n.containers.udata,i,k,b,x);var s,o;a.get(n.containers.session)?(s=parseInt(a.parse(n.containers.session)[a.unsbjs(n.containers.session)][n.aliases.session.pages_seen])||1,s+=1):s=1,a.get(n.containers.session)&&!e.is_utm_changed||(o=(new Date).getTime()),a.set(n.containers.session,n.pack.session(s,o),y.session_length,b,x),y.promocode&&!a.get(n.containers.promocode)&&a.set(n.containers.promocode,n.pack.promo(y.promocode),k,b,x)}(),a.parse(n.containers)}},{"./data":2,"./helpers/cookies":3,"./helpers/uri":4,"./helpers/utils":5,"./migrations":7,"./params":8,"./terms":9}],7:[function(e,t,r){"use strict";var n=e("./data"),i=e("./helpers/cookies");t.exports={go:function(e,t,r){var a,s=this.migrations,o={l:e,d:t,i:r};if(i.get(n.containers.first)||i.get(n.service.migrations)){if(!i.get(n.service.migrations))for(a=0;a<s.length;a++)s[a].go(s[a].id,o)}else{var c=[];for(a=0;a<s.length;a++)c.push(s[a].id);var u="";for(a=0;a<c.length;a++)u+=c[a]+"=1",a<c.length-1&&(u+=n.delimiter);i.set(n.service.migrations,u,o.l,o.d,o.i)}},migrations:[{id:"1418474375998",version:"1.0.0-beta",go:function(e,t){var r=e+"=1",a=e+"=0",s=function(e,t,r){return t||r?e:n.delimiter};try{var o=[];for(var c in n.containers)n.containers.hasOwnProperty(c)&&o.push(n.containers[c]);for(var u=0;u<o.length;u++)if(i.get(o[u])){var d=i.get(o[u]).replace(/(\|)?\|(\|)?/g,s);i.destroy(o[u],t.d,t.i),i.destroy(o[u],t.d,!t.i),i.set(o[u],d,t.l,t.d,t.i)}i.get(n.containers.session)&&i.set(n.containers.session,n.pack.session(0),t.l,t.d,t.i),i.set(n.service.migrations,r,t.l,t.d,t.i)}catch(p){i.set(n.service.migrations,a,t.l,t.d,t.i)}}}]}},{"./data":2,"./helpers/cookies":3}],8:[function(e,t,r){"use strict";var n=e("./terms"),i=e("./helpers/uri");t.exports={fetch:function(e){var t=e||{},r={};if(r.lifetime=this.validate.checkFloat(t.lifetime)||6,r.lifetime=parseInt(30*r.lifetime*24*60),r.session_length=this.validate.checkInt(t.session_length)||30,r.timezone_offset=this.validate.checkInt(t.timezone_offset),r.campaign_param=t.campaign_param||!1,r.term_param=t.term_param||!1,r.content_param=t.content_param||!1,r.user_ip=t.user_ip||n.none,t.promocode?(r.promocode={},r.promocode.min=parseInt(t.promocode.min)||1e5,r.promocode.max=parseInt(t.promocode.max)||999999):r.promocode=!1,t.typein_attributes&&t.typein_attributes.source&&t.typein_attributes.medium?(r.typein_attributes={},r.typein_attributes.source=t.typein_attributes.source,r.typein_attributes.medium=t.typein_attributes.medium):r.typein_attributes={source:"(direct)",medium:"(none)"},t.domain&&this.validate.isString(t.domain)?r.domain={host:t.domain,isolate:!1}:t.domain&&t.domain.host?r.domain=t.domain:r.domain={host:i.getHost(document.location.hostname),isolate:!1},r.referrals=[],t.referrals&&t.referrals.length>0)for(var a=0;a<t.referrals.length;a++)t.referrals[a].host&&r.referrals.push(t.referrals[a]);if(r.organics=[],t.organics&&t.organics.length>0)for(var s=0;s<t.organics.length;s++)t.organics[s].host&&t.organics[s].param&&r.organics.push(t.organics[s]);return r.organics.push({host:"bing.com",param:"q",display:"bing"}),r.organics.push({host:"yahoo.com",param:"p",display:"yahoo"}),r.organics.push({host:"about.com",param:"q",display:"about"}),r.organics.push({host:"aol.com",param:"q",display:"aol"}),r.organics.push({host:"ask.com",param:"q",display:"ask"}),r.organics.push({host:"globososo.com",param:"q",display:"globo"}),r.organics.push({host:"go.mail.ru",param:"q",display:"go.mail.ru"}),r.organics.push({host:"rambler.ru",param:"query",display:"rambler"}),r.organics.push({host:"tut.by",param:"query",display:"tut.by"}),r.referrals.push({host:"t.co",display:"twitter.com"}),r.referrals.push({host:"plus.url.google.com",display:"plus.google.com"}),r},validate:{checkFloat:function(e){return!(!e||!this.isNumeric(parseFloat(e)))&&parseFloat(e)},checkInt:function(e){return!(!e||!this.isNumeric(parseInt(e)))&&parseInt(e)},isNumeric:function(e){return!isNaN(e)},isString:function(e){return"[object String]"===Object.prototype.toString.call(e)}}}},{"./helpers/uri":4,"./terms":9}],9:[function(e,t,r){"use strict";t.exports={traffic:{utm:"utm",organic:"organic",referral:"referral",typein:"typein"},referer:{referral:"referral",organic:"organic",social:"social"},none:"(none)",oops:"(Houston, we have a problem)"}},{}]},{},[1])(1)});
1
+ /** @mate-academy/sourcebuster v1.4.0 **/
2
+ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.sbjs=e()}}(function(){return function e(t,r,n){function i(s,o){if(!r[s]){if(!t[s]){var c="function"==typeof require&&require;if(!o&&c)return c(s,!0);if(a)return a(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var d=r[s]={exports:{}};t[s][0].call(d.exports,function(e){var r=t[s][1][e];return i(r?r:e)},d,d.exports,e,t,r,n)}return r[s].exports}for(var a="function"==typeof require&&require,s=0;s<n.length;s++)i(n[s]);return i}({1:[function(e,t,r){"use strict";var n=e("./init"),i={init:function(e){this.get=n(e),e&&e.callback&&"function"==typeof e.callback&&e.callback(this.get)}};t.exports=i},{"./init":6}],2:[function(e,t,r){"use strict";var n=e("./terms"),i=e("./helpers/utils"),a={containers:{current:"sbjs_current",current_extra:"sbjs_current_add",first:"sbjs_first",first_extra:"sbjs_first_add",session:"sbjs_session",udata:"sbjs_udata",promocode:"sbjs_promo"},service:{migrations:"sbjs_migrations"},delimiter:"|||",aliases:{main:{type:"typ",source:"src",medium:"mdm",campaign:"cmp",content:"cnt",term:"trm",account_id:"ac_id",campaign_id:"cmp_id",ad_group_id:"adg_id",ad_id:"ad_id",term_id:"trm_id"},extra:{fire_date:"fd",entrance_point:"ep",referer:"rf"},session:{pages_seen:"pgs",current_page:"cpg",session_id:"sid"},udata:{visits:"vst",ip:"uip",agent:"uag"},promo:"code"},pack:{main:function(e){return a.aliases.main.type+"="+e.type+a.delimiter+a.aliases.main.source+"="+e.source+a.delimiter+a.aliases.main.medium+"="+e.medium+a.delimiter+a.aliases.main.campaign+"="+e.campaign+a.delimiter+a.aliases.main.content+"="+e.content+a.delimiter+a.aliases.main.term+"="+e.term+a.delimiter+a.aliases.main.account_id+"="+e.account_id+a.delimiter+a.aliases.main.campaign_id+"="+e.campaign_id+a.delimiter+a.aliases.main.ad_group_id+"="+e.ad_group_id+a.delimiter+a.aliases.main.ad_id+"="+e.ad_id+a.delimiter+a.aliases.main.term_id+"="+e.term_id},unpack:function(e){var t={},r=e.split("|||");return r.forEach(function(e){var r=e.split("="),n=r[0],i=r[1];t[n]=i}),t},extra:function(e){return a.aliases.extra.fire_date+"="+i.setDate(new Date,e)+a.delimiter+a.aliases.extra.entrance_point+"="+document.location.href+a.delimiter+a.aliases.extra.referer+"="+(document.referrer||n.none)},user:function(e,t){return a.aliases.udata.visits+"="+e+a.delimiter+a.aliases.udata.ip+"="+t+a.delimiter+a.aliases.udata.agent+"="+navigator.userAgent},session:function(e,t){var r=a.aliases.session.pages_seen+"="+e+a.delimiter+a.aliases.session.current_page+"="+document.location.href;return t?r+a.delimiter+a.aliases.session.session_id+"="+t:r},promo:function(e){return a.aliases.promo+"="+i.setLeadingZeroToInt(i.randomInt(e.min,e.max),e.max.toString().length)}}};t.exports=a},{"./helpers/utils":5,"./terms":9}],3:[function(e,t,r){"use strict";var n=e("../data").delimiter;t.exports={encodeData:function(e){return encodeURIComponent(e).replace(/\!/g,"%21").replace(/\~/g,"%7E").replace(/\*/g,"%2A").replace(/\'/g,"%27").replace(/\(/g,"%28").replace(/\)/g,"%29")},decodeData:function(e){try{return decodeURIComponent(e).replace(/\%21/g,"!").replace(/\%7E/g,"~").replace(/\%2A/g,"*").replace(/\%27/g,"'").replace(/\%28/g,"(").replace(/\%29/g,")")}catch(t){try{return unescape(e)}catch(r){return""}}},set:function(e,t,r,n,i){var a,s;if(r){var o=new Date;o.setTime(o.getTime()+60*r*1e3),a="; expires="+o.toGMTString()}else a="";s=n&&!i?";domain=."+n:"",document.cookie=this.encodeData(e)+"="+this.encodeData(t)+a+s+"; path=/"},get:function(e){for(var t=this.encodeData(e)+"=",r=document.cookie.split(";"),n=0;n<r.length;n++){for(var i=r[n];" "===i.charAt(0);)i=i.substring(1,i.length);if(0===i.indexOf(t))return this.decodeData(i.substring(t.length,i.length))}return null},destroy:function(e,t,r){this.set(e,"",-1,t,r)},parse:function(e){var t=[],r={};if("string"==typeof e)t.push(e);else for(var i in e)e.hasOwnProperty(i)&&t.push(e[i]);for(var a=0;a<t.length;a++){var s;r[this.unsbjs(t[a])]={},s=this.get(t[a])?this.get(t[a]).split(n):[];for(var o=0;o<s.length;o++){var c=s[o].split("="),u=c.splice(0,1);u.push(c.join("=")),r[this.unsbjs(t[a])][u[0]]=this.decodeData(u[1])}}return r},unsbjs:function(e){return e.replace("sbjs_","")}}},{"../data":2}],4:[function(e,t,r){"use strict";t.exports={parse:function(e){for(var t=this.parseOptions,r=t.parser[t.strictMode?"strict":"loose"].exec(e),n={},i=14;i--;)n[t.key[i]]=r[i]||"";return n[t.q.name]={},n[t.key[12]].replace(t.q.parser,function(e,r,i){r&&(n[t.q.name][r]=i)}),n},parseOptions:{strictMode:!1,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}},getParam:function(e){for(var t={},r=e?e:window.location.search.substring(1),n=r.split("&"),i=0;i<n.length;i++){var a=n[i].split("=");if("undefined"==typeof t[a[0]])t[a[0]]=a[1];else if("string"==typeof t[a[0]]){var s=[t[a[0]],a[1]];t[a[0]]=s}else t[a[0]].push(a[1])}return t},getHost:function(e){return this.parse(e).host.replace("www.","")}}},{}],5:[function(e,t,r){"use strict";t.exports={escapeRegexp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},setDate:function(e,t){var r=e.getTimezoneOffset()/60,n=e.getHours(),i=t||0===t?t:-r;e.setHours(n+r+i);var a=e.getFullYear(),s=this.setLeadingZeroToInt(e.getMonth()+1,2),o=this.setLeadingZeroToInt(e.getDate(),2),c=this.setLeadingZeroToInt(e.getHours(),2),u=this.setLeadingZeroToInt(e.getMinutes(),2),d=this.setLeadingZeroToInt(e.getSeconds(),2);return a+"-"+s+"-"+o+" "+c+":"+u+":"+d},setLeadingZeroToInt:function(e,t){for(var r=e+"";r.length<t;)r="0"+r;return r},randomInt:function(e,t){return Math.floor(Math.random()*(t-e+1))+e}}},{}],6:[function(e,t,r){"use strict";var n=e("./data"),i=e("./terms"),a=e("./helpers/cookies"),s=e("./helpers/uri"),o=e("./helpers/utils"),c=e("./params"),u=e("./migrations");t.exports=function(e){function t(){var e,t,s,o="undefined"!=typeof v.utm_source||"undefined"!=typeof v.utm_medium||"undefined"!=typeof v.utm_campaign||"undefined"!=typeof v.utm_content||"undefined"!=typeof v.utm_term||"undefined"!=typeof v.utm_ac_id||"undefined"!=typeof v.utm_id||"undefined"!=typeof v.utm_ad_group_id||"undefined"!=typeof v.utm_ad_id||"undefined"!=typeof v.utm_term_id||"undefined"!=typeof v.gclid||"undefined"!=typeof v.yclid||"undefined"!=typeof v[y.campaign_param]||"undefined"!=typeof v[y.term_param]||"undefined"!=typeof v[y.content_param],c=a.parse(n.containers),u=c[a.unsbjs(n.containers.current)],p=f(i.traffic.organic),m=!1;if(h(),o)_(),e=d(i.traffic.utm),t=u,s=n.pack.unpack(e),m=r(t,s);else if(p)_(),e=d(i.traffic.organic),t=u,s=n.pack.unpack(e),m=r(t,s);else if(!a.get(n.containers.session)&&f(i.traffic.referral))_(),e=d(i.traffic.referral),m=!0;else{if(a.get(n.containers.first)||a.get(n.containers.current))return{data:a.get(n.containers.current),is_utm_changed:m};_(),e=d(i.traffic.typein),m=!0}return{data:e,is_utm_changed:m}}function r(e,t){return e[n.aliases.main.type]!==t[n.aliases.main.type]||e[n.aliases.main.source]!==t[n.aliases.main.source]||e[n.aliases.main.medium]!==t[n.aliases.main.medium]||e[n.aliases.main.campaign]!==t[n.aliases.main.campaign]||e[n.aliases.main.content]!==t[n.aliases.main.content]||e[n.aliases.main.term]!==t[n.aliases.main.term]}function d(e){switch(e){case i.traffic.utm:w="undefined"!=typeof v.utm_type?v.utm_type:i.traffic.utm,q="undefined"!=typeof v.utm_source?v.utm_source:"undefined"!=typeof v.gclid?"google":"undefined"!=typeof v.yclid?"yandex":i.none,I="undefined"!=typeof v.utm_medium?v.utm_medium:"undefined"!=typeof v.gclid?"cpc":"undefined"!=typeof v.yclid?"cpc":i.none,j="undefined"!=typeof v.utm_campaign?v.utm_campaign:"undefined"!=typeof v[y.campaign_param]?v[y.campaign_param]:"undefined"!=typeof v.gclid?"google_cpc":"undefined"!=typeof v.yclid?"yandex_cpc":i.none,R="undefined"!=typeof v.utm_content?v.utm_content:"undefined"!=typeof v[y.content_param]?v[y.content_param]:i.none,D="undefined"!=typeof v.utm_term?v.utm_term:"undefined"!=typeof v[y.term_param]?v[y.term_param]:p()||i.none,H="undefined"!=typeof v.utm_ac_id?v.utm_ac_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,T="undefined"!=typeof v.utm_id?v.utm_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,E="undefined"!=typeof v.utm_ad_group_id?v.utm_ad_group_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,O="undefined"!=typeof v.utm_ad_id?v.utm_ad_id:"undefined"!=typeof v.gclid?"google_cpc":i.none,$="undefined"!=typeof v.utm_term_id?v.utm_term_id:"undefined"!=typeof v.gclid?"google_cpc":i.none;break;case i.traffic.organic:w=i.traffic.organic,q=q||s.getHost(document.referrer),I=i.referer.organic,j=i.none,R=i.none,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;case i.traffic.referral:w=i.traffic.referral,q=q||s.getHost(document.referrer),I=I||i.referer.referral,j=i.none,R=s.parse(document.referrer).path,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;case i.traffic.typein:w=i.traffic.typein,q=y.typein_attributes.source,I=y.typein_attributes.medium,j=i.none,R=i.none,D=i.none,H=i.none,T=i.none,E=i.none,O=i.none,$=i.none;break;default:w=i.oops,q=i.oops,I=i.oops,j=i.oops,R=i.oops,D=i.oops,H=i.oops,T=i.oops,E=i.oops,O=i.oops,$=i.oops}var t={type:w,source:q,medium:I,campaign:j,content:R,term:D,account_id:H,campaign_id:T,ad_group_id:E,ad_id:O,term_id:$};return n.pack.main(t)}function p(){var e=document.referrer;if(v.utm_term)return v.utm_term;if(!(e&&s.parse(e).host&&s.parse(e).host.match(/^(?:.*\.)?yandex\..{2,9}$/i)))return!1;try{return s.getParam(s.parse(document.referrer).query).text}catch(t){return!1}}function f(e){var t=document.referrer;switch(e){case i.traffic.organic:return!!t&&m(t)&&l(t);case i.traffic.referral:return!!t&&m(t)&&g(t);default:return!1}}function m(e){if(y.domain){if(x)return s.getHost(e)!==s.getHost(b);var t=new RegExp("^(?:.*\\.)?"+o.escapeRegexp(b)+"$","i");return!s.getHost(e).match(t)}return s.getHost(e)!==s.getHost(document.location.href)}function l(e){var t="yandex",r="text",n="google",i=new RegExp("^(?:.*\\.)?"+o.escapeRegexp(t)+"\\..{2,9}$"),a=new RegExp(".*"+o.escapeRegexp(r)+"=.*"),c=new RegExp("^(?:www\\.)?"+o.escapeRegexp(n)+"\\..{2,9}$");if(s.parse(e).query&&s.parse(e).host.match(i)&&s.parse(e).query.match(a))return q=t,!0;if(s.parse(e).host.match(c))return q=n,!0;if(!s.parse(e).query)return!1;for(var u=0;u<y.organics.length;u++){if(s.parse(e).host.match(new RegExp("^(?:.*\\.)?"+o.escapeRegexp(y.organics[u].host)+"$","i"))&&s.parse(e).query.match(new RegExp(".*"+o.escapeRegexp(y.organics[u].param)+"=.*","i")))return q=y.organics[u].display||y.organics[u].host,!0;if(u+1===y.organics.length)return!1}}function g(e){if(!(y.referrals.length>0))return q=s.getHost(e),!0;for(var t=0;t<y.referrals.length;t++){if(s.parse(e).host.match(new RegExp("^(?:.*\\.)?"+o.escapeRegexp(y.referrals[t].host)+"$","i")))return q=y.referrals[t].display||y.referrals[t].host,I=y.referrals[t].medium||i.referer.referral,!0;if(t+1===y.referrals.length)return q=s.getHost(e),!0}}function _(){a.set(n.containers.current_extra,n.pack.extra(y.timezone_offset),k,b,x),a.get(n.containers.first_extra)||a.set(n.containers.first_extra,n.pack.extra(y.timezone_offset),k,b,x)}function h(){var e=v.gclid||"",t=v.gbraid||"",r=v.wbraid||"",n=v.fbclid||"",i=v.ttclid||"",s="sd"===v.utm_source?v.utm_term||"":"";""!==t&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-gbraid",t,k,b,x)),""!==r&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-wbraid",r,k,b,x)),""!==e&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-gclid",e,k,b,x)),""!==n&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-fbclid",n,k,b,x)),""!==i&&(a.destroy("_mate-sdclid",b,x),a.set("_mate-ttclid",i,k,b,x)),""!==s&&a.set("_mate-sdclid",s,k,b,x)}var y=c.fetch(e),v=s.getParam(),b=y.domain.host,x=y.domain.isolate,k=y.lifetime;u.go(k,b,x);var w,q,I,j,R,D,H,T,E,O,$;return function(){var e=t();a.set(n.containers.current,e.data,k,b,x),a.get(n.containers.first)||a.set(n.containers.first,a.get(n.containers.current),k,b,x);var r,i;a.get(n.containers.udata)?(r=parseInt(a.parse(n.containers.udata)[a.unsbjs(n.containers.udata)][n.aliases.udata.visits])||1,r=a.get(n.containers.session)?r:r+1,i=n.pack.user(r,y.user_ip)):(r=1,i=n.pack.user(r,y.user_ip)),a.set(n.containers.udata,i,k,b,x);var s,o;a.get(n.containers.session)?(s=parseInt(a.parse(n.containers.session)[a.unsbjs(n.containers.session)][n.aliases.session.pages_seen])||1,s+=1):s=1,a.get(n.containers.session)&&!e.is_utm_changed||(o=(new Date).getTime()),a.set(n.containers.session,n.pack.session(s,o),y.session_length,b,x),y.promocode&&!a.get(n.containers.promocode)&&a.set(n.containers.promocode,n.pack.promo(y.promocode),k,b,x)}(),a.parse(n.containers)}},{"./data":2,"./helpers/cookies":3,"./helpers/uri":4,"./helpers/utils":5,"./migrations":7,"./params":8,"./terms":9}],7:[function(e,t,r){"use strict";var n=e("./data"),i=e("./helpers/cookies");t.exports={go:function(e,t,r){var a,s=this.migrations,o={l:e,d:t,i:r};if(i.get(n.containers.first)||i.get(n.service.migrations)){if(!i.get(n.service.migrations))for(a=0;a<s.length;a++)s[a].go(s[a].id,o)}else{var c=[];for(a=0;a<s.length;a++)c.push(s[a].id);var u="";for(a=0;a<c.length;a++)u+=c[a]+"=1",a<c.length-1&&(u+=n.delimiter);i.set(n.service.migrations,u,o.l,o.d,o.i)}},migrations:[{id:"1418474375998",version:"1.0.0-beta",go:function(e,t){var r=e+"=1",a=e+"=0",s=function(e,t,r){return t||r?e:n.delimiter};try{var o=[];for(var c in n.containers)n.containers.hasOwnProperty(c)&&o.push(n.containers[c]);for(var u=0;u<o.length;u++)if(i.get(o[u])){var d=i.get(o[u]).replace(/(\|)?\|(\|)?/g,s);i.destroy(o[u],t.d,t.i),i.destroy(o[u],t.d,!t.i),i.set(o[u],d,t.l,t.d,t.i)}i.get(n.containers.session)&&i.set(n.containers.session,n.pack.session(0),t.l,t.d,t.i),i.set(n.service.migrations,r,t.l,t.d,t.i)}catch(p){i.set(n.service.migrations,a,t.l,t.d,t.i)}}}]}},{"./data":2,"./helpers/cookies":3}],8:[function(e,t,r){"use strict";var n=e("./terms"),i=e("./helpers/uri");t.exports={fetch:function(e){var t=e||{},r={};if(r.lifetime=this.validate.checkFloat(t.lifetime)||6,r.lifetime=parseInt(30*r.lifetime*24*60),r.session_length=this.validate.checkInt(t.session_length)||30,r.timezone_offset=this.validate.checkInt(t.timezone_offset),r.campaign_param=t.campaign_param||!1,r.term_param=t.term_param||!1,r.content_param=t.content_param||!1,r.user_ip=t.user_ip||n.none,t.promocode?(r.promocode={},r.promocode.min=parseInt(t.promocode.min)||1e5,r.promocode.max=parseInt(t.promocode.max)||999999):r.promocode=!1,t.typein_attributes&&t.typein_attributes.source&&t.typein_attributes.medium?(r.typein_attributes={},r.typein_attributes.source=t.typein_attributes.source,r.typein_attributes.medium=t.typein_attributes.medium):r.typein_attributes={source:"(direct)",medium:"(none)"},t.domain&&this.validate.isString(t.domain)?r.domain={host:t.domain,isolate:!1}:t.domain&&t.domain.host?r.domain=t.domain:r.domain={host:i.getHost(document.location.hostname),isolate:!1},r.referrals=[],t.referrals&&t.referrals.length>0)for(var a=0;a<t.referrals.length;a++)t.referrals[a].host&&r.referrals.push(t.referrals[a]);if(r.organics=[],t.organics&&t.organics.length>0)for(var s=0;s<t.organics.length;s++)t.organics[s].host&&t.organics[s].param&&r.organics.push(t.organics[s]);return r.organics.push({host:"bing.com",param:"q",display:"bing"}),r.organics.push({host:"yahoo.com",param:"p",display:"yahoo"}),r.organics.push({host:"about.com",param:"q",display:"about"}),r.organics.push({host:"aol.com",param:"q",display:"aol"}),r.organics.push({host:"ask.com",param:"q",display:"ask"}),r.organics.push({host:"globososo.com",param:"q",display:"globo"}),r.organics.push({host:"go.mail.ru",param:"q",display:"go.mail.ru"}),r.organics.push({host:"rambler.ru",param:"query",display:"rambler"}),r.organics.push({host:"tut.by",param:"query",display:"tut.by"}),r.referrals.push({host:"t.co",display:"twitter.com"}),r.referrals.push({host:"plus.url.google.com",display:"plus.google.com"}),r},validate:{checkFloat:function(e){return!(!e||!this.isNumeric(parseFloat(e)))&&parseFloat(e)},checkInt:function(e){return!(!e||!this.isNumeric(parseInt(e)))&&parseInt(e)},isNumeric:function(e){return!isNaN(e)},isString:function(e){return"[object String]"===Object.prototype.toString.call(e)}}}},{"./helpers/uri":4,"./terms":9}],9:[function(e,t,r){"use strict";t.exports={traffic:{utm:"utm",organic:"organic",referral:"referral",typein:"typein"},referer:{referral:"referral",organic:"organic",social:"social"},none:"(none)",oops:"(Houston, we have a problem)"}},{}]},{},[1])(1)});
package/src/js/init.js CHANGED
@@ -120,7 +120,13 @@ module.exports = function(prefs) {
120
120
 
121
121
  case terms.traffic.utm:
122
122
 
123
- __sbjs_type = terms.traffic.utm;
123
+ // Allow explicit type override via utm_type URL parameter
124
+ // This fixes mixed attribution when organic visits include UTM params in redirect URLs
125
+ if (typeof get_param.utm_type !== 'undefined') {
126
+ __sbjs_type = get_param.utm_type;
127
+ } else {
128
+ __sbjs_type = terms.traffic.utm;
129
+ }
124
130
 
125
131
  if (typeof get_param.utm_source !== 'undefined') {
126
132
  __sbjs_source = get_param.utm_source;
@@ -342,10 +348,10 @@ module.exports = function(prefs) {
342
348
  ) {
343
349
  __sbjs_source = y_host;
344
350
  return true;
345
- } else if (!!uri.parse(referer).host.match(g_host_regex)) {
351
+ } else if (uri.parse(referer).host.match(g_host_regex)) {
346
352
  __sbjs_source = g_host;
347
353
  return true;
348
- } else if (!!uri.parse(referer).query) {
354
+ } else if (uri.parse(referer).query) {
349
355
  for (var i = 0; i < p.organics.length; i++) {
350
356
  if (
351
357
  uri.parse(referer).host.match(new RegExp('^(?:.*\\.)?' + utils.escapeRegexp(p.organics[i].host) + '$', 'i')) &&
@@ -394,6 +400,7 @@ module.exports = function(prefs) {
394
400
  var gbraid = get_param.gbraid || '';
395
401
  var wbraid = get_param.wbraid || '';
396
402
  var fbclid = get_param.fbclid || '';
403
+ var ttclid = get_param.ttclid || '';
397
404
 
398
405
  // if utm_source = "sd" -> utm_term param is used
399
406
  var sdclid = get_param.utm_source === 'sd' ? get_param.utm_term || '' : '';
@@ -417,6 +424,11 @@ module.exports = function(prefs) {
417
424
  cookies.set('_mate-fbclid', fbclid, lifetime, domain, isolate);
418
425
  }
419
426
 
427
+ if (ttclid !== '') {
428
+ cookies.destroy('_mate-sdclid', domain, isolate);
429
+ cookies.set('_mate-ttclid', ttclid, lifetime, domain, isolate);
430
+ }
431
+
420
432
  if (sdclid !== '') {
421
433
  cookies.set('_mate-sdclid', sdclid, lifetime, domain, isolate);
422
434
  }
@@ -0,0 +1,334 @@
1
+ describe('utm_type override', () => {
2
+ it('should override typ when utm_type is provided', () => {
3
+ setLocation('https://example.com/?utm_type=organic&utm_source=google&utm_medium=organic');
4
+
5
+ const sbjs = require('./sourcebuster');
6
+ sbjs.init();
7
+
8
+ expect(sbjs.get.current.typ).toBe('organic');
9
+ });
10
+
11
+ it('should default to typ=utm when utm_type is not provided', () => {
12
+ setLocation('https://example.com/?utm_source=facebook&utm_medium=cpc');
13
+
14
+ const sbjs = require('./sourcebuster');
15
+ sbjs.init();
16
+
17
+ expect(sbjs.get.current.typ).toBe('utm');
18
+ });
19
+ });
20
+
21
+ describe('traffic type detection', () => {
22
+ it('should set typ to utm for gclid parameter', () => {
23
+ setLocation('https://example.com/?gclid=abc123');
24
+
25
+ const sbjs = require('./sourcebuster');
26
+ sbjs.init();
27
+
28
+ expect(sbjs.get.current.typ).toBe('utm');
29
+ expect(sbjs.get.current.src).toBe('google');
30
+ });
31
+
32
+ it('should set typ to organic when referrer is google.com', () => {
33
+ setLocation('https://example.com/');
34
+ setReferrer('https://www.google.com/');
35
+
36
+ const sbjs = require('./sourcebuster');
37
+ sbjs.init();
38
+
39
+ expect(sbjs.get.current.typ).toBe('organic');
40
+ expect(sbjs.get.current.src).toBe('google');
41
+ });
42
+
43
+ it('should set typ to referral when referrer is non-search domain', () => {
44
+ setLocation('https://example.com/');
45
+ setReferrer('https://facebook.com/post');
46
+
47
+ const sbjs = require('./sourcebuster');
48
+ sbjs.init();
49
+
50
+ expect(sbjs.get.current.typ).toBe('referral');
51
+ expect(sbjs.get.current.src).toBe('facebook.com');
52
+ expect(sbjs.get.current.mdm).toBe('referral');
53
+ });
54
+
55
+ it('should set typ to typein when no referrer and no UTM', () => {
56
+ setLocation('https://example.com/');
57
+ setReferrer('');
58
+
59
+ const sbjs = require('./sourcebuster');
60
+ sbjs.init();
61
+
62
+ expect(sbjs.get.current.typ).toBe('typein');
63
+ expect(sbjs.get.current.src).toBe('(direct)');
64
+ expect(sbjs.get.current.mdm).toBe('(none)');
65
+ });
66
+ });
67
+
68
+ describe('cookie persistence', () => {
69
+ it('should store current visit data in sbjs_current cookie', () => {
70
+ setLocation('https://example.com/?utm_source=test');
71
+
72
+ const sbjs = require('./sourcebuster');
73
+ sbjs.init();
74
+
75
+ const cookie = decodeURIComponent(getCookie('sbjs_current'));
76
+ expect(cookie).toBeDefined();
77
+ expect(cookie).toContain('src=test');
78
+ });
79
+
80
+ it('should set sbjs_first only on first visit and never change it', () => {
81
+ setLocation('https://example.com/?utm_source=google');
82
+ let sbjs = require('./sourcebuster');
83
+ sbjs.init();
84
+ expect(sbjs.get.first.src).toBe('google');
85
+
86
+ jest.resetModules();
87
+ setLocation('https://example.com/?utm_source=facebook');
88
+ sbjs = require('./sourcebuster');
89
+ sbjs.init();
90
+
91
+ expect(sbjs.get.first.src).toBe('google');
92
+ expect(sbjs.get.current.src).toBe('facebook');
93
+ });
94
+ });
95
+
96
+ describe('source overriding rules', () => {
97
+ it('should allow UTM to override previous referral source', () => {
98
+ setLocation('https://example.com/');
99
+ setReferrer('https://facebook.com/');
100
+ let sbjs = require('./sourcebuster');
101
+ sbjs.init();
102
+ expect(sbjs.get.current.typ).toBe('referral');
103
+
104
+ jest.resetModules();
105
+ clearCookies();
106
+ setCookie('sbjs_current', 'typ=referral|||src=facebook.com|||mdm=referral|||cmp=(none)|||cnt=(none)|||trm=(none)');
107
+ setLocation('https://example.com/?utm_source=google');
108
+ setReferrer('');
109
+ sbjs = require('./sourcebuster');
110
+ sbjs.init();
111
+
112
+ expect(sbjs.get.current.typ).toBe('utm');
113
+ expect(sbjs.get.current.src).toBe('google');
114
+ });
115
+
116
+ it('should allow organic to override previous referral source', () => {
117
+ setLocation('https://example.com/');
118
+ setReferrer('https://facebook.com/');
119
+ let sbjs = require('./sourcebuster');
120
+ sbjs.init();
121
+
122
+ jest.resetModules();
123
+ clearCookies();
124
+ setCookie('sbjs_current', 'typ=referral|||src=facebook.com|||mdm=referral|||cmp=(none)|||cnt=(none)|||trm=(none)');
125
+ setLocation('https://example.com/');
126
+ setReferrer('https://www.google.com/');
127
+ sbjs = require('./sourcebuster');
128
+ sbjs.init();
129
+
130
+ expect(sbjs.get.current.typ).toBe('organic');
131
+ });
132
+
133
+ it('should not allow typein to override previous source', () => {
134
+ setLocation('https://example.com/?utm_source=google');
135
+ let sbjs = require('./sourcebuster');
136
+ sbjs.init();
137
+
138
+ jest.resetModules();
139
+ clearCookies();
140
+ setCookie('sbjs_current', 'typ=utm|||src=google|||mdm=cpc|||cmp=(none)|||cnt=(none)|||trm=(none)');
141
+ setLocation('https://example.com/');
142
+ setReferrer('');
143
+ sbjs = require('./sourcebuster');
144
+ sbjs.init();
145
+
146
+ expect(sbjs.get.current.src).toBe('google');
147
+ });
148
+
149
+ it('should not allow referral to override within same session', () => {
150
+ setLocation('https://example.com/?utm_source=google');
151
+ let sbjs = require('./sourcebuster');
152
+ sbjs.init();
153
+
154
+ jest.resetModules();
155
+ setLocation('https://example.com/page2');
156
+ setReferrer('https://facebook.com/');
157
+ sbjs = require('./sourcebuster');
158
+ sbjs.init();
159
+
160
+ expect(sbjs.get.current.src).toBe('google');
161
+ });
162
+ });
163
+
164
+ describe('UTM parameters capture', () => {
165
+ it('should capture all standard UTM parameters', () => {
166
+ setLocation('https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=summer&utm_content=banner&utm_term=shoes');
167
+
168
+ const sbjs = require('./sourcebuster');
169
+ sbjs.init();
170
+
171
+ expect(sbjs.get.current.src).toBe('google');
172
+ expect(sbjs.get.current.mdm).toBe('cpc');
173
+ expect(sbjs.get.current.cmp).toBe('summer');
174
+ expect(sbjs.get.current.cnt).toBe('banner');
175
+ expect(sbjs.get.current.trm).toBe('shoes');
176
+ });
177
+
178
+ it('should capture extended Google Ads UTM parameters', () => {
179
+ setLocation('https://example.com/?gclid=abc&utm_id=67890');
180
+
181
+ const sbjs = require('./sourcebuster');
182
+ sbjs.init();
183
+
184
+ expect(sbjs.get.current.typ).toBe('utm');
185
+ expect(sbjs.get.current.src).toBe('google');
186
+ });
187
+ });
188
+
189
+ describe('session tracking', () => {
190
+ it('should increment page views within same session', () => {
191
+ setLocation('https://example.com/');
192
+ let sbjs = require('./sourcebuster');
193
+ sbjs.init();
194
+ expect(parseInt(sbjs.get.session.pgs)).toBe(1);
195
+
196
+ jest.resetModules();
197
+ setLocation('https://example.com/about');
198
+ sbjs = require('./sourcebuster');
199
+ sbjs.init();
200
+
201
+ expect(parseInt(sbjs.get.session.pgs)).toBe(2);
202
+ });
203
+
204
+ it('should create new session when UTM parameters change', () => {
205
+ setLocation('https://example.com/?utm_source=google');
206
+ let sbjs = require('./sourcebuster');
207
+ sbjs.init();
208
+ const firstSessionId = sbjs.get.session.sid;
209
+
210
+ jest.resetModules();
211
+ setLocation('https://example.com/?utm_source=facebook');
212
+ sbjs = require('./sourcebuster');
213
+ sbjs.init();
214
+
215
+ expect(sbjs.get.session.sid).toBeDefined();
216
+ expect(firstSessionId).toBeDefined();
217
+ expect(sbjs.get.session.sid).not.toBe(firstSessionId);
218
+ expect(parseInt(sbjs.get.session.pgs)).toBe(2);
219
+ });
220
+ });
221
+
222
+ describe('visit counting', () => {
223
+ it('should increment visit counter only when session expires', () => {
224
+ setLocation('https://example.com/?utm_source=google');
225
+ let sbjs = require('./sourcebuster');
226
+ sbjs.init();
227
+ expect(parseInt(sbjs.get.udata.vst)).toBe(1);
228
+
229
+ jest.resetModules();
230
+ setLocation('https://example.com/page2');
231
+ sbjs = require('./sourcebuster');
232
+ sbjs.init();
233
+ expect(parseInt(sbjs.get.udata.vst)).toBe(1);
234
+
235
+ jest.resetModules();
236
+ clearCookies();
237
+ setCookie('sbjs_current', 'typ=utm|||src=google|||mdm=cpc|||cmp=(none)|||cnt=(none)|||trm=(none)');
238
+ setCookie('sbjs_udata', 'vst=1|||uip=(none)|||uag=test');
239
+ setLocation('https://example.com/page3');
240
+ sbjs = require('./sourcebuster');
241
+ sbjs.init();
242
+ expect(parseInt(sbjs.get.udata.vst)).toBe(2);
243
+ });
244
+ });
245
+
246
+ describe('click ID storage', () => {
247
+ it('should store gclid in separate cookie', () => {
248
+ setLocation('https://example.com/?gclid=abc123');
249
+
250
+ const sbjs = require('./sourcebuster');
251
+ sbjs.init();
252
+
253
+ expect(getCookie('_mate-gclid')).toBe('abc123');
254
+ });
255
+
256
+ it('should store fbclid in separate cookie', () => {
257
+ setLocation('https://example.com/?fbclid=fb456');
258
+
259
+ const sbjs = require('./sourcebuster');
260
+ sbjs.init();
261
+
262
+ expect(getCookie('_mate-fbclid')).toBe('fb456');
263
+ });
264
+
265
+ it('should destroy old sdclid when new gclid arrives', () => {
266
+ setLocation('https://example.com/?utm_source=sd&utm_term=old123');
267
+ let sbjs = require('./sourcebuster');
268
+ sbjs.init();
269
+ expect(getCookie('_mate-sdclid')).toBe('old123');
270
+
271
+ jest.resetModules();
272
+ setLocation('https://example.com/?gclid=new456');
273
+ sbjs = require('./sourcebuster');
274
+ sbjs.init();
275
+
276
+ const sdclid = getCookie('_mate-sdclid');
277
+ expect(sdclid === undefined || sdclid === '').toBe(true);
278
+ expect(getCookie('_mate-gclid')).toBe('new456');
279
+ });
280
+ });
281
+
282
+ describe('organic source detection', () => {
283
+ it('should detect Bing organic traffic', () => {
284
+ setLocation('https://example.com/');
285
+ setReferrer('https://www.bing.com/search?q=test');
286
+
287
+ const sbjs = require('./sourcebuster');
288
+ sbjs.init();
289
+
290
+ expect(sbjs.get.current.typ).toBe('organic');
291
+ expect(sbjs.get.current.src).toBe('bing');
292
+ });
293
+
294
+ it('should detect Yahoo organic traffic', () => {
295
+ setLocation('https://example.com/');
296
+ setReferrer('https://search.yahoo.com/search?p=test');
297
+
298
+ const sbjs = require('./sourcebuster');
299
+ sbjs.init();
300
+
301
+ expect(sbjs.get.current.typ).toBe('organic');
302
+ expect(sbjs.get.current.src).toBe('yahoo');
303
+ });
304
+ });
305
+
306
+ describe('referral content tracking', () => {
307
+ it('should store referrer path as utm_content for referral traffic', () => {
308
+ setLocation('https://example.com/');
309
+ setReferrer('https://facebook.com/some/post/path');
310
+
311
+ const sbjs = require('./sourcebuster');
312
+ sbjs.init();
313
+
314
+ expect(sbjs.get.current.cnt).toBe('/some/post/path');
315
+ });
316
+ });
317
+
318
+ describe('custom configuration', () => {
319
+ it('should respect custom typein attributes', () => {
320
+ setLocation('https://example.com/');
321
+ setReferrer('');
322
+
323
+ const sbjs = require('./sourcebuster');
324
+ sbjs.init({
325
+ typein_attributes: {
326
+ source: 'custom_direct',
327
+ medium: 'custom_none'
328
+ }
329
+ });
330
+
331
+ expect(sbjs.get.current.src).toBe('custom_direct');
332
+ expect(sbjs.get.current.mdm).toBe('custom_none');
333
+ });
334
+ });
@@ -0,0 +1,68 @@
1
+ let cookieStore = {};
2
+
3
+ Object.defineProperty(document, 'cookie', {
4
+ get: () => {
5
+ return Object.entries(cookieStore)
6
+ .map(([key, value]) => `${key}=${value}`)
7
+ .join('; ');
8
+ },
9
+ set: (cookieString) => {
10
+ const parts = cookieString.split(';');
11
+ const nameValue = parts[0];
12
+ const eqIndex = nameValue.indexOf('=');
13
+ const name = nameValue.substring(0, eqIndex).trim();
14
+ const value = nameValue.substring(eqIndex + 1);
15
+
16
+ if (cookieString.includes('expires=Thu, 01 Jan 1970')) {
17
+ delete cookieStore[name];
18
+ } else {
19
+ cookieStore[name] = value;
20
+ }
21
+ },
22
+ configurable: true,
23
+ });
24
+
25
+ global.clearCookies = () => {
26
+ cookieStore = {};
27
+ };
28
+
29
+ global.setCookie = (name, value) => {
30
+ cookieStore[name] = value;
31
+ };
32
+
33
+ global.getCookie = (name) => {
34
+ return cookieStore[name];
35
+ };
36
+
37
+ global.setLocation = (url) => {
38
+ const urlObj = new URL(url);
39
+
40
+ Object.defineProperty(window, 'location', {
41
+ value: {
42
+ href: urlObj.href,
43
+ search: urlObj.search,
44
+ hostname: urlObj.hostname,
45
+ pathname: urlObj.pathname,
46
+ protocol: urlObj.protocol,
47
+ origin: urlObj.origin,
48
+ host: urlObj.host,
49
+ },
50
+ writable: true,
51
+ configurable: true,
52
+ });
53
+ };
54
+
55
+ global.setReferrer = (referrer) => {
56
+ Object.defineProperty(document, 'referrer', {
57
+ value: referrer,
58
+ writable: true,
59
+ configurable: true,
60
+ });
61
+ };
62
+
63
+ beforeEach(() => {
64
+ clearCookies();
65
+ setLocation('https://example.com/');
66
+ setReferrer('');
67
+ jest.resetModules();
68
+ });