PageSourceSearch

https://www.metal-supply.se/products/subscription.html?product=1079&campaign_code=paywall

html metal-supply.se collected 2026-10-02 04:42:01 UTC 153,989 bytes, 2,709 lines download raw bytes

1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE html>
3<html xmlns="http://www.w3.org/1999/xhtml"><head id="j_idt5">
4        <link rel="SHORTCUT ICON" href="https://f.nordiskemedier.dk/favicon/metal.ico" />
5        <link rel="ICON" href="https://f.nordiskemedier.dk/favicon/metal.ico" type="image/x-icon" />
6        <title>Välj prenumeration</title>
7        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
8        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
9    <meta id="viewport" name="viewport" content="width=device-width, initial-scale=1" />
10    
10<script>
11        //<![CDATA[
12        (function () {
13            var width = window.innerWidth ||
14                document.documentElement.clientWidth ||
15                document.body.clientWidth;
16            if (width >= 768) {
17                document.getElementById("viewport").setAttribute("content", "width=1344");
18            } else {
19                document.getElementById("viewport").setAttribute("content", "width=device-width, initial-scale=1");
20            }
21        })();
22        //]]>
23    </script>
23
24        <meta http-equiv="content-script-type" content="text/javascript" />
25        <meta http-equiv="cache-control" content="no-cache" />
26        <meta http-equiv="expires" content="0" />
27        <meta http-equiv="pragma" content="no-cache" />
28        
28<script src="/js/vars.js?t=1790858078229" type="text/javascript"></script>
28
29        
29<script src="/js/access.js?t=1790858078229" type="text/javascript"></script>
29
30        
30<script>
31            window.startupTimestamp = "1790858078229";
32            window.contextPath = "";
33            window.domain = "https://www.metal-supply.se";
34            window.fileDomain = "https://f.nordiskemedier.dk";
35            window.logoName = "10";
36            window.hostId = 10;
37            window.visitor = {};
38            window.cvrRestApiAddress = "https://cvr-api.nordiskemedier.dk/resources";
39            window.metaObject = {"industryName":"","authorInitials":"","pageType":"","contentType":""};
40            window.testMode = false;
41
42            window.googleAnalytics = false;
43            window.pendingScriptExecutions = [];
44            window.enableCookieBot = new function () {};
45
46            window.trackerEnabled = true; // TODO: replace with JsVarsServlet after merge
47        </script>
47
48    
49    
49<script type="text/javascript" async="true">
50        //<![CDATA[
51        (function() {
52            var host = window.location.hostname;
53            var element = document.createElement('script');
54            var firstScript = document.getElementsByTagName('script')[0];
55            var url = 'https://cmp.inmobi.com'
56                .concat('/choice/', 'h8eTMmqFZF-_K', '/', host, '/choice.js?tag_version=V3');
57            var uspTries = 0;
58            var uspTriesLimit = 3;
59            element.async = true;
60            element.type = 'text/javascript';
61            element.src = url;
62
63            // Not default InMobi code - make sure there is a script present
64            // before inserting anything before it.
65            if (firstScript) {
66                firstScript.parentNode.insertBefore(element, firstScript);
67            }
68
69            function makeStub() {
70                var TCF_LOCATOR_NAME = '__tcfapiLocator';
71                var queue = [];
72                var win = window;
73                var cmpFrame;
74
75                function addFrame() {
76                    var doc = win.document;
77                    var otherCMP = !!(win.frames[TCF_LOCATOR_NAME]);
78
79                    if (!otherCMP) {
80                        if (doc.body) {
81                            var iframe = doc.createElement('iframe');
82
83                            iframe.style.cssText = 'display:none';
84                            iframe.name = TCF_LOCATOR_NAME;
85                            doc.body.appendChild(iframe);
86                        } else {
87                            setTimeout(addFrame, 5);
88                        }
89                    }
90                    return !otherCMP;
91                }
92
93                function tcfAPIHandler() {
94                    var gdprApplies;
95                    var args = arguments;
96
97                    if (!args.length) {
98                        return queue;
99                    } else if (args[0] === 'setGdprApplies') {
100                        if (
101                            args.length > 3 &&
102                            args[2] === 2 &&
103                            typeof args[3] === 'boolean'
104                        ) {
105                            gdprApplies = args[3];
106                            if (typeof args[2] === 'function') {
107                                args[2]('set', true);
108                            }
109                        }
110                    } else if (args[0] === 'ping') {
111                        var retr = {
112                            gdprApplies: gdprApplies,
113                            cmpLoaded: false,
114                            cmpStatus: 'stub'
115                        };
116
117                        if (typeof args[2] === 'function') {
118                            args[2](retr);
119                        }
120                    } else {
121                        if(args[0] === 'init' && typeof args[3] === 'object') {
122                            args[3] = Object.assign(args[3], { tag_version: 'V3' });
123                        }
124                        queue.push(args);
125                    }
126                }
127
128                function postMessageEventHandler(event) {
129                    var msgIsString = typeof event.data === 'string';
130                    var json = {};
131
132                    try {
133                        if (msgIsString) {
134                            json = JSON.parse(event.data);
135                        } else {
136                            json = event.data;
137                        }
138                    } catch (ignore) {}
139
140                    var payload = json.__tcfapiCall;
141
142                    if (payload) {
143                        window.__tcfapi(
144                            payload.command,
145                            payload.version,
146                            function(retValue, success) {
147                                var returnMsg = {
148                                    __tcfapiReturn: {
149                                        returnValue: retValue,
150                                        success: success,
151                                        callId: payload.callId
152                                    }
153                                };
154                                if (msgIsString) {
155                                    returnMsg = JSON.stringify(returnMsg);
156                                }
157                                if (event && event.source && event.source.postMessage) {
158                                    event.source.postMessage(returnMsg, '*');
159                                }
160                            },
161                            payload.parameter
162                        );
163                    }
164                }
165
166                while (win) {
167                    try {
168                        if (win.frames[TCF_LOCATOR_NAME]) {
169                            cmpFrame = win;
170                            break;
171                        }
172                    } catch (ignore) {}
173
174                    if (win === window.top) {
175                        break;
176                    }
177                    win = win.parent;
178                }
179                if (!cmpFrame) {
180                    addFrame();
181                    win.__tcfapi = tcfAPIHandler;
182                    win.addEventListener('message', postMessageEventHandler, false);
183                }
184            };
185
186            makeStub();
187
188            function makeGppStub() {
189                const CMP_ID = 10;
190                const SUPPORTED_APIS = [
191                    '2:tcfeuv2',
192                    '6:uspv1',
193                    '7:usnatv1',
194                    '8:usca',
195                    '9:usvav1',
196                    '10:uscov1',
197                    '11:usutv1',
198                    '12:usctv1'
199                ];
200
201                window.__gpp_addFrame = function (n) {
202                    if (!window.frames[n]) {
203                        if (document.body) {
204                            var i = document.createElement("iframe");
205                            i.style.cssText = "display:none";
206                            i.name = n;
207                            document.body.appendChild(i);
208                        } else {
209                            window.setTimeout(window.__gpp_addFrame, 10, n);
210                        }
211                    }
212                };
213                window.__gpp_stub = function () {
214                    var b = arguments;
215                    __gpp.queue = __gpp.queue || [];
216                    __gpp.events = __gpp.events || [];
217
218                    if (!b.length || (b.length == 1 && b[0] == "queue")) {
219                        return __gpp.queue;
220                    }
221
222                    if (b.length == 1 && b[0] == "events") {
223                        return __gpp.events;
224                    }
225
226                    var cmd = b[0];
227                    var clb = b.length > 1 ? b[1] : null;
228                    var par = b.length > 2 ? b[2] : null;
229                    if (cmd === "ping") {
230                        clb(
231                            {
232                                gppVersion: "1.1", // must be “Version.Subversion”, current: “1.1”
233                                cmpStatus: "stub", // possible values: stub, loading, loaded, error
234                                cmpDisplayStatus: "hidden", // possible values: hidden, visible, disabled
235                                signalStatus: "not ready", // possible values: not ready, ready
236                                supportedAPIs: SUPPORTED_APIS, // list of supported APIs
237                                cmpId: CMP_ID, // IAB assigned CMP ID, may be 0 during stub/loading
238                                sectionList: [],
239                                applicableSections: [-1],
240                                gppString: "",
241                                parsedSections: {},
242                            },
243                            true
244                        );
245                    } else if (cmd === "addEventListener") {
246                        if (!("lastId" in __gpp)) {
247                            __gpp.lastId = 0;
248                        }
249                        __gpp.lastId++;
250                        var lnr = __gpp.lastId;
251                        __gpp.events.push({
252                            id: lnr,
253                            callback: clb,
254                            parameter: par,
255                        });
256                        clb(
257                            {
258                                eventName: "listenerRegistered",
259                                listenerId: lnr, // Registered ID of the listener
260                                data: true, // positive signal
261                                pingData: {
262                                    gppVersion: "1.1", // must be “Version.Subversion”, current: “1.1”
263                                    cmpStatus: "stub", // possible values: stub, loading, loaded, error
264                                    cmpDisplayStatus: "hidden", // possible values: hidden, visible, disabled
265                                    signalStatus: "not ready", // possible values: not ready, ready
266                                    supportedAPIs: SUPPORTED_APIS, // list of supported APIs
267                                    cmpId: CMP_ID, // list of supported APIs
268                                    sectionList: [],
269                                    applicableSections: [-1],
270                                    gppString: "",
271                                    parsedSections: {},
272                                },
273                            },
274                            true
275                        );
276                    } else if (cmd === "removeEventListener") {
277                        var success = false;
278                        for (var i = 0; i < __gpp.events.length; i++) {
279                            if (__gpp.events[i].id == par) {
280                                __gpp.events.splice(i, 1);
281                                success = true;
282                                break;
283                            }
284                        }
285                        clb(
286                            {
287                                eventName: "listenerRemoved",
288                                listenerId: par, // Registered ID of the listener
289                                data: success, // status info
290                                pingData: {
291                                    gppVersion: "1.1", // must be “Version.Subversion”, current: “1.1”
292                                    cmpStatus: "stub", // possible values: stub, loading, loaded, error
293                                    cmpDisplayStatus: "hidden", // possible values: hidden, visible, disabled
294                                    signalStatus: "not ready", // possible values: not ready, ready
295                                    supportedAPIs: SUPPORTED_APIS, // list of supported APIs
296                                    cmpId: CMP_ID, // CMP ID
297                                    sectionList: [],
298                                    applicableSections: [-1],
299                                    gppString: "",
300                                    parsedSections: {},
301                                },
302                            },
303                            true
304                        );
305                    } else if (cmd === "hasSection") {
306                        clb(false, true);
307                    } else if (cmd === "getSection" || cmd === "getField") {
308                        clb(null, true);
309                    }
310                    //queue all other commands
311                    else {
312                        __gpp.queue.push([].slice.apply(b));
313                    }
314                };
315                window.__gpp_msghandler = function (event) {
316                    var msgIsString = typeof event.data === "string";
317                    try {
318                        var json = msgIsString ? JSON.parse(event.data) : event.data;
319                    } catch (e) {
320                        var json = null;
321                    }
322                    if (typeof json === "object" && json !== null && "__gppCall" in json) {
323                        var i = json.__gppCall;
324                        window.__gpp(
325                            i.command,
326                            function (retValue, success) {
327                                var returnMsg = {
328                                    __gppReturn: {
329                                        returnValue: retValue,
330                                        success: success,
331                                        callId: i.callId,
332                                    },
333                                };
334                                event.source.postMessage(msgIsString ? JSON.stringify(returnMsg) : returnMsg, "*");
335                            },
336                            "parameter" in i ? i.parameter : null,
337                            "version" in i ? i.version : "1.1"
338                        );
339                    }
340                };
341                if (!("__gpp" in window) || typeof window.__gpp !== "function") {
342                    window.__gpp = window.__gpp_stub;
343                    window.addEventListener("message", window.__gpp_msghandler, false);
344                    window.__gpp_addFrame("__gppLocator");
345                }
346            };
347
348            makeGppStub();
349
350            var uspStubFunction = function() {
351                var arg = arguments;
352                if (typeof window.__uspapi !== uspStubFunction) {
353                    setTimeout(function() {
354                        if (typeof window.__uspapi !== 'undefined') {
355                            window.__uspapi.apply(window.__uspapi, arg);
356                        }
357                    }, 500);
358                }
359            };
360
361            var checkIfUspIsReady = function() {
362                uspTries++;
363                if (window.__uspapi === uspStubFunction && uspTries < uspTriesLimit) {
364                    console.warn('USP is not accessible');
365                } else {
366                    clearInterval(uspInterval);
367                }
368            };
369
370            if (typeof window.__uspapi === 'undefined') {
371                window.__uspapi = uspStubFunction;
372                var uspInterval = setInterval(checkIfUspIsReady, 6000);
373            }
374        })();
375        //]]>
376    </script>
376
377            
377<script type="application/ld+json">
378                {
379                    "@context":"http://schema.org",
380                    "@type":"NewsMediaOrganization",
381                    "name":"Metal Supply",
382                    "logo":{
383                        "@type":"ImageObject",
384                        "url":"https://f.nordiskemedier.dk/logo/portal/10.png"
385                    },
386                    "url":"https://www.metal-supply.se",
387                    "ethicsPolicy":"https://www.metal-supply.se/privacy",
388                    "sameAs":["https://www.linkedin.com/company/metal-supply-se/"]
389                }
390            </script>
390
391        
391<script src="/js/notbot.js?t=1790858078229" type="text/javascript"></script>
391
392
393        <link href="https://f.nordiskemedier.dk/font/media.css" rel="stylesheet" />
394        <link rel="stylesheet" href="https://f.nordiskemedier.dk/font-awesome/pro/6.6.0/css/all.min.css" />
395        <link rel="stylesheet" href="https://f.nordiskemedier.dk/bootstrap/5.3.6/css/bootstrap.min.css" />
396        <link rel="stylesheet" href="/css/default.css?t=1790858078229" type="text/css" />
397        
397<script src="https://f.nordiskemedier.dk/jquery/jquery-3.6.0.min.js"></script>
397
398        
399        
399<script src="/js/jquery-ui.min.js"></script>
399<script type="text/javascript" src="/javax.faces.resource/js/jquery.cookies.2.2.0.min.js.html?ln=portal-jsf&amp;t=17908580"></script>
399
400        
400<script src="https://f.nordiskemedier.dk/bootstrap/5.3.6/js/bootstrap.bundle.min.js"></script>
400
401        
401<script src="/js/default.js?t=1790858078229" type="text/javascript"></script>
vendor: 138 bytes, lines 401-403
401
402        <script src="https://www.google.com/recaptcha/api.js?render=explicit&amp;hl=sv" type="text/javascript"></script>
403                
403<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
403
404                
404<script src="/dist/vue-components.umd.min.js?t=1790858078229" type="text/javascript"></script>
404
405        
406        
406<script src="https://f.nordiskemedier.dk/turnjs4/lib/turn.min.js" type="text/javascript"></script>
406<!--[if lt IE 9]>
407            
407<script src="https://f.nordiskemedier.dk/turnjs4/lib/turn.html4.min.js" type="text/javascript"></script>
407<![endif]--><!--[if lt IE 9]>
408                
408<script type="text/javascript">
409                    window.location = "/browser-support.html";
410                </script>
410<![endif]-->
411        
411<script src="https://cdn.jsdelivr.net/npm/ua-parser-js@0/dist/ua-parser.min.js"></script>
411
412    
412<script type="text/javascript">
413        window.enableGTM = function() {
414            try {
vendor: 647 bytes, lines 414-427
414
415                (function (w, d, s, l, i) {
416                    w[l] = w[l] || [];
417                    w[l].push({
418                        'gtm.start':
419                            new Date().getTime(), event: 'gtm.js'
420                    });
421                    var f = d.getElementsByTagName(s)[0],
422                        j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : '';
423                    j.async = true;
424                    j.src =
425                        'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
426                    f.parentNode.insertBefore(j, f);
427                })(window, document, 'script', 'dataLayer', '
427GTM-PPHWGFF
vendor: 16 bytes, lines 427-428
427');
428            
428} catch (err) {
429                console.log(err);
430            }
431        };
432    </script>
432
433        
434
435        
436        
436<script src="/js/cookie-utilities.js"></script>
436
437    
437<script type="text/javascript">
438        var gaPageType = 'misc';
439        var gaContentType = 'misc';
440        var gaPageAge = null;
441        var gaPageSize = null;
442        var gaIndustryName = 'null';
443        
444    </script>
444
445    
445<script type="text/javascript">
446        window.enableBanners = function () {
447            try {
448                window['banner-consent-is-ready'] = true;
449                EventBus.broadcast("banner-consent-is-ready");
450            } catch (err) {
451                console.log(err);
452            }
453        };
454    </script>
454
455    
455<script type="text/javascript">
456        //<![CDATA[
457        (function () {
458            var salespanelModuleEnabled = false;
459            var quantCastModuleEnabled = true;
460            var salespanelResolve, salespanelReject;
461            window.salespanelPromise = new Promise((resolve, reject) => {
462                // Check if Salespanel and QuantCast module is enabled for this host and check if the tag has loaded.
463                if (!salespanelModuleEnabled || !quantCastModuleEnabled) {
464                    resolve(false);
465                }
466                salespanelResolve = resolve;
467                salespanelReject = reject;
468            });
469
470            // Reject just in case QuantCast module is enabled but variable is not initialized.
471            if (typeof window.__tcfapi == "undefined") {
472                salespanelReject("QuantCast error: __tcfapi is undefined");
473                return;
474            }
475
476            // Listen for Quantcast events for changes to Salespanel consent.
477            window.__tcfapi('addEventListener', 2, async function (tcData, success) {
478                if (!success) {
479                    salespanelReject("Salespanel error: Could not create event listener.");
480                    return;
481                }
482
483                // the rest of this function is called when the page is loaded OR
484                // - the user accepts / rejects / updates the consent terms
485                // - the user dismisses the consent box by clicking the 'x'
486                if (tcData.eventStatus !== 'tcloaded' && tcData.eventStatus !== 'useractioncomplete') {
487                    return;
488                }
489
490                // Salespanel is managed by Google Tag Manager and is not inserted if the relevant consent is not given.
491                // If consent is given, it returns true, otherwise false after 2,5 seconds.
492                var loops = 0;
493                while(!salespanelObjectLoaded() && loops < 5) {
494                    await new Promise(resolve => setTimeout(resolve, 500));
495                    loops += 1;
496                }
497
498                if (salespanelObjectLoaded()) {
499                    // Set cookie.
500                    allowTracking();
501                    salespanelResolve(true);
502                } else {
503                    // Remove cookie.
504                    rejectTracking();
505                    // Salespanel did not load in time or was rejected by consent.
506                    salespanelReject("Salespanel error: Not loaded.");
507                }
508            });
509
510            function salespanelObjectLoaded() {
511                return typeof $salespanel !== "undefined" && $salespanel.hasOwnProperty("push");
512            }
513
514            function allowTracking() {
515                // Check if Salespanel tracking has already been allowed.
516                if ($.cookies.get("track_uid") !== null) {
517                    return;
518                }
519
520                try {
521                    // Activate tracking when the visitor provides explicit consent.
522                    // Place `track_uid` cookie.
523                    $salespanel.push(["set", "tracking:allowTracking"]);
524                } catch (e) {
525                    salespanelReject("Salespanel error: Allow tracking failed.");
526                }
527            }
528
529            function rejectTracking() {
530                // Remove cookie if user removed Salespanel consent.
531                // All created Salespanel events will now be un-identified.
532                if ($.cookies.get("track_uid")) {
533                    $.cookies.del("track_uid", {domain: '.metal-supply.se'});
534                }
535            }
536        })();
537        //]]>
538    </script>
538
539    
539<script type="text/javascript">
540        //<![CDATA[
541        window.paywallScripts = {
542            seenPaywall: async function (type) {
543                // Wait for salespanel promise to be fulfilled (either loaded or not).
544                const salespanelLoaded = await window.salespanelPromise.catch(() => {
545                    // Salespanel didn't load if promise is rejected.
546                    return false;
547                });
548                if (!salespanelLoaded) return;
549
550                // Find previous amount of seen paywalls.
551                await this.seenPaywallPromise().then(seenPaywalls => {
552                    // Increment amount of seen paywall on visitor attribute.
553                    this.setPaywallsAttribute(seenPaywalls);
554
555                    // Create Meta/Facebook Pixel event notifying of a seen paywall.
556                    if (seenPaywalls > 3) {
557                        fbq('trackCustom', "Set paywall +3 gange");
558                    }
559                }).catch((message) => {
560                    console.error(message);
561                });
562
563                // Create Salespanel event notifying of a seen paywall.
564                this.sendPaywallEvent(type);
565            },
566            seenPaywallPromise: function () {
567                return new Promise((resolve, reject) => {
568                    try {
569                        $salespanel.push(["get", "qualify:visitor", function (data) {
570                            data.visitor_attributes.paywalls !== null ?
571                                resolve(data.visitor_attributes.paywalls) :
572                                resolve(0);
573                        }]);
574                    } catch (e) {
575                        reject("Salespanel error: Get details failed.");
576                    }
577                });
578            },
579            setPaywallsAttribute: function (seenPaywalls) {
580                try {
581                    $salespanel.push(["set", "attributes:visitor", {
582                        "paywalls": seenPaywalls + 1
583                    }]);
584                } catch (e) {
585                    console.error("Salespanel error: Couldn't set attribute.");
586                }
587            },
588            sendPaywallEvent: function (type) {
589                try {
590                    $salespanel.push(["set",
591                        "activity:customActivity",
592                        "website",
593                        "Saw paywall",
594                        type
595                    ]);
596                } catch (e) {
597                    console.error("Salespanel error: Couldn't send custom activity.");
598                }
599            }
600        }
601        //]]>
602    </script>
602
603            
603<script type="text/javascript">
604                (function (){
605                    var is = [];
606                    var impersonating = false;
607                    if (!impersonating && window.visitor.person && window.visitor.person.id) {
608                        is.push({
609                            name: "person",
610                            ref: window.visitor.person.id
611                        });
612                    }
613                    if (!impersonating && window.visitor.recipient && window.visitor.recipient.id) {
614                        is.push({
615                            name: "recipient",
616                            ref: window.visitor.recipient.id
617                        });
618                    }
619
620                    var evtr;
621                    var queue = [];
622                    window.queueTrackerEvent = function (a, sn, sr, tn, tr) {
623                        if (evtr) {
624                            evtr(a, sn, sr, tn, tr, is);
625                        } else {
626                            queue.push({
627                                a: a,
628                                sn: sn,
629                                sr: sr,
630                                tn: tn,
631                                tr: tr
632                            })
633                        }
634                    };
635                    window.addEventListener("onTrackerLoaded", function () {
636                        evtr = window.createTracker("https://api.evtr.nordiskemedier.dk", "evtr");
637                        while (queue.length) {
638                            var ev = queue.splice(0, 1)[0];
639                            if (ev) {
640                                evtr(ev.a, ev.sn, ev.sr, ev.tn, ev.tr, is);
641                            }
642                        }
643                    });
644                })();
645            </script>
645
646            
646<script async="async" src="https://js.evtr.nordiskemedier.dk/_.js?t=1790858078229" type="text/javascript"></script>
646
647
648        
648<script type="text/javascript">
649            $(function() {
650                $('.item').hover(
651                function() { $(this).css('background-color', '#efefef').css('cursor', 'pointer') },
652                function() { $(this).css('background-color', 'transparent').css('cursor', 'normal') }
653            );
654                $(".tt").tooltip();
655            });
656            function getTitle() {
657                return document.title;
658            }
659            function getLocation() {
660                return window.location;
661            }
662            function getUrl() {
663                return window.location.href;
664            }
665            function confirmDelete(p) {
666                var v = "\u00C4r du s\u00E4ker p\u00E5 att du vill radera \"{0}\"?";
667                v = v.replace("{0}", p);
668                return confirm(v);
669            }
670            function getVisitorEmail() {
671                return "";
672            }
673            function getVisitorRememberInfo() {
674                return true;
675            }
676
677            var ids = [];
678            function messageFade() {
679                $('.fade').fadeTo('slow', 0.3);
680            }
681            
682            // Remove cookies that are no longer in use
683            $(document).ready(function () {
684                $.cookies.del("c1");
685                $.cookies.del("c2");
686                $.cookies.del("c3");
687            });
688
689            window.pushGTrackScript = function (f, cont) {
690                window.pendingScriptExecutions.push({
691                    callback: function () {
692                        if (window.googleAnalytics) {
693                            eval(f(cont));
694                        }
695                    },
696                    context: cont
697                });
698
699            }
700            $(window).on('load', function () {
701                // if subscription is suspended change paywall message.
702                if ($('#paywall-overlay') && window.visitor?.person?.suspended) {
703                    $('#paywall-overlay .paywall-package').html("\u00C5tkomsten \u00E4r avst\u00E4ngd.");
704                    $('#paywall-overlay .paywall-body-wrapper').html("Av s\u00E4kerhetssk\u00E4l \u00E4r ditt konto tillf\u00E4lligt avst\u00E4ngt.".replace('{0}', "[email protected]").replace('{1}', "[email protected]"));
705                    $('.paywall-content-wrapper').addClass('warning');
706                }
707            });
708        </script>
708
709        
709<script type="text/javascript">
710            //<![CDATA[
711            function center(element) {
712                var e=$(element);
713                var w=e.width();
714                var h=e.height();
715                e.css("position","fixed").css("z-index","50000").css("top","50%").css("left","50%").css("margin-left","-"+(w/2)+"px").css("margin-top","-"+(h/2)+"px");
716                e.draggable({
717                    handle: $(element+"_handle")
718                });
719            }
720            //]]>
721        </script>
721
722
723        
724        <link rel="alternate" type="application/rss+xml" title="News RSS" href="https://www.metal-supply.se/xml/rss2/articles" />
725        <link rel="alternate" type="application/rss+xml" title="Advertisements RSS" href="https://www.metal-supply.se/xml/rss2/advertisements?typeId=1&amp;typeId=2" />
726        <link rel="alternate" type="application/rss+xml" title="Competences RSS" href="https://www.metal-supply.se/xml/rss2/competences" />
727        <link rel="alternate" type="application/rss+xml" title="Jobs RSS" href="https://www.metal-supply.se/xml/rss2/jobs" />
728        <link rel="alternate" type="application/rss+xml" title="Courses RSS" href="https://www.metal-supply.se/xml/rss2/courses" />
729
730        
730<script>
731            window.adTracker = {
732                slots: {},
733                adsMeta: {},
734                hoverState: {
735                    currentSlotId: null,
736                    lastChangeTs: 0
737                },
738                clickState: {
739                    lastPointerDown: null,  // { slotId, ts }
740                    clickHandled: false
741                }
742            };
743        </script>
743<script async="async" src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"></script>
743<script>window.googletag = window.googletag || {cmd: []};if (!window.__gptGlobalsInit) {  window.__gptGlobalsInit = true;  window.slotFallbackData = new Map();  window.__inViewPct = window.__inViewPct || {};  window.__lastRefreshAt = new Map();  window.__slotCooldownMs = new Map();  function __canRefresh(slot){    const id = slot.getSlotElementId();    const last = window.__lastRefreshAt.get(id) || 0;    const cd = window.__slotCooldownMs.get(id) || 30000;    return Date.now() - last >= cd;  }  function __markRefreshed(slot){ window.__lastRefreshAt.set(slot.getSlotElementId(), Date.now()); }  window.__refreshState = window.__refreshState || {};  function __getRefreshState(id){    return (window.__refreshState[id] = window.__refreshState[id] || { pending:false, nextAllowedTs:0 });  }  function __tryRefresh(slot){    const id = slot.getSlotElementId();    const st = __getRefreshState(id);    if (!st.pending) return;    if (st.refreshScheduled) return;    const now = Date.now();    const pct = (window.__inViewPct && window.__inViewPct[id]) || 0;    if (now < st.nextAllowedTs){      __scheduleTryRefresh(slot, st.nextAllowedTs - now);      return;    }    if (pct < 50){      __scheduleTryRefresh(slot, 3000);      return;    }    if (!__canRefresh(slot)){      __scheduleTryRefresh(slot, 3000);      return;    }    st.refreshScheduled = true;    const ranInt = Math.floor(Math.random() * (2000 - 100 + 1)) + 100;    setTimeout(function(){      googletag.pubads().refresh([slot]);      __markRefreshed(slot);      st.pending = false;      st.refreshScheduled = false;    }, ranInt);  }function handleSlotRender(slotElementId) {    var labelId = 'label-' + slotElementId;    var labelEl = document.getElementById(labelId);    if (!labelEl) {        return;    }    labelEl.style.display = 'block';}function registerAdSlot(slotId) {    const slotEl = document.getElementById(slotId);    if (!slotEl) return;    const wrapper = slotEl;    wrapper.dataset.adSlotId = slotId;    if (!wrapper.style.position) {        wrapper.style.position = 'relative';    }    window.adTracker = window.adTracker || {};    window.adTracker.slots = window.adTracker.slots || {};    window.adTracker.slotListeners = window.adTracker.slotListeners || {};    const existing = window.adTracker.slotListeners[slotId];    if (existing && existing.wrapper) {        existing.wrapper.removeEventListener('mouseenter', existing.mouseenter);        existing.wrapper.removeEventListener('mouseleave', existing.mouseleave);    }    const mouseenter = function () {        window.adTracker.hoverState.currentSlotId = slotId;        window.adTracker.hoverState.lastChangeTs = Date.now();    };    const mouseleave = function () {        if (window.adTracker.hoverState.currentSlotId === slotId) {            window.adTracker.hoverState.currentSlotId = null;            window.adTracker.hoverState.lastChangeTs = Date.now();        }    };    wrapper.addEventListener('mouseenter', mouseenter);    wrapper.addEventListener('mouseleave', mouseleave);    window.adTracker.slotListeners[slotId] = {        wrapper: wrapper,        mouseenter: mouseenter,        mouseleave: mouseleave    };    window.adTracker.slots[slotId] = wrapper;}  function __scheduleTryRefresh(slot, delayMs){    const id = slot.getSlotElementId();    const st = __getRefreshState(id);    if (st.tryTimer) clearTimeout(st.tryTimer);    st.tryTimer = setTimeout(function(){      st.tryTimer = null;      __tryRefresh(slot);    }, Math.max(0, delayMs || 0));  }  googletag.cmd.push(function(){    googletag.pubads().addEventListener('slotVisibilityChanged', function(e){      const slot = e.slot;      const id = slot.getSlotElementId();      window.__inViewPct[id] = e.inViewPercentage || 0;      __scheduleTryRefresh(slot, 250);    });    googletag.pubads().addEventListener('impressionViewable', function(e){      const slot = e.slot;      const id = slot.getSlotElementId();      const cd = window.__slotCooldownMs.get(id) || 30000;      const st = __getRefreshState(id);      st.pending = true;      st.nextAllowedTs = Date.now() + cd;      __scheduleTryRefresh(slot, cd);    });  });  window.fireWindowResizeEvent = window.fireWindowResizeEvent || function(){    try { window.dispatchEvent(new Event('resize')); } catch(e){}  };}googletag.cmd.push(function(){  window.__fallbackHandled = window.__fallbackHandled || new Set();  googletag.pubads().addEventListener('slotRenderEnded', function(event){    const adslotId = event.slot.getSlotElementId();    if (!event.isEmpty) { fireWindowResizeEvent();        handleSlotRender(adslotId);       window.adTracker.adsMeta[adslotId] = {       creativeId: event.creativeId,       lineItemId: event.lineItemId,       campaignId: event.campaignId,       size: event.size,       adUnitPath: event.slot.getAdUnitPath(),      };    registerAdSlot(adslotId);    return; }    if (!window.slotFallbackData || !window.slotFallbackData.has(adslotId)) { fireWindowResizeEvent(); return; }    if (window.__fallbackHandled.has(adslotId)) { fireWindowResizeEvent(); return; }    window.__fallbackHandled.add(adslotId);    const cfg = window.slotFallbackData.get(adslotId);    try { googletag.destroySlots([event.slot]); } catch(e) {}    requestAnimationFrame(function(){      const toArr = s => s.split('],').map(x=>JSON.parse(x.replace(/\s/g,'') + (x.endsWith(']')?'':']')));      const sizeArrayLarge  = cfg.sizesLarge  ? toArr(cfg.sizesLarge)  : [];      const sizeArraySmall  = cfg.sizesSmall  ? toArr(cfg.sizesSmall)  : [];      const sizeArrayMobile = cfg.sizesMobile ? toArr(cfg.sizesMobile) : [];      var mapping = googletag.sizeMapping()        .addSize([1588,0], sizeArrayLarge)        .addSize([768,0],  sizeArraySmall)        .addSize([0,0],    sizeArrayMobile).build();      var already = googletag.pubads().getSlots().some(s => s.getSlotElementId() === adslotId);      if (!already) {        var fb = googletag.defineSlot(cfg.fallbackAdUnitPath, cfg.sizes, adslotId)          .defineSizeMapping(mapping)          .addService(googletag.pubads());        if (cfg.refreshAdSlot === 'true') {          window.__slotCooldownMs && window.__slotCooldownMs.set(adslotId, Number(cfg.refreshInterval)||30000);        } else {          window.__slotCooldownMs && window.__slotCooldownMs.set(adslotId, 1440000);        }      }      setTimeout(function(){        try { googletag.display(adslotId); } catch(e) { console.warn('fallback display failed:', e); }        fireWindowResizeEvent();      }, 0);    });  });});googletag.cmd.push(function(){googletag.setConfig({singleRequest: true});googletag.setConfig({ collapseDiv: "ON_NO_FILL" });  googletag.enableServices();});</script>
743
744
745
746        
746<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
746</head><body class="minified">
747            
747<script src="/js/cookie-consent.js"></script>
747
748
749        <div style="display:none;">
750            <a href="/void/index.html" rel="nofollow">23948sdkhjf</a>
751        </div>
752        <i id="media-width-detection" style="display: none">
753            
754            <i class="d-md-none xs"></i>
755            <i class="d-none d-md-inline lg"></i>
756        </i>
vendor: 93 bytes, lines 756-758
756
757            
758            <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
758GTM-PPHWGFF
vendor: 101 bytes, lines 758-761
758" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
759
760        
761        
761<div class="remodal-bg">
762        <header id="main-header" v-cloak="" class="unprintable">
763            <nav>
764                <div>
765                    <global-search-icon></global-search-icon>
766                </div>
767                <div>
768                    <a href="/" class="logo">
769                        <img src="https://f.nordiskemedier.dk/logo/portal/10.png" alt="Metal Supply" />
770                    </a>
771                </div>
772                <div>
773                    <button v-if="window.visitor.person" v-on:click.prevent="open(personMenu)" class="btn btn-link btn-log-in px-0" style="position: relative;">
774                        <i class="fa-light fa-user d-sm-none"></i>
775                        <span class="d-none d-sm-inline">Mitt konto</span>
776                        <span class="badge bg-danger rounded-pill translate-middle notification-badge notification-badge--account" v-if="unreadNotifications &gt; 0 &amp;&amp; 10 &gt; unreadNotifications">{{ unreadNotifications }}</span>
777                        <span class="badge bg-danger rounded-pill translate-middle notification-badge notification-badge--account" v-else-if="unreadNotifications &gt; 0 &amp;&amp; unreadNotifications &gt;= 10"> 9+ </span>
778                    </button>
779                    <button v-else="" v-on:click.prevent="open(topMenu)" class="btn btn-link btn-log-in px-0">
780                        <i class="fa-light fa-user d-sm-none"></i>
781                        <span class="d-none d-sm-inline">Logga in</span>
782                    </button>
783                    <button v-if="(window.visitor.ipAccess &amp;&amp; !window.visitor.ipAccess.disable &amp;&amp; window.visitor.ipAccess.corporateClient) || (window.visitor.person &amp;&amp; window.visitor.corporateClient)" v-on:click.prevent="open(ipAccessMenu)" class="btn btn-link btn-ip-access px-0">
784                        <span class="d-flex" v-if="window.visitor.corporateClient &amp;&amp; window.visitor.person &amp;&amp; window.visitor.person.companiesWhereAdmin &amp;&amp; window.visitor.person.companiesWhereAdmin.length == 1">
785                            <i class="fa-light fa-lock-open me-1"></i><span class="short-name">{{ truncateString(window.visitor.corporateClient.name, 12) }}</span><span class="long-name">{{ truncateString(window.visitor.corporateClient.name, 20) }}</span>
786                        </span>
787                        <span class="d-flex" v-else-if="window.visitor.corporateClient &amp;&amp; window.visitor.person &amp;&amp; window.visitor.person.companiesWhereAdmin &amp;&amp; window.visitor.person.companiesWhereAdmin.length &gt; 1">
788                            <i class="fa-light fa-lock-open me-1"></i><span class="short-name">{{ truncateString("Företagslösning", 12) }}</span><span class="long-name">{{ truncateString("Företagslösning", 20) }}</span>
789                        </span>
790                        <span class="d-flex" v-else-if="window.visitor.ipAccess &amp;&amp; !window.visitor.ipAccess.disable &amp;&amp; window.visitor.ipAccess.corporateClient">
791                            <i class="fa-light fa-lock-open me-1"></i><span class="short-name">{{ truncateString(window.visitor.ipAccess.corporateClient.name, 12) }}</span><span class="long-name">{{ truncateString(window.visitor.ipAccess.corporateClient.name, 20) }}</span>
792                        </span>
793                        <span class="d-flex" v-else="">
794                            <i class="fa-light fa-lock-open me-1"></i><span class="short-name">{{ truncateString(window.visitor.corporateClient.name, 12) }}</span><span class="long-name">{{ truncateString(window.visitor.corporateClient.name, 20) }}</span>
795                        </span>
796                    </button>
797                    <template v-else=""><a id="j_idt106:j_idt108" href="/products/subscription.html" style="" class="btn btn-primary" target="">
798                            <span class="d-inline d-sm-none">Köp</span>
799                            <span class="d-none d-sm-inline">Köp åtkomst</span></a>
800                    </template>
801                    <button v-on:click.prevent="open(rightMenu)" class="btn btn-link btn-bars px-0 d-inline-flex">
802                        <i class="fa-light fa-bars-staggered"></i>
803                    </button>
804                </div>
805            </nav>
806            <div v-on:click.self="close" class="menu-container menu-top" v-bind:class="getStyleClass(topMenu)">
807                <div>
808                    <menu-log-in v-bind:sign-up-link="signUpLink" v-on:close="close"></menu-log-in>
809                </div>
810            </div>
811            <div v-on:click.self="close" class="menu-container menu-right" v-bind:class="getStyleClass(rightMenu)">
812                <div>
813                    <div style="align-items: center;" class="d-flex justify-content-end">
814                        <button v-if="window.visitor.person" v-on:click.prevent="open(personMenu)" class="btn btn-link btn-log-in px-0">
815                            Mitt konto
816                        </button>
817                        <button v-else="" v-on:click.prevent="open(topMenu)" class="btn btn-link btn-log-in px-0">
818                            <i class="fa-light fa-user d-sm-none"></i>
819                            <span class="d-none d-sm-inline">Logga in</span>
820                        </button>
821                        <button v-if="(window.visitor.ipAccess &amp;&amp; !window.visitor.ipAccess.disable &amp;&amp; window.visitor.ipAccess.corporateClient) || (window.visitor.person &amp;&amp; window.visitor.corporateClient)" v-on:click.prevent="open(ipAccessMenu)" class="btn btn-link btn-ip-access px-0 mx-4">
822                            <span class="d-flex" v-if="window.visitor.corporateClient &amp;&amp; window.visitor.person &amp;&amp; window.visitor.person.companiesWhereAdmin &amp;&amp; window.visitor.person.companiesWhereAdmin.length == 1">
823                                <i class="fa-light fa-lock-open me-1"></i><span class="short-name">{{ truncateString(window.visitor.corporateClient.name, 12) }}</span><span class="long-name">{{ truncateString(window.visitor.corporateClient.name, 20) }}</span>
824                            </span>
825                            <span class="d-flex" v-else-if="window.visitor.corporateClient &amp;&amp; window.visitor.person &amp;&amp; window.visitor.person.companiesWhereAdmin &amp;&amp; window.visitor.person.companiesWhereAdmin.length &gt; 1">
826                                <i class="fa-light fa-lock-open me-1"></i><span class="short-name">{{ truncateString("Företagslösning", 12) }}</span><span class="long-name">{{ truncateString("Företagslösning", 20) }}</span>
827                            </span>
828                            <span class="d-flex" v-else-if="window.visitor.ipAccess &amp;&amp; !window.visitor.ipAccess.disable &amp;&amp; window.visitor.ipAccess.corporateClient">
829                                <i class="fa-light fa-lock-open me-1"></i><span class="short-name">{{ truncateString(window.visitor.ipAccess.corporateClient.name, 12) }}</span><span class="long-name">{{ truncateString(window.visitor.ipAccess.corporateClient.name, 20) }}</span>
830                            </span>
831                            <span class="d-flex" v-else="">
832                                <i class="fa-light fa-lock-open me-1"></i><span class="short-name">{{ truncateString(window.visitor.corporateClient.name, 12) }}</span><span class="long-name">{{ truncateString(window.visitor.corporateClient.name, 20) }}</span>
833                            </span>
834                        </button>
835                        <template v-else=""><a id="j_idt110:j_idt112" href="/products/subscription.html" style="" class="btn btn-primary mx-4" target="">
836                                <span class="d-inline d-sm-none">Köp</span>
837                                <span class="d-none d-sm-inline">Köp åtkomst</span></a>
838                        </template>
839                        <button v-on:click.prevent="close" class="btn btn-link btn-x px-0 d-inline-flex">
840                            <i class="fa-light fa-xmark-large"></i>
841                        </button>
842                    </div>
843                    <div class="mt-5 mb-4">
844                        <global-search-input></global-search-input>
845                    </div>
846                    <ul class="primary-menu">
847                        <li v-for="(option, i) in mainOptions" v-bind:key="i" v-bind:class="{'open': unfolded == i}">
848                            <a v-if="option.target" v-bind:href="option.target" v-bind:target="option.external ? '_blank' : ''">{{ option.name }}</a>
849                            <template v-else-if="option.children">
850                                <a href="#" v-on:click.prevent="unfolded = unfolded != i ? i : null">{{ option.name }}<i class="fa-light" v-bind:class="{'fa-chevron-down': unfolded != i, 'fa-chevron-up': unfolded == i}"></i></a>
851                                <ul>
852                                    <li v-for="(child, j) in option.children" v-bind:key="j">
853                                        <a v-bind:href="child.target" v-bind:target="child.external ? '_blank' : ''">{{ child.name }}</a>
854                                    </li>
855                                </ul>
856                            </template>
857                        </li>
858                    </ul>
859                    <ul class="secondary-menu">
860                            <li>
861                                <a href="/epages/archive.html">
862                                    <i class="fa-light fa-newspaper"></i>E-tidning
863                                </a>
864                            </li>
865                        <li>
866                            <a href="/newsletter/subscribe.html"><i class="fa-light fa-envelope"></i>Registrera nyhetsbrev</a>
867                        </li>
868                        <li>
869                            <a href="/bookmark"><i class="fa-light fa-bookmark"></i>Min läslista</a>
870                        </li>
871                    </ul>
872                    <ul v-if="mainSecondaryOptions &amp;&amp; mainSecondaryOptions.length" class="secondary-menu">
873                        <li v-for="(option, i) in mainSecondaryOptions" v-bind:key="i">
874                            <a v-if="option.target" v-bind:href="option.target" v-bind:target="option.external ? '_blank' : ''">{{ option.name }}</a>
875                            <template v-else-if="option.children">
876                                <span>{{ option.name }}</span>
877                                <ul>
878                                    <li v-for="(child, j) in option.children" v-bind:key="j">
879                                        <a v-bind:href="child.target" v-bind:target="child.external ? '_blank' : ''">{{ child.name }}</a>
880                                    </li>
881                                </ul>
882                            </template>
883                        </li>
884                    </ul>
885                        <div class="extra">
886                            <ip-access-toggle></ip-access-toggle>
887                        </div>
888                </div>
889            </div>
890            <div v-if="window.visitor.person" v-on:click.self="close" class="menu-container menu-right" v-bind:class="getStyleClass(personMenu)">
891                <div>
892                    <div class="d-flex">
893                        <div class="d-flex w-50 align-items-center">
894                        </div>
895
896                        <div style="align-items: center;" class="d-flex justify-content-end w-50">
897                            <button v-on:click.prevent="close" class="btn btn-link btn-x px-0 d-inline-flex">
898                                <i class="fa-light fa-xmark-large"></i>
899                            </button>
900                        </div>
901                    </div>
902                    <ul class="primary-menu mt-4">
903                        <li v-bind:class="{'open': unfolded == -1}">
904                            <a href="#" v-on:click.prevent="unfolded = unfolded != -1 ? -1 : null" class="border-top-0">
905                                <span class="d-block">
906                                    <span class="d-block">{{ window.visitor.person.name }}</span>
907                                    <small v-if="window.visitor.member" class="d-block text-muted">
908                                        <span class="me-2">{{ window.visitor.member.name }}</span>
909                                        <span v-if="window.visitor.person.members &amp;&amp; window.visitor.person.members.length &gt; 1" class="border rounded px-1">+{{ window.visitor.person.members.length - 1 }}</span>
910                                    </small>
911                                </span>
912                                <i class="fa-light" v-bind:class="{'fa-chevron-down': unfolded != -1, 'fa-chevron-up': unfolded == -1}"></i>
913                            </a>
914                            <ul>
915                                <li v-if="window.visitor.person.members &amp;&amp; window.visitor.person.members.length &gt; 1" v-for="member in window.visitor.person.members">
916                                    <a href="#" v-on:click="switchMember(member.id)">
917                                        {{ member.name }}
918                                        <small class="d-block text-muted">Företagsprofil<i v-if="window.visitor.member &amp;&amp; member.id === window.visitor.member.id" class="text-success ms-2 fa-solid fa-check-circle"></i></small>
919                                    </a>
920                                </li>
921                                <li>
922                                    <a href="/user/update.html">Inställningar</a>
923                                </li>
924                                <li>
925                                    <a href="/member/log-out.html">Logga ut</a>
926                                </li>
927                            </ul>
928                        </li>
929                        <li v-for="(option, i) in personOptions" v-bind:key="i" v-bind:class="{'open': unfolded == i}">
930                            <a v-if="option.target" v-bind:href="option.target" v-bind:target="option.external ? '_blank' : ''">{{ option.name }}</a>
931                            <template v-else-if="option.children">
932                                <a href="#" v-on:click.prevent="unfolded = unfolded != i ? i : null">{{ option.name }}<i class="fa-light" v-bind:class="{'fa-chevron-down': unfolded != i, 'fa-chevron-up': unfolded == i}"></i></a>
933                                <ul>
934                                    <li v-for="(child, j) in option.children" v-bind:key="j">
935                                        <a v-bind:href="child.target" v-bind:target="child.external ? '_blank' : ''">{{ child.name }}</a>
936                                    </li>
937                                </ul>
938                            </template>
939                        </li>
940                    </ul>
941                    <ul class="secondary-menu">
942                            <li>
943                                <a href="/epages/archive.html">
944                                    <i class="fa-light fa-newspaper"></i>E-tidning
945                                </a>
946                            </li>
947                        <li>
948                            <a href="/newsletter/subscribe.html"><i class="fa-light fa-envelope"></i>Registrera nyhetsbrev</a>
949                        </li>
950                        <li>
951                            <a href="/bookmark"><i class="fa-light fa-bookmark"></i>Min läslista</a>
952                        </li>
953                    </ul>
954                    <ul v-if="mainSecondaryOptions &amp;&amp; mainSecondaryOptions.length" class="secondary-menu">
955                        <li v-for="(option, i) in mainSecondaryOptions" v-bind:key="i">
956                            <a v-if="option.target" v-bind:href="option.target" v-bind:target="option.external ? '_blank' : ''">{{ option.name }}</a>
957                            <template v-else-if="option.children">
958                                <span>{{ option.name }}</span>
959                                <ul>
960                                    <li v-for="(child, j) in option.children" v-bind:key="j">
961                                        <a v-bind:href="child.target" v-bind:target="child.external ? '_blank' : ''">{{ child.name }}</a>
962                                    </li>
963                                </ul>
964                            </template>
965                        </li>
966                    </ul>
967                        <div class="extra">
968                            <ip-access-toggle></ip-access-toggle>
969                        </div>
970                </div>
971            </div>
972            <div v-if="(window.visitor.ipAccess &amp;&amp; !window.visitor.ipAccess.disable &amp;&amp; window.visitor.ipAccess.corporateClient) || (window.visitor.person &amp;&amp; window.visitor.corporateClient)" v-on:click.self="close" class="menu-container menu-right" v-bind:class="getStyleClass(ipAccessMenu)">
973                <div>
974                    <div style="align-items: center;" class="d-flex justify-content-end">
975                        <button v-on:click.prevent="close" class="btn btn-link btn-x px-0 d-inline-flex">
976                            <i class="fa-light fa-xmark-large"></i>
977                        </button>
978                    </div>
979                            <ul class="ip-menu">
980                                <li>
981                                    <h5 v-if="window.visitor.corporateClient &amp;&amp; window.visitor.person &amp;&amp; window.visitor.person.companiesWhereAdmin &amp;&amp; window.visitor.person.companiesWhereAdmin.length == 1" class="m-0">{{ window.visitor.corporateClient.name }}</h5>
982                                    <h5 v-else-if="window.visitor.corporateClient &amp;&amp; window.visitor.person &amp;&amp; window.visitor.person.companiesWhereAdmin &amp;&amp; window.visitor.person.companiesWhereAdmin.length &gt; 1" class="m-0">Företagslösning</h5>
983                                    <h5 v-else-if="window.visitor.ipAccess &amp;&amp; !window.visitor.ipAccess.disable &amp;&amp; window.visitor.ipAccess.corporateClient" class="m-0">{{ window.visitor.ipAccess.corporateClient.name }}</h5>
984                                    <h5 v-else="" class="m-0">{{ window.visitor.corporateClient.name }}</h5>
985                                </li>
986                                <li v-if="window.visitor.corporateClient &amp;&amp; window.visitor.person &amp;&amp; window.visitor.person.companiesWhereAdmin &amp;&amp; window.visitor.person.companiesWhereAdmin.length &gt;= 1"><p><b>Välkommen till vår företagslösning</b></p>
987<p>Här kan du administrera användarna i din företagslösning.</p>
988                                </li>
989                                <li v-else-if="window.visitor.corporateClient &amp;&amp; window.visitor.person &amp;&amp; window.visitor.corporateClient &amp;&amp; !window.visitor.ipAccess">Välkommen till din prenumeration för Metal Supply.
990                                </li>
991                                <li v-else=""><p><b>Welcome to our Corporate client solution</b></p>
992<p>Your IP is registered with the company mentioned above and provides access to Metal Supply.</p>
993                                </li>
994                                <template v-if="window.visitor.person &amp;&amp; window.visitor.person.companiesWhereAdmin &amp;&amp; window.visitor.person.companiesWhereAdmin.length &gt;= 1">
995                                    <li v-for="company in window.visitor.person.companiesWhereAdmin" class="subscription-menu-company-link">
996                                        <a v-bind:href="company.link">
997                                            <span class="d-block">
998                                                <span class="d-block">
999                                                    Hantera företagsprenumeration
1000                                                </span>
1001                                                <small v-if="window.visitor.person.companiesWhereAdmin.length &gt;= 1" class="d-block text-muted">{{company.name}}</small>
1002                                            </span>
1003                                        </a>
1004                                    </li>
1005                                </template>
1006                                <li v-if="window.visitor.ipAccess &amp;&amp; window.visitor.ipAccess.corporateClient &amp;&amp; window.visitor.ipAccess.corporateClient.type != 3 &amp;&amp; window.visitor.ipAccess.corporateClient.type != 2 &amp;&amp; !window.visitor.person">
1007                                    <a v-bind:href="'/corporate-client/index.html?token='+window.visitor.ipAccess.corporateClient.token" class="btn btn-link p-0">
1008                                        Click here to go to sign-up<i class="fa-light fa-arrow-right ms-2"></i>
1009                                    </a>
1010                                </li>
1011                            </ul>
1012                        <div class="extra">
1013                            <ip-access-toggle></ip-access-toggle>
1014                        </div>
1015                </div>
1016            </div>
1017        </header>
1018        
1018<script type="application/javascript">
1019            //<![CDATA[
1020            window.mainMenu = new Vue({
1021                el: "#main-header",
1022                data: {
1023                    topMenu: {
1024                        transitioning: false,
1025                        open: false
1026                    },
1027                    rightMenu: {
1028                        transitioning: false,
1029                        open: false
1030                    },
1031                    personMenu: {
1032                        transitioning: false,
1033                        open: false
1034                    },
1035                    ipAccessMenu: {
1036                        transitioning: false,
1037                        open: false
1038                    },
1039                    notificationsMenu: {
1040                        transitioning: false,
1041                        open: false
1042                    },
1043                    personNotifications: [],
1044                    unreadNotifications: 0,
1045                    hasMore: true,
1046                    stack: [],
1047                    unfolded: null,
1048                    mainOptions: [{"children":[{"external":false,"name":"Senaste nytt","target":"/article/latest.html"}],"name":"Nyheter"},{"children":[{"external":false,"name":"Medlemsnyheter","target":"/announcement"},{"external":false,"name":"Företag","target":"/company"}],"name":"Branschinsikt"},{"children":[{"external":false,"name":"Maskiner","target":"/machine"},{"external":false,"name":"Produkter","target":"/product"},{"external":false,"name":"Tjänster","target":"/competence"},{"external":false,"name":"Kurser","target":"/course"}],"name":"Köp & Sälj"},{"external":false,"name":"Jobb","target":"/job"},{"external":false,"name":"Kalendarium","target":"/event/search"}],
1049                    mainSecondaryOptions: [{"children":[{"external":false,"name":"Bli prenumerant","target":"/products/subscription.html"}
1049,{"external":true,"name":"Bli medlem","target":"https://nordiskemediehus.dk/se/produkt/medlemskab/"},{"external":true,"name":"Annonsera","target":"https://nordiskemediehus.dk/se/se-metal-supply/"},{"external":true,"name":"Se alla produkter","target":"https://nordiskemediehus.dk/se/produkter/"}],"name":"Produkter"}],
1050                    createSubscriptionLink: {"external":false,"name":"Bli prenumerant","target":"/products/subscription.html"},
1051                    createMembershipLink: {"external":true,"name":"Bli medlem","target":"https://nordiskemediehus.dk/se/produkt/medlemskab/"},
1052                },
1053                computed: {
1054                    personOptions: function () {
1055                        const options = [];
1056
1057                        const add = (list, name, target) => {
1058                            const option = {
1059                                name
1060                            };
1061                            if (target) {
1062                                option.target = target;
1063                            } else {
1064                                option.children = [];
1065                            }
1066                            list.push(option);
1067                            return option.children;
1068                        }
1069
1070                        if (!window.visitor.member) {
1071                            add(options, "Market overview", "/watch");
1072                        } else {
1073                            add(options, "Aktiviteter", "/member");
1074
1075                            if (window.visitor.member.state.type.announcements || window.visitor.member.state.type.posts) {
1076                                const createItems = add(options, "Skapa ett inlägg");
1077                                if (window.visitor.member.state.type.announcements) {
1078                                    add(createItems, "Nyhet", "/post/announcement");
1079                                }
1080                                if (window.visitor.member.state.type.posts) {
1081                                    if (true) {
1082                                        add(createItems, "Maskin eller produkt", "/post/machine-or-product");
1083                                    }
1084                                    if (true) {
1085                                        add(createItems, "Tj\u00E4nst", "/post/competence");
1086                                    }
1087                                    if (true) {
1088                                        add(createItems, "Jobb", "/post/job");
1089                                    }
1090                                    if (true) {
1091                                        add(createItems, "Kurs", "/post/course");
1092                                    }
1093                                }
1094
1095                                if (window.visitor.member.state.type.posts && true && (true)) {
1096                                    const crawlingItems = add(options, "Importlagring");
1097                                    add(crawlingItems, "Import overview", "/post/overview?imported=true");
1098                                    add(crawlingItems, "Crawling status", "/import/status.html");
1099                                }
1100
1101                                add(options, "Sammanst\u00E4llning", "/post/overview");
1102                            }
1103                            // if (window.visitor.member.misc.banners || window.visitor.member.misc.newsletterBanners) {
1104                            //     const bannerItems = add(options, "Annonsering");
1105                            //     if (window.visitor.member.misc.banners) {
1106                            //         add(bannerItems, "\u00D6versikt", "/banner/index.html");
1107                            //     }
1108                            //     if (window.visitor.member.misc.newsletterBanners) {
1109                            //         add(bannerItems, "Annonsering i nyhetsbrevet", "/newsletter/banner/index.html");
1110                            //     }
1111                            //     // Member-specifik kode... virker ikke med cache
1112                            //     // const saleEmail = "N\/A";
1113                            //     // if (saleEmail.indexOf("@") != -1) {
1114                            //     //     add(bannerItems, "Kontakta oss f\u00F6r ett kostnadsf\u00F6rslag", "mailto:" + saleEmail + "?subject=N\u00E4r det g\u00E4ller annonsering");
1115                            //     // }
1116                            // }
1117
1118                            if (false) {
1119                                add(options, "Market overview", "/watch");
1120                            }
1121
1122                            const profileItems = add(options, "F\u00F6retagsprofil");
1123                            add(profileItems, "Se profilen", "/company/view/" + window.visitor.member.id + "/" + window.visitor.member.slug);
1124                            if (window.visitor.member.state.type.profile) {
1125                                add(profileItems, "Redigera profil", "/company/profile.html");
1126                            }
1127                            add(profileItems, "Kontakter", "/member-contact/overview");
1128                            if (window.visitor.member.state.type.supplements) {
1129                                add(profileItems, "F\u00F6retagsportf\u00F6lj", "/supplement/management");
1130                            }
1131                            add(profileItems, "Inst\u00E4llningar f\u00F6r administrat\u00F6rer", "/company/administrators.html");
1132
1133                            add(options, "Hj\u00E4lp", "/member/help.html");
1134                        }
1135
1136                        return options;
1137                        //     var addContacts = function (items, text, contacts) {
1138                        //         if (contacts) {
1139                        //             var contactItems = [];
1140                        //             for (var i = 0; i < contacts.length; i++) {
1141                        //                 var contact = contacts[i];
1142                        //                 contactItems.push({
1143                        //                     text: contact.name,
1144                        //                     portrait: contact.portrait,
1145                        //                     phonePrefix: "Tel: ",
1146                        //                     phone: contact.phone,
1147                        //                     email: contact.email
1148                        //                 });
1149                        //             }
1150                        //             items.push({
1151                        //                 text: text,
1152                        //                 items: contactItems,
1153                        //             });
1154                        //         }
1155                        //     };
1156                        //
1157                        //     var contactItems = [];
1158                        //     for (var contact in this.visitor.contacts) {
1159                        //         addContacts(contactItems, this.visitor.contacts[contact].title, this.visitor.contacts[contact].contacts);
1160                        //     }
1161                        //
1162                        //     items.push({
1163                        //         icon: "fa-light fa-phone-alt",
1164                        //         text: "Kontakt",
1165                        //         href: "#",
1166                        //         items: contactItems,
1167                        //     });
1168                        //
1169                        //     return {
1170                        //         items: items
1171                        //     };
1172                        // }
1173                    },
1174                    signUpLink: function () {
1175                        if (window.access.module.subscriptions && this.createSubscriptionLink) {
1176                            this.createSubscriptionLink.name = "Prenumerera";
1177                            return this.createSubscriptionLink;
1178                        } else if (this.createMembershipLink) {
1179                            this.createMembershipLink.name = "Bli medlem";
1180                            return this.createMembershipLink;
1181                        } else {
1182                            return null;
1183                        }
1184                    }
1185                },
1186                watch: {
1187                    stack: function (newValue) {
1188                        if (newValue && newValue.length > 0) {
1189                            document.body.classList.add("menu-open");
1190                        } else {
1191                            document.body.classList.remove("menu-open");
1192                        }
1193                    }
1194                },
1195                mounted: function () {
1196                    document.addEventListener("keyup", this.keyupListener);
1197                },
1198                unmounted: function () {
1199                    window.removeEventListener("keyup", this.keyupListener);
1200                },
1201                created: function () {
1202                    this.loadUnreadNotificationCount();
1203                },
1204                updated: function () {
1205                    if(this.notificationsMenu.open) {
1206                        this.$nextTick(() => {
1207                            this.markNotificationsSeen();
1208                        });
1209                    }
1210                },
1211                methods: {
1212                    truncateString(str, maxLength) {
1213                        if (!str || typeof str !== 'string') return '';
1214                        const ellipsis = '…';
1215
1216                        if (str.length > maxLength) {
1217                            let trimmed = str.slice(0, maxLength);
1218                            trimmed = trimmed.replace(/\s+$/, '');
1219                            if ((trimmed + ellipsis).length < str.length) {
1220                                return trimmed + ellipsis;
1221                            }
1222                        }
1223
1224                        return str;
1225                    },
1226                    keyupListener: function (event) {
1227                        if (event.keyCode == 27) {
1228                            this.close();
1229                        }
1230                    },
1231                    open: function (menu) {
1232                        this.stack.push(menu);
1233                        menu.transitioning = true;
1234                        this.$nextTick(() => {
1235                            menu.open = true;
1236                        })
1237                    },
1238                    openNotificationsMenu: function () {
1239                        if(false) {
1240                            this.open(this.notificationsMenu);
1241                            this.loadNotifications();
1242                        }
1243                    },
1244                    close: function () {
1245                        const menu = this.stack.length ? this.stack.splice(this.stack.length - 1, 1)[0] : null;
1246                        if (menu) {
1247                            menu.open = false;
1248                            setTimeout(() => {
1249                                menu.transitioning = false;
1250                            }, 250)
1251                        }
1252                    },
1253                    closeNotificationsMenu: function () {
1254                        this.$nextTick(() => {
1255                            this.loadUnreadNotificationCount();
1256                        });
1257                        this.close(this.notificationsMenu);
1258                    },
1259                    getStyleClass: function (menu) {
1260                        return {
1261                            "transitioning": menu.transitioning || menu.open,
1262                            "open": menu.open
1263                        };
1264                    },
1265                    switchMember: function (memberId) {
1266                        this.$services.personSecureService.switchMember(memberId)
1267                            .then(() => window.location.reload())
1268                            .catch(err => console.error(err));
1269                    },
1270                    openLogIn: function () {
1271                        Vue.$hashUtil.remove("paywall");
1272                        this.open(this.topMenu);
1273                    },
1274                    loadNotifications: function () {
1275                        if (window.visitor.person && false) {
1276                         this.$services.notificationSecureService.loadByPerson()
1277                             .then(data => {
1278                               this.personNotifications = data;
1279                             }).catch(err => {
1280                           console.error(err);
1281                         });
1282                        }
1283                    },
1284                    loadUnreadNotificationCount: function () {
1285                        if (window.visitor.person && false) {
1286                          this.$services.notificationSecureService.loadUnreadCount()
1287                              .then(data => {
1288                                this.unreadNotifications = data;
1289                              }).catch(err => {
1290                            console.error(err);
1291                          });
1292                        }
1293                    },
1294                    async markNotificationsSeen() {
1295                        if (this.personNotifications.length > 0) {
1296                            const personNotificationIds = this.personNotifications
1297                                            .filter(n => !n.seen)
1298                                            .map(n => n.id);
1299                            if (personNotificationIds.length > 0) {
1300                                this.$services.notificationSecureService.seen(personNotificationIds);
1301                            }
1302                        }
1303                    },
1304                    async handleClick(personNotification) {
1305                        this.$services.notificationSecureService.clicked(personNotification.id);
1306                        window.location.href = personNotification.notification.link;
1307                    },
1308                    async loadMore() {
1309                        min = Math.max(this.personNotifications.length, 0);
1310                        this.loadNotifications(min, 15);
1311                    },
1312                    timeAgo(dateString) {
1313                        const created = new Date(dateString);
1314                        const now = new Date();
1315
1316                        const seconds = Math.floor((now - created) / 1000);
1317
1318                        if (seconds < 60) return seconds + ' sekunder sedan';
1319
1320                        const minutes = Math.floor(seconds / 60);
1321                        if (minutes < 60) return minutes + ' minuter sedan';
1322
1323                        const hours = Math.floor(minutes / 60);
1324                        if (hours < 60) return hours + ' timmar sedan';
1325
1326                        const days = Math.floor(hours / 24);
1327                        if (days < 7) return days + ' dagar sedan';
1328
1329                        const dd = ("0" + created.getDate()).slice(0-2);
1330                        const mm = ("0" + (created.getMonth() + 1)).slice(0-2);
1331                        const yyyy = created.getFullYear();
1332                        return dd + "-" + mm + "-" + yyyy;
1333                    }
1334                }
1335            });
1336            //]]>
1337        </script>
1337
1338        <header id="extra-header" class="unprintable">
1339            <nav></nav>
1340            <nav>
1341                <featured-links v-bind:value="featuredOptions"></featured-links>
1342            </nav>
1343        </header>
1344        
1344<script type="application/javascript">
1345            //<![CDATA[
1346            new Vue({
1347                el: "#extra-header",
1348                data: {
1349                    featuredOptions: [{"external":false,"name":"Nyheter","target":"/"},{"external":false,"name":"Medlemsnyheter","target":"/announcement"},{"external":false,"name":"Köp & Sälj","target":"/buy-sell"},{"external":false,"name":"Jobb","target":"/job"},{"external":false,"name":"Företag","target":"/company"}],
1350                    articles: []
1351                }
1352            });
1353            //]]>
1354        </script>
1354
1355    <hash-modal id="paywall-modal" v-cloak="" v-on:opened="opened" hash="paywall" class="paywall paywall-modal ">
1356                    <div class="paywall-message">Logga in eller skapa en prenumeration f&ouml;r att spara artiklar
1357                    </div>
1358            <div class="paywall-body-wrapper">
1359                <div class="paywall-gain">
1360                    Få tillgång till allt innehåll på Metal Supply
1361                </div>
1362                <div class="paywall-binding">
1363                    Ingen bindningstid eller kortinformation krävs
1364                </div>
1365                <div class="paywall-action"><a id="j_idt148:j_idt150:j_idt161:j_idt165" href="/products/subscription.html?product=1079&amp;campaign_code=paywall" style="" class="btn btn-primary" target="">
1366                        Prova Metal Supply nu
1367                    </a>
1368                </div>
1369                <div class="paywall-log-in">
1370                    Redan prenumerant? <a href="#" v-on:click.prevent="window.mainMenu.openLogIn()">Logga in</a>
1371                </div>
1372                <div class="paywall-conditions">
1373                    <div>
1374                        Gäller endast personlig prenumeration.
1375                    </div>
1376                        <div>Kontakta oss för en <a id="j_idt148:j_idt150:j_idt169:0:j_idt171" href="/products/subscription.html?product=1103&amp;campaign_code=paywall">företagslösning</a>.
1377                        </div>
1378                </div>
1379            </div>
1380    </hash-modal>
1381    
1381<script type="text/javascript">
1382        //<![CDATA[
1383        new Vue({
1384            el: "#paywall-modal",
1385            methods: {
1386                opened: function () {
1387                    window.paywallScripts.seenPaywall("unknown");
1388                }
1389            }
1390        });
1391        //]]>
1392    </script>
1392
1393
1394            <div class="super-container">
1395                <div class="base-container">
1396
1397
1398                    <main>
1399    
1399<script src="/js/vue-components.js"></script>
1399
1400
1401    <div id="supscriptions-app" v-cloak="">
1402        <div v-if="loading" class="d-flex justify-content-center" style="margin-top: 10px;">
1403            <div class="loading-spinner-subscription"></div>
1404        </div>
1405        <div v-else-if="!selectedProduct &amp;&amp; hideProducts === false">
1406            <div class="d-flex justify-content-center subscription-description-single">
1407                Välj din åtkomst till Metal Supply
1408            </div>
1409            <div style="position: relative;">
1410                <div class="row g-0" v-on:touchstart="onTouchStart" v-on:touchmove="onTouchMove" v-on:touchend="onTouchEnd">
1411                    <div class="col d-none d-md-flex align-items-center justify-content-center">
1412                        <div v-if="productIndex" v-on:click="prevProduct()" class="subscription-scroll-button left">
1413                            <i class="fas fa-chevron-circle-left"></i>
1414                        </div>
1415                    </div>
1416                    <div class="col-12 col-md-11">
1417                        <transition-group id="products" tag="div" v-bind:style="touchQueue.length ? 'overflow-x: hidden' : ''" class="row flex-md-row flex-md-nowrap justify-content-center subscription-product-list subscription-zero-highlight-box-container" v-bind:class="{'justify-content-md-start': products.length &gt; 3}" mode="out-in" v-bind:name="slideDirection">
1418                            <div v-for="(product, index) in visibleProducts" v-bind:key="'product' + product.id" class="col-12 col-md-4">
1419                                <div class="subscription-product align-self-start d-flex flex-column justify-content-between" v-bind:id="'product-'+product.id">
1420                                    <div>
1421                                        <div v-if="product.free &amp;&amp; product.price != null &amp;&amp; !campaignProductId" class="subscription-zero-highlight-box">
1422                                            Prova 1 månad för 0 kr.
1423                                        </div>
1424                                        <div class="product-name-price-combined">
1425                                            <div class="product-name">
1426                                                {{ formattedProductName(product.name) }}
1427                                            </div>
1428                                            <div v-if="product.price != null" class="product-price-text d-flex justify-content-center" v-html="formattedPrice(product.price)">
1429                                            </div>
1430                                            <div v-else="" class="product-price-text d-flex justify-content-center">Kontakta oss</div>
1431
1432                                            <div v-if="product.subtitle" class="form-price-subtitle d-flex justify-content-center">
1433                                                {{ product.subtitle }}
1434                                            </div>
1435                                        </div>
1436                                        <ul class="product-features">
1437                                            <li v-for="(feature, index) in computedFeatures(product.id)" v-if="product.showFeatures || index == 0 || index == 1 || index == 2" v-bind:class="index == 2 &amp;&amp; !product.showFeatures ? 'transparent-feature' : ''">
1438                                                <span v-bind:id="'feature-name-' + index" v-bind:class="'subscription-feature-name'" v-html="formatFeatureTitle(feature.title)">
1439                                                </span>
1440                                                <div v-if="containsDoubleBrackets(feature.title)" class="subscription-feature-hover">
1441                                                    {{ feature.text }}
1442                                                </div>
1443                                            </li>
1444                                        </ul>
1445                                    </div>
1446                                    <div>
1447                                        <div v-if="product.showFeatures">
1448                                            <button type="button" class="btn btn-success btn-rounded w-100" v-on:click="selectProduct(product)">
1449                                                <template v-if="product != null &amp;&amp; !product.price">
1450                                                    Kontakta oss för erbjudanden
1451                                                </template>
1452                                                <template v-else-if="product != null &amp;&amp; product.price &amp;&amp; !product.free">
1453                                                    Köp en prenumeration  
1454                                                </template>
1455                                                <template v-else-if="product != null &amp;&amp; product.price &amp;&amp; product.free">
1456                                                    Prova på
1457                                                </template>
1458                                            </button>
1459                                            <div class="product-description d-flex justify-content-center">
1460                                                {{ product.priceDetail }}
1461                                            </div>
1462                                        </div>
1463                                        <div class="product-show-more" v-on:click="showFeatures(product, !product.showFeatures)" v-show="!product.showFeatures">
1464                                            <div class="d-flex justify-content-center">
1465                                                <i v-bind:class="['fa-light', product.showFeatures ? '' : 'fa-chevron-circle-down']"></i>
1466                                            </div>
1467                                        </div>
1468                                        <div class="d-flex justify-content-center" v-if="product.showFeatures &amp; window.width &lt; 768" v-on:click="showFeatures(product, false)">
1469                                            <i class="fas fa-chevron-circle-up" style="font-size: 40px;"></i>
1470                                        </div>
1471                                    </div>
1472                                </div>
1473                            </div>
1474                        </transition-group>
1475                    </div>
1476                    <div class="col d-none d-md-flex align-items-center justify-content-center">
1477                        <div v-if="productIndex + productCols &lt; products.length" v-on:click="nextProduct()" class="subscription-scroll-button right">
1478                            <i class="fas fa-chevron-circle-right"></i>
1479                        </div>
1480                    </div>
1481                </div>
1482            </div>
1483        </div>
1484
1485        
1486
1487        <div v-else-if="selectedProduct || hideProducts === true" id="contact-form" style="display: block;" v-bind:style="['display: block']">
1488            <div class="d-flex justify-content-center subscription-description-single">
1489                <ul id="progress-bar" class="subscription-progressbar">
1490                    <li class="active">Information</li>
1491                    <li v-if="selectedProduct != null &amp;&amp; selectedProduct.price != null || renewCard === true">Betalning</li>
1492                    <li>Kvitto</li>
1493                </ul>
1494            </div>
1495            <div v-if="productPage">
1496
1497                <div class="row">
1498                    <div class="col-12 col-md-8 order-2 order-md-1">
1499                        <form id="supscriptionsFormApp" class="subscription-form" v-on:submit.prevent="handleSubmit">
1500                            <div>
1501                                <h3>Beställning av:  {{ formattedProductName(selectedProduct.name) }}</h3>
1502                                
1503                                <div role="tabpanel" class="tab-pane fade in active show" id="profile">
1504
1505                                    <div id="contactType">
1506                                        <div class="form-group form-check" style="text-align: start; width: 100%;">
1507                                            <input id="company" class="form-check-input" type="checkbox" v-model="pendingOrder.company" v-bind:disabled="companyDisabled" />
1508                                            <label for="company">Är du ett företag?</label>
1509                                        </div>
1510                                    </div>
1511
1512                                    <div id="infoContainer">
1513                                        
1514                                        <div class="row">
1515                                            
1516                                            <div class="col-12 col-sm-6">
1517                                                <input-text-floating id="firstName" label="Förnamn *" v-bind:errors="formErrors.firstName" v-model="pendingOrder.firstName" required="true" maxlength="50" placeholder=""></input-text-floating>
1518                                            </div>
1519                                            
1520                                            <div class="col-12 col-sm-6">
1521                                                <input-text-floating id="lastName" label="Efternamn *" v-bind:errors="formErrors.lastName" v-model="pendingOrder.lastName" required="true" maxlength="50" placeholder=""></input-text-floating>
1522                                            </div>
1523                                        </div>
1524                                        
1525                                        <input-text-floating id="email" label="E-post *" v-bind:errors="formErrors.email" v-model="pendingOrder.email" required="true" maxlength="255" placeholder="" input-type="email"></input-text-floating>
1526                                        
1527                                        
1528                                        <input-text-floating v-show="pendingOrder.company" id="companyName" v-bind:label="'F\u00F6retag' + (pendingOrder.company ? ' *' : '')" v-bind:errors="formErrors.companyName" v-model="pendingOrder.companyName" v-bind:required="pendingOrder.company ? true : false" maxlength="50" placeholder=""></input-text-floating>
1529                                        
1530                                        <input-text-floating v-show="pendingOrder.company" id="cvr" v-bind:label="'VAT nummer' + (pendingOrder.company ? ' *' : '')" v-bind:errors="formErrors.cvr" v-model="pendingOrder.cvr" v-bind:required="pendingOrder.company ? true : false " maxlength="255" placeholder=""></input-text-floating>
1531                                        
1532                                        <div class="autocomplete-container">
1533                                            <div id="addressInput-container" class="form-floating">
1534                                                <input-text-floating id="addressInput" label="Adress *" v-bind:errors="formErrors.addressInput" v-model="pendingOrder.address" maxlength="1000" required="true" placeholder="" onkeyup="makeAPICall()"></input-text-floating>
1535                                                
1536                                                <div id="autocompleteDropdown" class="autocomplete-suggestions" style="display: none;"></div>
1537                                            </div>
1538                                        </div>
1539                                        <div class="checkbox form-group">
1540                                            <div id="detailedAddressGroup">
1541                                                <input id="showDetailedAddress" type="checkbox" v-model="showDetailedAddress" class="checkbox" />
1542                                                <label for="showDetailedAddress">Visa detaljerad adressinmatning</label>
1543                                            </div>
1544                                        </div>
1545                                        <div v-show="showDetailedAddress" class="detailed-address form-group">
1546                                            <div class="row">
1547                                                
1548                                                
1549                                                <div v-if="bordas" class="col-12 col-sm-6">
1550                                                    <input-text-floating id="streetName" label="Gata/väg" v-bind:errors="formErrors.streetName" v-model="pendingOrder.streetName" maxlength="255" placeholder=""></input-text-floating>
1551                                                </div>
1552                                                
1553                                                <div v-if="bordas" class="col-4 col-sm-2">
1554                                                    <input-text-floating id="streetNumber" label="Nr." v-bind:errors="formErrors.streetNumber" v-model="pendingOrder.streetNumber" placeholder=""></input-text-floating>
1555                                                </div>
1556                                                
1557                                                <div v-if="bordas" class="col-4 col-sm-2">
1558                                                    <input-text-floating id="floor" label="VÃ¥ning" v-bind:errors="formErrors.floor" v-model="pendingOrder.floor" maxlength="2" placeholder=""></input-text-floating>
1559                                                </div>
1560                                                
1561                                                <div v-if="bordas" class="col-4 col-sm-2">
1562                                                    <input-text-floating id="door" label="Dörr" v-bind:errors="formErrors.door" v-model="pendingOrder.door" maxlength="4" placeholder=""></input-text-floating>
1563                                                </div>
1564
1565
1566                                                
1567                                                <div v-if="!bordas" class="col-12">
1568                                                    <input-text-floating id="addressFull" label="Adress" v-bind:errors="formErrors.addressFull" v-model="pendingOrder.addressFull" maxlength="1000" placeholder=""></input-text-floating>
1569                                                </div>
1570                                                
1571                                                <div class="col-12 col-sm-4">
1572                                                    <input-text-floating id="postalCode" label="Postnummer" v-bind:errors="formErrors.postalCode" v-model="pendingOrder.postalCode" maxlength="10" placeholder=""></input-text-floating>
1573                                                </div>
1574                                                
1575                                                <div class="col-12 col-sm-8">
1576                                                    <input-text-floating id="addressCity" label="Stad" v-bind:errors="formErrors.addressCity" v-model="pendingOrder.addressCity" maxlength="50" placeholder=""></input-text-floating>
1577                                                </div>
1578                                            </div>
1579                                        </div>
1580
1581                                        
1582                                        <div class="row">
1583                                            
1584                                            <div class="col-12 col-md-6">
1585                                                <div id="countryId-container" class="form-group">
1586                                                    <div class="form-floating">
1587                                                        <select id="countryId" class="form-select" v-model="pendingOrder.country" required="true">
1588                                                            <option value="" selected="" disabled="">Land</option>
1589                                                            <option v-for="countryOption in countryOptions" v-bind:value="countryOption.id">{{ countryOption.name }}
1590                                                            </option>
1591                                                        </select>
1592                                                        <label for="countryId">Land *</label>
1593                                                    </div>
1594                                                </div>
1595                                            </div>
1596                                            
1597                                            <div class="col-12 col-md-6">
1598                                                <div id="phone-container">
1599                                                    <div class="row g-0">
1600                                                        <div class="col-auto">
1601                                                            <input-text-floating id="callingCode" label="Kod *" v-bind:errors="formErrors.callingCode" v-model="pendingOrder.callingCode" required="true" maxlength="5" placeholder="" style="max-width: 5rem;" input-type="number" input-class="border-end-0 rounded-0 rounded-start"></input-text-floating>
1602                                                        </div>
1603                                                        <div class="col">
1604                                                            <input-text-floating id="phoneNumber" label="Telefon *" v-bind:errors="formErrors.phoneNumber" v-model="pendingOrder.phoneNumber" required="true" maxlength="25" placeholder="" input-type="tel" input-class="rounded-0 rounded-end"></input-text-floating>
1605                                                        </div>
1606                                                    </div>
1607                                                </div>
1608                                            </div>
1609                                        </div>
1610                                    </div>
1611                                    
1612                                    <div class="form-floating">
1613                                        <textarea id="remarks" v-model="pendingOrder.remarks" v-bind:errors="formErrors.remarks" placeholder="" maxlength="5000" class="form-control custom-textarea"></textarea>
1614                                        <label for="remarks" class="input-label">Notering</label>
1615                                    </div>
1616                                </div>
1617                            </div>
1618                            <div>
1619
1620                                
1621
1622
1623
1624
1625
1626
1627
1628
1629                                
1630                                <div class="form-group checkbox">
1631                                    <input id="marketing" type="checkbox" v-model="pendingOrder.marketing" />
1632                                    <label for="marketing">Ja tack, jag vill gärna få marknadsföring, erbjudanden, undersökningar o.s.v. från Metal Supply. <a href="/privacy">Läs cookie- och datapolicy.</a></label>
1633                                </div>
1634
1635                                
1636                                <div v-show="selectedProduct.price" id="acceptTerms-container" class="form-group checkbox">
1637                                    <input id="termsAccepted" type="checkbox" v-model="termsAccepted" required="true" />
1638                                    <label for="termsAccepted">Jag har läst och godkänner prenumerationsavtalet.  <a href="/page/v
1638iew.html?id=18342">Se villkoren</a></label>
1639                                </div>
1640                            </div>
1641                            
1642                            <div class="payment-buttons justify-content-center d-flex">
1643                                
1644                                <template v-if="!selectedProduct.price">
1645                                    <button type="submit" id="company-button" class="btn btn-success btn-rounded d-flex justify-content-center" value="company">
1646                                        Skicka
1647                                    </button>
1648                                </template>
1649                                
1650                                <template v-else-if="selectedProduct.price &amp;&amp; selectedProduct.free">
1651                                    <button type="submit" id="trail-button" class="btn btn-success btn-rounded d-flex justify-content-center" value="trail">
1652                                        Prova nu
1653                                    </button>
1654                                </template>
1655                                
1656                                <template v-else-if="selectedProduct.price &amp;&amp; !selectedProduct.free">
1657                                    <div class="row justify-content-center">
1658                                        <div id="invoiceButton" class="form-group clearfix" style="margin-top: 10px; width: 280px">
1659                                            <div class="d-sm-flex justify-content-center">
1660                                                <div class="d-flex flex-column justify-content-center mx-sm-1">
1661                                                    <button type="submit" id="invoice-contact-button" class="btn btn-success btn-rounded d-flex justify-content-center" value="invoice">
1662                                                        Faktura
1663                                                    </button>
1664                                                </div>
1665                                            </div>
1666                                        </div>
1667                                        <div v-if="onlinePaymentModule &amp;&amp; bordasModule" id="cardButton" class="form-group clearfix" style="margin-top: 10px; width: 280px">
1668                                            <div class="d-sm-flex justify-content-center">
1669                                                <div class="d-flex flex-column justify-content-center mx-sm-1">
1670                                                        <button type="submit" id="card-button" class="btn btn-success btn-rounded d-flex justify-content-center" value="card">
1671                                                            GÃ¥ till kortbetalning
1672                                                        </button>
1673                                                </div>
1674                                            </div>
1675                                        </div>
1676                                    </div>
1677                                </template>
1678                            </div>
1679                        </form>
1680                    </div>
1681                    <div class="col-12 col-md-4 order-1 order-md-2">
1682                        <div class="d-flex flex-column subscription-product-list">
1683
1684                            <div class="subscription-product">
1685                                <div>
1686                                    <div class="product-name-price-combined">
1687                                        <div class="product-choice-text">
1688                                            Du har valt:
1689                                        </div>
1690
1691                                        <div class="product-name">
1692                                            {{ formattedProductName(selectedProduct.name) }}
1693                                        </div>
1694
1695                                        <div v-if="selectedProduct.price" class="product-price-text d-flex justify-content-center" v-html="formattedPrice(selectedProduct.price)">
1696                                        </div>
1697
1698                                        <div v-if="selectedProduct.subtitle" class="form-price-subtitle d-flex justify-content-center">
1699                                            {{ selectedProduct.subtitle }}
1700                                        </div>
1701                                    </div>
1702
1703                                    <div v-if="selectedProduct.price" class="total-price">
1704                                        <span>Till betalning nu:</span>
1705                                        <span class="price-now"> {{ selectedProduct.simplePrice }} </span>
1706                                    </div>
1707                                    <div v-if="selectedProduct.priceDetail" class="form-price-detail d-flex justify-content-center">
1708                                            {{ selectedProduct.priceDetail }}
1709                                    </div>
1710
1711                                    <ul class="product-features d-none d-md-block">
1712                                        <li v-for="(feature, index) in computedFeatures(selectedProduct.id)" v-if="selectedProduct.showFeatures">
1713                                            <span v-bind:id="'feature-name-' + index" v-bind:class="'subscription-feature-name'" v-html="formatFeatureTitle(feature.title)">
1714                                            </span>
1715                                            <div v-if="containsDoubleBrackets(feature.title)" class="subscription-feature-hover">
1716                                                {{ feature.text }}
1717                                            </div>
1718                                        </li>
1719                                    </ul>
1720                                </div>
1721                                <div>
1722                                    <span class="change-package" v-on:click="deselectProduct(selectedProduct)">Byt paket</span>
1723                                </div>
1724                            </div>
1725                        </div>
1726                    </div>
1727                </div>
1728            </div>
1729            <div v-else-if="paymentPage" id="paymentPage">
1730                <div id="checkout-container-div">
1731                    
1732                </div>
1733            </div>
1734            <div v-else-if="receiptPage" id="receiptPage" class="d-flex flex-column justify-content-center">
1735                <div class="row">
1736                    <div class="col-12 receipt">
1737                        <div v-if="selectedProduct != null &amp;&amp; !selectedProduct.price">
1738                            <div class="header">
1739                                <b>Tack för din information</b>
1740                            </div>
1741                            <div class="subtext mt-5 mt-md-4 mb-5">
1742                                <div class="subtext subheader">
1743                                    Vi kommer snart att kontakta dig med mer information om våra produkter.
1744                                </div>
1745                                <div class="subtext disclaimer">
1746                                    Vi ser fram emot att diskutera hur vi bäst kan möta dina behov.
1747                                </div>
1748                            </div>
1749                        </div>
1750                        <div v-else-if="hideProducts === true">
1751                            <div class="header">
1752                                <b>Tack för din information</b>
1753                            </div>
1754                            <div class="subtext mt-5 mt-md-4 mb-5">
1755                                <div class="subtext subheader">
1756                                    Din prenumeration har uppdaterats med den nya betalningsinformationen.
1757                                </div>
1758                            </div>
1759                        </div>
1760                        <div v-else="">
1761                            <div class="header">
1762                                <b>Tack för registreringen</b>
1763                            </div>
1764                            <div class="subtext mt-5 mt-md-4 mb-5">
1765                                <div class="subtext subheader">
1766                                    Du har fått ett e-postmeddelande för att aktivera din prenumeration.
1767                                </div>
1768                                <div class="subtext disclaimer">
1769                                    Kan du inte hitta aktiveringsmailet? Kolla din skräppost.
1770                                </div>
1771                            </div>
1772                        </div>
1773
1774                        <a id="frontpage" class="btn btn-primary btn-rounded" href="/">
1775                            <div>
1776                                GÃ¥ till startsidan
1777                            </div>
1778                        </a>
1779                    </div>
1780                </div>
1781            </div>
1782
1783            <global-errors v-bind:value="globalErrors"></global-errors>
1784        </div>
1785
1786        <div v-if="!loading &amp;&amp; !selectedProduct &amp;&amp; hideProducts === false" class="subscription-bottom-text">
1787            För alla prenumerationer tilldelas en personlig inloggning över flera enheter
1788        </div>
1789    </div>
1790
1791    
1791<script type="text/javascript">
1792        var vm;
1793        //<![CDATA[
1794        (function () {
1795            vm = new Vue({
1796                el: '#supscriptions-app',
1797                data: {
1798                    productGroups: null,
1799                    loading: false,
1800                    selectedProduct: null,
1801                    hideProducts: false,
1802                    productPage: false,
1803                    deeplinkProduct: null,
1804                    paymentPage: false,
1805                    receiptPage: false,
1806                    renewCard: false,
1807                    pendingOrder: {
1808                        company: true,
1809                        firstName: '',
1810                        lastName: '',
1811                        email: '',
1812                        companyName: '',
1813                        cvr: '',
1814                        address: '',
1815                        country: '2',
1816                        phoneNumber: '',
1817                        callingCode: '',
1818                        streetName: '',
1819                        streetNumber: '',
1820                        floor: '',
1821                        door: '',
1822                        addressFull: '',
1823                        postalCode: '',
1824                        addressCity: '',
1825                        remarks: '',
1826                        product: '',
1827                        campaignCode: 'paywall',
1828                        marketing: false,
1829                        submitType: ''
1830                    },
1831                    showDetailedAddress: false,
1832                    termsAccepted: false,
1833                    formErrors: {},
1834                    globalErrors: [],
1835                    countryOptions: [],
1836                    bordasModule: true,
1837            bordas: false,
1838                productType: 'SUBSCRIPTION',
1839                campaignProductId: '',
1840                products: [],
1841                productClasses: [],
1842                bundle: {
1843                id_10626: ''
1844            },
1845            paymentId: null,
1846                checkoutLanguage: null,
1847                subscriptionId: null,
1848                checkoutKeyValue: null,
1849                subscriptionSet: false,
1850                companyDisabled: false,
1851                onlinePaymentModule: false,
1852            productCols: 3,
1853                productIndex: 0,
1854                slideDirection: '',
1855                touchQueue: [],
1856                touchStartX: 0,
1857                touchEndX: 0,
1858                minSwipeDistance: 50,
1859                isSmallScreen: false,
1860                mediaQuery: null
1861        },
1862            created: function () {
1863                Vue.$bundle("portal", this.bundle, (bundle) => {
1864                    this.bundle = bundle;
1865                });
1866
1867                this.mediaQuery = window.matchMedia('(min-width: 768px)');
1868                this.updateScreenSize(this.mediaQuery);
1869                this.mediaQuery.addEventListener('change', this.updateScreenSize);
1870
1871                this.loading = true;
1872                const promises = [];
1873
1874                promises.push(this.getProductGroups(this.productType, this.campaignProductId).then((data) => {
1875                    this.productGroups = data;
1876
1877                    for (var i = 0; i < this.productGroups.length; i++) {
1878                        this.products = this.products.concat(this.productGroups[i].products ? this.productGroups[i].products : []);
1879                    }
1880
1881                    window.addEventListener('resize', this.handleResize);
1882                    this.handleResize();
1883
1884                    if (this.window.width < 768) {
1885                        for (var i = 0; i < this.productGroups.length; i++) {
1886                            if (this.productGroups[i].products) {
1887                                for (var j = 0; j < this.productGroups[i].products.length; j++) {
1888                                    this.productGroups[i].products[j].showFeatures = false;
1889                                }
1890                            }
1891                        }
1892                    }
1893
1894                    // Navigate to the product from the link if a product is specified in it.
1895                    if (this.deeplinkProduct !== null) {
1896                        this.navigateToProductInLink();
1897                    }
1898
1899                    if (this.subscriptionId !== null) {
1900                        this.navigateToPaymentToRenew();
1901                    }
1902                }));
1903
1904                promises.push(this.fetchCountries().then((data) => {
1905                    this.countryOptions = data;
1906                    let foundCountry = this.countryOptions.find(country => {
1907                        return parseInt(country.id) == this.pendingOrder.country;
1908                    });
1909                    this.pendingOrder.callingCode = foundCountry.callingCode;
1910                }));
1911
1912                promises.push(this.getcheckoutLang().then((data) => {
1913                    this.checkoutLanguage = data;
1914                }));
1915
1916                Promise.all(promises).finally(() => {
1917                    this.loading = false;
1918                });
1919
1920                // Check if it is a "deeplink". (A '' in the link.)
1921                // Save it to be used for navigating the product.
1922
1923                const queryString = window.location.search;
1924                const urlParams = new URLSearchParams(queryString);
1925                const deeplinkProduct = urlParams.get('product')
1926                if (deeplinkProduct) {
1927                    this.deeplinkProduct = deeplinkProduct;
1928                }
1929                const paymentId = urlParams.get('paymentid');
1930                if (paymentId) {
1931                    this.paymentId = paymentId;
1932                }
1933                const subscriptionId = urlParams.get('subscriptionid');
1934                if (subscriptionId) {
1935                    this.subscriptionId = subscriptionId;
1936                }
1937            },
1938            beforeDestroy: function () {
1939                this.mediaQuery.removeEventListener('change', this.updateScreenSize);
1940            },
1941            destroyed: function () {
1942                window.removeEventListener('resize', this.handleResize);
1943            },
1944            computed: {
1945                visibleProducts: function () {
1946                    if (this.isSmallScreen) {
1947                        return this.products;
1948                    }
1949                    return this.products.slice(this.productIndex, this.productIndex + this.productCols);
1950                }
1951            },
1952            watch: {
1953                "pendingOrder.country": function (newId) {
1954                    let foundCountry = this.countryOptions.find(country => parseInt(country.id) == this.pendingOrder.country);
1955                    this.pendingOrder.callingCode = foundCountry.callingCode;
1956
1957                    const country = this.countryOptions.find(country => parseInt(country.id) == newId);
1958                    this.callingCode = country ? country.callingCode : "";
1959                }
1960            },
1961            methods: {
1962                updateScreenSize: function (e) {
1963                    // If the media query matches, we're on 768+ pixels screens
1964                    this.isSmallScreen = !e.matches;
1965                },
1966                handleResize: function () {
1967                    var widthBefore = this.window.width;
1968
1969
1970                    this.window.width = window.innerWidth;
1971                    this.window.height = window.innerHeight;
1972
1973                    if (this.window.width < 768 && widthBefore > 767.9999) {
1974                        for (var i = 0; i < this.productGroups.length; i++) {
1975                            if (this.productGroups[i].products) {
1976                                for (var j = 0; j < this.productGroups[i].products.length; j++) {
1977                                    this.productGroups[i].products[j].showFeatures = false;
1978                                }
1979                            }
1980                        }
1981                    }
1982                    if (this.window.width >= 767.9999) {
1983                        for (var i = 0; i < this.productGroups.length; i++) {
1984                            if (this.productGroups[i].products) {
1985                                for (var j = 0; j < this.productGroups[i].products.length; j++) {
1986                                    this.productGroups[i].products[j].showFeatures = true;
1987                                }
1988                            }
1989                        }
1990                    }
1991                },
1992                scrollToTop: function () {
1993                    this.$nextTick(() => {
1994                        window.scrollTo(0, 0);
1995                    });
1996                },
1997                computedFeatures: function (id) {
1998                    var features = [];
1999                    for (var i = 0; i < this.products.length; i++) {
2000                        if (this.products[i].id === id) {
2001                            features = this.products[i].features;
2002                            break;
2003                        }
2004                    }
2005                    return features;
2006                },
2007                selectProduct: function (product) {
2008                    this.selectedProduct = product;
2009                    this.productPage = true;
2010                    this.pendingOrder.product = product;
2011                    if (!this.selectedProduct.price) {
2012                        this.termsAccepted = true;
2013                    }
2014                    // Log selected product in the link
2015                    // for it to be used for deeplinks for social medias and other places.
2016
2017                    // Get the current URL
2018                    let url = new URL(window.location);
2019                    // Add or update the query parameter
2020                    url.searchParams.set('product', product.id);
2021                    // Update the URL without reloading the page
2022                    history.pushState({}, '', url);
2023
2024
2025                    // window.location = window.location + '?product=' + product.id;
2026                    if (this.bordasModule) {
2027                        this.fetchBordas().then((data) => {
2028                            if (data === true) {
2029                                this.bordas = true;
2030                            }
2031                        });
2032                    }
2033
2034                    this.getCheckoutKey().then((data) => {
2035                        if (data) {
2036                            this.checkoutKeyValue = data;
2037                        }
2038                    });
2039
2040                    openOrder(this.pendingOrder.product.id, this.pendingOrder.product.name, this.productGroups);
2041
2042                    if (!this.selectedProduct.price) {
2043                        // this.pendingOrder.company = true;
2044                        this.companyDisabled = true;
2045                    } else {
2046                        // this.pendingOrder.company = false;
2047                        this.companyDisabled = false;
2048                    }
2049
2050                    this.scrollToTop();
2051                },
2052                deselectProduct: function (product) {
2053
2054                    let url = new URL(window.location);
2055                    // Add or update the query parameter
2056                    url.searchParams.delete('product', product.id);
2057                    // Update the URL without reloading the page
2058                    history.pushState({}, '', url);
2059
2060                    this.selectedProduct = null;
2061                    this.productPage = false;
2062                    this.pendingOrder.product = null;
2063                    this.bordas = false;
2064                    this.termsAccepted = false;
2065                    this.pendingOrder.companyName = '';
2066                    this.pendingOrder.cvr = '';
2067                    this.pendingOrder.company = true;
2068                    var length = this.products.length;
2069
2070                    this.scrollToTop();
2071                },
2072                navigateToProductInLink: function () {
2073                    for (var i = 0; i < this.productGroups.length; i++) {
2074                        for (var j = 0; j < this.productGroups[i].products.length; j++) {
2075                            // Found product group
2076                            if (this.deeplinkProduct == this.productGroups[i].products[j].id) {
2077                                for (var q = 0; q < this.products.length; q++) {
2078                                    // Found product
2079                                    if (this.deeplinkProduct == this.products[q].id) {
2080                                        var product = this.products[q];
2081
2082                                        // Get the current URL
2083                                        let url = new URL(window.location);
2084                                        // Add or update the query parameter
2085                                        url.searchParams.set('product', product.id);
2086                                        this.selectedProduct = product;
2087                                        this.pendingOrder.product = product;
2088                                        this.fetchBordas().then((data) => {
2089                                            if (data === true) {
2090                                                this.bordas = true;
2091                                            }
2092                                        });
2093
2094                                        if (!this.selectedProduct.price) {
2095                                            // this.pendingOrder.company = true;
2096                                            this.companyDisabled = true;
2097                                        } else {
2098                                            // this.pendingOrder.company = false;
2099                                            this.companyDisabled = false;
2100                                        }
2101
2102                                        if (this.paymentId) {
2103                                            url.searchParams.set('paymentid', this.paymentId);
2104                                            // Update the URL without reloading the page
2105                                            history.pushState({}, '', url);
2106                                            this.paymentPage = true;
2107                                            this.productPage = false;
2108
2109                                            this.getCheckoutKey().then((data) => {
2110                                                if (data) {
2111                                                    this.checkoutKeyValue = data;
2112                                                    this.$nextTick(() => {
2113                                                        $('#progress-bar li:not(.active):first').addClass('active');
2114                                                        $('#progress-bar li.active:first').removeClass('active');
2115                                                        vm.setupCheckout();
2116                                                    });
2117                                                }
2118                                            });
2119                                        } else {
2120                                            this.productPage = true;
2121                                            // Update the URL without reloading the page
2122                                            history.pushState({}, '', url);
2123                                        }
2124                                    }
2125                                }
2126                            }
2127                        }
2128                    }
2129                },
2130                navigateToPaymentToRenew: function () {
2131                    let url = new URL(window.location);
2132                    url.searchParams.set('subscriptionid', this.subscriptionId);
2133                    if (this.paymentId != null) {
2134                        url.searchParams.set('paymentid', this.paymentId);
2135                    }
2136
2137                    this.renewCard = true;
2138
2139                    // Update the URL without reloading the page
2140                    history.pushState({}, '', url);
2141                    this.paymentPage = true;
2142                    this.productPage = false;
2143                    this.hideProducts = true;
2144
2145                    this.$nextTick(() => {
2146                        //APPEND NEW PAYMENT ID TO URL THEN SETUP
2147                        vm.renewCardPayment(vm.subscriptionId, vm.paymentId);
2148                    });
2149
2150                },
2151                showFeatures: function (product, showFeatures) {
2152                    if (this.window.width < 768) {
2153                        product.showFeatures = showFeatures;
2154                    }
2155                },
2156                prevProduct: function () {
2157                    if (this.productIndex > 0) {
2158                        this.slideDirection = 'col-4-slide-right';
2159                        this.productIndex--;
2160                    }
2161                },
2162                nextProduct: function () {
2163                    if (this.productIndex + this.productCols < this.products.length) {
2164                        this.slideDirection = 'col-4-slide-left';
2165                        this.productIndex++;
2166                    }
2167                },
2168                onTouchStart: function (event) {
2169                    this.touchQueue.push(true);
2170                    this.$nextTick(() => {
2171                        this.touchStartX = event.changedTouches[0].screenX;
2172                        this.touchEndX = this.touchStartX;
2173                    });
2174                },
2175                onTouchMove: function (event) {
2176                    this.$nextTick(() => {
2177                        this.touchEndX = event.changedTouches[0].screenX;
2178                        const deltaX = this.touchEndX - this.touchStartX;
2179                        if (Math.abs(deltaX) > this.minSwipeDistance) {
2180                            if (deltaX > 0) {
2181                                this.prevProduct();
2182                            } else {
2183                                this.nextProduct();
2184                            }
2185                        }
2186                    });
2187                },
2188                onTouchEnd: function (event) {
2189                    this.onTouchMove(event);
2190                    this.$nextTick(() => {
2191                        setTimeout(() => {
2192                            this.touchQueue.splice(0, 1);
2193                        }, 500);
2194                    });
2195                },
2196                formattedProductName: function (productName) {
2197                    return productName.charAt(0).toUpperCase() + productName.slice(1).toLowerCase();
2198                },
2199                formattedPrice: function (price) {
2200                    if (price) {
2201                        var formattedPrice;
2202                        // return price.replace(/^(\d+)/, '<b style="margin-right: 1mm">$1</b> ');
2203                        formattedPrice = price.replace(/^(\d+)/, '[b]$1[/b]');
2204                        return Vue.$bbUtil.inline(formattedPrice);
2205                    }
2206                    return price;
2207                },
2208                handleSubmit: async function (event) {
2209                    const submitType = event.submitter?.value;
2210                    this.pendingOrder.submitType = submitType;
2211
2212                    this.$clearFormErrors(this.formErrors);
2213                    var errors = false;
2214                    var errorMessages = '{';
2215
2216                    if (!this.pendingOrder.postalCode) {
2217                        errors = true;
2218                        errorMessages = errorMessages + "\"postalCode\": [\"Obligatoriskt.\"], "
2219                    }
2220                    if (!this.pendingOrder.addressCity) {
2221                        errors = true;
2222                        errorMessages = errorMessages + "\"addressCity\": [\"Obligatoriskt.\"], "
2223                    }
2224                    if (this.bordas) {
2225                        if (!this.pendingOrder.streetName) {
2226                            errors = true;
2227                            errorMessages = errorMessages + "\"streetName\": [\"Obligatoriskt.\"], "
2228                        }
2229                        if (!this.pendingOrder.streetNumber) {
2230                            errors = true;
2231                            errorMessages = errorMessages + "\"streetNumber\": [\"Obligatoriskt.\"], "
2232                        }
2233                    } else {
2234                        if (!this.pendingOrder.addressFull) {
2235                            errors = true;
2236                            errorMessages = errorMessages + "\"addressFull\"
2236: [\"Obligatoriskt.\"], "
2237                        }
2238                    }
2239
2240                    if (errors) {
2241                        if (!this.showDetailedAddress) {
2242                            this.showDetailedAddress = true;
2243                        }
2244                        errorMessages = errorMessages.substring(0, errorMessages.length - 2);
2245                        errorMessages = errorMessages + "}"
2246                        const obj = JSON.parse(errorMessages);
2247                        this.$showFormErrors(this.formErrors, obj);
2248                        return;
2249                    }
2250
2251                    //Serverside validation
2252                    this.formErrors = {};
2253                    // Create order
2254                    this.submitOrderForm(this.pendingOrder).then((data) => {
2255                        if (!data) {
2256                            //Do nothing if validation failed
2257                        } else {
2258                            if (this.pendingOrder.submitType === "company") {
2259                                //Contact
2260                                $('#progress-bar li:not(.active):first').addClass('active');
2261                                $('#progress-bar li.active:first').removeClass('active');
2262
2263                                this.receiptPage = true;
2264                                this.productPage = false;
2265                                successGA(window.ga);
2266                            } else if (this.pendingOrder.submitType === "invoice") {
2267                                //If bordas invoice payment then skip nexi payment and remember salespanel
2268                                $('#progress-bar li:not(.active):first').addClass('active');
2269                                $('#progress-bar li:not(.active):first').addClass('active');
2270                                $('#progress-bar li.active:first').removeClass('active');
2271                                $('#progress-bar li.active:first').removeClass('active');
2272                                this.receiptPage = true;
2273                                this.productPage = false;
2274                                successGA(window.ga);
2275                                salespanel();
2276                            } else if (this.pendingOrder.submitType === "card") {
2277                                // Product that need payment
2278                                $('#progress-bar li:not(.active):first').addClass('active');
2279                                $('#progress-bar li.active:first').removeClass('active');
2280                                this.paymentPage = true;
2281                                this.productPage = false;
2282                                this.handlePaymentAndCreate()
2283                            } else if (this.pendingOrder.submitType === "trail") {
2284                                //Free trial
2285                                $('#progress-bar li:not(.active):first').addClass('active');
2286                                $('#progress-bar li:not(.active):first').addClass('active');
2287                                $('#progress-bar li.active:first').removeClass('active');
2288                                $('#progress-bar li.active:first').removeClass('active');
2289                                this.receiptPage = true;
2290                                this.productPage = false;
2291                                successGA(window.ga);
2292                                salespanel();
2293                            }
2294                        }
2295                    });
2296                },
2297                fetchCountries: async function () {
2298                    return this.$services.countryService.hostCountriesFirst();
2299                },
2300                getcheckoutLang: async function () {
2301                    return this.$services.paymentService.getCheckoutLanguage();
2302                },
2303                fetchBordas: function () {
2304                    if (this.selectedProduct) {
2305                        return this.$services.paymentService.supportBordas(this.selectedProduct.id);
2306                    } else {
2307                        return false;
2308                    }
2309                },
2310                getCheckoutKey: async function () {
2311                    return this.$services.paymentService.getCheckoutKey();
2312                },
2313                getProductGroups: async function (type, campaignId) {
2314                    if (campaignId) {
2315                        return this.$services.paymentService.getProductGroups(type, campaignId);
2316                    } else {
2317                        return this.$services.paymentService.getProductGroups(type);
2318                    }
2319                },
2320                submitOrderForm: async function (pendingOrder) {
2321                    this.formErrors = {};
2322                    this.globalErrors = {};
2323                    return this.validationService().submit(pendingOrder).then(() => {
2324                        return true;
2325                    }).catch((data) => {
2326                        this.$showFormErrors(this.formErrors, data.response.data.errors);
2327
2328                        if (data.response.data.errors.globalError) {
2329                            this.globalErrors = data.response.data.errors.globalError;
2330                        }
2331                        return false;
2332                    });
2333                },
2334                handlePaymentOrder: async function (pendingOrder) {
2335                    return this.validationService().payment(pendingOrder).then((data) => {
2336                        this.paymentId = data;
2337
2338                        let url = new URL(window.location);
2339                        url.searchParams.set('paymentid', this.paymentId);
2340                        // Update the URL without reloading the page
2341                        history.pushState({}, '', url);
2342                        this.getCheckoutKey().then((data) => {
2343                            if (data) {
2344                                this.checkoutKeyValue = data;
2345                                this.setupCheckout();
2346                            }
2347                        });
2348                        return true;
2349                    }).catch((data) => {
2350                        this.$showFormErrors(this.formErrors, data.response.data.errors);
2351
2352                        if (data.response.data.errors.globalError) {
2353                            this.globalErrors = data.response.data.errors.globalError;
2354                        }
2355                        return false;
2356                    });
2357                },
2358                updateSubscription: async function (paymentId) {
2359                    return this.validationService().subscription(paymentId).then(() => {
2360                        return true;
2361                    }).catch((data) => {
2362                        this.$showFormErrors(this.formErrors, data.response.data.errors);
2363
2364                        if (data.response.data.errors.globalError) {
2365                            this.globalErrors = data.response.data.errors.globalError;
2366                        }
2367                        return false;
2368                    });
2369                },
2370                renewCardPayment: async function (subscriptionId, paymentId) {
2371                    return this.validationService().renew(subscriptionId, paymentId).then((data) => {
2372                        this.paymentId = data;
2373
2374                        let url = new URL(window.location);
2375                        url.searchParams.set('paymentid', this.paymentId);
2376                        // Update the URL without reloading the page
2377                        history.pushState({}, '', url);
2378
2379                        this.getCheckoutKey().then((data) => {
2380                            if (data) {
2381                                this.checkoutKeyValue = data;
2382                                this.$nextTick(() => {
2383                                    $('#progress-bar li:not(.active):first').addClass('active');
2384                                    $('#progress-bar li.active:first').removeClass('active');
2385                                    vm.setupCheckout();
2386                                });
2387                            }
2388                        });
2389                        return true;
2390                    }).catch((data) => {
2391                        this.$showFormErrors(this.formErrors, data.response.data.errors);
2392
2393                            if (data.response.data.errors.globalError) {
2394                                this.globalErrors = data.response.data.errors.globalError;
2395                            }
2396                            return false;
2397                        });
2398                    },
2399                    validationService: function () {
2400                        return {
2401                            submit: async function (pendingOrder) {
2402                                return vm.$services.paymentService.validateOrder(pendingOrder);
2403                            },
2404                            payment: async function (pendingOrder) {
2405                                return vm.$services.paymentService.handlePayment(pendingOrder);
2406                            },
2407                            subscription: async function (paymentId) {
2408                                return vm.$services.paymentService.setSubscription(paymentId);
2409                            },
2410                            renew: async function (subscriptionId, paymentId) {
2411                                return vm.$services.paymentService.renewCard(subscriptionId, paymentId);
2412                            }
2413                        }
2414                    },
2415                    handlePaymentAndCreate: function () {
2416                        this.formErrors = {};
2417                        // Create order
2418                        this.handlePaymentOrder(this.pendingOrder).then((data) => {
2419                            if (!data) {
2420                                //Do nothing if validation failed
2421                            }
2422                        });
2423                    },
2424                    setupCheckout: function () {
2425                        const urlParams = new URLSearchParams(window.location.search);
2426                        const paymentId = urlParams.get('paymentid') ? urlParams.get('paymentid') : this.paymentId;
2427                        if (paymentId) {
2428                            const checkoutOptions = {
2429                                checkoutKey: vm.checkoutKeyValue,
2430                                paymentId: paymentId,
2431                                containerId: "checkout-container-div",
2432                                language: vm.checkoutLanguage
2433                            };
2434                            const checkout = new Dibs.Checkout(checkoutOptions);
2435                            checkout.on('payment-completed', function (response) {
2436                                vm.formErrors = {};
2437                                //Updated payment/subscription row in Database
2438                                if (!vm.subscriptionSet) {
2439                                    vm.subscriptionSet = true;
2440                                    vm.updateSubscription(vm.paymentId).then((data) => {
2441                                        if (!data) {
2442                                            //Do nothing if validation failed
2443                                        } else {
2444                                            $('#progress-bar li:not(.active):first').addClass('active');
2445                                            $('#progress-bar li:not(.active):first').addClass('active');
2446                                            $('#progress-bar li.active:first').removeClass('active');
2447                                            $('#progress-bar li.active:first').removeClass('active');
2448                                            vm.paymentPage = false;
2449                                            vm.receiptPage = true;
2450                                            var paymentFrame = document.getElementById("nets-checkout-iframe");
2451                                            paymentFrame.style.display = "none";
2452
2453                                            salespanel();
2454                                            successGA(window.ga);
2455                                        }
2456                                    });
2457
2458                            }
2459                        });
2460                    } else {
2461                        $('#progress-bar li.active:last').removeClass('active');
2462                        this.paymentPage = false;
2463                        this.productPage = true;
2464                    }
2465
2466                },
2467                formatFeatureTitle(title) {
2468                    return title.replace(/\[\[(.*?)\]\]/g, '<span style="text-decoration: underline;">$1</span>');
2469                },
2470                containsDoubleBrackets(title) {
2471                    return /\[\[.*?\]\]/.test(title);  // Checks if title contains [[...]]
2472                },
2473            }
2474        });
2475        })();
2476
2477        function openOrder(productId, productName, groups) {
2478            // Find related product group
2479            var productGroup = groups.find(group => {
2480                return group.products.find(groupProduct => {
2481                    return groupProduct.id == productId;
2482                })
2483            });
2484
2485            // Make product and group name and available for GTM
2486            window.dataLayer = window.dataLayer || [];
2487            window.dataLayer.push({"product-name": productName});
2488            window.dataLayer.push({"product-group": productGroup.name});
2489
2490        }
2491        //]]>
2492    </script>
2492
2493
2494    
2494<script>
2495
2496        //Hide the dropdown menus if the user clicks elsewhere
2497        $(document).on('click', function (e) {
2498            if ($(e.target).closest('#autocompleteDropdown').length == 0) {
2499                $("#autocompleteDropdown").hide();
2500            }
2501        });
2502
2503        var lastTime = 0;
2504
2505        //Construct call to autocomplete Api
2506        function makeAPICall() {
2507            var bordas = vm.$data.bordas;
2508            var now = new Date().getTime(); // Time in milliseconds
2509            if (now - lastTime < 500) {
2510                return;
2511            } else {
2512                lastTime = now;
2513            }
2514
2515            var inputValue;
2516            var country;
2517
2518            // Get value from the input box
2519            inputValue = document.getElementById('addressInput').value;
2520            country = vm.$data.pendingOrder.country;
2521
2522            if (inputValue && inputValue.length > 2 && country) {
2523                // Construct the API URL with input value
2524                var apiUrl;
2525                apiUrl = "/rest/autocompleteapi/gep-autocomplete?country=" + country + "&address=" + inputValue;
2526
2527                // Make the API call using fetch
2528                fetch(apiUrl)
2529                    .then(response => response.json())
2530                    .then(data => {
2531                        // Update the dropdown with names from the API response
2532                        updateAutocompleteDropdown(data, bordas, country);
2533                    })
2534                    .catch(error => {
2535                        console.error('Error:', error);
2536                    });
2537            }
2538        }
2539
2540        //Display the result from autocomplete Api
2541        function updateAutocompleteDropdown(addresses, bordas, country) {
2542            var dropdown;
2543
2544            dropdown = document.getElementById('autocompleteDropdown');
2545
2546            dropdown.innerHTML = ''; // Clear existing options
2547
2548            // Add new options based on the API response
2549            addresses.forEach(address => {
2550                var streetName = address.streetName;
2551                var houseNumber = address.houseNumber;
2552                var zipcode = address.zipcode;
2553                var city = address.city;
2554                var floor = address.floor != null ? address.floor : null;
2555                var door = address.door != null ? address.door : null;
2556                var letter = address.letter != null ? address.letter : null;
2557
2558                var textBordas = streetName + " " + houseNumber + (letter ? letter : "") + (floor ? " " + floor : "") + (door ? " " + door : "") + " " + zipcode + " " + city;
2559                var text = streetName + " " + houseNumber + (letter ? letter : "") + (floor ? " " + floor : "") + (door ? " " + door : "");
2560
2561                var item = document.createElement('div');
2562                item.className = 'autocomplete-suggestion';
2563                item.textContent = textBordas;
2564                item.onclick = function () {
2565                    // Set the selected value to the detailed input fields
2566                    vm.$data.pendingOrder.streetName = streetName;
2567                    vm.$data.pendingOrder.streetNumber = houseNumber + (letter ? letter : "");
2568                    vm.$data.pendingOrder.floor = floor;
2569                    vm.$data.pendingOrder.door = door;
2570                    vm.$data.pendingOrder.postalCode = zipcode;
2571                    vm.$data.pendingOrder.addressCity = city;
2572                    vm.$data.pendingOrder.addressFull = text;
2573
2574                    //Set input of main field
2575                    document.getElementById('addressInput').value = textBordas;
2576
2577                    // Hide the dropdown
2578                    dropdown.style.display = 'none';
2579                };
2580                dropdown.appendChild(item);
2581            });
2582
2583            var item = document.createElement('div');
2584            var reference = document.createElement('a');
2585            reference.href = "https://geposit.se/";
2586            reference.innerHTML = 'Adressuppgifter hämtade från Geposit';
2587            reference.rel = "nofollow";
2588            reference.target = "_blank";
2589            item.appendChild(reference);
2590
2591            item.className = 'autocomplete-credit';
2592            dropdown.appendChild(item);
2593
2594            // Show the dropdown below the input field
2595            dropdown.style.display = addresses.length > 0 ? 'block' : 'none';
2596        }
2597    </script>
2597
2598    
2598<script>
2599        async function salespanel() {
2600            window.dataLayer = window.dataLayer || [];
2601            window.dataLayer.push({"event": "subscription_order"});
2602            window.$salespanel = window.$salespanel || [];
2603            window.$salespanel.push(["set", "activity:customActivity", "website", "Abonnement bestilling"]);
2604        }
2605    </script>
2605
2606    
2606<script>
2607        function successGA(ga) {
2608            if (typeof ga !== 'undefined' && ga) {
2609                ga('send', 'event', 'Subscriber', 'join');
2610            } else if (typeof _gaq !== 'undefined' && _gaq) {
2611                _gaq.push(['_trackEvent', 'Subscriber', 'join', 'Metal Supply']);
2612            }
2613        }
2614    </script>
2614
2615    
2615<script>
2616        function formatText(inputText, targetElement) {
2617            targetElement.textContent = ""; // Clear previous content
2618
2619            let parts = inputText.split(/(\[\[.*?\]\])/g); // Split by [[ ]]
2620
2621            parts.forEach(part => {
2622                if (part.match(/\[\[(.*?)\]\]/)) {
2623                    let underlinedText = document.createElement("u");
2624                    underlinedText.textContent = part.replace(/\[\[|\]\]/g, ""); // Remove [[ ]]
2625                    targetElement.appendChild(underlinedText);
2626                } else {
2627                    let normalText = document.createTextNode(part);
2628                    targetElement.appendChild(normalText);
2629                }
2630            });
2631        }
2632    </script>
2632
2633                    </main>
2634
2635                </div>
2636            </div>
2637        <footer id="main-footer" v-cloak="" class="unprintable">
2638            <nav>
2639                <div class="row text-center text-md-start">
2640                    <div class="col-12 col-md-3 mb-5 mb-md-0">
2641                        <a href="/">
2642                            <img src="https://f.nordiskemedier.dk/logo/inverted/10.png" alt="Metal Supply" loading="lazy" class="logo" />
2643                        </a>
2644                    </div>
2645                    <div class="col-12 col-md-6">
2646                        <div class="row">
2647                            <div v-for="(option, i) in footerOptions" v-bind:key="i" class="col-12 mb-4" v-bind:class="footerOptionClass">
2648                                <h6>{{ option.name }}</h6>
2649                                <ul>
2650                                    <li v-for="(child, j) in option.children" v-bind:key="j">
2651                                        <a v-bind:href="child.target" v-bind:target="child.external ? '_blank' : ''">{{ child.name }}</a>
2652                                    </li>
2653                                </ul>
2654                            </div>
2655                        </div>
2656                    </div>
2657                </div>
2658            </nav>
2659            <nav>
2660                <div>
2661                    <div>
2662                        <div class="row">
2663                            <div class="col-12 col-md-8 order-1 order-md-2 mb-4 text-center address"><div>Metal Supply - metall- och verkstadsindustrins knutpunkt</div>
2664                            </div>
2665                            <div class="col-6 col-md-2 order-2 order-md-1 mb-4">
2666                            </div>
2667                            <div class="col-6 col-md-2 order-3 mb-4 text-end">
2668                                <ip-access-toggle></ip-access-toggle>
2669                            </div>
2670                        </div>
2671                    </div>
2672                </div>
2673            </nav>
2674        </footer>
2675        
2675<script type="application/javascript">
2676            //<![CDATA[
2677            new Vue({
2678                el: "#main-footer",
2679                data: {
2680                    footerOptions: [{"children":[{"external":false,"name":"Bli prenumerant","target":"/products/subscription.html"},{"external":true,"name":"Bli medlem","target":"https://nordiskemediehus.dk/se/produkt/medlemskab/"},{"external":true,"name":"Annonsera","target":"https://nordiskemediehus.dk/se/se-metal-supply/"},{"external":true,"name":"Se alla produkter","target":"https://nordiskemediehus.dk/se/produkter/"}],"name":"Produkter"},{"children":[{"external":false,"name":"Cookies och personuppgiftspolicy","target":"/privacy"},{"external":false,"name":"Juridik och upphovsrätt","target":"/page/view.html?id=17921"},{"external":false,"name":"KlagomÃ¥l","target":"/page/view.html?id=17919"},{"external":false,"name":"Sponsrat innehÃ¥ll","target":"/lb-article"}],"name":"Övrigt"},{"children":[{"external":false,"name":"Kontakta redaktionen","target":"mailto:[email protected]"},{"external":false,"name":"Kontakta oss","target":"/page/view.html?id=18313"},{"external":true,"name":"Jobba hos oss","target":"https://nordiskemediehus.dk/se/om-os/karriere/"},{"external":true,"name":"Om Metal Supply","target":"https://nordiskemediehus.dk/se/se-metal-supply/"}],"name":"Kontakt"}]
2681                },
2682                computed: {
2683                    footerOptionClass: function () {
2684                        const len = this.footerOptions.length;
2685                        if (len <= 1) {
2686                            return "col-sm-12";
2687                        } else if (len == 2) {
2688                            return "col-sm-6";
2689                        } else if (len == 3) {
2690                            return "col-sm-4";
2691                        } else if (len == 4) {
2692                            return "col-sm-3";
2693                        } else if (len >= 5 && len <= 6) {
2694                            return "col-sm-4";
2695                        } else if (len >= 7 && len <= 8) {
2696                            return "col-sm-3";
2697                        } else if (len == 9) {
2698                            return "col-sm-4";
2699                        } else {
2700                            return "col-sm-3";
2701                        }
2702                    }
2703                }
2704            });
2705            //]]>
2706        </script>
2706
2707        </div></body>
2708
2709</html>

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.