1/** 2 * AFS Analytics â Pricing page JS 3 * Port vanille de pricing2.js (sans jQuery) 4 * Données de prix issues de orderform_2.js (live) 5 */ 6 7/* ---- Price data (from live orderform_2.js) ---- */ 8 9// G_plan_price[period * 5 + plan_index] 10// plan indexes: free=0, silver=1, gold=2, diamond=4 11// periods: 0=1 mois, 1=3 mois, 2=6 mois, 3=12 mois, 4=24 mois 12var G_plan_price = [ 13 0, 25.95, 39.95, 0, 490, // 1 mois 14 0, 23.95, 37.95, 0, 490, // 3 mois 15 0, 22.95, 36.95, 0, 490, // 6 mois 16 0, 19.95, 34.95, 0, 490, // 12 mois (défaut) 17 0, 19.95, 32.95, 0, 490 // 24 mois 18]; 19 20// PV tiers: [label, extra_price_eur, ...] par paires 21var G_pv_silver = [ 22 "50,000", 0, 23 "150,000", 0, 24 "300,000", 5, 25 "600,000", 10, 26 "900,000", 15, 27 "1,2M", 20, 28 "2M", 40, 29 "3M", 45, 30 "4M", 60, 31 "5M", 80 32]; 33var G_pv_gold = [ 34 "50,000", 0, 35 "250,000", 0, 36 "500,000", 10, 37 "700,000", 20, 38 "900,000", 25, 39 "1,2M", 30, 40 "2M", 50, 41 "3M", 70, 42 "4M", 100, 43 "5M", 150 44]; 45var G_pv_diamond = [ 46 "50,000", 0, 47 "200,000", 0, 48 "400,000", 0, 49 "600,000", 0, 50 "900,000", 0, 51 "1,2M", 50, 52 "2M", 100, 53 "3M", 150, 54 "4M", 200, 55 "5M", 250 56]; 57 58// Remises actives (silver=20%, gold=30%) 59var G_plan_discount = [0, 20, 30, 0, 0]; 60 61// Plan indexes 62var G_plan_index = { free: 0, silver: 1, gold: 2, diamond: 4 }; 63 64// Compat stub 65function ChangePlan() {} 66 67 68/* ---- Helpers ---- */ 69 70function qs(el, sel) { return el.querySelector(sel); } 71function qsa(el, sel) { return el.querySelectorAll(sel); } 72 73/* ---- Compute PV tiers (même logique que pricing2.js) ---- */ 74function computePVData(rawData) { 75 var ret = [], last_pr = 0; 76 for (var f = 0; f < rawData.length; f += 2) { 77 var pv = rawData[f].replace(',000', 'K'); 78 var pr = rawData[f + 1]; 79 if (!pr && last_pr === 0) { 80 ret = []; 81 } 82 ret.push({ limit: pv, price: pr, index: f >> 1 }); 83 } 84 return ret; 85} 86 87 88/* ---- AFSA_plan class (vanille) ---- */ 89 90function AFSA_plan(el) { 91 this.el_ = el; 92 this.cfg_ = JSON.parse(el.getAttribute('data-cfg') || '{}'); 93 this.type_ = this.cfg_.type; 94 this.plan_id_ = this.cfg_.plan_id; 95 this.currency_ = (this.cfg_.currency || 'EUR').toLowerCase(); 96 this.plan_index_ = G_plan_index[this.type_] || 1; 97 this.period_index_ = 3; // défaut : abonnement 12 mois 98 this.base_price_ = -1; 99 this.discount_ = 0; 100 this.extra_pv_ = 0; 101 this.pv_data_ = null; 102 this.websites_qt_ = 1; 103 this.pv_qt_ = 0; 104 this.el_amount_ = null; 105 this.lng_ = document.body.classList.contains('fr') ? 'fr' : 'en'; 106} 107 108AFSA_plan.prototype = { 109 110 init: function() { 111 var self = this; 112 var i = (this.period_index_ * 5) + this.plan_index_; 113 var el_price = qs(this.el_, '.price'); 114 var el_submit = qs(this.el_, '.button.submit'); 115 var month_label = this.lng_ === 'fr' ? 'mois' : 'month'; 116 117 this.base_price_ = G_plan_price[i]; 118 119 // Pour diamond, afficher "an" / "year" au lieu de "mois" 120 if (this.type_ === 'diamond') { 121 month_label = this.lng_ === 'fr' ? 'an' : 'year'; 122 } 123 124 // Injecter le bloc montant dans .price 125 var amount_div = document.createElement('div'); 126 amount_div.className = 'amount'; 127 this.el_amount_ = document.createElement('div'); 128 this.el_amount_.className = 'value digit'; 129 amount_div.appendChild(this.el_amount_); 130 amount_div.insertAdjacentHTML('beforeend', 131 this.renderCurrency() + 132 '<div class="csep">/</div>' + 133 '<div class="period">' + month_label + '</div>' 134 ); 135 if (el_price) el_price.appendChild(amount_div); 136 137 this.updateDiscount() 138 .initPVSlider() 139 .updatePrice(); 140 141 this.onPVSliderChange(0); 142 143 // Click sur le bouton â order URL 144 if (el_submit && this.type_ !== 'diamond') { 145 el_submit.addEventListener('click', function() { 146 window.location = self.buildOrderURL(); 147 }); 148 } 149 }, 150 151 buildOrderURL: function() { 152 return 'https://www.afsanalytics.com/order_2.php?' + 153 'plan=' + this.plan_id_ + 154 '&quantity=' + this.websites_qt_ + 155 '&pv=' + this.pv_qt_; 156 }, 157 158 updateDiscount: function() { 159 var v = this.discount_ = G_plan_discount[this.plan_index_] || 0; 160 var el_discount = qs(this.el_, '.discount'); 161 if (el_discount && v) { 162 el_discount.classList.remove('hidden'); 163 var el_val = qs(el_discount, '.value'); 164 if (el_val) el_val.innerHTML = v; 165 } 166 return this; 167 }, 168 169 updatePrice: function() { 170 if (!this.el_amount_) return this; 171 var p = this.base_price_; 172 var r = p - ((p / 100) * this.discount_) + this.extra_pv_; 173 // Diamond : afficher prix annuel sans décimales 174 this.el_amount_.innerHTML = this.type_ === 'diamond' 175 ? Math.round(r) 176 : r.toFixed(2); 177 return this; 178 }, 179 180 renderCurrency: function() { 181 var sym = this.currency_ === 'eur' ? 'â¬' : '$'; 182 return '<div class="currency ' + this.currency_ + '">' + sym + '</div>'; 183 }, 184 185 getPVData: function() { 186 if (this.pv_data_) return this.pv_data_; 187 var raw = G_pv_silver;
188 if (this.type_ === 'gold') raw = G_pv_gold; 189 if (this.type_ === 'diamond') raw = G_pv_diamond; 190 return this.pv_data_ = computePVData(raw); 191 }, 192 193 initPVSlider: function() { 194 var self = this; 195 var el = qs(this.el_, '.pv_slider'); 196 var data = this.getPVData(); 197 if (!el) return this; 198 el.setAttribute('max', data.length - 1); 199 el.addEventListener('input', function() { self.onPVSliderChange(parseInt(this.value)); }); 200 el.addEventListener('change', function() { self.onPVSliderChange(parseInt(this.value)); }); 201 return this; 202 }, 203 204 onPVSliderChange: function(idx) { 205 var data = this.getPVData(); 206 var d = data[idx] || data[0]; 207 var el = qs(this.el_, '.pv_slider'); 208 var el_value = qs(this.el_, '.pv_select .infos .value'); 209 if (el_value) el_value.innerHTML = d.limit; 210 this.pv_qt_ = d.index; 211 this.extra_pv_ = parseFloat(d.price); 212 this.updatePrice(); 213 } 214}; 215 216 217/* ---- Init au chargement ---- */ 218 219document.addEventListener('DOMContentLoaded', function() { 220 221 ChangePlan(); // compat stub 222 223 var discount_available = G_plan_discount.some(function(v) { return v > 0; }); 224 225 // Instancier un AFSA_plan pour chaque plan payant 226 var cards = document.querySelectorAll('.plan_option'); 227 cards.forEach(function(el) { 228 if (!el.classList.contains('free')) { 229 (new AFSA_plan(el)).init(); 230 } 231 if (discount_available) { 232 el.classList.add('extended'); 233 } 234 }); 235});
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.