() => {
  return {
    modules: ['https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js',
      'https://cdn.rawgit.com/mrdoob/three.js/25bc88abaef7f2f9376b8bbdea28973aa4925629/examples/js/controls/OrbitControls.js',
      'https://cdn.rawgit.com/mrdoob/three.js/6c7f000734f8579da37fb39e5c2e9e5e2dfb14f8/examples/js/Detector.js'
    ],
    body: `
    
    `,
    console: true,
    script: () => {
      document.addEventListener("DOMContentLoaded", (e) => {
        const webglEl = document.getElementById('sphere'),
        width = window.innerWidth,
        height = window.innerHeight,
        panoramasArray = [
          "https://res.cloudinary.com/dkcygpizo/image/upload/v1491862637/codepen/1_dtotv2.jpg",
          "https://res.cloudinary.com/dkcygpizo/image/upload/v1491862643/codepen/4_yvn4cb.jpg",
          "https://res.cloudinary.com/dkcygpizo/image/upload/v1491862642/codepen/5_ydhnc6.jpg"
        ];
        let panoramaNumber = 0 /* Math.floor(Math.random()*panoramasArray.length)* /;
    /* Creating the scene */
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, width / height, 1, 1100);
        camera.position.x = 0.1;
        const renderer = Detector.webgl ? new THREE.WebGLRenderer(): new THREE.CanvasRenderer();
        renderer.setSize(width, height);
        webglEl.appendChild(renderer.domElement);
        const sphereMaterial = new THREE.MeshBasicMaterial();
        sphereMaterial.map = new THREE.TextureLoader().setCrossOrigin("anonymous").load(panoramasArray[panoramaNumber]);
        //sphereMaterial.map = new THREE.TextureLoader().load(panoramasArray[panoramaNumber]); // For local images
        const sphereGeometry = new THREE.SphereGeometry(500, 60, 40);
        const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
        sphere.scale.x = -1;
        scene.add(sphere);
        /* Rendering & OrbitControls */
        const controls = new THREE.OrbitControls(camera, webglEl);
        controls.enablePan = false;
        controls.enableZoom = false;
        controls.autoRotate = true;
        controls.autoRotateSpeed = 0.5;
        controls.maxPolarAngle = 2; // Radians
        controls.minPolarAngle = 1; // Radians
        function render() {
          controls.update();
          requestAnimationFrame(render);
          renderer.render(scene, camera);
        }
        render();
        /* Add Controls */
        let deltaCount = 0;
        function onMouseWheel(e) {
          e.preventDefault();
          function mouseWheel() {
            if (e.wheelDeltaY) {
              // WebKit
              camera.fov -= e.wheelDeltaY * 0.05;
            } else if (e.wheelDelta) {
              // Opera / IE9
              camera.fov -= e.wheelDelta * 0.05;
            } else if (e.detail) {
              // Firefox
              camera.fov += e.detail * 1.0;
            }
            camera.fov = Math.max(40, Math.min(100, camera.fov));
          }
          if (e.deltaY < 0) {
            if (deltaCount < 6) {
              mouseWheel();
              deltaCount += 1;
            }
          } else {
            if (deltaCount > 0) {
              mouseWheel();
              deltaCount -= 1;
            }
          }
          camera.updateProjectionMatrix();
        }
        function onWindowResize() {
          camera.aspect = window.innerWidth / window.innerHeight;
          camera.updateProjectionMatrix();
          renderer.setSize(window.innerWidth, window.innerHeight);
        }
        document.addEventListener('mousewheel', onMouseWheel, false);
        document.addEventListener('DOMMouseScroll', onMouseWheel, false);
        window.addEventListener('resize', onWindowResize, false);
        /* Switch & Zoom */
        const switchBtn = document.querySelectorAll('.controls li[class*="switch"]'),
        zoomBtn = document.querySelectorAll('.controls li[class*="zoom"]');
        for (let i = 0; i < switchBtn.length; i++) {
          switchBtn[i].onclick = (e) => {
            let j = panoramasArray.length;
            panoramaNumber = ~e.target.className.indexOf("controls__switch-next") ? (panoramaNumber + 1) % j: (panoramaNumber - 1) % j;
            sphereMaterial.map = new THREE.TextureLoader().setCrossOrigin("anonymous").load(panoramasArray[Math.abs(panoramaNumber)]);
            //sphereMaterial.map = new THREE.TextureLoader().load(panoramasArray[Math.abs(panoramaNumber)]); // For local images
          };
        }
        for (let i = 0; i < zoomBtn.length; i++) {
          zoomBtn[i].onclick = (e) => {
            if (~e.target.className.indexOf("controls__zoom-in")) {
              if (deltaCount < 6) {
                camera.fov = Math.max(40, Math.min(100, camera.fov - 6));
                deltaCount += 1;
              }
            } else {
              if (deltaCount > 0) {
                camera.fov = Math.max(40, Math.min(100, camera.fov + 6));
                deltaCount -= 1;
              }
            }
            camera.updateProjectionMatrix();
          }
        }
      });
    }
  }
}