Why did targets.some not return true and prevent repeat of coordinates generated?

Console output was as follows:

Targetting Pattern:  Random About Target
Grid Coordinates:  [ 20 , 10 ]
Salvo Coordinates:
21,12,
21,11,
17,8,
19,7,
21,12,  <<== duplicate
20,12,
20,7,
18,12,
21,8,
22,11   <<== duplicate

Code Extract (1st approach):
(using ‘some’ method)

function firePattern_onTargRand( col, row ){
    var firePattern = 'Random About Target' ;
    var target = [] ;
    var targets = [] ;
    var munitionsCost = 10 ;
    var alreadyTargetted = false ;

    for( i=1 ; i <= munitionsCost ; i++ ){
        do {
            target = [ 
                col + getRandomInteger( 0, 6 ) -3 ,
                row + getRandomInteger( 0, 6 ) -3
            ] ;
        } while( targets.some(element => element === target ) ) ;

        targets.push( target ) ;
    } ;

    console.log( "Targetting Pattern:  " + `${firePattern}` + "nGrid Coordinates:  [" + ` ${col} , ${row} ` + "]nSalvo Coordinates:n" + targets ) ;
    return targets ;
} ;

Code Extract (2nd approach):
(direct comparison of array elements in loop)

function firePattern_onTargRand( col, row ){
    var firePattern = 'Random About Target' ;
    var target = [] ;
    var targets = [] ;
    var munitionsCost = 10 ;
    var alreadyTargetted = false ;

    for( i=1 ; i <= munitionsCost ; i++ ){
        do {
            target = [ 
                col + getRandomInteger( 0, 6 ) -3 ,
                row + getRandomInteger( 0, 6 ) -3
            ] ;
            isDuplicate = false ;
            for( let i = 0 ; i < targets.length ; i++ ){
                    if( targets[i] == target ) {
                    isDuplicate = true ;
                } ;
            } ; 
        } while( isDuplicate === true ) ;

        targets.push( target ) ;
        } ;

    console.log( "Targetting Pattern:  " + `${firePattern}` + "nGrid Coordinates:  [" + ` ${col} , ${row} ` + "]nSalvo Coordinates:n" + targets ) ;
    return targets ;
} ;

Anyone know why I keep getting duplicates, when every pair of coordinates should be unique?

PS – I am very much a JavaScript novice.

Why is the error thrown with setTimeout not passed up to the parent try/catch block?

const fn2 = async (delay) => {
    return new Promise(resolve => setTimeout(() => { throw new Error("error") }, delay));
}

try {
  await fn2(1000);
} catch (err) {
  console.log("Rejected", err);
}
console.log("Finished.");

Please note, I am running this as a module (.mjs).

The only output I get (after 1000ms) is an error:

Error: error
at Timeout._onTimeout (file:///HelloWorld.mjs:2:60)
at listOnTimeout (node:internal/timers:581:17)
at process.processTimers (node:internal/timers:519:7)

If I am awaiting the promise, how come the try/catch block still isn’t catching the error?

It even seems to fail if I use .then .catch chaining:

fn2(1000).then(result => {
  console.log("Success", result);
})
.catch(error => {
  console.log("Rejected", error);
})

Error: error
at Timeout._onTimeout (file:///HelloWorld.mjs:2:60)
at listOnTimeout (node:internal/timers:581:17)
at process.processTimers (node:internal/timers:519:7)

This seems to be a nuance of setTimeout because if I change the code, the error is properly handled.

const fn2 = async (delay) => {
  // return new Promise(resolve => setTimeout(() => { throw new Error("error") }, delay));
  return new Promise(resolve => { throw new Error("error") });
}

Output:

Rejected Error: error
at file:///HelloWorld.mjs:3:41
at new Promise ()
at fn2 (file:///HelloWorld.mjs:3:10)
at file:///HelloWorld.mjs:7:9
at ModuleJob.run (node:internal/modules/esm/module_job:234:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:473:24)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:123:5) Finished.

Why doesn’t the try/catch block catch the rejected promise even when using await?

Ok, there’s a lot of questions and answers on this, but they don’t seem to jive with the following code:

const fn2 = async (delay) => {
    return new Promise(resolve => setTimeout(() => { throw new Error("error") }, delay));
}

try {
  await fn2(1000);
} catch (err) {
  console.log("Rejected", err);
}
console.log("Finished.");

Please note, I am running this as a module (.mjs).

The only output I get (after 1000ms) is an error:

Error: error
at Timeout._onTimeout (file:///HelloWorld.mjs:2:60)
at listOnTimeout (node:internal/timers:581:17)
at process.processTimers (node:internal/timers:519:7)

If I am awaiting the promise, how come the try/catch block still isn’t catching the error? And how is it that the program can be terminated at that point and never reach console.log("Finished.");?

I’m trying really hard to understand the behavior of unhandled exceptions within an asynchronous function and am expecting the top level try/catch to save me.

It even seems to fail if I use .then .catch chaining:

fn2(1000).then(result => {
  console.log("Success", result);
})
.catch(error => {
  console.log("Rejected", error);
})

Error: error
at Timeout._onTimeout (file:///HelloWorld.mjs:2:60)
at listOnTimeout (node:internal/timers:581:17)
at process.processTimers (node:internal/timers:519:7)

Why do I keep getting errors when attempting to get current position in JavaScript?

I have an html, css, js project with a map using leaflet. Sometimes location works but most of the time I get errors. Here is my JS code:

onst map = L.map('map').setView([30, 0], 3);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'}).addTo(map);
const err = document.querySelector("#error");
const moodIcons = document.querySelectorAll(".mood-icon");
let currentLocation = null;

function getLocation() {
  
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(success, error, { maximumAge: 5000, timeout: 10000, enableHighAccuracy: true });
  }
  else {
    err.innerHTML = "Geolocation is not supported by this browser.";
  }

  return location;
}

function success(position) {
  
  currentLocation = [position.coords.latitude, position.coords.longitude]
  map.setView(currentLocation, 17);
}
  
function error(error) {
  console.log(error)
  err.innerHTML = "Please allow location permission to add a marker to the mood map";
}

// ---------------------------------------------------------------------------------------------

getLocation();

On Firefox I get this error:

Firefox error

On Chrome I get this error:

Chrome error example

When I open my html page in the browser I get prompted to allow location. When I click on allow Iocation permission the console immediately shows the error. have tried setting options for the getCurrentPosition method like a timeout but issue persists. The weird thing is that sometimes it will work. Without me even changing the code. Additionally, I get this error on Chrome only 127.0.0.1/:1 Network location provider at 'https://www.googleapis.com/' : Returned error code 429.

Why can I access objects that weren’t declared in the file? Only the classes were exported

So, I’m currently learning ESM and I was doing some practicing by exporting and importing two classes. In the file where I created the classes I also created two objects that are instances of those classes. In a second file, I imported both classes but NOT the instances,I then copied and pasted code from the first file into the second to test if the classes had imported and I forgot that I hadn’t exported the instances, but it still worked. Here is the first file.

//tests.js (file one)


export class Person{
    #age;
    constructor(name, age){
        this._name = name;
        this.#age = age;
    }
    

    get name(){
        return this._name;
    }

    intro(){
        console.log(`My name is ${this._name} and I am ${this.#age} years old`);
    }

    set changeName(newName){
        if(newName.length < 3 && typeof newName === 'string'){
            console.log('ERROR: Name cannot be less than 3 characters (Name remains unchanged)');
            return;
        }
        this._name = newName;
    }

    get age(){
        return this.#age;
    }

    birthday(){
        this.#age++;
    }
    

};

export default class Safe{
    #owner;
    #secret;
    #code;
    constructor(secret, code, owner){
        this.#secret = secret;
        this.#code = code;
        this.#owner = owner;
    }

    getSecret(code){
        if(code !== this.#code){
            console.log('!INCORRECT CODE!');
            return;
        }

        console.log(this.#secret);
    }

    get ownerHint(){
        return `Owner first two letters -> ${this.#owner[0]}${this.#owner[1]}`
    }

    changeCode(newCode, owner){
        if(owner[0] !== this.#owner[0]){
            console.log(`ERROR: OWNER VERIFICATION FAILED`);
            return;
        } 

        this.#code = newCode;


    }

}

const secret = new Safe('I have a cat!', 2818, 'Sam');

console.log(secret.ownerHint);
secret.getSecret(2818);
secret.changeCode(2817, 'Sam');
secret.getSecret(2817);


const sam = new Person('Sam', 21);
console.log(sam.age);
console.log(sam.name);
sam.intro();
sam.changeName= 'Sammy';
sam.birthday();
console.log(sam.age);
sam.intro();

Here is the second file (the file I imported both classes):

//test2.js

import Safe, { Person } from "./tests.js"

const newSafe = new Safe('I have a cat!', 2818, 'Sam');
const newPerson = new Person('Sam', 17);

//here is where the error is made, but for some reason IT WORKS? 
//the sam and secret instances are only declared in the tests.js file 

console.log(secret.ownerHint);
secret.getSecret(2818);
secret.changeCode(2817, 'Sam');
secret.getSecret(2817);



console.log(sam.age);
console.log(sam.name);
sam.intro();
sam.changeName = 'Sammy';
sam.birthday();
console.log(sam.age);
sam.intro();

How does the second file know of the existence of the “sam” and “secret” instance? Now, even more confusing than this, is that when I run the second file (node test2.js), the code runs fine until it reaches a point and then it just throws a reference error, “secret is not defined” here is the output

Owner first two letters -> Sa
I have a cat!
I have a cat!
21
Sam
My name is Sam and I am 21 years old
22
My name is Sammy and I am 22 years old
file:///home/javascript-projects/test2.js:8
console.log(secret.ownerHint);
            ^

ReferenceError: secret is not defined

How the hell does it go from outputting everything fine in both the “secret” and “sam” instances to then suddenly changing its mind and throwing an error. Why not just throw an error in the first place? Oh, and as I’m typing this I tried to test by removing all the code except for the import syntax, AND IT STILL WORKED except it didn’t throw a reference error.

How to set the field if changed in using TypeScript keyof?

I want to set the field if changed. I tried:

interface Foo {
  id: string;
  bar?: number
}
function setIfChanged(newProduct: Foo, existingProduct: Foo, key: keyof Foo): boolean {


  if (newProduct[key] !== existingProduct[key]) {
    existingProduct[key] = newProduct[key]; // error here
    console.log(`Product ${key} updated:`, newProduct);
    return true;
  }
  return false;
}
Type 'string | number | undefined' is not assignable to type 'never'. 
Type 'undefined' is not assignable to type 'never'

I don’t want to use // @ts-ignore or type assertion (as).

min-height behaviour in css [closed]

I don’t know what the problem of min-height is. I learned that it defines the minimum height of element but now it is behaving somehow. Until when I put it in a scrollable element that the scroll works as expected.

Is it a must I always set the min-height for a scrollable element before or for it to function well?

I was expecting the scrollable element not height beyond the viewport but it does not until I added min-height: 0; that it stops spanning beyond the viewport

Can I use quickbook API on node js client side application to access data?

I have created simple node js application using express for quick book authentication and get access token, Once I get access token I am try to get journalentry from my another client side node js application, when I write code to access journalentry it’s give me following error on console log

Access to fetch at
‘https://sandbox-quickbooks.api.intuit.com/v3/company/xxxx/query?minorversion=75&query=select%20*%20from%20journalentry%20startposition%201%20maxresults%20500’
from origin ‘https://localhost:3000’ has been blocked by CORS policy:
Response to preflight request doesn’t pass access control check: No
‘Access-Control-Allow-Origin’ header is present on the requested
resource.

When I put same code on node js express server, I am able access data.
So my conclusion is quickbook api doesn’t NOT support client-side API calls.

Am I right ? or is there any another way to achieve that?

Code sample for reference

const requestRootUrl = "https://sandbox-quickbooks.api.intuit.com";
const companyId = "xxxx";
  const selectQuery = "select * from journalentry startposition 1 maxresults 500";
  try {
    const response = await fetch(`${requestRootUrl}/v3/company/${companyId}/query?minorversion=75&query=${selectQuery}`, {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        Accept: 'application/json'
      }
    });
    const responseData = await response.json();
    if (responseData.error) {
      alert("response Data Error: " + responseData.error_description);
      return;
    }
    console.log("response Data, ", responseData)
  } catch (error) {
    console.log("Error details", error)
  }

How to Fetch Other Posts on Scroll Without AJAX and Jquery in WordPress?

I want to fetch other posts in WordPress. I can fetch next post on scroll. But when I go to latest post, it fetches nothing. When I go to the second latest post, on scroll it fetches only first post. When I go to the third latest post, it fetches only first and second latest posts. And so on. I want to fetch all posts on scroll, one by one.

<?php
$next_post = get_next_post();
  if ($next_post) :
    $next_post_url = get_permalink($next_post->ID);
?>
    <a id="next-post-link" href="<?php echo esc_url($next_post_url); ?>" 
       style="display: none;">
    </a>
<?php endif; ?>

JavaScript

document.addEventListener("DOMContentLoaded", function()
  {
  let loading = false;

  window.addEventListener("scroll", function()
    {
    let nextPostLink = document.getElementById("next-post-link");

    if (!nextPostLink || loading) return;

    let scrollPosition = window.innerHeight + window.scrollY;
    let documentHeight = document.documentElement.scrollHeight;

    if (scrollPosition >= documentHeight - 200) 
      {
      loading = true;
      let url = nextPostLink.href;

      fetch(url)
      .then(response => response.text())
      .then(data => 
        {
        let parser  = new DOMParser();
        let doc     = parser.parseFromString(data, "text/html");
        let newPost = doc.querySelector("#post-container .post");

        if (newPost) 
          {
          document.getElementById("post-container").appendChild(newPost);

          let newNextPostLink = doc.querySelector("#next-post-link");
          if (newNextPostLink) 
            {
            nextPostLink.href = newNextPostLink.href;
            } 
          else 
            {
            nextPostLink.remove(); // No more posts
            }

          // Update URL without reloading
          history.pushState(null, "", url);
          }

        loading = false;
        })
      .catch(error =>
        {
        console.error("Error fetching next post:", error);
        loading = false;
        });
      }
    });
  });

React native reanimated Build issues

I made an app using supabase client and react native using expo, It runs fine on dev move in Expo go app, Now I tried to build it and faced issues. Later It compiled but ever since each build has blank screen after after each build. I decided now to try simple View tag with text in app/_layout.tsx, now compiling gave a working app. Now i decided to use bgm for testing and the BGM plays when i open the app but nothing shows. I have tries almost everything nothing resolved it, I think its caused by react-native-reanimated library but i add its requirement of plugin in my babel. here is my app/_layout.tsx and index.tsx as far as i have understood the error index is either not loading or not animating at all.
i have verified almost everything. Its an urgent project of sorts, can anyone give me idea, what should i do. And I also have added gesture handler and safe area provider in main _layout.tsx

import { pvpGameRole, roomIdAtom, selectedBoardAtom } from '@/utils/atoms/store';
import { useButtonAudio } from '@/utils/AudioProvider';
import { useFocusEffect } from '@react-navigation/native';
import { LinearGradient } from 'expo-linear-gradient';
import { useRouter } from 'expo-router';
import { useSetAtom } from 'jotai';
import { ChevronRight, Settings } from 'lucide-react-native';
import { useCallback } from 'react';
import { Image, Pressable, Text, TouchableOpacity, View } from 'react-native';
import Animated, { FadeInUp } from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

export default function HomeScreen() {
  const router = useRouter();
  const insets = useSafeAreaInsets();
  const { playButtonSound } = useButtonAudio();
  const setSelectedBoard = useSetAtom(selectedBoardAtom);
  const setRoomId = useSetAtom(roomIdAtom);
  const setPvpGameRole = useSetAtom(pvpGameRole);

  useFocusEffect(
    useCallback(() => {
      setSelectedBoard(null);
      setRoomId(null);
      setPvpGameRole(null);
    }, [])
  );

  const handlePlayAIPress = () => {
    playButtonSound();
    router.replace({
      pathname: '/(tabs)/select',
      params: { from: 'AI' },
    });
  };

  const handlePlayPVPPress = () => {
    playButtonSound();
    router.replace({
      pathname: '/(tabs)/select',
      params: { from: 'PVP' },
    });
  };

  return (
    <View className="flex-1 bg-gray-50 p-5" style={{ paddingTop: insets.top }}>
      <Animated.View
        className="mt-4 rounded-2xl  overflow-hidden mb-8 relative"
        entering={FadeInUp.duration(1000).springify().delay(100)}
      >
        <View className="flex-row justify-between items-center px-4">
          <Text className="font-bold" style={{ fontSize: 32 }}>Bingo Blast</Text>
          <Pressable onPress={() => {
            playButtonSound();
            router.push("/settings");
          }}>
            <Settings size={28} color="#000" />
          </Pressable>
        </View>
      </Animated.View>
      <Animated.View
        className="mt-2 h-[200px] rounded-2xl overflow-hidden mb-8 relative"
        entering={FadeInUp.duration(1000).springify().delay(300)}
      >
        <Image source={icons.banner} className="w-full h-full" />
        <LinearGradient
          colors={['rgba(150, 120, 255, 0.3)', 'transparent']}
          className="absolute left-0 right-0 top-0 h-full"
        />
      </Animated.View>

      <View className="gap-y-4">
        <Animated.View entering={FadeInUp.duration(800).springify().delay(500)}>
          <TouchableOpacity
            className="rounded-xl overflow-hidden shadow-md"
            onPress={() => {
              playButtonSound();
              router.push('/(tabs)/boards');
            }}
          >
            <LinearGradient
              colors={['#4158D0', '#C850C0']}
              className="p-5 h-[110px]"
            >
              <Text className="font-poppins-bold text-xl text-white mb-2">Your Boards</Text>
              <Text className="font-poppins-regular text-sm text-white/90 w-4/5">
                Design & manage your own bingo boards
              </Text>
              <ChevronRight color="#fff" size={24} style={{ position: 'absolute', right: 20, bottom: 20 }} />
            </LinearGradient>
          </TouchableOpacity>
        </Animated.View>

        <Animated.View entering={FadeInUp.duration(800).springify().delay(700)}>
          <TouchableOpacity
            className="rounded-xl overflow-hidden shadow-md"
            onPress={handlePlayAIPress}
          >
            <LinearGradient
              colors={['#FF512F', '#F09819']}
              className="p-5 h-[110px]"
            >
              <Text className="font-poppins-bold text-xl text-white mb-2">Play Against AI (Beta)</Text>
              <Text className="font-poppins-regular text-sm text-white/90 w-4/5">
                Challenge our AI in an exciting game of bingo
              </Text>
              <ChevronRight color="#fff" size={24} style={{ position: 'absolute', right: 20, bottom: 20 }} />
            </LinearGradient>
          </TouchableOpacity>
        </Animated.View>

        <Animated.View entering={FadeInUp.duration(800).springify().delay(700)}>
          <TouchableOpacity
            className="rounded-xl overflow-hidden shadow-md"
            onPress={handlePlayPVPPress}
          >
            <LinearGradient
              colors={['#2D6A4F', '#95E1A8']}
              className="p-5 h-[110px]"
            >
              <Text className="font-poppins-bold text-xl text-white mb-2">PvP Showdown</Text>
              <Text className="font-poppins-regular text-sm text-white/90 w-4/5">
                Ready to test your skills in real battle?
              </Text>
              <ChevronRight color="#fff" size={24} style={{ position: 'absolute', right: 20, bottom: 20 }} />
            </LinearGradient>
          </TouchableOpacity>
        </Animated.View>
      </View>
    </View>
  );
}
import React from 'react';

export default function TabsLayout() {
    return (
        <Tabs
            screenOptions={{
                headerShown: false
            }}
            tabBar={() => null}
        >
            <Tabs.Screen name="index" />
            <Tabs.Screen name="ai" />
            <Tabs.Screen name="boards" />
            <Tabs.Screen name="create_lobby" />
            <Tabs.Screen name="join_lobby" />
            <Tabs.Screen name="pvp" />
            <Tabs.Screen name="room" />
            <Tabs.Screen name="select" />
            <Tabs.Screen name="settings" />
        </Tabs>
    );
}

Show only the current page on a scrollspy-type menu

I made a mouse-wheel horizontal-scrolling page, based on code that I found. As you see in the code, there are only 10 pages, but I want to add more. As you scroll through the pages, the menu at right shows your current page. Now, if there were 40 or 50 pages, the menu could not show all of them.

So, how do I show only the current page, or possibly one before the current and one after the current? In other words, pages 3, 4, and 5 in the menu. They would need to change as the user continue scrolling so that only the current page and the before and after pages are showing in the menu.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Animation</title>
<link rel="stylesheet" href="13.css">
</head>
<body>
<div class="container">

<section class="sectionA sliding">
<div id="slide1"   class="slide"    style="background-image:url(2.jpg)"></div>
<div id="slide2"   class="slide"    style="background-image:url(3.jpg)"></div>
<div id="slide3"   class="slide"    style="background-image:url(4.jpg)"></div>
<div id="slide4"   class="slide"    style="background-image:url(5.jpg)"></div>
<div id="slide5"   class="slide"    style="background-image:url(6.jpg)"></div>
<div id="slide6"   class="slide"    style="background-image:url(7.jpg)"></div>
<div id="slide7"   class="slide"    style="background-image:url(8.jpg)"></div>
<div id="slide8"   class="slide"    style="background-image:url(9.jpg)"></div>
<div id="slide9"   class="slide"    style="background-image:url(10.jpg)"></div>
<div id="slide10"  class="slide"    style="background-image:url(11.jpg)"></div></section>

<div class="navBar item">
<div class="line"></div>
<div class="navSectionContent active" id='section_1'>   <span>Page 1</span>   <button></button></div>
<div class="navSectionContent"        id='section_2'>   <span>Page 2</span>   <button></button></div>
<div class="navSectionContent"        id='section_3'>   <span>Page 3</span>   <button></button></div>
<div class="navSectionContent"        id='section_4'>   <span>Page 4</span>   <button></button></div>
<div class="navSectionContent"        id='section_5'>   <span>Page 5</span>   <button></button></div>
<div class="navSectionContent"        id='section_6'>   <span>Page 6</span>   <button></button></div>
<div class="navSectionContent"        id='section_7'>   <span>Page 7</span>   <button></button></div>
<div class="navSectionContent"        id='section_8'>   <span>Page 8</span>   <button></button></div>
<div class="navSectionContent"        id='section_9'>   <span>Page 9</span>   <button></button></div>
<div class="navSectionContent"        id='section_10'>  <span>Page 10</span>  <button></button></div></div>

<div class="loader"><img src="12.gif"></div></div>

<script src="14.js"></script>

</body></html>
html {
overflow:hidden;
}
body,html {
height:100vh;
}
body {
background:#000;
margin:0;
padding:0;
color:#fff;
font-family:arial;
font-size:12px;
}
div.container {
width:100%!important;
margin:0;
position:relative;
}
.container {
height:100%;
position:relative;
}
.loader {
background:#000;
width:100%;
height:100%;
position:absolute;
left:0;
top:0;
z-index:1000;
}
.loader img {
position:absolute;
margin:auto;
left:0;
right:0;
bottom:0;
top:0;
}
.sectionA {
height:100%;
}
.sectionA::after,.sectionA::before {
display:table;
content:"";
}
.sectionA::after {
clear:both;
zoom:1;
}
.sectionA.sliding {
-webkit-transition:all .4s ease;
-moz-transition:all .4s ease;
-o-transition:all .4s ease;
transition:all 1s ease-in-out .3s;
}
.navBar {
width:100px;
height:590px;
position:fixed;
right:.5vw;
margin:auto;
}
.navBar.item {
height:590px;
top:3vh;
}
.navBar.item .line {
position:absolute;
right:5px;
top:0vh;
height:590px;
width:12px;
border:1px solid #fff;
background:transparent;
}
.navBar::after,.navBar::before {
display:table;
content:"";
}
.navBar::after {
clear:both;
zoom:1;
}
.navBar .navSectionContent {
position:relative;
margin-bottom:46px;
text-align:right;
float:right;
display:inline-block;
clear:both;
}
.navBar button {
width:0;
height:0;
background:transparent;
position:absolute;
top:0;
right:0;
bottom:0;
margin:auto;
border:0;
}
.navBar .navSectionContent.active button {
background:rgba(0,255,0,.7);
width:12px;
height:43px;
position:absolute;
top:0;
right:6px;
bottom:0;
margin:auto;
}
.navBar span {
margin-right:30px;
cursor:pointer;
font-size:12px;
font-weight:200;
display:inline-block;
color:#fff;
background:rgba(0,0,0,.3);
padding:0 4px;
}
.navBar .navSectionContent.active span {
color:#fff;
background:rgba(0,255,0,.3);
padding:12px;
margin-right:18px;
border-radius:8px;
border-top-right-radius:0;
border-bottom-right-radius:0;
border:1px solid rgba(255,255,255,.3);
font-size:14px;
font-weight:400;
}
.slide {
height:100%;
float:left;
}
@media only screen and (max-width:1350px) {
.navBar {
right:19px;
}
}
.slide {
background:#skyblue;
}
var A_util = {
browser: {
hasTouchSupport: 'createTouch' in document,
version: (navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie)[/: ]([d.]+)/) || []) [1],
androidversion: function () {
var e = navigator.userAgent.match(/s*Androids*([0-9]+).?([0-9]+)?.?([0-9]+)?s*/);
return e && e[1] && e[2] ? parseFloat(e[1] + '.' + e[2]) : !(!e || !e[1]) && parseFloat(e[1])},
isWebkit: - 1 < navigator.userAgent.indexOf('AppleWebKit/'),
isMobileSafari: /(ipad|iphone|ipod|android).*apple.*mobile.*safari/.test(navigator.userAgent.toLowerCase()),
isAppleChrome: /crios/.test(navigator.userAgent.toLowerCase()),
isAppleMobileDevice: /(ipad|iphone|ipod)/.test(navigator.userAgent.toLowerCase()),
isAndroidMobileDevice: /android/.test(navigator.userAgent.toLowerCase()),
isTansoDl: navigator.userAgent.toLowerCase().match(/TansoDL/i),
isWindowsPhone: function () {
return !!(navigator.userAgent.toLowerCase().match(/Windows CE|IEMobile|Windows Phone OS/i) || 'XDomainRequest' in window)},
highPixelDensityDisplay: 2 <= window.devicePixelRatio,
iPhone4: 2 <= window.devicePixelRatio && this.isMobileSafari,
currentOrientation: null,
isBlackBerry: function () {
return !!navigator.userAgent.match(/BlackBerry/i)},
isBB10: function () {
return !!navigator.userAgent.match(/BB10/i)},
iOSversion: function () {
var e = window.navigator.userAgent,
t = e.indexOf('OS ');
return ( - 1 < e.indexOf('iPhone') || - 1 < e.indexOf('iPad')) && - 1 < t ? window.Number(e.substr(t + 3, 3).replace('_', '.')) : 0 }},
addClass: function (e, t) {
var n = e && 'object' == typeof e.className ? e.className.baseVal : e.className;
this.hasClass(e, t) || ('object' == typeof e.className ? e.className.baseVal = n += n ? ' ' + t : t : e.className = n += n ? ' ' + t : t)},
addClassMultiple: function (e, t) {
for (var n = 0, a = e.length; n < a; n++) this.hasClass(e[n], t) || (e[n].className ? e[n].className += ' ' + t : e[n].className += t)},
addEventHandler: function (e, t, n) {
e.addEventListener ? e.addEventListener(t, n, !1) : e.attachEvent ? e.attachEvent('on' + t, n) : e['on' + t] = n},
extendSimple: function (e, t) {
for (var n in t) t.hasOwnProperty(n) && (e[n] = t[n]);
return e},
extendDefaults: function (e, t, n) {
var a,
o = Object.prototype.hasOwnProperty;
for (a in t) !o.call(t, a) || 'constructor' === a && e === window || (void 0 === t[a] ? delete e[a] : n && void 0 !== e[a] || (e[a] = t[a]));
return e},
hasClass: function (e, t) {
e = e && 'object' == typeof e.className ? e.className.baseVal : e.className;
return e && new RegExp('(\s|^)' + t + '(\s|$)').test(e)},
removeClass: function (e, t) {
var n = ' ' + (e && 'object' == typeof e.className ? e.className.baseVal : e.className).replace(/[trn]/g, ' ') + ' ';
if (this.hasClass(e, t)) {
for (; 0 <= n.indexOf(' ' + t + ' '); ) n = n.replace(' ' + t + ' ', ' ');
'object' == typeof e.className ? e.className.baseVal = n.replace(/^s+|s+$/g, '') : e.className = n.replace(/^s+|s+$/g, '')}},
removeClassMultiple: function (e, t) {
for (var n = 0, a = e.length; n < a; n++) {
var o = ' ' + e[n].className.replace(/[trn]/g, ' ') + ' ';
if (this.hasClass(e[n], t)) {
for (; 0 <= o.indexOf(' ' + t + ' '); ) o = o.replace(' ' + t + ' ', ' ');
e[n].className = o.replace(/^s+|s+$/g, '')}}},
removeEventHandler: function (e, t, n) {
e.removeEventListener ? e.removeEventListener(t, n, !1) : e.detachEvent ? e.detachEvent('on' + t, n) : e['on' + t] = null},
children: function (e) {
for (var t = e.childNodes, n = [], a = t.length; a--; ) 1 == t[a].nodeType && n.unshift(t[a]);
return n},
triggerEvent: function (e, t) {
var n;
document.createEvent ? ((n = document.createEvent('HTMLEvents')).initEvent(t, !0, !1), e.dispatchEvent(n)) : e.fireEvent('on' + t)},
ajaxGet: function (e) {
var t,n = '';
for (t in e.data) '' != n && (n += '&'),n += t + '=' + encodeURIComponent(e.data[t]);
var a = new XMLHttpRequest;
a.open('GET', e.url + '?' + n, !0),
a.onreadystatechange = function () {
4 === this.readyState && (200 <= this.status && this.status < 400 ? e.success && 'function' == typeof e.success && e.success(JSON.parse(this.responseText)) : console.error('Ajax error occured.'))},a.send()},
ajaxGetData: function (e) {
var t = '';
if (void 0 !== e.data) for (var n in e.data) '' != t && (t += '&'),t += n + '=' + encodeURIComponent(e.data[n]);
var a = e.url,
o = new XMLHttpRequest;
o.open('GET', a, !0),
o.onreadystatechange = function () {
4 === this.readyState && (200 <= this.status && this.status < 400 ? e.success && 'function' == typeof e.success && e.success(this.responseText) : console.error('Ajax error occured.'))},o.send()},
appendString: function (e, t) {
var n = document.createElement('div');
for (n.innerHTML = t; n.firstChild; ) e.appendChild(n.firstChild)},
nextElementSibling: function (e) {
for (; (e = e.nextSibling) && 1 !== e.nodeType; );
return e},
previousElementSibling: function (e) {
for (; (e = e.previousSibling) && 1 !== e.nodeType; );
return e},
closest: function (e, t) {
var n;
for (Element.prototype.matches || (Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function (e) {
for (var t = (this.document || this.ownerDocument).querySelectorAll(e), n = t.length; 0 <= --n && t.item(n) !== this; );
return - 1 < n});
null !== e; ) {
if (null !== (n = e.parentElement) && n instanceof Element && n.matches(t)) return n;
e = n}
return null},
setText: function (e, t) {e.textContent ? e.textContent = t : e.innerText = t},
setData: function (e, t, n) {
e.dataset ? (t = t.replace(/[-_]([a-z])/g, function (e) {
return e[1].toUpperCase()
}), e.dataset[t] = n) : e.setAttribute('data-' + t, n)},
getData: function (e, t) {
return e.dataset ? (t = t.replace(/[-_]([a-z])/g, function (e) {
return e[1].toUpperCase()}), e.dataset[t]) : e.getAttribute('data-' + t)},
domReady: function (e) {
function n() {
document.addEventListener ? (document.removeEventListener('DOMContentLoaded', t), window.removeEventListener('load', t)) : (document.detachEvent('onreadystatechange', t), window.detachEvent('onload', t))}
var a = !1,t = function () {
a || !document.addEventListener && 'load' !== event.type && 'complete' !== document.readyState || (a = !0, n(), e())};
if ('complete' === document.readyState) e();
else if (document.addEventListener) document.addEventListener('DOMContentLoaded', t),
window.addEventListener('load', t);
else {
document.attachEvent('onreadystatechange', t),window.attachEvent('onload', t);
var o = !1;
try {o = null == window.frameElement && document.documentElement} catch (e) {}
o && o.doScroll && !function t() {
if (!a) {
try {
o.doScroll('left')
} catch (e) {
return setTimeout(t, 50)}
a = !0,
n(),
e()}}()}},
  lastChild: function (e) {
    if (!e.children.length) return null;
    if (e.lastElementChild) return e.lastElementChild;
    for (var t = e.children.length - 1; 0 <= t; --t) {
      var n = e.children[t];
      if (1 === n.nodeType) return n
    }
  },
  offset: function (e) {
    var e = e.getBoundingClientRect(),
    t = document.body,
    n = document.documentElement,
    a = window.pageYOffset || n.scrollTop || t.scrollTop,
    o = window.pageXOffset || n.scrollLeft || t.scrollLeft,
    r = n.clientTop || t.clientTop || 0,
    n = n.clientLeft || t.clientLeft || 0,
    t = e.top + a - r,
    a = e.left + o - n;
    return {
      left: Math.round(a),
      top: Math.round(t)
    }
  },
  empty: function (e) {
    for (; e.firstChild; ) e.removeChild(e.firstChild)
  },
  preventDefault: function (e) {
    e.preventDefault ? e.preventDefault() : e.returnValue = !1
  },
  toggleClass: function (e, t) {
    if (e.classList) e.classList.toggle(t);
     else {
      for (var n = e.className.split(' '), a = - 1, o = n.length; o--; ) n[o] === t && (a = o);
      0 <= a ? n.splice(a, 1) : n.push(t),
      e.className = n.join(' ')
    }
  },
  debounce: function (e, t, n) {
    function a() {
      o = null
    }
    var o = null;
    return function () {
      n && n.apply(this, arguments),
      o || (e.apply(this, arguments), o = setTimeout(a, t))
}},
areCookiesEnabled: function () {
    var e = !!navigator.cookieEnabled;
    return void 0 !== navigator.cookieEnabled || e || (document.cookie = 'testcookie', e = - 1 != document.cookie.indexOf('testcookie')),
    e
  },
  isLocalStorageEnabled: function () {
    if ('undefined' == typeof localStorage) return !1;
    try {
      localStorage.removeItem('LsAccessSuccess'),
      localStorage.setItem('LsAccessSuccess', 'localStorageEnabledOk'),
      localStorage.removeItem('LsAccessSuccess')
    } catch (e) {
      return !1
    }
    var e;
    return !!A_util.areCookiesEnabled() && ( - 1 == document.cookie.indexOf('local_storage') && ((e = new Date).setTime(e.getTime() + 31536000000), e = ' expires = ' + e.toGMTString() + ';', document.cookie = 'local_storage = 1;' + e + ' path=/;'), !0)
  },
  storage: {
    hasLocalStorage: function () {
      try {
        localStorage.enableStorage = 1,
        localStorage.removeItem('enableStorage')
      } catch (e) {
        return !1
      }
      return !0
    }(),
    defaultExpiry: 1,
    saveWithExpiry: function (e, t, n) {
      this.hasLocalStorage && ((n = t.expires && !n ? t.expires : n) || (n = new Date).setDate(n.getDate() + this.defaultExpiry), n = n instanceof Date ? n.getTime() : parseInt(n), this.saveItem(e, {
        val: t,
        expires: n
      }))
    },
    getItem: function (t) {
      if (this.hasLocalStorage) {
        var e;
        try {
          e = JSON.parse(localStorage[t])
        } catch (e) {
          return localStorage[t]
        }
        return parseInt(e.expires) < (new Date).getTime() ? (this.deleteItem(t), null) : e.val || e
      }
    },
    saveItem: function (e, t) {
      this.hasLocalStorage && (t = JSON.stringify('object' == typeof t ? t : {
        val: t
      }), localStorage.setItem(e, t))
    },
    deleteItem: function (e) {
      this.hasLocalStorage && localStorage.removeItem(e)
    },
    saveExpiry: function (e, t, n) {
      return 'undefined' != typeof Storage && (n = {
        value: JSON.stringify(t),
        timestamp: (new Date).getTime() + n
      }, localStorage.setItem(e, JSON.stringify(n)), t)
    },
    getExpiry: function (e) {
      return 'undefined' != typeof Storage && !!(e = JSON.parse(localStorage.getItem(e))) && (new Date).getTime() < e.timestamp && JSON.parse(e.value)
    }
  },
  ajaxCall: function (n) {
    if (null == n || '' == n.url || '' == n.data || '' == n.type) return console.log('ajaxPost: Parameters can't be empty'),
    !1;
    a = new (1 == n.crossDomain && 'undefined' != typeof XDomainRequest ? XDomainRequest : XMLHttpRequest);
    var a,
    e,
    o = new CustomEvent('ajaxSuccess'),
    r = new CustomEvent('ajaxFail'),
    t = n.type ? n.type.toUpperCase() : 'GET',
    s = '',
    c = n.contentType || 'application/x-www-form-urlencoded; charset=UTF-8';
    for (e in n.data) '' != s && (s += '&'),
    s += e + '=' + encodeURIComponent(n.data[e]);
    if ('GET' === t && (0 == n.cache ? n.url += '&timestamp=' + Date.now() : n.url += s ? ( - 1 !== n.url.indexOf('?') ? '&' : '?') + s : ''), a.open(t, n.url, !0), '' != n.dataType && 'string' == typeof n.dataType ? a.responseType = n.dataType : a.responseType = 'json', a instanceof XMLHttpRequest && void 0 === n.requestType && (a.setRequestHeader('X-Requested-With', 'XMLHttpRequest'), a.setRequestHeader('Content-Type', c)), '' != n.requestType && 'string' == typeof n.requestType && (s = JSON.stringify(n.data), a.setRequestHeader('Content-Type', n.requestType)), n.headers && (Object.keys || (Object.keys = function (e) {
      var t,
      n = [
      ];
      for (t in e) e.hasOwnProperty(t) && n.push(t);
      return n
    }), Object.keys(n.headers).forEach(function (e) {
      a.setRequestHeader(e, n.headers[e])
    })), 'false' == n.cache && 'POST' == t && a.setRequestHeader('cache-control', 'no-cache'), n.xhrFields) for (i in n.xhrFields) a[i] = n.xhrFields[i];
    return 'function' == typeof n.beforeSend && !1 === n.beforeSend() ? a.abort() : (a.onreadystatechange = function () {
      var t = {
      };
      if (4 == a.readyState) if (200 <= a.status && a.status < 400) {
        try {
          t = JSON.parse(a.responseText)
        } catch (e) {
          t = a.response
        }
        'function' == typeof n.success && (a instanceof XMLHttpRequest ? n.success(t) : a.onload(function () {
          n.success(t)
        })),
        a.dispatchEvent(o)
      } else a.dispatchEvent(r),
      t = {
        error: 'Error getting data from AJAX call'
      };
      if (null != t && void 0 !== t.error) return console.log('ajaxPost: ' + t.error),
      !1
    }, a.send(s), a.done = function (e) {
      'function' == typeof e && (a instanceof XMLHttpRequest ? A_util.addEventHandler(a, 'ajaxSuccess', e) : a.onload = e())
    }, a.fail = function (e) {
      'function' == typeof e && (a instanceof XMLHttpRequest ? A_util.addEventHandler(a, 'ajaxFail', e) : a.onerror = e())
    }, a.always = function (e) {
      'function' == typeof e && (a instanceof XMLHttpRequest ? (A_util.addEventHandler(a, 'ajaxSuccess', e), A_util.addEventHandler(a, 'ajaxFail', e)) : (a.onload = e(), a.onerror = e()))
    }, a)
  },
  getEventTarget: function (e) {
    return (e = e || window.event).target || e.srcElement
  }
};
!function () {
  function e(e, t) {
    t = t || {
      bubbles: !1,
      cancelable: !1,
      detail: void 0
    };
    var n = document.createEvent('CustomEvent');
    return n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail),
    n
  }
  'function' != typeof window.CustomEvent && (e.prototype = window.Event.prototype, window.CustomEvent = e)
}();

var url = window.location.toString(),
hash = url.substring(url.indexOf('#') + 1),
activeNum = null,
genericFunctionModule = function () {
var n = document.querySelectorAll('.slide'),l = null,i = null;
function r(e, t) {
e = document.querySelector(e);
t = ('0' + t).slice( - 2),e && (e.textContent = t)}
function t() {
var e,t,o,n = (new Date).getTime(),n = i - n;
n < 0 ? clearInterval(l) : n && (e = Math.floor(n / 86400000), t = Math.floor(n % 86400000 / 3600000), o = Math.floor(n % 3600000 / 60000), n = Math.floor(n % 60000 / 1000), r('.js-days', e), r('.js-hours', t), r('.js-mins', o), r('.js-secs', n))
}
return {
widthSlide: function () {
if (n.length) for (var e = 0;
e < n.length; e++) n[e].style.width = window.innerWidth + 'px';
document.querySelector('.sectionA') && (document.querySelector('.sectionA').style.width = window.innerWidth * n.length + 'px', document.querySelector('.sectionA').style.marginLeft = '-' + window.innerWidth * activeNum + 'px'),
      document.querySelector('#section_' + (activeNum + 1)) && A_util.addClass(document.querySelector('#section_' + (activeNum + 1)), 'active')
    },
    faqAlign: function () {
      window.innerHeight < 890 ? (document.querySelector('#faqContent') && A_util.addClass(document.querySelector('#faqContent'), 'scrollMin'), document.querySelector('.scrollBar') && (document.querySelector('.scrollBar').style.display = 'block'), document.querySelector('.track1') && (document.querySelector('.track1').style.display = 'block'), setTimeout(function () {
        AB_scroll.init({
          selector: document.querySelectorAll('#faqContent'),
          height: 'auto',
          width: 'auto',
          color: '#F39000',
          size: '7px',
          alwaysVisible: !0,
          railVisible: !0,
          railOpacity: 1,
          railColor: '#222',
          distance: - 2,
          railClass: 'track1',
          opacity: '1',
          wrapperClass: 'wrapper1'
        })
      }, 2000), document.querySelector('.modalMTubes') && A_util.addClass(document.querySelector('.modalMTubes'), 'smallModalMTubes')) : (document.querySelector('#faqContent') && A_util.removeClass(document.querySelector('#faqContent'), 'scrollMin'), document.querySelector('.scrollBar') && (document.querySelector('.scrollBar').style.display = 'none'), document.querySelector('.track1') && (document.querySelector('.track1').style.display = 'none'), document.querySelector('.modalMTubes') && A_util.removeClass(document.querySelector('.modalMTubes'), 'smallModalMTubes'))
    },
    urlActiveSection: function () {
      A_util.removeClassMultiple(n, 'active');
      for (var e = 0; e < n.length; e++) n[e].id.replace('Slide', '').toLowerCase() === hash.toLowerCase() && A_util.addClass(document.querySelector('#' + n[e].id), 'active')
    },
    getIndex: function (e) {
      if (e) for (var t = e.parentNode.childNodes, o = 0, n = 0; n < t.length; n++) {
        if (t[n] == e) return o;
        1 == t[n].nodeType && o++
      }
      return - 1
    },
    slideFunction: function (e) {
      var t = document.querySelectorAll('.navSectionContent'),
      o = document.querySelector('.sectionA');
      o && A_util.addClass(o, 'sliding'),
      e ? activeNum-- : activeNum++,
      e = n.length ? n[activeNum] : null,
      'undefined' != typeof WIDGET_PREMIUM_SIGNUP && (WIDGET_PREMIUM_SIGNUP.realEstateTracking = changeRealEstateTrackingObj(e, !1)),
      A_util.removeClassMultiple(t, 'active'),
      (t = document.querySelector('#section_' + (activeNum + 1))) && A_util.addClass(t, 'active'),
      o && (o.style.marginLeft = '-' + n[0].clientWidth * activeNum + 'px'),
      A_util.removeClassMultiple(n, 'active'),
      A_util.addClass(e, 'active')
    },
    tooltipPromo: function () {
      var e = document.querySelector('.tooltipPromoTrigger'),
      t = document.querySelector('.tooltipPromo'),
      o = (n = e.getBoundingClientRect()).left - (t.offsetWidth - e.offsetWidth) / 2,
      n = n.top + e.offsetHeight + 7 + 'px';
      t.style.left = o + 'px',
      t.style.right = 'auto',
      t.style.top = n,
      t.style.opacity = 1
    },
    startTimer: function (e) {
      i = new Date(e).getTime(),
      l = setInterval(t, 1000)
    }
  }
}(),
premiumEventHandlersModule = {
  faqDropDownClick: function () {
    var e = this.parentElement.children;
    A_util.toggleClass(this.querySelectorAll('p') [0], 'linearSlide');
    for (var t = 0; t < e.length; t++) e[t] !== this && (A_util.removeClass(e[t], 'active'), A_util.removeClassMultiple(e[t].querySelectorAll('p'), 'linearSlide'));
    A_util.toggleClass(this, 'active')
  },
  navBarClick: function () {
    var e = document.querySelectorAll('.navSectionContent');
    activeNum = genericFunctionModule.getIndex(this) - 1,
    allSlides = document.querySelectorAll('.slide'),
    'undefined' != typeof WIDGET_PREMIUM_SIGNUP && (WIDGET_PREMIUM_SIGNUP.realEstateTracking = changeRealEstateTrackingObj(allSlides[activeNum], !1)),
    document.querySelector('.sectionA') && (A_util.addClass(document.querySelector('.sectionA'), 'sliding'), document.querySelector('.sectionA').style.marginLeft = '-' + document.querySelector('.slide').clientWidth * activeNum + 'px'),
    A_util.removeClassMultiple(e, 'active'),
    A_util.addClass(this, 'active')
  },
  hashChangeEvent: function () {
    genericFunctionModule.urlActiveSection(),
    activeNum = genericFunctionModule.getIndex(document.querySelector('.navSectionContent.active')) - 1,
    A_util.removeClass(document.querySelector('.navSectionContent'), 'active'),
    document.querySelector('#section_' + (activeNum + 1)) && A_util.addClass(document.querySelector('#section_' + (activeNum + 1)), 'active'),
    genericFunctionModule.widthSlide()
  },
  resizeFunction: function () {
    document.querySelector('.sectionA') && A_util.removeClass(document.querySelector('.sectionA'), 'sliding'),
    genericFunctionModule.widthSlide(),
    genericFunctionModule.faqAlign()
  },
  mouseUpFunction: function (e) {
    joinPageUrlParam.reloadParamsOnModalClose(e.target)
  },
  mouseScrollFunction: function (e) {
    document.querySelector('.modalMTubes.premiumSignupModal') || 0 !== document.querySelectorAll('.scrollOn').length || (0 < e.wheelDelta || e.detail < 0 ? 0 < activeNum && genericFunctionModule.slideFunction(!0) : activeNum < document.querySelectorAll('.slide').length - 1 && genericFunctionModule.slideFunction(!1))
  }
};
function changeRealEstateTrackingObj(e, t) {
  return (jslide = t ? document.querySelector('.slide.active') : e) && jslide.dataset && jslide.dataset.tracking ? jslide.dataset.tracking : ''
}
A_util.domReady(function () {
  var e,
  t,
  o,
  n = document.querySelectorAll('.slide'),
  l = ('undefined' != typeof WIDGET_PREMIUM_SIGNUP && (WIDGET_PREMIUM_SIGNUP.realEstateTracking = changeRealEstateTrackingObj(n, !0)), 1 < url.indexOf('#') ? genericFunctionModule.urlActiveSection() : A_util.addClass(document.querySelector('#slide1'), 'active'), activeNum = genericFunctionModule.getIndex(document.querySelector('.navSectionContent.active')) - 1, document.querySelectorAll('.navSectionContent')),
  i = document.querySelectorAll('.dropDownContent'),
  n = document.querySelector('#faqContent');
  if (l.length) for (var r = 0; r < l.length; r++) A_util.addEventHandler(l[r], 'click', premiumEventHandlersModule.navBarClick);
  if (i.length) for (r = 0; r < i.length; r++) A_util.addEventHandler(i[r], 'click', premiumEventHandlersModule.faqDropDownClick),
  A_util.addEventHandler(i[r], 'keypress', premiumEventHandlersModule.faqDropDownClick);
  n && (A_util.addEventHandler(document.querySelector('#faqContent'), 'DOMMouseScroll', function (e) {
    e.stopPropagation()
  }), A_util.addEventHandler(document.querySelector('#faqContent'), 'mousewheel', function (e) {
    e.stopPropagation()
  }), A_util.addEventHandler(n, 'mouseover', function (e) {
    window.innerHeight < 860 && A_util.addClass(this, 'scrollOn')
  }), A_util.addEventHandler(n, 'mouseleave', function (e) {
    A_util.removeClass(this, 'scrollOn')
  })),
  A_util.addEventHandler(window, 'hashchange', premiumEventHandlersModule.hashChangeEvent),
  A_util.addEventHandler(window, 'resize', premiumEventHandlersModule.resizeFunction),
  A_util.addEventHandler(document, 'mouseup', premiumEventHandlersModule.mouseUpFunction),
  A_util.addEventHandler(window, 'mousewheel', premiumEventHandlersModule.mouseScrollFunction),
  A_util.addEventHandler(window, 'DOMMouseScroll', premiumEventHandlersModule.mouseScrollFunction),
  document.querySelector('.sectionA .logo a') && A_util.addEventHandler(document.querySelector('.sectionA .logo a'), 'click', function (e) {
    e.preventDefault(),
    document.querySelector('#section_1') && document.querySelector('#section_1').click()
  }),
  document.querySelector('.tooltipPromo') && (document.querySelector('.tooltipPromo span') && A_util.addEventHandler(document.querySelector('.tooltipPromo span'), 'click', function (e) {
    e.stopPropagation(),
    A_util.setCookie('promoTooltip', 1);
    e = document.querySelector('.tooltipPromo');
    e && e.parentNode.removeChild(e)
  }), e = setInterval(function () {
    0 !== document.querySelector('.tooltipPromoTrigger').getBoundingClientRect().top && (genericFunctionModule.tooltipPromo(), clearInterval(e), A_util.addEventHandler(window, 'resize', genericFunctionModule.tooltipPromo))
  }, 100)),
(n = document.querySelector('.promoDeal')) && (t = n.querySelector('span'), o = document.querySelector('.lifeTimeOffer'), n.addEventListener('click'), n.click()),
genericFunctionModule.faqAlign(),genericFunctionModule.widthSlide(),document.querySelector('.offerLifeTime') && document.querySelector('#offersBlock .offer') && (document.querySelector('.offerLifeTime').dataset.paymentType = document.querySelectorAll('#offersBlock .offer') [0].dataset.paymentType),
PREMIUM_SIGNUP.isPreBlackFriday && genericFunctionModule.startTimer('Nov 26, 2020 00:00:00 GMT-0500'),premiumSignupModal.init()}),
document.addEventListener('DOMContentLoaded', function () {document.querySelector('.loader') && (document.querySelector('.loader').style.display = 'none')});

Standard upload form on NodeJS has an empty file field

I want to upload a file to a NodeJS server. Following File uploading with Express 4.0: req.files undefined , I try this code in mre.js:

'use strict';

const path = require('path');
const express = require('express');
const app = express();

// Set up the view engine
app.set('view engine', 'pug');
app.set('views', path.join(__dirname, 'views'));


const UPLOAD = "/upload";

app.get(UPLOAD, async (req, res) => {
  
  return res.render("upload");
});


const fileUpload = require('express-fileupload');

app.post(UPLOAD, fileUpload(), async (req, res) => {
  let keys = Object.keys(req.files);
  fs.readFile(req.files[keys[0]].path, (err, e) => {
    if(err) console.log(err);
    fs.writeFile(keys[0], e, (err) => {
      console.log(err)
    })
  })

  req.flash("success", "File uploaded");
  return res.redirect(UPLOAD);
});



const http = require('http');
const httpServer = http.createServer(app);

let server = httpServer.listen(8080, () => {
  console.log("n# HTTP server started");
});

and the view is:

doctype html
html

  body
    form.left(method='POST')
    
      input(type='file', id="file", name="filename", accept=".xls,.xlsx,.txt")
      input(type="submit", name="submit", value="Upload")

I launch with node mre.js, I see the form at http://localhost:8080/upload, but when I upload a file, I get this error:

mre.js:24
  let keys = Object.keys(req.files);
TypeError: Cannot convert undefined or null to object

I tried several variations to no avail, for example I log the full request with console.log(req), and the filename I uploaded does not appear. But it seems to work on multiple answers of that thread, so I think there’s something obvious I am overlooking.

How can I get the file uploaded to a NodeJS server?

Need Javascript help – Popup-selected value not updating main page dropdown [closed]

I’m working on a web project involving interaction between a main HTML form and a popup window using JavaScript. The goal is:

The main page contains a dropdown with predefined values.

It also includes a button labeled “Additional LookUp”.

When clicked, the button opens a popup window that allows users to search and select a new value.

When the user clicks RETURN in the popup, the selected value should be passed back and update the main page dropdown. Main Page:

Get chat status in zendesk

We use the zendesk chat app on the shopify site. And I need to get the chat status: online, away or offline. I tried it, but now it doesn’t work, because it is related to an old version of the API:

zE('webWidget:on', 'chat:departmentStatus', function(dept) {
  if (dept.name === 'CRM' && dept.status === 'online') {
    zE('webWidget', 'updateSettings', {
      webWidget: {
        chat: {
          departments: {
            enabled: [''],
            select: 'CRM'
          },
          suppress: false
        }
      }
    });
  } else if (dept.name === 'CRM' && dept.status !== 'online') {
    zE('webWidget', 'updateSettings', {
      webWidget: {
        chat: {
          suppress: true
        }
      }
    });
  }
});

webWidget:on – no longer supported

But in the new documentation I didn’t find what I need. Please help.

google sheets app script use selection as input (e.g. C105:I105) [duplicate]

I want to call a custom function like this in Google Sheets:

=countColoredCells(C105:I105, "#ff0000")

Where C105:I105 is a range reference, the same way you would use it in =SUM(C105:I105). However, I’ve parsed the input string in my function, and what I get is this completely useless array of an array of empty strings:

function countColoredCells(input, color) {
  return JSON.stringify(input);
}

Result: [["","","","","",""]]

I thought I must be mistaken, but I’ve checked the type, the length, etc., and they seem to be empty strings. (upon further investigation, I see that it gives you the cell values, but I want the actual cell references so I can check the color of the cells)

How can I use this input to iterate these cells?

NOTE:
I know I can put it in as a string and parse it, but that defeats the purpose. I expect to be able to use it like any other Sheets function with a selection directly input into it.

I also know that most examples get a selection off the sheet, which is also not what I want. My end result is that I want to automatically run this on each row in a growing spreadsheet (i.e. C106:I106, C107:I107, etc.).