(function () { const nav = document.querySelector("#mss-side-nav-pro"); if (!nav) return; const buttons = Array.from(nav.querySelectorAll("button[data-find]")); let foundSections = []; let ticking = false; function normalize(text) { return (text || "") .toLowerCase() .normalize("NFD") .replace(/[\u0300-\u036f]/g, "") .replace(/\s+/g, " ") .trim(); } function getCandidates() { return Array.from(document.querySelectorAll("h1, h2, h3, h4, h5, p, span, strong")) .filter(function (el) { if (el.closest("#mss-side-nav-pro")) return false; const text = normalize(el.textContent); return text.length > 3 && text.length < 220; }); } function findTarget(text) { const wanted = normalize(text); const candidates = getCandidates(); let matches = candidates.filter(function (el) { return normalize(el.textContent) === wanted; }); if (!matches.length) { matches = candidates.filter(function (el) { return normalize(el.textContent).includes(wanted); }); } return matches[0] || null; } function initNav() { foundSections = []; buttons.forEach(function (button, index) { const label = button.getAttribute("data-find"); const id = "mss-pro-section-" + index; const target = findTarget(label); if (target) { target.id = id; target.style.scrollMarginTop = "135px"; button.dataset.targetId = id; button.classList.remove("not-found"); foundSections.push({ button: button, element: target, id: id }); } else { button.dataset.targetId = ""; button.classList.add("not-found"); } }); sortSections(); updateActive(); } function sortSections() { foundSections.sort(function (a, b) { const topA = a.element.getBoundingClientRect().top + window.pageYOffset; const topB = b.element.getBoundingClientRect().top + window.pageYOffset; return topA - topB; }); } function scrollToTarget(target) { const y = target.getBoundingClientRect().top + window.pageYOffset - 120; window.scrollTo({ top: Math.max(0, y), behavior: "smooth" }); } function updateActive() { if (!foundSections.length) return; const triggerPoint = window.pageYOffset + Math.min(265, window.innerHeight * 0.32); let active = foundSections[0]; foundSections.forEach(function (section) { const sectionTop = section.element.getBoundingClientRect().top + window.pageYOffset; if (sectionTop <= triggerPoint) { active = section; } }); buttons.forEach(function (button) { button.classList.remove("active"); }); if (active && active.button) { active.button.classList.add("active"); } } function requestUpdate() { if (ticking) return; ticking = true; window.requestAnimationFrame(function () { updateActive(); ticking = false; }); } buttons.forEach(function (button) { button.addEventListener("click", function (event) { event.preventDefault(); event.stopPropagation(); const id = button.dataset.targetId; const target = id ? document.getElementById(id) : null; if (!target) return; scrollToTarget(target); buttons.forEach(function (item) { item.classList.remove("active"); }); button.classList.add("active"); setTimeout(updateActive, 500); }); }); window.addEventListener("scroll", requestUpdate, { passive: true }); window.addEventListener("resize", function () { sortSections(); updateActive(); }); if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", function () { setTimeout(initNav, 400); setTimeout(initNav, 1200); setTimeout(initNav, 2600); setTimeout(initNav, 5000); }); } else { setTimeout(initNav, 400); setTimeout(initNav, 1200); setTimeout(initNav, 2600); setTimeout(initNav, 5000); } })();
MicroSoudure Signature

Personnalisation de manettes sur mesure

Chaque projet est préparé selon les choix du client, que ce soit avec votre propre manette ou avec une manette reconditionnée fournie par notre atelier. Les pièces sont commandées spécialement pour chaque projet, avec un délai moyen d’environ 2 semaines pour la réception et l’installation.

Pour le moment, le formulaire de personnalisation est disponible uniquement pour les manettes PS5 DualSense, en raison d’un manque de stock pour les manettes Xbox Series.

Si vous souhaitez personnaliser une manette Xbox Series, écrivez-nous avec les options désirées. Nous vérifierons les choix disponibles selon l’inventaire et les pièces pouvant être commandées.

Dépôt requis avant la commande des pièces

Pour tout projet personnalisé, un acompte de 50 % du montant estimé est requis avant la commande des pièces.

Si le projet est annulé ou modifié après l’achat des pièces nécessaires, les frais réellement engagés pourront être retenus de l’acompte, notamment le coût des pièces commandées spécialement, les frais de livraison, les taxes applicables et le travail déjà effectué.

Tout solde excédentaire, s’il y a lieu, sera remboursé au client.

01

Disponibilité variable

La disponibilité des couleurs, designs et options peut changer rapidement. Certaines pièces peuvent devenir en rupture de stock à tout moment, parfois sans retour prévu.

02

Compatibilité selon la version

Il existe plusieurs révisions de manettes PS5 depuis leur sortie initiale. Selon la version exacte de la manette, certaines options peuvent être plus limitées, difficiles à trouver ou non compatibles.

03

Validation avant commande

Les options choisies et le prix final sont toujours confirmés avec le client avant toute commande de pièces. Si une option n’est plus disponible, une alternative sera proposée.

Manette personnalisée sur mesure

Configure ta manette selon ton style de jeu : joysticks, shell, boutons, paddles, mouse-click et accessoires. Le prix estimé se calcule automatiquement.

Manettes personnalisées MicroSoudure Signature
Informations client
Configuration de la manette
Prix estimé
0 $
Résumé copié avec succès.

Le prix affiché est une estimation automatique basée sur la configuration sélectionnée. Le montant final peut varier selon la disponibilité des pièces, leur prix au moment de la commande.

(function(){ const dest = "[email protected]"; const fee = 30; const groups = [ ["Manette","controller",1,[["Client fournit sa manette",0],["Manette remise à neuf",50]]], ["Version de joystick","joystick",0,[["OEM - ALPS",0],["HALL EFFECT - GINFULL",40],["TMR - GINFULL DS13 MAX",70],["TMR - K-SILVER JS13PRO+",70],["TMR - GULIKIT NS51",85]]], ["Coque avant / Shell","frontShell",0,[["OEM",0],["Personnaliser LUNA - eXtremeRate",40],["Personnaliser - eXtremeRate",37]]], ["Coque arrière","backShell",0,[["OEM",0],["Soft Touch Grip - eXtremeRate",31],["Non-Slip Grip - eXtremeRate",35],["Glossy - eXtremeRate",31]]], ["Boutons personnalisés","buttons",0,[["Blanc OEM",0],["Glossy - Aftermarket",15],["Glossy - eXtremeRate",25],["Spécial Glossy - eXtremeRate",25],["Matt - eXtremeRate",26],["Chrome - eXtremeRate",26],["Kit boutons + thumbstick métal - Aftermarket",20],["Kit boutons + thumbstick métal - eXtremeRate",42],["Kit LED - eXtremeRate",65],["Ergonomic Split Dpad Buttons",20]]], ["Garniture avant / Trim","trim",0,[["Noir OEM",0],["Personnaliser - Aftermarket",15],["Personnaliser - eXtremeRate",30]]], ["Bagues décoratives","rings",0,[["Noir OEM",0],["Personnaliser - Aftermarket",10],["Personnaliser - eXtremeRate",20]]], ["Paddles arrière + coque arrière","paddles",1,[["Aucun",0],["RISE V3 - 2 paddles",60],["RISE V3 - 2 paddles métal",65],["RISE4 V3 - 4 paddles",65],["RISE4 V3 - 4 paddles métal",75],["RISE4 V4 - 4 paddles",65],["RISE Plus MAX + Clicky Trigger",95],["RISE Plus MAX métal + Clicky Trigger",105],["RISE4 Plus MAX + Clicky Trigger",105],["RISE4 Plus MAX métal + Clicky Trigger",115],["SPARK + Clicky Trigger",105]]], ["Thumbsticks personnalisés","thumbsticks",0,[["Noir OEM",0],["Personnaliser OEM",5],["Personnaliser - eXtremeRate",20],["ThumbsGear V3 interchangeable - eXtremeRate",30]]], ["Boutons avant mouse-click","frontMouse",0,[["Aucun",0],["Kit Mouse Clicky avant - eXtremeRate",32]]], ["Triggers mouse-click","triggerMouse",0,[["Aucun",0],["Kit Trigger Mouse Clicky - eXtremeRate",38]]], ["Boutons avant + triggers mouse-click","fullMouse",0,[["Aucun",0],["Full Mouse Clicky Kit - eXtremeRate",48]]], ["Case de transport SKULL & CO.","case",1,[["Aucun",0],["Case - SKULL & CO.",40]]], ["Retirer moteurs de vibration","rumbleRemove",0,[["Non",0],["Oui",0]]], ["Retirer microphone intégré","micRemove",0,[["Non",0],["Oui",0]]] ]; const root = document.getElementById("msbuilder"); const cfg = root.querySelector("#cfg"); const sum = root.querySelector("#sum"); const total = root.querySelector("#total"); const toast = root.querySelector("#toast"); function money(v){ return v.toLocaleString("fr-CA") + " $"; } function make(){ cfg.innerHTML = ""; groups.forEach(function(g){ const field = document.createElement("div"); field.className = g[2] ? "full ms-field" : "ms-field"; const label = document.createElement("label"); label.textContent = g[0] + " *"; const select = document.createElement("select"); select.className = "ms-select"; select.dataset.key = g[1]; select.dataset.label = g[0]; g[3].forEach(function(o){ const option = document.createElement("option"); option.value = o[0]; option.dataset.price = o[1]; option.textContent = o[0] + " " + (o[1] ? "(+" + money(o[1]) + ")" : "(Inclus)"); select.appendChild(option); }); field.appendChild(label); field.appendChild(select); cfg.appendChild(field); }); root.querySelectorAll("select").forEach(function(select){ select.addEventListener("change", calc); }); calc(); } function data(){ return Array.from(root.querySelectorAll("select")).map(function(select){ const option = select.options[select.selectedIndex]; return { key: select.dataset.key, label: select.dataset.label, value: option ? option.value : "", price: option ? (+option.dataset.price || 0) : 0 }; }); } function addSummaryRow(labelText, valueText, priceText){ const row = document.createElement("div"); row.className = "row"; const left = document.createElement("span"); left.textContent = labelText; const right = document.createElement("span"); right.className = "sum-value"; const choice = document.createElement("span"); choice.className = "sum-choice"; choice.textContent = valueText; right.appendChild(choice); if (priceText) { const price = document.createElement("span"); price.className = "sum-price"; price.textContent = priceText; right.appendChild(price); } row.appendChild(left); row.appendChild(right); sum.appendChild(row); } function calc(){ const d = data(); const sub = d.reduce(function(a,b){ return a + b.price; },0); const install = d.some(function(i){ return i.key !== "controller" && i.price > 0; }) ? fee : 0; const t = sub + install; total.textContent = money(t); sum.innerHTML = ""; d.forEach(function(i){ addSummaryRow( i.label, i.value, i.price ? "+" + money(i.price) : "Inclus" ); }); addSummaryRow( "Frais d'installation", install ? "+" + money(install) : "Inclus", "" ); } function txt(){ const d = data(); const sub = d.reduce(function(a,b){ return a + b.price; },0); const install = d.some(function(i){ return i.key !== "controller" && i.price > 0; }) ? fee : 0; const t = sub + install; let x = "Nouvelle demande de manette personnalisée - MicroSoudure Signature\n\n"; x += "INFORMATIONS CLIENT\n"; x += "Nom : " + (root.querySelector("#msn").value || "Non indiqué") + "\n"; x += "Téléphone : " + (root.querySelector("#msp").value || "Non indiqué") + "\n"; x += "Courriel : " + (root.querySelector("#mse").value || "Non indiqué") + "\n\n"; x += "CONFIGURATION\n"; d.forEach(function(i){ x += "- " + i.label + " : " + i.value + " " + (i.price ? "(+" + money(i.price) + ")" : "(Inclus)") + "\n"; }); x += "- Frais d'installation : " + (install ? "+" + money(install) : "Inclus") + "\n\n"; x += "PRIX ESTIMÉ : " + money(t) + "\n\n"; x += "NOTES\n" + (root.querySelector("#msnote").value || "Aucune note ajoutée") + "\n\n"; x += "Note : prix estimé seulement. Le prix final peut varier selon la disponibilité des pièces, le prix au moment de la commande, la compatibilité et l'état de la manette."; return x; } function show(message){ toast.textContent = message; toast.style.display = "block"; setTimeout(function(){ toast.style.display = "none"; },2500); } root.querySelector("#copy").onclick = function(){ if (navigator.clipboard) { navigator.clipboard.writeText(txt()).then(function(){ show("Résumé copié avec succès."); }); } else { show("Copie non disponible."); } }; root.querySelector("#send").onclick = function(){ location.href = "mailto:" + dest + "?subject=" + encodeURIComponent("Demande de manette personnalisée") + "&body=" + encodeURIComponent(txt()); }; make(); })();
Choix ajouté au formulaire.
(function () { const choiceFields = { frontShell: { placeholder: "# coque", label: "Coque avant", titles: [ { title: "Coque avant - eXtremeRate", option: "Personnaliser - eXtremeRate" }, { title: "Coque avant LUNA - eXtremeRate", option: "Personnaliser LUNA - eXtremeRate" } ] }, backShell: { placeholder: "# coque", label: "Coque arrière", titles: [ { title: "Coque arrière Soft Touch - eXtremeRate", option: "Soft Touch Grip - eXtremeRate" }, { title: "Coque arrière Non-Slip - eXtremeRate", option: "Non-Slip Grip - eXtremeRate" }, { title: "Coque arrière Glossy - eXtremeRate", option: "Glossy - eXtremeRate" } ] }, trim: { placeholder: "# façade", label: "Façade avant", titles: [ { title: "Façade avant - eXtremeRate", option: "Personnaliser - eXtremeRate" }, { title: "Façade avant - Aftermarket", option: "Personnaliser - Aftermarket" } ] }, buttons: { placeholder: "# couleur", label: "Boutons", titles: [ { title: "Kit Boutons (Matt) - eXtremeRate", option: "Matt - eXtremeRate" }, { title: "Kit Boutons (Chrome) - eXtremeRate", option: "Chrome - eXtremeRate" }, { title: "Kit Boutons (Glossy) - eXtremeRate", option: "Glossy - eXtremeRate" }, { title: "Kit Boutons Spécial (Glossy) - eXtremeRate", option: "Spécial Glossy - eXtremeRate" }, { title: "Kit Boutons (Glossy) - Aftermarket", option: "Glossy - Aftermarket" }, { title: "Kit Boutons et Thumbstick (Métal) - eXtremeRate", option: "Kit boutons + thumbstick métal - eXtremeRate" } ] }, rings: { placeholder: "# bague", label: "Bagues décoratives", titles: [ { title: "Bagues décoratives - eXtremeRate", option: "Personnaliser - eXtremeRate" }, { title: "Bagues décoratives - Aftermarket", option: "Personnaliser - Aftermarket" } ] }, thumbsticks: { placeholder: "# couleur", label: "Thumbsticks", titles: [ { title: "Thumbstick - Original", option: "Personnaliser OEM" }, { title: "Thumbstick - eXtremeRate", option: "Personnaliser - eXtremeRate" }, { title: "eXtremeRate ThumbsGear V3 Interchangeable", option: "ThumbsGear V3 interchangeable - eXtremeRate" } ] }, case: { placeholder: "# case", label: "Case de transport", titles: [ { title: "Case de transport SKULL & CO.", option: "Case - SKULL & CO." }, { title: "Case de transport SKULL & CO", option: "Case - SKULL & CO." }, { title: "Case de transport - SKULL & CO.", option: "Case - SKULL & CO." }, { title: "Case de transport - SKULL & CO", option: "Case - SKULL & CO." }, { title: "Case transport SKULL & CO.", option: "Case - SKULL & CO." }, { title: "Case transport SKULL & CO", option: "Case - SKULL & CO." }, { title: "Case de transport", option: "Case - SKULL & CO." }, { title: "Case transport", option: "Case - SKULL & CO." } ] } }; function getFormRoot() { return document.querySelector("#msbuilder"); } function normalize(text) { return (text || "") .toLowerCase() .normalize("NFD") .replace(/[\u0300-\u036f]/g, "") .replace(/[–—]/g, "-") .replace(/[.]/g, "") .replace(/\s*&\s*/g, " & ") .replace(/\s*\+\s*/g, " + ") .replace(/\s*-\s*/g, " - ") .replace(/\s+/g, " ") .trim(); } function showToast(message) { const toast = document.querySelector("#mss-choice-toast"); if (!toast) return; toast.textContent = message; toast.classList.add("show"); setTimeout(function () { toast.classList.remove("show"); }, 2200); } function addChoiceBoxes() { const formRoot = getFormRoot(); if (!formRoot) return; Object.keys(choiceFields).forEach(function (key) { const select = formRoot.querySelector('select[data-key="' + key + '"]'); if (!select) return; if (select.closest(".mss-choice-wrap")) return; const config = choiceFields[key]; const wrap = document.createElement("div"); wrap.className = "mss-choice-wrap"; const input = document.createElement("input"); input.type = "text"; input.className = "mss-choice-input"; input.placeholder = config.placeholder; input.setAttribute("data-choice-for", key); input.setAttribute("aria-label", config.label); select.parentNode.insertBefore(wrap, select); wrap.appendChild(select); wrap.appendChild(input); }); } function patchChoiceInputs() { const formRoot = getFormRoot(); if (!formRoot) return; formRoot.querySelectorAll(".mss-choice-input").forEach(function (input) { if (input.dataset.mssChoiceInputPatched === "true") return; input.dataset.mssChoiceInputPatched = "true"; input.classList.toggle("filled", !!input.value.trim()); input.addEventListener("input", function () { input.classList.toggle("filled", !!input.value.trim()); refreshNotes(); refreshSummary(); }); }); } function allTitles() { return Object.keys(choiceFields).flatMap(function (key) { return choiceFields[key].titles.map(function (entry) { return { title: entry.title, option: entry.option, key: key, normalizedTitle: normalize(entry.title) }; }); }); } function isIgnored(el) { return ( el.closest("#msbuilder") || el.closest("#mss-side-nav-pro") || el.closest("#mss-choice-box-helper") || el.closest(".mss-top-nav") ); } function getSectionMarkers() { const titles = allTitles(); return Array.from(document.querySelectorAll("h1,h2,h3,h4,h5,p,span,strong,div")) .map(function (item) { if (isIgnored(item)) return null; const text = normalize(item.textContent); if (text.length <= 3 || text.length >= 180) return null; const found = titles.find(function (entry) { return text === entry.normalizedTitle; }); if (!found) return null; return { top: item.getBoundingClientRect().top + window.pageYOffset, section: found }; }) .filter(Boolean) .sort(function (a, b) { return a.top - b.top; }); } function findNearestSectionFromMarkers(element, markers) { const elTop = element.getBoundingClientRect().top + window.pageYOffset; let best = null; markers.forEach(function (marker) { if (marker.top <= elTop) { best = marker.section; } }); return best; } function getNumbersFromText(text) { const raw = (text || "").trim(); if (!raw) return []; if (!/^[\s#\d]+$/.test(raw)) return []; const clean = raw.replace(/\D/g, ""); if (!clean) return []; const number = parseInt(clean, 10); if (clean === "49") { return ["4", "9"]; } if (clean.length <= 2 && number >= 1 && number <= 30) { return [String(number)]; } if (clean.length === 2 && number > 30) { return [clean.charAt(0), clean.charAt(1)]; } return []; } function resolveNumberFromClick(el, event) { const numbers = getNumbersFromText(el.textContent); if (!numbers.length) return ""; if (numbers.length === 1) { return numbers[0]; } const rect = el.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; if (rect.height > rect.width * 1.15) { return y < rect.height / 2 ? numbers[0] : numbers[1]; } return x < rect.width / 2 ? numbers[0] : numbers[1]; } function makeNumbersClickable() { const markers = getSectionMarkers(); if (!markers.length) return; const candidates = Array.from(document.querySelectorAll("p,span,strong,div")) .filter(function (el) { if (isIgnored(el)) return false; if (el.classList.contains("mss-number-click")) return false; if (el.children.length > 0) return false; const numbers = getNumbersFromText(el.textContent); if (!numbers.length) return false; return !!findNearestSectionFromMarkers(el, markers); }); candidates.forEach(function (el) { const section = findNearestSectionFromMarkers(el, markers); if (!section) return; el.classList.add("mss-number-click"); el.dataset.choiceKey = section.key; el.title = "Ajouter au formulaire : " + section.title; el.addEventListener("click", function (event) { event.preventDefault(); event.stopPropagation(); const number = resolveNumberFromClick(el, event); if (!number) return; document .querySelectorAll('.mss-number-click.active[data-choice-key="' + section.key + '"]') .forEach(function (active) { active.classList.remove("active"); }); el.classList.add("active"); setChoice(section.key, "#" + number, section.title, section.option); }); }); } function selectMatchingOption(key, optionText) { const formRoot = getFormRoot(); if (!formRoot) return; const select = formRoot.querySelector('select[data-key="' + key + '"]'); if (!select || !optionText) return; const wanted = normalize(optionText); const options = Array.from(select.options); let match = options.find(function (opt) { return normalize(opt.value) === wanted || normalize(opt.textContent) === wanted; }); if (!match) { match = options.find(function (opt) { const value = normalize(opt.value || opt.textContent); return value.includes(wanted) || wanted.includes(value); }); } if (match) { select.value = match.value; select.dispatchEvent(new Event("change", { bubbles: true })); } } function setChoice(key, value, sectionTitle, optionText) { const formRoot = getFormRoot(); if (!formRoot) return; const input = formRoot.querySelector('[data-choice-for="' + key + '"]'); if (!input) { showToast("Case introuvable pour : " + sectionTitle); return; } selectMatchingOption(key, optionText); input.value = value; input.classList.add("filled"); input.dispatchEvent(new Event("input", { bubbles: true })); input.dispatchEvent(new Event("change", { bubbles: true })); refreshNotes(); setTimeout(function () { refreshSummary(); }, 60); showToast("Ajouté : " + sectionTitle + " " + value); } function getSelectDisplayValue(select) { if (!select || select.selectedIndex < 0) return ""; const selectedOption = select.options[select.selectedIndex]; if (!selectedOption) return ""; const value = (selectedOption.value || selectedOption.textContent || "").trim(); const text = (selectedOption.textContent || "").trim(); const finalValue = value || text; const normalized = normalize(finalValue); if ( !finalValue || normalized === "0" || normalized === "-" || normalized.includes("choisir") || normalized.includes("selectionner") || normalized.includes("sélectionner") || normalized.includes("aucun") || normalized.includes("aucune") || normalized.includes("non merci") ) { return ""; } return finalValue; } function getChoiceValues() { const formRoot = getFormRoot(); if (!formRoot) return []; return Object.keys(choiceFields).map(function (key) { const input = formRoot.querySelector('[data-choice-for="' + key + '"]'); const select = formRoot.querySelector('select[data-key="' + key + '"]'); const inputValue = input ? input.value.trim() : ""; const selectValue = getSelectDisplayValue(select); let finalValue = inputValue; if (key === "case") { if (selectValue && inputValue) { finalValue = selectValue + " — " + inputValue; } else if (selectValue) { finalValue = selectValue; } else { finalValue = inputValue; } } return { key: key, label: choiceFields[key].label, value: finalValue }; }).filter(function (item) { return item.value; }); } function refreshNotes() { const formRoot = getFormRoot(); if (!formRoot) return; const notes = formRoot.querySelector("#msnote"); if (!notes) return; const start = "--- Choix couleurs / modèles ---"; const end = "--- Fin choix couleurs / modèles ---"; let current = notes.value || ""; const regex = new RegExp("\\n?" + start + "[\\s\\S]*?" + end, "m"); current = current.replace(regex, "").trim(); const choices = getChoiceValues(); if (choices.length) { const block = [ start, ...choices.map(function (item) { return item.label + " : " + item.value; }), end ].join("\n"); notes.value = current ? current + "\n\n" + block : block; } else { notes.value = current; } } function refreshSummary() { const formRoot = getFormRoot(); if (!formRoot) return; const choices = getChoiceValues(); const rows = Array.from(formRoot.querySelectorAll("#sum .row")); rows.forEach(function (row) { const left = row.querySelector("span:first-child"); const right = row.querySelector("span:last-child"); if (!left || !right) return; const label = normalize(left.textContent); const match = choices.find(function (item) { return label.includes(normalize(item.label)); }); const old = right.querySelector(".mss-summary-choice"); if (old) old.remove(); if (match) { const small = document.createElement("div"); small.className = "mss-summary-choice"; small.style.marginTop = "3px"; small.style.color = "#fff"; small.style.opacity = "0.95"; small.textContent = "Choix : " + match.value; right.appendChild(small); } }); } function patchSelectChanges() { const formRoot = getFormRoot(); if (!formRoot) return; formRoot.querySelectorAll("select").forEach(function (select) { if (select.dataset.mssChoicePatched === "true") return; select.dataset.mssChoicePatched = "true"; select.addEventListener("change", function () { setTimeout(function () { refreshNotes(); refreshSummary(); }, 30); }); }); } function init() { addChoiceBoxes(); patchChoiceInputs(); patchSelectChanges(); makeNumbersClickable(); refreshNotes(); refreshSummary(); } function boot() { setTimeout(init, 50); setTimeout(init, 150); setTimeout(init, 300); setTimeout(init, 700); setTimeout(init, 1500); setTimeout(init, 3000); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", boot); } else { boot(); } })();
(function () { const fields = { frontShell: { placeholder: "# coque", label: "Coque avant" }, backShell: { placeholder: "# coque", label: "Coque arrière" }, trim: { placeholder: "# façade", label: "Façade avant" }, buttons: { placeholder: "# couleur", label: "Boutons" }, rings: { placeholder: "# bague", label: "Bagues décoratives" }, thumbsticks: { placeholder: "# couleur", label: "Thumbsticks" }, case: { placeholder: "# case", label: "Case de transport" } }; function addFastChoiceBoxes() { const root = document.querySelector("#msbuilder"); if (!root) return false; let added = false; Object.keys(fields).forEach(function (key) { const select = root.querySelector('select[data-key="' + key + '"]'); if (!select) return; if (select.closest(".mss-choice-wrap")) return; const config = fields[key]; const wrap = document.createElement("div"); wrap.className = "mss-choice-wrap"; const input = document.createElement("input"); input.type = "text"; input.className = "mss-choice-input"; input.placeholder = config.placeholder; input.setAttribute("data-choice-for", key); input.setAttribute("aria-label", config.label); select.parentNode.insertBefore(wrap, select); wrap.appendChild(select); wrap.appendChild(input); input.addEventListener("input", function () { input.classList.toggle("filled", !!input.value.trim()); }); added = true; }); return added; } function bootFastLoader() { addFastChoiceBoxes(); const observer = new MutationObserver(function () { addFastChoiceBoxes(); }); observer.observe(document.documentElement, { childList: true, subtree: true }); setTimeout(addFastChoiceBoxes, 50); setTimeout(addFastChoiceBoxes, 150); setTimeout(addFastChoiceBoxes, 300); setTimeout(addFastChoiceBoxes, 700); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", bootFastLoader); } else { bootFastLoader(); } })();

Note importante
Les coques affichées sont des exemples de modèles pouvant être installés.. Les coques disponibles varient selon l’inventaire chez eXtremeRate et sont parfois très limité.
Nous vous invitons à visiter les liens situés sous chaque catégorie, puis à nous indiquer le modèle souhaité dans la section “Demande spéciale”.


Coque avant - eXtremeRate


1

4

7

10

2

5

8

11

3

6

9

12

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration.
La disponibilité sera confirmée avant la commande des pièces.


Coque avant LUNA - eXtremeRate


1

5

9

13

17

21

25

2

6

10

14

18

22

26

3

7

11

15

19

23

27

4

8

12

16

20

24

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Coque arrière Soft Touch - eXtremeRate


1

5

9

13

2

6

10

14

3

7

11

15

4

8

12

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Coque arrière Non-Slip - eXtremeRate


1

5

9

2

6

10

3

7

4

8

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Coque arrière Glossy - eXtremeRate


1

4

2

5

3

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Kit paddles + coque arrière - eXtremeRate


RISE V3

2 boutons arrière programmables.
Configuration simple et légère pour ajouter des raccourcis en jeu.
Inclus :
• Shell/Coque arrière
• 2 boutons arrière
• Remapping programmable

RISE4 V3

4 boutons arrière programmables pour plus de contrôle et de rapidité.
.
Inclus :
• Shell/Coque arrière
• 4 boutons arrière
• Remapping programmable
• Grip arrière

RISE4 V4

Version améliorée du RISE4 avec design plus récent et compatibilité plus large.Inclus :
• Shell/Coque arrière
• 4 boutons arrière
• Remapping programmable
• Grip arrière
• Design V4 amélioré

RISE Plus MAX

Version performance avec trigger stops clicky R2/L2 et meilleure prise en main.Inclus :
• Shell/Coque arrière
• 2 boutons arrière
• Trigger stops clicky
• Grip arrière texturé tidal-hexagon
• Remapping programmable

RISE4 Plus MAX

Version complète avec 4 boutons arrière et trigger stops clicky R2/L2.Inclus :
• Shell/Coque arrière
• 4 boutons arrière
• Trigger stops clicky
• Grip arrière texturé tidal-hexagon
• Remapping programmable

SPARK

Kit premium avec écran OLED intégré, trigger clicky R2/L2. configuration avancée.Inclus :
• Shell/Coque arrière
• 4 boutons arrière
• Écran OLED intégré
• Trigger stops clicky
• Grip arrière texturé tidal-hexagon
• Remapping avancé

La disponibilité exacte des couleurs, sera confirmée par la suite avec le client.*


Façade avant - eXtremeRate


1

5

9

13

17

2

6

10

14

18

3

7

11

15

4

8

12

16

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Façade avant - Aftermarket


1

6

11

16

2

7

12

17

3

8

13

18

4

9

14

19

5

10

15

20

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Thumbstick - Original


1

3

2

4

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Thumbstick - eXtremeRate


1

5

9

13

17

2

6

10

14

18

3

7

11

15

19

4

8

12

16

20

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration.


ThumbsGear V3 Interchangeable - eXtremeRate


1

2

3

4

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Kit Boutons (Matt) - eXtremeRate


1

6

11

16

2

7

12

17

3

8

13

18

4

9

14

19

5

10

15

20

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Kit Boutons (Chrome) - eXtremeRate


1

6

2

7

3

8

4

9

5

10

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Kit Boutons (Glossy) - eXtremeRate


1

5

2

6

3

7

4

8

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Kit Boutons Spécial (Glossy) - eXtremeRate


1

5

2

6

3

7

4

8

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Kit Boutons (Glossy) - Aftermarket


1

6

11

2

7

12

3

8

13

4

9

5

10

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Kit Boutons et Thumbstick (Métal) - eXtremeRate


1

5

2

6

3

7

4

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Kit Boutons et Thumbstick (Métal) - Aftermarket


1

5

2

6

3

7

4

8

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Bagues Décoratives
- eXtremeRate


1

4

7

2

5

8

3

6

9

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Bagues Décoratives
- Aftermarket


1

6

11

2

7

12

3

8

4

9

5

10

Cliquez sur le numéro du modèle souhaité pour l’ajouter automatiquement à votre configuration


Case de Transport - SKULL & CO.


1

2