PageSourceSearch

https://siegel.ausgezeichnet.org/widgets/4fa7f9640cf2ccdc2014e7d1/review-trust-badge.js?ver=7.1.2

js ausgezeichnet.org collected 2026-10-01 15:07:56 UTC 26,200 bytes, 440 lines download raw bytes

1/* Ausgezeichnet Review Trust Badge Widget */
2(function(d) {
3  'use strict';
4
5  var NW_RESPONSIVE_BP = 640;
6
7function injectNwMobileCss(doc) {
8  if (!doc || doc.getElementById('au-nw-mobile-css')) return;
9  var style = doc.createElement('style');
10  style.id = 'au-nw-mobile-css';
11  var compact = [
12    '.au-nw-bar-inner{flex-wrap:wrap!important;gap:8px 10px!important;padding:8px 12px!important;}',
13    '.au-nw-bar-quote{flex:1 1 100%!important;white-space:normal!important;display:-webkit-box!important;-webkit-line-clamp:2!important;-webkit-box-orient:vertical!important;}',
14    '.au-nw-modal-overlay{padding:12px!important;}',
15    '.au-nw-split-grid{grid-template-columns:1fr!important;}',
16    '.au-nw-split-grid>.au-nw-split-accent{border-right:none!important;border-bottom:1px solid var(--au-nw-line,#e6e2d8)!important;}',
17    '.au-nw-flex-split{flex-direction:column!important;}',
18    '.au-nw-flex-split>.au-nw-split-sidebar{width:100%!important;border-right:none!important;border-bottom:1px solid var(--au-nw-line,#e6e2d8)!important;}',
19    '.au-nw-editorial-cols{flex-direction:column!important;}',
20    '.au-nw-editorial-vdiv{display:none!important;}',
21    '.au-nw-reviews-2col{grid-template-columns:1fr!important;}',
22    '.au-nw-summary-header{grid-template-columns:1fr!important;gap:16px!important;}',
23    '.au-nw-summary-cta{width:100%!important;text-align:center;justify-content:center!important;}',
24    '.au-nw-card-wide{grid-template-columns:1fr!important;gap:10px!important;padding:12px!important;}',
25    '.au-nw-card-wide__chevron{display:none!important;}',
26    '.au-nw-card-wide__meta{align-items:flex-start!important;}',
27    '.au-nw-trust-shell{min-width:0!important;width:100%!important;max-width:100%!important;}',
28    '.au-nw-product-inline{width:100%!important;max-width:100%!important;box-sizing:border-box!important;}',
29  ].join('');
30  style.textContent = [
31            /* Merchant themes that carry a `div:empty{display:none}` style — common
32       enough as dead-markup cleanup — erased the widgets' own empty boxes:
33       the rating bars, the 1px dividers, the spinner and the modal's body
34       mount, which is filled after it is inserted and so is empty when the
35       rule is matched. Scoped to the widget's own subtree, and !important
36       because the theme rule may carry it too. */
37    '.au-nw-embed-host div:empty,.au-nw-embed-host span:empty,.au-nw-embed-host i:empty,',
38    '.au-nw-widget-root div:empty,.au-nw-widget-root span:empty,.au-nw-widget-root i:empty,',
39    '.au-nw-modal-overlay div:empty,.au-nw-modal-overlay span:empty,.au-nw-modal-overlay i:empty,',
40    '.au-nw-toast-anchor div:empty,.au-nw-toast-anchor span:empty,.au-nw-toast-anchor i:empty',
41    '{display:revert!important;}',
42    '.au-nw-embed-host{display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box;}',
43    '.au-nw-card-shell{display:flex;flex-direction:column;width:100%;max-width:100%;min-width:0;box-sizing:border-box;}',
44    '.au-nw-card-wide{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;width:100%;max-width:100%;min-width:0;box-sizing:border-box;}',
45    '.au-nw-card-wide__meta{display:flex;flex-direction:column;gap:2px;min-width:0;}',
46    '.au-nw-trust-shell{box-sizing:border-box;}',
47    '.au-nw-split-grid{display:grid;grid-template-columns:minmax(0,220px) minmax(0,1fr);}',
48    '.au-nw-split-grid>.au-nw-split-accent{border-right:1px solid var(--au-nw-line,#e6e2d8);}',
49    '.au-nw-flex-split{display:flex;align-items:stretch;}',
50    '.au-nw-flex-split>.au-nw-split-sidebar{flex:0 0 auto;width:160px;border-right:1px solid var(--au-nw-line,#e6e2d8);}',
51    '.au-nw-flex-split>.au-nw-split-main{flex:1 1 auto;min-width:0;}',
52    '.au-nw-editorial-cols{display:flex;}',
53    '.au-nw-editorial-cols>.au-nw-editorial-col{flex:1 1 0;min-width:0;padding:16px 18px;}',
54    '.au-nw-editorial-vdiv{width:1px;background:var(--au-nw-line-soft,#efece4);align-self:stretch;flex:none;}',
55    '.au-nw-reviews-2col{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;}',
56    '.au-nw-clamp-3{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;}',
57    '.au-nw-summary-header{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:20px 24px;align-items:center;}',
58    '.au-nw-summary-cta{white-space:nowrap;}',
59    '.au-nw-modal-overlay{padding:24px;}',
60    '.au-nw-toast-anchor{position:fixed;bottom:18px;right:18px;left:auto;z-index:2147483647;}',
61    '.au-nw-bar-inner{display:flex;align-items:center;gap:14px;max-width:1200px;margin:0 auto;padding:10px 20px;flex-wrap:nowrap;}',
62    '.au-nw-bar-quote{flex:1;min-width:0;font-style:italic;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}',
63    '@container au-nw (max-width:' + NW_RESPONSIVE_BP + 'px){' + compact + '}',
64    '.au-nw-is-compact .au-nw-bar-inner,.au-nw-is-compact.au-nw-bar-inner{flex-wrap:wrap!important;gap:8px 10px!important;padding:8px 12px!important;}',
65    '.au-nw-is-compact .au-nw-bar-quote,.au-nw-is-compact.au-nw-bar-quote{flex:1 1 100%!important;white-space:normal!important;display:-webkit-box!important;-webkit-line-clamp:2!important;-webkit-box-orient:vertical!important;}',
66    '.au-nw-is-compact.au-nw-modal-overlay,.au-nw-is-compact .au-nw-modal-overlay{padding:12px!important;}',
67    '.au-nw-is-compact .au-nw-split-grid>.au-nw-split-accent,.au-nw-is-compact.au-nw-split-grid>.au-nw-split-accent{border-right:none!important;border-bottom:1px solid var(--au-nw-line,#e6e2d8)!important;}',
68    '.au-nw-is-compact .au-nw-flex-split,.au-nw-is-compact.au-nw-flex-split{flex-direction:column!important;}',
69    '.au-nw-is-compact .au-nw-flex-split>.au-nw-split-sidebar,.au-nw-is-compact.au-nw-flex-split>.au-nw-split-sidebar{width:100%!important;border-right:none!important;border-bottom:1px solid var(--au-nw-line,#e6e2d8)!important;}',
70    '.au-nw-is-compact .au-nw-editorial-cols,.au-nw-is-compact.au-nw-editorial-cols{flex-direction:column!important;}',
71    '.au-nw-is-compact .au-nw-editorial-vdiv,.au-nw-is-compact.au-nw-editorial-vdiv{display:none!important;}',
72    '.au-nw-is-compact .au-nw-reviews-2col,.au-nw-is-compact.au-nw-reviews-2col{grid-template-columns:1fr!important;}',
73    '.au-nw-is-compact .au-nw-summary-header,.au-nw-is-compact.au-nw-summary-header{grid-template-columns:1fr!important;gap:16px!important;}',
74    '.au-nw-is-compact .au-nw-summary-cta,.au-nw-is-compact.au-nw-summary-cta{width:100%!important;text-align:center;justify-content:center!important;}',
75    '.au-nw-is-compact .au-nw-card-wide,.au-nw-is-compact.au-nw-card-wide{grid-template-columns:1fr!important;gap:10px!important;padding:12px!important;}',
76        '.au-nw-is-compact .au-nw-card-wide__meta,.au-nw-is-compact.au-nw-card-wide__meta{align-items:flex-start!important;}',
77    '.au-nw-is-compact .au-nw-trust-shell,.au-nw-is-compact.au-nw-trust-shell{min-width:0!important;width:100%!important;max-width:100%!important;}',
78    '.au-nw-is-compact .au-nw-product-inline,.au-nw-is-compact.au-nw-product-inline{width:100%!important;max-width:100%!important;box-sizing:border-box!important;}',
79    '.au-nw-toast-anchor.au-nw-is-compact{left:12px!important;right:12px!important;bottom:12px!important;}',
80    '.au-nw-toast-anchor.au-nw-is-compact>.au-nw-widget-root{width:100%!important;max-width:100%!important;}',
81    '@media (max-width:' + NW_RESPONSIVE_BP + 'px){' +
82    '.au-nw-toast-anchor{left:12px!important;right:12px!important;bottom:12px!important;}.au-nw-toast-anchor>.au-nw-widget-root{width:100%!important;max-width:100%!important;}' +
83    '.au-nw-is-compact .au-nw-split-grid,.au-nw-is-compact.au-nw-split-grid{grid-template-columns:1fr!important;}',
84    '}',
85  ].join('');
86  (doc.head || doc.documentElement).appendChild(style);
87}
88
89function prepareNwEmbedHost(el) {
90  if (!el) return;
91  el.classList.add('au-nw-widget-wrap', 'au-nw-embed-host');
92  el.style.width = el.style.width || '100%';
93  el.style.maxWidth = '100%';
94  el.style.minWidth = '0';
95  el.style.boxSizing = 'border-box';
96}
97
98function applyNwCompactState(el) {
99  if (!el) return;
100  var w = el.getBoundingClientRect().width;
101  if (w > 0 && w <= NW_RESPONSIVE_BP) el.classList.add('au-nw-is-compact');
102  else el.classList.remove('au-nw-is-compact');
103}
104
105function observeNwResponsiveEl(el, doc) {
106  if (!el || el.getAttribute('data-au-nw-responsive')) return;
107  el.setAttribute('data-au-nw-responsive', '1');
108  applyNwCompactState(el);
109  if (!doc.defaultView || !('ResizeObserver' in doc.defaultView)) return;
110  var ro = new doc.defaultView.ResizeObserver(function() { applyNwCompactState(el); });
111  ro.observe(el);
112}
113
114function scanNwResponsive(root) {
115  var doc = root && root.ownerDocument ? root.ownerDocument : (typeof document !== 'undefined' ? document : null);
116  if (!doc) return;
117  var scope = root && root.querySelectorAll ? root : doc;
118  var sel = '.au-nw-widget-wrap,.au-nw-widget-root,.au-nw-modal-overlay,.au-nw-toast-anchor';
119  var nodes = scope.querySelectorAll ? scope.querySelectorAll(sel) : [];
120  for (var i = 0; i < nodes.length; i++) observeNwResponsiveEl(nodes[i], doc);
121}
122
123function initNwResponsive(doc) {
124  if (!doc || doc.__auNwResponsiveInit) return;
125  doc.__auNwResponsiveInit = true;
126  function scan() { scanNwResponsive(doc); }
127  if (doc.readyState === 'loading') {
128    doc.addEventListener('DOMContentLoaded', scan);
129  } else {
130    scan();
131  }
132  if (typeof MutationObserver !== 'undefined' && doc.body) {
133    var mo = new MutationObserver(scan);
134    mo.observe(doc.body, { childList: true, subtree: true });
135  }
136  var win = doc.defaultView;
137  if (win) {
138    win.addEventListener('resize', scan);
139  }
140}
141  injectNwMobileCss(d);
142  initNwResponsive(d);
143
144  var ACC  = '#d97350';
145  var STAR = '#e6c860';
146  var FG   = '#15130f';
147  var FGM  = '#6c6862';
148  var FGF  = '#9c968d';
149  var BGC  = '#fff';
150  var BGS  = '#f4f2eb';
151  var LN   = '#e6e2d8';
152  var LNS  = '#efece4';
153  var R    = '14px';
154  var RS   = '8px';
155  var FONT = 'Geist,ui-sans-serif,system-ui,sans-serif';
156  var MONO = '"Geist Mono",ui-monospace,monospace';
157
158  var score      = 4.92;
159  var total      = 471;
160  var profileUrl = "https:\/\/siegel.ausgezeichnet.org\/bewertungen-ausgezeichnet.org-QR870";
161  var logoUrl    = "https:\/\/siegel.ausgezeichnet.org\/asset\/images\/host_ausgezeichnet\/logo.svg";
162  var orgName    = "AUSGEZEICHNET.org";
163  var brandName  = "AUSGEZEICHNET";
164  var guidelineUrl = "https:\/\/www.ausgezeichnet.org\/hinweise-bewertungen\/";
165  var hasReviews = total > 0;
166
167  var scoreLabels = {"en":{"very_good":"very good","good":"good","satisfying":"satisfying","sufficient":"sufficient","poor":"poor"},"de":{"very_good":"sehr gut","good":"gut","satisfying":"befriedigend","sufficient":"ausreichend","poor":"mangelhaft"}};
168
169  var I18N = {
170    en: {
171      reviews: 'reviews',
172      view_all: 'View all →',
173      no_reviews_title: 'No reviews yet',
174      no_reviews_body: 'Be the first to review {org}.',
175      be_first_review: 'Be first reviewer →',
176      review_info: 'Notes on reviews',
177      review_info_short: 'Notices'
178    },
179    de: {
180      reviews: 'Bewertungen',
181      view_all: 'Alle ansehen →',
182      no_reviews_title: 'Noch keine verifizierten Bewertungen',
183      no_reviews_body: 'Seien Sie der Erste und bewerten Sie {org}.',
184      be_first_review: 'Als Erste/r bewerten →',
185      review_info: 'Hinweise',
186      review_info_short: 'Hinweise'
187    },
188  };
189
190  function resolveLang(el) {
191    var lang = (el && el.getAttribute('data-lang')) || 'de';
192    lang = String(lang).toLowerCase();
193    return lang === 'en' ? 'en' : 'de';
194  }
195
196  function t(lang, key) {
197    var dict = I18N[lang] || I18N.de;
198    return dict[key] || key;
199  }
200
201  function scoreLabel(lang, s) {
202    var tiers = scoreLabels[lang] || scoreLabels.de;
203    if (s >= 4.5) return tiers.very_good;
204    if (s >= 3.5) return tiers.good;
205    if (s >= 2.5) return tiers.satisfying;
206    if (s >= 1.5) return tiers.sufficient;
207    return tiers.poor;
208  }
209
210  // Single source of truth for all widget number formatting.
211  // d = 0 → integer with thousand separator (140137 → "140.137")
212  // d > 0 → decimal with comma             (4.75   → "4,75")
213  function formatNumber(n, d) {
214    var num = Number(n);
215    if (!isFinite(num)) return '';
216    if (!d) return num.toLocaleString('de-DE');
217    return num.toFixed(d).replace('.', ',');
218  }
219
220  function stars(s, sz) {
221    var o = '<span style="display:inline-flex;gap:2px;color:' + STAR + ';line-height:0;">';
222    for (var i = 1; i <= 5; i++) {
223      var f = i <= Math.round(s);
224      o += '<svg width="' + sz + '" height="' + sz + '" viewBox="0 0 24 24" style="overflow:visible;"><path d="M12 2.5l2.96 6 6.62.96-4.79 4.67 1.13 6.59L12 17.6l-5.92 3.12 1.13-6.59-4.79-4.67 6.62-.96L12 2.5z" fill="' + (f?STAR:'none') + '" stroke="' + STAR + '" stroke-width="' + (f?0:1.5) + '" stroke-linejoin="round"/></svg>';
225    }
226    return o + '</span>';
227  }
228
229  function mark(sz) {
230    return '<img src="' + logoUrl + '" width="' + sz + '" height="' + sz + '" style="display:block;flex:none;width:' + sz + 'px;height:' + sz + 'px;max-width:none;" />';
231  }
232
233  function brand(sz, dom) {
234    return '<span style="display:inline-flex;align-items:center;gap:8px;font-weight:600;font-size:14px;color:' + FG + ';font-family:' + FONT + ';">' +
235      mark(sz || 28) +
236      '<span style="letter-spacing:.04em;font-weight:600;text-transform:uppercase;font-size:12px;">' + brandName + (dom ? '<span style="opacity:.55;font-weight:400;">.org</span>' : '') + '</span></span>';
237  }
238
239  function wrap(href, inner) {
240    return '<a href="' + href + '" target="_blank" rel="noopener noreferrer" class="au-nw-widget-root" style="display:block;text-decoration:none;color:inherit;">' + inner + '</a>';
241  }
242
243  function wrap2(href, inner) {
244    return '<a href="' + href + '" target="_blank" rel="noopener noreferrer" class="au-nw-widget-root" style="display:flex;flex-direction:column;align-items:center;justify-content:center;text-decoration:none;color:inherit;">' + inner + '</a>';
245  }
246
247  /**
248   * Standalone "info" icon link (FontAwesome circle-info, solid). Used directly
249   * (Horizontal pill, Editorial stamp, Floating bubble, Side tab) and reused inside
250   * infoLink() as the trailing icon. `interactive=false` returns a decorative <span>
251   * so the markup is safe to nest inside another <a>.
252   */
253  function infoIcon(lang, opts) {
254    opts = opts || {};
255    var size = opts.size || 14;
256    var color = opts.color || '#9A9CAB';
257    var interactive = opts.interactive !== false;
258    var label = t(lang, 'review_info');
259    /* FontAwesome circle-info (solid). Glyph already includes the filled circle, so we omit the wrapping border. */
260    var inner = '<svg aria-hidden="true" width="' + size + '" height="' + size + '" viewBox="0 0 512 512" style="display:block;"><path fill="currentColor" d="M256 512a256 256 0 1 0 0-512 256 256 0 1 0 0 512zM224 160a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm-8 64l48 0c13.3 0 24 10.7 24 24l0 88 8 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-80 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l24 0 0-64-24 0c-13.3 0-24-10.7-24-24s10.7-24 24-24z"/></svg>';
261    var sharedStyle = 'display:inline-flex;align-items:center;justify-content:center;width:' + size + 'px;height:' + size + 'px;color:' + color + ';text-decoration:none;flex:none;';
262    if (!interactive) {
263      return '<span aria-hidden="true" style="' + sharedStyle + '">' + inner + '</span>';
264    }
265    return '<a href="' + guidelineUrl + '" target="_blank" rel="noopener noreferrer" aria-label="' + label + '" title="' + label + '"' +
266      ' onclick="event.stopPropagation();"' +
267      ' style="' + sharedStyle + '">' + inner + '</a>';
268  }
269
270  /**
271   * Text link to the brand's review-notes page, with an external-link glyph (square +
272   * outgoing arrow) trailing the label. Used in variants that include a textual
273   * notes-on-reviews line (e.g. Classic stamp).
274   */
275  function infoLink(lang, opts) {
276    opts = opts || {};
277    var short = opts.short === true;
278    var size = opts.size || (short ? 9 : 10);
279    var iconSize = opts.iconSize || Math.round(size * 1.1);
280    var color = opts.color || FGM;
281    var label = t(lang, short ? 'review_info_short' : 'review_info');
282    /* External-link glyph (FontAwesome arrow-up-right-from-square path) — decorative, since the wrapping <a> already carries the link semantics. */
283    var icon = '<svg aria-hidden="true" width="' + iconSize + '" height="' + iconSize + '" viewBox="0 0 512 512" style="flex:none;display:inline-block;"><path fill="currentColor" d="M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l82.7 0-201.4 201.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3 448 192c0 17.7 14.3 32 32 32s32-14.3 32-32l0-160c0-17.7-14.3-32-32-32L320 0zM80 96C35.8 96 0 131.8 0 176L0 432c0 44.2 35.8 80 80 80l256 0c44.2 0 80-35.8 80-80l0-80c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 80c0 8.8-7.2 16-16 16L80 448c-8.8 0-16-7.2-16-16l0-256c0-8.8 7.2-16 16-16l80 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L80 96z"/></svg>';
284    return '<a href="' + guidelineUrl + '" target="_blank" rel="noopener noreferrer"' +
285      ' onclick="event.stopPropagation();"' +
286      ' style="display:inline-flex;align-items:center;gap:5px;font-size:' + size + 'px;color:' + color + ';' + (short ? 'padding-bottom:3px;' : '') + 'text-decoration:none;text-underline-offset:2px;letter-spacing:.04em;">' +
287      '<span>' + label + '</span>' + (!short ? icon : '') +
288      '</a>';
289  }
290
291  function emptyBadge(lang) {
292    return wrap(profileUrl,
293      '<div class="au-nw-trust-shell" style="display:inline-flex;flex-direction:column;align-items:center;gap:8px;background:' + BGC + ';border:1px solid ' + LN + ';border-radius:' + R + ';padding:12px 14px;text-align:center;font-family:' + FONT + ';box-shadow:0 1px 0 rgba(20,17,12,.04);">' +
294        brand(20, false) +
295        '<div style="font-size:11px;font-weight:600;color:' + FG + ';">' + t(lang, 'no_reviews_title') + '</div>' +
296        '<div style="font-size:10px;color:' + FGM + ';line-height:1.45;">' + t(lang, 'no_reviews_body').replace('{org}', orgName || 'this business') + '</div>' +
297        '<div style="font-size:10px;font-weight:500;color:' + ACC + ';">' + t(lang, 'be_first_review') + '</div>' +
298        infoLink(lang) +
299      '</div>');
300  }
301
302  var V = {
303    /* Classic stamp — notes-on-reviews shown as a text link in the bottom row. */
304    classic: function(lang) {
305      return wrap(profileUrl,
306        '<div class="au-nw-trust-shell" style="display:inline-flex;flex-direction:column;align-items:center;gap:10px;background:' + BGC + ';border:1px solid ' + LN + ';border-radius:' + R + ';padding:16px 16px 14px;text-align:center;
306font-family:' + FONT + ';box-shadow:0 1px 0 rgba(20,17,12,.04),0 1px 2px rgba(20,17,12,.04);">' +
307          brand(28, false) +
308          '<div style="height:1px;margin-bottom:5px;width:100%;background:' + LNS + '"></div>' +
309          stars(score, 14) +
310          '<div style="display:flex;flex-direction:column;gap:2px;align-items:center;">' +
311            '<div style="font-size:11px;letter-spacing:.18em;color:' + FGF + ';text-transform:uppercase;">' + scoreLabel(lang, score) + '</div>' +
312            '<span style="font-weight:500;">' + formatNumber(score, 2) + '<span style="color:' + FGF + ';"> / ' + formatNumber(5, 2) + '</span></span>' +
313          '</div>' +
314          '<div style="font-size:10px;color:' + FGF + ';">' + formatNumber(total) + ' ' + t(lang, 'reviews') + '</div>' +
315          infoLink(lang) +
316        '</div>');
317    },
318
319    /* Horizontal pill — notes-on-reviews as an inline circle icon right after the stars. */
320    pill: function(lang) {
321      return wrap(profileUrl,
322        '<div style="display:inline-flex;align-items:center;gap:10px;background:' + BGC + ';border:1px solid ' + LN + ';border-radius:999px;padding:8px 14px 8px 8px;box-shadow:0 6px 18px -6px rgba(20,17,12,.18),0 2px 4px rgba(20,17,12,.05);font-family:' + FONT + ';">' +
323          mark(32) +
324          '<div style="display:flex;flex-direction:column;">' +
325            '<div style="display:flex;align-items:center;gap:6px;">' +
326              stars(score, 11) +
327              '<span style="font-size:12px;font-weight:600;">' + formatNumber(score, 2) + '</span>' +
328              '<div style="margin-top:3px">' + infoIcon(lang, { size: 12 }) + '</div>'+
329            '</div>' +
330            '<span style="font-size:10px;margin-top:-3px;color:' + FGF + ';letter-spacing:.04em;">' + formatNumber(total) + ' ' + t(lang, 'reviews') + '</span>' +
331          '</div>' +
332          '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" style="color:' + FGM + '"><path d="M9 6l6 6-6 6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' +
333        '</div>');
334    },
335
336    /* Floating bubble — circle info icon centred just below the bubble. */
337    bubble: function(lang) {
338      return wrap2(profileUrl,
339        '<div style="position:relative;display:inline-flex;width:86px;height:86px;border-radius:50%;background:' + BGC + ';border:1px solid ' + LN + ';box-shadow:0 22px 44px -16px rgba(20,17,12,.28),0 4px 10px rgba(20,17,12,.08);flex-direction:column;align-items:center;justify-content:center;gap:2px;font-family:' + FONT + ';">' +
340          '<span style="font-size:22px;font-weight:600;letter-spacing:-.02em;line-height:1;">' + formatNumber(score, 1) + '</span>' +
341          stars(score, 9) +
342                    '<span style="width:20px;height:20px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;">' +
343              mark(18) +
344          '</span>' +
345          '<span style="position:absolute;bottom:-12px;left:50%;transform:translateX(-50%);">' + infoIcon(lang, { size: 14 }) + '</span>' +
346        '</div>');
347    },
348
349    /* Side tab / Seal — circle info icon centred just below the seal. */
350    seal: function(lang) {
351      return wrap(profileUrl,
352        '<div style="position:relative;display:inline-flex;flex-direction:column;align-items:center;background:' + BGC + ';border:1px solid ' + LN + ';border-radius:' + R + ' ' + R + ' 0 0;box-shadow:0 22px 44px -16px rgba(20,17,12,.28),0 4px 10px rgba(20,17,12,.08);width:76px;font-family:' + FONT + ';">' +
353          '<div style="padding:12px 8px 4px;display:flex;flex-direction:column;align-items:center;gap:6px;">' +
354            mark(38) +
355            stars(score, 9) +
356          '</div>' +
357          '<div style="padding:4px 8px 4px;text-align:center;">' +
358            '<div style="font-size:10px;font-family:' + FONT + ';letter-spacing:.05em;color:' + FGM + ';text-transform:uppercase;margin-bottom:3px;">' + scoreLabel(lang, score) + '</div>' +
359            '<div style="font-size:15px;font-family:' + FONT + ';font-weight:600;letter-spacing:-.02em;line-height:1;color:' + FG + ';">' + formatNumber(score, 2) + '</div>' +
360            '<div style="font-size:9px;
360font-family:' + FONT + ';color:' + FGF + ';">/ ' + formatNumber(5, 2) + '</div>' +
361          '</div>' +
362          '<span style="padding-bottom:3px;">' + infoLink(lang, { short: true }) + '</span>' +
363        '</div>');
364    },
365
366    stamp: function(lang) {
367      return wrap(profileUrl,
368        '<div style="display:inline-flex;flex-direction:column;gap:4px;background:' + BGC + ';border:1px solid ' + LN + ';border-radius:' + RS + ';padding:12px 14px;font-family:' + FONT + ';">' +
369          '<div style="display:inline-flex;align-items:center;gap:5px;">' +
370            mark(14) +
371            '<span style="font-size:9px;letter-spacing:.18em;color:' + FG + ';text-transform:uppercase;font-weight:600;">' + brandName + '</span>' +
372          '</div>' +
373          '<div style="display:flex;align-items:center;gap:8px;">' +
374            '<span style="font-size:24px;font-weight:600;letter-spacing:-.02em;line-height:1;margin-right:5px">' + formatNumber(score, 2) + '</span>' +
375            stars(score, 11) +
376            infoIcon(lang, { size: 14 }) +
377          '</div>' +
378          '<div style="font-size:11px;color:' + FGM + ';">' + formatNumber(total) + ' ' + t(lang, 'reviews') + ' · <span style="color:' + ACC + ';font-weight:500;">' + t(lang, 'view_all') + '</span></div>' +
379        '</div>');
380    },
381  };
382
383  var POS = {
384    'bottom-right': 'position:fixed;bottom:20px;right:20px;z-index:2147483647;',
385    'bottom-left':  'position:fixed;bottom:20px;left:20px;z-index:2147483647;',
386  };
387
388  function applyTheme(dark, shape) {
389    if (dark) {
390      BGC = '#1c1a16'; BGS = '#181613'; LN = '#2a2722'; LNS = '#221f1b';
391      FG = '#f5f3ee'; FGM = '#a39e95'; FGF = '#6e6a62';
392    }
393    if (shape === 'rounded') { R = '22px'; RS = '14px'; }
394    else if (shape === 'square') { R = '4px'; RS = '2px'; }
395  }
396
397  function inject() {
398    var badges = d.querySelectorAll('.auorgTrustBadge');
399    if (!badges.length) return;
400    for (var i = 0; i < badges.length; i++) {
401      var el = badges[i];
402      if (el.getAttribute('data-auorg-init')) continue;
403      el.setAttribute('data-auorg-init', '1');
404      var variant  = (el.getAttribute('data-variant')  || 'classic').toLowerCase();
405      var position = (el.getAttribute('data-position') || 'bottom-right').toLowerCase();
406      applyTheme(el.getAttribute('data-dark') === 'true', el.getAttribute('data-shape') || 'default');
407        var ca = el.getAttribute('data-accent'), cb = el.getAttribute('data-bg'), cl = el.getAttribute('data-border'), ct = el.getAttribute('data-text');
408  if (ca) ACC = ca;
409  if (cb) BGC = cb;
410  if (cl) { LN = cl; LNS = cl; }
411  if (ct) FG = ct;
412      var fn = V[variant] || V.classic;
413      var posCSS = POS[position] || POS['bottom-right'];
414      var wrapper = d.createElement('div');
415      wrapper.className = 'au-nw-widget-wrap';
416      wrapper.style.cssText = posCSS;
417      var widgetLang = resolveLang(el);
418      var emptyMode = (el.getAttribute('data-empty-mode') || 'collect').toLowerCase();
419      if (!hasReviews) {
420        if (emptyMode === 'hide') {
421          el.style.display = 'none';
422          continue;
423        }
424        wrapper.innerHTML = emptyBadge(widgetLang);
425      } else {
426        wrapper.innerHTML = fn(widgetLang);
427      }
428      d.body.appendChild(wrapper);
429      scanNwResponsive(wrapper);
430      el.style.display = 'none';
431    }
432  }
433
434  if (d.readyState === 'loading') {
435    d.addEventListener('DOMContentLoaded', inject);
436  } else {
437    inject();
438  }
439
440}(document));

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.