PageSourceSearch

https://boutique.tetu.com/core/js/angular/tbs-piano.js?v=

js tetu.com collected 2026-10-02 03:56:40 UTC 4,984 bytes, 154 lines download raw bytes

1angular.module('AboShopApp').factory('pianoManager', ['commonConfig', '$rootScope', 'Auth', 'customerManager',
2	function (commonConfig, $rootScope, Auth, customerManager) {
3		const factory = {};
4		let pianoEnable = false;
5		let coreProperties = {};
6
7		factory.init = function init() {
8			if (_pianoConfigured()) {
9				const script = document.createElement('script');
10				script.src='https://tag.aticdn.net/piano-analytics.js';
11				script.crossOrigin = 'anomynous';
12				script.addEventListener('load', function () {
13					pa.setConfigurations({
14						site: _getPianoSiteId(), // ID de site
15						collectDomain: commonConfig.pianoSite.collectDomain, // Domaine de collecte
16						addEventURL: 'true', // Ajoute une propriété contenant l'URL de la page en cours. (Obligation ACPM)
17						campaignPrefix: ['utm_','at_'], // Préfixe préférentiel pour les campagnes marketing
18						enableUTMTracking: true, // Définit le paramètre marketing UTM pour alimenter les campagnes marketing
19						sendEmptyProperties: false // Permet de ne pas envoyer des propriétés vides
20					});
21					if (commonConfig.didomiId) {
22						pa.privacy.setMode("exempt");
23						// En mode "exempt", le SDK Piano ne collecte que les propriétés de sa
24						// liste d'autorisation par défaut ; toute propriété non déclarée est
25						// retirée côté client avant l'envoi (vérifié sur le wire pa-cd.com).
26						// On déclare donc nos coreProperties/props non standards :
27						// - purchase_amount : montant de commande sur /common/paymentstatus
28						// - site_level2    : découpage éditorial (ex. "La_Boutique")
29						// - page_content   : flag éditorial global
30						pa.privacy.include.properties(['purchase_amount', 'site_level2', 'page_content'], ['exempt']);
31					}
32					pianoEnable = true;
33					const initPiano = new CustomEvent('initPiano');
34					document.dispatchEvent(initPiano);
35
36					factory.addCoreProperty('page_content', false);
37					factory.addCoreProperty('site_level2', _getSiteLevel2());
38					factory.addCoreProperty('site_env', commonConfig.target.match(/^prod/i) ? 'Prod' : 'Preprod');
39				});
40				document.head.appendChild(script);
41
42				document.addEventListener('click', function(e) {
43					var target = e.target.closest('.optout-consent');
44					if (target) {
45						e.preventDefault();
46						_pianoEnabled(function() {
47							pa.privacy.setMode("optout");
48
49							var purposeId = _getPianoPurposeId();
50							if (purposeId) {
51								window.didomiOnReady = window.didomiOnReady || [];
52								window.didomiOnReady.push(function(Didomi) {
53									var t = Didomi.openTransaction();
54									t.disablePurpose(purposeId);
55									t.commit();
56								});
57							}
58							alert("Désactivation du suivi utilisateur (Opt-out)");
59						});
60					}
61				});
62			}
63		}
64
65		function _pianoConfigured() {
66			return commonConfig.pianoSite != null;
67		}
68
69		function _pianoEnabled(callback) {
70			if (_pianoConfigured()) {
71				if (pianoEnable) {
72					callback();
73				} else {
74					document.addEventListener('initPiano', callback, {once: true});
75				}
76			}
77		}
78
79		function _isMobile() {
80			return window.matchMedia("(max-width: 768px)").matches;
81		}
82
83		function _getPianoSiteId() {
84			return _isMobile() && commonConfig.pianoSite.idMobile
85			? commonConfig.pianoSite.idMobile
86			: commonConfig.pianoSite.idDesktop;
87		}
88
89		function _getSiteLevel2() {
90			return commonConfig.pianoSite?.site_level2 ?? "Boutique";
91		}
92
93		function _getPianoPurposeId() {
94			if (commonConfig.vendorsNameEnabled) {
95				for (var i = 0; i < commonConfig.vendorsNameEnabled.length; i++) {
96					if (commonConfig.vendorsNameEnabled[i].idtbs === 'piano') {
97						return commonConfig.vendorsNameEnabled[i].purposeId;
98					}
99				}
100			}
101			return null;
102		}
103
104		factory.addCoreProperty = function addCoreProperty(key, value, ifEmpty = false) {
105			if (!ifEmpty || coreProperties[key] == null) {
106				coreProperties[key] = value;
107			}
108		}
109
110		factory.removeCoreProperty = function removeCoreProperty(key) {
111			delete coreProperties[key];
112		}
113
114		factory.resetCoreProperties = function resetCoreProperties() {
115			coreProperties = {};
116		}
117
118		factory.sendEvent = function sendEvent(event, props) {
119			_pianoEnabled(() => {
120				pa.sendEvent(event, {
121					...coreProperties,
122					...props
123				});
124			});
125		}
126
127		factory.customerInfos = function customerInfos() {
128			_pianoEnabled(() => {
129				if (Auth.isClientConnecte()) {
130					customerManager.getCustomer(false).then((customer) => {
131						pa.setUser(customer.codeClient, customer.estAbonne? 'Abonné' : 'Non abonné', true);
132					});
133				} else {
134					pa.deleteUser();
135				}
136			});
137		}
138
139		factory.clickProductDeclinaison = function clickProductDeclinaison(product) {
140			factory.sendEvent('click.action', {
141				click: 'Sélection du tarif',
142				click_chapter1: product.tarif.support ? product.tarif.support.libelleSupport : null
143			});
144		}
145
146		factory.setPrivacyMode = function setPrivacyMode(mode) {
147			_pianoEnabled(() => {
148				pa.privacy.setMode(mode);
149			});
150		}
151
152		return factory;
153	}
154]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.